@tekyzinc/gsd-t 5.11.21 → 5.11.22
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/README.md +1 -1
- package/package.json +1 -1
- package/templates/workflows/gsd-t-scan.workflow.js +38 -0
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
|
+
## [5.11.22] - 2026-08-10
|
|
6
|
+
|
|
7
|
+
### Changed — the probe now slices vertically, by business capability
|
|
8
|
+
|
|
9
|
+
Two runs over the **same** codebase produced 47 slices and 34 slices with **zero
|
|
10
|
+
keys in common**. One cut by technical layer (`api-routes-billing`,
|
|
11
|
+
`lib-billing`, `schema-billing`, `pages-billing`); the other by feature
|
|
12
|
+
(`billing-invoicing-payments`). "Decompose by cohesive responsibility" is
|
|
13
|
+
satisfied by both readings, so the axis was free to flip between runs.
|
|
14
|
+
|
|
15
|
+
Two consequences, both bad:
|
|
16
|
+
|
|
17
|
+
- **Registers cannot be compared run to run.** Nothing corresponds.
|
|
18
|
+
- **The worst defects become invisible.** A cross-tenant access hole is a route
|
|
19
|
+
that never checks the caller's school before reaching the data layer. Cut by
|
|
20
|
+
layer, the route and the data access land in different slices and no single
|
|
21
|
+
agent sees both ends.
|
|
22
|
+
|
|
23
|
+
The axis is now pinned: one slice owns a whole feature — routes, logic, tables
|
|
24
|
+
and screens together. Genuinely cross-cutting concerns owned by no feature
|
|
25
|
+
(authentication, shared middleware, the build) may still be their own slice.
|
|
26
|
+
|
|
27
|
+
A prompt is advice, so a mechanical check backs it: slice keys prefixed with a
|
|
28
|
+
layer name are reported as **SLICING AXIS DRIFT**, naming what it costs. It
|
|
29
|
+
warns rather than halts — a horizontally-sliced scan still finds real defects.
|
|
30
|
+
|
|
31
|
+
**Not yet measured.** The reasoning is sound and the failure it targets is real,
|
|
32
|
+
but no run has proven vertical finds more than horizontal. Slices get larger
|
|
33
|
+
(~200 files rather than ~100 on a 6.9k-file repo), which is what produced
|
|
34
|
+
oversized-output failures earlier. Compare two registers before trusting it.
|
|
35
|
+
|
|
36
|
+
- `templates/workflows/gsd-t-scan.workflow.js`: the axis instruction + drift detector
|
|
37
|
+
- `test/m112-scan-schema-tolerance.test.js`: 5 tests, including the detector matched against the real keys from both runs
|
|
38
|
+
|
|
5
39
|
## [5.11.21] - 2026-08-10
|
|
6
40
|
|
|
7
41
|
### Added — a final sweep that re-runs slices the rush broke
|
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.22** - 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.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekyzinc/gsd-t",
|
|
3
|
-
"version": "5.11.
|
|
3
|
+
"version": "5.11.22",
|
|
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",
|
|
@@ -416,6 +416,24 @@ const probe = await agent(
|
|
|
416
416
|
``,
|
|
417
417
|
`Decompose HONESTLY by cohesive responsibility: not so coarse that an agent can't read its whole slice, not so fine that you emit one slice per file. A well-decomposed system has a finite, sensible number of real responsibilities — find them. (A volume-derived backstop cap is enforced after you return ONLY to catch over-slicing; a clean sub-domain decomposition lands under it. Report accurate \`totals\` — they set the backstop. If your count is truncated, you sliced too finely.)`,
|
|
418
418
|
``,
|
|
419
|
+
// The axis was unspecified, and both readings satisfy "cohesive": a technical
|
|
420
|
+
// layer is cohesive, and so is a business feature. Two runs over the SAME
|
|
421
|
+
// codebase (HiloAviation, 2026-08-10) produced 47 slices and 34 slices with
|
|
422
|
+
// ZERO keys in common — one cut by layer (api-routes-billing, lib-billing,
|
|
423
|
+
// schema-billing, pages-billing), the other by feature (billing-invoicing-
|
|
424
|
+
// payments). Two consequences, both bad:
|
|
425
|
+
//
|
|
426
|
+
// · Registers cannot be compared run to run. Nothing corresponds.
|
|
427
|
+
// · The worst defects become invisible. A cross-tenant access hole is a
|
|
428
|
+
// route that fails to check the caller's school before reaching the data
|
|
429
|
+
// layer — cut by layer, the route and the data access land in different
|
|
430
|
+
// slices and NO agent sees both ends.
|
|
431
|
+
//
|
|
432
|
+
// So the axis is pinned: vertical, by feature. Slices get larger (~200 files
|
|
433
|
+
// instead of ~100 on a 6.9k-file repo), which the backstop cap still bounds.
|
|
434
|
+
`SLICE VERTICALLY, BY BUSINESS CAPABILITY — never by technical layer. One slice owns a whole feature end to end: its routes, its business logic, its database tables and its screens together. Correct: "billing-invoicing-payments" (one slice covering all of billing). WRONG: "api-routes-billing" + "lib-billing" + "schema-billing" + "pages-billing" (the same feature split four ways). Do NOT prefix keys with a layer name (api-*, lib-*, schema-*, pages-*, components-*) — a layer prefix means you sliced the wrong way. The reason is not tidiness: the worst defects live in the seam BETWEEN layers (a route that never checks the caller's tenant before hitting the data layer), and an agent that owns only one layer cannot see both ends of that seam.`,
|
|
435
|
+
`The only slices that may be layer-shaped are genuinely cross-cutting concerns owned by no feature — authentication, the shared middleware, the build pipeline. If a slice belongs to a feature, it goes in that feature's slice.`,
|
|
436
|
+
``,
|
|
419
437
|
`Measure with real tooling and report in \`totals\`: files, loc, routes, tables, components, featureDomains (distinct business/feature areas). Read \`${projectDir}/package.json\` for the stack. Return JSON per the schema: totals + slices.`,
|
|
420
438
|
SHAPE_RULE,
|
|
421
439
|
].join("\n"),
|
|
@@ -426,6 +444,26 @@ if (!rawSlices.length) {
|
|
|
426
444
|
log("probe returned no slices — halting");
|
|
427
445
|
return { status: "failed", reason: "no-slices", probe };
|
|
428
446
|
}
|
|
447
|
+
// Did the probe slice the way it was told? A layer prefix is the tell.
|
|
448
|
+
//
|
|
449
|
+
// The instruction alone is not enough — a prompt is advice, and this axis flipped
|
|
450
|
+
// silently between two runs of the same codebase. Naming the drift out loud is
|
|
451
|
+
// what makes it visible; the run continues, because a horizontally-sliced scan
|
|
452
|
+
// still finds real defects, it just misses the cross-layer ones and cannot be
|
|
453
|
+
// compared to the last register.
|
|
454
|
+
const LAYER_PREFIX = /^(api|api-routes|routes|lib|libs|schema|schemas|db|pages|page|components?|ui|hooks?|utils?|services?|models?|controllers?|middleware|types?)[-_]/i;
|
|
455
|
+
const layerShaped = rawSlices.filter((sl) => LAYER_PREFIX.test(String(sl.key || "")));
|
|
456
|
+
if (layerShaped.length > 2) {
|
|
457
|
+
log(
|
|
458
|
+
`⚠ SLICING AXIS DRIFT — ${layerShaped.length} of ${rawSlices.length} slices are named after a technical layer ` +
|
|
459
|
+
`(${layerShaped.slice(0, 5).map((sl) => sl.key).join(", ")}${layerShaped.length > 5 ? ", …" : ""}). ` +
|
|
460
|
+
`Slices are meant to run VERTICALLY, one per business capability. Sliced by layer, a defect in the seam between ` +
|
|
461
|
+
`layers — a route that never checks the caller's tenant before reaching the data layer — is invisible, because no ` +
|
|
462
|
+
`single agent sees both ends. This register also cannot be compared to one from a vertically-sliced run: the ` +
|
|
463
|
+
`slices do not correspond.`
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
|
|
429
467
|
// Volume-derived cap as a runaway backstop (the probe over-slices without it).
|
|
430
468
|
const computedCap = computeSliceCap(probe.totals || {});
|
|
431
469
|
const sliceCap = maxSlicesOverride || computedCap;
|