@tekyzinc/gsd-t 4.19.14 → 4.20.11
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/CHANGELOG.md +33 -0
- package/README.md +3 -1
- package/bin/gsd-t-audit-distill.cjs +171 -0
- package/bin/gsd-t-logging-envelope-check.cjs +566 -0
- package/bin/gsd-t-logging-scaffolder.cjs +281 -0
- package/bin/gsd-t-migrate-logging.cjs +203 -0
- package/bin/gsd-t-trace-distill.cjs +196 -0
- package/bin/gsd-t-verify-gate.cjs +2 -0
- package/bin/gsd-t.js +67 -7
- package/commands/gsd-t-help.md +8 -0
- package/commands/gsd-t-init.md +11 -0
- package/commands/gsd-t-migrate-logging.md +46 -0
- package/commands/gsd-t-verify.md +2 -1
- package/package.json +1 -1
- package/templates/CLAUDE-global.md +37 -0
- package/templates/logging/audit-module.template.ts +469 -0
- package/templates/logging/trace-module.template.ts +190 -0
- package/templates/workflows/gsd-t-phase.workflow.js +33 -0
package/bin/gsd-t.js
CHANGED
|
@@ -203,6 +203,24 @@ const {
|
|
|
203
203
|
} = require("./playwright-bootstrap.cjs");
|
|
204
204
|
const { hasUI } = require("./ui-detection.cjs");
|
|
205
205
|
|
|
206
|
+
// M100 D1: stack-adaptive storage scaffolder — the sole init-scaffold seam.
|
|
207
|
+
// Presents real alternatives and PAUSES for human approval; never silently
|
|
208
|
+
// picks a logging backend. See .gsd-t/contracts/logging-scaffold-seam-contract.md.
|
|
209
|
+
const { scaffoldLogging } = require("./gsd-t-logging-scaffolder.cjs");
|
|
210
|
+
|
|
211
|
+
// runLoggingScaffoldStep(projectDir, opts): the init-dispatch integration
|
|
212
|
+
// point. Calls the scaffolder and explicitly checks the envelope's `status`
|
|
213
|
+
// field: on "PAUSED" it halts BEFORE any sink/template write and surfaces
|
|
214
|
+
// alternatives[] to the caller; it only proceeds (halted:false) once a
|
|
215
|
+
// resolved `backend` comes back (fresh approval or a valid recorded choice).
|
|
216
|
+
function runLoggingScaffoldStep(projectDir, opts) {
|
|
217
|
+
const envelope = scaffoldLogging(Object.assign({ projectDir }, opts || {}));
|
|
218
|
+
if (envelope.status === "PAUSED") {
|
|
219
|
+
return { halted: true, alternatives: envelope.alternatives, resumeToken: envelope.resumeToken };
|
|
220
|
+
}
|
|
221
|
+
return { halted: false, backend: envelope.backend, envelope };
|
|
222
|
+
}
|
|
223
|
+
|
|
206
224
|
function readProjectDeps(projectDir) {
|
|
207
225
|
const pkgPath = path.join(projectDir, "package.json");
|
|
208
226
|
if (!fs.existsSync(pkgPath)) return [];
|
|
@@ -2130,6 +2148,26 @@ async function doInit(projectName) {
|
|
|
2130
2148
|
// M52 D1: auto-install the journey-coverage gate. Idempotent — no-op if marker present.
|
|
2131
2149
|
if (hasUI(projectDir)) installJourneyCoverageHook(projectDir);
|
|
2132
2150
|
|
|
2151
|
+
// M100 D1: storage scaffolder step. Presents real backend alternatives and
|
|
2152
|
+
// PAUSES for human approval — the ONE sanctioned pause against Level-3
|
|
2153
|
+
// full-auto. On PAUSED, halts here and surfaces alternatives; never writes
|
|
2154
|
+
// a trace/audit sink or picks a backend silently. See
|
|
2155
|
+
// .gsd-t/contracts/logging-scaffold-seam-contract.md.
|
|
2156
|
+
try {
|
|
2157
|
+
const loggingOutcome = runLoggingScaffoldStep(projectDir);
|
|
2158
|
+
if (loggingOutcome.halted) {
|
|
2159
|
+
warn("Logging backend not yet chosen — scaffolder is PAUSED for human approval:");
|
|
2160
|
+
for (const alt of loggingOutcome.alternatives) {
|
|
2161
|
+
info(` - ${alt.backend}${alt.recommended ? " (recommended)" : ""}: ${alt.label} — ${alt.reason}`);
|
|
2162
|
+
}
|
|
2163
|
+
info(`Re-run init with an approved backend to resume (resumeToken: ${loggingOutcome.resumeToken}).`);
|
|
2164
|
+
} else {
|
|
2165
|
+
success(`Logging backend: ${loggingOutcome.backend}`);
|
|
2166
|
+
}
|
|
2167
|
+
} catch (e) {
|
|
2168
|
+
warn(`Logging scaffold step errored: ${e.message || e}`);
|
|
2169
|
+
}
|
|
2170
|
+
|
|
2133
2171
|
showInitTree(projectDir);
|
|
2134
2172
|
}
|
|
2135
2173
|
|
|
@@ -3736,13 +3774,17 @@ function refreshVersionAsync() {
|
|
|
3736
3774
|
}
|
|
3737
3775
|
|
|
3738
3776
|
function showUpdateNotice(latest) {
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3777
|
+
// Human-facing banner MUST go to stderr — writing it to stdout corrupts the JSON
|
|
3778
|
+
// output of machine commands (e.g. `graph body`, `graph --output json`), breaking
|
|
3779
|
+
// any JSON.parse consumer. stderr keeps the banner visible without polluting stdout.
|
|
3780
|
+
const e = (msg) => console.error(msg);
|
|
3781
|
+
e("");
|
|
3782
|
+
e(` ${YELLOW}╭──────────────────────────────────────────────╮${RESET}`);
|
|
3783
|
+
e(` ${YELLOW}│${RESET} Update available: ${DIM}${PKG_VERSION}${RESET} → ${GREEN}${latest}${RESET} ${YELLOW}│${RESET}`);
|
|
3784
|
+
e(` ${YELLOW}│${RESET} Run: ${CYAN}npm update -g @tekyzinc/gsd-t${RESET} ${YELLOW}│${RESET}`);
|
|
3785
|
+
e(` ${YELLOW}│${RESET} Then: ${CYAN}gsd-t update-all${RESET} ${YELLOW}│${RESET}`);
|
|
3786
|
+
e(` ${YELLOW}│${RESET} Changelog: ${CYAN}gsd-t changelog${RESET} ${YELLOW}│${RESET}`);
|
|
3787
|
+
e(` ${YELLOW}╰──────────────────────────────────────────────╯${RESET}`);
|
|
3746
3788
|
}
|
|
3747
3789
|
|
|
3748
3790
|
function doChangelog() {
|
|
@@ -4871,6 +4913,8 @@ module.exports = {
|
|
|
4871
4913
|
promptForApiKeyIfMissing,
|
|
4872
4914
|
resolveApiKeyEnvVar,
|
|
4873
4915
|
runTaskCounterRetirementMigration,
|
|
4916
|
+
// M100: storage scaffolder seam
|
|
4917
|
+
runLoggingScaffoldStep,
|
|
4874
4918
|
};
|
|
4875
4919
|
|
|
4876
4920
|
// ─── Main ────────────────────────────────────────────────────────────────────
|
|
@@ -4972,6 +5016,22 @@ if (require.main === module) {
|
|
|
4972
5016
|
case "graph":
|
|
4973
5017
|
doGraph(args.slice(1));
|
|
4974
5018
|
break;
|
|
5019
|
+
case "migrate-logging": {
|
|
5020
|
+
// M100 D1 wiring on d5's behalf — d1 is the SOLE editor of bin/gsd-t.js;
|
|
5021
|
+
// d5 owns bin/gsd-t-migrate-logging.cjs (the module) and
|
|
5022
|
+
// commands/gsd-t-migrate-logging.md (the command). See
|
|
5023
|
+
// .gsd-t/contracts/logging-scaffold-seam-contract.md §Ownership boundary.
|
|
5024
|
+
let migrateLogging;
|
|
5025
|
+
try {
|
|
5026
|
+
migrateLogging = require("./gsd-t-migrate-logging.cjs");
|
|
5027
|
+
} catch (e) {
|
|
5028
|
+
error(`migrate-logging module not found: ${e.message || e}`);
|
|
5029
|
+
process.exit(1);
|
|
5030
|
+
}
|
|
5031
|
+
Promise.resolve(migrateLogging.run ? migrateLogging.run(args.slice(1)) : migrateLogging(args.slice(1)))
|
|
5032
|
+
.catch((e) => { error(e.message || String(e)); process.exit(1); });
|
|
5033
|
+
break;
|
|
5034
|
+
}
|
|
4975
5035
|
case "headless":
|
|
4976
5036
|
doHeadless(args.slice(1));
|
|
4977
5037
|
break;
|
package/commands/gsd-t-help.md
CHANGED
|
@@ -76,6 +76,7 @@ HEADLESS (CI/CD) CLI
|
|
|
76
76
|
research-gate Classify a guessed claim: internal (grep) / external (web) / ambiguous (LLM judge) [M89]
|
|
77
77
|
architectural-trigger Fire the architectural-assumption trigger (divergence-sampling or extend-existing-code) [M90]
|
|
78
78
|
loop-ledger Record a debug cycle, read exit state, detect non-convergence (premise-re-examination) [M90]
|
|
79
|
+
migrate-logging Brownfield: scaffold trace + audit logging into an existing project, additively [M100]
|
|
79
80
|
|
|
80
81
|
BACKLOG Manual
|
|
81
82
|
───────────────────────────────────────────────────────────────────────────────
|
|
@@ -553,6 +554,13 @@ Use these when user asks for help on a specific command:
|
|
|
553
554
|
- **CLI**: `gsd-t loop-ledger append-cycle --assertion "<symptom>" --surface "<file>" --fileClass unit --projectDir <dir>`. `gsd-t loop-ledger read-exit-state --projectDir <dir>`. Exit 0 on success.
|
|
554
555
|
- **Contract**: `.gsd-t/contracts/unproven-assumption-doctrine-contract.md` §3 v1.0.0 STABLE.
|
|
555
556
|
|
|
557
|
+
### migrate-logging (M100)
|
|
558
|
+
- **Summary**: Brownfield migration — scaffolds the two framework-default logging streams (trace + audit) into an EXISTING project, ADDITIVELY. Trace is a default for every project except explicit opt-out recorded at `.gsd-t/trace-optout.json` (see `trace-logging-contract.md` §opt-out-record — a stateless CLI/library with no runtime data-flow may opt out); audit is a default except an explicit opt-out recorded at `.gsd-t/audit-optout.json` (see `audit-logging-contract.md` §opt-out-record) — the migration honors an existing opt-out for either stream rather than forcing a store on it. Every pre-existing project file is left byte-for-byte unchanged; only new logging files are added. Dispatch is wired into `bin/gsd-t.js` `case "migrate-logging"` by d1 (the sole editor of that file) on d5's behalf — the module (`bin/gsd-t-migrate-logging.cjs`) and this command are owned by d5 via the scaffold-seam contract.
|
|
559
|
+
- **Files**: `bin/gsd-t-migrate-logging.cjs`. Contracts: `.gsd-t/contracts/logging-scaffold-seam-contract.md`, `.gsd-t/contracts/logging-schema-distillation-contract.md`, `trace-logging-contract.md`, `audit-logging-contract.md`.
|
|
560
|
+
- **Use when**: An existing (brownfield) project needs the trace/audit defaults retrofitted without touching its current code or tests.
|
|
561
|
+
- **CLI**: `gsd-t migrate-logging <projectDir> [--plan <path-to-plan.md>]`. Exit 0 on success · 1 on migration error.
|
|
562
|
+
- **Proven**: `test/m100-d5-migration-fixture.test.js` — runs the migration against a throwaway fixture repo and asserts additive/non-destructive behavior (pre-existing files unchanged) before/after snapshot comparison.
|
|
563
|
+
|
|
556
564
|
## Unknown Command
|
|
557
565
|
|
|
558
566
|
If user asks for help on unrecognized command:
|
package/commands/gsd-t-init.md
CHANGED
|
@@ -350,6 +350,17 @@ Operator overrides: `gsd-t setup-playwright [path]` (explicit single-project ins
|
|
|
350
350
|
|
|
351
351
|
The spawn-time gate in `bin/headless-auto-spawn.cjs` re-runs the install on first need if the project skipped this step (e.g., older project that pre-dates M50).
|
|
352
352
|
|
|
353
|
+
## Step 11.5: Logging Backend Scaffold (M100)
|
|
354
|
+
|
|
355
|
+
The `bin/gsd-t.js init` flow calls `runLoggingScaffoldStep(projectDir)` (from `bin/gsd-t-logging-scaffolder.cjs`) automatically, right before the init tree summary. This is the sole init-scaffold seam for M100's trace/audit logging.
|
|
356
|
+
|
|
357
|
+
- It detects the stack (has-DB → `db-table` alternative; no-server/desktop → `local-sqlite` | `local-jsonl`, with SQLite flagged over flat-file for audit queryability).
|
|
358
|
+
- It **presents real alternatives and PAUSES for human approval** — this is the ONE sanctioned pause against the Level-3 full-auto default (see `.gsd-t/contracts/logging-scaffold-seam-contract.md`). It never silently picks a backend.
|
|
359
|
+
- On re-run with a previously-approved choice, it resumes deterministically (no re-prompt) and records the backend into the project's `CLAUDE.md`.
|
|
360
|
+
- If it halts with `status:"PAUSED"`, report the presented alternatives to the user and wait for them to choose before re-running init with an approved backend — do NOT guess or auto-select on their behalf.
|
|
361
|
+
|
|
362
|
+
See `.gsd-t/contracts/logging-scaffold-seam-contract.md` for the full seam envelope shape consumed by d2 (trace), d4 (audit), and d5 (migrate-logging).
|
|
363
|
+
|
|
353
364
|
## Step 12: Test Verification
|
|
354
365
|
|
|
355
366
|
After initialization:
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# GSD-T: Migrate Logging — Brownfield Trace + Audit Retrofit
|
|
2
|
+
|
|
3
|
+
Scaffolds the two framework-default logging streams — **trace** (transient debug signal, no opt-out) and **audit** (durable accountability record, default except explicit opt-out) — into an EXISTING project, additively. See `~/.claude/CLAUDE.md` § Logging Defaults for the two hard rules this command implements.
|
|
4
|
+
|
|
5
|
+
## What this does
|
|
6
|
+
|
|
7
|
+
- Copies the trace module template (`templates/logging/trace-module.template.ts`) to `src/logging/trace.ts` — **only if that file does not already exist**.
|
|
8
|
+
- Copies the audit module template (`templates/logging/audit-module.template.ts`) to `src/logging/audit.ts` — **only if that file does not already exist**.
|
|
9
|
+
- Distills the per-project trace category / audit action schema from the project's own plan (when `--plan` is given) into `.gsd-t/logging-schema.json` — never confabulated; an unstated category/action is a gap, not a guess.
|
|
10
|
+
- Runs d1's stack-adaptive storage scaffolder (`scaffoldLogging()`), which detects the stack and **pauses for human approval** before recording a storage backend — never silently picks one.
|
|
11
|
+
|
|
12
|
+
## Non-destructive guarantee (MANDATORY)
|
|
13
|
+
|
|
14
|
+
This command is **purely additive**. Every write is preceded by an existence check; a file that already exists in the target project is left byte-for-byte untouched. It is proven non-destructive on a throwaway fixture in `test/m100-d5-migration-fixture.test.js` — a run that modifies or deletes any pre-existing fixture file is a test FAILURE.
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
gsd-t migrate-logging <projectDir> [--plan <path-to-plan.md>] [--approve <db-table|local-sqlite|local-jsonl>]
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- `<projectDir>` — required. The existing project to retrofit.
|
|
23
|
+
- `--plan <path>` — optional. Distills the concrete trace category / audit action set from this plan file. Omit to get an empty (never invented) schema.
|
|
24
|
+
- `--approve <backend>` — optional. Approves a storage backend up front (`db-table` / `local-sqlite` / `local-jsonl`). Omit to let the scaffolder pause and present alternatives first.
|
|
25
|
+
|
|
26
|
+
## Step 1: Run the migration
|
|
27
|
+
|
|
28
|
+
Invoke the module via the CLI dispatch (owned by d1 — `bin/gsd-t.js` `case "migrate-logging"`; the module itself is owned by this domain, see `.gsd-t/contracts/logging-scaffold-seam-contract.md`):
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
gsd-t migrate-logging "$ARGUMENTS"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Step 2: Report
|
|
35
|
+
|
|
36
|
+
Show the created/skipped file lists and the storage scaffold result (approved backend, or the PAUSED alternatives list awaiting human approval) exactly as returned by the module — do not summarize away a PAUSED state as if it were complete.
|
|
37
|
+
|
|
38
|
+
## Step 3: If storage is PAUSED
|
|
39
|
+
|
|
40
|
+
Present the alternatives to the user and wait for an explicit backend choice (the ONE sanctioned pause against the Level-3 full-auto default — see `.gsd-t/contracts/logging-scaffold-seam-contract.md`). Re-run with `--approve <backend>` once chosen.
|
|
41
|
+
|
|
42
|
+
$ARGUMENTS
|
|
43
|
+
|
|
44
|
+
## Auto-Clear
|
|
45
|
+
|
|
46
|
+
All work is committed to project files. Execute `/clear` to free the context window for the next command.
|
package/commands/gsd-t-verify.md
CHANGED
|
@@ -20,9 +20,10 @@ preflight → brief → verify-gate (deterministic Track 1+2)
|
|
|
20
20
|
Per `.gsd-t/contracts/orthogonal-validation-contract.md` v1.0.0 STABLE, the three triad stages are orthogonal objective functions — no collapse, no substitution, no transitive trust. Synthesis preserves category labels.
|
|
21
21
|
|
|
22
22
|
**Hard-failing gates** (each halts before triad):
|
|
23
|
-
- `verify-gate` — deterministic Track 1 (preflight envelope) + Track 2 (tsc/biome/npm-test/knip/gitleaks/scc fan-out)
|
|
23
|
+
- `verify-gate` — deterministic Track 1 (preflight envelope) + Track 2 (tsc/biome/npm-test/knip/gitleaks/scc/logging-envelope fan-out)
|
|
24
24
|
- M57 `build-coverage` + `ci-parity` — origin TimeTracking v1.10.12 Dockerfile incident
|
|
25
25
|
- M58 `test-data --purge` — origin GSD-T-Board v0.1.10 2442 E2E orphans incident
|
|
26
|
+
- M100 `logging-envelope` — structural predicate (`bin/gsd-t-logging-envelope-check.cjs`) enforcing BOTH the trace envelope (`ts`/`category`/`decision`/`detail`) and the audit envelope (`ts`/`actor`/`action`/`target`/`before`/`after`/`context`) over per-project-varying schemas — never a hardcoded category/action value. Also enforces the trace PII bar (recursing into nested `data`), the no-collapse boundary (a record MUST NOT carry top-level markers from both streams), append-only/immutability, retention-configurability, and audit-default-except-opt-out (`.gsd-t/audit-optout.json`). FAIL-CLOSED — never warn-and-proceed. Contract: `.gsd-t/contracts/logging-verify-gate-contract.md`.
|
|
26
27
|
|
|
27
28
|
## Step 1: Read the current milestone state
|
|
28
29
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekyzinc/gsd-t",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.20.11",
|
|
4
4
|
"description": "GSD-T: Contract-Driven Development for Claude Code — 54 slash commands with headless-by-default workflow spawning, unattended supervisor relay with event stream, graph-powered code analysis, real-time agent dashboard, task telemetry, doc-ripple enforcement, backlog management, impact analysis, test sync, milestone archival, and PRD generation",
|
|
5
5
|
"author": "Tekyz, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -222,6 +222,16 @@ The hard rules (non-negotiable, all projects):
|
|
|
222
222
|
- **Functional, not layout.** Every assertion must prove state changed / data flowed / content loaded / widget responded — not mere existence (`isVisible`/`toBeAttached`). If a test would pass on empty HTML with the right IDs and no JS, rewrite it.
|
|
223
223
|
- **Test-data cleanup.** Tests that insert data MUST register it via the `withTestData()` fixture so verify Step 4.5 (`gsd-t test-data --purge`) can remove it; an adapter throw/refusal FAILs the gate. Adapters refuse to delete ids lacking the ledger `taggedPrefix`. See [[feedback_test_data_cleanup_convention]] + `.gsd-t/contracts/test-data-ledger-contract.md`.
|
|
224
224
|
|
|
225
|
+
## Logging Defaults — Trace + Audit (M100 — MANDATORY)
|
|
226
|
+
|
|
227
|
+
Every GSD-T project gets TWO logging streams scaffolded by default at `gsd-t-init` — never opt-in, and never silently skipped (an opt-out must be an explicit, reasoned, recorded decision, not a silent absence). Contracts: `.gsd-t/contracts/trace-logging-contract.md`, `.gsd-t/contracts/audit-logging-contract.md`, `.gsd-t/contracts/logging-schema-distillation-contract.md`, `.gsd-t/contracts/logging-scaffold-seam-contract.md`.
|
|
228
|
+
|
|
229
|
+
- **Rule 1 — Trace is a default for EVERY project EXCEPT explicit opt-out.** Trace = a transient, PII-barred, toggleable DEBUGGING SIGNAL STREAM (`ts`/`category`/`decision`/`detail` envelope). Scaffolded into every project regardless of stack; `gsd-t-verify` FAILs a project with no discoverable trace module/store AND no valid opt-out record. A stateless CLI/library with no runtime data-flow (no requests/jobs/integrations/user sessions) may opt out by writing the canonical opt-out record to `.gsd-t/trace-optout.json` (`{"traceOptOut": true, "reason": "<why>"}` — see `trace-logging-contract.md` §opt-out-record); a running application must NOT opt out.
|
|
230
|
+
- **Rule 2 — Audit is a default for EVERY project EXCEPT explicit opt-out declared in the project's own CLAUDE.md.** Audit = a durable, admin-queryable, append-only ACCOUNTABILITY record (`ts`/`actor`/`action`/`target`/`before`/`after`/`context` envelope). A project that genuinely has no admin-facing accountability surface (e.g. a pure local trace-only tool) may opt out by writing the canonical opt-out record to `.gsd-t/audit-optout.json` (`{"auditOptOut": true, "reason": "<why>"}` — see `audit-logging-contract.md` §opt-out-record). `gsd-t-verify` FAILs any project with neither a discoverable audit store NOR a valid opt-out record; a valid opt-out is honored and does NOT fail the project for missing audit.
|
|
231
|
+
- **Storage is stack-adaptive and human-approval-gated** — `bin/gsd-t-logging-scaffolder.cjs` detects the stack, presents real alternatives, and STOPS for approval; it never silently picks a backend (the one sanctioned pause against the Level-3 full-auto default).
|
|
232
|
+
- **Trace and audit NEVER collapse into one stream.** A trace envelope carrying audit markers (`before`/`after`/`actor`/`action`) or vice-versa is a contract violation and a `gsd-t-verify` FAIL — see each contract's §no-collapse boundary.
|
|
233
|
+
- **Brownfield migration**: `gsd-t migrate-logging <projectDir>` scaffolds both streams into an EXISTING project additively — it never modifies or deletes a pre-existing file. See `commands/gsd-t-migrate-logging.md`.
|
|
234
|
+
|
|
225
235
|
## Orthogonal Validation Triad (Mandatory)
|
|
226
236
|
|
|
227
237
|
Every code-producing phase ends with `gsd-t-verify.workflow.js`, which runs three orthogonal validators as `parallel()` `agent()` stages with schema-validated output. Per `.gsd-t/contracts/orthogonal-validation-contract.md` v1.0.0 STABLE, they are declared orthogonal objective functions — no collapse, no substitution, no transitive trust.
|
|
@@ -419,6 +429,33 @@ asserting. If you lack a fresh source, say so explicitly: *"I believe X, but I d
|
|
|
419
429
|
source — please verify."* Do NOT state an external/time-varying fact as known when it is a guess.
|
|
420
430
|
See memory pointer: `feedback_auto_research_external_gaps`.
|
|
421
431
|
|
|
432
|
+
### Architect's Oversight Doctrine (M101 — governed, enforced)
|
|
433
|
+
|
|
434
|
+
**Contract:** `.gsd-t/contracts/architects-oversight-contract.md` v1.0.0 STABLE
|
|
435
|
+
|
|
436
|
+
**Never build before the design has passed the architect's interrogation.** GSD-T staffs verifiers (Red Team, QA, code-review, pre-mortem) — all asking "is this correct?" — but no seat asked "is this the *smartest, simplest* design given what we already have?" The result: the wrong thing built correctly, then thoroughly tested, then shipped (the Binvoice completeness-scan waste — a whole-page scan re-deriving a count already stored locally). This doctrine fills the empty architect seat. Sibling to the Unproven-Assumption Doctrine: that one bars unproven *facts*; this one bars unproven *necessity*.
|
|
437
|
+
|
|
438
|
+
**The Six-Stage Pass — run IN ORDER before proposing or building any solution. Each stage can KILL the plan. Every "am I sure?" is answered with EVIDENCE (a grep, a Read, a graph query), never conviction — self-confidence is what produced the waste.**
|
|
439
|
+
|
|
440
|
+
1. **Objective** — What is the core objective? Why is it the core objective? *(Kills: building the wrong thing.)*
|
|
441
|
+
2. **Conflict** — Does it support or conflict with other core objectives? Must we re-examine/re-plan an already-built objective? *(Kills: a local win that breaks the system; frozen past decisions.)*
|
|
442
|
+
3. **Reuse** — Have I already accomplished any piece of this? Can I reuse the **process**, or the **output** of that process? *(Query the graph — not memory. This stage kills redundant work like the completeness scan. Split is load-bearing: reuse the answer already produced, not just the code.)*
|
|
443
|
+
4. **Simplicity** — Is this the simplest, most efficient plan? Am I sure? *(Evidence, not conviction. Kills bloat.)*
|
|
444
|
+
5. **Reuse forecast & duplication** — see §Reuse Logic below. *(Kills both over-engineering and rogue-twin sprawl.)*
|
|
445
|
+
6. **Risk** — Security risks? Stability/scalability risks? Am I sure? *(Kills fast-but-fragile.)*
|
|
446
|
+
→ **Then build.**
|
|
447
|
+
|
|
448
|
+
**§Reuse Logic (Stage 5 — how to avoid both sprawl and stability-breakage):**
|
|
449
|
+
- **Forecast reuse likelihood** against long-term project scope (read requirements/architecture — don't guess): **HIGH** (core domain entity / recurs in roadmap / pure transformation) or **LOW** (one-off UI/debug/glue / single caller). HIGH → build clean + extractable now (NOT config-knobbed — that's the YAGNI trap), register in the graph as reuse-likely. LOW → simplest inline thing, no abstraction.
|
|
450
|
+
- **When a similar-but-not-reusable thing already exists:** (a) same WHAT (job) or same HOW (surface)? Same WHAT → generalize; merely similar → build new. (b) If generalize: **extract a shared core, do NOT mutate** the working original (old callers keep identical behavior). (c) If blast-radius/stability forbids touching it → build new, **but register a "reuse-candidate" link in the graph** pointing at the twin, so the duplication is visible and re-decided on next touch. **Never build a silent rogue twin** — sprawl disables Stage 3's reuse-check for everyone after you.
|
|
451
|
+
- **A wrong forecast self-corrects:** the graph's similarity check surfaces a LOW-forecast function that got reused anyway at the next Stage 3. So the forecast need only be directionally right — the graph rescues the misses. That is what removes the paralysis.
|
|
452
|
+
|
|
453
|
+
**§Plain-English proof (the artifact you can always review, never must):** the Six-Stage answers are written into the milestone's **PseudoCode document** in plain, jargon-free language (style: `.gsd-t/pseudocode/` — title + one-line purpose, `CURRENT`/`PROPOSED` blocks, `# plain comment` inline, a summary table; near-zero preamble). Jargon is where unexamined complexity hides — a layman-legible sentence has nowhere for a pointless operation to survive. The pseudocode IS the audit, and it lets the user approve *direction before code* as the senior reviewer, not a rubber-stamp.
|
|
454
|
+
|
|
455
|
+
**§Jargonless output (co-equal with brevity, NOT a trade-off):** short and clear are different axes; jargon is short, so brevity rules alone reward it. Every reply, plan, options-prompt, and mid-work narration glosses jargon in plain words on first use. The crux: individual shorthand may be decodable, but **several mashed into one sentence become unintelligible** — never force the reader toward an "I don't understand" escape hatch; if that option would help, the sentence already failed. Enforced by the Reader Contract (injected every turn).
|
|
456
|
+
|
|
457
|
+
**§Enforcement (three layers — same shape as Unproven-Assumption):** (1) this doctrine = the *definition* (reference, always available); (2) a **PreToolUse hook on Write/Edit** = the *trigger* — injects a one-line reminder pointing here at the build moment, so it can't be missed under load; (3) the **plan/milestone workflow gate** = the *execution* — the Six-Stage Pass runs as blocking `agent()` steps with graph/doc evidence, and pseudocode-completeness is a verify check. Injecting the doctrine ≠ executing it; the workflow does the doing.
|
|
458
|
+
|
|
422
459
|
### Phase Flow
|
|
423
460
|
- Upon completing a phase, automatically proceed to the next phase
|
|
424
461
|
- ONLY run Discussion phase if truly required (clear path → skip to Plan)
|