@opengsd/gsd-core 1.18.0 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +2 -1
- package/.opencode/plugins/gsd-core.js +2 -3
- package/agents/gsd-code-fixer.compact.md +7 -7
- package/agents/gsd-code-fixer.md +13 -7
- package/agents/gsd-code-reviewer.compact.md +49 -8
- package/agents/gsd-code-reviewer.md +53 -14
- package/agents/gsd-executor.md +8 -4
- package/agents/gsd-verifier.md +1 -1
- package/bin/install.js +422 -103
- package/commands/gsd/update.md +5 -2
- package/gsd-core/bin/gsd-tools.cjs +179 -30
- package/gsd-core/bin/lib/agent-install-check.cjs +29 -3
- package/gsd-core/bin/lib/args-terminator.cjs +114 -0
- package/gsd-core/bin/lib/broken-windows.cjs +59 -1
- package/gsd-core/bin/lib/capability-lifecycle.cjs +1 -12
- package/gsd-core/bin/lib/capability-lock.cjs +13 -2
- package/gsd-core/bin/lib/capability-registry.cjs +376 -103
- package/gsd-core/bin/lib/capability-state.cjs +14 -8
- package/gsd-core/bin/lib/capability-validator.cjs +32 -0
- package/gsd-core/bin/lib/commands.cjs +27 -17
- package/gsd-core/bin/lib/config-loader.cjs +13 -3
- package/gsd-core/bin/lib/config.cjs +256 -58
- package/gsd-core/bin/lib/core-utils.cjs +45 -0
- package/gsd-core/bin/lib/decision-coverage-support.cjs +74 -0
- package/gsd-core/bin/lib/frontmatter.cjs +21 -3
- package/gsd-core/bin/lib/gate-api-coverage-verify-pre.cjs +2 -2
- package/gsd-core/bin/lib/gate-context-drift.cjs +9 -4
- package/gsd-core/bin/lib/gate-decision-coverage-plan.cjs +6 -1
- package/gsd-core/bin/lib/gate-decision-coverage-verify.cjs +6 -1
- package/gsd-core/bin/lib/gate-evaluation-scope.cjs +134 -13
- package/gsd-core/bin/lib/gate-phase-context.cjs +7 -8
- package/gsd-core/bin/lib/gate-schema-drift.cjs +1 -1
- package/gsd-core/bin/lib/gate-tdd-review-checkpoint.cjs +63 -22
- package/gsd-core/bin/lib/gate-ui-safety.cjs +23 -5
- package/gsd-core/bin/lib/git-info-exclude.cjs +52 -0
- package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +31 -12
- package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +9 -7
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +3 -3
- package/gsd-core/bin/lib/health-diagnostic-types.cjs +4 -0
- package/gsd-core/bin/lib/health-diagnostic.cjs +52 -1
- package/gsd-core/bin/lib/host-integration.cjs +13 -6
- package/gsd-core/bin/lib/init.cjs +245 -68
- package/gsd-core/bin/lib/install-engine.cjs +246 -32
- package/gsd-core/bin/lib/install-profiles.cjs +9 -4
- package/gsd-core/bin/lib/installer-migration-report.cjs +2 -0
- package/gsd-core/bin/lib/io.cjs +6 -0
- package/gsd-core/bin/lib/markdown-line-diff.cjs +147 -0
- package/gsd-core/bin/lib/markdown-sectionizer.cjs +147 -1
- package/gsd-core/bin/lib/markdown-table.cjs +23 -0
- package/gsd-core/bin/lib/mcp-server.cjs +8 -5
- package/gsd-core/bin/lib/milestone-lock.cjs +8 -1
- package/gsd-core/bin/lib/milestone-release-map.cjs +244 -0
- package/gsd-core/bin/lib/milestone-release-tags.cjs +440 -0
- package/gsd-core/bin/lib/milestone.cjs +61 -51
- package/gsd-core/bin/lib/model-catalog.cjs +8 -0
- package/gsd-core/bin/lib/normalize-test-command.cjs +67 -0
- package/gsd-core/bin/lib/phase-entry-grammar.cjs +119 -0
- package/gsd-core/bin/lib/phase-id-display.cjs +2 -0
- package/gsd-core/bin/lib/phase-id.cjs +629 -38
- package/gsd-core/bin/lib/phase-lifecycle.cjs +12 -44
- package/gsd-core/bin/lib/phase-locator.cjs +328 -19
- package/gsd-core/bin/lib/phase.cjs +3066 -653
- package/gsd-core/bin/lib/planning-document.cjs +26 -5
- package/gsd-core/bin/lib/planning-inspect.cjs +27 -35
- package/gsd-core/bin/lib/planning-snapshot.cjs +15 -8
- package/gsd-core/bin/lib/planning-workspace.cjs +21 -3
- package/gsd-core/bin/lib/pristine-baseline.cjs +11 -3
- package/gsd-core/bin/lib/read-only-git-env.cjs +79 -0
- package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +2 -2
- package/gsd-core/bin/lib/review-lane-descriptor.cjs +57 -2
- package/gsd-core/bin/lib/review-lane-invocation.cjs +125 -18
- package/gsd-core/bin/lib/review-lane-runner.cjs +33 -4
- package/gsd-core/bin/lib/reviewer-step-dispatch.cjs +11 -9
- package/gsd-core/bin/lib/roadmap-parser.cjs +735 -137
- package/gsd-core/bin/lib/roadmap-progress.cjs +136 -0
- package/gsd-core/bin/lib/roadmap-upgrade.cjs +47 -7
- package/gsd-core/bin/lib/roadmap.cjs +383 -123
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +381 -14
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +8 -4
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +60 -16
- package/gsd-core/bin/lib/shell-command-projection.cjs +151 -19
- package/gsd-core/bin/lib/smart-entry.cjs +35 -11
- package/gsd-core/bin/lib/state-contract.cjs +39 -15
- package/gsd-core/bin/lib/state-document.cjs +344 -27
- package/gsd-core/bin/lib/state-transition.cjs +156 -32
- package/gsd-core/bin/lib/state.cjs +527 -186
- package/gsd-core/bin/lib/surface.cjs +9 -0
- package/gsd-core/bin/lib/task-command-router.cjs +5 -25
- package/gsd-core/bin/lib/task-content-resolution.cjs +46 -1
- package/gsd-core/bin/lib/template.cjs +2 -2
- package/gsd-core/bin/lib/validate.cjs +3 -2
- package/gsd-core/bin/lib/vendor/re2js.cjs +863 -577
- package/gsd-core/bin/lib/vendor/re2js.d.cts +284 -219
- package/gsd-core/bin/lib/verification.cjs +96 -9
- package/gsd-core/bin/lib/verify.cjs +4 -2
- package/gsd-core/bin/lib/workstream-inventory.cjs +26 -20
- package/gsd-core/bin/lib/worktree-safety.cjs +22 -1
- package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +1 -0
- package/gsd-core/bin/verify-reapply-patches.cjs +411 -10
- package/gsd-core/references/cicd-review-patterns.md +45 -0
- package/gsd-core/references/git-integration.md +11 -0
- package/gsd-core/references/loop-hook-dispatch.md +13 -6
- package/gsd-core/references/necessity-review.md +48 -0
- package/gsd-core/references/planning-config.md +2 -0
- package/gsd-core/references/tdd.md +2 -2
- package/gsd-core/templates/DEBUG.md +16 -0
- package/gsd-core/templates/config.json +2 -1
- package/gsd-core/templates/verification-report.md +1 -1
- package/gsd-core/workflows/audit-fix.md +2 -1
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +10 -1
- package/gsd-core/workflows/code-review-fix.md +46 -5
- package/gsd-core/workflows/code-review.md +64 -7
- package/gsd-core/workflows/complete-milestone/steps/project-md-evolution-review.md +145 -0
- package/gsd-core/workflows/complete-milestone/steps/release-map.md +80 -0
- package/gsd-core/workflows/complete-milestone.md +37 -150
- package/gsd-core/workflows/diagnose-issues.md +29 -5
- package/gsd-core/workflows/discuss-phase/modes/power.md +1 -1
- package/gsd-core/workflows/discuss-phase-assumptions.md +33 -2
- package/gsd-core/workflows/discuss-phase-power.md +19 -2
- package/gsd-core/workflows/discuss-phase.md +6 -10
- package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +13 -7
- package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +7 -2
- package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +2 -1
- package/gsd-core/workflows/execute-phase/steps/verify-phase-goal.md +2 -2
- package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +11 -2
- package/gsd-core/workflows/execute-phase.md +10 -6
- package/gsd-core/workflows/execute-plan.md +1 -1
- package/gsd-core/workflows/health.md +2 -1
- package/gsd-core/workflows/import.md +1 -1
- package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +2 -2
- package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +13 -9
- package/gsd-core/workflows/plan-phase.md +14 -14
- package/gsd-core/workflows/pr-branch.md +2 -0
- package/gsd-core/workflows/quick/steps/plan-checker-loop.md +1 -1
- package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +8 -1
- package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +2 -1
- package/gsd-core/workflows/quick.md +1 -1
- package/gsd-core/workflows/reapply-patches.md +104 -0
- package/gsd-core/workflows/review.md +70 -154
- package/gsd-core/workflows/section-manifest.json +5 -0
- package/gsd-core/workflows/secure-phase.md +1 -1
- package/gsd-core/workflows/settings-advanced.md +57 -9
- package/gsd-core/workflows/settings.md +1 -0
- package/gsd-core/workflows/ship.md +15 -4
- package/gsd-core/workflows/spec-phase.md +3 -6
- package/gsd-core/workflows/verify-work.md +4 -3
- package/hooks/dist/gsd-agent-isolation-guard.js +11 -1
- package/hooks/dist/gsd-cursor-subagent-start.js +6 -2
- package/hooks/dist/gsd-graphify-update.sh +6 -0
- package/hooks/dist/gsd-path-export.js +95 -0
- package/hooks/dist/gsd-secret-read-guard.js +172 -39
- package/hooks/dist/gsd-statusline.js +37 -3
- package/hooks/dist/gsd-windsurf-pre-write.js +29 -2
- package/hooks/dist/gsd-workflow-guard.js +3 -2
- package/hooks/dist/gsd-worktree-path-guard.js +29 -2
- package/hooks/dist/lib/git-probe.js +16 -0
- package/hooks/dist/lib/isolation-sentinel.js +44 -0
- package/hooks/dist/managed-hooks-registry.cjs +1 -0
- package/hooks/gsd-agent-isolation-guard.js +11 -1
- package/hooks/gsd-cursor-subagent-start.js +6 -2
- package/hooks/gsd-graphify-update.sh +6 -0
- package/hooks/gsd-path-export.js +95 -0
- package/hooks/gsd-secret-read-guard.js +172 -39
- package/hooks/gsd-statusline.js +37 -3
- package/hooks/gsd-windsurf-pre-write.js +29 -2
- package/hooks/gsd-workflow-guard.js +3 -2
- package/hooks/gsd-worktree-path-guard.js +29 -2
- package/hooks/hooks.json +1 -0
- package/hooks/lib/git-probe.js +16 -0
- package/hooks/lib/isolation-sentinel.js +44 -0
- package/hooks/managed-hooks-registry.cjs +1 -0
- package/package.json +15 -8
- package/pi/gsd.cjs +1047 -10
- package/pi/package-agents/gsd-advisor-researcher.md +113 -0
- package/pi/package-agents/gsd-ai-researcher.md +111 -0
- package/pi/package-agents/gsd-assumptions-analyzer.md +110 -0
- package/pi/package-agents/gsd-code-fixer.md +774 -0
- package/pi/package-agents/gsd-code-reviewer.md +441 -0
- package/pi/package-agents/gsd-codebase-mapper.md +850 -0
- package/pi/package-agents/gsd-debug-session-manager.md +416 -0
- package/pi/package-agents/gsd-debugger.md +1274 -0
- package/pi/package-agents/gsd-doc-classifier.md +269 -0
- package/pi/package-agents/gsd-doc-synthesizer.md +259 -0
- package/pi/package-agents/gsd-doc-verifier.md +212 -0
- package/pi/package-agents/gsd-doc-writer.md +626 -0
- package/pi/package-agents/gsd-dom-verifier.md +164 -0
- package/pi/package-agents/gsd-domain-researcher.md +144 -0
- package/pi/package-agents/gsd-eval-auditor.md +185 -0
- package/pi/package-agents/gsd-eval-planner.md +149 -0
- package/pi/package-agents/gsd-executor.md +898 -0
- package/pi/package-agents/gsd-framework-selector.md +159 -0
- package/pi/package-agents/gsd-integration-checker.md +476 -0
- package/pi/package-agents/gsd-intel-updater.md +338 -0
- package/pi/package-agents/gsd-mempalace-curator.md +49 -0
- package/pi/package-agents/gsd-nyquist-auditor.md +200 -0
- package/pi/package-agents/gsd-pattern-mapper.md +340 -0
- package/pi/package-agents/gsd-phase-researcher.md +897 -0
- package/pi/package-agents/gsd-plan-checker.md +1077 -0
- package/pi/package-agents/gsd-planner.md +1003 -0
- package/pi/package-agents/gsd-project-researcher.md +611 -0
- package/pi/package-agents/gsd-research-synthesizer.md +259 -0
- package/pi/package-agents/gsd-roadmapper.md +779 -0
- package/pi/package-agents/gsd-security-auditor.md +171 -0
- package/pi/package-agents/gsd-ui-auditor.md +581 -0
- package/pi/package-agents/gsd-ui-checker.md +417 -0
- package/pi/package-agents/gsd-ui-researcher.md +469 -0
- package/pi/package-agents/gsd-user-profiler.md +174 -0
- package/pi/package-agents/gsd-verifier.md +963 -0
- package/pi/package-agents/manifest.json +39 -0
- package/pi/package-skills/gsd-add-tests/SKILL.md +39 -0
- package/pi/package-skills/gsd-ai-integration-phase/SKILL.md +36 -0
- package/pi/package-skills/gsd-audit-fix/SKILL.md +34 -0
- package/pi/package-skills/gsd-audit-milestone/SKILL.md +40 -0
- package/pi/package-skills/gsd-audit-uat/SKILL.md +26 -0
- package/pi/package-skills/gsd-autonomous/SKILL.md +52 -0
- package/pi/package-skills/gsd-capture/SKILL.md +68 -0
- package/pi/package-skills/gsd-cleanup/SKILL.md +25 -0
- package/pi/package-skills/gsd-code-review/SKILL.md +71 -0
- package/pi/package-skills/gsd-complete-milestone/SKILL.md +147 -0
- package/pi/package-skills/gsd-config/SKILL.md +60 -0
- package/pi/package-skills/gsd-debug/SKILL.md +64 -0
- package/pi/package-skills/gsd-discuss-phase/SKILL.md +74 -0
- package/pi/package-skills/gsd-docs-update/SKILL.md +50 -0
- package/pi/package-skills/gsd-eval-review/SKILL.md +35 -0
- package/pi/package-skills/gsd-execute-phase/SKILL.md +62 -0
- package/pi/package-skills/gsd-explore/SKILL.md +26 -0
- package/pi/package-skills/gsd-extract-learnings/SKILL.md +25 -0
- package/pi/package-skills/gsd-fast/SKILL.md +33 -0
- package/pi/package-skills/gsd-forensics/SKILL.md +59 -0
- package/pi/package-skills/gsd-graphify/SKILL.md +210 -0
- package/pi/package-skills/gsd-health/SKILL.md +36 -0
- package/pi/package-skills/gsd-help/SKILL.md +37 -0
- package/pi/package-skills/gsd-import/SKILL.md +46 -0
- package/pi/package-skills/gsd-inbox/SKILL.md +42 -0
- package/pi/package-skills/gsd-ingest-docs/SKILL.md +43 -0
- package/pi/package-skills/gsd-manager/SKILL.md +46 -0
- package/pi/package-skills/gsd-map-codebase/SKILL.md +85 -0
- package/pi/package-skills/gsd-mempalace-capture/SKILL.md +111 -0
- package/pi/package-skills/gsd-mempalace-recall/SKILL.md +111 -0
- package/pi/package-skills/gsd-milestone-summary/SKILL.md +54 -0
- package/pi/package-skills/gsd-mvp-phase/SKILL.md +45 -0
- package/pi/package-skills/gsd-new-milestone/SKILL.md +49 -0
- package/pi/package-skills/gsd-new-project/SKILL.md +49 -0
- package/pi/package-skills/gsd-next/SKILL.md +34 -0
- package/pi/package-skills/gsd-ns-context/SKILL.md +31 -0
- package/pi/package-skills/gsd-ns-ideate/SKILL.md +30 -0
- package/pi/package-skills/gsd-ns-manage/SKILL.md +42 -0
- package/pi/package-skills/gsd-ns-project/SKILL.md +34 -0
- package/pi/package-skills/gsd-ns-review/SKILL.md +35 -0
- package/pi/package-skills/gsd-ns-workflow/SKILL.md +44 -0
- package/pi/package-skills/gsd-onboard/SKILL.md +46 -0
- package/pi/package-skills/gsd-pause-work/SKILL.md +48 -0
- package/pi/package-skills/gsd-phase/SKILL.md +61 -0
- package/pi/package-skills/gsd-plan-phase/SKILL.md +62 -0
- package/pi/package-skills/gsd-plan-review-convergence/SKILL.md +63 -0
- package/pi/package-skills/gsd-pr-branch/SKILL.md +31 -0
- package/pi/package-skills/gsd-profile-user/SKILL.md +48 -0
- package/pi/package-skills/gsd-progress/SKILL.md +51 -0
- package/pi/package-skills/gsd-quick/SKILL.md +179 -0
- package/pi/package-skills/gsd-quick-batch/SKILL.md +114 -0
- package/pi/package-skills/gsd-resume-work/SKILL.md +31 -0
- package/pi/package-skills/gsd-review/SKILL.md +50 -0
- package/pi/package-skills/gsd-review-backlog/SKILL.md +65 -0
- package/pi/package-skills/gsd-secure-phase/SKILL.md +37 -0
- package/pi/package-skills/gsd-settings/SKILL.md +30 -0
- package/pi/package-skills/gsd-ship/SKILL.md +27 -0
- package/pi/package-skills/gsd-sketch/SKILL.md +56 -0
- package/pi/package-skills/gsd-spec-phase/SKILL.md +63 -0
- package/pi/package-skills/gsd-spike/SKILL.md +53 -0
- package/pi/package-skills/gsd-stats/SKILL.md +22 -0
- package/pi/package-skills/gsd-surface/SKILL.md +177 -0
- package/pi/package-skills/gsd-thread/SKILL.md +29 -0
- package/pi/package-skills/gsd-ui-phase/SKILL.md +35 -0
- package/pi/package-skills/gsd-ui-review/SKILL.md +35 -0
- package/pi/package-skills/gsd-ultraplan-phase/SKILL.md +38 -0
- package/pi/package-skills/gsd-undo/SKILL.md +38 -0
- package/pi/package-skills/gsd-update/SKILL.md +54 -0
- package/pi/package-skills/gsd-validate-phase/SKILL.md +37 -0
- package/pi/package-skills/gsd-verify-work/SKILL.md +41 -0
- package/pi/package-skills/gsd-workspace/SKILL.md +57 -0
- package/pi/package-skills/gsd-workstreams/SKILL.md +73 -0
- package/scripts/build-hooks.js +4 -0
- package/scripts/ci-next-health.cjs +246 -23
- package/scripts/command-contract-helpers.cjs +1 -1
- package/scripts/docs-guard-registry.cjs +22 -7
- package/scripts/gen-features.cjs +14 -2
- package/scripts/gen-health-docs.cjs +13 -1
- package/scripts/gen-pi-package-skills.cjs +217 -0
- package/scripts/lib/drift-scan.cjs +27 -0
- package/scripts/lib/macos-conformance-tier.generated.cjs +17 -1
- package/scripts/lib/platform-conformance-tier.generated.cjs +37 -1
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +3 -3
- package/scripts/lint-phase-enumeration-drift.cjs +8 -4
- package/scripts/lint-retired-runtime-name.cjs +5 -0
- package/scripts/lint-roadmap-progress-drift.cjs +421 -0
- package/scripts/mutation-matrix.cjs +23 -1
- package/scripts/npm-audit-baseline.cjs +41 -7
- package/scripts/reviewed-or-maintainer-policy.cjs +181 -0
- package/scripts/select-docs-guards.cjs +1 -1
- package/scripts/self-test-report-policy.cjs +350 -0
- package/scripts/sync-next-version.cjs +38 -6
- package/skills/gsd-update/SKILL.md +5 -2
- package/vscode/package.json +1 -1
- package/scripts/diagnose-validate-commit-in-tier.cjs +0 -270
- package/scripts/diagnose-validate-commit-phases.cjs +0 -348
- package/scripts/xtrace-phase-timing.cjs +0 -205
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gsd-core",
|
|
3
3
|
"displayName": "GSD Core",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.20.0",
|
|
5
5
|
"description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "open-gsd",
|
|
@@ -18,5 +18,6 @@
|
|
|
18
18
|
"claude-code",
|
|
19
19
|
"gsd"
|
|
20
20
|
],
|
|
21
|
+
"commands": [],
|
|
21
22
|
"skills": "./skills/"
|
|
22
23
|
}
|
|
@@ -365,7 +365,7 @@ function handleHookResult(hookResult, output) {
|
|
|
365
365
|
throw new Error(reason);
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
-
// Advisory: inject additionalContext into metadata
|
|
368
|
+
// Advisory: inject additionalContext into metadata
|
|
369
369
|
const advisory =
|
|
370
370
|
parsed &&
|
|
371
371
|
parsed.hookSpecificOutput &&
|
|
@@ -382,8 +382,7 @@ function handleHookResult(hookResult, output) {
|
|
|
382
382
|
}
|
|
383
383
|
output.metadata._gsdAdvisory.push(advisory);
|
|
384
384
|
}
|
|
385
|
-
//
|
|
386
|
-
console.error(advisory);
|
|
385
|
+
// Not written to stderr: the OpenCode TUI draws a plugin's stderr over the prompt input (#5648).
|
|
387
386
|
// >>> gsd:opencode-parity
|
|
388
387
|
deliverAdvisory(advisory, output);
|
|
389
388
|
// <<< gsd:opencode-parity
|
|
@@ -73,12 +73,12 @@ After applying each fix:
|
|
|
73
73
|
| Language | Check Command |
|
|
74
74
|
|----------|--------------|
|
|
75
75
|
| JavaScript | `node -c {file}` (syntax check) |
|
|
76
|
-
| TypeScript | `npx tsc --noEmit {file}`
|
|
76
|
+
| TypeScript | Project-aware check only, output filtered to `{file}`: the project's own typecheck (`npm run typecheck` / `tsc -b`) if it exists, else `npx tsc --noEmit -p <nearest tsconfig*.json>` whose `--listFilesOnly` output lists `{file}`; no config includes `{file}` → Tier 1 only. Never pass `{file}` to `tsc` positionally. |
|
|
77
77
|
| Python | `python -c "import ast; ast.parse(open('{file}').read())"` |
|
|
78
78
|
| JSON | `node -e "JSON.parse(require('fs').readFileSync('{file}','utf-8'))"` |
|
|
79
79
|
| Other | Skip to Tier 1 only |
|
|
80
80
|
|
|
81
|
-
**Scoping:** TypeScript errors in OTHER files are pre-existing — IGNORE; only fail on errors in the file you edited. `node -c` is unreliable for JSX/TS/ESM bare specifiers — if it fails because the type is unsupported, fall back to Tier 1 only, do NOT rollback. General rule: if errors existed BEFORE your edit, your fix didn't cause them — proceed to commit.
|
|
81
|
+
**Scoping:** TypeScript errors in OTHER files are pre-existing — IGNORE; only fail on errors in the file you edited. A solution-style root `tsconfig.json` (`"files": []` plus `references`) checks no source files and exits 0 — NOT a passing check; use a referenced config whose `--listFilesOnly` lists `{file}`, or fall back to Tier 1. TypeScript procedure: prefer a `typecheck` script in the nearest `package.json`; else walk up from `{file}` to the nearest `tsconfig.json` (solution-style: try each referenced config in turn), run from that config's directory `npx tsc --noEmit -p <config> --listFilesOnly` and keep the first config listing `{file}` (none → Tier 1), then `npx tsc --noEmit -p <config>` (never `-b`: no build artifacts) keeping only output lines for `{file}`; roll back only for errors on lines you changed, otherwise treat as pre-existing and proceed. `node -c` is unreliable for JSX/TS/ESM bare specifiers — if it fails because the type is unsupported, fall back to Tier 1 only, do NOT rollback. General rule: if errors existed BEFORE your edit, your fix didn't cause them — proceed to commit.
|
|
82
82
|
|
|
83
83
|
- Syntax check FAILS with NEW errors in your file → rollback_strategy immediately.
|
|
84
84
|
- FAILS with pre-existing errors only → proceed to commit.
|
|
@@ -256,17 +256,17 @@ Treat this as a finally-block obligation: even on early exit (config error, no f
|
|
|
256
256
|
|
|
257
257
|
<step name="load_context">
|
|
258
258
|
1. Read all `<required_reading>` files if present.
|
|
259
|
-
2. Parse `<config>` block: `phase_dir`, `padded_phase`, `review_path` (full path to REVIEW.md), `fix_scope` ("critical_warning" default, or "all" includes Info), `fix_report_path` (output REVIEW-FIX.md path).
|
|
259
|
+
2. Parse `<config>` block: `phase_dir`, `padded_phase`, `review_path` (full path to REVIEW.md), `fix_scope` ("critical_warning" default, or "all" includes Info and necessity), `fix_report_path` (output REVIEW-FIX.md path).
|
|
260
260
|
3. `cat {review_path}`.
|
|
261
261
|
4. Parse frontmatter `status:`. If `"clean"` or `"skipped"`: exit with "No issues to fix -- REVIEW.md status is {status}." — do NOT create REVIEW-FIX.md, exit 0 (not an error).
|
|
262
262
|
5. Load project context (`<project_context>`): CLAUDE.md, skills.
|
|
263
263
|
</step>
|
|
264
264
|
|
|
265
265
|
<step name="parse_findings">
|
|
266
|
-
1. Extract findings via `<finding_parser>` rules: `id`, `severity` (Critical CR-*/BL-*, Warning WR-*, Info IN-*), `title`, `file` (primary), `files` (all referenced, for multi-file fixes), `line` (or null), `issue`, `fix` (may be multi-line/code fences).
|
|
267
|
-
2. Filter by `fix_scope`: `critical_warning` → CR-*/BL-*/WR-* only; `all` → + IN
|
|
268
|
-
3. Sort: Critical first, then Warning, then Info; same-severity keeps document order.
|
|
269
|
-
4. Record `findings_in_scope` count for frontmatter.
|
|
266
|
+
1. Extract findings via `<finding_parser>` rules: `id`, `severity` (Critical CR-*/BL-*, Warning WR-*, Info IN-*), `category` (`necessity` when the finding carries a `**Category:** necessity` line, #4100 — unnecessary code, not broken code), `title`, `file` (primary), `files` (all referenced, for multi-file fixes), `line` (or null), `issue`, `fix` (may be multi-line/code fences).
|
|
267
|
+
2. Filter by `fix_scope`: `critical_warning` → CR-*/BL-*/WR-* only, and `critical_warning` excludes necessity findings (removal is the human's scope call; the marker overrides the prefix, so a WR-* carrying `**Category:** necessity` is out of scope and skipped with no edit); `all` → + IN-*, and `all` includes necessity findings, ordered last — record each as `fixed: requires human verification`.
|
|
268
|
+
3. Sort: Critical first, then Warning, then Info, then necessity; same-severity keeps document order.
|
|
269
|
+
4. Record `findings_in_scope` count for frontmatter. If `findings_in_scope` is 0, apply nothing: write REVIEW-FIX.md with `fixed: 0`, `skipped: 0`, `status: all_fixed`, and a body stating no finding was in scope and the out-of-scope findings remain in REVIEW.md.
|
|
270
270
|
</step>
|
|
271
271
|
|
|
272
272
|
<step name="apply_fixes">
|
package/agents/gsd-code-fixer.md
CHANGED
|
@@ -110,13 +110,14 @@ Run syntax/parse check appropriate to file type:
|
|
|
110
110
|
| Language | Check Command |
|
|
111
111
|
|----------|--------------|
|
|
112
112
|
| JavaScript | `node -c {file}` (syntax check) |
|
|
113
|
-
| TypeScript | `npx tsc --noEmit {file}`
|
|
113
|
+
| TypeScript | Project-aware check only, output filtered to `{file}`: the project's own typecheck (`npm run typecheck` / `tsc -b`) if it exists, else `npx tsc --noEmit -p <nearest tsconfig*.json>` whose `--listFilesOnly` output lists `{file}`; no config includes `{file}` → Tier 1 only. Never pass `{file}` to `tsc` positionally. |
|
|
114
114
|
| Python | `python -c "import ast; ast.parse(open('{file}').read())"` |
|
|
115
115
|
| JSON | `node -e "JSON.parse(require('fs').readFileSync('{file}','utf-8'))"` |
|
|
116
116
|
| Other | Skip to Tier 1 only |
|
|
117
117
|
|
|
118
118
|
**Scoping syntax checks:**
|
|
119
|
-
- TypeScript:
|
|
119
|
+
- TypeScript: Run the project-aware check from the table above. If it reports errors in OTHER files (not the file you just edited), those are pre-existing project errors — **IGNORE them**. Only fail if errors reference the specific file you modified. A solution-style root `tsconfig.json` (`"files": []` plus `references`) checks no source files and exits 0, so it is NOT a passing check: use a referenced config whose `--listFilesOnly` output includes `{file}`, or fall back to Tier 1.
|
|
120
|
+
- TypeScript procedure: (1) Look for a `typecheck` script in the nearest `package.json` and prefer it. (2) Otherwise start at `{file}`'s directory and walk up to the nearest `tsconfig.json`; if it is solution-style, take each config it references (e.g. `tsconfig.app.json`, `tsconfig.node.json`) and try them in turn. (3) Run from the config's own directory with `npx tsc --noEmit -p <config> --listFilesOnly` and keep the first config whose listing includes `{file}`; if none does, fall back to Tier 1. (4) Run `npx tsc --noEmit -p <config>` (use `-p`, never `-b`, so no build artifacts or `.tsbuildinfo` files are written) and keep only output lines that start with `{file}`'s path as `tsc` prints it relative to that directory. (5) Roll back only for errors on lines you changed; errors you cannot attribute to your edit are pre-existing — fall back to Tier 1 and proceed.
|
|
120
121
|
- JavaScript: `node -c {file}` is reliable for plain .js but NOT for JSX, TypeScript, or ESM with bare specifiers. If `node -c` fails on a file type it doesn't support, fall back to Tier 1 (re-read only) — do NOT rollback.
|
|
121
122
|
- General rule: If a syntax check produces errors that existed BEFORE your edit (compare with pre-fix state), the fix did not introduce them. Proceed to commit.
|
|
122
123
|
|
|
@@ -157,6 +158,8 @@ Each finding starts with:
|
|
|
157
158
|
|
|
158
159
|
Where ID matches: `CR-\d+` or `BL-\d+` (Critical-tier-equivalent), `WR-\d+` (Warning), or `IN-\d+` (Info)
|
|
159
160
|
|
|
161
|
+
A finding whose body carries a `**Category:** necessity` line is a **necessity finding** (#4100): code the reviewer judged unnecessary, not broken. Its prefix still gives its severity.
|
|
162
|
+
|
|
160
163
|
**Required Fields:**
|
|
161
164
|
|
|
162
165
|
- **File:** line contains primary file path
|
|
@@ -438,7 +441,7 @@ This cleanup is unconditional when a worktree was created — register it mental
|
|
|
438
441
|
- `phase_dir`: Path to phase directory (e.g., `.planning/phases/02-code-review-command`)
|
|
439
442
|
- `padded_phase`: Zero-padded phase number (e.g., "02")
|
|
440
443
|
- `review_path`: Full path to REVIEW.md (e.g., `.planning/phases/02-code-review-command/02-REVIEW.md`)
|
|
441
|
-
- `fix_scope`: "critical_warning" (default) or "all" (includes Info findings)
|
|
444
|
+
- `fix_scope`: "critical_warning" (default) or "all" (includes Info and necessity findings)
|
|
442
445
|
- `fix_report_path`: Full path for REVIEW-FIX.md output (e.g., `.planning/phases/02-code-review-command/02-REVIEW-FIX.md`)
|
|
443
446
|
|
|
444
447
|
**3. Read REVIEW.md:**
|
|
@@ -464,6 +467,7 @@ Read `./CLAUDE.md` and check for `.claude/skills/` or `.agents/skills/` (as desc
|
|
|
464
467
|
For each finding, extract:
|
|
465
468
|
- `id`: Finding identifier (e.g., CR-01, WR-03, IN-12)
|
|
466
469
|
- `severity`: Critical (CR-* or BL-*), Warning (WR-*), Info (IN-*)
|
|
470
|
+
- `category`: `necessity` when the finding carries a `**Category:** necessity` line, otherwise none
|
|
467
471
|
- `title`: Issue title from `### ` heading
|
|
468
472
|
- `file`: Primary file path from **File:** line
|
|
469
473
|
- `files`: ALL file paths referenced in finding (including in Fix section) — for multi-file fixes
|
|
@@ -472,15 +476,17 @@ For each finding, extract:
|
|
|
472
476
|
- `fix`: Full fix content from **Fix:** section (may be multi-line, may contain code fences)
|
|
473
477
|
|
|
474
478
|
**2. Filter by fix_scope:**
|
|
475
|
-
- If `fix_scope == "critical_warning"`: include only CR-*, BL-*, and WR-* findings
|
|
476
|
-
- If `fix_scope == "all"`: include CR-*, BL-*, WR-*, and IN-* findings
|
|
479
|
+
- If `fix_scope == "critical_warning"`: include only CR-*, BL-*, and WR-* findings; `critical_warning` excludes necessity findings (removing code is a scope decision for the human, #4100). The marker overrides the prefix: a WR-* finding carrying `**Category:** necessity` is OUT of scope here, and is skipped without applying any edit
|
|
480
|
+
- If `fix_scope == "all"`: include CR-*, BL-*, WR-*, and IN-* findings; `all` includes necessity findings, ordered last. A necessity fix removes code, so record it as `fixed: requires human verification`
|
|
477
481
|
|
|
478
482
|
**3. Sort findings by severity:**
|
|
479
|
-
- Critical (CR-* and BL-*) first, then Warning, then Info
|
|
483
|
+
- Critical (CR-* and BL-*) first, then Warning, then Info, then necessity findings
|
|
480
484
|
- Within same severity, maintain document order
|
|
481
485
|
|
|
482
486
|
**4. Count findings in scope:**
|
|
483
487
|
Record `findings_in_scope` for REVIEW-FIX.md frontmatter.
|
|
488
|
+
|
|
489
|
+
If `findings_in_scope` is 0, apply nothing: write REVIEW-FIX.md with `fixed: 0`, `skipped: 0`, `status: all_fixed`, and a body stating that no finding was in scope and the out-of-scope findings remain in REVIEW.md.
|
|
484
490
|
</step>
|
|
485
491
|
|
|
486
492
|
<step name="apply_fixes">
|
|
@@ -701,7 +707,7 @@ main checkout after teardown).
|
|
|
701
707
|
|
|
702
708
|
**DO verify each fix** using 3-tier verification strategy:
|
|
703
709
|
- Minimum: re-read file, confirm fix present
|
|
704
|
-
- Preferred: syntax check (node -c, tsc
|
|
710
|
+
- Preferred: syntax check (node -c, project-aware tsc -p, python ast.parse, etc.)
|
|
705
711
|
- Fallback: accept minimum if no syntax checker available
|
|
706
712
|
|
|
707
713
|
**DO skip findings that cannot be applied cleanly** — do not force broken fixes. Mark as skipped with clear reason.
|
|
@@ -49,6 +49,8 @@ Read `./CLAUDE.md` if present — follow project guidelines, security requiremen
|
|
|
49
49
|
|
|
50
50
|
**3. Code Quality** — dead code, unused imports/variables, poor naming, missing error handling, inconsistent patterns, overly complex functions (high cyclomatic complexity), code duplication, magic numbers, commented-out code
|
|
51
51
|
|
|
52
|
+
**4. Necessity** (#4100) — reachable code whose guarded-against problem cannot occur in this stack: impossible-state guard, already-defended-elsewhere, cargo-culted pattern, phantom requirement, generality without instantiation. At `standard`/`deep`, Read `~/.claude/gsd-core/references/necessity-review.md` before classifying; if unreadable, say so in the Summary and omit `necessity:`. `quick` does not assess necessity. Warning when provable from the repo, Info when judgment, Never Critical; cite the evidence the state cannot occur and add a `**Category:** necessity` line.
|
|
53
|
+
|
|
52
54
|
**Out of Scope (v1):** performance issues (O(n²) algorithms, memory leaks, inefficient queries) — NOT in scope. Focus on correctness, security, maintainability.
|
|
53
55
|
|
|
54
56
|
</review_scope>
|
|
@@ -56,10 +58,12 @@ Read `./CLAUDE.md` if present — follow project guidelines, security requiremen
|
|
|
56
58
|
<depth_levels>
|
|
57
59
|
|
|
58
60
|
**quick** — pattern-matching only, grep/regex scan for common anti-patterns, no full file reads. Target: <2 min.
|
|
59
|
-
|
|
61
|
+
Checks (commands in `review_by_depth`): Hardcoded secrets; Dangerous functions; Debug artifacts; Empty catch blocks; Commented-out code; Unpinned actions; Non-idempotent install; Missing job timeout.
|
|
62
|
+
The last three: GitHub Actions workflows only.
|
|
60
63
|
|
|
61
64
|
**standard** (default) — Read each changed file, check bugs/security/quality in context, cross-reference imports/exports. Target: 5-15 min.
|
|
62
65
|
Language-aware checks: **JS/TS** unchecked `.length`, missing `await`, unhandled promise rejection, `as any`, `==` vs `===`, null coalescing issues. **Python** bare `except:`, mutable default args, f-string injection, `eval()`, missing `with` for file ops. **Go** unchecked error returns, goroutine leaks, context not passed, `defer` in loops, race conditions. **C/C++** buffer overflow patterns, use-after-free, null pointer deref, missing bounds checks, memory leaks. **Shell** unquoted variables, `eval`, missing `set -e`, command injection via interpolation.
|
|
66
|
+
**CI/CD pipelines** (by path: `.github/workflows/*.yml`, `Dockerfile*`, `docker-compose*.yml`, deploy scripts): Read `~/.claude/gsd-core/references/cicd-review-patterns.md`; if it cannot be read, say so in the Summary and check: non-idempotent steps (`npm install` vs `npm ci`, unlocked `pip install`, unguarded `mkdir`/`rm`), no job `timeout-minutes`, deploy without `concurrency` + `cancel-in-progress`, per-environment rebuild (not build-once), no health check or rollback, load-bearing `continue-on-error`, static credentials where OIDC works, unpinned actions.
|
|
63
67
|
|
|
64
68
|
**deep** — all of standard + cross-file analysis: trace call chains across imports, check type consistency at API boundaries (TS interfaces, API contracts), verify error propagation (thrown errors caught by callers), check state mutation consistency across modules, detect circular dependencies/coupling. Target: 15-30 min.
|
|
65
69
|
|
|
@@ -109,6 +113,7 @@ Use its `files`. A `status` of `unresolvable` (exit 69, JSON still printed), or
|
|
|
109
113
|
NOTE: do NOT exclude all `.md` — commands, workflows, and agents are source code in this codebase.
|
|
110
114
|
|
|
111
115
|
**2. Group by language/type:** JS/TS (`.js`,`.jsx`,`.ts`,`.tsx`), Python (`.py`), Go (`.go`), C/C++ (`.c`,`.cpp`,`.h`,`.hpp`), Shell (`.sh`,`.bash`), other → generic.
|
|
116
|
+
CI/CD (by path): `.github/workflows/*.yml`/`*.yaml`, `Dockerfile*`, `docker-compose*.yml`, `deploy*.sh` (also Shell).
|
|
112
117
|
|
|
113
118
|
**3. Exit early if empty:** create REVIEW.md with `status: skipped`, all finding counts 0. Body: "No source files to review after filtering. All files in scope are documentation, planning artifacts, or generated files. Use `status: skipped` (not `clean`) because no actual review was performed."
|
|
114
119
|
|
|
@@ -116,14 +121,47 @@ NOTE: `status: clean` = reviewed, no issues. `status: skipped` = no reviewable f
|
|
|
116
121
|
</step>
|
|
117
122
|
|
|
118
123
|
<step name="review_by_depth">
|
|
119
|
-
**depth=quick:** run
|
|
124
|
+
**depth=quick:** run every check from `<depth_levels>`:
|
|
120
125
|
```bash
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
grep -n -E "
|
|
126
|
+
# Set FILE per scoped path with: while IFS= read -r FILE (never paste a name into code).
|
|
127
|
+
|
|
128
|
+
# Hardcoded secrets
|
|
129
|
+
grep -n -E -- "(password|secret|api_key|token|apikey|api-key)\s*[=:]\s*['\"][^'\"]+['\"]" "$FILE"
|
|
130
|
+
|
|
131
|
+
# Dangerous functions
|
|
132
|
+
grep -n -E -- "eval\(|innerHTML|dangerouslySetInnerHTML|exec\(|system\(|shell_exec|passthru" "$FILE"
|
|
133
|
+
|
|
134
|
+
# Debug artifacts
|
|
135
|
+
grep -n -E -- "console\.log|debugger;|TODO|FIXME|XXX|HACK" "$FILE"
|
|
136
|
+
|
|
137
|
+
# Empty catch blocks
|
|
138
|
+
grep -n -E -- "catch\s*\([^)]*\)\s*\{\s*\}" "$FILE"
|
|
139
|
+
|
|
140
|
+
# Commented-out code
|
|
141
|
+
grep -n -E -- "^\s*//.*[{};]|^\s*#[[:space:]]*(if|for|while|def|class|elif|else|try|except|with)[[:space:](].*:[[:space:]]*$|^\s*/\*[^*].*[{};]" "$FILE"
|
|
142
|
+
|
|
143
|
+
# Unpinned actions
|
|
144
|
+
grep -n -E -- "^[[:space:]]*(-[[:space:]]+)?uses:[[:space:]]*['\"]?[^[:space:]'\"]+@(main|master|latest)['\"]?([[:space:]]|$)" "$FILE"
|
|
145
|
+
|
|
146
|
+
# Non-idempotent install
|
|
147
|
+
[ -f package-lock.json ] && grep -n -E -- "(^|[^[:alnum:]_-])npm[[:space:]]+(install|i)([[:space:]]|$)" "$FILE" | grep -v -E "^[0-9]+:[[:space:]]*#|[[:space:]](-g|--global)([[:space:]]|$)"
|
|
148
|
+
|
|
149
|
+
# Missing job timeout
|
|
150
|
+
awk '
|
|
151
|
+
function flush() { if (job != "" && runs && !timed) print line ": " job ": no job-level timeout-minutes"; job = "" }
|
|
152
|
+
{ sub(/\r$/, "") }
|
|
153
|
+
/^[^[:space:]#]/ { flush(); injobs = ($0 ~ /^jobs:[[:space:]]*(#.*)?$/); jind = -1; next }
|
|
154
|
+
!injobs || /^[[:space:]]*(#.*)?$/ { next }
|
|
155
|
+
{ ind = match($0, /[^ ]/) - 1 }
|
|
156
|
+
jind < 0 { jind = ind }
|
|
157
|
+
ind == jind { flush(); job = $0; sub(/^ +/, "", job); sub(/:.*/, "", job); line = NR; kind = -1; runs = 0; timed = 0; next }
|
|
158
|
+
kind < 0 { kind = ind }
|
|
159
|
+
ind == kind && /^ *runs-on:/ { runs = 1 }
|
|
160
|
+
ind == kind && /^ *timeout-minutes:/ { timed = 1 }
|
|
161
|
+
END { flush() }
|
|
162
|
+
' "$FILE"
|
|
125
163
|
```
|
|
126
|
-
Severity: secrets/dangerous=Critical, debug=Info, empty catch=Warning.
|
|
164
|
+
Severity: secrets/dangerous=Critical, debug and commented-out code=Info, empty catch and the three CI/CD checks=Warning.
|
|
127
165
|
|
|
128
166
|
**depth=standard:** per file — Read full content, apply language-specific checks, check for: functions >50 lines, deep nesting (>4 levels), missing error handling in async functions, hardcoded config values, type safety issues (TS `any`, loose Python typing). Record findings with file path, line number, description.
|
|
129
167
|
|
|
@@ -133,7 +171,7 @@ Severity: secrets/dangerous=Critical, debug=Info, empty catch=Warning.
|
|
|
133
171
|
<step name="classify_findings">
|
|
134
172
|
**Critical** — security vulnerabilities, data loss, crashes, auth bypasses: SQL/command/path-traversal injection, hardcoded secrets in production code, null pointer derefs that crash, auth/authz bypasses, unsafe deserialization, buffer overflows.
|
|
135
173
|
|
|
136
|
-
**Warning** — logic errors, unhandled edge cases, missing error handling, code smells that could cause bugs: unchecked array access, missing async error handling, off-by-one errors, `==` vs `===` coercion, unhandled promise rejections, dead code paths indicating logic errors.
|
|
174
|
+
**Warning** — logic errors, unhandled edge cases, missing error handling, code smells that could cause bugs: unchecked array access, missing async error handling, off-by-one errors, `==` vs `===` coercion, unhandled promise rejections, dead code paths indicating logic errors; CI/CD pipeline findings: every check in the CI/CD entry.
|
|
137
175
|
|
|
138
176
|
**Info** — style, naming, dead code, unused imports, suggestions: unused imports/variables, poor naming (single letters except loop counters), commented-out code, TODO/FIXME, magic numbers, duplication.
|
|
139
177
|
|
|
@@ -158,10 +196,13 @@ findings:
|
|
|
158
196
|
warning: N
|
|
159
197
|
info: N
|
|
160
198
|
total: N
|
|
199
|
+
necessity: N
|
|
161
200
|
status: clean | issues_found
|
|
162
201
|
---
|
|
163
202
|
```
|
|
164
203
|
|
|
204
|
+
`necessity:` only at standard/deep: the necessity findings among `warning` + `info`, never added to `total`.
|
|
205
|
+
|
|
165
206
|
**3. Body sections (required order):**
|
|
166
207
|
1) `## Structural Findings (fallow)` — only if structural findings provided; normalized items first.
|
|
167
208
|
2) `## Narrative Findings (AI reviewer)` — your adversarial findings, including any external claim independently verified (`(external: {slug})`).
|
|
@@ -61,6 +61,8 @@ This ensures project-specific patterns, conventions, and best practices are appl
|
|
|
61
61
|
|
|
62
62
|
**3. Code Quality** — Dead code, unused imports/variables, poor naming conventions, missing error handling, inconsistent patterns, overly complex functions (high cyclomatic complexity), code duplication, magic numbers, commented-out code
|
|
63
63
|
|
|
64
|
+
**4. Necessity** (#4100) — reachable code whose guarded-against problem cannot occur in this stack: impossible-state guard, already-defended-elsewhere, cargo-culted pattern, phantom requirement, generality without instantiation. At `standard`/`deep`, Read `~/.claude/gsd-core/references/necessity-review.md` before classifying findings; if it cannot be read, say so in the Summary and omit `necessity:`. `quick` does not assess necessity. Warning when provable from the repo, Info when it rests on judgment, Never Critical; each finding cites the evidence that the state cannot occur and carries a `**Category:** necessity` line.
|
|
65
|
+
|
|
64
66
|
**Out of Scope (v1):** Performance issues (O(n²) algorithms, memory leaks, inefficient queries) are NOT in scope for v1. Focus on correctness, security, and maintainability.
|
|
65
67
|
|
|
66
68
|
</review_scope>
|
|
@@ -71,12 +73,17 @@ This ensures project-specific patterns, conventions, and best practices are appl
|
|
|
71
73
|
|
|
72
74
|
**quick** — Pattern-matching only. Use grep/regex to scan for common anti-patterns without reading full file contents. Target: under 2 minutes.
|
|
73
75
|
|
|
74
|
-
|
|
75
|
-
- Hardcoded secrets
|
|
76
|
-
- Dangerous functions
|
|
77
|
-
- Debug artifacts
|
|
78
|
-
- Empty catch blocks
|
|
79
|
-
- Commented-out code
|
|
76
|
+
Checks (commands in `review_by_depth`):
|
|
77
|
+
- Hardcoded secrets
|
|
78
|
+
- Dangerous functions
|
|
79
|
+
- Debug artifacts
|
|
80
|
+
- Empty catch blocks
|
|
81
|
+
- Commented-out code
|
|
82
|
+
- Unpinned actions
|
|
83
|
+
- Non-idempotent install
|
|
84
|
+
- Missing job timeout
|
|
85
|
+
|
|
86
|
+
The last three: GitHub Actions workflows only.
|
|
80
87
|
|
|
81
88
|
**standard** (default) — Read each changed file. Check for bugs, security issues, and quality problems in context. Cross-reference imports and exports. Target: 5-15 minutes.
|
|
82
89
|
|
|
@@ -86,6 +93,7 @@ Language-aware checks:
|
|
|
86
93
|
- **Go**: Unchecked error returns, goroutine leaks, context not passed, `defer` in loops, race conditions
|
|
87
94
|
- **C/C++**: Buffer overflow patterns, use-after-free indicators, null pointer dereferences, missing bounds checks, memory leaks
|
|
88
95
|
- **Shell**: Unquoted variables, `eval` usage, missing `set -e`, command injection via interpolation
|
|
96
|
+
- **CI/CD pipelines** (by path: `.github/workflows/*.yml`, `Dockerfile*`, `docker-compose*.yml`, deploy scripts): Read `~/.claude/gsd-core/references/cicd-review-patterns.md`; if it cannot be read, say so in the Summary and check: non-idempotent steps (`npm install` vs `npm ci`, unlocked `pip install`, unguarded `mkdir`/`rm`), no job `timeout-minutes`, deploy without `concurrency` + `cancel-in-progress`, per-environment rebuild (not build-once), no health check or rollback, load-bearing `continue-on-error`, static credentials where OIDC works, unpinned actions
|
|
89
97
|
|
|
90
98
|
**deep** — All of standard, plus cross-file analysis. Trace function call chains across imports. Target: 15-30 minutes.
|
|
91
99
|
|
|
@@ -174,6 +182,7 @@ NOTE: Do NOT exclude all `.md` files — commands, workflows, and agents are sou
|
|
|
174
182
|
- Go: `.go`
|
|
175
183
|
- C/C++: `.c`, `.cpp`, `.h`, `.hpp`
|
|
176
184
|
- Shell: `.sh`, `.bash`
|
|
185
|
+
- CI/CD (by path): `.github/workflows/*.yml`/`*.yaml`, `Dockerfile*`, `docker-compose*.yml`, `deploy*.sh` (also Shell)
|
|
177
186
|
- Other: Review generically
|
|
178
187
|
|
|
179
188
|
**3. Exit early if empty:** If no source files remain after filtering, create REVIEW.md with:
|
|
@@ -194,22 +203,48 @@ NOTE: `status: clean` means "reviewed and found no issues." `status: skipped` me
|
|
|
194
203
|
Branch on depth level:
|
|
195
204
|
|
|
196
205
|
**For depth=quick:**
|
|
197
|
-
Run
|
|
206
|
+
Run every check from `<depth_levels>` quick section:
|
|
198
207
|
```bash
|
|
208
|
+
# Set FILE per scoped path with: while IFS= read -r FILE (never paste a name into code).
|
|
209
|
+
|
|
199
210
|
# Hardcoded secrets
|
|
200
|
-
grep -n -E "(password|secret|api_key|token|apikey|api-key)\s*[=:]\s*['\"]\
|
|
211
|
+
grep -n -E -- "(password|secret|api_key|token|apikey|api-key)\s*[=:]\s*['\"][^'\"]+['\"]" "$FILE"
|
|
201
212
|
|
|
202
213
|
# Dangerous functions
|
|
203
|
-
grep -n -E "eval\(|innerHTML|dangerouslySetInnerHTML|exec\(|system\(|shell_exec"
|
|
214
|
+
grep -n -E -- "eval\(|innerHTML|dangerouslySetInnerHTML|exec\(|system\(|shell_exec|passthru" "$FILE"
|
|
204
215
|
|
|
205
216
|
# Debug artifacts
|
|
206
|
-
grep -n -E "console\.log|debugger;|TODO|FIXME|XXX|HACK"
|
|
207
|
-
|
|
208
|
-
# Empty catch
|
|
209
|
-
grep -n -E "catch\s*\([^)]*\)\s*\{\s*\}"
|
|
217
|
+
grep -n -E -- "console\.log|debugger;|TODO|FIXME|XXX|HACK" "$FILE"
|
|
218
|
+
|
|
219
|
+
# Empty catch blocks
|
|
220
|
+
grep -n -E -- "catch\s*\([^)]*\)\s*\{\s*\}" "$FILE"
|
|
221
|
+
|
|
222
|
+
# Commented-out code
|
|
223
|
+
grep -n -E -- "^\s*//.*[{};]|^\s*#[[:space:]]*(if|for|while|def|class|elif|else|try|except|with)[[:space:](].*:[[:space:]]*$|^\s*/\*[^*].*[{};]" "$FILE"
|
|
224
|
+
|
|
225
|
+
# Unpinned actions
|
|
226
|
+
grep -n -E -- "^[[:space:]]*(-[[:space:]]+)?uses:[[:space:]]*['\"]?[^[:space:]'\"]+@(main|master|latest)['\"]?([[:space:]]|$)" "$FILE"
|
|
227
|
+
|
|
228
|
+
# Non-idempotent install
|
|
229
|
+
[ -f package-lock.json ] && grep -n -E -- "(^|[^[:alnum:]_-])npm[[:space:]]+(install|i)([[:space:]]|$)" "$FILE" | grep -v -E "^[0-9]+:[[:space:]]*#|[[:space:]](-g|--global)([[:space:]]|$)"
|
|
230
|
+
|
|
231
|
+
# Missing job timeout
|
|
232
|
+
awk '
|
|
233
|
+
function flush() { if (job != "" && runs && !timed) print line ": " job ": no job-level timeout-minutes"; job = "" }
|
|
234
|
+
{ sub(/\r$/, "") }
|
|
235
|
+
/^[^[:space:]#]/ { flush(); injobs = ($0 ~ /^jobs:[[:space:]]*(#.*)?$/); jind = -1; next }
|
|
236
|
+
!injobs || /^[[:space:]]*(#.*)?$/ { next }
|
|
237
|
+
{ ind = match($0, /[^ ]/) - 1 }
|
|
238
|
+
jind < 0 { jind = ind }
|
|
239
|
+
ind == jind { flush(); job = $0; sub(/^ +/, "", job); sub(/:.*/, "", job); line = NR; kind = -1; runs = 0; timed = 0; next }
|
|
240
|
+
kind < 0 { kind = ind }
|
|
241
|
+
ind == kind && /^ *runs-on:/ { runs = 1 }
|
|
242
|
+
ind == kind && /^ *timeout-minutes:/ { timed = 1 }
|
|
243
|
+
END { flush() }
|
|
244
|
+
' "$FILE"
|
|
210
245
|
```
|
|
211
246
|
|
|
212
|
-
Record findings with severity: secrets/dangerous=Critical, debug=Info, empty catch=Warning
|
|
247
|
+
Record findings with severity: secrets/dangerous=Critical, debug and commented-out code=Info, empty catch and the three CI/CD checks=Warning
|
|
213
248
|
|
|
214
249
|
**For depth=standard:**
|
|
215
250
|
For each file:
|
|
@@ -253,6 +288,7 @@ For each finding, assign severity:
|
|
|
253
288
|
- Type coercion issues (`==` vs `===`)
|
|
254
289
|
- Unhandled promise rejections
|
|
255
290
|
- Dead code paths that indicate logic errors
|
|
291
|
+
- CI/CD pipeline findings: every check in the CI/CD entry
|
|
256
292
|
|
|
257
293
|
**Info** — Style issues, naming improvements, dead code, unused imports, suggestions:
|
|
258
294
|
- Unused imports/variables
|
|
@@ -287,10 +323,13 @@ findings:
|
|
|
287
323
|
warning: N
|
|
288
324
|
info: N
|
|
289
325
|
total: N
|
|
326
|
+
necessity: N
|
|
290
327
|
status: clean | issues_found
|
|
291
328
|
---
|
|
292
329
|
```
|
|
293
330
|
|
|
331
|
+
Emit `necessity:` only at standard/deep depth. It counts the necessity findings among `warning` + `info` and is never added to `total`.
|
|
332
|
+
|
|
294
333
|
**3. Body sections (required order):**
|
|
295
334
|
1) `## Structural Findings (fallow)` — only when structural findings were provided; list normalized items first.
|
|
296
335
|
2) `## Narrative Findings (AI reviewer)` — your adversarial findings from direct code review, including any external-reviewer claim you independently verified (`(external: {slug})`, see `load_context` step 5).
|
package/agents/gsd-executor.md
CHANGED
|
@@ -766,7 +766,14 @@ Do NOT skip. Do NOT proceed to state updates if self-check fails.
|
|
|
766
766
|
</self_check>
|
|
767
767
|
|
|
768
768
|
<state_updates>
|
|
769
|
-
After SUMMARY.md, update STATE.md
|
|
769
|
+
After SUMMARY.md, update ROADMAP.md progress FIRST, then STATE.md. The ROADMAP write is the step that can decline (`missing_phase_details`), and a decline stops the plan before any STATE.md write, so STATE.md never advances past a plan the ROADMAP did not record:
|
|
770
|
+
|
|
771
|
+
```bash
|
|
772
|
+
# Update ROADMAP.md progress for this phase (plan counts, status). A decline stops here, before STATE.md moves.
|
|
773
|
+
PROGRESS=$(gsd_run query roadmap.update-plan-progress "${PHASE_NUMBER}") && REASON=$(jq -er '.reason//""' <<<"$PROGRESS") && [ "$REASON" != missing_phase_details ] || { echo "ERROR: ROADMAP update-plan-progress did not complete for ${PHASE_NUMBER}-${PLAN} (missing_phase_details decline, failed query, or jq not installed). STOP: skip this plan's completion steps." >&2; exit 1; }
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
Then update STATE.md using `gsd-tools query` state handlers (named flags):
|
|
770
777
|
|
|
771
778
|
```bash
|
|
772
779
|
# Advance plan counter (handles edge cases automatically)
|
|
@@ -793,9 +800,6 @@ gsd_run query state.record-session \
|
|
|
793
800
|
```
|
|
794
801
|
|
|
795
802
|
```bash
|
|
796
|
-
# Update ROADMAP.md progress for this phase (plan counts, status)
|
|
797
|
-
gsd_run query roadmap.update-plan-progress "${PHASE_NUMBER}"
|
|
798
|
-
|
|
799
803
|
# Mark completed requirements from PLAN.md frontmatter
|
|
800
804
|
# Extract the `requirements` array from the plan's frontmatter, then mark each complete
|
|
801
805
|
gsd_run query requirements.mark-complete ${REQ_IDS}
|
package/agents/gsd-verifier.md
CHANGED
|
@@ -689,7 +689,7 @@ verified: YYYY-MM-DDTHH:MM:SSZ
|
|
|
689
689
|
status: passed | gaps_found | human_needed
|
|
690
690
|
score: N/M must-haves verified
|
|
691
691
|
covered_files: [...]
|
|
692
|
-
covered_digest: "
|
|
692
|
+
covered_digest: "v4:sha256:..."
|
|
693
693
|
behavior_unverified: 0 # Count of ⚠️ PRESENT_BEHAVIOR_UNVERIFIED truths (present + wired, behavior not exercised); each is detailed in behavior_unverified_items below (and in human_verification when status is human_needed)
|
|
694
694
|
overrides_applied: 0 # Count of PASSED (override) items included in score
|
|
695
695
|
overrides: # Only if overrides exist — carried forward or newly added
|