Repository navigation
Install spectacles agentic workflow suite - #255
norrietaylor wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthroughThis PR establishes a complete GitHub Actions-based SDD orchestration layer consisting of issue templates, command-routing workflows (spec, triage, dispatch, monitor), three-tier execution wrappers (haiku, sonnet, opus), and supporting task/PR management workflows that automate specification-driven development pipelines. ChangesSDD Pipeline Infrastructure
Sequence Diagram(s)sequenceDiagram
participant User
participant IssueTemplate
participant SpecRoute as sdd-spec route
participant FastpathApprove as fastpath-approve
participant Execute as sdd-execute-tier
participant Monitor as sdd-monitor
participant Dispatch as sdd-dispatch route
participant TaskExec as Execute Task
User->>IssueTemplate: Create tracking issue
activate IssueTemplate
IssueTemplate->>SpecRoute: /spec command or label
deactivate IssueTemplate
activate SpecRoute
SpecRoute->>SpecRoute: Permission check
SpecRoute->>FastpathApprove: Trigger if sdd:fastpath
deactivate SpecRoute
activate FastpathApprove
FastpathApprove->>FastpathApprove: Extract plan comment & tier
FastpathApprove->>Execute: Dispatch with entry:fastpath
FastpathApprove->>IssueTemplate: Update labels (remove sdd:fastpath, add sdd:in-progress)
deactivate FastpathApprove
activate Monitor
Monitor->>Monitor: Check armed-but-idle trackers
Monitor->>Dispatch: Post /dispatch comment
deactivate Monitor
activate Dispatch
Dispatch->>Dispatch: Walk sub-issues, parse blockers
Dispatch->>Dispatch: Compute ready set
Dispatch->>TaskExec: Post /execute to each ready task
Dispatch->>IssueTemplate: Apply sdd:ready + sdd:dispatched labels
deactivate Dispatch
activate Execute
Execute->>Execute: Route job: permission check
Execute->>Execute: Resolve task & tier gate
Execute->>TaskExec: Call reusable workflow
TaskExec->>User: Create implementation PR
deactivate Execute
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
Comment |
sdd-validate findings — Implementation boundaryResolved boundary: Implementation (changed files are not spec or architecture files) PR: Install spectacles agentic workflow suite ( Gate 1 — Proof artifacts re-executed and passingInfo: No task sub-issue is linked in this PR body (no Gate 2 — Changed files within task scopeBlocker · 17 of 18 changed files are under
Note: This is the spectacles install PR and the Gate 3 — No real credentials in the diffPass. The diff was scanned for hardcoded tokens, passwords, and secrets. None were found. Secrets referenced in the PR body ( Summary
Action required: A Blocker was found.
|
There was a problem hiding this comment.
Actionable comments posted: 1
Note
Due to the large number of review comments, Critical severity comments were prioritized as inline comments.
🟠 Major comments (21)
.github/workflows/sdd-triage.yml-81-81 (1)
81-81:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPin workflow/action references to commit SHAs.
actions/github-script@v9(line 81) andnorrietaylor/spectacles/.github/workflows/sdd-triage.lock.yml@main(line 214) are mutable refs; pin both to immutable commit SHAs to avoid unexpected upstream changes.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-triage.yml at line 81, Replace the mutable action refs with immutable commit SHAs: locate the uses entry "uses: actions/github-script@v9" and replace the tag with the specific commit SHA for the actions/github-script repository, and locate the reference "norrietaylor/spectacles/.github/workflows/sdd-triage.lock.yml@main" and replace the branch ref with that repository's exact commit SHA; ensure you fetch the correct commit SHAs from the respective upstream repos/tags and update both places so the workflow pins to the immutable SHAs rather than `@v9` or `@main`..github/workflows/sdd-triage.yml-89-101 (1)
89-101:⚠️ Potential issue | 🟠 Major | ⚡ Quick winFilter issue-label triggers to tracking issues only.
The
issuesbranch routes on label changes without checking whether the issue is a tracking issue (no parent). A mislabeled sub-issue can incorrectly trigger triage routing.Targeted fix
if (event === 'issues') { const action = payload.action; const label = payload.label && payload.label.name; if (action === 'labeled' && label === 'sdd:triage') { run = true; } else if (action === 'unlabeled' && label === 'needs-human') { run = true; } + if (run) { + try { + const { data } = await github.rest.issues.get({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: payload.issue.number, + }); + if (data.parent_issue_url) { + run = false; + core.info('Sub-issue label event ignored for sdd-triage.'); + } + } catch (err) { + core.info('Could not fetch issue #' + payload.issue.number + + ': ' + err.message); + } + } if (run) { ctx = { item_type: 'issue', item_number: payload.issue.number }; } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-triage.yml around lines 89 - 101, The issue: the 'issues' event handler sets run and ctx for any label change without ensuring the issue is a top-level tracking issue; to fix, restrict the labeled/unlabeled checks inside the event === 'issues' branch to only proceed when the issue is a tracking issue (no parent). Concretely, inside that branch where action, label, run, and ctx are used, add a guard that checks the payload.issue is top-level (e.g., !payload.issue.parent or equivalent field your payload uses to indicate a parent) before evaluating the 'labeled sdd:triage' or 'unlabeled needs-human' conditions and before setting ctx = { item_type: 'issue', item_number: payload.issue.number } so sub-issues won't trigger triage routing..github/workflows/sdd-spec.yml-88-88 (1)
88-88:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPin
uses:refs to commit SHAs in.github/workflows/sdd-spec.yml(and scope the minted App token)
uses:references in this workflow are mutable tags/branches, not immutable commit SHAs:
- 88:
actions/github-script@v9- 364:
actions/create-github-app-token@v3- 371:
actions/github-script@v9- 590:
norrietaylor/spectacles/.github/workflows/sdd-spec.lock.yml@main- 640:
actions/create-github-app-token@v3- 647:
actions/github-script@v9Additionally, the
actions/create-github-app-token@v3steps mint the installation token using onlyapp-id/private-key/owner/repositorieswith no explicit permission-scope narrowing in this workflow, increasing the blast radius of the token.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-spec.yml at line 88, The workflow uses mutable action refs and mints an overly-broad App token; replace each mutable `uses:` reference (e.g., actions/github-script@v9, actions/create-github-app-token@v3, norrietaylor/spectacles/.github/workflows/sdd-spec.lock.yml@main) with the corresponding pinned commit SHA for that action, and for the steps that call `actions/create-github-app-token@v3` narrow the minted installation token by adding explicit permission scope inputs (and repository list if applicable) so the token only has the minimum required permissions (e.g., specify permissions like contents: read or issues: write as needed) and ensure the step uses the pinned SHA as well..github/workflows/sdd-spec.yml-364-369 (1)
364-369:⚠️ Potential issue | 🟠 Major | ⚡ Quick winNarrow GitHub App token permissions to least privilege
Both
actions/create-github-app-token@v3steps in.github/workflows/sdd-spec.yml(lines 364-369, and the same pattern at 640-645) omit anypermission-*inputs, so the minted installation token inherits all permissions granted to the GitHub App installation (not least-privilege).The corresponding
github-scriptcode only uses Issues APIs (issues.get,issues.listComments,issues.createComment,issues.addLabels), so grant onlypermission-issues: writefor each “Mint App token” step (avoidpermission-actionsandpermission-contentshere unless this workflow uses them elsewhere for the same app token).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-spec.yml around lines 364 - 369, The GitHub App installation token steps using actions/create-github-app-token@v3 currently omit explicit permissions and thus inherit all app permissions; update each "Mint App token" step (the actions/create-github-app-token@v3 invocation around the existing app-id/private-key/owner/repositories inputs) to explicitly set permission-issues: write so the token is least-privilege for the github-script code that only calls issues.get, issues.listComments, issues.createComment and issues.addLabels; apply the same change to the duplicate step later in the file..github/workflows/distillery-sync.yml-31-31 (1)
31-31:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPin the reusable workflow reference to an immutable SHA (avoid
@main).
.github/workflows/distillery-sync.ymlline 31 usesnorrietaylor/spectacles/.github/workflows/distillery-sync.lock.yml@main(mutable@main), which breaks deterministic runs/unpinned-uses policy.Suggested change
- uses: norrietaylor/spectacles/.github/workflows/distillery-sync.lock.yml@main + uses: norrietaylor/spectacles/.github/workflows/distillery-sync.lock.yml@<40-char-commit-sha>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/distillery-sync.yml at line 31, Replace the mutable reference "uses: norrietaylor/spectacles/.github/workflows/distillery-sync.lock.yml@main" with an immutable commit SHA: identify the correct commit SHA for norrietaylor/spectacles (e.g., from the repository's commits for the referenced workflow file) and update that uses line to reference the SHA instead of `@main` so the reusable workflow is pinned; ensure the updated line still points to ".github/workflows/distillery-sync.lock.yml@<SHA>" to satisfy the pinned-uses policy..github/workflows/sdd-execute-haiku.yml-112-112 (1)
112-112:⚠️ Potential issue | 🟠 Major | ⚡ Quick winUse token-strict command matching here as well.
startsWith('/execute')andstartsWith('/revise')also match/executefooand/revisex. Those comments still land in the task's shared concurrency group and can cancel a legitimate in-flight run before the route script noops, which defeats the throwaway-group carve-out.Also applies to: 134-145
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-execute-haiku.yml at line 112, The group expression is using startsWith('/execute') and startsWith('/revise') which also match tokens like "/executefoo" and "/revisex"; update every occurrence of that token test (the startsWith checks in the group expression and the similar checks around lines referenced) to use a token-strict match (e.g. a regex that enforces end-of-token or whitespace such as matches(github.event.comment.body, '^/execute(\\s|$)') and '^/revise(\\s|$)') so only exact commands or commands followed by whitespace match and avoid false positives that join the shared concurrency group..github/workflows/sdd-monitor.yml-331-389 (1)
331-389:⚠️ Potential issue | 🟠 Major | ⚡ Quick winMonitor's ready-count logic ignores cross-repo blockers.
This pass only parses
blocked by#123``, whilesdd-dispatchalso honors `blocked by owner/repo#123`. A task blocked in another repo will be counted as ready here, so the monitor can keep posting `/dispatch` comments that dispatch immediately rejects as an empty ready set.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-monitor.yml around lines 331 - 389, The ready-count logic only parses "blocked by `#N`" (in the block that builds blockerNums from body.matchAll) and thus ignores cross-repo blockers; update the parser and blocker lookup so it recognizes both "blocked by `#123`" and "blocked by owner/repo#123" by extracting optional owner and repo plus the issue number (use the existing body variable and matchAll call but change the regex and mapping to produce blocker descriptors rather than plain ints), then when calling github.rest.issues.get use the matched owner/repo if present or fall back to the current owner/repo variables (keep checking got.data.pull_request and got.data.state as before); ensure error messages (the core.info calls in the catch) include the fully qualified blocker identifier and treat failures as still blocked exactly as existing logic does..github/workflows/sdd-execute-sonnet.yml-112-112 (1)
112-112:⚠️ Potential issue | 🟠 Major | ⚡ Quick winUse token-strict command matching here as well.
startsWith('/execute')andstartsWith('/revise')also match/executefooand/revisex. Those comments still land in the task's shared concurrency group and can cancel a legitimate in-flight run before the route script noops, which defeats the throwaway-group carve-out.Also applies to: 134-145
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-execute-sonnet.yml at line 112, The group expression currently uses startsWith('/execute') and startsWith('/revise') which also match '/executefoo' and '/revisex'; change those to token-strict checks by replacing startsWith('/execute') and startsWith('/revise') with contains(concat(' ', github.event.comment.body, ' '), ' /execute ') and contains(concat(' ', github.event.comment.body, ' '), ' /revise ') respectively (apply same fix to the other occurrence in the expression block referenced). Update the group expression whe 8BD0 re github.event.comment.body is checked so the shared concurrency key only triggers on exact token matches..github/workflows/sdd-triage-dedupe-tasks.yml-102-123 (1)
102-123:⚠️ Potential issue | 🟠 Major | ⚡ Quick winDon't dedupe phase-C tasks on title alone.
originalis selected purely by normalized title, then only rechecked for "looks like a task". Two legitimate task sub-issues under the same Unit can share a short title while differing in repo/blockers/proof artifacts, and this would auto-close the newer one incorrectly. Compare a stronger fingerprint before closing anything.Also applies to: 126-152
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-triage-dedupe-tasks.yml around lines 102 - 123, The current dedupe picks `original` solely by normalized `titleKey` using `isSameTitleEarlierTask`, which can false-match distinct phase-C tasks; update the matching to compute and compare a stronger fingerprint (e.g., combine normalized title plus additional distinguishing fields such as repository identifier, blocker list, and proof-artifact markers parsed from the issue body/labels) when filtering `siblings` before assigning `original` (adjust the predicate used in `.filter(...)` instead of `isSameTitleEarlierTask`); apply the same stronger-fingerprint comparison in the analogous block later (lines referenced in the review) so we only auto-close a sibling when title plus those extra fields match..github/workflows/sdd-execute-opus.yml-112-112 (1)
112-112:⚠️ Potential issue | 🟠 Major | ⚡ Quick winUse token-strict command matching here as well.
startsWith('/execute')andstartsWith('/revise')also match/executefooand/revisex. Those comments still land in the task's shared concurrency group and can cancel a legitimate in-flight run before the route script noops, which defeats the throwaway-group carve-out.Also applies to: 134-145
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-execute-opus.yml at line 112, The group expression uses startsWith(github.event.comment.body, '/execute') and '/revise' which also match prefixes like /executefoo; replace those with token-strict regex matches using the matches operator, e.g. use github.event.comment.body =~ '^/execute\\b' and github.event.comment.body =~ '^/revise\\b' (and update the same occurrences referenced in the later block around lines 134-145) so only exact commands or commands followed by whitespace/word-boundaries trigger the concurrency-group logic..github/workflows/sdd-review.yml-55-55 (1)
55-55:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPin the action and hosted reusable workflow to immutable SHAs.
.github/workflows/sdd-review.ymlusesactions/github-script@v9andnorrietaylor/spectacles/.github/workflows/sdd-review.lock.yml@main; both are mutable refs, so review behavior/security can change due to upstream updates. Pin bothuses:references to commit SHAs instead.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-review.yml at line 55, The workflow currently references mutable refs (uses: actions/github-script@v9 and uses: norrietaylor/spectacles/.github/workflows/sdd-review.lock.yml@main); replace each mutable tag with the corresponding immutable commit SHA for that repository/use (pin both actions/github-script and norrietaylor/spectacles references to their specific commit SHAs) so the workflow and hosted reusable workflow are fixed to exact commits; update the two uses: entries (the actions/github-script reference and the norrietaylor/spectacles reusable workflow reference) to their respective SHAs and commit the change..github/workflows/sdd-execute-haiku.yml-174-174 (1)
174-174:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPin
uses:refs in.github/workflows/sdd-execute-haiku.ymlto immutable SHAs
actions/github-script@v9(174),norrietaylor/spectacles/.../sdd-execute-haiku.lock.yml@main(814), andactions/create-github-app-token@v3(855) are mutable tags/refs, which harms reproducibility and can change behavior without a code change.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-execute-haiku.yml at line 174, The workflow uses mutable refs; replace the mutable tags with immutable commit SHAs: locate the uses entries for actions/github-script@v9, actions/create-github-app-token@v3, and the norrietaylor/spectacles.../sdd-execute-haiku.lock.yml@main reference, and update each to the corresponding full commit SHA (e.g., actions/github-script@<sha>, actions/create-github-app-token@<sha>, norrietaylor/spectacles/.../sdd-execute-haiku.lock.yml@<sha>) so the workflow pins to immutable refs and remains reproducible..github/workflows/sdd-pr-sanitize.yml-66-66 (1)
66-66:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPin
actions/github-scriptto an immutable commit SHA
uses: actions/github-script@v9uses a mutable tag; GitHub recommends pinning GitHub Actions to full-length commit SHAs to prevent upstream tag moves/supply-chain tampering. Preferuses: actions/github-script@<40-char-sha> # v9(same pattern appears in other workflows too).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-pr-sanitize.yml at line 66, The workflow is using a mutable tag "uses: actions/github-script@v9"; replace this with the full 40-character commit SHA for the actions/github-script action (e.g. "uses: actions/github-script@<40-char-sha> # v9") to pin the dependency and add the trailing comment to indicate the intended tag; update the line containing actions/github-script@v9 and mirror the same change for any other workflows using the same mutable tag..github/workflows/sdd-execute-sonnet.yml-174-174 (1)
174-174:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPin the actions and reusable workflow refs to immutable commit SHAs
In
.github/workflows/sdd-execute-sonnet.yml, theseuses:entries are mutable tag refs, so upstream changes can alter behavior without any repo change:
actions/github-script@v9(174)norrietaylor/spectacles/.github/workflows/sdd-execute-sonnet.lock.yml@main(814)actions/create-github-app-token@v3(855)Pin each to a full commit SHA.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-execute-sonnet.yml at line 174, The workflow uses mutable tag refs for third-party actions and a reusable workflow; find the exact commit SHAs for each referenced resource (actions/github-script@v9, norrietaylor/spectacles/.github/workflows/sdd-execute-sonnet.lock.yml@main, actions/create-github-app-token@v3) and replace the tag refs with their corresponding full commit SHAs (e.g. actions/github-script@<full-sha>) so the workflow is pinned immutably; update each `uses:` entry to the SHA form and optionally add a short comment noting the pinned SHA and original tag for future maintainers..github/workflows/sdd-triage-dedupe-tasks.yml-40-40 (1)
40-40:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPin
actions/github-scriptto an immutable commit SHA.
.github/workflows/sdd-triage-dedupe-tasks.yml:40currently usesactions/github-script@v9, leaving this job dependent on a mutable tag (supply-chain risk); pin to the full-length SHA instead.uses: actions/github-script@v9🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-triage-dedupe-tasks.yml at line 40, Replace the mutable tag usage "uses: actions/github-script@v9" with the full immutable commit SHA for the v9 release (e.g., "uses: actions/github-script@<full-commit-sha>"); locate the line containing uses: actions/github-script@v9 in the workflow and update it to reference the full-length Git commit SHA from the actions/github-script repository to remove supply-chain risk..github/workflows/sdd-dispatch.yml-849-854 (1)
849-854:⚠️ Potential issue | 🟠 Major | ⚡ Quick winScope GitHub App installation token permissions to the minimum needed.
All
actions/create-github-app-token@v3steps in.github/workflows/sdd-dispatch.ymlmint an installation token without anypermission-*inputs, so the token inherits the GitHub App installation’s full permission set (job-levelpermissions:only limitsGITHUB_TOKEN). Since these steps only use Issues APIs (createComment,addLabels,removeLabel), restrict the minted token to only the requiredpermission-*(e.g.,permission-issues: write) to reduce blast radius.Applies to the four minting steps at ~849-854, ~925-930, ~1094-1099, and ~1168-1173.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-dispatch.yml around lines 849 - 854, The create-github-app-token steps currently mint installation tokens with full app installation permissions; update each actions/create-github-app-token@v3 invocation to scope the token to the minimal permission needed for the workflow by adding the permission-issues input (e.g., permission-issues: write) so the token only allows Issues API operations (createComment, addLabels, removeLabel); locate each usage of actions/create-github-app-token@v3 in the file and add the permission-issues: write key under with: for those steps..github/workflows/sdd-execute-opus.yml-174-174 (1)
174-174:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPin Actions and the reusable workflow to immutable commit SHAs
actions/github-script@v9,actions/create-github-app-token@v3, andnorrietaylor/spectacles/.github/workflows/sdd-execute-opus.lock.yml@mainare mutable refs; pinning them to full commit SHAs prevents upstream retags/branch moves from changing execution.uses: actions/github-script@v9Also at 814 (
...@main) and 855 (...@v3).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-execute-opus.yml at line 174, The workflow is pinning external actions and a reusable workflow to mutable tags which can change; update the three uses entries (the action identifier strings "actions/github-script@v9", "actions/create-github-app-token@v3", and the reusable workflow reference "norrietaylor/spectacles/.github/workflows/sdd-execute-opus.lock.yml@main") to their corresponding immutable full commit SHAs (replace the `@vX/`@main refs with @<full-commit-sha>) so the workflow consistently executes the exact intended commits; locate and replace each occurrence (the one at the shown line and the other occurrences around lines referenced in the review) ensuring the SHAs come from the exact upstream repository commit you want pinned..github/workflows/sdd-monitor.yml-128-128 (1)
128-128:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPin GitHub Actions to immutable SHAs (and tighten monitor token + ready-task parsing)
- In
.github/workflows/sdd-monitor.yml,actions/create-github-app-token@v3(line 128) andactions/github-script@v9(line 135) use mutable tags—pin to commit SHAs.- The App token minting step doesn’t specify any explicit permission narrowing (only
app-id,private-key,owner,repositories), so it should request least-privilege for what the monitor needs.- The “ready” computation only considers blockers written as
blocked by #<N>(blocked by #(\d+)) and checks them in the same repo; different/cross-repo blocker formats would be ignored (empty blocker set ⇒ treated as “allClosed”), potentially causing premature/dispatchspam.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-monitor.yml at line 128, Pin the GitHub Actions to immutable commit SHAs by replacing uses: actions/create-github-app-token@v3 and uses: actions/github-script@v9 with their exact commit SHAs; in the create-github-app-token step (the App token minting step) add an explicit permissions block requesting least-privilege (e.g., issues: read, contents: read, metadata: read — adjust to the exact minimal scopes the monitor needs) instead of relying only on app-id/private-key/owner/repositories; and tighten the “ready” computation by expanding the blocker regex (currently /blocked by #(\d+)/) to also match cross-repo forms like owner/repo#123 and full issue URLs (e.g., /([\w-]+\/[\w-]+)#(\d+)/ and URL patterns), ensure you resolve and check issues across repos, and change the logic so an empty blocker set does NOT imply allClosed (only mark allClosed when at least one blocker was detected and all detected blockers are closed)..github/workflows/sdd-dispatch.yml-78-78 (1)
78-78:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPin GitHub Actions
uses:references to immutable SHAs/digests (avoid moving@v*tags).In
.github/workflows/sdd-dispatch.yml,uses:referencesactions/github-script@v9andactions/create-github-app-token@v3(e.g., lines 78, 524, 849, 856, 886, 925, 932, 1094, 1101, 1168, 1175). Pin these to immutable SHAs/digests.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-dispatch.yml at line 78, The workflow pins ephemeral action references (e.g., uses: actions/github-script@v9 and uses: actions/create-github-app-token@v3) which should be replaced with their immutable commit SHAs/digests; locate every occurrence of those uses strings in .github/workflows/sdd-dispatch.yml (examples: the lines referencing actions/github-script@v9 and actions/create-github-app-token@v3) and update each to the corresponding full SHA or digest from the action repository (e.g., actions/github-script@<sha>), commit the exact digests so the workflow uses a fixed, immutable version, and verify the workflow still passes..github/workflows/sdd-monitor.yml-126-133 (1)
126-133:⚠️ Potential issue | 🟠 Major | ⚡ Quick winNarrow the GitHub App installation token permissions for the monitor job.
The monitor mints the token via
actions/create-github-app-token@v3but doesn’t pass anypermission-*inputs, so the generated App installation token inherits the App installation’s full permission set (it’s not controlled by the workflowpermissions:block).- name: Mint App token id: app uses: actions/create-github-app-token@v3 with: app-id: ${{ vars.APP_ID }} private-key: ${{ secrets.APP_PRIVATE_KEY }} owner: ${{ github.repository_owner }} repositories: ${{ github.event.repository.name }}Add minimal
permission-*inputs to thewith:block for the mint step (needs read access plus issue-comment write for the/dispatchcomment).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-monitor.yml around lines 126 - 133, The Mint App token step (name: "Mint App token", id: app, uses: actions/create-github-app-token@v3) currently mints an installation token with the App's full installation permissions; add minimal permission-* inputs to the step's with: block to restrict the token (e.g., permission-issues: write for the /dispatch comment and permission-contents: read for repo read access), ensuring only required scopes are granted..github/workflows/sdd-triage-promote-ready.yml-60-60 (1)
60-60:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPin
actions/github-scriptto an immutable commit SHA (avoid@v9)
In.github/workflows/sdd-triage-promote-ready.yml(line 60),uses: actions/github-script@v9uses a mutable tag; pin to the intended v9 release commit SHA. The same unpinned@v9appears in several other workflows too—update them for consistency.🔒 Suggested change
- uses: actions/github-script@v9 + uses: actions/github-script@<full-length-commit-sha>🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-triage-promote-ready.yml at line 60, Replace the mutable action reference "uses: actions/github-script@v9" with the immutable commit SHA for the intended v9 release: fetch the exact commit SHA from the actions/github-script v9 release on GitHub and update the workflow entry to "uses: actions/github-script@<COMMIT_SHA>"; apply the same replacement across all workflows that currently use "`@v9`" to ensure consistency and immutability.
🟡 Minor comments (2)
.github/workflows/sdd-validate.yml-109-126 (1)
109-126:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFail closed when parent-issue lookup errors.
If
github.rest.issues.getfails, the current branch falls through and treats the issue as a tracking issue (Line 125), which can trigger false-positive validation runs.Suggested change
- let parentUrl = ''; + let parentUrl = ''; + let lookupOk = true; try { const { data } = await github.rest.issues.get({ owner: context.repo.owner, repo: context.repo.repo, issue_number: payload.issue.number, }); parentUrl = data.parent_issue_url || ''; } catch (err) { + lookupOk = false; core.info('Could not fetch issue #' + payload.issue.number + ': ' + err.message); } - if (parentUrl) { + if (!lookupOk) { + core.info('Skipping run because parent lookup failed.'); + } else if (parentUrl) { core.info('Issue #' + payload.issue.number + ' has a parent (' + parentUrl + '); not a tracking issue, ignoring.'); } else { run = true;🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-validate.yml around lines 109 - 126, The parent-issue lookup can fail and currently falls through treating the issue as a tracking issue; update the catch block around github.rest.issues.get to fail closed by setting run = false (or otherwise aborting further processing) and log the error with context (use payload.issue.number and parentUrl variables), so that when an exception occurs you do not proceed to set ctx/run for validation; modify the catch that currently calls core.info to also prevent the else-branch from marking the issue as a tracking issue (e.g., set run = false or return) and keep the existing log via core.info..github/workflows/sdd-execute-haiku.yml-481-507 (1)
481-507:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winStop using
parent_issue_urlas a fast-path/router discriminator.In
.github/workflows/sdd-execute-haiku.yml(fast-path-complete detection),isFastpathis gated on!parent_issue_url, butsdd-dispatch.ymldocuments that RESTGET /issues/{n}leaves native sub-issues with an emptyparent_issue_url. That makesparent_issue_urlan unreliable way to distinguish tracking issues from task sub-issues. Normal full-path task merges shouldn’t matchfastpathSignalbecausesdd:in-progress/sdd:dispatchedare applied to tracking issues (tasks getsdd:ready), but the router remains brittle—use a stable discriminator instead (e.g., tracking vs task viamodel:*label presence/absence) rather thanparent_issue_url.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-execute-haiku.yml around lines 481 - 507, The code currently treats an issue as a "tracking" issue by checking parent_issue_url (parentUrl) which is unreliable; change the fast-path discriminator to detect tracking vs task via stable model:* labels instead: after fetching issue labels in the github.rest.issues.get response, compute a boolean like isTracking = labels.includes('model:tracking') (or another agreed stable model label) and replace the existing check that uses parentUrl (the "!parentUrl && fastpathSignal" condition) with "isTracking && fastpathSignal"; remove reliance on parent_issue_url entirely when deciding isFastpath so fast-path detection uses only labels and the existing sdd:in-progress / sdd:dispatched checks.
🧹 Nitpick comments (1)
.github/workflows/sdd-execute-opus.yml (1)
481-507: ⚡ Quick winAvoid relying on REST
parent_issue_urlfor fast-path vs full-path merge routing (use GraphQL parent instead).The
fastpath-completerouting in.github/workflows/sdd-execute-opus.yml(lines 481-507) doesn’t treat!parent_issue_urlas “tracking” by itself: it also requires eithersdd:fastpath/sdd:fastpath-reviewlabels, or (sdd:in-progresspresent ANDsdd:dispatchedabsent). Sincesdd-dispatchappliessdd:in-progress/sdd:dispatchedto the tracking issue (not task sub-issues), a normal full-path task merge is unlikely to satisfyfastpathSignaleven if REST returns an emptyparent_issue_url.However, REST
parent_issue_urlis explicitly unreliable in this repo (GraphQLIssue.parentis treated as authoritative insdd-dispatchdue to issue#133), so using REST here is still fragile. Switch this check to GraphQL (or a label-based tracking invariant such as “nomodel:*”).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/sdd-execute-opus.yml around lines 481 - 507, The code uses the REST field parent_issue_url (via github.rest.issues.get for refNumber) to decide fast-path routing (logic in fastpathSignal using parent_issue_url and labels), which is unreliable; replace the REST parent check with a GraphQL query for the Issue.parent (or alternatively a robust label-only invariant such as detecting absence of any model:* labels) and base the fastpathSignal on that authoritative parent value plus labels; update the block that reads parentUrl and computes fastpathSignal (references: headRef, headMatch, refNumber, github.rest.issues.get, parent_issue_url, fastpathSignal) to fetch Issue.parent via GitHub GraphQL and use that result in place of parent_issue_url (or use the label-based check) before evaluating the fast-path conditional.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/sdd-validate.yml:
- Line 68: The workflow uses non-deterministic action refs; replace the floating
refs `actions/github-script@v9` and
`norrietaylor/spectacles/.github/workflows/sdd-validate.lock.yml@main` with
their corresponding pinned commit SHAs (exact full commit hashes) to ensure
reproducible runs—locate the `uses:` lines in .github/workflows/sdd-validate.yml
and update each `uses:` value to the full git sha for the referenced repository
and path.
---
Major comments:
In @.github/workflows/distillery-sync.yml:
- Line 31: Replace the mutable reference "uses:
norrietaylor/spectacles/.github/workflows/distillery-sync.lock.yml@main" with an
immutable commit SHA: identify the correct commit SHA for
norrietaylor/spectacles (e.g., from the repository's commits for the referenced
workflow file) and update that uses line to reference the SHA instead of `@main`
so the reusable workflow is pinned; ensure the updated line still points to
".github/workflows/distillery-sync.lock.yml@<SHA>" to satisfy the pinned-uses
policy.
In @.github/workflows/sdd-dispatch.yml:
- Around line 849-854: The create-github-app-token steps currently mint
installation tokens with full app installation permissions; update each
actions/create-github-app-token@v3 invocation to scope the token to the minimal
permission needed for the workflow by adding the permission-issues input (e.g.,
permission-issues: write) so the token only allows Issues API operations
(createComment, addLabels, removeLabel); locate each usage of
actions/create-github-app-token@v3 in the file and add the permission-issues:
write key under with: for those steps.
- Line 78: The workflow pins ephemeral action references (e.g., uses:
actions/github-script@v9 and uses: actions/create-github-app-token@v3) which
should be replaced with their immutable commit SHAs/digests; locate every
occurrence of those uses strings in .github/workflows/sdd-dispatch.yml
(examples: the lines referencing actions/github-script@v9 and
actions/create-github-app-token@v3) and update each to the corresponding full
SHA or digest from the action repository (e.g., actions/github-script@<sha>),
commit the exact digests so the workflow uses a fixed, immutable version, and
verify the workflow still passes.
In @.github/workflows/sdd-execute-haiku.yml:
- Line 112: The group expression is using startsWith('/execute') and
startsWith('/revise') which also match tokens like "/executefoo" and "/revisex";
update every occurrence of that token test (the startsWith checks in the group
expression and the similar checks around lines referenced) to use a token-strict
match (e.g. a regex that enforces end-of-token or whitespace such as
matches(github.event.comment.body, '^/execute(\\s|$)') and '^/revise(\\s|$)') so
only exact commands or commands followed by whitespace match and avoid false
positives that join the shared concurrency group.
- Line 174: The workflow uses mutable refs; replace the mutable tags with
immutable commit SHAs: locate the uses entries for actions/github-script@v9,
actions/create-github-app-token@v3, and the
norrietaylor/spectacles.../sdd-execute-haiku.lock.yml@main reference, and update
each to the corresponding full commit SHA (e.g., actions/github-script@<sha>,
actions/create-github-app-token@<sha>,
norrietaylor/spectacles/.../sdd-execute-haiku.lock.yml@<sha>) so the workflow
pins to immutable refs and remains reproducible.
In @.github/workflows/sdd-execute-opus.yml:
- Line 112: The group expression uses startsWith(github.event.comment.body,
'/execute') and '/revise' which also match prefixes like /executefoo; replace
those with token-strict regex matches using the matches operator, e.g. use
github.event.comment.body =~ '^/execute\\b' and github.event.comment.body =~
'^/revise\\b' (and update the same occurrences referenced in the later block
around lines 134-145) so only exact commands or commands followed by
whitespace/word-boundaries trigger the concurrency-group logic.
- Line 174: The workflow is pinning external actions and a reusable workflow to
mutable tags which can change; update the three uses entries (the action
identifier strings "actions/github-script@v9",
"actions/create-github-app-token@v3", and the reusable workflow reference
"norrietaylor/spectacles/.github/workflows/sdd-execute-opus.lock.yml@main") to
their corresponding immutable full commit SHAs (replace the `@vX/`@main refs with
@<full-commit-sha>) so the workflow consistently executes the exact intended
commits; locate and replace each occurrence (the one at the shown line and the
other occurrences around lines referenced in the review) ensuring the SHAs come
from the exact upstream repository commit you want pinned.
In @.github/workflows/sdd-execute-sonnet.yml:
- Line 112: The group expression currently uses startsWith('/execute') and
startsWith('/revise') which also match '/executefoo' and '/revisex'; change
those to token-strict checks by replacing startsWith('/execute') and
startsWith('/revise') with contains(concat(' ', github.event.comment.body, ' '),
' /execute ') and contains(concat(' ', github.event.comment.body, ' '), '
/revise ') respectively (apply same fix to the other occurrence in the
expression block referenced). Update the group expression where
github.event.comment.body is checked so the shared concurrency key only triggers
on exact token matches.
- Line 174: The workflow uses mutable tag refs for third-party actions and a
reusable workflow; find the exact commit SHAs for each referenced resource
(actions/github-script@v9,
norrietaylor/spectacles/.github/workflows/sdd-execute-sonnet.lock.yml@main,
actions/create-github-app-token@v3) and replace the tag refs with their
corresponding full commit SHAs (e.g. actions/github-script@<full-sha>) so the
workflow is pinned immutably; update each `uses:` entry to the SHA form and
optionally add a short comment noting the pinned SHA and original tag for future
maintainers.
In @.github/workflows/sdd-monitor.yml:
- Around line 331-389: The ready-count logic only parses "blocked by `#N`" (in the
block that builds blockerNums from body.matchAll) and thus ignores cross-repo
blockers; update the parser and blocker lookup so it recognizes both "blocked by
`#123`" and "blocked by owner/repo#123" by extracting optional owner and repo plus
the issue number (use the existing body variable and matchAll call but change
the regex and mapping to produce blocker descriptors rather than plain ints),
then when calling github.rest.issues.get use the matched owner/repo if present
or fall back to the current owner/repo variables (keep checking
got.data.pull_request and got.data.state as before); ensure error messages (the
core.info calls in the catch) include the fully qualified blocker identifier and
treat failures as still blocked exactly as existing logic does.
- Line 128: Pin the GitHub Actions to immutable commit SHAs by replacing uses:
actions/create-github-app-token@v3 and uses: actions/github-script@v9 with their
exact commit SHAs; in the create-github-app-token step (the App token minting
step) add an explicit permissions block requesting least-privilege (e.g.,
issues: read, contents: read, metadata: read — adjust to the exact minimal
scopes the monitor needs) instead of relying only on
app-id/private-key/owner/repositories; and tighten the “ready” computation by
expanding the blocker regex (currently /blocked by #(\d+)/) to also match
cross-repo forms like owner/repo#123 and full issue URLs (e.g.,
/([\w-]+\/[\w-]+)#(\d+)/ and URL patterns), ensure you resolve and check issues
across repos, and change the logic so an empty blocker set does NOT imply
allClosed (only mark allClosed when at least one blocker was detected and all
detected blockers are closed).
- Around line 126-133: The Mint App token step (name: "Mint App token", id: app,
uses: actions/create-github-app-token@v3) currently mints an installation token
with the App's full installation permissions; add minimal permission-* inputs to
the step's with: block to restrict the token (e.g., permission-issues: write for
the /dispatch comment and permission-contents: read for repo read access),
ensuring only required scopes are granted.
In @.github/workflows/sdd-pr-sanitize.yml:
- Line 66: The workflow is using a mutable tag "uses: actions/github-script@v9";
replace this with the full 40-character commit SHA for the actions/github-script
action (e.g. "uses: actions/github-script@<40-char-sha> # v9") to pin the
dependency and add the trailing comment to indicate the intended tag; update the
line containing actions/github-script@v9 and mirror the same change for any
other workflows using the same mutable tag.
In @.github/workflows/sdd-review.yml:
- Line 55: The workflow currently references mutable refs (uses:
actions/github-script@v9 and uses:
norrietaylor/spectacles/.github/workflows/sdd-review.lock.yml@main); replace
each mutable tag with the corresponding immutable commit SHA for that
repository/use (pin both actions/github-script and norrietaylor/spectacles
references to their specific commit SHAs) so the workflow and hosted reusable
workflow are fixed to exact commits; update the two uses: entries (the
actions/github-script reference and the norrietaylor/spectacles reusable
workflow reference) to their respective SHAs and commit the change.
In @.github/workflows/sdd-spec.yml:
- Line 88: The workflow uses mutable action refs and mints an overly-broad App
token; replace each mutable `uses:` reference (e.g., actions/github-script@v9,
actions/create-github-app-token@v3,
norrietaylor/spectacles/.github/workflows/sdd-spec.lock.yml@main) with the
corresponding pinned commit SHA for that action, and for the steps that call
`actions/create-github-app-token@v3` narrow the minted installation token by
adding explicit permission scope inputs (and repository list if applicable) so
the token only has the minimum required permissions (e.g., specify permissions
like contents: read or issues: write as needed) and ensure the step uses the
pinned SHA as well.
- Around line 364-369: The GitHub App installation token steps using
actions/create-github-app-token@v3 currently omit explicit permissions and thus
inherit all app permissions; update each "Mint App token" step (the
actions/create-github-app-token@v3 invocation around the existing
app-id/private-key/owner/repositories inputs) to explicitly set
permission-issues: write so the token is least-privilege for the github-script
code that only calls issues.get, issues.listComments, issues.createComment and
issues.addLabels; apply the same change to the duplicate step later in the file.
In @.github/workflows/sdd-triage-dedupe-tasks.yml:
- Around line 102-123: The current dedupe picks `original` solely by normalized
`titleKey` using `isSameTitleEarlierTask`, which can false-match distinct
phase-C tasks; update the matching to compute and compare a stronger fingerprint
(e.g., combine normalized title plus additional distinguishing fields such as
repository identifier, blocker list, and proof-artifact markers parsed from the
issue body/labels) when filtering `siblings` before assigning `original` (adjust
the predicate used in `.filter(...)` instead of `isSameTitleEarlierTask`); apply
the same stronger-fingerprint comparison in the analogous block later (lines
referenced in the review) so we only auto-close a sibling when title plus those
extra fields match.
- Line 40: Replace the mutable tag usage "uses: actions/github-script@v9" with
the full immutable commit SHA for the v9 release (e.g., "uses:
actions/github-script@<full-commit-sha>"); locate the line containing uses:
actions/github-script@v9 in the workflow and update it to reference the
full-length Git commit SHA from the actions/github-script repository to remove
supply-chain risk.
In @.github/workflows/sdd-triage-promote-ready.yml:
- Line 60: Replace the mutable action reference "uses: actions/github-script@v9"
with the immutable commit SHA for the intended v9 release: fetch the exact
commit SHA from the actions/github-script v9 release on GitHub and update the
workflow entry to "uses: actions/github-script@<COMMIT_SHA>"; apply the same
replacement across all workflows that currently use "`@v9`" to ensure consistency
and immutability.
In @.github/workflows/sdd-triage.yml:
- Line 81: Replace the mutable action refs with immutable commit SHAs: locate
the uses entry "uses: actions/github-script@v9" and replace the tag with the
specific commit SHA for the actions/github-script repository, and locate the
reference "norrietaylor/spectacles/.github/workflows/sdd-triage.lock.yml@main"
and replace the branch ref with that repository's exact commit SHA; ensure you
fetch the correct commit SHAs from the respective upstream repos/tags and update
both places so the workflow pins to the immutable SHAs rather than `@v9` or `@main`.
- Around line 89-101: The issue: the 'issues' event handler sets run and ctx for
any label change without ensuring the issue is a top-level tracking issue; to
fix, restrict the labeled/unlabeled checks inside the event === 'issues' branch
to only proceed when the issue is a tracking issue (no parent). Concretely,
inside that branch where action, label, run, and ctx are used, add a guard that
checks the payload.issue is top-level (e.g., !payload.issue.parent or equivalent
field your payload uses to indicate a parent) before evaluating the 'labeled
sdd:triage' or 'unlabeled needs-human' conditions and before setting ctx = {
item_type: 'issue', item_number: payload.issue.number } so sub-issues won't
trigger triage routing.
---
Minor comments:
In @.github/workflows/sdd-execute-haiku.yml:
- Around line 481-507: The code currently treats an issue as a "tracking" issue
by checking parent_issue_url (parentUrl) which is unreliable; change the
fast-path discriminator to detect tracking vs task via stable model:* labels
instead: after fetching issue labels in the github.rest.issues.get response,
compute a boolean like isTracking = labels.includes('model:tracking') (or
another agreed stable model label) and replace the existing check that uses
parentUrl (the "!parentUrl && fastpathSignal" condition) with "isTracking &&
fastpathSignal"; remove reliance on parent_issue_url entirely when deciding
isFastpath so fast-path detection uses only labels and the existing
sdd:in-progress / sdd:dispatched checks.
In @.github/workflows/sdd-validate.yml:
- Around line 109-126: The parent-issue lookup can fail and currently falls
through treating the issue as a tracking issue; update the catch block around
github.rest.issues.get to fail closed by setting run = false (or otherwise
aborting further processing) and log the error with context (use
payload.issue.number and parentUrl variables), so that when an exception occurs
you do not proceed to set ctx/run for validation; modify the catch that
currently calls core.info to also prevent the else-branch from marking the issue
as a tracking issue (e.g., set run = false or return) and keep the existing log
via core.info.
---
Nitpick comments:
In @.github/workflows/sdd-execute-opus.yml:
- Around line 481-507: The code uses the REST field parent_issue_url (via
github.rest.issues.get for refNumber) to decide fast-path routing (logic in
fastpathSignal using parent_issue_url and labels), which is unreliable; replace
the REST parent check with a GraphQL query for the Issue.parent (or
alternatively a robust label-only invariant such as detecting absence of any
model:* labels) and base the fastpathSignal on that authoritative parent value
plus labels; update the block that reads parentUrl and computes fastpathSignal
(references: headRef, headMatch, refNumber, github.rest.issues.get,
parent_issue_url, fastpathSignal) to fetch Issue.parent via GitHub GraphQL and
use that result in place of parent_issue_url (or use the label-based check)
before evaluating the fast-path conditional.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 531e5bcd-15d5-4671-97bb-274f758f9b2e
📒 Files selected for processing (18)
.github/ISSUE_TEMPLATE/bug.md.github/ISSUE_TEMPLATE/chore.md.github/ISSUE_TEMPLATE/feature.md.github/ISSUE_TEMPLATE/spec.md.github/workflows/distillery-sync.yml.github/workflows/sdd-dispatch.yml.github/workflows/sdd-execute-haiku.yml.github/workflows/sdd-execute-opus.yml.github/workflows/sdd-execute-sonnet.yml.github/workflows/sdd-monitor.yml.github/workflows/sdd-pr-sanitize.yml.github/workflows/sdd-review.yml.github/workflows/sdd-spec.yml.github/workflows/sdd-triage-dedupe-tasks.yml.github/workflows/sdd-triage-promote-ready.yml.github/workflows/sdd-triage.yml.github/workflows/sdd-validate.yml.gitignore
| steps: | ||
| - name: Decide whether to run and build aw_context | ||
| id: decide | ||
| uses: actions/github-script@v9 |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify this file has no non-SHA uses refs.
rg -nP '^\s*uses:\s*[^@\s]+@(?!(?:[0-9a-fA-F]{40})\b)[^\s]+' .github/workflows/sdd-validate.yml
# Expected after fix: no outputRepository: gominimal/minimal
Length of output: 186
Pin GitHub Actions/workflow uses refs to commit SHAs in .github/workflows/sdd-validate.yml.
Current non-deterministic refs:
- Line 68:
actions/github-script@v9 - Line 140:
norrietaylor/spectacles/.github/workflows/sdd-validate.lock.yml@main
Suggested change
- uses: actions/github-script@v9
+ uses: actions/github-script@<40-char-commit-sha>
- uses: norrietaylor/spectacles/.github/workflows/sdd-validate.lock.yml@main
+ uses: norrietaylor/spectacles/.github/workflows/sdd-validate.lock.yml@<40-char-commit-sha>🧰 Tools
🪛 zizmor (1.25.2)
[error] 68-68: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/sdd-validate.yml at line 68, The workflow uses
non-deterministic action refs; replace the floating refs
`actions/github-script@v9` and
`norrietaylor/spectacles/.github/workflows/sdd-validate.lock.yml@main` with
their corresponding pinned commit SHAs (exact full commit hashes) to ensure
reproducible runs—locate the `uses:` lines in .github/workflows/sdd-validate.yml
and update each `uses:` value to the full git sha for the referenced repository
and path.
|
Closing this will we tag upstream |
Installs the spectacles agentic workflow agent suite onto this repo via the two-layer distribution model. Wrappers pin hosted reusable workflows at
@main.Direct-to-default-branch writes from
scripts/quick-setup.share blocked by branch protection (PR +buildcheck required), so the file artifacts are delivered as this PR. Labels and repo variables were applied out-of-band (non-branch APIs).Contents
.github/workflows/(8sdd-*agents,distillery-sync,sdd-pr-sanitize,sdd-triage-dedupe-tasks,sdd-triage-promote-ready,sdd-monitor).github/ISSUE_TEMPLATE/.gitignore:.serena/exclusion (Serena working-tree state)Already applied (outside this PR)
needs-human,kind:*,priority:*,sdd:*,model:*,plan:provided)DISTILLERY_PROJECT=minimal,SERENA_LANGUAGE_SERVERS=rust-analyzerOperator config still required
Repo or org level:
APP_ID, optionalSDD_DISPATCH_MAX_PARALLEL(default 5)APP_PRIVATE_KEY,COPILOT_GITHUB_TOKEN,LEAK_DENYLISTDistillery (
DISTILLERY_MCP_URL,DISTILLERY_OAUTH_TOKEN) is provided at the org level.🤖 Generated with Claude Code
Summary by CodeRabbit
Documentation
Chores