@opengsd/gsd-core 1.13.0 → 1.14.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 +1 -1
- package/agents/gsd-advisor-researcher.compact.md +85 -0
- package/agents/gsd-ai-researcher.compact.md +96 -0
- package/agents/gsd-assumptions-analyzer.compact.md +81 -0
- package/agents/gsd-code-fixer.compact.md +458 -0
- package/agents/gsd-code-fixer.md +5 -5
- package/agents/gsd-code-reviewer.compact.md +269 -0
- package/agents/gsd-code-reviewer.md +15 -3
- package/agents/gsd-codebase-mapper.compact.md +760 -0
- package/agents/gsd-debug-session-manager.compact.md +345 -0
- package/agents/gsd-doc-classifier.compact.md +192 -0
- package/agents/gsd-doc-synthesizer.compact.md +200 -0
- package/agents/gsd-doc-verifier.compact.md +143 -0
- package/agents/gsd-doc-writer.compact.md +440 -0
- package/agents/gsd-dom-verifier.compact.md +138 -0
- package/agents/gsd-domain-researcher.compact.md +141 -0
- package/agents/gsd-eval-auditor.compact.md +160 -0
- package/agents/gsd-eval-planner.compact.md +137 -0
- package/agents/gsd-framework-selector.compact.md +82 -0
- package/agents/gsd-integration-checker.compact.md +245 -0
- package/agents/gsd-intel-updater.compact.md +226 -0
- package/agents/gsd-mempalace-curator.compact.md +45 -0
- package/agents/gsd-nyquist-auditor.compact.md +179 -0
- package/agents/gsd-pattern-mapper.compact.md +275 -0
- package/agents/gsd-project-researcher.compact.md +587 -0
- package/agents/gsd-research-synthesizer.compact.md +212 -0
- package/agents/gsd-roadmapper.compact.md +454 -0
- package/agents/gsd-roadmapper.md +13 -0
- package/agents/gsd-security-auditor.compact.md +162 -0
- package/agents/gsd-ui-auditor.compact.md +404 -0
- package/agents/gsd-ui-checker.compact.md +277 -0
- package/agents/gsd-ui-researcher.compact.md +282 -0
- package/agents/gsd-user-profiler.compact.md +108 -0
- package/bin/install.js +206 -68
- package/commands/gsd/cleanup.md +1 -0
- package/commands/gsd/code-review.md +2 -1
- package/commands/gsd/complete-milestone.md +1 -0
- package/commands/gsd/config.md +1 -0
- package/commands/gsd/debug.md +1 -0
- package/commands/gsd/graphify.md +1 -0
- package/commands/gsd/health.md +1 -0
- package/commands/gsd/mempalace-capture.md +1 -0
- package/commands/gsd/mempalace-recall.md +1 -0
- package/commands/gsd/new-milestone.md +1 -0
- package/commands/gsd/new-project.md +1 -0
- package/commands/gsd/next.md +1 -0
- package/commands/gsd/pause-work.md +1 -0
- package/commands/gsd/phase.md +1 -0
- package/commands/gsd/pr-branch.md +1 -0
- package/commands/gsd/resume-work.md +1 -0
- package/commands/gsd/review-backlog.md +1 -0
- package/commands/gsd/settings.md +2 -1
- package/commands/gsd/stats.md +1 -0
- package/commands/gsd/thread.md +1 -0
- package/commands/gsd/workspace.md +1 -0
- package/commands/gsd/workstreams.md +1 -0
- package/gsd-core/bin/check-latest-version.cjs +8 -3
- package/gsd-core/bin/gsd-tools.cjs +338 -125
- package/gsd-core/bin/lib/adr-parser.cjs +1 -1
- package/gsd-core/bin/lib/artifacts.cjs +2 -1
- package/gsd-core/bin/lib/audit.cjs +39 -22
- package/gsd-core/bin/lib/broken-windows.cjs +168 -49
- package/gsd-core/bin/lib/capability-lifecycle.cjs +10 -6
- package/gsd-core/bin/lib/capability-loader.cjs +135 -1
- package/gsd-core/bin/lib/capability-registry.cjs +79 -67
- package/gsd-core/bin/lib/capability-source.cjs +19 -2
- package/gsd-core/bin/lib/capability-validator.cjs +14 -1
- package/gsd-core/bin/lib/check-command-router.cjs +113 -36
- package/gsd-core/bin/lib/code-review-depth.cjs +2 -2
- package/gsd-core/bin/lib/commands.cjs +650 -72
- package/gsd-core/bin/lib/config-loader.cjs +1 -0
- package/gsd-core/bin/lib/config.cjs +153 -38
- package/gsd-core/bin/lib/coverage.cjs +1 -1
- package/gsd-core/bin/lib/decisions.cjs +137 -34
- package/gsd-core/bin/lib/external-descriptor-trust.cjs +29 -14
- package/gsd-core/bin/lib/gsd2-import.cjs +1 -2
- package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +12 -1
- package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +1 -1
- package/gsd-core/bin/lib/init.cjs +409 -47
- package/gsd-core/bin/lib/install-engine.cjs +16 -3
- package/gsd-core/bin/lib/install-profiles.cjs +14 -0
- package/gsd-core/bin/lib/installer-migrations.cjs +33 -4
- package/gsd-core/bin/lib/loop-resolver.cjs +50 -31
- package/gsd-core/bin/lib/mcp-catalog.cjs +2 -2
- package/gsd-core/bin/lib/milestone.cjs +19 -8
- package/gsd-core/bin/lib/model-resolver.cjs +101 -10
- package/gsd-core/bin/lib/phase-command-router.cjs +7 -1
- package/gsd-core/bin/lib/phase-id.cjs +161 -22
- package/gsd-core/bin/lib/phase-lifecycle.cjs +61 -0
- package/gsd-core/bin/lib/phase.cjs +167 -63
- package/gsd-core/bin/lib/planning-inspect.cjs +34 -18
- package/gsd-core/bin/lib/planning-snapshot.cjs +61 -12
- package/gsd-core/bin/lib/planning-workspace.cjs +50 -1
- package/gsd-core/bin/lib/pristine-baseline.cjs +182 -0
- package/gsd-core/bin/lib/prohibition-enforcement.cjs +91 -4
- package/gsd-core/bin/lib/quick-batch.cjs +1 -1
- package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +61 -2
- package/gsd-core/bin/lib/research-store.cjs +11 -12
- package/gsd-core/bin/lib/review-lane-invocation.cjs +23 -0
- package/gsd-core/bin/lib/reviewer-step-dispatch.cjs +337 -0
- package/gsd-core/bin/lib/roadmap-parser.cjs +56 -15
- package/gsd-core/bin/lib/roadmap.cjs +108 -14
- package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +27 -10
- package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +12 -3
- package/gsd-core/bin/lib/runtime-artifact-layout.cjs +13 -5
- package/gsd-core/bin/lib/runtime-hooks-surface.cjs +193 -4
- package/gsd-core/bin/lib/security.cjs +126 -7
- package/gsd-core/bin/lib/state-document.cjs +130 -28
- package/gsd-core/bin/lib/state-md-schema.cjs +21 -14
- package/gsd-core/bin/lib/state-transition.cjs +142 -28
- package/gsd-core/bin/lib/state.cjs +223 -27
- package/gsd-core/bin/lib/surface.cjs +60 -2
- package/gsd-core/bin/lib/task-command-router.cjs +12 -6
- package/gsd-core/bin/lib/uat.cjs +1 -1
- package/gsd-core/bin/lib/update-context.cjs +30 -24
- package/gsd-core/bin/lib/vendor/js-yaml.cjs +11 -3
- package/gsd-core/bin/lib/verification.cjs +47 -15
- package/gsd-core/bin/lib/verify-command-grounding.cjs +1 -1
- package/gsd-core/bin/lib/verify.cjs +188 -23
- package/gsd-core/bin/lib/workstream-inventory.cjs +1 -0
- package/gsd-core/bin/lib/worktree-safety.cjs +13 -7
- package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
- package/gsd-core/bin/shared/config-schema.manifest.json +5 -0
- package/gsd-core/bin/verify-reapply-patches.cjs +439 -80
- package/gsd-core/references/compact-content-gate.md +66 -0
- package/gsd-core/references/loop-hook-dispatch.md +18 -0
- package/gsd-core/references/model-profiles.md +12 -3
- package/gsd-core/references/planning-config.md +3 -0
- package/gsd-core/references/tdd.md +5 -2
- package/gsd-core/references/thinking-models-planning.md +18 -2
- package/gsd-core/references/verification-patterns.md +17 -4
- package/gsd-core/references/worktree-path-safety.md +112 -2
- package/gsd-core/templates/README.md +7 -1
- package/gsd-core/templates/state.md +6 -3
- package/gsd-core/templates/summary.compact.md +212 -0
- package/gsd-core/templates/user-setup.compact.md +199 -0
- package/gsd-core/templates/user-setup.md +0 -9
- package/gsd-core/workflows/add-todo.md +3 -2
- package/gsd-core/workflows/autonomous.md +13 -10
- package/gsd-core/workflows/check-todos.md +4 -2
- package/gsd-core/workflows/cleanup.md +3 -1
- package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +7 -0
- package/gsd-core/workflows/code-review-fix.md +3 -3
- package/gsd-core/workflows/code-review.md +156 -30
- package/gsd-core/workflows/complete-milestone/detail/elaboration.md +274 -0
- package/gsd-core/workflows/complete-milestone.md +39 -262
- package/gsd-core/workflows/docs-update/detail/elaboration.md +179 -0
- package/gsd-core/workflows/docs-update.md +14 -155
- package/gsd-core/workflows/execute-phase/detail/elaboration.md +124 -0
- package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +18 -3
- package/gsd-core/workflows/execute-phase/steps/completion-reconciliation.md +56 -0
- package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +7 -2
- package/gsd-core/workflows/execute-phase/steps/executor-progress-policy.md +43 -0
- package/gsd-core/workflows/execute-phase/steps/sequential-root-pin.md +35 -0
- package/gsd-core/workflows/execute-phase.md +53 -152
- package/gsd-core/workflows/execute-plan.md +20 -7
- package/gsd-core/workflows/help/modes/full.compact.md +398 -0
- package/gsd-core/workflows/help.md +1 -1
- package/gsd-core/workflows/map-codebase.md +50 -3
- package/gsd-core/workflows/new-milestone.md +54 -12
- package/gsd-core/workflows/new-project/detail/elaboration.md +216 -0
- package/gsd-core/workflows/new-project.md +32 -202
- package/gsd-core/workflows/plan-phase/detail/elaboration.md +209 -0
- package/gsd-core/workflows/plan-phase.md +22 -181
- package/gsd-core/workflows/pr-branch.md +19 -7
- package/gsd-core/workflows/quick.md +8 -1
- package/gsd-core/workflows/reapply-patches.md +77 -3
- package/gsd-core/workflows/settings.md +18 -5
- package/gsd-core/workflows/update.md +7 -5
- package/gsd-core/workflows/verify-work/detail/elaboration.md +230 -0
- package/gsd-core/workflows/verify-work.md +20 -180
- package/hooks/dist/gsd-agent-isolation-guard.js +42 -16
- package/hooks/dist/gsd-context-monitor.js +88 -15
- package/hooks/dist/gsd-cursor-subagent-start.js +34 -14
- package/hooks/dist/gsd-secret-read-guard.js +44 -18
- package/hooks/dist/gsd-statusline.js +11 -7
- package/hooks/dist/gsd-validate-commit.sh +34 -4
- package/hooks/dist/gsd-worktree-path-guard.js +25 -14
- package/hooks/dist/gsd-write-guard.js +46 -1
- package/hooks/dist/lib/dispatch-identity.js +187 -0
- package/hooks/dist/lib/filename-classification.js +64 -0
- package/hooks/dist/lib/isolation-deny-reason.js +53 -1
- package/hooks/dist/lib/isolation-sentinel.js +58 -19
- package/hooks/gsd-agent-isolation-guard.js +42 -16
- package/hooks/gsd-context-monitor.js +88 -15
- package/hooks/gsd-cursor-subagent-start.js +34 -14
- package/hooks/gsd-secret-read-guard.js +44 -18
- package/hooks/gsd-statusline.js +11 -7
- package/hooks/gsd-validate-commit.sh +34 -4
- package/hooks/gsd-worktree-path-guard.js +25 -14
- package/hooks/gsd-write-guard.js +46 -1
- package/hooks/lib/dispatch-identity.js +187 -0
- package/hooks/lib/filename-classification.js +64 -0
- package/hooks/lib/isolation-deny-reason.js +53 -1
- package/hooks/lib/isolation-sentinel.js +58 -19
- package/package.json +10 -6
- package/scripts/benchmark-compact-content-variants.cjs +298 -0
- package/scripts/benchmark-compact-content.cjs +368 -0
- package/scripts/check-contract-drift.cjs +4 -1
- package/scripts/check-env.cjs +36 -8
- package/scripts/check-glossary-refs.cjs +25 -21
- package/scripts/ci-next-health.cjs +271 -0
- package/scripts/ci-prepare-test-scope.cjs +7 -7
- package/scripts/ci-test-scope.cjs +126 -20
- package/scripts/ci-timeout-report.cjs +1 -1
- package/scripts/diff-touches-shipped-paths.cjs +1 -1
- package/scripts/docs-guard-registry.cjs +7 -2
- package/scripts/gen-adr-index.cjs +8 -2
- package/scripts/gen-inventory-manifest.cjs +12 -0
- package/scripts/gen-platform-conformance-tier.cjs +557 -0
- package/scripts/lib/drift-scan.cjs +1 -1
- package/scripts/lib/macos-conformance-tier.generated.cjs +210 -0
- package/scripts/lib/npm-version-check-diagnosis.cjs +59 -0
- package/scripts/lib/platform-conformance-tier.generated.cjs +276 -0
- package/scripts/lib/suite-detection.cjs +32 -0
- package/scripts/lint-allowed-tools-parity.cjs +221 -0
- package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +19 -2
- package/scripts/lint-phase-id-drift.cjs +338 -13
- package/scripts/lint-response-language-coverage.cjs +9 -3
- package/scripts/lint-source-test-name-collision.cjs +1 -1
- package/scripts/lint-test-file-count.allowlist.json +1 -0
- package/scripts/lint-vendored-deps.cjs +128 -17
- package/scripts/lint-workflow-shellcheck-baseline.json +85 -0
- package/scripts/prompt-injection-scan.sh +14 -0
- package/scripts/workflow-size.cjs +139 -0
- package/skills/gsd-cleanup/SKILL.md +1 -0
- package/skills/gsd-code-review/SKILL.md +2 -1
- package/skills/gsd-complete-milestone/SKILL.md +1 -0
- package/skills/gsd-config/SKILL.md +1 -0
- package/skills/gsd-debug/SKILL.md +1 -0
- package/skills/gsd-graphify/SKILL.md +1 -0
- package/skills/gsd-health/SKILL.md +1 -0
- package/skills/gsd-mempalace-capture/SKILL.md +1 -0
- package/skills/gsd-mempalace-recall/SKILL.md +1 -0
- package/skills/gsd-new-milestone/SKILL.md +1 -0
- package/skills/gsd-new-project/SKILL.md +1 -0
- package/skills/gsd-next/SKILL.md +1 -0
- package/skills/gsd-pause-work/SKILL.md +1 -0
- package/skills/gsd-phase/SKILL.md +1 -0
- package/skills/gsd-pr-branch/SKILL.md +1 -0
- package/skills/gsd-resume-work/SKILL.md +1 -0
- package/skills/gsd-review-backlog/SKILL.md +1 -0
- package/skills/gsd-settings/SKILL.md +2 -1
- package/skills/gsd-stats/SKILL.md +1 -0
- package/skills/gsd-thread/SKILL.md +1 -0
- package/skills/gsd-workspace/SKILL.md +1 -0
- package/skills/gsd-workstreams/SKILL.md +1 -0
- package/vscode/package.json +1 -1
- package/gsd-core/templates/claude-md.md +0 -145
- package/gsd-core/templates/codebase/concerns.md +0 -310
- package/gsd-core/templates/codebase/conventions.md +0 -307
- package/gsd-core/templates/codebase/integrations.md +0 -280
- package/gsd-core/templates/codebase/structure.md +0 -285
- package/gsd-core/templates/codebase/testing.md +0 -480
- package/gsd-core/templates/debug-subagent-prompt.md +0 -91
- package/gsd-core/templates/discovery.md +0 -146
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Compact Content Gate
|
|
2
|
+
|
|
3
|
+
Shared by every workflow spine split under ADR-4139, and by every lazily-read fragment or
|
|
4
|
+
planning-artifact template given a compact variant under Phase 6 (#4406). States the config check
|
|
5
|
+
and both resolution rules once — a spine or fragment references this file; it never restates
|
|
6
|
+
either check inline.
|
|
7
|
+
|
|
8
|
+
## The check
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
COMPACT_CONTENT=$(gsd_run query config-get workflow.compact_content --raw 2>/dev/null || echo "false")
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Stream 1 — spine + detail (top-level, eagerly `@`-included workflows)
|
|
15
|
+
|
|
16
|
+
- **`COMPACT_CONTENT` is `"false"` (default):** Read every part under this workflow's own `detail/` directory (a sibling of this spine, e.g. `gsd-core/workflows/<name>/detail/*.md`) now, in full, before continuing past this point. Their content elaborates on the spine you are reading — treat everything they say as part of this document from here on.
|
|
17
|
+
- **`COMPACT_CONTENT` is `"true"`:** Do not read the detail file. Continue directly with the spine's own content — per ADR-4139 Decision 3, it is complete enough to run this workflow correctly on its own.
|
|
18
|
+
|
|
19
|
+
**The fail-safe this holds (ADR-4139 Decision 4):** A `Read` that does not fire for any reason (tool error, a skipped step, a misread condition) leaves you running on the spine alone. That is the same, correct, terser state an opted-in project runs in on purpose — never a state with no instructions. The spine's own completeness is what makes this safe; this gate is only ever additive.
|
|
20
|
+
|
|
21
|
+
## Streams 1b and 4 — variant resolution (lazily-read fragments and planning-artifact templates)
|
|
22
|
+
|
|
23
|
+
For a `workflows/<name>/{modes,steps,templates}/*.md` fragment or a `gsd-core/templates/**`
|
|
24
|
+
planning-artifact template that has a registered `.compact.md` sibling (same directory, same stem,
|
|
25
|
+
`.compact.md` suffix):
|
|
26
|
+
|
|
27
|
+
- **`COMPACT_CONTENT` is `"false"` (default), or the file has no registered `.compact.md` sibling:** Read the canonical path exactly as named — unchanged from today.
|
|
28
|
+
- **`COMPACT_CONTENT` is `"true"` and a `.compact.md` sibling is registered:** Read the `.compact.md` sibling instead of the canonical path.
|
|
29
|
+
|
|
30
|
+
Both files are complete, independently — Read exactly one, never both, and never read the compact
|
|
31
|
+
sibling's content as an addendum to the canonical file.
|
|
32
|
+
|
|
33
|
+
**The fail-safe this holds:** unlike stream 1, a call site this rule actually applies to is already
|
|
34
|
+
reached only by a runtime `Read` — a missed `Read` already means zero overlay content, with or
|
|
35
|
+
without `workflow.compact_content`. Selecting between two independently-complete files at that
|
|
36
|
+
call site does not introduce a new way to end up with nothing; the worst case is identical to
|
|
37
|
+
today's. This is why stream 1b/4 can use variant-swap (two independent files) where stream 1 could
|
|
38
|
+
not: the degradation-direction argument that ruled out converting stream 1's `@`-includes (ADR-4139
|
|
39
|
+
Decision 4) does not apply at a genuine runtime-`Read` call site, because there is no
|
|
40
|
+
host-guaranteed baseline being traded away there.
|
|
41
|
+
|
|
42
|
+
**This rule is scoped per call site, not per file.** A `gsd-core/templates/**` file can have both
|
|
43
|
+
kinds of reference in the corpus at once — some places name it inside an eager `@`-include or an
|
|
44
|
+
orchestrator build-time embed (the same mechanism as stream 1, just reaching a template path
|
|
45
|
+
instead of a workflow path), others name it in prose instructing a runtime `Read`. Only the latter
|
|
46
|
+
gets rewritten to point at this rule; an eager reference to the canonical file is left exactly as
|
|
47
|
+
it is, for the same reason stream 1's `@`-includes were left alone — converting it would trade a
|
|
48
|
+
host-guaranteed load for a conditional one. Before wiring any call site, confirm by inspection
|
|
49
|
+
which kind it is; do not assume every mention of a `gsd-core/templates/**` path is a runtime `Read`
|
|
50
|
+
just because the directory's typical case is.
|
|
51
|
+
|
|
52
|
+
## Stream 2 — agent-skill payloads (the `gsd_run query agent-skills` CLI seam)
|
|
53
|
+
|
|
54
|
+
`agents/<name>.compact.md`, same directory, same stem, `.compact.md` suffix — registered and
|
|
55
|
+
checked the same way as streams 1b/4. The selection is different: this seam already runs through
|
|
56
|
+
a real function call (`cmdAgentSkills`, `src/init.cts`), so the resolution happens **in code**,
|
|
57
|
+
not by a `gsd_run query config-get` prose instruction. There is nothing to state here for a
|
|
58
|
+
workflow author to follow, because no workflow author calls this seam directly — it fires only
|
|
59
|
+
inside the `#2454` persona fallback for non-Claude, AGENTS-native runtimes that cannot dispatch a
|
|
60
|
+
named subagent.
|
|
61
|
+
|
|
62
|
+
Same two rules as streams 1b/4, enforced in code instead of prose: `workflow.compact_content` off,
|
|
63
|
+
or no registered `.compact.md` sibling for that agent, serves the canonical persona unchanged; on,
|
|
64
|
+
with a sibling registered, serves the compact one. The one addition code gives that prose could
|
|
65
|
+
not: a missing sibling is disclosed in the served payload itself (a leading `<!-- gsd: no compact
|
|
66
|
+
payload registered ... -->` comment) rather than silently serving canonical with no signal at all.
|
|
@@ -57,6 +57,24 @@ Dispatch the referenced unit. Exactly one of `ref.skill`, `ref.agent`, or `ref.c
|
|
|
57
57
|
|
|
58
58
|
Wait for the result before continuing to the next hook or the next step.
|
|
59
59
|
|
|
60
|
+
**`supportsReviewerLanes` (optional, boolean).** A `step` entry may carry
|
|
61
|
+
`supportsReviewerLanes: true` alongside `ref` (#4209). A workflow opts a step into external
|
|
62
|
+
reviewer-lane dispatch by calling `gsd_run review-lane dispatch-step --cap-id <capId> --point
|
|
63
|
+
<point> --explicit <slugs> ...` — `dispatch-step` resolves its OWN active hook for `<point>` (via
|
|
64
|
+
`resolveActiveHooksForPoint`, the same in-process resolver `loop render-hooks` itself calls) and
|
|
65
|
+
checks whether `<capId>`'s hook carries this field before proceeding; the workflow does not
|
|
66
|
+
resolve or gate on the trait itself, only passes the two flags naming which step it is. When the
|
|
67
|
+
trait reads exactly `true`, `dispatch-step` routes through `dispatchReviewerLanes`, the one
|
|
68
|
+
interpreter in `src/reviewer-step-dispatch.cts` that reuses the existing reviewer-lane selection,
|
|
69
|
+
planning, and invocation machinery, so any explicitly selected reviewer lane also reviews the
|
|
70
|
+
same scope. Absent or `false` is inert: `dispatch-step` itself is a no-op (a non-boolean value is
|
|
71
|
+
rejected by `capability-validator.cjs` at load time, so it never reaches `dispatch-step` at all).
|
|
72
|
+
This is the only place a step opts into reviewer-lane support: a capability beyond `code-review`
|
|
73
|
+
reuses it by declaring the same trait on its own step and calling `dispatch-step` with
|
|
74
|
+
`--cap-id`/`--point`, with zero bespoke TRAIT-RESOLUTION code of its own. The workflow still owns
|
|
75
|
+
matching its own CLI flags against the reviewer-lane roster and assembling the evidence block
|
|
76
|
+
handed to its consolidator — those are NOT part of what this trait makes reusable.
|
|
77
|
+
|
|
60
78
|
A `step` is **advisory by construction**: it never blocks or redirects the host workflow —
|
|
61
79
|
that is what a `gate` is for. Each dispatch is best-effort; on error record a warning and
|
|
62
80
|
continue, honoring `onError`.
|
|
@@ -58,6 +58,10 @@ Model profiles control which Claude model each GSD agent uses. This allows balan
|
|
|
58
58
|
3. **Profile table** — the per-agent column from the active `model_profile`
|
|
59
59
|
4. **Runtime default** — when nothing else applies
|
|
60
60
|
|
|
61
|
+
Steps 2–4 select the *tier*; a `model_profile_overrides.<runtime>.<tier>` entry then
|
|
62
|
+
maps that tier to a concrete model (#4192 — honored on the claude runtime as well, so
|
|
63
|
+
pinning composes with tiering instead of replacing it).
|
|
64
|
+
|
|
61
65
|
### Why two layers above the profile?
|
|
62
66
|
|
|
63
67
|
- **Profile** is a global tier strategy (everyone runs balanced).
|
|
@@ -215,8 +219,11 @@ is (highest → lowest):
|
|
|
215
219
|
(see §Dynamic Routing — escalation steps tier up per attempt counter)
|
|
216
220
|
4. If no dynamic_routing match, check models[phase_type] for a phase-type tier
|
|
217
221
|
(see §Per-Phase-Type Model Map for the agent → phase-type mapping)
|
|
218
|
-
5.
|
|
219
|
-
|
|
222
|
+
5. Check model_profile_overrides.<runtime>.<tier> for a per-tier model override
|
|
223
|
+
(honored on the claude runtime too — #4192; verbatim unless it maps to the
|
|
224
|
+
current tier alias)
|
|
225
|
+
6. If no phase-type slot, look up agent in profile table
|
|
226
|
+
7. Pass model parameter to Task call
|
|
220
227
|
```
|
|
221
228
|
|
|
222
229
|
`model` and `effort` resolve through different mechanisms at different
|
|
@@ -246,7 +253,9 @@ Override specific agents without changing the entire profile:
|
|
|
246
253
|
}
|
|
247
254
|
```
|
|
248
255
|
|
|
249
|
-
Overrides take precedence over the profile. Valid values: `opus`, `sonnet`, `haiku`, `inherit`, or any fully-qualified model ID (e.g., `"o3"`, `"openai/o3"`, `"google/gemini-2.5-pro"`).
|
|
256
|
+
Overrides take precedence over the profile. Valid values: `opus`, `sonnet`, `haiku`, `fable`, `inherit`, or any fully-qualified model ID (e.g., `"o3"`, `"openai/o3"`, `"google/gemini-2.5-pro"`). `fable` is a Claude Code Agent-tool alias, not a GSD profile tier — it has no column in the profile table above.
|
|
257
|
+
|
|
258
|
+
On the Claude runtime, fully-qualified Claude model IDs are honored as explicit generation pins (#4192): an ID that names the current tier default (e.g. `"claude-sonnet-5"`) resolves to its tier alias — the same model in the form the Agent tool always accepts — while any other ID (e.g. `"claude-opus-4-7"`) resolves verbatim, with a warn-once stderr note that setups accepting only tier aliases will not honor a full ID. To pin a generation for a whole tier rather than one agent, set `model_profile_overrides.claude.<tier>` (see docs/CONFIGURATION.md — Runtime-Aware Profiles).
|
|
250
259
|
|
|
251
260
|
## Switching Profiles
|
|
252
261
|
|
|
@@ -289,6 +289,7 @@ Set via `workflow.*` namespace in config.json (e.g., `"workflow": { "research":
|
|
|
289
289
|
| `workflow.ui_phase` | boolean | `true` | `true`, `false` | Generate UI-SPEC.md for frontend phases |
|
|
290
290
|
| `workflow.ui_safety_gate` | boolean | `true` | `true`, `false` | Require safety gate approval for UI changes |
|
|
291
291
|
| `workflow.text_mode` | boolean | `false` | `true`, `false` | Use plain-text numbered lists instead of AskUserQuestion menus |
|
|
292
|
+
| `workflow.compact_content` | boolean | `false` | `true`, `false` | Compact content mode (#4139, ADR-4139) — per-project boolean selecting terser payloads. Six workflows branch on it via spine+detail: `plan-phase` (#4402, pilot), `execute-phase`, `docs-update`, `new-project`, `verify-work`, `complete-milestone` (#4405). The rest of the eager-window corpus was reviewed and recorded as not worth splitting (`docs/PARTITION-RULES.md`). Lazily-`Read` workflow fragments and `gsd-core/templates/**` templates use a `.compact.md` sibling instead (#4406, `gsd-core/references/compact-content-gate.md` § "Streams 1b and 4") — wired today for `help --full` and the sequential-execution `SUMMARY.md`/`USER-SETUP.md` reads. Agent-skill payloads (#4407, § "Stream 2") use the same `.compact.md` sibling shape, resolved in code by the `gsd_run query agent-skills` CLI seam rather than prose, for the non-Claude persona fallback only |
|
|
292
293
|
| `workflow.research_before_questions` | boolean | `false` | `true`, `false` | Run research before interactive questions in discuss phase (also honored on the `/gsd:quick` path, #3894). _Alias:_ `research_before_questions` is the flat-key form used in `CONFIG_DEFAULTS`; `workflow.research_before_questions` is the canonical namespaced form. |
|
|
293
294
|
| `workflow.discuss_mode` | string | `"discuss"` | `"discuss"`, `"assumptions"` | Default mode for discuss-phase: `"discuss"` runs interactive questioning; `"assumptions"` analyzes codebase and surfaces assumptions instead |
|
|
294
295
|
| `workflow.skip_discuss` | boolean | `false` | `true`, `false` | Skip discuss phase entirely |
|
|
@@ -360,6 +361,8 @@ Set via `hooks.*` namespace (e.g., `"hooks": { "context_warnings": true }`).
|
|
|
360
361
|
| Key | Type | Default | Allowed Values | Description |
|
|
361
362
|
|-----|------|---------|----------------|-------------|
|
|
362
363
|
| `hooks.context_warnings` | boolean | `true` | `true`, `false` | Show warnings when context budget is exceeded |
|
|
364
|
+
| `hooks.context_warning_threshold` | number | `35` | Greater than 0 and at most 100, and strictly greater than `hooks.context_critical_threshold`. `config-set` refuses 0: nothing is below it, so no critical value could satisfy the pair | Percent of context window REMAINING at or below which the monitor emits CONTEXT WARNING. An out-of-domain value falls back **per key**; both keys revert to their defaults only when the RESOLVED pair violates `critical < warning`. Read from the root project config — a workstream-scoped `config-set` does not reach this hook. Inert on a runtime with no context-monitor hook installed, Codex among them (#2586); see [context-monitor.md](../../docs/context-monitor.md) (#4285) |
|
|
365
|
+
| `hooks.context_critical_threshold` | number | `25` | At least 0 and less than 100, and strictly less than `hooks.context_warning_threshold`. `config-set` refuses 100: nothing is above it, so no warning value could satisfy the pair | Percent of context window REMAINING at or below which the monitor escalates to CONTEXT CRITICAL. Setting only one of the pair is checked against the other's default, so tune both when moving either past the other. Same root-config scope, and the same installed-monitor prerequisite, as the key above (#4285) |
|
|
363
366
|
|
|
364
367
|
### Learnings Fields
|
|
365
368
|
|
|
@@ -273,8 +273,11 @@ When `workflow.tdd_mode` is enabled in config, the RED/GREEN/REFACTOR gate seque
|
|
|
273
273
|
After completing a `type: tdd` plan, the executor validates the git log:
|
|
274
274
|
```bash
|
|
275
275
|
# The commit protocol promises no zero-padding for ${PHASE}/${PLAN} — strip both and
|
|
276
|
-
# match the commit-scope position anchored (#4003).
|
|
277
|
-
|
|
276
|
+
# match the commit-scope position anchored (#4003). #4619: PHASE may be decimal/
|
|
277
|
+
# N-segment; zero-strip only the leading integer segment, escape the rest.
|
|
278
|
+
PHASE_INT=${PHASE%%.*}; PHASE_FRAC=${PHASE#"$PHASE_INT"}
|
|
279
|
+
PHASE_N="$((10#$PHASE_INT))${PHASE_FRAC//./\\.}"
|
|
280
|
+
PLAN_N=$((10#${PLAN}))
|
|
278
281
|
# Check for RED gate commit
|
|
279
282
|
git log --oneline -E --grep="^test\((0*${PHASE_N})-(0*${PLAN_N})\):" | head -1
|
|
280
283
|
# Check for GREEN gate commit
|
|
@@ -34,13 +34,29 @@ For each significant decision in this plan, ask what undoing it would cost three
|
|
|
34
34
|
|
|
35
35
|
This is the reasoning step that produces the rating. The taxonomy itself, the emission rules, and the anti-patterns live in @~/.claude/gsd-core/references/planner-reversibility.md — do not maintain a second classification here.
|
|
36
36
|
|
|
37
|
-
## 5.
|
|
37
|
+
## 5. Occam's Razor
|
|
38
|
+
|
|
39
|
+
**Counters:** Plans that prescribe avoidable dependencies, abstractions, files, or speculative flexibility before execution begins.
|
|
40
|
+
|
|
41
|
+
This check complements the planner's RESEARCH.md `dont_hand_roll` guidance and the plan checker's Dimension 12 (Pattern Compliance): those sources identify capabilities and established patterns, while this check orders otherwise sufficient implementation choices. The executor applies the related check later in `thinking-models-execution.md`, after the plan has already selected an approach.
|
|
42
|
+
|
|
43
|
+
After preserving locked user decisions and complete requirement coverage, choose the first option that is demonstrably sufficient for the task's `<done>` condition:
|
|
44
|
+
|
|
45
|
+
1. Existing project behavior, helper, or established pattern
|
|
46
|
+
2. Standard-library capability
|
|
47
|
+
3. Native platform capability
|
|
48
|
+
4. Already-installed dependency
|
|
49
|
+
5. Minimum new implementation
|
|
50
|
+
|
|
51
|
+
This ordering is a sufficiency check, not permission to make the task smaller. It must never reduce requested scope or override locked user decisions, requirement coverage, security, validation, accessibility, error handling, or verification. The planner uses it when choosing implementation actions; the plan checker flags a new abstraction or dependency only when a higher rung is demonstrably sufficient.
|
|
52
|
+
|
|
53
|
+
## 6. Curse of Knowledge Counter
|
|
38
54
|
|
|
39
55
|
**Counters:** Plan-to-executor ambiguity from compressed instructions.
|
|
40
56
|
|
|
41
57
|
For each `<action>` step, re-read it as if you have NEVER seen this codebase. Is every noun unambiguous (which file? which function? which endpoint?)? Is every verb specific (add WHERE? modify HOW?)? If a step could be interpreted two ways, rewrite it. Include file paths, function names, and expected behavior in every action step.
|
|
42
58
|
|
|
43
|
-
##
|
|
59
|
+
## 7. Base Rate Neglect Counter
|
|
44
60
|
|
|
45
61
|
**Counters:** Planners ignoring low-confidence research caveats.
|
|
46
62
|
|
|
@@ -309,14 +309,17 @@ grep -r "$hook_name()" src/ --include="*.tsx" --include="*.ts" | grep -v "$hook_
|
|
|
309
309
|
# .env file exists
|
|
310
310
|
[ -f ".env" ] || [ -f ".env.local" ]
|
|
311
311
|
|
|
312
|
-
# Required variable is defined
|
|
313
|
-
|
|
312
|
+
# Required variable is defined (in the environment: dotenv/direnv/the framework has loaded it)
|
|
313
|
+
printenv "$VAR_NAME" >/dev/null
|
|
314
314
|
```
|
|
315
315
|
|
|
316
316
|
**Substantive check:**
|
|
317
317
|
```bash
|
|
318
|
-
# Variable has actual value (not placeholder)
|
|
319
|
-
|
|
318
|
+
# Variable has an actual value (not a placeholder) -- tests the shape, never prints the value;
|
|
319
|
+
# exit 0 = real value, exit 1 = missing or placeholder (case-insensitive)
|
|
320
|
+
v=$(printenv "$VAR_NAME"); case "$(printf %s "$v" | tr '[:upper:]' '[:lower:]')" in
|
|
321
|
+
""|*your-*-here*|*xxx*|*placeholder*|*todo*) exit 1;;
|
|
322
|
+
esac
|
|
320
323
|
|
|
321
324
|
# Value looks valid for type:
|
|
322
325
|
# - URLs should start with http
|
|
@@ -324,6 +327,16 @@ grep -E "^$VAR_NAME=.+" .env .env.local 2>/dev/null | grep -v "your-.*-here|xxx|
|
|
|
324
327
|
# - Booleans should be true/false
|
|
325
328
|
```
|
|
326
329
|
|
|
330
|
+
When the variable is not present in the agent's own environment (a framework that loads
|
|
331
|
+
`.env.local` itself at runtime does not export it to the shell that runs these checks),
|
|
332
|
+
ask the user to confirm it is set rather than reading `.env` directly. Variable NAMES can
|
|
333
|
+
still be checked against `.env.example`, which the secret-read guard exempts from its
|
|
334
|
+
protected-file patterns.
|
|
335
|
+
|
|
336
|
+
One guard-matching note worth knowing when auditing docs for `.env` mentions: the guard
|
|
337
|
+
treats a grep PATTERN whose last path segment is a secret file name as a file operand, so
|
|
338
|
+
`grep -n "\.env" file.md` is denied while `grep -n "\.env\b" file.md` is allowed.
|
|
339
|
+
|
|
327
340
|
**Stub patterns specific to env:**
|
|
328
341
|
```bash
|
|
329
342
|
# RED FLAGS - These are stubs:
|
|
@@ -1,7 +1,117 @@
|
|
|
1
1
|
# Worktree Path Safety
|
|
2
2
|
|
|
3
|
-
Guards for executor agents running inside Claude Code worktrees.
|
|
4
|
-
|
|
3
|
+
Guards for executor agents running inside Claude Code worktrees. The
|
|
4
|
+
supplied-root pin (step 0p) runs in EVERY mode; the remaining checks run before
|
|
5
|
+
any staging, Edit, or Write operation in worktree mode.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Supplied-root pin — step 0p (#4254, EVERY mode)
|
|
10
|
+
|
|
11
|
+
Sequential-mode dispatch (no `isolation="worktree"`) gives the executor no
|
|
12
|
+
spawn-time cwd guarantee, and the worktree-only guards below do not apply — so
|
|
13
|
+
a sequential executor whose process cwd resolved to a different checkout of
|
|
14
|
+
the same repo would self-derive that checkout as its root and commit there,
|
|
15
|
+
silently. Step 0p closes that hole by comparing the executor's actual root
|
|
16
|
+
against a root the ORCHESTRATOR already validated — never against anything the
|
|
17
|
+
executor derives itself.
|
|
18
|
+
|
|
19
|
+
**Runtime contract (executor):** if your prompt contains a `<project_root_pin>`
|
|
20
|
+
block, run its guard script verbatim before your first Edit/Write and again
|
|
21
|
+
before every commit, in the same cwd as that write or commit. On FATAL, halt
|
|
22
|
+
and report — recovery (moving commits between checkouts) is an
|
|
23
|
+
orchestrator/human decision, never agent self-repair. If your prompt contains
|
|
24
|
+
NO `<project_root_pin>` block (worktree/isolated dispatch, or a legacy
|
|
25
|
+
orchestrator), emit one warning line and continue with steps 0a/0b below — do
|
|
26
|
+
not fail closed on dispatches that never carried a pin. **Never bind
|
|
27
|
+
`{PINNED_ROOT}` yourself**: if this template reaches you unbound it is
|
|
28
|
+
reference prose, not your pin — only the orchestrator's build-time
|
|
29
|
+
substitution produces a valid guard.
|
|
30
|
+
|
|
31
|
+
**Composition contract (orchestrator — build time, NOT a sub-agent runtime
|
|
32
|
+
step):** copy the guard below into the dispatched prompt inside a
|
|
33
|
+
`<project_root_pin>` block, substituting `{PINNED_ROOT}` with the literal value
|
|
34
|
+
of `$ORCHESTRATOR_WT` captured at execute_waves entry, shell-single-quoted:
|
|
35
|
+
wrap the path in `'…'` and escape any embedded `'` as `'\''`. A path that
|
|
36
|
+
cannot be quoted this way must halt the phase (surface a blocker) rather than
|
|
37
|
+
ship a pin that could mis-parse. The comparison is git-vs-git on BOTH sides —
|
|
38
|
+
`git -C` resolves the pinned path to its repo's canonical toplevel in git's
|
|
39
|
+
own path representation, so symlink aliases, trailing slashes, `/var` vs
|
|
40
|
+
`/private/var` spellings, and Windows drive-letter forms — forward- or
|
|
41
|
+
backslash-separated, `RUNNER~1`-style short names included — compare equal by
|
|
42
|
+
construction (shell `pwd -P` normalization does NOT match git's emission on
|
|
43
|
+
Windows — do not re-introduce it).
|
|
44
|
+
|
|
45
|
+
Two portability rules baked into the guard below, learned from the #4254 CI
|
|
46
|
+
Windows legs: (1) a backslash comparator must be GENERATED at runtime
|
|
47
|
+
(`printf '\134'`), because a backslash written twice in the script text does
|
|
48
|
+
not survive the Windows command-line round-trip into bash — the doubled form
|
|
49
|
+
arrives halved, which silently rewrites any escape pattern that relies on it;
|
|
50
|
+
(2) every FATAL names its `Guard stage` and, where a git capture failed,
|
|
51
|
+
git's own stderr in a `Diagnostic` line, so a platform failure self-describes
|
|
52
|
+
instead of surfacing as a bare `Actual root: <none>`.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# gsd:guard=supplied-root-pin (#4254) — run before the first Edit/Write and before every commit.
|
|
56
|
+
PINNED_ROOT='{PINNED_ROOT}' # orchestrator build-time substitution — the only valid source of this value
|
|
57
|
+
PIN_STAGE=''
|
|
58
|
+
PIN_DIAG=''
|
|
59
|
+
gsd_pin_fail() {
|
|
60
|
+
echo "FATAL: executor root does not match the orchestrator-supplied PROJECT_ROOT pin (#4254)." >&2
|
|
61
|
+
echo " Pinned root: ${PINNED_ROOT:-<empty or unexpanded>}" >&2
|
|
62
|
+
echo " Actual root: ${ACTUAL_ROOT:-<none>}" >&2
|
|
63
|
+
echo " Guard stage: ${PIN_STAGE:-<unset>}" >&2
|
|
64
|
+
if [ -n "$PIN_DIAG" ]; then echo " Diagnostic: $PIN_DIAG" >&2; fi
|
|
65
|
+
echo " No writes or commits are permitted from this checkout. HALT and report; recovery is an" >&2
|
|
66
|
+
echo " orchestrator/human decision. Only the IMMEDIATE submodule of the pinned checkout is a" >&2
|
|
67
|
+
echo " legitimate other cwd — nested submodules must surface as a blocker, not self-route." >&2
|
|
68
|
+
exit 1
|
|
69
|
+
}
|
|
70
|
+
# Backslash comparator, generated at runtime: a backslash written twice in this
|
|
71
|
+
# script does not survive the Windows spawn path into bash (the command-line
|
|
72
|
+
# round-trip halves the doubled form), which rejected every C:\ pin at the form
|
|
73
|
+
# gate on the #4254 CI Windows legs. printf's octal escape is a lone backslash,
|
|
74
|
+
# which does survive; the quoted expansion below is literal in a case pattern.
|
|
75
|
+
BS=$(printf '\134')
|
|
76
|
+
# Fail closed if the comparator could not be generated: an empty BS would widen
|
|
77
|
+
# the drive-form arm below to drive-RELATIVE pins (C:foo) — the one fail-open
|
|
78
|
+
# seam in this construction, closed loudly rather than trusted to the shell.
|
|
79
|
+
if [ -z "$BS" ]; then
|
|
80
|
+
PIN_STAGE=form-gate
|
|
81
|
+
PIN_DIAG='backslash comparator generation failed (printf octal escape returned empty)'
|
|
82
|
+
gsd_pin_fail
|
|
83
|
+
fi
|
|
84
|
+
case "$PINNED_ROOT" in
|
|
85
|
+
''|'{PINNED_ROOT}') PIN_STAGE=pin-unbound; gsd_pin_fail ;; # empty or unexpanded pin — fail closed, never warn-and-proceed
|
|
86
|
+
/*) ;; # absolute POSIX form
|
|
87
|
+
[A-Za-z]:/*|[A-Za-z]:"$BS"*) ;; # Windows drive form, forward- or backslash-separated
|
|
88
|
+
*) PIN_STAGE=form-gate; gsd_pin_fail ;; # relative pin — never trustworthy across cwds
|
|
89
|
+
esac
|
|
90
|
+
ACTUAL_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
|
|
91
|
+
if [ -z "$ACTUAL_ROOT" ]; then
|
|
92
|
+
PIN_STAGE=actual-capture
|
|
93
|
+
PIN_DIAG="git rev-parse --show-toplevel from the cwd failed: $(git rev-parse --show-toplevel 2>&1 1>/dev/null)"
|
|
94
|
+
gsd_pin_fail
|
|
95
|
+
fi
|
|
96
|
+
PINNED_TL=$(git -C "$PINNED_ROOT" rev-parse --show-toplevel 2>/dev/null)
|
|
97
|
+
if [ -z "$PINNED_TL" ]; then
|
|
98
|
+
PIN_STAGE=pinned-capture
|
|
99
|
+
PIN_DIAG="git -C <pinned root> rev-parse --show-toplevel failed: $(git -C "$PINNED_ROOT" rev-parse --show-toplevel 2>&1 1>/dev/null)"
|
|
100
|
+
gsd_pin_fail
|
|
101
|
+
fi
|
|
102
|
+
if [ "$ACTUAL_ROOT" != "$PINNED_TL" ]; then
|
|
103
|
+
# Registered-submodule allowance: sub_repos plans legitimately commit inside an
|
|
104
|
+
# immediate submodule of the pinned checkout. The superproject working tree is
|
|
105
|
+
# git-emitted in the same representation as PINNED_TL, so the equality is
|
|
106
|
+
# representation-safe on every platform.
|
|
107
|
+
SUPER_TL=$(git rev-parse --show-superproject-working-tree 2>/dev/null)
|
|
108
|
+
if [ "$SUPER_TL" != "$PINNED_TL" ]; then
|
|
109
|
+
PIN_STAGE=root-mismatch
|
|
110
|
+
PIN_DIAG="actual=${ACTUAL_ROOT} pinned=${PINNED_TL} superproject=${SUPER_TL:-<none>}"
|
|
111
|
+
gsd_pin_fail
|
|
112
|
+
fi
|
|
113
|
+
fi
|
|
114
|
+
```
|
|
5
115
|
|
|
6
116
|
---
|
|
7
117
|
|
|
@@ -21,8 +21,14 @@ These files live directly at `.planning/` — not inside phase subdirectories.
|
|
|
21
21
|
| `LEARNINGS.md` | *(inline)* | `/gsd:extract-learnings`, `/gsd:execute-phase` (gated: `features.global_learnings`) | Phase retrospective learnings for future plans |
|
|
22
22
|
| `THREADS.md` | *(inline)* | `/gsd:thread` | Persistent discussion threads |
|
|
23
23
|
| `config.json` | `config.json` | `/gsd:new-project`, `/gsd:health --repair` | Project-specific GSD configuration |
|
|
24
|
-
| `CLAUDE.md` |
|
|
24
|
+
| `CLAUDE.md` | *(inline)* | `/gsd-profile` | Auto-assembled Claude Code context file |
|
|
25
25
|
| `RETROSPECTIVE.md` | *(inline)* | `/gsd:complete-milestone` | Living milestone retrospective updated at each milestone close |
|
|
26
|
+
| `WINDOWS.md` | *(none)* | broken-windows ledger (`src/broken-windows.cts`) | Tracked known-broken items pending resolution (#3224) |
|
|
27
|
+
| `STATE-ARCHIVE.md` | *(none)* | `state.cts`'s `cmdStatePrune` | Pruned historical STATE.md entries |
|
|
28
|
+
| `milestone.lock` | *(none)* | `src/milestone-lock.cts` | Persistent milestone (phase + session) claim, unlike the transient `STATE.md.lock`/`WAITING.json` (#3311) |
|
|
29
|
+
| `state.json` | *(none)* | `src/state-contract.cts` | Machine-readable state contract published at step boundaries (#3227) |
|
|
30
|
+
| `skill-manifest.json` | *(none)* | `init.cts`'s `cmdSkillManifest --write` | Project-scoped skill manifest (#3964) |
|
|
31
|
+
| `PATTERNS.md` | *(inline)* | `/gsd:extract-learnings` (graduation, `workflows/graduation.md`, `patterns` target) | Graduated cross-phase patterns -- distinct from the per-phase `NN-PATTERNS.md` below (#4282) |
|
|
26
32
|
|
|
27
33
|
### Version-stamped artifacts (pattern: `vX.Y-*.md`)
|
|
28
34
|
|
|
@@ -172,9 +172,12 @@ Updated after each plan completion.
|
|
|
172
172
|
**Decisions:** Reference to PROJECT.md Key Decisions table, plus recent decisions summary for quick access. Full decision log lives in PROJECT.md.
|
|
173
173
|
|
|
174
174
|
**Pending Todos:** Ideas captured via /gsd-add-todo
|
|
175
|
-
-
|
|
176
|
-
|
|
177
|
-
-
|
|
175
|
+
- One bullet per pending todo, rendered by `init.todos`'s `pending_todos_markdown`
|
|
176
|
+
(each bullet capped at 240 characters: `- [date] [area] title — [todo file](path) — Needs ...`;
|
|
177
|
+
the todo-file link is repo-relative, so the cap does not depend on checkout path length)
|
|
178
|
+
- `None yet.` when there are no pending todos
|
|
179
|
+
- No collapse-by-count fallback — every pending todo gets its own line, always
|
|
180
|
+
(see #2618 design doc for why a "count if many" fallback was rejected)
|
|
178
181
|
|
|
179
182
|
**Blockers/Concerns:** From "Next Phase Readiness" sections
|
|
180
183
|
- Issues that affect future work
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Summary Template
|
|
2
|
+
|
|
3
|
+
Template for `.planning/phases/XX-name/{phase}-{plan}-SUMMARY.md` - phase completion documentation.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## File Template
|
|
8
|
+
|
|
9
|
+
```markdown
|
|
10
|
+
---
|
|
11
|
+
phase: XX-name
|
|
12
|
+
plan: YY
|
|
13
|
+
subsystem: [primary category: auth, payments, ui, api, database, infra, testing, etc.]
|
|
14
|
+
tags: [searchable tech: jwt, stripe, react, postgres, prisma]
|
|
15
|
+
|
|
16
|
+
# Dependency graph
|
|
17
|
+
requires:
|
|
18
|
+
- phase: [prior phase this depends on]
|
|
19
|
+
provides: [what that phase built that this uses]
|
|
20
|
+
provides:
|
|
21
|
+
- [bullet list of what this phase built/delivered]
|
|
22
|
+
affects: [list of phase names or keywords that will need this context]
|
|
23
|
+
|
|
24
|
+
# Actuals (#2632) — pairs with the plan's `estimate` to calibrate future estimates.
|
|
25
|
+
# Same estimateTokens scale (chars/4 over the realized diff), never a harness token count.
|
|
26
|
+
actuals:
|
|
27
|
+
tokens: [chars/4 over files actually changed]
|
|
28
|
+
tasks: [tasks completed]
|
|
29
|
+
commits: [commits made]
|
|
30
|
+
|
|
31
|
+
# Tech tracking
|
|
32
|
+
tech-stack:
|
|
33
|
+
added: [libraries/tools added in this phase]
|
|
34
|
+
patterns: [architectural/code patterns established]
|
|
35
|
+
|
|
36
|
+
key-files:
|
|
37
|
+
created: [important files created]
|
|
38
|
+
modified: [important files modified]
|
|
39
|
+
|
|
40
|
+
key-decisions:
|
|
41
|
+
- "Decision 1"
|
|
42
|
+
- "Decision 2"
|
|
43
|
+
|
|
44
|
+
patterns-established:
|
|
45
|
+
- "Pattern 1: description"
|
|
46
|
+
- "Pattern 2: description"
|
|
47
|
+
|
|
48
|
+
requirements-completed: [] # REQUIRED — Copy ALL requirement IDs from this plan's `requirements` frontmatter field.
|
|
49
|
+
|
|
50
|
+
# Coverage metadata (#1602) — one entry per shipped deliverable. Drives DETERMINISTIC UAT routing in verify-work.
|
|
51
|
+
# OMIT this whole block for legacy/prose-only SUMMARYs — verify-work then falls back to the ## Accomplishments bullets
|
|
52
|
+
# (byte-identical behavior for un-migrated phases). See <coverage_guidance> below for the contract.
|
|
53
|
+
coverage:
|
|
54
|
+
- id: D1
|
|
55
|
+
description: "[deliverable in human-readable form — what would have been a prose ## Accomplishments bullet]"
|
|
56
|
+
requirement: "[REQ-ID from this plan's `requirements`, or omit if none]"
|
|
57
|
+
verification:
|
|
58
|
+
- kind: unit # unit | integration | e2e | automated_ui | manual_procedural | other
|
|
59
|
+
ref: "[tests/path.test.ts#test name | playwright:shot.png | command invocation]"
|
|
60
|
+
status: pass # pass | fail | unknown — from the latest run
|
|
61
|
+
human_judgment: false # REQUIRED boolean. false => may auto-pass IF every verification status is `pass`.
|
|
62
|
+
- id: D2
|
|
63
|
+
description: "[a deliverable that needs a human to sign off]"
|
|
64
|
+
verification: []
|
|
65
|
+
human_judgment: true
|
|
66
|
+
rationale: "[REQUIRED when human_judgment: true — why automation is insufficient]"
|
|
67
|
+
|
|
68
|
+
# Metrics
|
|
69
|
+
duration: Xmin
|
|
70
|
+
completed: YYYY-MM-DD
|
|
71
|
+
status: complete
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
# Phase [X]: [Name] Summary
|
|
75
|
+
|
|
76
|
+
**[Substantive one-liner describing outcome - NOT "phase complete" or "implementation finished"]**
|
|
77
|
+
|
|
78
|
+
## Performance
|
|
79
|
+
|
|
80
|
+
- **Duration:** [time] (e.g., 23 min, 1h 15m)
|
|
81
|
+
- **Started:** [ISO timestamp]
|
|
82
|
+
- **Completed:** [ISO timestamp]
|
|
83
|
+
- **Tasks:** [count completed]
|
|
84
|
+
- **Files modified:** [count]
|
|
85
|
+
|
|
86
|
+
## Accomplishments
|
|
87
|
+
- [Most important outcome]
|
|
88
|
+
- [Second key accomplishment]
|
|
89
|
+
- [Third if applicable]
|
|
90
|
+
|
|
91
|
+
## Task Commits
|
|
92
|
+
|
|
93
|
+
Each task was committed atomically:
|
|
94
|
+
|
|
95
|
+
1. **Task 1: [task name]** - `abc123f` (feat/fix/test/refactor)
|
|
96
|
+
2. **Task 2: [task name]** - `def456g` (feat/fix/test/refactor)
|
|
97
|
+
3. **Task 3: [task name]** - `hij789k` (feat/fix/test/refactor)
|
|
98
|
+
|
|
99
|
+
**Plan metadata:** `lmn012o` (docs: complete plan)
|
|
100
|
+
|
|
101
|
+
_Note: TDD tasks may have multiple commits (test → feat → refactor)_
|
|
102
|
+
|
|
103
|
+
## Files Created/Modified
|
|
104
|
+
- `path/to/file.ts` - What it does
|
|
105
|
+
- `path/to/another.ts` - What it does
|
|
106
|
+
|
|
107
|
+
## Decisions Made
|
|
108
|
+
[Key decisions with brief rationale, or "None - followed plan as specified"]
|
|
109
|
+
|
|
110
|
+
## Deviations from Plan
|
|
111
|
+
|
|
112
|
+
[If no deviations: "None - plan executed exactly as written"]
|
|
113
|
+
|
|
114
|
+
[If deviations occurred:]
|
|
115
|
+
|
|
116
|
+
### Auto-fixed Issues
|
|
117
|
+
|
|
118
|
+
**1. [Rule X - Category] Brief description**
|
|
119
|
+
- **Found during:** Task [N] ([task name])
|
|
120
|
+
- **Issue:** [What was wrong]
|
|
121
|
+
- **Fix:** [What was done]
|
|
122
|
+
- **Files modified:** [file paths]
|
|
123
|
+
- **Verification:** [How it was verified]
|
|
124
|
+
- **Committed in:** [hash] (part of task commit)
|
|
125
|
+
|
|
126
|
+
[... repeat for each auto-fix ...]
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
**Total deviations:** [N] auto-fixed ([breakdown by rule])
|
|
131
|
+
**Impact on plan:** [Brief assessment - e.g., "All auto-fixes necessary for correctness/security. No scope creep."]
|
|
132
|
+
|
|
133
|
+
## Issues Encountered
|
|
134
|
+
[Problems and how they were resolved, or "None"]
|
|
135
|
+
|
|
136
|
+
[Note: "Deviations from Plan" documents unplanned work that was handled automatically via deviation rules. "Issues Encountered" documents problems during planned work that required problem-solving.]
|
|
137
|
+
|
|
138
|
+
## User Setup Required
|
|
139
|
+
|
|
140
|
+
[If USER-SETUP.md was generated:]
|
|
141
|
+
**External services require manual configuration.** See [{phase}-USER-SETUP.md](./{phase}-USER-SETUP.md) for:
|
|
142
|
+
- Environment variables to add
|
|
143
|
+
- Dashboard configuration steps
|
|
144
|
+
- Verification commands
|
|
145
|
+
|
|
146
|
+
[If no USER-SETUP.md:]
|
|
147
|
+
None - no external service configuration required.
|
|
148
|
+
|
|
149
|
+
## Next Phase Readiness
|
|
150
|
+
[What's ready for next phase]
|
|
151
|
+
[Any blockers or concerns]
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
*Phase: XX-name*
|
|
155
|
+
*Completed: [date]*
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
<frontmatter_guidance>
|
|
159
|
+
**Purpose:** Enable automatic context assembly via dependency graph. Frontmatter makes summary metadata machine-readable so plan-phase can scan all summaries quickly and select relevant ones based on dependencies (`requires`/`provides`/`affects` create the explicit links; transitive closure follows from them).
|
|
160
|
+
|
|
161
|
+
**Subsystem/Tags:** Primary categorization + searchable technical keywords, for detecting related phases and tech-stack awareness. **Key-files:** important files for @context references in PLAN.md. **Patterns:** established conventions future phases should maintain.
|
|
162
|
+
|
|
163
|
+
**Population:** Frontmatter is populated during summary creation in execute-plan.md. See `<step name="create_summary">` for field-by-field guidance.
|
|
164
|
+
|
|
165
|
+
**Status (#2830):** `status: complete` is the default — the plan finished. Use `status: halted` instead when the plan reached a designed stop (a gate failure, a spike concluding without expanding into the full build, or any other intentional non-completion) and intentionally left tasks unfinished. `halted` is machine-read: any plan whose `depends_on` (directly or transitively) names a halted plan is reported as blocked, not offered to the executor, until the halt is resolved and re-summarized as `complete`.
|
|
166
|
+
</frontmatter_guidance>
|
|
167
|
+
|
|
168
|
+
<coverage_guidance>
|
|
169
|
+
**Purpose (#1602):** The `coverage:` block is a per-deliverable Requirements Traceability Matrix. It lets `verify-work`'s `extract_tests` step route deliverables DETERMINISTICALLY — auto-passing those proven by passing tests and reserving human UAT for genuine judgment — instead of re-deriving coverage from prose. Consumed via `gsd-tools uat classify-coverage --summary <SUMMARY>`.
|
|
170
|
+
|
|
171
|
+
**Field semantics:**
|
|
172
|
+
|
|
173
|
+
| Field | Purpose |
|
|
174
|
+
|---|---|
|
|
175
|
+
| `id` | Stable identifier (`D1`, `D2`…) for cross-referencing from UAT.md and audit reports. Must be unique within the SUMMARY. |
|
|
176
|
+
| `description` | The deliverable in human-readable form — what would have been a prose bullet. |
|
|
177
|
+
| `requirement` | Links back to a REQUIREMENTS.md REQ-ID (joins `requirements-completed`). Optional. |
|
|
178
|
+
| `verification[].kind` | Enum: `unit \| integration \| e2e \| automated_ui \| manual_procedural \| other`. |
|
|
179
|
+
| `verification[].ref` | Test path + descriptor (`file#test name`), Playwright screenshot ref, or command invocation. Required per entry. |
|
|
180
|
+
| `verification[].status` | `pass \| fail \| unknown` — populated from the latest test run. |
|
|
181
|
+
| `human_judgment` | Explicit boolean; REQUIRED. `true` always routes to a human. |
|
|
182
|
+
| `rationale` | REQUIRED when `human_judgment: true`. The audit trail for why automation is insufficient. |
|
|
183
|
+
|
|
184
|
+
**Deterministic contract (what the classifier does):**
|
|
185
|
+
- A deliverable auto-passes (no human prompt) **only** when `human_judgment: false` AND `verification` is non-empty AND every `verification[].status` is `pass`. This is the narrow, fully-proven case.
|
|
186
|
+
- **Everything else is presented to a human** — `human_judgment: true`, an empty `verification:`, any non-`pass`/`unknown` status, or any schema error. A false-negative is a redundant prompt (the status quo); a false-positive ships a bug UAT existed to catch.
|
|
187
|
+
- **Fail-safe default:** if you cannot determine coverage for a deliverable, you MUST set `human_judgment: true` with `rationale: "Coverage not determined at authoring time — verifier must classify"`. Never leave a deliverable's `human_judgment` empty, and never set it `false` just to skip the prompt — auto-pass additionally requires a passing `verification` entry, so the flag alone cannot skip the human.
|
|
188
|
+
- `coverage: []` means "no deliverables to classify" (the single-confirmation path). OMITTING the block entirely means "legacy" — `verify-work` falls back to prose `## Accomplishments` extraction unchanged.
|
|
189
|
+
</coverage_guidance>
|
|
190
|
+
|
|
191
|
+
<one_liner_rules>
|
|
192
|
+
The one-liner MUST be substantive:
|
|
193
|
+
|
|
194
|
+
**Good:** "JWT auth with refresh rotation using jose library" · "Prisma schema with User, Session, and Product models" · "Dashboard with real-time metrics via Server-Sent Events"
|
|
195
|
+
|
|
196
|
+
**Bad:** "Phase complete" · "Authentication implemented" · "Foundation finished" · "All tasks done"
|
|
197
|
+
|
|
198
|
+
The one-liner should tell someone what actually shipped.
|
|
199
|
+
</one_liner_rules>
|
|
200
|
+
|
|
201
|
+
<guidelines>
|
|
202
|
+
**Frontmatter:** MANDATORY - complete all fields. Enables automatic context assembly for future planning.
|
|
203
|
+
|
|
204
|
+
**One-liner:** Must be substantive. "JWT auth with refresh rotation using jose library" not "Authentication implemented".
|
|
205
|
+
|
|
206
|
+
**Decisions section:**
|
|
207
|
+
- Key decisions made during execution with rationale
|
|
208
|
+
- Extracted to STATE.md accumulated context
|
|
209
|
+
- Use "None - followed plan as specified" if no deviations
|
|
210
|
+
|
|
211
|
+
**After creation:** STATE.md updated with position, decisions, issues.
|
|
212
|
+
</guidelines>
|