@tekyzinc/gsd-t 2.50.12 → 2.53.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/CHANGELOG.md +24 -0
- package/README.md +379 -372
- package/bin/component-registry.js +250 -0
- package/bin/graph-cgc.js +510 -510
- package/bin/graph-indexer.js +147 -147
- package/bin/graph-overlay.js +195 -195
- package/bin/graph-parsers.js +327 -327
- package/bin/graph-query.js +453 -452
- package/bin/graph-store.js +154 -154
- package/bin/qa-calibrator.js +194 -0
- package/bin/scan-data-collector.js +153 -153
- package/bin/scan-diagrams-generators.js +187 -187
- package/bin/scan-diagrams.js +79 -79
- package/bin/scan-renderer.js +92 -92
- package/bin/scan-report-sections.js +121 -121
- package/bin/scan-report.js +184 -184
- package/bin/scan-schema-parsers.js +199 -199
- package/bin/scan-schema.js +103 -103
- package/bin/token-budget.js +246 -0
- package/commands/Claude-md.md +10 -10
- package/commands/branch.md +15 -15
- package/commands/checkin.md +45 -45
- package/commands/global-change.md +209 -209
- package/commands/gsd-t-audit.md +199 -0
- package/commands/gsd-t-backlog-add.md +94 -94
- package/commands/gsd-t-backlog-edit.md +111 -111
- package/commands/gsd-t-backlog-list.md +63 -63
- package/commands/gsd-t-backlog-move.md +94 -94
- package/commands/gsd-t-backlog-promote.md +123 -123
- package/commands/gsd-t-backlog-remove.md +86 -86
- package/commands/gsd-t-backlog-settings.md +158 -158
- package/commands/gsd-t-complete-milestone.md +528 -515
- package/commands/gsd-t-debug.md +506 -399
- package/commands/gsd-t-discuss.md +174 -174
- package/commands/gsd-t-execute.md +758 -634
- package/commands/gsd-t-feature.md +276 -276
- package/commands/gsd-t-health.md +142 -142
- package/commands/gsd-t-help.md +465 -457
- package/commands/gsd-t-impact.md +302 -302
- package/commands/gsd-t-init.md +320 -280
- package/commands/gsd-t-integrate.md +365 -249
- package/commands/gsd-t-milestone.md +87 -87
- package/commands/gsd-t-partition.md +442 -361
- package/commands/gsd-t-pause.md +82 -82
- package/commands/gsd-t-plan.md +345 -344
- package/commands/gsd-t-populate.md +111 -111
- package/commands/gsd-t-prd.md +326 -326
- package/commands/gsd-t-project.md +211 -211
- package/commands/gsd-t-promote-debt.md +123 -123
- package/commands/gsd-t-prompt.md +137 -137
- package/commands/gsd-t-qa.md +266 -266
- package/commands/gsd-t-quick.md +357 -234
- package/commands/gsd-t-reflect.md +134 -134
- package/commands/gsd-t-resume.md +72 -72
- package/commands/gsd-t-scan.md +615 -615
- package/commands/gsd-t-setup.md +76 -0
- package/commands/gsd-t-status.md +192 -166
- package/commands/gsd-t-test-sync.md +381 -381
- package/commands/gsd-t-triage-and-merge.md +171 -171
- package/commands/gsd-t-verify.md +382 -382
- package/commands/gsd-t-visualize.md +118 -118
- package/commands/gsd-t-wave.md +401 -378
- package/docs/GSD-T-README.md +425 -422
- package/docs/architecture.md +385 -369
- package/docs/harness-design-analysis.md +371 -0
- package/docs/infrastructure.md +205 -205
- package/docs/prd-graph-engine.md +398 -398
- package/docs/prd-gsd2-hybrid.md +559 -559
- package/docs/prd-harness-evolution.md +583 -0
- package/docs/requirements.md +14 -0
- package/docs/workflows.md +226 -226
- package/examples/.gsd-t/domains/example-domain/scope.md +13 -13
- package/package.json +40 -40
- package/scripts/gsd-t-auto-route.js +39 -39
- package/scripts/gsd-t-dashboard-mockup.html +1143 -1143
- package/scripts/gsd-t-dashboard-server.js +171 -171
- package/scripts/gsd-t-dashboard.html +262 -262
- package/scripts/gsd-t-event-writer.js +128 -128
- package/scripts/gsd-t-statusline.js +94 -94
- package/scripts/gsd-t-tools.js +175 -175
- package/templates/CLAUDE-global.md +639 -614
- package/templates/CLAUDE-project.md +24 -0
- package/templates/backlog-settings.md +18 -18
- package/templates/backlog.md +1 -1
- package/templates/progress.md +40 -40
- package/templates/shared-services-contract.md +60 -60
- package/templates/stacks/desktop.ini +2 -2
- package/bin/desktop.ini +0 -2
- package/commands/desktop.ini +0 -2
- package/docs/ci-examples/desktop.ini +0 -2
- package/docs/desktop.ini +0 -2
- package/examples/.gsd-t/contracts/desktop.ini +0 -2
- package/examples/.gsd-t/desktop.ini +0 -2
- package/examples/.gsd-t/domains/desktop.ini +0 -2
- package/examples/.gsd-t/domains/example-domain/desktop.ini +0 -2
- package/examples/desktop.ini +0 -2
- package/examples/rules/desktop.ini +0 -2
- package/scripts/desktop.ini +0 -2
- package/templates/desktop.ini +0 -2
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* GSD-T Component Registry — Track and audit GSD-T enforcement components
|
|
5
|
+
*
|
|
6
|
+
* Manages the component registry (.gsd-t/component-registry.jsonl) and
|
|
7
|
+
* cost/benefit ledger (.gsd-t/metrics/component-impact.jsonl) for M31
|
|
8
|
+
* harness self-audit capability.
|
|
9
|
+
*
|
|
10
|
+
* Zero external dependencies (Node.js built-ins only).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const fs = require("fs");
|
|
14
|
+
const path = require("path");
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
getComponents, getComponent, registerComponent, updateStatus,
|
|
18
|
+
getFlaggedComponents, recordImpact, getImpactHistory, seedRegistry,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// ── getComponents ─────────────────────────────────────────────────────────────
|
|
22
|
+
|
|
23
|
+
/** @param {string} [projectDir] @returns {object[]} All registered components */
|
|
24
|
+
function getComponents(projectDir) {
|
|
25
|
+
return loadJsonl(registryPath(projectDir));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ── getComponent ──────────────────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
/** @param {string} id @param {string} [projectDir] @returns {object|null} */
|
|
31
|
+
function getComponent(id, projectDir) {
|
|
32
|
+
return getComponents(projectDir).find((c) => c.id === id) || null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ── registerComponent ─────────────────────────────────────────────────────────
|
|
36
|
+
|
|
37
|
+
/** @param {object} component @param {string} [projectDir] @returns {object} */
|
|
38
|
+
function registerComponent(component, projectDir) {
|
|
39
|
+
const fp = registryPath(projectDir);
|
|
40
|
+
const components = loadJsonl(fp);
|
|
41
|
+
if (components.find((c) => c.id === component.id)) {
|
|
42
|
+
throw new Error(`Component '${component.id}' already registered`);
|
|
43
|
+
}
|
|
44
|
+
const entry = { ...component, status: component.status || "active" };
|
|
45
|
+
ensureDir(path.dirname(fp));
|
|
46
|
+
fs.appendFileSync(fp, JSON.stringify(entry) + "\n");
|
|
47
|
+
return entry;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ── updateStatus ──────────────────────────────────────────────────────────────
|
|
51
|
+
|
|
52
|
+
/** @param {string} id @param {string} status @param {string} [projectDir] @returns {boolean} */
|
|
53
|
+
function updateStatus(id, status, projectDir) {
|
|
54
|
+
const fp = registryPath(projectDir);
|
|
55
|
+
const components = loadJsonl(fp);
|
|
56
|
+
const comp = components.find((c) => c.id === id);
|
|
57
|
+
if (!comp) return false;
|
|
58
|
+
comp.status = status;
|
|
59
|
+
atomicWriteJsonl(fp, components);
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ── getFlaggedComponents ──────────────────────────────────────────────────────
|
|
64
|
+
|
|
65
|
+
/** @param {string} [projectDir] @returns {object[]} Components with status 'flagged' */
|
|
66
|
+
function getFlaggedComponents(projectDir) {
|
|
67
|
+
return getComponents(projectDir).filter((c) => c.status === "flagged");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// ── recordImpact ──────────────────────────────────────────────────────────────
|
|
71
|
+
|
|
72
|
+
/** @param {string} componentId @param {string} milestoneId @param {object} impactData @param {string} [projectDir] @returns {object} */
|
|
73
|
+
function recordImpact(componentId, milestoneId, impactData, projectDir) {
|
|
74
|
+
const fp = impactPath(projectDir);
|
|
75
|
+
const history = loadJsonl(fp);
|
|
76
|
+
const consecutive = computeConsecutiveNegative(history, componentId, impactData.verdict);
|
|
77
|
+
const entry = {
|
|
78
|
+
ts: new Date().toISOString(),
|
|
79
|
+
milestone: milestoneId,
|
|
80
|
+
component_id: componentId,
|
|
81
|
+
token_cost: impactData.token_cost || 0,
|
|
82
|
+
bugs_prevented: impactData.bugs_prevented || 0,
|
|
83
|
+
false_positives: impactData.false_positives || 0,
|
|
84
|
+
context_pct: impactData.context_pct || 0,
|
|
85
|
+
verdict: impactData.verdict || "neutral",
|
|
86
|
+
consecutive_negative: consecutive,
|
|
87
|
+
};
|
|
88
|
+
ensureDir(path.dirname(fp));
|
|
89
|
+
fs.appendFileSync(fp, JSON.stringify(entry) + "\n");
|
|
90
|
+
if (consecutive >= 3) updateStatus(componentId, "flagged", projectDir);
|
|
91
|
+
return entry;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ── getImpactHistory ──────────────────────────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
/** @param {string} componentId @param {string} [projectDir] @returns {object[]} */
|
|
97
|
+
function getImpactHistory(componentId, projectDir) {
|
|
98
|
+
return loadJsonl(impactPath(projectDir)).filter((r) => r.component_id === componentId);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// ── seedRegistry ──────────────────────────────────────────────────────────────
|
|
102
|
+
|
|
103
|
+
/** Seed registry with all known GSD-T enforcement components. Skips existing. @param {string} [projectDir] */
|
|
104
|
+
function seedRegistry(projectDir) {
|
|
105
|
+
const seeds = buildSeeds();
|
|
106
|
+
const fp = registryPath(projectDir);
|
|
107
|
+
const existing = loadJsonl(fp);
|
|
108
|
+
const existingIds = new Set(existing.map((c) => c.id));
|
|
109
|
+
ensureDir(path.dirname(fp));
|
|
110
|
+
const toAdd = seeds.filter((s) => !existingIds.has(s.id));
|
|
111
|
+
for (const comp of toAdd) {
|
|
112
|
+
fs.appendFileSync(fp, JSON.stringify(comp) + "\n");
|
|
113
|
+
}
|
|
114
|
+
return toAdd;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ── Internal: seed data ───────────────────────────────────────────────────────
|
|
118
|
+
|
|
119
|
+
function buildSeeds() {
|
|
120
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
121
|
+
return [
|
|
122
|
+
{
|
|
123
|
+
id: "comp-red-team",
|
|
124
|
+
name: "Red Team Adversarial QA",
|
|
125
|
+
description: "Adversarial subagent that tries to break code after QA passes. Inverted incentive: more bugs found = more value.",
|
|
126
|
+
injection_points: ["gsd-t-execute", "gsd-t-integrate", "gsd-t-quick", "gsd-t-debug"],
|
|
127
|
+
token_cost_estimate: 8000,
|
|
128
|
+
date_added: today,
|
|
129
|
+
milestone_added: "M30",
|
|
130
|
+
category: "qa",
|
|
131
|
+
can_disable: true,
|
|
132
|
+
shadow_capable: true,
|
|
133
|
+
status: "active",
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
id: "comp-qa-agent",
|
|
137
|
+
name: "QA Agent",
|
|
138
|
+
description: "Test generation, execution, and gap reporting subagent. Never writes feature code.",
|
|
139
|
+
injection_points: ["gsd-t-execute", "gsd-t-integrate"],
|
|
140
|
+
token_cost_estimate: 5000,
|
|
141
|
+
date_added: today,
|
|
142
|
+
milestone_added: "M17",
|
|
143
|
+
category: "qa",
|
|
144
|
+
can_disable: true,
|
|
145
|
+
shadow_capable: true,
|
|
146
|
+
status: "active",
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
id: "comp-stack-rules",
|
|
150
|
+
name: "Stack Rules Engine",
|
|
151
|
+
description: "Auto-detects project tech stack and injects mandatory best-practice rules into subagent prompts.",
|
|
152
|
+
injection_points: ["gsd-t-execute", "gsd-t-quick", "gsd-t-integrate", "gsd-t-wave", "gsd-t-debug"],
|
|
153
|
+
token_cost_estimate: 2000,
|
|
154
|
+
date_added: today,
|
|
155
|
+
milestone_added: "M22",
|
|
156
|
+
category: "enforcement",
|
|
157
|
+
can_disable: false,
|
|
158
|
+
shadow_capable: false,
|
|
159
|
+
status: "active",
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
id: "comp-doc-ripple",
|
|
163
|
+
name: "Doc-Ripple",
|
|
164
|
+
description: "Automated document ripple — updates downstream docs after code changes by analyzing blast radius.",
|
|
165
|
+
injection_points: ["gsd-t-execute", "gsd-t-quick", "gsd-t-integrate"],
|
|
166
|
+
token_cost_estimate: 3000,
|
|
167
|
+
date_added: today,
|
|
168
|
+
milestone_added: "M28",
|
|
169
|
+
category: "documentation",
|
|
170
|
+
can_disable: true,
|
|
171
|
+
shadow_capable: true,
|
|
172
|
+
status: "active",
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
id: "comp-e2e-enforcement",
|
|
176
|
+
name: "E2E Enforcement",
|
|
177
|
+
description: "Mandates running full E2E suite when playwright.config.* or cypress.config.* exists. Blocks unit-only reporting.",
|
|
178
|
+
injection_points: ["gsd-t-execute", "gsd-t-test-sync", "gsd-t-verify", "gsd-t-quick", "gsd-t-wave"],
|
|
179
|
+
token_cost_estimate: 500,
|
|
180
|
+
date_added: today,
|
|
181
|
+
milestone_added: "M24",
|
|
182
|
+
category: "enforcement",
|
|
183
|
+
can_disable: false,
|
|
184
|
+
shadow_capable: false,
|
|
185
|
+
status: "active",
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
id: "comp-pre-commit-gate",
|
|
189
|
+
name: "Pre-Commit Gate",
|
|
190
|
+
description: "Mandatory checklist before every commit: contracts, docs, schema, requirements, architecture all updated.",
|
|
191
|
+
injection_points: ["gsd-t-execute", "gsd-t-quick", "gsd-t-integrate", "gsd-t-wave"],
|
|
192
|
+
token_cost_estimate: 1000,
|
|
193
|
+
date_added: today,
|
|
194
|
+
milestone_added: "M10",
|
|
195
|
+
category: "enforcement",
|
|
196
|
+
can_disable: false,
|
|
197
|
+
shadow_capable: false,
|
|
198
|
+
status: "active",
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
id: "comp-observability",
|
|
202
|
+
name: "Observability Logging",
|
|
203
|
+
description: "Token usage tracking and context utilization logging for every subagent spawn. Writes to token-log.md.",
|
|
204
|
+
injection_points: ["gsd-t-execute", "gsd-t-quick", "gsd-t-integrate", "gsd-t-wave", "gsd-t-debug"],
|
|
205
|
+
token_cost_estimate: 200,
|
|
206
|
+
date_added: today,
|
|
207
|
+
milestone_added: "M25",
|
|
208
|
+
category: "orchestration",
|
|
209
|
+
can_disable: false,
|
|
210
|
+
shadow_capable: false,
|
|
211
|
+
status: "active",
|
|
212
|
+
},
|
|
213
|
+
];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ── Internal: consecutive negative counter ────────────────────────────────────
|
|
217
|
+
|
|
218
|
+
function computeConsecutiveNegative(history, componentId, newVerdict) {
|
|
219
|
+
const prior = history.filter((r) => r.component_id === componentId);
|
|
220
|
+
if (newVerdict !== "negative") return 0;
|
|
221
|
+
let count = 1;
|
|
222
|
+
for (let i = prior.length - 1; i >= 0; i--) {
|
|
223
|
+
if (prior[i].verdict === "negative") count++;
|
|
224
|
+
else break;
|
|
225
|
+
}
|
|
226
|
+
return count;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
230
|
+
|
|
231
|
+
function registryPath(d) { return path.join(d || process.cwd(), ".gsd-t", "component-registry.jsonl"); }
|
|
232
|
+
function impactPath(d) { return path.join(d || process.cwd(), ".gsd-t", "metrics", "component-impact.jsonl"); }
|
|
233
|
+
|
|
234
|
+
function loadJsonl(fp) {
|
|
235
|
+
if (!fs.existsSync(fp)) return [];
|
|
236
|
+
const c = fs.readFileSync(fp, "utf8").trim();
|
|
237
|
+
return c ? c.split("\n").map(safeParse).filter(Boolean) : [];
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function safeParse(l) { try { return JSON.parse(l); } catch { return null; } }
|
|
241
|
+
|
|
242
|
+
function atomicWriteJsonl(fp, records) {
|
|
243
|
+
const dir = path.dirname(fp);
|
|
244
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
245
|
+
const tmp = fp + ".tmp." + process.pid;
|
|
246
|
+
fs.writeFileSync(tmp, records.map((r) => JSON.stringify(r)).join("\n") + "\n");
|
|
247
|
+
fs.renameSync(tmp, fp);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function ensureDir(d) { if (!fs.existsSync(d)) fs.mkdirSync(d, { recursive: true }); }
|