@tekyzinc/gsd-t 5.8.10 → 5.10.10

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/bin/gsd-t.js CHANGED
@@ -505,6 +505,31 @@ const WORKTREE_HOOK_MARKER = "gsd-t-worktree-guard";
505
505
  const WORKTREE_HOOK_COMMAND =
506
506
  'bash -c \'[ -f "$(npm root -g)/@tekyzinc/gsd-t/scripts/gsd-t-worktree-guard.js" ] && node "$(npm root -g)/@tekyzinc/gsd-t/scripts/gsd-t-worktree-guard.js" || true\'';
507
507
 
508
+ // ─── M106 Fallback guard (PreToolUse Write|Edit) ────────────────────────────
509
+ // Denies a write that introduces a fallback the user never approved. NO `|| true`
510
+ // here, unlike the worktree guard: if this script is missing, the shell must fail
511
+ // loudly rather than let unchecked writes through. Swallowing its absence is the
512
+ // exact pattern the guard exists to stop.
513
+ const FALLBACK_HOOK_MARKER = "gsd-t-fallback-guard";
514
+ const FALLBACK_HOOK_COMMAND =
515
+ 'node "$(npm root -g)/@tekyzinc/gsd-t/scripts/gsd-t-fallback-guard.js"';
516
+
517
+ // ─── M108 Install self-heal (SessionStart) ──────────────────────────────────
518
+ // Checks the project's tools before any work starts, restores what is missing,
519
+ // and reports what it could not fix. Not a fallback — it repairs the failure
520
+ // and then the session runs correctly, rather than routing around it.
521
+ const INSTALL_HEAL_MARKER = "gsd-t-install-heal";
522
+ const INSTALL_HEAL_COMMAND =
523
+ 'bash -c \'[ -f "$(npm root -g)/@tekyzinc/gsd-t/scripts/gsd-t-install-heal.js" ] && node "$(npm root -g)/@tekyzinc/gsd-t/scripts/gsd-t-install-heal.js" || true\'';
524
+
525
+ // ─── M107 Concise hook (Stop) ───────────────────────────────────────────────
526
+ // Sends a long reply to a fresh Claude for a shorter rewrite. Fail-open by
527
+ // design (`|| true`): it governs how a reply READS, never whether it is true,
528
+ // so a broken rewriter must never gag a correct answer.
529
+ const CONCISE_HOOK_MARKER = "gsd-t-concise-hook";
530
+ const CONCISE_HOOK_COMMAND =
531
+ 'bash -c \'[ -f "$(npm root -g)/@tekyzinc/gsd-t/scripts/gsd-t-concise-hook.js" ] && node "$(npm root -g)/@tekyzinc/gsd-t/scripts/gsd-t-concise-hook.js" || true\'';
532
+
508
533
  // Append entries to {projectDir}/.gitignore. Each entry added only if absent.
509
534
  // Idempotent. Returns true if any entries were added, false otherwise.
510
535
  function ensureGitignoreEntries(projectDir, entries) {
@@ -963,6 +988,76 @@ function configureWorktreeGuardHook(settingsPath) {
963
988
  return configureWriteEditHook(settingsPath, WORKTREE_HOOK_MARKER, WORKTREE_HOOK_COMMAND, "worktree guard");
964
989
  }
965
990
 
991
+ // M106 — register the fallback guard on Write|Edit. Same registrar again.
992
+ function configureFallbackGuardHook(settingsPath) {
993
+ return configureWriteEditHook(settingsPath, FALLBACK_HOOK_MARKER, FALLBACK_HOOK_COMMAND, "fallback guard");
994
+ }
995
+
996
+ // M107 — register the concise rewriter on Stop. Not a Write|Edit hook, so it
997
+ // uses the Stop registrar below rather than configureWriteEditHook.
998
+ function configureConciseHook(settingsPath) {
999
+ return configureStopHook(settingsPath, CONCISE_HOOK_MARKER, CONCISE_HOOK_COMMAND, "concise rewrite");
1000
+ }
1001
+
1002
+ // M108 — register the install self-heal on SessionStart, so a broken install is
1003
+ // repaired before any work begins.
1004
+ function configureInstallHealHook(settingsPath) {
1005
+ return configureEventHook(settingsPath, "SessionStart", INSTALL_HEAL_MARKER, INSTALL_HEAL_COMMAND, "install self-heal");
1006
+ }
1007
+
1008
+ // Register a Stop hook by marker. Mirrors configureWriteEditHook exactly, on the
1009
+ // Stop event instead of PreToolUse.
1010
+ function configureStopHook(settingsPath, marker, command, label) {
1011
+ return configureEventHook(settingsPath, "Stop", marker, command, label);
1012
+ }
1013
+
1014
+ // Register a hook on any event by marker. One registrar for every event, so a
1015
+ // new hook needs no new copy of this logic.
1016
+ function configureEventHook(settingsPath, event, marker, command, label) {
1017
+ const targetPath = settingsPath || SETTINGS_JSON;
1018
+ let settings = {};
1019
+ if (fs.existsSync(targetPath)) {
1020
+ try {
1021
+ settings = JSON.parse(fs.readFileSync(targetPath, "utf8"));
1022
+ if (!settings || typeof settings !== "object") settings = {};
1023
+ } catch {
1024
+ warn(`settings.json has invalid JSON — cannot configure ${label} hook`);
1025
+ return { installed: false, action: "noop" };
1026
+ }
1027
+ }
1028
+ if (!settings.hooks) settings.hooks = {};
1029
+ if (!Array.isArray(settings.hooks[event])) settings.hooks[event] = [];
1030
+
1031
+ let action = "noop";
1032
+ let found = false;
1033
+ for (const entry of settings.hooks[event]) {
1034
+ if (!entry || !Array.isArray(entry.hooks)) continue;
1035
+ for (const h of entry.hooks) {
1036
+ if (h && typeof h.command === "string" && h.command.includes(marker)) {
1037
+ found = true;
1038
+ if (h.command !== command) { h.command = command; action = "refreshed"; }
1039
+ }
1040
+ }
1041
+ }
1042
+ if (!found) {
1043
+ // The install check goes FIRST on SessionStart, so a broken install is
1044
+ // repaired before anything else tries to use the missing tools.
1045
+ const entry = { matcher: "", hooks: [{ type: "command", command }] };
1046
+ if (event === "SessionStart") settings.hooks[event].unshift(entry);
1047
+ else settings.hooks[event].push(entry);
1048
+ action = "added";
1049
+ }
1050
+ if (action === "noop") return { installed: true, action };
1051
+
1052
+ try {
1053
+ fs.writeFileSync(targetPath, JSON.stringify(settings, null, 2));
1054
+ } catch (e) {
1055
+ warn(`Failed to write settings.json: ${e.message}`);
1056
+ return { installed: false, action: "noop" };
1057
+ }
1058
+ return { installed: true, action };
1059
+ }
1060
+
966
1061
  function configureWriteEditHook(settingsPath, marker, command, label) {
967
1062
  const targetPath = settingsPath || SETTINGS_JSON;
968
1063
  let settings = {};
@@ -1533,10 +1628,16 @@ const UTILITY_SCRIPTS = ["gsd-t-tools.js", "gsd-t-statusline.js", "gsd-t-event-w
1533
1628
 
1534
1629
  function installUtilityScripts() {
1535
1630
  ensureDir(SCRIPTS_DIR);
1631
+ const notDelivered = [];
1536
1632
  for (const script of UTILITY_SCRIPTS) {
1537
1633
  const src = path.join(PKG_SCRIPTS, script);
1538
1634
  const dest = path.join(SCRIPTS_DIR, script);
1539
- if (!fs.existsSync(src)) continue;
1635
+ if (!fs.existsSync(src)) {
1636
+ // Promised but absent from the package. Reported, never skipped quietly —
1637
+ // the same silence let projects run for weeks on a half install.
1638
+ notDelivered.push(script);
1639
+ continue;
1640
+ }
1540
1641
  const srcContent = fs.readFileSync(src, "utf8");
1541
1642
  const destContent = fs.existsSync(dest) ? fs.readFileSync(dest, "utf8") : "";
1542
1643
  if (normalizeEol(srcContent) !== normalizeEol(destContent)) {
@@ -1545,6 +1646,11 @@ function installUtilityScripts() {
1545
1646
  info(`${script} unchanged`);
1546
1647
  }
1547
1648
  }
1649
+ if (notDelivered.length) {
1650
+ warn(`${notDelivered.length} script(s) are named by the installer but absent from the package:`);
1651
+ for (const s of notDelivered) warn(` ${s}`);
1652
+ warn(` Anything depending on these will fail. This is a packaging defect.`);
1653
+ }
1548
1654
  }
1549
1655
 
1550
1656
  // ─── Global Bin Tools (~/.claude/bin/) ───────────────────────────────────────
@@ -1591,6 +1697,21 @@ const GLOBAL_BIN_TOOLS = [
1591
1697
  // caller but absent from BOTH lists is dead in every project
1592
1698
  // ([[project_global_bin_propagation_gap]], 4 prior occurrences).
1593
1699
  "gsd-t-pseudocode-style.cjs",
1700
+ // M106 — Fallback detector. scripts/gsd-t-fallback-guard.js (a PreToolUse hook)
1701
+ // shells out to this by absolute path; if it is missing the guard DENIES the
1702
+ // write rather than allowing it unchecked, so an omission here breaks every
1703
+ // Write/Edit rather than failing silently. Also in PROJECT_BIN_TOOLS below.
1704
+ "gsd-t-fallback-detect.cjs",
1705
+ // M107 — Concise rewriter. scripts/gsd-t-concise-hook.js (a Stop hook) shells
1706
+ // out to this; absent, the hook allows the long reply through (fail-open by
1707
+ // design — it governs readability, never truth).
1708
+ "gsd-t-concise-rewrite.cjs",
1709
+ // M108 — Install self-check, run by the SessionStart hook and by
1710
+ // `gsd-t install-check`.
1711
+ "gsd-t-install-check.cjs",
1712
+ // M109 — project-history reader + rule miner, used by /gsd-t-setup to write a
1713
+ // project CLAUDE.md from what actually happened rather than from a template.
1714
+ "gsd-t-project-history.cjs", "gsd-t-rule-mine.cjs",
1594
1715
  ];
1595
1716
 
1596
1717
  function installGlobalBinTools() {
@@ -1838,10 +1959,14 @@ const SHARED_TEMPLATES = [
1838
1959
  function installSharedTemplates() {
1839
1960
  ensureDir(CLAUDE_TEMPLATES_DIR);
1840
1961
  let installed = 0, skipped = 0;
1962
+ const notDelivered = [];
1841
1963
  for (const file of SHARED_TEMPLATES) {
1842
1964
  const src = path.join(PKG_TEMPLATES, file);
1843
1965
  const dest = path.join(CLAUDE_TEMPLATES_DIR, file);
1844
- if (!fs.existsSync(src)) continue;
1966
+ if (!fs.existsSync(src)) {
1967
+ notDelivered.push(file); // promised but absent — reported, never silent
1968
+ continue;
1969
+ }
1845
1970
  if (fs.existsSync(dest) &&
1846
1971
  normalizeEol(fs.readFileSync(src, "utf8")) === normalizeEol(fs.readFileSync(dest, "utf8"))) {
1847
1972
  skipped++;
@@ -1852,6 +1977,10 @@ function installSharedTemplates() {
1852
1977
  }
1853
1978
  if (skipped > 0) info(`${skipped} templates unchanged`);
1854
1979
  success(`${installed + skipped} shared templates → ~/.claude/templates/`);
1980
+ if (notDelivered.length) {
1981
+ warn(`${notDelivered.length} template(s) are named by the installer but absent from the package:`);
1982
+ for (const f of notDelivered) warn(` ${f}`);
1983
+ }
1855
1984
  }
1856
1985
 
1857
1986
  function installCommands(isUpdate) {
@@ -2035,6 +2164,27 @@ async function doInstall(opts = {}) {
2035
2164
  else info("Worktree-collision guard already configured");
2036
2165
  }
2037
2166
 
2167
+ const fbHook = configureFallbackGuardHook(SETTINGS_JSON);
2168
+ if (fbHook.installed) {
2169
+ if (fbHook.action === "added") success("Fallback guard added (denies a write that adds an unapproved fallback — M106)");
2170
+ else if (fbHook.action === "refreshed") success("Fallback guard refreshed");
2171
+ else info("Fallback guard already configured");
2172
+ }
2173
+
2174
+ const ccHook = configureConciseHook(SETTINGS_JSON);
2175
+ if (ccHook.installed) {
2176
+ if (ccHook.action === "added") success("Concise-rewrite hook added (shortens a long reply before you read it — M107)");
2177
+ else if (ccHook.action === "refreshed") success("Concise-rewrite hook refreshed");
2178
+ else info("Concise-rewrite hook already configured");
2179
+ }
2180
+
2181
+ const healHook = configureInstallHealHook(SETTINGS_JSON);
2182
+ if (healHook.installed) {
2183
+ if (healHook.action === "added") success("Install self-heal added (restores missing tools before work starts — M108)");
2184
+ else if (healHook.action === "refreshed") success("Install self-heal refreshed");
2185
+ else info("Install self-heal already configured");
2186
+ }
2187
+
2038
2188
  heading("Graph Engine (CGC)");
2039
2189
  installCgc();
2040
2190
 
@@ -2993,6 +3143,19 @@ const PROJECT_BIN_TOOLS = [
2993
3143
  "gsd-t-model-tier-policy.cjs",
2994
3144
  // M86 — Model-profile config + resolver CLI (standard/pro/premium tier-spend switch).
2995
3145
  "gsd-t-model-profile.cjs",
3146
+ // M106 — Fallback detector. The PreToolUse guard prefers the project-local
3147
+ // copy; the verify gate dispatches to it by absolute path. Missing here means
3148
+ // every Write/Edit is DENIED (the guard halts rather than allowing unchecked),
3149
+ // so this entry is load-bearing — [[project_global_bin_propagation_gap]].
3150
+ "gsd-t-fallback-detect.cjs",
3151
+ // M107 — Concise rewriter, invoked by the Stop hook.
3152
+ "gsd-t-concise-rewrite.cjs",
3153
+ // M108 — Install self-check. Every project carries its own copy so it can
3154
+ // verify and repair itself even when the global install is what broke.
3155
+ "gsd-t-install-check.cjs",
3156
+ // M109 — project-history reader + rule miner, so /gsd-t-setup can write a
3157
+ // project CLAUDE.md from what actually happened rather than from a template.
3158
+ "gsd-t-project-history.cjs", "gsd-t-rule-mine.cjs",
2996
3159
  // M89 — Auto-research gate classifier (classify a guessed claim as internal vs external;
2997
3160
  // propagated to each registered project's bin/ so the workflow runCli fallback resolves
2998
3161
  // downstream — per [[project_global_bin_propagation_gap]]).
@@ -3157,10 +3320,20 @@ function copyBinToolsToProject(projectDir, projectName) {
3157
3320
  }
3158
3321
  }
3159
3322
  let copied = 0;
3323
+ // Tools this pass could NOT deliver. Every one is reported. A silent skip
3324
+ // here is how binvoice ran for weeks with 20 of 38 tools while every update
3325
+ // reported success — the missing files were never counted, so nothing looked
3326
+ // wrong. ([[project_global_bin_propagation_gap]], now 5 occurrences.)
3327
+ const notDelivered = [];
3160
3328
  for (const tool of PROJECT_BIN_TOOLS) {
3161
3329
  const src = path.join(PKG_ROOT, "bin", tool);
3162
3330
  const dest = path.join(projectBinDir, tool);
3163
- if (!fs.existsSync(src)) continue;
3331
+ if (!fs.existsSync(src)) {
3332
+ // The package promises a tool it does not contain. That is a packaging
3333
+ // defect and it affects EVERY project — it must never pass unremarked.
3334
+ notDelivered.push({ tool, why: "absent from the package being installed" });
3335
+ continue;
3336
+ }
3164
3337
  let needsCopy = true;
3165
3338
  if (fs.existsSync(dest)) {
3166
3339
  try {
@@ -3168,7 +3341,7 @@ function copyBinToolsToProject(projectDir, projectName) {
3168
3341
  const destContent = fs.readFileSync(dest, "utf8");
3169
3342
  if (srcContent === destContent) needsCopy = false;
3170
3343
  } catch {
3171
- // fall through, will copy
3344
+ // could not compare — copy, which is the safe direction
3172
3345
  }
3173
3346
  }
3174
3347
  if (needsCopy) {
@@ -3177,10 +3350,17 @@ function copyBinToolsToProject(projectDir, projectName) {
3177
3350
  try { fs.chmodSync(dest, 0o755); } catch {}
3178
3351
  copied++;
3179
3352
  } catch (e) {
3180
- warn(`${projectName} — failed to copy ${tool}: ${e.message}`);
3353
+ notDelivered.push({ tool, why: e.message });
3181
3354
  }
3182
3355
  }
3183
3356
  }
3357
+ if (notDelivered.length) {
3358
+ warn(`${projectName} — ${notDelivered.length} of ${PROJECT_BIN_TOOLS.length} tools were NOT delivered:`);
3359
+ for (const n of notDelivered) warn(` ${n.tool} — ${n.why}`);
3360
+ warn(` This project's install is incomplete. Tools that depend on the missing`);
3361
+ warn(` files will fail. Run 'gsd-t install-check --project ${projectDir}' after`);
3362
+ warn(` fixing the package.`);
3363
+ }
3184
3364
  let cleaned = 0;
3185
3365
  if (!_isGsdTSourcePackage(projectDir)) {
3186
3366
  for (const stray of DEPRECATED_BIN_STRAYS) {
@@ -5369,6 +5549,20 @@ if (require.main === module) {
5369
5549
  });
5370
5550
  process.exit(res.status == null ? 1 : res.status);
5371
5551
  }
5552
+ case "install-check": {
5553
+ // M108 — check this project's tools against the installed package, and
5554
+ // restore anything missing. `--check` reports without changing anything;
5555
+ // `--report` reads the shared log of every repair across all projects.
5556
+ const { spawnSync } = require("child_process");
5557
+ const js = path.join(__dirname, "gsd-t-install-check.cjs");
5558
+ if (!require("node:fs").existsSync(js)) {
5559
+ error(`gsd-t-install-check.cjs not found at ${js} — reinstall GSD-T`);
5560
+ process.exit(1);
5561
+ }
5562
+ const res = spawnSync(process.execPath, [js, ...args.slice(1)], { stdio: "inherit" });
5563
+ process.exit(res.status == null ? 1 : res.status);
5564
+ }
5565
+
5372
5566
  case "pseudocode-style": {
5373
5567
  // Contract v1.2.0 §1.1 — `gsd-t pseudocode-style (--doc <f> | --dir <d>)` thin
5374
5568
  // dispatcher to the PseudoCode flow-line STYLE gate. Sibling of `guard-map`:
@@ -72,109 +72,133 @@ CLAUDE.md Analysis:
72
72
 
73
73
  Note: "No existing CLAUDE.md — will generate from scratch."
74
74
 
75
- ## Step 4: Ask Targeted Questions
75
+ ## Step 3.5: Read what actually happened here
76
76
 
77
- Only ask what could NOT be auto-detected. Skip questions where the answer is already clear from scanning.
77
+ Before writing anything, read the project's own history. A rule that keeps
78
+ getting broken is the rule that most needs writing down, and nobody remembers
79
+ those on request — they have to be found.
78
80
 
79
- **Potential questions** (ask only if not auto-detected):
81
+ ```bash
82
+ node bin/gsd-t-project-history.cjs --project . --json
83
+ ```
80
84
 
81
- 1. **Branch Guard**: "Which branch should commits target?" (skip if only `main` or `master` exists)
82
- 2. **Autonomy Level**: "What autonomy level? Level 1 (Supervised), Level 2 (Standard), Level 3 (Full Auto — default)" (skip if existing CLAUDE.md already declares it)
83
- 3. **Workflow Preferences**: "Any overrides to the global defaults? (Research Policy, Phase Flow)" (skip if user has no overrides)
84
- 4. **Deployed URLs**: "Production, staging, and local URLs?" (skip if found in .env or existing docs)
85
- 5. **Project-specific rules**: "Any 'never do' rules specific to this project?" (skip if existing CLAUDE.md already has them)
85
+ Three sources, cheapest first. Each reports whether it was there; a missing one
86
+ is **named**, never skipped in silence:
86
87
 
87
- **Do NOT ask about**:
88
- - Tech stack (auto-detected)
89
- - Naming conventions (auto-detected)
90
- - Testing framework (auto-detected)
91
- - File structure (auto-detected)
92
- - Anything already covered by the global CLAUDE.md
88
+ | Source | What it gives |
89
+ |---|---|
90
+ | Git | Files fixed the same way repeatedly, and real reverts |
91
+ | Decision log | Directives already recorded, with dates |
92
+ | Past sessions | What the user typed when something kept going wrong |
93
93
 
94
- ## Step 5: Generate CLAUDE.md
94
+ Session history is large — one project holds 315 MB — so the tool funnels it:
95
+ keep only the user's own turns, drop pasted logs, keep only complaint-shaped
96
+ lines. Under a second, and the result fits in context.
95
97
 
96
- Build the file using this structure. Include only sections that have real content — omit empty sections entirely.
98
+ **If it exits 4, there is no history at all.** Do not carry on and write a
99
+ thinner file. Stop and ask:
97
100
 
98
- ```markdown
99
- # {Project Name}
101
+ ```
102
+ Sources found: git 67 commits | decision log 1 line | sessions 0 | contracts 0
103
+
104
+ I can mine 0 rules from this project's history.
105
+
106
+ a) Write stack and commands only — the rules section left out, with the
107
+ reason written into the file. Not a normal CLAUDE.md.
108
+ b) You dictate the rules now.
109
+ c) Stop.
110
+ ```
111
+
112
+ Whichever they pick, the gap goes **into the generated file** — "Rules: none
113
+ derivable, no project history" — so thinness stays visible rather than reading
114
+ as "this project has no rules."
100
115
 
101
- ## Branch Guard
102
- **Expected branch**: {branch}
116
+ ## Step 4: Show the rules found, and let the user tick them
103
117
 
104
- ## Project Overview
105
- {Brief description — what problem does this solve and for whom?}
118
+ Do **not** ask the user to recall rules. Mine every rule the project already
119
+ states, and let them confirm:
106
120
 
107
- ### Architecture
108
- {High-level architecture summary if the project has one — e.g., "Three-tier WebSocket bridge" with a diagram. Keep it concise. Details belong in docs/architecture.md}
121
+ ```bash
122
+ node bin/gsd-t-rule-mine.cjs --project . --top 12
123
+ ```
124
+
125
+ Six sources, ranked by how many agree — a rule found in three places ranks top,
126
+ because repetition is the evidence. The output is a tick-list:
127
+
128
+ ```
129
+ 12 candidate rules for binvoice. Tick the ones that must NEVER be broken.
109
130
 
110
- ## Where Things Live
131
+ RULE SEEN IN
132
+ 1 [ ] NEVER contact the buyer directly CLAUDE.md (HC-003)
133
+ 2 [ ] TEXT-FIRST capture (enforced by a pre-write gate) CLAUDE.md (HC-004)
134
+ 3 [ ] NEVER scan the whole page CLAUDE.md (HC-005)
111
135
 
112
- | Need to find... | Look here |
113
- |-----------------|-----------|
114
- | {component} | {path} |
136
+ Tick numbers (e.g. 1,3,4) or 'all':
137
+ ```
115
138
 
116
- ## Key Technologies
117
- {Bulleted list of language, framework, database, testing, etc.}
139
+ The right-hand column is what makes this fast — the user is confirming
140
+ something they already said, not recalling it. **Cap the screen at 12.**
141
+ Anything below goes to `.gsd-t/setup-rules-full.md`; nothing is dropped.
118
142
 
119
- ## Documentation
120
- - Requirements: docs/requirements.md
121
- - Architecture: docs/architecture.md
122
- - Workflows: docs/workflows.md
123
- - Infrastructure: docs/infrastructure.md
143
+ **Never invent a rule.** Every one comes from somewhere in the project, and the
144
+ tick-list shows where. A rule the user did not tick is not inviolable — it may
145
+ still belong elsewhere in the file, but not in that section.
124
146
 
125
- ## Autonomy Level
126
- **Level {N} — {Name}** ({description}) <!-- default: Level 3 — Full Auto -->
147
+ **Determine these by reading, never by asking:**
127
148
 
128
- ## Workflow Preferences
129
- <!-- Override global defaults. Delete what you don't need to override. -->
149
+ | | How |
150
+ |---|---|
151
+ | Which branch | `git branch --show-current` |
152
+ | Where the repo misleads | Two version fields disagreeing, a legacy path that still looks live |
153
+ | Which files are dangerous | Fixed 5+ times in the git history |
154
+ | Stack, build, test | The manifest |
130
155
 
131
- ### Research Policy
132
- {project-specific overrides, or omit section}
156
+ **Ask only if genuinely unresolvable:** the autonomy level when no existing
157
+ CLAUDE.md declares one, and deployed URLs when nothing records them.
133
158
 
134
- ### Phase Flow
135
- {project-specific overrides, or omit section}
159
+ ## Step 5: Generate CLAUDE.md
136
160
 
137
- ## Testing
138
- {Framework, file organization, naming, running instructions}
161
+ Use the mold at `templates/CLAUDE-project.md`. It is a real mold — do NOT copy
162
+ any existing project's file, and never GSD-T's own.
139
163
 
140
- ## Code Patterns to Follow
141
- {Project-specific conventions that differ from or extend global defaults}
164
+ **Every section may be left out, with the reason stated. None may be padded.**
142
165
 
143
- ### Naming Conventions
144
- {If different from global defaults}
166
+ | Section | Include when | Fill from |
167
+ |---|---|---|
168
+ | Title + one-line what-this-is | Always | The manifest, the README |
169
+ | **Rules that can never be broken** | The user ticked at least one | Step 4's tick-list, verbatim |
170
+ | Where the repo misleads you | Reading the code gives a confident wrong answer | Determined, never asked |
171
+ | Files riskier than they look | Some file was fixed 5+ times | Git history |
172
+ | Where this differs from global | A genuine difference exists | Compared against `~/.claude/CLAUDE.md` |
173
+ | Stack and commands | Always | The manifest |
174
+ | Where things are written down | Always | Fixed pointers |
145
175
 
146
- ## Running the App
147
- {Dev server, build commands, first-time setup}
176
+ **Target 40–70 lines.** If it is longer, something in it is either restating a
177
+ global rule or repeating what the repo already says.
148
178
 
149
- ## Environment Variables
150
- | Variable | Purpose | Default |
151
- |----------|---------|---------|
152
- | {VAR} | {purpose} | {default} |
179
+ ### What must never appear
153
180
 
154
- ## Deployed URLs
155
- - **Production**: {url}
156
- - **Staging**: {url}
157
- - **Local**: http://localhost:{port}
181
+ | Never | Why |
182
+ |---|---|
183
+ | Anything the global file already says | Three projects each paste the entire Destructive Action Guard verbatim — 15 wasted lines apiece |
184
+ | Anything a hook or gate enforces | The machine does not read this file |
185
+ | A version number, a line count, "currently in progress" | Wrong within a week. It belongs in `progress.md` |
186
+ | A file listing, a dependency list, a command count | The repo answers it, and answers it currently |
187
+ | A rule nobody stated | Every rule comes from the tick-list, and the tick-list shows its source |
158
188
 
159
- ## Don't Do These Things
160
- {Project-specific rules only — don't repeat global rules}
189
+ ### The line that matters most
161
190
 
162
- ## GSD-T Workflow
163
- This project uses contract-driven development.
164
- - State: .gsd-t/progress.md
165
- - Contracts: .gsd-t/contracts/
166
- - Domains: .gsd-t/domains/
191
+ A rule states **what must never happen and what breaks if it does**. If it is
192
+ enforced by a hook or a gate, say so — the reader should know a machine is
193
+ watching:
167
194
 
168
- ## Current Status
169
- See `.gsd-t/progress.md` for current milestone/phase state.
195
+ ```
196
+ - **Never touch facebook.com** — no permissions, no requests, no DOM writes.
197
+ A single write turns a read-only observer into an actor on someone else's
198
+ account. Enforced by a pre-write gate.
170
199
  ```
171
200
 
172
- ### Section Rules:
173
- - **NEVER duplicate** global CLAUDE.md content (Destructive Action Guard, Pre-Commit Gate, Prime Directives, etc.)
174
- - **ALWAYS include**: Branch Guard, GSD-T Workflow, Current Status
175
- - **Include if relevant**: Where Things Live, Testing, Code Patterns, Environment Variables
176
- - **Omit if empty**: Deployed URLs (if not deployed), Architecture (if trivial), Workflow Preferences (if no overrides)
177
-
201
+ Not: *"Be careful with Facebook interactions."*
178
202
  ## Step 5.5: Quality North Star Configuration
179
203
 
180
204
  After generating the CLAUDE.md content (Step 5) and before presenting it to the user, offer a Quality North Star section if one is not already present.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tekyzinc/gsd-t",
3
- "version": "5.8.10",
3
+ "version": "5.10.10",
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",