@tekyzinc/gsd-t 4.0.14 → 4.0.16
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 +34 -0
- package/bin/gsd-t.js +97 -15
- package/commands/gsd-t-debug.md +4 -1
- package/commands/gsd-t-design-decompose.md +4 -1
- package/commands/gsd-t-doc-ripple.md +4 -1
- package/commands/gsd-t-execute.md +4 -1
- package/commands/gsd-t-help.md +5 -0
- package/commands/gsd-t-impact.md +4 -1
- package/commands/gsd-t-integrate.md +4 -1
- package/commands/gsd-t-milestone.md +4 -1
- package/commands/gsd-t-partition.md +4 -1
- package/commands/gsd-t-plan.md +4 -1
- package/commands/gsd-t-prd.md +4 -1
- package/commands/gsd-t-scan.md +10 -3
- package/commands/gsd-t-verify.md +4 -1
- package/commands/gsd-t-wave.md +4 -1
- package/package.json +1 -1
- package/templates/CLAUDE-global.md +1 -1
- package/templates/workflows/gsd-t-scan.workflow.js +45 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to GSD-T are documented here. Updated with each release.
|
|
4
4
|
|
|
5
|
+
## [4.0.16] - 2026-06-02 (M69 Workflow scriptPath Resolution — patch)
|
|
6
|
+
|
|
7
|
+
### Fixed — workflow commands now run from any project, not just the GSD-T source repo
|
|
8
|
+
|
|
9
|
+
Every workflow-backed command (`gsd-t-scan`, `-execute`, `-verify`, `-wave`, `-integrate`, `-debug`, and the 6 `-phase`-runner commands) hard-coded a relative `scriptPath: "templates/workflows/..."`. That path only resolves when CWD is the GSD-T source repo; from any consumer project the workflow script (which ships inside the installed package, not the project) is unreachable, so `Workflow({scriptPath})` silently fails and the agent falls back to a hand-driven run. This is why a deep scan in a consumer project produced the register but not the 5 `.gsd-t/scan/*.md` dimension files — the M67 Document phase never executed.
|
|
10
|
+
|
|
11
|
+
- `bin/gsd-t.js`: new `gsd-t workflow-path <name>` subcommand — prints the ABSOLUTE path to `gsd-t-<name>.workflow.js` resolved from the CLI's own `PKG_ROOT`. Accepts name aliases (with/without `gsd-t-` prefix or `.workflow.js` suffix). Exit 0 + path; exit 4 + available list on unknown name; exit 64 on missing arg. Resolves from any CWD (works for global/local/npx installs since it follows the invoked binary).
|
|
12
|
+
- `commands/gsd-t-{scan,execute,verify,wave,integrate,debug,partition,plan,impact,milestone,prd,doc-ripple,design-decompose}.md` (13 files): replaced the relative `scriptPath` with an instruction to resolve the absolute path first via `gsd-t workflow-path <name>`.
|
|
13
|
+
- `templates/CLAUDE-global.md`, `commands/gsd-t-help.md`: documented the resolution requirement + the new subcommand.
|
|
14
|
+
- `test/m69-workflow-path.test.js`: +6 tests (resolves known/aliased/all-8 workflows, CWD-independence, exit 4 unknown, exit 64 usage).
|
|
15
|
+
|
|
16
|
+
Effect: `/gsd-t-scan` (and all workflow commands) now run correctly from any registered project with no special prompt or absolute-path workaround.
|
|
17
|
+
|
|
18
|
+
### Added — `.gsd-t/techdebt_in_plain_english.md` scan output
|
|
19
|
+
|
|
20
|
+
The scan Document phase now also writes a non-technical companion to the tech-debt register: every TD item restated in layman's terms, why it matters in business/user consequences, and a concrete real-world analogy, with severity translated into plain urgency. For founders/PMs/stakeholders who need the findings without the jargon.
|
|
21
|
+
|
|
22
|
+
- `templates/workflows/gsd-t-scan.workflow.js`: +1 `docTargets` entry (`techdebt-plain-english`); included in the document-phase git commit.
|
|
23
|
+
- `commands/gsd-t-scan.md`: Document Ripple lists the new output.
|
|
24
|
+
|
|
25
|
+
Suite: 1278 pass / 0 fail / 4 skip — zero regressions.
|
|
26
|
+
|
|
27
|
+
## [4.0.15] - 2026-06-01 (M68 update-all Retired-Tool Prune — patch)
|
|
28
|
+
|
|
29
|
+
### Fixed — update-all now prunes bin tools retired in M61/M65
|
|
30
|
+
|
|
31
|
+
`update-all` kept the propagated 7-tool subset fresh but never deleted tools GSD-T retired — the `DEPRECATED_BIN_STRAYS` sweep list only carried `gsd-t.js`. Result: 22 of 24 registered projects carried 11-17 dead `.cjs` files (the M61/M65 token-telemetry, unattended-relay, headless-spawn, and context-meter clusters), and the "already current" summary masked it. Surfaced when a project appeared not to update.
|
|
32
|
+
|
|
33
|
+
- `bin/gsd-t.js`: added the 17 M61/M65-retired tools to `DEPRECATED_BIN_STRAYS`; generalized the stray sweep so retired `.cjs` are pruned only when they carry a GSD-T provenance marker (`_hasGsdtProvenance`) — a user's same-named file without the marker is left untouched. `gsd-t.js` keeps its bespoke "GSD-T CLI Installer" header match.
|
|
34
|
+
- `test/bin-gsd-t-resilience.test.js`: +2 regression tests (retired-provenance `.cjs` swept; user-authored same-named `.cjs` survives).
|
|
35
|
+
- One-off: pruned 273 retired `.cjs` across the 21 affected projects (proved no live requirers first — the only references were retirement-breadcrumb comments).
|
|
36
|
+
|
|
37
|
+
Suite: 1269 pass / 0 fail / 4 skip — zero regressions.
|
|
38
|
+
|
|
5
39
|
## [4.0.14] - 2026-05-29 (M67 Scan Deep Document Phase — patch)
|
|
6
40
|
|
|
7
41
|
### Added — deterministic deep document cross-population in the scan Workflow
|
package/bin/gsd-t.js
CHANGED
|
@@ -2473,11 +2473,60 @@ const PROJECT_BIN_TOOLS = [
|
|
|
2473
2473
|
|
|
2474
2474
|
// Files that older versions of this installer copied into project bin/ but
|
|
2475
2475
|
// are no longer part of PROJECT_BIN_TOOLS. On each update-all pass, sweep the
|
|
2476
|
-
// project's bin/ and remove any stray
|
|
2477
|
-
//
|
|
2478
|
-
//
|
|
2479
|
-
//
|
|
2480
|
-
|
|
2476
|
+
// project's bin/ and remove any stray that carries GSD-T provenance — that
|
|
2477
|
+
// proves it's an old installer artifact, not a user's own file sharing the
|
|
2478
|
+
// name. User-owned files (no GSD-T provenance marker) are left alone.
|
|
2479
|
+
//
|
|
2480
|
+
// M68: the M61/M65 retirement removed the token-telemetry + unattended +
|
|
2481
|
+
// headless-spawn + context-meter clusters from the package and from
|
|
2482
|
+
// PROJECT_BIN_TOOLS, but never added them here — so update-all kept the current
|
|
2483
|
+
// 7 tools fresh while leaving 11-17 dead .cjs lingering in every project's bin/.
|
|
2484
|
+
// Adding them closes that gap so future retirements prune cleanly.
|
|
2485
|
+
// Each retired tool maps to one or more VERBATIM header sentinels it actually
|
|
2486
|
+
// shipped with (recovered from git history at the commit before each was deleted).
|
|
2487
|
+
// A stray is swept only when its content contains the exact product header — proof
|
|
2488
|
+
// it was SHIPPED by this installer, not merely that it mentions "gsd-t". This is the
|
|
2489
|
+
// M68 red-team fix: the prior loose substring (`/gsd-t/` over 1200 chars) would have
|
|
2490
|
+
// deleted a user's own same-named helper that happened to reference a `.gsd-t/` path.
|
|
2491
|
+
// A user file can match only by reproducing a verbatim product header — implausible.
|
|
2492
|
+
const DEPRECATED_BIN_STRAY_SIGNATURES = {
|
|
2493
|
+
"gsd-t.js": ["GSD-T CLI Installer"], // bespoke installer header
|
|
2494
|
+
// M61 D3 — token telemetry / context-runway cluster
|
|
2495
|
+
"gsd-t-token-capture.cjs": ["GSD-T Token Capture", "gsd-t-token-capture"],
|
|
2496
|
+
"token-telemetry.cjs": ["GSD-T Token Telemetry"],
|
|
2497
|
+
"token-budget.cjs": ["GSD-T Token Budget"],
|
|
2498
|
+
"token-optimizer.cjs": ["GSD-T Token Optimizer"],
|
|
2499
|
+
"runway-estimator.cjs": ["GSD-T Runway", "runway-estimator"],
|
|
2500
|
+
// Verbatim shipped comment header (no bare "GSD-T" — red-team HIGH-1: a bare token
|
|
2501
|
+
// would delete a user's same-named file that merely mentions GSD-T).
|
|
2502
|
+
"context-budget-audit.cjs": ["Context Budget Audit — measures the static context cost"],
|
|
2503
|
+
"context-meter-config.cjs": ["Context Meter config loader (M34)"],
|
|
2504
|
+
"context-meter-config.test.cjs": ["context-meter-config"],
|
|
2505
|
+
// M61 D2 — unattended relay + headless spawn cluster
|
|
2506
|
+
"gsd-t-unattended.cjs": ["GSD-T Unattended", "gsd-t-unattended"],
|
|
2507
|
+
"gsd-t-unattended-platform.cjs": ["GSD-T Unattended", "gsd-t-unattended"],
|
|
2508
|
+
"gsd-t-unattended-safety.cjs": ["GSD-T Unattended", "gsd-t-unattended"],
|
|
2509
|
+
"headless-auto-spawn.cjs": ["GSD-T Headless Auto-Spawn"],
|
|
2510
|
+
"headless-exit-codes.cjs": ["GSD-T headless exit-code contract"],
|
|
2511
|
+
"handoff-lock.cjs": ["GSD-T Handoff Lock — Fail-safe sentinel"],
|
|
2512
|
+
"unattended-watch-format.cjs": ["bin/unattended-watch-format.cjs", "unattended watch-tick activity block"],
|
|
2513
|
+
// M61 D1/D4 — misc retired
|
|
2514
|
+
"log-tail.cjs": ["Log Tail — print the last N lines"], // verbatim shipped comment
|
|
2515
|
+
"event-stream.cjs": ["bin/event-stream.cjs", "unattended supervisor watch-tick"],
|
|
2516
|
+
};
|
|
2517
|
+
const DEPRECATED_BIN_STRAYS = Object.keys(DEPRECATED_BIN_STRAY_SIGNATURES);
|
|
2518
|
+
|
|
2519
|
+
// A stray is swept only if its first 1200 chars contain one of the VERBATIM header
|
|
2520
|
+
// sentinels the tool actually shipped with. "Mentions gsd-t" is NOT enough — that
|
|
2521
|
+
// would risk deleting a user's same-named file (red-team HIGH-1). Returns the matched
|
|
2522
|
+
// sentinel (for logging) or null.
|
|
2523
|
+
function _matchedStraySignature(name, content) {
|
|
2524
|
+
const sigs = DEPRECATED_BIN_STRAY_SIGNATURES[name];
|
|
2525
|
+
if (!sigs) return null;
|
|
2526
|
+
const head = content.slice(0, 1200);
|
|
2527
|
+
for (const s of sigs) if (head.includes(s)) return s;
|
|
2528
|
+
return null;
|
|
2529
|
+
}
|
|
2481
2530
|
|
|
2482
2531
|
function copyBinToolsToProject(projectDir, projectName) {
|
|
2483
2532
|
const projectBinDir = path.join(projectDir, "bin");
|
|
@@ -2537,19 +2586,15 @@ function copyBinToolsToProject(projectDir, projectName) {
|
|
|
2537
2586
|
if (!fs.existsSync(strayPath)) continue;
|
|
2538
2587
|
try {
|
|
2539
2588
|
const strayContent = fs.readFileSync(strayPath, "utf8");
|
|
2540
|
-
const
|
|
2541
|
-
|
|
2542
|
-
// is unique enough to rule out user-owned files: node shebang + the
|
|
2543
|
-
// verbatim JSDoc header "GSD-T CLI Installer". Matches every historical
|
|
2544
|
-
// version of bin/gsd-t.js, not just the current one, so older strays
|
|
2545
|
-
// (e.g. v3.13.11 left behind on v3.13.12+) are still swept.
|
|
2546
|
-
const isOurs =
|
|
2547
|
-
head.startsWith("#!/usr/bin/env node") &&
|
|
2548
|
-
head.includes("GSD-T CLI Installer");
|
|
2549
|
-
if (isOurs) {
|
|
2589
|
+
const matched = _matchedStraySignature(stray, strayContent);
|
|
2590
|
+
if (matched) {
|
|
2550
2591
|
fs.unlinkSync(strayPath);
|
|
2551
2592
|
cleaned++;
|
|
2593
|
+
// Red-team fix (HIGH-2): name every deleted file so a destructive sweep
|
|
2594
|
+
// across many projects is reconstructable from scrollback, not a bare count.
|
|
2595
|
+
info(`${projectName} — removed retired bin/${stray} (matched shipped header "${matched.slice(0, 40)}")`);
|
|
2552
2596
|
}
|
|
2597
|
+
// No signature match → leave it alone (user's own same-named file).
|
|
2553
2598
|
} catch {
|
|
2554
2599
|
// leave the file alone on any read error
|
|
2555
2600
|
}
|
|
@@ -4401,6 +4446,43 @@ if (require.main === module) {
|
|
|
4401
4446
|
const code = runParallelCli(args.slice(1), process.env);
|
|
4402
4447
|
process.exit(code);
|
|
4403
4448
|
}
|
|
4449
|
+
case "workflow-path": {
|
|
4450
|
+
// M69 — print the ABSOLUTE path to a GSD-T workflow script, resolved from
|
|
4451
|
+
// this CLI's own install root. Command files shell out to this instead of
|
|
4452
|
+
// hard-coding a relative `templates/workflows/...` scriptPath, which only
|
|
4453
|
+
// resolves when CWD is the GSD-T source repo — from any consumer project
|
|
4454
|
+
// the relative path is unresolvable and `Workflow({scriptPath})` silently
|
|
4455
|
+
// fails, forcing a hand-driven fallback (the HiloAviation scan incident).
|
|
4456
|
+
//
|
|
4457
|
+
// Usage: gsd-t workflow-path <name> (name with or without the
|
|
4458
|
+
// `gsd-t-` prefix / `.workflow.js` suffix). Exit 0 + path on stdout;
|
|
4459
|
+
// exit 4 + error on stderr if the workflow is unknown.
|
|
4460
|
+
const raw = (args[1] || "").trim();
|
|
4461
|
+
if (!raw) {
|
|
4462
|
+
process.stderr.write("usage: gsd-t workflow-path <name>\n");
|
|
4463
|
+
process.exit(64);
|
|
4464
|
+
}
|
|
4465
|
+
const wfDir = path.join(PKG_ROOT, "templates", "workflows");
|
|
4466
|
+
// Normalize: strip a leading "gsd-t-" and a trailing ".workflow.js"/".js",
|
|
4467
|
+
// then rebuild the canonical filename.
|
|
4468
|
+
const stem = raw
|
|
4469
|
+
.replace(/\.workflow\.js$/, "")
|
|
4470
|
+
.replace(/\.js$/, "")
|
|
4471
|
+
.replace(/^gsd-t-/, "");
|
|
4472
|
+
const file = path.join(wfDir, `gsd-t-${stem}.workflow.js`);
|
|
4473
|
+
if (!fs.existsSync(file)) {
|
|
4474
|
+
const avail = fs.existsSync(wfDir)
|
|
4475
|
+
? fs.readdirSync(wfDir)
|
|
4476
|
+
.filter((f) => f.endsWith(".workflow.js"))
|
|
4477
|
+
.map((f) => f.replace(/^gsd-t-/, "").replace(/\.workflow\.js$/, ""))
|
|
4478
|
+
.join(", ")
|
|
4479
|
+
: "(workflows dir missing)";
|
|
4480
|
+
process.stderr.write(`gsd-t workflow-path: unknown workflow "${raw}". Available: ${avail}\n`);
|
|
4481
|
+
process.exit(4);
|
|
4482
|
+
}
|
|
4483
|
+
process.stdout.write(file + "\n");
|
|
4484
|
+
process.exit(0);
|
|
4485
|
+
}
|
|
4404
4486
|
case "preflight": {
|
|
4405
4487
|
// M55 D5 — `gsd-t preflight` thin dispatcher to bin/cli-preflight.cjs.
|
|
4406
4488
|
const { spawnSync } = require("child_process");
|
package/commands/gsd-t-debug.md
CHANGED
|
@@ -22,7 +22,10 @@ Call the `Workflow` tool with:
|
|
|
22
22
|
|
|
23
23
|
```js
|
|
24
24
|
{
|
|
25
|
-
|
|
25
|
+
// Resolve the ABSOLUTE path FIRST via Bash: `gsd-t workflow-path debug` (the
|
|
26
|
+
// workflow ships in the installed @tekyzinc/gsd-t package, not this project — a
|
|
27
|
+
// bare relative path only resolves from the GSD-T source repo). Use its stdout here:
|
|
28
|
+
scriptPath: "<absolute path printed by `gsd-t workflow-path debug`>",
|
|
26
29
|
args: {
|
|
27
30
|
symptom: "describe the failing test or runtime error in one sentence",
|
|
28
31
|
projectDir: "."
|
|
@@ -18,7 +18,10 @@ Capture the design reference from `$ARGUMENTS` (Figma URL / image path). If Figm
|
|
|
18
18
|
|
|
19
19
|
```js
|
|
20
20
|
{
|
|
21
|
-
|
|
21
|
+
// Resolve the ABSOLUTE path FIRST via Bash: `gsd-t workflow-path phase` (the
|
|
22
|
+
// workflow ships in the installed @tekyzinc/gsd-t package, not this project — a
|
|
23
|
+
// bare relative path only resolves from the GSD-T source repo). Use its stdout here:
|
|
24
|
+
scriptPath: "<absolute path printed by `gsd-t workflow-path phase`>",
|
|
22
25
|
args: {
|
|
23
26
|
phase: "design-decompose",
|
|
24
27
|
projectDir: ".",
|
|
@@ -18,7 +18,10 @@ Read the recent commit range (or `$ARGUMENTS` if a specific scope is given) and
|
|
|
18
18
|
|
|
19
19
|
```js
|
|
20
20
|
{
|
|
21
|
-
|
|
21
|
+
// Resolve the ABSOLUTE path FIRST via Bash: `gsd-t workflow-path phase` (the
|
|
22
|
+
// workflow ships in the installed @tekyzinc/gsd-t package, not this project — a
|
|
23
|
+
// bare relative path only resolves from the GSD-T source repo). Use its stdout here:
|
|
24
|
+
scriptPath: "<absolute path printed by `gsd-t workflow-path phase`>",
|
|
22
25
|
args: {
|
|
23
26
|
phase: "doc-ripple",
|
|
24
27
|
projectDir: ".",
|
|
@@ -22,7 +22,10 @@ Call the `Workflow` tool with:
|
|
|
22
22
|
|
|
23
23
|
```js
|
|
24
24
|
{
|
|
25
|
-
|
|
25
|
+
// Resolve the ABSOLUTE path FIRST via Bash: `gsd-t workflow-path execute` (the
|
|
26
|
+
// workflow ships in the installed @tekyzinc/gsd-t package, not this project — a
|
|
27
|
+
// bare relative path only resolves from the GSD-T source repo). Use its stdout here:
|
|
28
|
+
scriptPath: "<absolute path printed by `gsd-t workflow-path execute`>",
|
|
26
29
|
args: {
|
|
27
30
|
milestone: "M{NN}",
|
|
28
31
|
domains: ["m{NN}-d1-...", "m{NN}-d2-...", ...],
|
package/commands/gsd-t-help.md
CHANGED
|
@@ -432,6 +432,11 @@ Use these when user asks for help on a specific command:
|
|
|
432
432
|
- **Files**: `.gsd-t/backlog-settings.md`
|
|
433
433
|
- **Use when**: Customizing the classification dimensions for your project
|
|
434
434
|
|
|
435
|
+
### workflow-path (M69)
|
|
436
|
+
- **Summary**: Prints the ABSOLUTE path to a GSD-T workflow script (`gsd-t-<name>.workflow.js`) resolved from the CLI's own install root. Command files shell out to this instead of hard-coding a relative `templates/workflows/...` scriptPath — which only resolves from the GSD-T source repo, so from any consumer project `Workflow({scriptPath})` would silently fail and fall back to a hand-driven scan (the HiloAviation incident).
|
|
437
|
+
- **Auto-invoked**: Yes — by every workflow-backed command (`gsd-t-scan`, `-execute`, `-verify`, `-wave`, `-integrate`, `-debug`, and the `-phase` runner) at Workflow-invocation time.
|
|
438
|
+
- **CLI**: `gsd-t workflow-path <name>` (name with or without the `gsd-t-` prefix / `.workflow.js` suffix). Exit 0 + absolute path on stdout; exit 4 + available list on unknown name; exit 64 on missing arg.
|
|
439
|
+
|
|
435
440
|
### preflight (M55)
|
|
436
441
|
- **Summary**: Deterministic state-precondition check (`bin/cli-preflight.cjs`); 6 built-in checks (branch-guard, contracts-stable, deps-installed, manifest-fresh, ports-free, working-tree-state). Exit 0/4. Pluggable, zero-dep, captureSpawn-exempt.
|
|
437
442
|
- **Auto-invoked**: Yes — by `gsd-t-execute` Step 1 and `gsd-t verify-gate` Track 1
|
package/commands/gsd-t-impact.md
CHANGED
|
@@ -18,7 +18,10 @@ Read `.gsd-t/progress.md`, the relevant domain `tasks.md`, and `docs/architectur
|
|
|
18
18
|
|
|
19
19
|
```js
|
|
20
20
|
{
|
|
21
|
-
|
|
21
|
+
// Resolve the ABSOLUTE path FIRST via Bash: `gsd-t workflow-path phase` (the
|
|
22
|
+
// workflow ships in the installed @tekyzinc/gsd-t package, not this project — a
|
|
23
|
+
// bare relative path only resolves from the GSD-T source repo). Use its stdout here:
|
|
24
|
+
scriptPath: "<absolute path printed by `gsd-t workflow-path phase`>",
|
|
22
25
|
args: {
|
|
23
26
|
phase: "impact",
|
|
24
27
|
milestone: "M{NN}",
|
|
@@ -28,7 +28,10 @@ Call the `Workflow` tool with:
|
|
|
28
28
|
|
|
29
29
|
```js
|
|
30
30
|
{
|
|
31
|
-
|
|
31
|
+
// Resolve the ABSOLUTE path FIRST via Bash: `gsd-t workflow-path integrate` (the
|
|
32
|
+
// workflow ships in the installed @tekyzinc/gsd-t package, not this project — a
|
|
33
|
+
// bare relative path only resolves from the GSD-T source repo). Use its stdout here:
|
|
34
|
+
scriptPath: "<absolute path printed by `gsd-t workflow-path integrate`>",
|
|
32
35
|
args: {
|
|
33
36
|
milestone: "M{NN}",
|
|
34
37
|
domains: ["m{NN}-d1-...", "m{NN}-d2-..."], // domains that just completed
|
|
@@ -18,7 +18,10 @@ Read `.gsd-t/progress.md` (current version + completed milestones), `docs/requir
|
|
|
18
18
|
|
|
19
19
|
```js
|
|
20
20
|
{
|
|
21
|
-
|
|
21
|
+
// Resolve the ABSOLUTE path FIRST via Bash: `gsd-t workflow-path phase` (the
|
|
22
|
+
// workflow ships in the installed @tekyzinc/gsd-t package, not this project — a
|
|
23
|
+
// bare relative path only resolves from the GSD-T source repo). Use its stdout here:
|
|
24
|
+
scriptPath: "<absolute path printed by `gsd-t workflow-path phase`>",
|
|
22
25
|
args: {
|
|
23
26
|
phase: "milestone",
|
|
24
27
|
projectDir: ".",
|
|
@@ -22,7 +22,10 @@ Call the `Workflow` tool with:
|
|
|
22
22
|
|
|
23
23
|
```js
|
|
24
24
|
{
|
|
25
|
-
|
|
25
|
+
// Resolve the ABSOLUTE path FIRST via Bash: `gsd-t workflow-path phase` (the
|
|
26
|
+
// workflow ships in the installed @tekyzinc/gsd-t package, not this project — a
|
|
27
|
+
// bare relative path only resolves from the GSD-T source repo). Use its stdout here:
|
|
28
|
+
scriptPath: "<absolute path printed by `gsd-t workflow-path phase`>",
|
|
26
29
|
args: {
|
|
27
30
|
phase: "partition",
|
|
28
31
|
milestone: "M{NN}",
|
package/commands/gsd-t-plan.md
CHANGED
|
@@ -18,7 +18,10 @@ Read `.gsd-t/progress.md` and each domain's `scope.md`/`constraints.md`. The par
|
|
|
18
18
|
|
|
19
19
|
```js
|
|
20
20
|
{
|
|
21
|
-
|
|
21
|
+
// Resolve the ABSOLUTE path FIRST via Bash: `gsd-t workflow-path phase` (the
|
|
22
|
+
// workflow ships in the installed @tekyzinc/gsd-t package, not this project — a
|
|
23
|
+
// bare relative path only resolves from the GSD-T source repo). Use its stdout here:
|
|
24
|
+
scriptPath: "<absolute path printed by `gsd-t workflow-path phase`>",
|
|
22
25
|
args: {
|
|
23
26
|
phase: "plan",
|
|
24
27
|
milestone: "M{NN}",
|
package/commands/gsd-t-prd.md
CHANGED
|
@@ -18,7 +18,10 @@ Read any existing `docs/requirements.md`, `docs/architecture.md`, and `.gsd-t/pr
|
|
|
18
18
|
|
|
19
19
|
```js
|
|
20
20
|
{
|
|
21
|
-
|
|
21
|
+
// Resolve the ABSOLUTE path FIRST via Bash: `gsd-t workflow-path phase` (the
|
|
22
|
+
// workflow ships in the installed @tekyzinc/gsd-t package, not this project — a
|
|
23
|
+
// bare relative path only resolves from the GSD-T source repo). Use its stdout here:
|
|
24
|
+
scriptPath: "<absolute path printed by `gsd-t workflow-path phase`>",
|
|
22
25
|
args: {
|
|
23
26
|
phase: "prd",
|
|
24
27
|
projectDir: ".",
|
package/commands/gsd-t-scan.md
CHANGED
|
@@ -20,13 +20,19 @@ Each stage is a schema-validated `agent()` call (or deterministic CLI). Finders
|
|
|
20
20
|
|
|
21
21
|
Read `CLAUDE.md`, `.gsd-t/progress.md`, `.gsd-t/contracts/`, and any existing `.gsd-t/techdebt.md` (the Workflow archives and continues from it). This tells the scan what's already known so it dedups rather than re-discovers.
|
|
22
22
|
|
|
23
|
-
## Step 2:
|
|
23
|
+
## Step 2: Resolve the workflow path, then invoke
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
First resolve the ABSOLUTE path to the workflow script (the workflow ships inside the installed `@tekyzinc/gsd-t` package, NOT in the current project — a bare relative `templates/workflows/...` path only resolves when CWD is the GSD-T source repo, so from any other project `Workflow()` cannot find it). Run via Bash:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
gsd-t workflow-path scan
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
It prints the absolute path (exit 0). Use that exact string as `scriptPath`. If `gsd-t` is not on PATH, fall back to `npx @tekyzinc/gsd-t workflow-path scan`, or derive it from the package: `node -e "const p=require('child_process').execSync('npm root -g').toString().trim(); console.log(p+'/@tekyzinc/gsd-t/templates/workflows/gsd-t-scan.workflow.js')"`. Do NOT fall back to a relative path or a hand-driven scan — that produces an incomplete result (the original bug). Then call the `Workflow` tool with:
|
|
26
32
|
|
|
27
33
|
```js
|
|
28
34
|
{
|
|
29
|
-
scriptPath: "
|
|
35
|
+
scriptPath: "<absolute path printed by `gsd-t workflow-path scan`>",
|
|
30
36
|
args: {
|
|
31
37
|
projectDir: ".", // the project to scan
|
|
32
38
|
scanNumber: 12, // optional — for the register header
|
|
@@ -65,6 +71,7 @@ Present a summary: headline volume totals, findings by severity, the top critica
|
|
|
65
71
|
The scan Workflow updates ALL of these deterministically (no manual follow-on):
|
|
66
72
|
|
|
67
73
|
- `.gsd-t/techdebt.md` — fresh register (synthesis; prior one archived to `.gsd-t/techdebt_YYYY-MM-DD.md`)
|
|
74
|
+
- `.gsd-t/techdebt_in_plain_english.md` — non-technical companion to the register: every TD item in layman's terms, why it matters, and a real-world analogy (document phase)
|
|
68
75
|
- `.gsd-t/scan/{architecture,security,quality,business-rules,contract-drift}.md` — dimension analysis files (document phase)
|
|
69
76
|
- `docs/architecture.md`, `docs/workflows.md`, `docs/infrastructure.md`, `docs/requirements.md`, `README.md` — living docs, **merged not overwritten** (document phase)
|
|
70
77
|
- HTML scan report via `bin/scan-report.js` (render phase)
|
package/commands/gsd-t-verify.md
CHANGED
|
@@ -31,7 +31,10 @@ Call the `Workflow` tool with:
|
|
|
31
31
|
|
|
32
32
|
```js
|
|
33
33
|
{
|
|
34
|
-
|
|
34
|
+
// Resolve the ABSOLUTE path FIRST via Bash: `gsd-t workflow-path verify` (the
|
|
35
|
+
// workflow ships in the installed @tekyzinc/gsd-t package, not this project — a
|
|
36
|
+
// bare relative path only resolves from the GSD-T source repo). Use its stdout here:
|
|
37
|
+
scriptPath: "<absolute path printed by `gsd-t workflow-path verify`>",
|
|
35
38
|
args: {
|
|
36
39
|
milestone: "M{NN}",
|
|
37
40
|
projectDir: ".",
|
package/commands/gsd-t-wave.md
CHANGED
|
@@ -26,7 +26,10 @@ Call the `Workflow` tool with:
|
|
|
26
26
|
|
|
27
27
|
```js
|
|
28
28
|
{
|
|
29
|
-
|
|
29
|
+
// Resolve the ABSOLUTE path FIRST via Bash: `gsd-t workflow-path wave` (the
|
|
30
|
+
// workflow ships in the installed @tekyzinc/gsd-t package, not this project — a
|
|
31
|
+
// bare relative path only resolves from the GSD-T source repo). Use its stdout here:
|
|
32
|
+
scriptPath: "<absolute path printed by `gsd-t workflow-path wave`>",
|
|
30
33
|
args: {
|
|
31
34
|
milestone: "M{NN}",
|
|
32
35
|
domains: ["m{NN}-d1-...", "m{NN}-d2-...", ...], // domains for this wave only, per integration-points
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekyzinc/gsd-t",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.16",
|
|
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",
|
|
@@ -319,7 +319,7 @@ Routine GSD-T actions (milestone → partition → plan → execute → verify
|
|
|
319
319
|
|
|
320
320
|
## GSD-T Workflows (M61 — v4.0.10+)
|
|
321
321
|
|
|
322
|
-
GSD-T workflows live at `templates/workflows/`. Each workflow is a self-contained native Workflow script that handles one phase of the GSD-T lifecycle. Command files (`commands/gsd-t-*.md`) are thin invokers that call `Workflow({scriptPath, args})`.
|
|
322
|
+
GSD-T workflows live at `templates/workflows/`. Each workflow is a self-contained native Workflow script that handles one phase of the GSD-T lifecycle. Command files (`commands/gsd-t-*.md`) are thin invokers that call `Workflow({scriptPath, args})`. The `scriptPath` MUST be resolved to an absolute path at invoke time via `gsd-t workflow-path <name>` (M69) — the workflow ships inside the installed `@tekyzinc/gsd-t` package, not the consumer project, so a bare relative `templates/workflows/...` path only resolves from the GSD-T source repo and silently breaks `Workflow()` everywhere else.
|
|
323
323
|
|
|
324
324
|
Canonical scripts:
|
|
325
325
|
- `gsd-t-execute.workflow.js` — preflight → brief → file-disjointness → parallel(domain workers) → integrate → verify-gate
|
|
@@ -43,7 +43,7 @@ export const meta = {
|
|
|
43
43
|
{ title: "Probe", detail: "volume probe → derive per-area slice list", model: "haiku" },
|
|
44
44
|
{ title: "Deep Scan", detail: "pipeline: per-slice deep finder → single verify" },
|
|
45
45
|
{ title: "Synthesis", detail: "dedup / merge / re-rank into techdebt.md", model: "opus" },
|
|
46
|
-
{ title: "Document", detail: "deep living-doc + dimension-file cross-population (per-doc fan-out)" },
|
|
46
|
+
{ title: "Document", detail: "deep living-doc + dimension-file + plain-English cross-population (per-doc fan-out)" },
|
|
47
47
|
{ title: "Render", detail: "schema extraction + diagrams + HTML report" },
|
|
48
48
|
],
|
|
49
49
|
};
|
|
@@ -463,6 +463,13 @@ if (!fs.existsSync(registerPath)) {
|
|
|
463
463
|
}
|
|
464
464
|
log(`register written: ${JSON.stringify(synthesis.counts)}`);
|
|
465
465
|
|
|
466
|
+
// Read the synthesized register so the plain-English doc can mirror its EXACT
|
|
467
|
+
// TD-NNN ids / order (red-team HIGH-1: raw findings carry no TD ids, so a doc
|
|
468
|
+
// built only from findings would invent divergent numbering and break the
|
|
469
|
+
// cross-reference to techdebt.md). The register exists here (confirmed above).
|
|
470
|
+
let registerText = "";
|
|
471
|
+
try { registerText = fs.readFileSync(registerPath, "utf8"); } catch (_) {}
|
|
472
|
+
|
|
466
473
|
// ─── Document — deep living-doc + dimension-file cross-population (M67) ───
|
|
467
474
|
// M66 made the register deep but left doc cross-population as a non-deterministic
|
|
468
475
|
// "lead agent follow-on" — effectively dropped. M67 fans out one agent PER DOCUMENT,
|
|
@@ -577,15 +584,51 @@ const docTargets = [
|
|
|
577
584
|
id: "readme", label: "README.md", merge: true,
|
|
578
585
|
prompt: `Update or create \`README.md\`: project name + description; tech stack + versions discovered; getting-started/setup (from infrastructure findings); brief architecture overview; link to \`docs/\` for detail. If it exists, MERGE — update tech-stack + setup sections but preserve the user's existing structure and custom content.`,
|
|
579
586
|
},
|
|
587
|
+
{
|
|
588
|
+
id: "techdebt-plain-english", label: ".gsd-t/techdebt_in_plain_english.md",
|
|
589
|
+
needsRegister: true, // red-team HIGH-1: must receive the synthesized register (TD-NNN ids live there, not in findings)
|
|
590
|
+
prompt: `Write \`.gsd-t/techdebt_in_plain_english.md\` — a NON-TECHNICAL companion to the tech-debt register, written for a smart reader who is NOT an engineer (e.g. a founder, PM, or stakeholder). Cover EVERY item in the register (one entry per TD-NNN, in the same severity order), using the EXACT TD-NNN ids from the register provided below. For each item:\n` +
|
|
591
|
+
`- **Heading**: \`### TD-NNN — <the plain-English name of the problem>\` (keep the TD-NNN id so it cross-references the technical register, but rename the title into everyday language — no jargon).\n` +
|
|
592
|
+
`- **What it is** (1-2 sentences): explain the problem with ZERO technical terms. If a technical word is unavoidable, define it in parentheses the way you'd explain it to a friend.\n` +
|
|
593
|
+
`- **Why it matters** (1-2 sentences): the business/user consequence — what could go wrong, who is affected, what it costs.\n` +
|
|
594
|
+
`- **Real-world analogy**: a concrete everyday comparison that makes the risk intuitive (e.g. "This is like leaving the spare house key under the doormat — convenient, but anyone who thinks to look can get in." for a hardcoded secret). The analogy must genuinely map to THIS specific item, not be generic.\n` +
|
|
595
|
+
`- **Severity in plain terms**: translate CRITICAL/HIGH/MEDIUM/LOW into urgency a non-engineer feels ("fix before launch" / "schedule soon" / "clean up eventually").\n` +
|
|
596
|
+
`Open with a 2-3 sentence plain-English summary of the overall health of the codebase and the headline counts. Derive everything from the verified findings — do not invent items or analogies that don't fit. This file is the layman's lens on the same findings as \`.gsd-t/techdebt.md\`.`,
|
|
597
|
+
},
|
|
580
598
|
];
|
|
581
599
|
|
|
582
600
|
const docResults = await parallel(
|
|
583
601
|
docTargets.map((d) => async () => {
|
|
584
602
|
const isLiving = !!d.merge;
|
|
603
|
+
// red-team HIGH-1: targets that mirror the register (plain-english) get the
|
|
604
|
+
// synthesized register text — the authoritative source of TD-NNN ids/order —
|
|
605
|
+
// not just the raw findings.
|
|
606
|
+
// red-team MEDIUM: do NOT silently truncate the register — a large register
|
|
607
|
+
// (e.g. 119 items ≈ 180KB) sliced to a small cap would drop the entire
|
|
608
|
+
// MEDIUM/LOW tail while the prompt says "cover EVERY item" (silent-cap
|
|
609
|
+
// anti-pattern the workflow forbids elsewhere). Cap generously, and if we DO
|
|
610
|
+
// hit it, tell the agent explicitly + log it so completeness loss is visible.
|
|
611
|
+
const REGISTER_CAP = 400000;
|
|
612
|
+
let registerBlock = "";
|
|
613
|
+
if (d.needsRegister) {
|
|
614
|
+
const truncated = registerText.length > REGISTER_CAP;
|
|
615
|
+
if (truncated) {
|
|
616
|
+
log(`⚠ register (${registerText.length} bytes) exceeds the ${REGISTER_CAP}-byte plain-english injection cap — the tail will be missing from techdebt_in_plain_english.md. Consider splitting the register.`);
|
|
617
|
+
}
|
|
618
|
+
registerBlock = [
|
|
619
|
+
"",
|
|
620
|
+
"Synthesized register (.gsd-t/techdebt.md) — use these EXACT TD-NNN ids/order:",
|
|
621
|
+
truncated ? "⚠ NOTE: the register was truncated to fit; cover every item you CAN see and end with a line noting that items beyond the last shown TD-NNN were omitted due to size." : "",
|
|
622
|
+
"```markdown",
|
|
623
|
+
registerText.slice(0, REGISTER_CAP),
|
|
624
|
+
"```",
|
|
625
|
+
].join("\n");
|
|
626
|
+
}
|
|
585
627
|
const prompt = [
|
|
586
628
|
`You are the documentation agent for ONE document in a GSD-T deep scan.`,
|
|
587
629
|
``,
|
|
588
630
|
baseCtx,
|
|
631
|
+
registerBlock,
|
|
589
632
|
``,
|
|
590
633
|
d.prompt,
|
|
591
634
|
``,
|
|
@@ -680,7 +723,7 @@ if (render.ok) {
|
|
|
680
723
|
// aren't versioned.
|
|
681
724
|
const commit = spawnSync(
|
|
682
725
|
"git",
|
|
683
|
-
["add", "-A", ".gsd-t/scan", "docs", "README.md", ":!.gsd-t/scan/.doc-backup"],
|
|
726
|
+
["add", "-A", ".gsd-t/scan", ".gsd-t/techdebt_in_plain_english.md", "docs", "README.md", ":!.gsd-t/scan/.doc-backup"],
|
|
684
727
|
{ cwd: projectDir, stdio: "pipe" }
|
|
685
728
|
);
|
|
686
729
|
if (commit.status === 0) {
|