gsdd-cli 0.19.0 → 0.19.1
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/README.md +4 -3
- package/agents/approach-explorer.md +9 -0
- package/agents/executor.md +118 -39
- package/agents/planner.md +32 -3
- package/bin/adapters/claude.mjs +9 -7
- package/bin/adapters/opencode.mjs +9 -7
- package/bin/gsdd.mjs +4 -4
- package/bin/lib/evidence-contract.mjs +216 -3
- package/bin/lib/health-truth.mjs +25 -10
- package/bin/lib/health.mjs +1 -1
- package/bin/lib/init-runtime.mjs +2 -0
- package/bin/lib/lifecycle-preflight.mjs +418 -6
- package/bin/lib/lifecycle-state.mjs +9 -4
- package/bin/lib/phase.mjs +7 -2
- package/bin/lib/plan-constants.mjs +5 -0
- package/bin/lib/rendering.mjs +4 -0
- package/bin/lib/session-fingerprint.mjs +91 -14
- package/distilled/DESIGN.md +142 -14
- package/distilled/EVIDENCE-INDEX.md +29 -5
- package/distilled/templates/approach.md +40 -0
- package/distilled/templates/delegates/approach-explorer.md +3 -0
- package/distilled/templates/delegates/plan-checker.md +14 -4
- package/distilled/workflows/audit-milestone.md +29 -1
- package/distilled/workflows/complete-milestone.md +36 -23
- package/distilled/workflows/execute.md +35 -33
- package/distilled/workflows/plan.md +18 -16
- package/distilled/workflows/verify.md +8 -8
- package/package.json +1 -1
|
@@ -11,9 +11,13 @@
|
|
|
11
11
|
import { createHash } from 'crypto';
|
|
12
12
|
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
13
13
|
import { join } from 'path';
|
|
14
|
+
import { output } from './cli-utils.mjs';
|
|
15
|
+
import { resolveWorkspaceContext } from './workspace-root.mjs';
|
|
14
16
|
|
|
15
17
|
const FINGERPRINT_FILE = '.state-fingerprint.json';
|
|
16
18
|
const FINGERPRINT_SOURCES = ['ROADMAP.md', 'SPEC.md', 'config.json'];
|
|
19
|
+
const FINGERPRINT_SCHEMA_VERSION = 2;
|
|
20
|
+
const FINGERPRINT_ALGORITHM = 'sha256:v2:exists-content';
|
|
17
21
|
|
|
18
22
|
/**
|
|
19
23
|
* Compute a SHA-256 fingerprint from the planning truth files.
|
|
@@ -23,15 +27,52 @@ const FINGERPRINT_SOURCES = ['ROADMAP.md', 'SPEC.md', 'config.json'];
|
|
|
23
27
|
export function computeFingerprint(planningDir) {
|
|
24
28
|
const hash = createHash('sha256');
|
|
25
29
|
const sources = {};
|
|
30
|
+
const files = {};
|
|
26
31
|
for (const file of FINGERPRINT_SOURCES) {
|
|
27
32
|
const filePath = join(planningDir, file);
|
|
28
|
-
const
|
|
33
|
+
const exists = existsSync(filePath);
|
|
34
|
+
const content = exists ? readFileSync(filePath, 'utf-8') : '';
|
|
35
|
+
hash.update(`${file}:${exists ? 'exists' : 'missing'}:${content}\n`);
|
|
36
|
+
sources[file] = exists;
|
|
37
|
+
files[file] = {
|
|
38
|
+
exists,
|
|
39
|
+
hash: createHash('sha256').update(content).digest('hex'),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return { hash: hash.digest('hex'), sources, files };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function computeLegacyFingerprint(planningDir) {
|
|
46
|
+
const hash = createHash('sha256');
|
|
47
|
+
const sources = {};
|
|
48
|
+
for (const file of FINGERPRINT_SOURCES) {
|
|
49
|
+
const filePath = join(planningDir, file);
|
|
50
|
+
const exists = existsSync(filePath);
|
|
51
|
+
const content = exists ? readFileSync(filePath, 'utf-8') : '';
|
|
29
52
|
hash.update(`${file}:${content}\n`);
|
|
30
|
-
sources[file] =
|
|
53
|
+
sources[file] = exists;
|
|
31
54
|
}
|
|
32
55
|
return { hash: hash.digest('hex'), sources };
|
|
33
56
|
}
|
|
34
57
|
|
|
58
|
+
export function cmdSessionFingerprint(...args) {
|
|
59
|
+
const { args: normalizedArgs, planningDir, invalid, error } = resolveWorkspaceContext(args);
|
|
60
|
+
if (invalid) {
|
|
61
|
+
console.error(error);
|
|
62
|
+
process.exitCode = 1;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const [action] = normalizedArgs;
|
|
67
|
+
if (action !== 'write') {
|
|
68
|
+
console.error('Usage: node .planning/bin/gsdd.mjs session-fingerprint write');
|
|
69
|
+
process.exitCode = 1;
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
output({ operation: 'session-fingerprint write', fingerprint: writeFingerprint(planningDir) });
|
|
74
|
+
}
|
|
75
|
+
|
|
35
76
|
/**
|
|
36
77
|
* Read the stored fingerprint from .planning/.state-fingerprint.json.
|
|
37
78
|
* Returns null if the file does not exist or is unparseable.
|
|
@@ -50,10 +91,13 @@ export function readStoredFingerprint(planningDir) {
|
|
|
50
91
|
* Write the current fingerprint to .planning/.state-fingerprint.json.
|
|
51
92
|
*/
|
|
52
93
|
export function writeFingerprint(planningDir) {
|
|
53
|
-
const { hash, sources } = computeFingerprint(planningDir);
|
|
94
|
+
const { hash, sources, files } = computeFingerprint(planningDir);
|
|
54
95
|
const data = {
|
|
96
|
+
schemaVersion: FINGERPRINT_SCHEMA_VERSION,
|
|
97
|
+
algorithm: FINGERPRINT_ALGORITHM,
|
|
55
98
|
hash,
|
|
56
99
|
sources,
|
|
100
|
+
files,
|
|
57
101
|
timestamp: new Date().toISOString(),
|
|
58
102
|
};
|
|
59
103
|
writeFileSync(join(planningDir, FINGERPRINT_FILE), JSON.stringify(data, null, 2) + '\n');
|
|
@@ -69,27 +113,33 @@ export function writeFingerprint(planningDir) {
|
|
|
69
113
|
*/
|
|
70
114
|
export function checkDrift(planningDir) {
|
|
71
115
|
const stored = readStoredFingerprint(planningDir);
|
|
72
|
-
const { hash: currentHash, sources: currentSources } = computeFingerprint(planningDir);
|
|
116
|
+
const { hash: currentHash, sources: currentSources, files: currentFiles } = computeFingerprint(planningDir);
|
|
73
117
|
|
|
74
118
|
if (!stored) {
|
|
75
119
|
return {
|
|
76
120
|
drifted: false,
|
|
77
121
|
noBaseline: true,
|
|
122
|
+
classification: 'no_baseline',
|
|
78
123
|
details: ['No stored fingerprint found — first session or fingerprint was cleared.'],
|
|
79
124
|
stored: null,
|
|
80
|
-
current: { hash: currentHash, sources: currentSources },
|
|
125
|
+
current: { hash: currentHash, sources: currentSources, files: currentFiles },
|
|
126
|
+
files: [],
|
|
81
127
|
};
|
|
82
128
|
}
|
|
83
129
|
|
|
84
|
-
const
|
|
130
|
+
const isLegacy = !stored.schemaVersion && !stored.files;
|
|
131
|
+
const comparison = isLegacy ? computeLegacyFingerprint(planningDir) : { hash: currentHash };
|
|
132
|
+
const drifted = stored.hash !== comparison.hash;
|
|
85
133
|
const details = [];
|
|
134
|
+
const files = drifted
|
|
135
|
+
? FINGERPRINT_SOURCES.map((file) => classifyFileDrift(file, stored, currentSources, currentFiles, { legacy: isLegacy }))
|
|
136
|
+
: FINGERPRINT_SOURCES.map((file) => ({ file, status: 'unchanged' }));
|
|
86
137
|
if (drifted) {
|
|
87
|
-
for (const file of
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (
|
|
91
|
-
else if (
|
|
92
|
-
else if (was && now) details.push(`${file} may have changed`);
|
|
138
|
+
for (const file of files) {
|
|
139
|
+
if (file.status === 'created') details.push(`${file.file} created`);
|
|
140
|
+
else if (file.status === 'removed') details.push(`${file.file} removed`);
|
|
141
|
+
else if (file.status === 'changed') details.push(`${file.file} changed`);
|
|
142
|
+
else if (file.status === 'unknown') details.push(`${file.file} may have changed`);
|
|
93
143
|
}
|
|
94
144
|
if (details.length === 0) {
|
|
95
145
|
details.push('Planning state hash changed since last recorded session.');
|
|
@@ -99,8 +149,35 @@ export function checkDrift(planningDir) {
|
|
|
99
149
|
return {
|
|
100
150
|
drifted,
|
|
101
151
|
noBaseline: false,
|
|
152
|
+
classification: drifted ? 'planning_state_drift' : 'clean',
|
|
153
|
+
compatibility: isLegacy ? 'legacy_v1' : null,
|
|
154
|
+
needsBaselineRefresh: isLegacy && !drifted,
|
|
102
155
|
details,
|
|
103
|
-
|
|
104
|
-
|
|
156
|
+
files,
|
|
157
|
+
stored: {
|
|
158
|
+
hash: stored.hash,
|
|
159
|
+
timestamp: stored.timestamp,
|
|
160
|
+
schemaVersion: stored.schemaVersion ?? null,
|
|
161
|
+
algorithm: stored.algorithm ?? null,
|
|
162
|
+
files: stored.files ?? null,
|
|
163
|
+
},
|
|
164
|
+
current: { hash: currentHash, sources: currentSources, files: currentFiles },
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function classifyFileDrift(file, stored, currentSources, currentFiles, { legacy = false } = {}) {
|
|
169
|
+
const was = stored.sources?.[file] ?? false;
|
|
170
|
+
const now = currentSources[file];
|
|
171
|
+
|
|
172
|
+
if (was && !now) return { file, status: 'removed' };
|
|
173
|
+
if (!was && now) return { file, status: 'created' };
|
|
174
|
+
if (!was && !now) return { file, status: 'unchanged' };
|
|
175
|
+
if (legacy) return { file, status: 'unknown' };
|
|
176
|
+
|
|
177
|
+
const storedFile = stored.files?.[file];
|
|
178
|
+
if (!storedFile?.hash) return { file, status: 'unknown' };
|
|
179
|
+
return {
|
|
180
|
+
file,
|
|
181
|
+
status: storedFile.hash === currentFiles[file].hash ? 'unchanged' : 'changed',
|
|
105
182
|
};
|
|
106
183
|
}
|
package/distilled/DESIGN.md
CHANGED
|
@@ -69,6 +69,8 @@
|
|
|
69
69
|
56. [Executable Brownfield Routing And Widen-Only Escalation](#d56---executable-brownfield-routing-and-widen-only-escalation)
|
|
70
70
|
57. [Bounded Brownfield Growth And Context-Preserving Milestone Handoff](#d57---bounded-brownfield-growth-and-context-preserving-milestone-handoff)
|
|
71
71
|
58. [Local Workflow Helper Launcher](#d58---local-workflow-helper-launcher)
|
|
72
|
+
59. [Continuity Authority And Planning-State Drift](#d59---continuity-authority-and-planning-state-drift)
|
|
73
|
+
60. [Release Closeout Contract](#d60---release-closeout-contract)
|
|
72
74
|
|
|
73
75
|
---
|
|
74
76
|
|
|
@@ -151,13 +153,13 @@ The same over-distillation pattern had also flattened `roadmapper.md`, `synthesi
|
|
|
151
153
|
|
|
152
154
|
**Executor leverage audit (2026-03-13):**
|
|
153
155
|
|
|
154
|
-
The executor was the last un-audited core lifecycle role. At 89 lines it was the most under-structured role contract in the system — no XML section boundaries, no
|
|
156
|
+
The executor was the last un-audited core lifecycle role. At 89 lines it was the most under-structured role contract in the system — no XML section boundaries, no explicit context-intake tiers, no scope boundary, no typed output example, no auth-gate protocol, no completion checklist. The audit applied the same S12 hardening pattern.
|
|
155
157
|
|
|
156
|
-
- **Executor kept from GSD:** mandatory
|
|
158
|
+
- **Executor kept from GSD:** mandatory context-intake discipline, explicit deviation-rule examples (null pointers, missing auth, missing dependency, new DB tables), auth-gate protocol (401/403 recognition, checkpoint return with exact auth steps), substantive summary quality gate, TDD RED/GREEN/REFACTOR steps with infrastructure detection, self-check discipline, and completion checklist.
|
|
157
159
|
- **Executor intentionally stripped:** wave-based parallelization, agent tracking journal, segment execution patterns A/B/C, auto-mode checkpoint routing (`auto_advance` config), per-task commit format `{type}({phase}-{plan}):`, `gsd-tools.cjs` CLI commands, template path references (`~/.claude/`), `user_setup` generation, `executor_model` selection, and codebase-map sync with dropped files (`STRUCTURE.md`, `INTEGRATIONS.md`).
|
|
158
160
|
- **Executor gained in GSDD:** XML-bounded section structure, explicit scope boundary (plan-scoped, does not own planning/verification/milestone audit), typed SUMMARY.md output example with YAML frontmatter, portable auth-gate protocol (checkpoint:user with exact steps, not vendor-specific checkpoint return format), and execution-loop alignment with the current GSDD plan schema (`checkpoint:user`, `checkpoint:review`, change-impact discipline).
|
|
159
161
|
|
|
160
|
-
The accompanying workflow alignment pass on `distilled/workflows/execute.md` added four targeted changes:
|
|
162
|
+
The accompanying workflow alignment pass on `distilled/workflows/execute.md` added four targeted changes: tiered context-intake enforcement, auth-gate routing in the checkpoint protocol, concrete deviation-rule examples matching the role contract, and a substantive summary quality gate.
|
|
161
163
|
|
|
162
164
|
This hardening pass also clarified a reusable architectural rule: strict portable workflows are not enough if the canonical role contracts underneath them are flattened into prose. Role strictness and workflow strictness both matter.
|
|
163
165
|
|
|
@@ -581,7 +583,7 @@ Design principle unchanged: derive state from primary artifacts (ROADMAP.md, SPE
|
|
|
581
583
|
|
|
582
584
|
**GSD:** No structural invariant tests. Framework correctness relies on manual review and ad-hoc checking.
|
|
583
585
|
|
|
584
|
-
**GSDD:**
|
|
586
|
+
**GSDD:** The guard and invariant suites enforce structural properties across framework markdown files. Every assertion message includes a `FIX:` instruction so CI agents can self-remediate.
|
|
585
587
|
|
|
586
588
|
**Suite inventory:**
|
|
587
589
|
|
|
@@ -600,7 +602,7 @@ Design principle unchanged: derive state from primary artifacts (ROADMAP.md, SPE
|
|
|
600
602
|
|
|
601
603
|
**Evidence:**
|
|
602
604
|
|
|
603
|
-
- `tests/gsdd.invariants.test.cjs`
|
|
605
|
+
- `tests/gsdd.invariants.test.cjs` and `tests/gsdd.guards.test.cjs` enforce structural drift checks with actionable `FIX:` messages
|
|
604
606
|
- OpenAI Harness Engineering blog (Feb 2026): "error messages as enforcement mechanism"
|
|
605
607
|
- External audit (2026-03-13): recommendation #4 "Mechanize the framework's invariants"
|
|
606
608
|
- GSD source: no equivalent test infrastructure
|
|
@@ -954,6 +956,7 @@ Implementation lives under `bin/lib/`:
|
|
|
954
956
|
| E6 | ERROR | `.planning/templates/research/` missing or empty |
|
|
955
957
|
| E7 | ERROR | `.planning/templates/codebase/` missing or empty |
|
|
956
958
|
| E8 | ERROR | `.planning/templates/` missing critical root files (`spec.md`, `roadmap.md`, `auth-matrix.md`) |
|
|
959
|
+
| E9 | ERROR | `.planning/templates/brownfield-change/` missing or missing critical files (`CHANGE.md`, `HANDOFF.md`, `VERIFICATION.md`) |
|
|
957
960
|
| W1 | WARN | `generation-manifest.json` missing |
|
|
958
961
|
| W2 | WARN | Template files modified locally (hash mismatch vs manifest) |
|
|
959
962
|
| W3 | WARN | Template/role files missing from disk but listed in manifest |
|
|
@@ -963,8 +966,8 @@ Implementation lives under `bin/lib/`:
|
|
|
963
966
|
| W7 | WARN | `distilled/DESIGN.md` health check table differs from implemented check IDs |
|
|
964
967
|
| W8 | WARN | `distilled/README.md` workflow inventory differs from `distilled/workflows/` |
|
|
965
968
|
| W9 | WARN | `.internal-research/gaps.md` references missing repo-local paths |
|
|
966
|
-
| W10 | WARN | ROADMAP
|
|
967
|
-
| W11 | WARN | Installed generated runtime surfaces drift from current render output |
|
|
969
|
+
| W10 | WARN | ROADMAP lifecycle status drift, including requirement checkbox and overview/detail phase status mismatches |
|
|
970
|
+
| W11 | WARN | Installed generated runtime/helper surfaces drift from current render output |
|
|
968
971
|
| W12 | WARN | Planning state drifted since last recorded session (fingerprint mismatch) |
|
|
969
972
|
| I1 | INFO | Generation manifest `frameworkVersion` differs from current `FRAMEWORK_VERSION` |
|
|
970
973
|
| I2 | INFO | Phase completion count from ROADMAP |
|
|
@@ -987,15 +990,15 @@ Implementation lives under `bin/lib/`:
|
|
|
987
990
|
|
|
988
991
|
3. **Pre-init guard.** If `.planning/config.json` doesn't exist, output a one-line message and exit 1. No partial checks — the workspace is simply not initialized.
|
|
989
992
|
|
|
990
|
-
4. **Split structural vs truth checks.** `bin/lib/health.mjs` keeps the structural workspace checks. `bin/lib/health-truth.mjs` holds the always-on cross-file truth checks (W7-
|
|
993
|
+
4. **Split structural vs truth checks.** `bin/lib/health.mjs` keeps the structural workspace checks. `bin/lib/health-truth.mjs` holds the always-on cross-file truth checks (W7-W12) so the health surface can grow without turning the main command into one monolith.
|
|
991
994
|
|
|
992
995
|
5. **Reuses existing modules.** `readManifest()` and `detectModifications()` from `manifest.mjs` handle W1-W3. `isProjectInitialized()` pattern from `models.mjs` handles the pre-init guard. Truth checks stay read-only and operate on repo-local artifacts only when those framework files exist.
|
|
993
996
|
|
|
994
|
-
6. **Framework-source mode skips installed-project template checks.** Inside the GSDD framework repo itself, `distilled/templates/` is the source of truth and `.planning/templates/` is intentionally absent. `npx -y gsdd-cli health` therefore skips the installed-project template/manifest checks (E3-
|
|
997
|
+
6. **Framework-source mode skips installed-project template checks.** Inside the GSDD framework repo itself, `distilled/templates/` is the source of truth and `.planning/templates/` is intentionally absent. `npx -y gsdd-cli health` therefore skips the installed-project template/manifest checks (E3-E9, W1-W3) in framework-source mode instead of producing false positives during self-health runs.
|
|
995
998
|
|
|
996
999
|
**What was removed vs GSD:**
|
|
997
1000
|
- `--repair` flag and associated repair actions
|
|
998
|
-
- Error codes E001-E005/W001-W007 (replaced with simpler E1-
|
|
1001
|
+
- Error codes E001-E005/W001-W007 (replaced with simpler E1-E9/W1-W12/I1-I3)
|
|
999
1002
|
- STATE.md checks (GSDD has no STATE.md per D7)
|
|
1000
1003
|
- PROJECT.md checks (GSDD uses SPEC.md, not checked by health — it's workflow-authored)
|
|
1001
1004
|
- Phase directory naming format checks (GSDD uses flat numbered files, not NN-name directories)
|
|
@@ -1365,6 +1368,7 @@ Both paths produce identical output: `{padded_phase}-APPROACH.md` in the phase d
|
|
|
1365
1368
|
| Questioning style | Rigid 4-question batched loop | Adaptive convergence (2-6 questions depending on complexity) | Fixed batch sizes don't match decision complexity. Some areas resolve in 2 questions, others need 6 |
|
|
1366
1369
|
| Pre-question research | No research before asking | Research subagent per technical area returns structured summary before asking | Users make better decisions when presented with researched options and trade-offs |
|
|
1367
1370
|
| Quality gate | None | Self-check before writing APPROACH.md (concrete decisions, no vague language, source backing, scope compliance) | Prevents weak outputs that force re-asking during planning |
|
|
1371
|
+
| Alignment proof gate | None | `APPROACH.md` records `alignment_status: user_confirmed` or explicit `approved_skip`, and planning validates this before goal-backward planning when `workflow.discuss: true` | Prevents native or existing-artifact paths from turning mandatory discussion into artifact theater |
|
|
1368
1372
|
| Intermediate persistence | No persistence until final output | Confirmed decisions written to disk incrementally | Protects against context limits in long conversations |
|
|
1369
1373
|
| Context loading | "Read everything" | JIT extraction guidance (e.g., "From SPEC.md read ONLY locked decisions") | Prevents context pollution with irrelevant content |
|
|
1370
1374
|
| Plan-checker integration | None | New `approach_alignment` dimension in plan-checker | Verifies plans honor approach decisions, not just requirements |
|
|
@@ -1398,11 +1402,11 @@ Isolating research in subagents and returning compressed summaries follows the C
|
|
|
1398
1402
|
|
|
1399
1403
|
**Trade-offs:**
|
|
1400
1404
|
|
|
1401
|
-
- Benefit: planner receives locked user decisions instead of guessing approaches; plan-checker can verify approach alignment; context stays lean via research isolation
|
|
1405
|
+
- Benefit: planner receives locked user decisions instead of guessing approaches; plan-checker can verify approach alignment; existing APPROACH artifacts are not trusted unless their alignment proof is valid; context stays lean via research isolation
|
|
1402
1406
|
- Cost: adds one interactive step before planning (~5-15 minutes of user time per phase); hybrid architecture is more complex than a single monolithic workflow
|
|
1403
1407
|
- Mitigation: `workflow.discuss: true|false` toggle in `.planning/config.json` allows skipping with explicit `reduced_alignment` reporting; taste areas skip research entirely. Default is `false` (opt-in) to stay consistent with GSDD's stripped-down identity; users enable it explicitly
|
|
1404
1408
|
|
|
1405
|
-
**GSDD implementation:** `agents/approach-explorer.md` (role contract), `distilled/templates/delegates/approach-explorer.md` (thin delegate), `distilled/templates/approach.md` (output template), `distilled/workflows/plan.md` (`<approach_exploration>` section), `agents/planner.md` (`<approach_decisions>` section), `distilled/templates/delegates/plan-checker.md` (`approach_alignment` dimension), `bin/adapters/claude.mjs` + `bin/adapters/opencode.mjs` + `bin/adapters/codex.mjs` (native agent rendering)
|
|
1409
|
+
**GSDD implementation:** `agents/approach-explorer.md` (role contract), `distilled/templates/delegates/approach-explorer.md` (thin delegate), `distilled/templates/approach.md` (output template), `distilled/workflows/plan.md` (`<approach_exploration>` section), `agents/planner.md` (`<approach_decisions>` section), `distilled/templates/delegates/plan-checker.md` (`approach_alignment` dimension), `bin/adapters/claude.mjs` + `bin/adapters/opencode.mjs` + `bin/adapters/codex.mjs` (native agent rendering), `tests/gsdd.guards.test.cjs`, `tests/gsdd.plan.adapters.test.cjs`, and `tests/gsdd.scenarios.test.cjs` (alignment-proof propagation coverage)
|
|
1406
1410
|
|
|
1407
1411
|
---
|
|
1408
1412
|
|
|
@@ -2157,7 +2161,8 @@ Sub-gap (b) was closed by D28's `<persistence>` mandate and guarded by G30. Sub-
|
|
|
2157
2161
|
- it reports blockers, owned writes, mutation expectations, and lifecycle posture
|
|
2158
2162
|
- it does not mutate ROADMAP or milestone state itself
|
|
2159
2163
|
- Keep `gsdd phase-status` as the only explicit ROADMAP mutator for phase-state transitions.
|
|
2160
|
-
- Require transition-sensitive workflow contracts to call the shared preflight seam instead of narrating their own lifecycle inference.
|
|
2164
|
+
- Require transition-sensitive workflow contracts, including plan creation, to call the shared preflight seam instead of narrating their own lifecycle inference.
|
|
2165
|
+
- Treat planning-state drift as warning-only for read-only surfaces and blocking for owned-write surfaces, with file-level drift details from the session fingerprint helper.
|
|
2161
2166
|
- Preserve `progress` as read-only and make it explicitly defer any recommended transition back to the downstream workflow's own preflight gate.
|
|
2162
2167
|
|
|
2163
2168
|
**Why this fits the codebase:**
|
|
@@ -2170,7 +2175,9 @@ Sub-gap (b) was closed by D28's `<persistence>` mandate and guarded by G30. Sub-
|
|
|
2170
2175
|
- `.planning/ROADMAP.md` (Phase 30 success criteria)
|
|
2171
2176
|
- `bin/lib/lifecycle-preflight.mjs`
|
|
2172
2177
|
- `bin/lib/lifecycle-state.mjs`
|
|
2178
|
+
- `bin/lib/session-fingerprint.mjs`
|
|
2173
2179
|
- `bin/gsdd.mjs`
|
|
2180
|
+
- `distilled/workflows/plan.md`
|
|
2174
2181
|
- `distilled/workflows/execute.md`
|
|
2175
2182
|
- `distilled/workflows/verify.md`
|
|
2176
2183
|
- `distilled/workflows/audit-milestone.md`
|
|
@@ -2179,6 +2186,7 @@ Sub-gap (b) was closed by D28's `<persistence>` mandate and guarded by G30. Sub-
|
|
|
2179
2186
|
- `distilled/workflows/resume.md`
|
|
2180
2187
|
- `distilled/workflows/progress.md`
|
|
2181
2188
|
- `tests/phase.test.cjs`
|
|
2189
|
+
- `tests/session-fingerprint.test.cjs`
|
|
2182
2190
|
- `tests/gsdd.guards.test.cjs`
|
|
2183
2191
|
- `tests/gsdd.scenarios.test.cjs`
|
|
2184
2192
|
- GSD comparison source: `get-shit-done/workflows/progress.md` still keeps lifecycle routing inside the workflow surface rather than through a shared helper seam, so this is an intentional GSDD tightening.
|
|
@@ -2188,7 +2196,7 @@ Sub-gap (b) was closed by D28's `<persistence>` mandate and guarded by G30. Sub-
|
|
|
2188
2196
|
- `progress` can continue reporting lifecycle posture without inheriting write authority or becoming a hidden transition surface.
|
|
2189
2197
|
- Phase 31 can build evidence-gated closure on top of a stable deterministic preflight contract instead of competing lifecycle entry logic.
|
|
2190
2198
|
|
|
2191
|
-
**GSDD implementation:** `bin/lib/lifecycle-preflight.mjs`, `bin/lib/lifecycle-state.mjs`, `bin/gsdd.mjs`, `bin/lib/init.mjs`, `distilled/workflows/execute.md`, `distilled/workflows/verify.md`, `distilled/workflows/audit-milestone.md`, `distilled/workflows/complete-milestone.md`, `distilled/workflows/new-milestone.md`, `distilled/workflows/resume.md`, `distilled/workflows/progress.md`, `tests/phase.test.cjs`, `tests/gsdd.guards.test.cjs`, `tests/gsdd.scenarios.test.cjs`
|
|
2199
|
+
**GSDD implementation:** `bin/lib/lifecycle-preflight.mjs`, `bin/lib/lifecycle-state.mjs`, `bin/lib/session-fingerprint.mjs`, `bin/gsdd.mjs`, `bin/lib/init.mjs`, `distilled/workflows/plan.md`, `distilled/workflows/execute.md`, `distilled/workflows/verify.md`, `distilled/workflows/audit-milestone.md`, `distilled/workflows/complete-milestone.md`, `distilled/workflows/new-milestone.md`, `distilled/workflows/resume.md`, `distilled/workflows/progress.md`, `tests/phase.test.cjs`, `tests/session-fingerprint.test.cjs`, `tests/gsdd.guards.test.cjs`, `tests/gsdd.scenarios.test.cjs`
|
|
2192
2200
|
|
|
2193
2201
|
---
|
|
2194
2202
|
|
|
@@ -2646,6 +2654,126 @@ Sub-gap (b) was closed by D28's `<persistence>` mandate and guarded by G30. Sub-
|
|
|
2646
2654
|
- Generated governance remains compact and routing-focused because helper-surface instructions stay out of `AGENTS.md`.
|
|
2647
2655
|
- Cross-platform proof is stronger for the local-helper seam itself, but direct live validation still needs to stay conservative by environment: the repo now has focused tests plus Windows fixture proof; Linux/WSL live consumer validation remains a separate evidence question.
|
|
2648
2656
|
|
|
2657
|
+
## D59 - Continuity Authority And Planning-State Drift
|
|
2658
|
+
|
|
2659
|
+
**Decision (2026-04-27):** Workspine continuity authority is split by surface. Git/worktree truth owns integration visibility and overwrite risk, `.planning/` owns local workflow contracts, phase artifacts own phase-local scope and proof, generated runtime surfaces own consumed helper/adapter freshness, and compressed judgment remains advisory context. Planning-state drift must stay warning-only for read-only/reporting surfaces, but mutating lifecycle surfaces must not silently proceed through material drift.
|
|
2660
|
+
|
|
2661
|
+
**Context:**
|
|
2662
|
+
- `.planning/` remains local-only by default in this framework repo. That preserves privacy and avoids noisy framework-internal planning commits, but it also means planning state can drift across sessions without git history protecting it.
|
|
2663
|
+
- Gap `I46` showed the concrete failure: one session wrote milestone state under ignored `.planning/`, another session read stale planning state and nearly routed execution as if the milestone did not exist.
|
|
2664
|
+
- Gap `S6` showed the related judgment failure: fresh sessions can recover artifact structure while losing the active constraints, unresolved uncertainty, decision posture, and anti-regression rules that explain how to continue safely.
|
|
2665
|
+
- Existing helper seams already detect part of the risk: `session-fingerprint.mjs` fingerprints `.planning/ROADMAP.md`, `.planning/SPEC.md`, and `.planning/config.json`; `lifecycle-preflight.mjs` exposes drift as `planning_state_drift`; `health` reports the same condition as `W12`.
|
|
2666
|
+
|
|
2667
|
+
**Authority matrix:**
|
|
2668
|
+
|
|
2669
|
+
| Surface | Owns | Does not own | Provenance check | Drift signal | Stop condition | Proof needed |
|
|
2670
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
2671
|
+
| Git branch/HEAD | Integration surface identity, commit baseline, branch-local work context | Planning truth, phase status, judgment | `git rev-parse --abbrev-ref HEAD`; `git rev-parse --short HEAD` | Unexpected branch or HEAD relative to the active plan/change | Mutating workflow targets a different branch or HEAD than the active plan/change declares | Captured branch/HEAD before mutation; explicit acknowledgement if mismatched |
|
|
2672
|
+
| Staged changes | Pending commit contents and delivery visibility risk | Final repo truth until committed; planning authority | `git diff --name-only --cached` | Staged paths outside declared write set | Staged work overlaps unrelated scope or would be accidentally included | Staged path list reviewed against plan write set |
|
|
2673
|
+
| Unstaged changes | Local uncommitted edits and overwrite/conflict risk | Approved implementation state; phase closure | `git diff --name-only` | Dirty tracked files outside declared write set | Mutating workflow would overwrite or reinterpret unrelated edits | Dirty path list reviewed; user decision if conflict or overlap exists |
|
|
2674
|
+
| Untracked files | Local-only artifacts and possible proof gaps | Durable repo truth; public/delivery evidence | `git status --porcelain=v1` | Untracked required artifacts, generated dirs, or scope-expanding files | Required proof/output exists only untracked when closure claims tracked truth | Required artifacts are tracked intentionally or explicitly classified local-only |
|
|
2675
|
+
| `.planning/SPEC.md` | Local product/workflow requirements and active milestone requirement truth | Git-tracked public truth in the framework repo; branch delivery state | Read active requirements/current state; compare to roadmap and trackers | `W12`; mismatch with ROADMAP/TODO/gaps; stale active milestone | Mutating lifecycle action depends on stale or contradictory requirements | Fresh read plus drift acknowledgement/blocking behavior before mutation |
|
|
2676
|
+
| `.planning/ROADMAP.md` | Active milestone/phase ordering, status, success criteria, stop/replan contract | Artifact existence proof; implementation completion by itself | Read active phase section; lifecycle evaluator/preflight | `W12`; overview/detail mismatch; phase artifact mismatch | Execute/verify/audit/complete would act on stale or contradictory roadmap state | Preflight passes or blocks; phase status agrees with artifacts |
|
|
2677
|
+
| Phase PLAN/SUMMARY/VERIFICATION | Phase-local scope, execution result, verification result, compressed judgment handoff | Milestone-wide truth alone; git integration truth; generated runtime freshness | Check phase directory and required artifact sequence | PLAN without SUMMARY; SUMMARY missing for verify; VERIFICATION missing for completed phase | Execute without valid pending plan; verify without summary; close phase without verification | Required artifact exists, is substantive, and matches roadmap status |
|
|
2678
|
+
| Checkpoint files | Session-local resume context and mid-session compressed judgment | Durable status; routing authority over fresh roadmap/git truth | `.planning/.continue-here.md` and `.planning/.continue-here.bak` presence/classification | Checkpoint narrative conflicts with branch/worktree/planning truth; stale generic checkpoint | Resume would route from materially misleading checkpoint without acknowledgement | Resume surfaces checkpoint/planning/git split; material mismatch requires acknowledgement |
|
|
2679
|
+
| Brownfield CHANGE/HANDOFF/VERIFICATION | Medium-scope brownfield operational anchor, judgment handoff, closeout proof | Milestone phase state; roadmap-owned lifecycle; generic scratchpad | `.planning/brownfield-change/*` presence and lifecycle-state classification | Artifact branch/write-scope mismatch; missing sibling file; stale next action | Resume/progress would treat stale brownfield artifact as current without warning/acknowledgement | CHANGE primary, HANDOFF judgment-only, VERIFICATION proof; mismatch handled by progress/resume split |
|
|
2680
|
+
| Milestone audit | Milestone closure evidence and pass/fail posture | Phase execution; public release/delivery unless evidence says so | `.planning/<version>-MILESTONE-AUDIT.md`, `status: passed`, evidence contract | Missing audit for completion; audit not passed; evidence gaps | `complete-milestone` without passed audit or required evidence | Audit artifact exists, passed, and required evidence kinds are present |
|
|
2681
|
+
| Generated runtime surfaces | Consumed local runtime/helper surfaces generated from authored source | Authored workflow truth; planning status; branch truth | `gsdd health --json` runtime freshness and manifest comparison | `W11` drift from current render output | Phase behavior depends on generated-surface parity, or closure claims runtime freshness | Run the normal update path only when needed; health/checks prove freshness |
|
|
2682
|
+
|
|
2683
|
+
**Decision rules:**
|
|
2684
|
+
- Read-only/reporting surfaces may warn on planning-state drift and continue. They must not refresh or mutate the planning fingerprint as a side effect.
|
|
2685
|
+
- Owned-write lifecycle surfaces must treat material planning-state drift as a stop or explicit acknowledgement boundary before writing summary, verification, milestone, roadmap, or checkpoint-cleanup artifacts.
|
|
2686
|
+
- No-baseline fingerprint state is not itself proof of drift. It should be classified explicitly, but it must not strand first-session users unless another contradiction exists.
|
|
2687
|
+
- Compressed judgment remains the four-section `<judgment>` shape (`active_constraints`, `unresolved_uncertainty`, `decision_posture`, `anti_regression`) and remains subordinate to operational state.
|
|
2688
|
+
- A tracked coordination artifact is not justified by Phase 44 evidence alone. It becomes necessary only if deterministic local checks cannot prevent stale-read/overwrite behavior or if a future release claim requires fresh-clone/public evidence.
|
|
2689
|
+
|
|
2690
|
+
**Evidence:**
|
|
2691
|
+
- `.planning/phases/44-continuity-authority-and-persistence/44-APPROACH.md`
|
|
2692
|
+
- `.planning/phases/44-continuity-authority-and-persistence/44-PLAN.md`
|
|
2693
|
+
- `.planning/SPEC.md` (`REL-01`)
|
|
2694
|
+
- `.planning/ROADMAP.md` (Phase 44)
|
|
2695
|
+
- `.internal-research/gaps.md` (`I46`, `S6`)
|
|
2696
|
+
- `bin/lib/session-fingerprint.mjs`
|
|
2697
|
+
- `bin/lib/lifecycle-preflight.mjs`
|
|
2698
|
+
- `bin/lib/runtime-freshness.mjs`
|
|
2699
|
+
- `distilled/workflows/progress.md`
|
|
2700
|
+
- `distilled/workflows/resume.md`
|
|
2701
|
+
- `distilled/workflows/execute.md`
|
|
2702
|
+
- `distilled/workflows/verify.md`
|
|
2703
|
+
- `distilled/workflows/audit-milestone.md`
|
|
2704
|
+
- `distilled/workflows/complete-milestone.md`
|
|
2705
|
+
- `distilled/workflows/new-milestone.md`
|
|
2706
|
+
- `distilled/templates/brownfield-change/CHANGE.md`
|
|
2707
|
+
- `distilled/templates/brownfield-change/HANDOFF.md`
|
|
2708
|
+
- `distilled/templates/brownfield-change/VERIFICATION.md`
|
|
2709
|
+
- `tests/session-fingerprint.test.cjs`
|
|
2710
|
+
- `tests/phase.test.cjs`
|
|
2711
|
+
|
|
2712
|
+
**Consequences:**
|
|
2713
|
+
- Phase execution can remain local-first without pretending ignored `.planning/` files are unconditional authority.
|
|
2714
|
+
- Planning drift becomes a concrete lifecycle safety signal rather than a generic health warning that agents can ignore.
|
|
2715
|
+
- The design avoids adding a scratchpad or second state system while preserving enough compressed judgment to guide cold-start continuation.
|
|
2716
|
+
- The remaining implementation question is narrow: make helper output and targeted tests reflect this authority split without widening Phase 44 into generated-surface or release-closeout work.
|
|
2717
|
+
|
|
2718
|
+
---
|
|
2719
|
+
|
|
2720
|
+
## D60 - Release Closeout Contract
|
|
2721
|
+
|
|
2722
|
+
**Decision (2026-04-27, enforced 2026-04-27):** Release-quality milestone closeout uses a release claim posture layered over the existing evidence posture matrix. The allowed postures are `repo_closeout`, `runtime_validated_closeout`, and `delivery_supported_closeout`; each posture must stay within the fixed evidence kinds `code`, `test`, `runtime`, `delivery`, and `human`.
|
|
2723
|
+
|
|
2724
|
+
**Context:**
|
|
2725
|
+
- D50 already defined the closure evidence matrix for `verify`, `audit-milestone`, and `complete-milestone`, but `repo_only` and `delivery_sensitive` are evidence bars rather than wording boundaries.
|
|
2726
|
+
- D59 clarified that `.planning/` remains local-only by default, generated runtime surfaces own their own freshness, and public/delivery claims need git/worktree or tracked repo-visible proof.
|
|
2727
|
+
- Phase 45 needed a way to close repo-local milestone work honestly without implying GitHub Releases, package publishes, runtime parity, generated-surface freshness, or external availability.
|
|
2728
|
+
- GitHub Releases remain explicitly deferred under `LSC-05`, so release closeout cannot depend on public release objects unless a later milestone approves them.
|
|
2729
|
+
|
|
2730
|
+
**Decision:**
|
|
2731
|
+
- Add release claim posture semantics to `bin/lib/evidence-contract.mjs` without adding evidence kinds or replacing delivery postures.
|
|
2732
|
+
- Define the three postures as claim boundaries:
|
|
2733
|
+
- `repo_closeout`: default; permits repo-local closeout only and must not imply public support, runtime validation, delivery, publication, or generated-surface freshness.
|
|
2734
|
+
- `runtime_validated_closeout`: permits claims about a named runtime behavior or runtime surface only when `runtime` evidence exists for that exact runtime or surface.
|
|
2735
|
+
- `delivery_supported_closeout`: permits externally consumed release, install, support, or delivery claims only when the `delivery_sensitive` evidence bar is satisfied.
|
|
2736
|
+
- Thread the posture through `audit-milestone` as audit-owned release closeout metadata: unsupported claims, waivers, deferrals, and contradiction checks are recorded with the audit evidence contract.
|
|
2737
|
+
- Make `complete-milestone` inherit the audit posture and stop when unsupported claims, invalid waivers, missing evidence, incompatible posture metadata, or failed claim-scoped contradiction checks remain.
|
|
2738
|
+
- Keep `verify` out of the main release-claim decision path; phase verification still records evidence, while milestone audit and completion own release closeout.
|
|
2739
|
+
- Enforce the inherited contract in `lifecycle-preflight complete-milestone` so milestone completion cannot proceed from a passed audit that lacks release-claim metadata or still contains unsupported stronger claims, invalid waivers, missing required evidence, incompatible posture metadata, or failed claim-scoped contradiction checks.
|
|
2740
|
+
|
|
2741
|
+
**Why this fits the codebase:**
|
|
2742
|
+
- It preserves the compact D50 evidence matrix and avoids a new `release` evidence kind.
|
|
2743
|
+
- It avoids a new workflow lane or `gsdd-release` command by using the existing closeout surfaces.
|
|
2744
|
+
- It lets repo-local milestones close without fabricated delivery proof while preventing stronger public/runtime/delivery language from outrunning evidence.
|
|
2745
|
+
- It respects D59: local-only planning artifacts can support internal closeout, but public release/support claims need tracked public or repo-visible evidence.
|
|
2746
|
+
|
|
2747
|
+
**Waiver and deferral rule:**
|
|
2748
|
+
Waivers may narrow a claim posture or defer an unsupported claim, but they never satisfy missing required evidence for the stronger claim. Deferrals must name the unsupported claim, missing evidence kind(s), and later workflow or milestone candidate when known.
|
|
2749
|
+
|
|
2750
|
+
**Contradiction checks:**
|
|
2751
|
+
Closeout must check evidence, public-surface, runtime, delivery, planning-drift, and generated-surface contradictions. Generated-surface drift blocks only claims that depend on generated runtime/helper freshness; it does not fail unrelated `repo_closeout` claims.
|
|
2752
|
+
|
|
2753
|
+
Posture compatibility is part of that closeout contract: `repo_closeout` and `runtime_validated_closeout` are repo-local wording boundaries over `repo_only`, while `delivery_supported_closeout` requires the `delivery_sensitive` evidence bar.
|
|
2754
|
+
|
|
2755
|
+
**Evidence:**
|
|
2756
|
+
- `.planning/phases/45-release-closeout-contract/45-APPROACH.md`
|
|
2757
|
+
- `.planning/phases/45-release-closeout-contract/45-PLAN.md`
|
|
2758
|
+
- `.planning/phases/48-generated-helper-and-closeout-contract-parity/48-PLAN.md`
|
|
2759
|
+
- `.planning/research/45-RESEARCH.md`
|
|
2760
|
+
- `.planning/SPEC.md` (`REL-02`, deferred `LSC-05`)
|
|
2761
|
+
- `.planning/ROADMAP.md` (Phase 45)
|
|
2762
|
+
- `bin/lib/evidence-contract.mjs`
|
|
2763
|
+
- `bin/lib/lifecycle-preflight.mjs`
|
|
2764
|
+
- `distilled/workflows/audit-milestone.md`
|
|
2765
|
+
- `distilled/workflows/complete-milestone.md`
|
|
2766
|
+
- `distilled/DESIGN.md` D50 and D59
|
|
2767
|
+
- `tests/phase.test.cjs`
|
|
2768
|
+
- `tests/gsdd.guards.test.cjs`
|
|
2769
|
+
- `tests/gsdd.scenarios.test.cjs`
|
|
2770
|
+
|
|
2771
|
+
**Consequences:**
|
|
2772
|
+
- A milestone audit can now distinguish internal repo closeout, runtime-validated closeout, and delivery-supported closeout without changing evidence kinds.
|
|
2773
|
+
- Missing delivery or runtime evidence must produce a downgrade or deferral; it cannot be hidden behind human waiver prose.
|
|
2774
|
+
- `complete-milestone` now fails closed before archive writes when the passed audit omits or contradicts the release claim contract.
|
|
2775
|
+
- Public claims are scoped to tracked public or repo-visible proof, while GitHub Releases, tags, package publication, and release automation remain deferred until explicitly planned.
|
|
2776
|
+
|
|
2649
2777
|
## Maintenance
|
|
2650
2778
|
|
|
2651
2779
|
This document is updated when:
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
- `.internal-research/gsd-distilled-audit-13th-march-2026.md` — Highest-ROI recommendation #3
|
|
102
102
|
|
|
103
103
|
## D13 — Mechanical Invariant Enforcement
|
|
104
|
-
- `tests/gsdd.invariants.test.cjs`
|
|
104
|
+
- `tests/gsdd.invariants.test.cjs` and `tests/gsdd.guards.test.cjs` enforce structural drift checks with actionable `FIX:` messages
|
|
105
105
|
- OpenAI Harness Engineering blog (Feb 2026): "error messages as enforcement mechanism"
|
|
106
106
|
- External audit (2026-03-13): recommendation #4 "Mechanize the framework's invariants"
|
|
107
107
|
- PRs #20-23: orphan `</output>` tags survived 4 manual review cycles before G4 caught them
|
|
@@ -212,7 +212,8 @@
|
|
|
212
212
|
- `get-shit-done/workflows/discuss-phase.md` (gray area identification, GSD source)
|
|
213
213
|
- `get-shit-done/workflows/list-phase-assumptions.md` (5-dimension assumption surfacing)
|
|
214
214
|
- `get-shit-done/workflows/discovery-phase.md` (3-level research workflow)
|
|
215
|
-
- `agents/approach-explorer.md`, `distilled/templates/delegates/approach-explorer.md`
|
|
215
|
+
- `agents/approach-explorer.md`, `distilled/templates/approach.md`, `distilled/templates/delegates/approach-explorer.md`, `distilled/templates/delegates/plan-checker.md`
|
|
216
|
+
- `distilled/workflows/plan.md`, `bin/adapters/opencode.mjs`, `tests/gsdd.guards.test.cjs`, `tests/gsdd.plan.adapters.test.cjs`, `tests/gsdd.scenarios.test.cjs`
|
|
216
217
|
|
|
217
218
|
## D30 — Hardening Propagation
|
|
218
219
|
- D28 consumer audit (2026-03-21): persistence failures at every workflow boundary
|
|
@@ -357,12 +358,12 @@
|
|
|
357
358
|
## D49 — Deterministic Lifecycle Preflight Gates
|
|
358
359
|
- `.planning/SPEC.md` (`ENGINE-01`, `ENGINE-02`, `ENGINE-03`)
|
|
359
360
|
- `.planning/ROADMAP.md` (Phase 30)
|
|
360
|
-
- `bin/lib/lifecycle-preflight.mjs`, `bin/lib/lifecycle-state.mjs`
|
|
361
|
+
- `bin/lib/lifecycle-preflight.mjs`, `bin/lib/lifecycle-state.mjs`, `bin/lib/session-fingerprint.mjs`
|
|
361
362
|
- `bin/gsdd.mjs`, `bin/lib/init.mjs`
|
|
362
|
-
- `distilled/workflows/execute.md`, `distilled/workflows/verify.md`
|
|
363
|
+
- `distilled/workflows/plan.md`, `distilled/workflows/execute.md`, `distilled/workflows/verify.md`
|
|
363
364
|
- `distilled/workflows/audit-milestone.md`, `distilled/workflows/complete-milestone.md`
|
|
364
365
|
- `distilled/workflows/new-milestone.md`, `distilled/workflows/resume.md`, `distilled/workflows/progress.md`
|
|
365
|
-
- `tests/phase.test.cjs`, `tests/gsdd.guards.test.cjs`, `tests/gsdd.scenarios.test.cjs`
|
|
366
|
+
- `tests/phase.test.cjs`, `tests/session-fingerprint.test.cjs`, `tests/gsdd.guards.test.cjs`, `tests/gsdd.scenarios.test.cjs`
|
|
366
367
|
- `get-shit-done/workflows/progress.md`
|
|
367
368
|
|
|
368
369
|
## D50 — Evidence-Gated Closure Matrix
|
|
@@ -454,6 +455,29 @@
|
|
|
454
455
|
- `distilled/workflows/execute.md`, `distilled/workflows/verify.md`, `distilled/workflows/resume.md`, `distilled/workflows/progress.md`
|
|
455
456
|
- `tests/gsdd.init.test.cjs`, `tests/gsdd.health.test.cjs`, `tests/gsdd.manifest.test.cjs`, `tests/phase.test.cjs`, `tests/gsdd.scenarios.test.cjs`
|
|
456
457
|
|
|
458
|
+
## D59 — Continuity Authority And Planning-State Drift
|
|
459
|
+
- `.planning/phases/44-continuity-authority-and-persistence/44-APPROACH.md`
|
|
460
|
+
- `.planning/phases/44-continuity-authority-and-persistence/44-PLAN.md`
|
|
461
|
+
- `.planning/SPEC.md` (`REL-01`)
|
|
462
|
+
- `.planning/ROADMAP.md` (Phase 44)
|
|
463
|
+
- `.internal-research/gaps.md` (`I46`, `S6`)
|
|
464
|
+
- `bin/lib/session-fingerprint.mjs`, `bin/lib/lifecycle-preflight.mjs`, `bin/lib/runtime-freshness.mjs`
|
|
465
|
+
- `distilled/workflows/progress.md`, `distilled/workflows/resume.md`, `distilled/workflows/plan.md`, `distilled/workflows/execute.md`, `distilled/workflows/verify.md`, `distilled/workflows/audit-milestone.md`, `distilled/workflows/complete-milestone.md`, `distilled/workflows/new-milestone.md`
|
|
466
|
+
- `distilled/templates/brownfield-change/CHANGE.md`, `distilled/templates/brownfield-change/HANDOFF.md`, `distilled/templates/brownfield-change/VERIFICATION.md`
|
|
467
|
+
- `tests/session-fingerprint.test.cjs`, `tests/phase.test.cjs`
|
|
468
|
+
|
|
469
|
+
## D60 — Release Closeout Contract
|
|
470
|
+
- `.planning/phases/45-release-closeout-contract/45-APPROACH.md`
|
|
471
|
+
- `.planning/phases/45-release-closeout-contract/45-PLAN.md`
|
|
472
|
+
- `.planning/phases/48-generated-helper-and-closeout-contract-parity/48-PLAN.md`
|
|
473
|
+
- `.planning/research/45-RESEARCH.md`
|
|
474
|
+
- `.planning/SPEC.md` (`REL-02`, deferred `LSC-05`)
|
|
475
|
+
- `.planning/ROADMAP.md` (Phase 45)
|
|
476
|
+
- `bin/lib/evidence-contract.mjs`, `bin/lib/lifecycle-preflight.mjs`
|
|
477
|
+
- `distilled/workflows/audit-milestone.md`, `distilled/workflows/complete-milestone.md`
|
|
478
|
+
- `distilled/DESIGN.md` D50 and D59
|
|
479
|
+
- `tests/phase.test.cjs`, `tests/gsdd.guards.test.cjs`, `tests/gsdd.scenarios.test.cjs`
|
|
480
|
+
|
|
457
481
|
---
|
|
458
482
|
|
|
459
483
|
## Maintenance
|
|
@@ -6,6 +6,8 @@ Template for `.planning/phases/XX-name/{phase_num}-APPROACH.md` — captures imp
|
|
|
6
6
|
|
|
7
7
|
**Key principle:** The top-level structure (`<domain>`, `<decisions>`, `<assumptions>`, `<deferred>`) is fixed. Section names WITHIN `<decisions>` emerge from what was actually discussed for THIS phase — a CLI phase has CLI-relevant sections, a UI phase has UI-relevant sections.
|
|
8
8
|
|
|
9
|
+
**Alignment proof:** When `.planning/config.json` has `workflow.discuss: true`, every APPROACH artifact must include an `## Alignment Proof` section before `<domain>`. It must record the canonical fields `alignment_status`, `alignment_method`, `user_confirmed_at`, `explicit_skip_approved`, `skip_scope`, `skip_rationale`, and `confirmed_decisions`. `Agent's Discretion` and agent-only "No questions needed" are not valid proof.
|
|
10
|
+
|
|
9
11
|
**Downstream consumers:**
|
|
10
12
|
- `planner` — Reads decisions to constrain implementation choices. Locked decisions must be implemented. Agent's Discretion items allow planner flexibility.
|
|
11
13
|
- `plan-checker` — Reads decisions to verify plans implement chosen approaches (approach_alignment dimension). Flags plans that contradict explicit user choices.
|
|
@@ -20,6 +22,18 @@ Template for `.planning/phases/XX-name/{phase_num}-APPROACH.md` — captures imp
|
|
|
20
22
|
**Explored:** [date]
|
|
21
23
|
**Status:** Ready for planning
|
|
22
24
|
|
|
25
|
+
## Alignment Proof
|
|
26
|
+
|
|
27
|
+
- `workflow.discuss`: [true | false]
|
|
28
|
+
- `alignment_status`: [user_confirmed | approved_skip | not_required]
|
|
29
|
+
- `alignment_method`: [conversation source, e.g. runtime command or user message]
|
|
30
|
+
- `user_confirmed_at`: [date or N/A]
|
|
31
|
+
- `explicit_skip_approved`: [true | false]
|
|
32
|
+
- `skip_scope`: [phase-wide / named gray area / N/A]
|
|
33
|
+
- `skip_rationale`: [why the user approved skipping discussion, or N/A]
|
|
34
|
+
- `confirmed_decisions`:
|
|
35
|
+
- [User-confirmed decision, or "N/A - approved skip"]
|
|
36
|
+
|
|
23
37
|
<domain>
|
|
24
38
|
## Phase Boundary
|
|
25
39
|
|
|
@@ -87,6 +101,19 @@ Template for `.planning/phases/XX-name/{phase_num}-APPROACH.md` — captures imp
|
|
|
87
101
|
**Explored:** 2026-03-22
|
|
88
102
|
**Status:** Ready for planning
|
|
89
103
|
|
|
104
|
+
## Alignment Proof
|
|
105
|
+
|
|
106
|
+
- `workflow.discuss`: true
|
|
107
|
+
- `alignment_status`: user_confirmed
|
|
108
|
+
- `alignment_method`: planning conversation
|
|
109
|
+
- `user_confirmed_at`: 2026-03-22
|
|
110
|
+
- `explicit_skip_approved`: false
|
|
111
|
+
- `skip_scope`: N/A
|
|
112
|
+
- `skip_rationale`: N/A
|
|
113
|
+
- `confirmed_decisions`:
|
|
114
|
+
- Use Recharts for chart rendering
|
|
115
|
+
- Use react-grid-layout for dashboard widgets
|
|
116
|
+
|
|
90
117
|
<domain>
|
|
91
118
|
## Phase Boundary
|
|
92
119
|
|
|
@@ -158,6 +185,19 @@ Build an interactive dashboard with configurable widgets. Users can view metrics
|
|
|
158
185
|
**Explored:** 2026-03-22
|
|
159
186
|
**Status:** Ready for planning
|
|
160
187
|
|
|
188
|
+
## Alignment Proof
|
|
189
|
+
|
|
190
|
+
- `workflow.discuss`: true
|
|
191
|
+
- `alignment_status`: user_confirmed
|
|
192
|
+
- `alignment_method`: planning conversation
|
|
193
|
+
- `user_confirmed_at`: 2026-03-22
|
|
194
|
+
- `explicit_skip_approved`: false
|
|
195
|
+
- `skip_scope`: N/A
|
|
196
|
+
- `skip_rationale`: N/A
|
|
197
|
+
- `confirmed_decisions`:
|
|
198
|
+
- Use HTTP-only cookies with JWT
|
|
199
|
+
- Use structured JSON errors
|
|
200
|
+
|
|
161
201
|
<domain>
|
|
162
202
|
## Phase Boundary
|
|
163
203
|
|
|
@@ -4,8 +4,11 @@ You are the approach explorer delegate for the plan workflow.
|
|
|
4
4
|
|
|
5
5
|
**Your job:** Identify gray areas in the target phase, research viable approaches for technical decisions, conduct an adaptive conversation with the user to capture locked decisions, and write APPROACH.md to the phase directory.
|
|
6
6
|
|
|
7
|
+
When `workflow.discuss: true`, APPROACH.md must prove user alignment before planning: use `alignment_status: user_confirmed` for real user-confirmed decisions or `alignment_status: approved_skip` only when the user explicitly approves skipping discussion. Record the canonical fields `alignment_method`, `user_confirmed_at`, `explicit_skip_approved`, `skip_scope`, `skip_rationale`, and `confirmed_decisions`. `Agent's Discretion` and agent-only "No questions needed" are not valid alignment proof.
|
|
8
|
+
|
|
7
9
|
Read only the explicit inputs provided by the orchestrator:
|
|
8
10
|
- target phase goal and requirement IDs from `.planning/ROADMAP.md`
|
|
11
|
+
- project config from `.planning/config.json`, especially `workflow.discuss`
|
|
9
12
|
- locked decisions and deferred items from `.planning/SPEC.md`
|
|
10
13
|
- phase research file (if exists)
|
|
11
14
|
- relevant codebase files (existing patterns and conventions)
|