@tekyzinc/gsd-t 5.11.11 → 5.11.13
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 +63 -0
- package/README.md +3 -7
- package/bin/gsd-t-concise-rewrite.cjs +74 -52
- package/bin/gsd-t.js +36 -0
- package/commands/gsd-t-architect.md +8 -0
- package/package.json +1 -1
- package/templates/CLAUDE-global.md +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,69 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to GSD-T are documented here. Updated with each release.
|
|
4
4
|
|
|
5
|
+
## [5.11.13] - 2026-08-09
|
|
6
|
+
|
|
7
|
+
### Fixed — the reply shortener discarded 4 of every 6 rewrites
|
|
8
|
+
|
|
9
|
+
A keyword check counted question marks, file paths and numbers, and threw the
|
|
10
|
+
whole rewrite away if a count dropped. Almost every rejection was the same
|
|
11
|
+
thing: the writer had asked *himself* a question ("Now the proof: does it
|
|
12
|
+
fire?"), the rewrite correctly cut it as narration, and the check saw a question
|
|
13
|
+
disappear. So a working shortener never once delivered.
|
|
14
|
+
|
|
15
|
+
Counting punctuation cannot tell an ask from thinking out loud. A reader can.
|
|
16
|
+
The same model now reads its own short version back against two questions — is
|
|
17
|
+
this only what he needs, and is it as short as his rules demand — and **fixes**
|
|
18
|
+
it. The reviewer returns text, never a verdict, so nothing is ever discarded. A
|
|
19
|
+
failed review keeps the first pass's rewrite rather than losing it.
|
|
20
|
+
|
|
21
|
+
Both passes now carry the relevance rule: keep only what changes what he
|
|
22
|
+
decides, does next, or now knows.
|
|
23
|
+
|
|
24
|
+
Measured on the reply that failed 4 of 6 before: **6 of 6 delivered, zero
|
|
25
|
+
discarded, 236 words down to 75-158.** Two Sonnet calls, 12-45s.
|
|
26
|
+
|
|
27
|
+
- `bin/gsd-t-concise-rewrite.cjs`: the check is gone; a review pass replaces it
|
|
28
|
+
- `test/m107-concise-rewrite.test.js`: 6 tests, including that the check cannot come back
|
|
29
|
+
|
|
30
|
+
## [5.11.12] - 2026-08-09
|
|
31
|
+
|
|
32
|
+
### Fixed — a retired command stayed typeable forever
|
|
33
|
+
|
|
34
|
+
Installing only ever copied, so a command retired in a past milestone never left
|
|
35
|
+
the machine. Eleven were still typeable long after the code behind them was
|
|
36
|
+
deleted — brainstorm, discuss and prompt (M38), the unattended trio and
|
|
37
|
+
visualize (M61). A command that still answers is one a person will reasonably
|
|
38
|
+
use; this surfaced when `/gsd-t-brainstorm` was treated as live and turned out
|
|
39
|
+
to have no source at all.
|
|
40
|
+
|
|
41
|
+
Install now deletes GSD-T commands the package no longer ships and NAMES each
|
|
42
|
+
one. Only `gsd-t-*.md` is considered, so a command you wrote is never touched.
|
|
43
|
+
An unreadable commands directory stops the install rather than reporting a clean
|
|
44
|
+
pass over a check that never ran.
|
|
45
|
+
|
|
46
|
+
README advertised five commands that do not exist while `help.md` correctly
|
|
47
|
+
called them retired — the two disagreed, and the README is what a reader
|
|
48
|
+
believes.
|
|
49
|
+
|
|
50
|
+
### Changed — /last30days is the first stop for an outside fact
|
|
51
|
+
|
|
52
|
+
Wired into the external-fact rule, the conversation-scope rule, and the
|
|
53
|
+
architect's research step. It searches where people report what actually
|
|
54
|
+
happened — Reddit, Hacker News, X, YouTube transcripts, GitHub — ranked by what
|
|
55
|
+
they engaged with, which is what those stages are asking for and what no
|
|
56
|
+
training data holds. About 40 seconds; web search remains the follow-up. Not
|
|
57
|
+
installed means SAY so in one line and use web search — never silently research
|
|
58
|
+
a thinner way.
|
|
59
|
+
|
|
60
|
+
Install it with `/plugin marketplace add mvanhorn/last30days-skill` then
|
|
61
|
+
`/plugin install last30days`.
|
|
62
|
+
|
|
63
|
+
- `bin/gsd-t.js`: retired commands are removed and named
|
|
64
|
+
- `README.md`: five dead command rows removed
|
|
65
|
+
- `commands/gsd-t-architect.md`, `templates/CLAUDE-global.md`: the research wiring
|
|
66
|
+
- `test/m112-retired-commands.test.js`: 5 tests, including that the README advertises nothing it does not ship
|
|
67
|
+
|
|
5
68
|
## [5.11.11] - 2026-08-09
|
|
6
69
|
|
|
7
70
|
### Fixed — the reply shortener was shortening itself
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# GSD-T: Contract-Driven Development for Claude Code
|
|
2
2
|
|
|
3
|
-
**v5.11.
|
|
3
|
+
**v5.11.13** - A methodology for reliable, parallelizable development using Claude Code with optional Agent Teams support.
|
|
4
4
|
|
|
5
5
|
**Eliminates context rot** — task-level fresh dispatch (one subagent per task, ~10-20% context each) means compaction never triggers.
|
|
6
6
|
**Compaction-proof debug loops** — `gsd-t headless --debug-loop` runs test-fix-retest cycles as separate `claude -p` sessions. A JSONL debug ledger persists all hypothesis/fix/learning history across fresh sessions. Anti-repetition preamble injection prevents retrying failed hypotheses. Escalation tiers (sonnet → opus → human) and a hard iteration ceiling enforced externally.
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
**Real-Time Agent Dashboard** — `gsd-t-stream-feed-server.js` serves a streaming UI at `127.0.0.1:7842` that renders all workers' stream-json output as a continuous feed with task/wave banners, duration + usage chips, token corner bar, localStorage filters, and replay via `WS /feed?from=N`. Dashboard auto-starts idempotently on each spawn (`scripts/gsd-t-dashboard-autostart.cjs`). Port is project-scoped via `projectScopedDefaultPort(projectDir)` so multi-project workflows do not clobber each other.
|
|
18
18
|
**Rigorous User-Journey Coverage + Anti-Drift Test Quality** — `bin/journey-coverage.cjs` regex listener detector + `gsd-t check-coverage` CLI + `scripts/hooks/pre-commit-journey-coverage` commit gate blocks viewer-source commits when uncovered listeners exist. Journey specs in `e2e/journeys/` use functional assertions (zero `toBeVisible`-only tests) per the E2E Test Quality Standard in CLAUDE.md.
|
|
19
19
|
**Universal Playwright Bootstrap + Deterministic UI Enforcement (M50)** — three executable enforcement layers: (1) `bin/playwright-bootstrap.cjs` + `bin/ui-detection.cjs` - idempotent installer detects package manager, installs `@playwright/test` + chromium, scaffolds `e2e/`; (2) Workflow runtime runs `playwright-bootstrap.cjs::installPlaywright()` before any E2E stage when `hasUI && !hasPlaywright`; install failure halts with `blocked-needs-human`; (3) `scripts/hooks/pre-commit-playwright-gate` (opt-in via `gsd-t doctor --install-hooks`) blocks viewer-source commits when staged files are newer than `.gsd-t/.last-playwright-pass`. The `gsd-t setup-playwright [path]` subcommand handles manual install.
|
|
20
|
-
**Visualizer (`/gsd-t-visualize`)** — launches a real-time browser dashboard with dual-pane view: top pane streams the main session, bottom pane streams whichever spawn the user clicks. Left rail shows Live Spawns and Completed (last 100 spawns, status-badged, collapsible). Right rail shows Spawn Plan / Parallelism / Tool Cost. Powered by `gsd-t-stream-feed-server.js` + `gsd-t-dashboard.html`.
|
|
21
20
|
**Surgical model selection** — models are assigned haiku/sonnet/opus per phase (**Fable removed 2026-07-24**; `opus` = **claude-opus-5**). **Single-source tier policy:** `bin/gsd-t-model-tier-policy.cjs` is the SINGLE source of truth; every high-stakes stage (solution-space probe, partition probe, competition judge, pre-mortem, Red Team, competition producers, debug both cycles) runs Opus 5. Opus 5 shipped at the same price as Opus 4.8 but >2× its coding score, so Fable's cost premium is no longer justified. The M82 judge-blindness invariant is relaxed to "fresh independent context" — producers and judge both run opus. Drift is mechanically enforced by the M71-family lint (`test/m85-workflow-tier-policy-lint.test.js`). **M86 model profiles:** `bin/gsd-t-model-profile.cjs` adds a per-project SECOND dimension — three named profiles (`standard` / `pro` / `premium`) that dial which stages run on Opus vs. Sonnet.
|
|
22
21
|
**Token Telemetry** — `gsd-t-calibration-hook.js` records token usage per spawn to `.gsd-t/token-metrics.jsonl` (18-field rows). `gsd-t-token-aggregator.js` aggregates across tasks for the `/gsd-t-metrics` view. Use the native Claude Code `/context` command for live in-session context percentage.
|
|
23
22
|
**Quality North Star** — projects define a `## Quality North Star` section in CLAUDE.md (1–3 sentences, e.g., "This is a published npm library. Every public API must be intuitive and backward-compatible."). `gsd-t-init` auto-detects preset (library/web-app/cli) from package.json signals; `gsd-t-setup` configures it for existing projects. Subagents read it as a quality lens; absent = silent skip (backward compatible).
|
|
@@ -135,7 +134,7 @@ gsd-t model-profile resolve --profile <p> [stage] [--json] # Resolve a profile i
|
|
|
135
134
|
|
|
136
135
|
**Plan Hardening (M83).** The `plan` phase now runs two blocking gates before execute, so a plan can't ship a dead deliverable: a deterministic **acceptance-traceability gate** (`gsd-t traceability-gate` — every AC must bind to a code path + a killing test; the headline capability needs both impl and test) and an adversarial **pre-mortem** agent (opus, fresh-context, predicts edge-case/NFR/dead-deliverable failures and requires a test for each). The temporal dual of the Red Team — attack the design at plan, not just the code at verify. Origin: a build where the headline capability shipped as dead code and burned 4 verify cycles. See `.gsd-t/contracts/plan-hardening-contract.md`.
|
|
137
136
|
|
|
138
|
-
**Competition Mode (M82 · automatic since M84).** On upstream, pre-contract phases (`/gsd-t-partition`, `/gsd-t-milestone`, `/gsd-t-
|
|
137
|
+
**Competition Mode (M82 · automatic since M84).** On upstream, pre-contract phases (`/gsd-t-partition`, `/gsd-t-milestone`, `/gsd-t-design-decompose`) the workflow **automatically decides** whether to compete: an Opus solution-space probe runs at phase start and, if it finds ≥2 genuinely different viable approaches, fans out 3 parallel candidate producers + a judge to pick the winner — the generative dual of the orthogonal validation triad. No flag needed (the probe is biased toward competing, since a better upstream artifact lowers total downstream cost). Partition's judge is an *objective* file-disjointness oracle; subjective phases use a blind + different-model + rubric judge. Override with `--no-competition` or `--competition N` only on explicit request. See `.gsd-t/contracts/competition-mode-contract.md`.
|
|
139
138
|
|
|
140
139
|
`gsd-t parallel` consumes the M44 task-graph (D1) and applies three pre-spawn gates (D4 depgraph validation → D5 file-disjointness → D6 economics) followed by mode-aware headroom/split math. Extends — does not replace — the M40 orchestrator. Contract: `.gsd-t/contracts/wave-join-contract.md` v1.1.0.
|
|
141
140
|
|
|
@@ -171,8 +170,6 @@ This will replace changed command files, back up your CLAUDE.md if customized, a
|
|
|
171
170
|
|---------|---------|------|
|
|
172
171
|
| `/gsd-t-help` | List all commands with descriptions | Manual |
|
|
173
172
|
| `/gsd-t-help {cmd}` | Detailed help for specific command | Manual |
|
|
174
|
-
| `/gsd-t-prompt` | Help formulate your idea before committing | Manual |
|
|
175
|
-
| `/gsd-t-brainstorm` | Creative exploration and idea generation | Manual |
|
|
176
173
|
| `/gsd-t-prd` | Generate a GSD-T-optimized Product Requirements Document | Manual |
|
|
177
174
|
|
|
178
175
|
### Project Initialization
|
|
@@ -218,7 +215,6 @@ This will replace changed command files, back up your CLAUDE.md if customized, a
|
|
|
218
215
|
| `/gsd-t-status` | Cross-domain progress view with token breakdown by domain/task/phase | Manual |
|
|
219
216
|
| `/gsd-t-resume` | Restore context, continue | Manual |
|
|
220
217
|
| `/gsd-t-quick` | Fast task with GSD-T guarantees | Manual |
|
|
221
|
-
| `/gsd-t-visualize` | Launch browser dashboard — SSE server + React Flow agent visualization | Manual |
|
|
222
218
|
| `/gsd-t-debug` | Systematic debugging with state | Manual |
|
|
223
219
|
| `/gsd-t-metrics` | View task telemetry, process ELO, signal distribution, domain health, and cross-project comparison (`--cross-project`) | Manual |
|
|
224
220
|
| `/gsd-t-health` | Validate .gsd-t/ structure, optionally repair | Manual |
|
|
@@ -395,7 +391,7 @@ The session default model (`/model`) is unaffected — profiles govern workflow
|
|
|
395
391
|
|
|
396
392
|
## Unattended / Background Runs
|
|
397
393
|
|
|
398
|
-
For zero-touch overnight or multi-hour runs, use the `/loop` skill with a GSD-T command
|
|
394
|
+
For zero-touch overnight or multi-hour runs, use the `/loop` skill with a GSD-T command. (The `/gsd-t-unattended` relay was retired in M61.)
|
|
399
395
|
|
|
400
396
|
The supervisor halts automatically when: the milestone reaches COMPLETED status, the wall-clock cap expires, `--max-iterations` is reached, safety rails detect a stall or unrecoverable error, or the stop sentinel is touched.
|
|
401
397
|
|
|
@@ -59,16 +59,24 @@ Rewrite the reply below following these rules exactly:
|
|
|
59
59
|
answering a direct question about that. He asks when he wants it.
|
|
60
60
|
4. NO JARGON. Plain words. If a technical term is genuinely needed, put the
|
|
61
61
|
plain meaning first and the term in brackets after it.
|
|
62
|
-
5.
|
|
62
|
+
5. KEEP ONLY WHAT IS RELEVANT TO HIM. Ask of every sentence: does this change
|
|
63
|
+
what he decides, what he does next, or what he now knows? If not, cut it.
|
|
64
|
+
Work the writer did, steps taken, what was checked, what was ruled out — all
|
|
65
|
+
of that is the writer's business, not his, unless he asked.
|
|
63
66
|
6. Prefer a short list or a small table over a paragraph.
|
|
64
67
|
|
|
65
68
|
KEEP THESE. They are not optional, and dropping any one of them means the
|
|
66
69
|
rewrite is rejected and thrown away:
|
|
67
70
|
|
|
68
71
|
- The first line, if it is a dated status banner.
|
|
69
|
-
- EVERY question being asked
|
|
70
|
-
something, that question MUST appear in your rewrite,
|
|
71
|
-
the end. This is the single most common way a rewrite is
|
|
72
|
+
- EVERY question being asked OF THE READER — one he is meant to answer. If the
|
|
73
|
+
reply ends by asking him something, that question MUST appear in your rewrite,
|
|
74
|
+
as its own line, at the end. This is the single most common way a rewrite is
|
|
75
|
+
rejected.
|
|
76
|
+
A question the writer asks HIMSELF is not one of these. "Is that the cause?",
|
|
77
|
+
"Now the proof: does the hook fire?", "So what is slow here?" are thinking out
|
|
78
|
+
loud — cut them like any other narration. The test is simple: would he type an
|
|
79
|
+
answer to it? If not, it is not a question.
|
|
72
80
|
- Any warning, failure, or thing that went wrong.
|
|
73
81
|
- File paths and links, exactly as written.
|
|
74
82
|
- Code blocks, exactly as written.
|
|
@@ -99,46 +107,46 @@ function wordCount(s) {
|
|
|
99
107
|
}
|
|
100
108
|
|
|
101
109
|
/**
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
110
|
+
* The second pass — the rewrite reviewed before it is delivered.
|
|
111
|
+
*
|
|
112
|
+
* A keyword check used to sit here: it counted question marks, file paths and
|
|
113
|
+
* numbers, and threw the whole rewrite away if a count dropped. It discarded
|
|
114
|
+
* 4 of every 6 rewrites, almost always because the writer had asked HIMSELF a
|
|
115
|
+
* question ("Now the proof: does it fire?") which the rewrite correctly cut as
|
|
116
|
+
* narration. Counting punctuation cannot tell an ask from thinking out loud.
|
|
117
|
+
*
|
|
118
|
+
* A reader can. So the same model that wrote the short version now reads it
|
|
119
|
+
* back against one question — is this what David needs, and is it as short as
|
|
120
|
+
* his rules demand — and fixes it. The reviewer returns text, never a verdict,
|
|
121
|
+
* so there is no path on which the work is discarded.
|
|
105
122
|
*/
|
|
106
|
-
|
|
107
|
-
return {
|
|
108
|
-
questions: (text.match(/[^.!?\n]*\?/g) || []).map((q) => q.trim()).filter((q) => q.length > 10),
|
|
109
|
-
numbers: text.match(/\b\d[\d,._]*\b/g) || [],
|
|
110
|
-
paths: text.match(/[\w./-]+\.(?:js|cjs|mjs|ts|tsx|json|md|py|sh)\b/g) || [],
|
|
111
|
-
codeBlocks: (text.match(/```/g) || []).length / 2,
|
|
112
|
-
};
|
|
113
|
-
}
|
|
123
|
+
const REVIEW = `You are checking a shortened reply before it reaches David.
|
|
114
124
|
|
|
115
|
-
|
|
116
|
-
const a = extractInvariants(original);
|
|
117
|
-
const b = extractInvariants(rewritten);
|
|
118
|
-
const lost = [];
|
|
125
|
+
He is a slow reader. Every extra line costs him real time.
|
|
119
126
|
|
|
120
|
-
|
|
121
|
-
lost.push("a question to the reader was dropped");
|
|
122
|
-
}
|
|
123
|
-
const lostPaths = a.paths.filter((p) => !rewritten.includes(p));
|
|
124
|
-
if (lostPaths.length > 0 && lostPaths.length === a.paths.length && a.paths.length > 0) {
|
|
125
|
-
lost.push("every file path was dropped");
|
|
126
|
-
}
|
|
127
|
-
if (a.codeBlocks > 0 && b.codeBlocks < a.codeBlocks) {
|
|
128
|
-
lost.push("a code block was dropped");
|
|
129
|
-
}
|
|
130
|
-
// A number appearing in the rewrite that was never in the original means
|
|
131
|
-
// something was invented.
|
|
132
|
-
const invented = b.numbers.filter((n) => n.length > 2 && !a.numbers.includes(n));
|
|
133
|
-
if (invented.length > 0) {
|
|
134
|
-
lost.push(`a number appeared that was not in the original: ${invented[0]}`);
|
|
135
|
-
}
|
|
136
|
-
return lost;
|
|
137
|
-
}
|
|
127
|
+
Two questions, both about the SHORT version:
|
|
138
128
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
129
|
+
1. Is this ONLY what he needs? Cut anything that does not change what he
|
|
130
|
+
decides, what he does next, or what he now knows. The work someone did,
|
|
131
|
+
steps taken, what was checked, what was ruled out — his business only if he
|
|
132
|
+
asked.
|
|
133
|
+
|
|
134
|
+
2. Is it truly concise by his rules? Answer first, nothing before it. No
|
|
135
|
+
preamble, no backstory, no jargon standing in for a plain word. Lists and
|
|
136
|
+
small tables over paragraphs.
|
|
137
|
+
|
|
138
|
+
Then check nothing was lost that he needs:
|
|
139
|
+
- a question he is meant to ANSWER must still be there, as its own line at the
|
|
140
|
+
end. A question the writer asked himself is narration — it should be gone.
|
|
141
|
+
- warnings, failures, and things that went wrong stay.
|
|
142
|
+
- file paths, links, code blocks and specific numbers stay exactly as written.
|
|
143
|
+
- no fact, number or name may change, and nothing may be added.
|
|
144
|
+
|
|
145
|
+
Return the final reply and nothing else. If it is already right, return it
|
|
146
|
+
unchanged. Never return commentary, never return an empty response.`;
|
|
147
|
+
|
|
148
|
+
/** One call to a fresh Claude. Used by both passes. */
|
|
149
|
+
function askClaude(prompt, cfg) {
|
|
142
150
|
// `--setting-sources project` is what stops the shortener shortening itself.
|
|
143
151
|
//
|
|
144
152
|
// A child started with the personal settings inherits the very Stop hook that
|
|
@@ -181,6 +189,25 @@ function rewrite(text, cfg) {
|
|
|
181
189
|
return { ok: true, text: out };
|
|
182
190
|
}
|
|
183
191
|
|
|
192
|
+
/** Pass 1 — shorten it. */
|
|
193
|
+
function rewrite(text, cfg) {
|
|
194
|
+
return askClaude(`${RULES}\n\n--- REPLY TO REWRITE ---\n${text}`, cfg);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Pass 2 — read the short version back and fix what pass 1 got wrong.
|
|
199
|
+
*
|
|
200
|
+
* Returns text, never a verdict, so the work is never discarded. If the review
|
|
201
|
+
* itself fails, pass 1's rewrite stands: it was already an improvement, and
|
|
202
|
+
* losing it because a second opinion did not arrive would be the old bug in a
|
|
203
|
+
* new place.
|
|
204
|
+
*/
|
|
205
|
+
function review(original, shortened, cfg) {
|
|
206
|
+
const prompt = `${REVIEW}\n\n--- WHAT HE ORIGINALLY WROTE (for reference only) ---\n${original}\n\n--- THE SHORT VERSION TO CHECK AND RETURN ---\n${shortened}`;
|
|
207
|
+
const r = askClaude(prompt, cfg);
|
|
208
|
+
return r.ok ? r.text : shortened;
|
|
209
|
+
}
|
|
210
|
+
|
|
184
211
|
function parseArgs(argv) {
|
|
185
212
|
const args = { project: process.cwd() };
|
|
186
213
|
for (let i = 2; i < argv.length; i++) {
|
|
@@ -231,19 +258,14 @@ function main() {
|
|
|
231
258
|
}, args.json);
|
|
232
259
|
}
|
|
233
260
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
error: `the rewrite lost something: ${lost.join("; ")}`,
|
|
239
|
-
note: "Rewrite rejected — this is the original, unchanged.",
|
|
240
|
-
words: before,
|
|
241
|
-
}, args.json);
|
|
242
|
-
}
|
|
261
|
+
// Second pass: the same model reads its own short version back, against the
|
|
262
|
+
// only two questions that matter — is this what David needs, and is it as
|
|
263
|
+
// short as his rules demand. It returns text, so nothing is ever discarded.
|
|
264
|
+
const finalText = review(text, r.text, cfg);
|
|
243
265
|
|
|
244
|
-
const after = wordCount(
|
|
266
|
+
const after = wordCount(finalText);
|
|
245
267
|
emit({
|
|
246
|
-
ok: true, exitCode: EXIT_OK, text:
|
|
268
|
+
ok: true, exitCode: EXIT_OK, text: finalText,
|
|
247
269
|
words: before, wordsAfter: after,
|
|
248
270
|
saved: before - after,
|
|
249
271
|
}, args.json);
|
|
@@ -251,4 +273,4 @@ function main() {
|
|
|
251
273
|
|
|
252
274
|
if (require.main === module) main();
|
|
253
275
|
|
|
254
|
-
module.exports = { wordCount,
|
|
276
|
+
module.exports = { wordCount, readConfig, rewrite, review, askClaude, RULES, REVIEW };
|
package/bin/gsd-t.js
CHANGED
|
@@ -2092,9 +2092,45 @@ function installCommands(isUpdate) {
|
|
|
2092
2092
|
|
|
2093
2093
|
if (skipped > 0) info(`${skipped} commands unchanged`);
|
|
2094
2094
|
success(`${gsdtCommands.length} GSD-T commands + ${utilityCommands.length} utilities ${isUpdate ? "updated" : "installed"} → ~/.claude/commands/`);
|
|
2095
|
+
|
|
2096
|
+
removeRetiredCommands(commandFiles);
|
|
2097
|
+
|
|
2095
2098
|
return { gsdtCommands, utilityCommands };
|
|
2096
2099
|
}
|
|
2097
2100
|
|
|
2101
|
+
/**
|
|
2102
|
+
* Delete GSD-T commands the package no longer ships.
|
|
2103
|
+
*
|
|
2104
|
+
* Installing only ever copied, so a command retired in a past milestone stayed
|
|
2105
|
+
* on disk forever: eleven were still typeable long after the code behind them
|
|
2106
|
+
* was deleted — brainstorm, discuss and prompt retired in M38, the unattended
|
|
2107
|
+
* trio and visualize in M61. A command that still answers is one a person will
|
|
2108
|
+
* reasonably use, and it then fails in confusing ways.
|
|
2109
|
+
*
|
|
2110
|
+
* Only `gsd-t-*.md` files are considered, so a command the user wrote is never
|
|
2111
|
+
* touched. Every removal is NAMED, and anything that cannot be read or deleted
|
|
2112
|
+
* STOPS the install: a leftover command is exactly the failure being fixed, so
|
|
2113
|
+
* reporting a clean install while one remains would restate the bug.
|
|
2114
|
+
*/
|
|
2115
|
+
function removeRetiredCommands(shipped) {
|
|
2116
|
+
const shippedSet = new Set(shipped);
|
|
2117
|
+
// No try/catch: an unreadable commands directory means the check cannot run,
|
|
2118
|
+
// and an install that skipped it must not report success.
|
|
2119
|
+
const present = fs.readdirSync(COMMANDS_DIR);
|
|
2120
|
+
|
|
2121
|
+
const retired = present.filter(
|
|
2122
|
+
(f) => f.startsWith("gsd-t-") && f.endsWith(".md") && !shippedSet.has(f)
|
|
2123
|
+
);
|
|
2124
|
+
if (retired.length === 0) return;
|
|
2125
|
+
|
|
2126
|
+
for (const file of retired) {
|
|
2127
|
+
fs.unlinkSync(path.join(COMMANDS_DIR, file));
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
info(`Removed ${retired.length} retired command(s) no longer shipped:`);
|
|
2131
|
+
for (const f of retired) info(` ${f.replace(/\.md$/, "")}`);
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2098
2134
|
const GSDT_START = "<!-- GSD-T:START";
|
|
2099
2135
|
const GSDT_END = "<!-- GSD-T:END";
|
|
2100
2136
|
|
|
@@ -184,6 +184,14 @@ platform behavior, known-good patterns, known failure modes, anything time-varyi
|
|
|
184
184
|
assert from memory. Cite what you find (URL + date) per the auto-research rule; a time-varying
|
|
185
185
|
external fact stated without a source is a guess.
|
|
186
186
|
|
|
187
|
+
**Reach for `/last30days <topic>` FIRST, before a plain web search.** It searches where people
|
|
188
|
+
actually report what happened — Reddit, Hacker News, X, YouTube transcripts, GitHub — and ranks by
|
|
189
|
+
what they engaged with, so it surfaces the known failure modes and "we tried this and regretted it"
|
|
190
|
+
threads a web search buries. That is exactly what this stage is asking for, and none of it is in
|
|
191
|
+
the model's training data. It takes about 40 seconds; a plain web search remains the follow-up when
|
|
192
|
+
the answer is a single settled fact it did not return. If the command is not installed, say so in
|
|
193
|
+
one line and fall back to web search — do NOT silently research a thinner way.
|
|
194
|
+
|
|
187
195
|
**When research contradicts a standing rule (e.g. the common solution uses a fallback, the project
|
|
188
196
|
bans fallbacks): the user's rule wins, and you name the conflict in ONE line.** Not a debate:
|
|
189
197
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekyzinc/gsd-t",
|
|
3
|
-
"version": "5.11.
|
|
3
|
+
"version": "5.11.13",
|
|
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",
|
|
@@ -429,7 +429,7 @@ For every load-bearing claim, tag it:
|
|
|
429
429
|
- **`[GUESSED:stale]`** — external/time-varying fact that may have changed.
|
|
430
430
|
|
|
431
431
|
A `[GUESSED:*]` claim is then CLASSIFIED — mechanical string-fact filter, three classes:
|
|
432
|
-
- **`class: external`** → research agent (`model: "opus"`) writes a `## Verified Facts (auto-research)` block (URL + fetch date); ENFORCE marker `<!-- auto-research-claim: class=external key=<key> status=uncited -->` is written; verify FAILs if it stays `status=uncited` (R-FAIL-1).
|
|
432
|
+
- **`class: external`** → research agent (`model: "opus"`) writes a `## Verified Facts (auto-research)` block (URL + fetch date); ENFORCE marker `<!-- auto-research-claim: class=external key=<key> status=uncited -->` is written; verify FAILs if it stays `status=uncited` (R-FAIL-1). **Try `/last30days <topic>` FIRST, then web search.** It searches where people report what actually happened — Reddit, Hacker News, X, YouTube transcripts, GitHub — ranked by what they engaged with, so it surfaces current behavior, gotchas and failure modes that a web search buries and that no model's training data holds. ~40 seconds. Cite what it returns the same way (URL + date). If it is not installed, SAY so in one line and use web search — never silently research a thinner way.
|
|
433
433
|
- **`class: internal`** → grep/Read only; escalate to external if grep empty.
|
|
434
434
|
- **`class: ambiguous`** → LLM judge (`model: "opus"`) decides; uncertain → research (never guess-internal).
|
|
435
435
|
|
|
@@ -449,6 +449,8 @@ Debug workflow calls `append-cycle` each iteration. When the SAME computed sympt
|
|
|
449
449
|
(API behavior, library version, pricing, rate limits, current best-practice), verify-or-flag before
|
|
450
450
|
asserting. If you lack a fresh source, say so explicitly: *"I believe X, but I do not have a current
|
|
451
451
|
source — please verify."* Do NOT state an external/time-varying fact as known when it is a guess.
|
|
452
|
+
**`/last30days <topic>` is the first place to look** — it reports what people have actually hit
|
|
453
|
+
recently rather than what was written up, which is usually what the question is really asking.
|
|
452
454
|
See memory pointer: `feedback_auto_research_external_gaps`.
|
|
453
455
|
|
|
454
456
|
### Architect's Oversight Doctrine (M101 — governed, enforced)
|