@tekyzinc/gsd-t 4.14.10 → 4.16.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 +23 -0
- package/README.md +2 -1
- package/commands/gsd-t-estimate.md +100 -0
- package/commands/gsd-t-help.md +6 -0
- package/commands/gsd-t-scan.md +3 -3
- package/package.json +1 -1
- package/templates/CLAUDE-global.md +2 -2
- package/templates/playbooks/tekyz-estimation-and-prd-playbook.md +112 -0
- package/templates/workflows/gsd-t-scan.workflow.js +78 -13
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to GSD-T are documented here. Updated with each release.
|
|
4
4
|
|
|
5
|
+
## [4.16.10] - 2026-07-01
|
|
6
|
+
|
|
7
|
+
### Added — `/gsd-t-estimate`: Tekyz client estimate + PRD from a scan
|
|
8
|
+
|
|
9
|
+
New standalone command that turns a completed scan (`.gsd-t/techdebt.md`) into a Tekyz client estimate (a Google Sheet with a T-Shirt-Size tab + a Team-Mix cross-check) and a matching PRD deliverable. Encodes the 7-phase Tekyz playbook proven on the HILO Figma ATOS project (21 criticals → 32.73 eng-days → $13,090–$16,362).
|
|
10
|
+
|
|
11
|
+
- `commands/gsd-t-estimate.md` — the skill: scope + read register; client renumber to TD-1 (range-bounded, archives untouched, second pass for bare/chained refs); T-shirt sizing (XS.25/S.5/M1/L3/XL5/XXL7, FE+BE columns independent); familiarization bump for new teams (bump SIZE not MF, never cross the M→L 3× cliff); Google Sheet write via a throwaway service-account + JWT (gcloud's spreadsheets scope is Google-blocked); domain grouping + SUMIF-range widen; Team-Mix reconcile; PRD with FR↔TD crosswalk + estimate-not-quote disclaimer + §10-syncs-the-sheet; three-total verify.
|
|
12
|
+
- `templates/playbooks/tekyz-estimation-and-prd-playbook.md` — bundled reference (ships in the package so the skill works in a fresh install).
|
|
13
|
+
- `commands/gsd-t-help.md`, `templates/CLAUDE-global.md`, `README.md` — doc-ripple (help summary, successor mapping `scan → estimate`, commands table).
|
|
14
|
+
- `test/filesystem.test.js` — command count 45→46 / 51→52.
|
|
15
|
+
|
|
16
|
+
Note: this produces a paid CLIENT estimate — the "no cost estimates" rule governs GSD-T's own Max-funded build work, not client deliverables.
|
|
17
|
+
|
|
18
|
+
## [4.15.10] - 2026-06-30
|
|
19
|
+
|
|
20
|
+
### Added — scan builds the graph index when absent + repo-labeled `share/` export
|
|
21
|
+
|
|
22
|
+
Two scan improvements, both prompted by a real hilo-figma-atos scan that grep-fell-back and produced same-named docs across projects.
|
|
23
|
+
|
|
24
|
+
- **Scan auto-builds the graph index when absent** (`templates/workflows/gsd-t-scan.workflow.js`). The wired graph path was documented "build index if absent, then query" but the BUILD step was never wired — `GRAPH_BUILD_SCHEMA` was defined and unused. So on any project without a pre-built index (the common case), scan probed `graph status`, saw not-ok, and silently grep-fell-back — the graph was NEVER used. Observed on hilo-figma-atos (a 30M-token scan grep-fell-back purely because the index had never been built). Fix: the wired branch now runs `gsd-t graph index` (new `runCliBuild` helper), re-probes, and only falls back if the build itself fails. This is the headline value of the whole graph arc — scan now engages the graph on first run, not only when a human pre-built it.
|
|
25
|
+
- **Repo-labeled `share/` export + dated archive (#47)** (`templates/workflows/gsd-t-scan.workflow.js`, `commands/gsd-t-scan.md`). The LAST scan step COPIES the living docs + scan reports into `share/<file>-<repo>.md` (e.g. `share/architecture-hilo-figma-atos.md`) so files shared across projects are distinguishable. INTERNAL files keep their fixed names (`.gsd-t/techdebt.md`, `docs/architecture.md`) so all internal tooling (promote-debt, gap-analysis, complete-milestone, …) is untouched — zero blast radius. Prior scan outputs are archived to `.gsd-t/scan/archive/<name>-YYYYMMDD-HHMM.md` for diffing new-vs-prior.
|
|
26
|
+
- `test/m94-d6-scan-consumer.test.js`: regression tests for both (build-when-absent + re-probe; share/ export + fixed internal names + dated archive).
|
|
27
|
+
|
|
5
28
|
## [4.14.10] - 2026-06-30
|
|
6
29
|
|
|
7
30
|
### Added — M99: Graph Observability & Consolidation
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# GSD-T: Contract-Driven Development for Claude Code
|
|
2
2
|
|
|
3
|
-
**v4.
|
|
3
|
+
**v4.16.10** - 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.
|
|
@@ -186,6 +186,7 @@ This will replace changed command files, back up your CLAUDE.md if customized, a
|
|
|
186
186
|
| `/gsd-t-scan` | Deep codebase analysis → techdebt.md | Manual |
|
|
187
187
|
| `/gsd-t-gap-analysis` | Requirements gap analysis — spec vs. existing code | Manual |
|
|
188
188
|
| `/gsd-t-promote-debt` | Convert techdebt items to milestones | Manual |
|
|
189
|
+
| `/gsd-t-estimate` | Turn a scan into a Tekyz client estimate (Google Sheet: T-Shirt Size + Team Mix) + matching PRD | Manual |
|
|
189
190
|
| `/gsd-t-populate` | Auto-populate docs from existing codebase | Manual |
|
|
190
191
|
| `/gsd-t-design-decompose` | Decompose design into element/widget/page contracts | Manual |
|
|
191
192
|
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# GSD-T: Estimate — Tekyz Client Estimate + PRD from a Scan
|
|
2
|
+
|
|
3
|
+
You are turning a completed GSD-T tech-debt scan into a **Tekyz client estimate** (a Google Sheet with a T-Shirt-Size tab + a Team-Mix cross-check) and a matching **PRD deliverable**. `$ARGUMENTS` may carry a scope override (e.g. `--severity high`).
|
|
4
|
+
|
|
5
|
+
**Full proven procedure:** read `~/.claude/playbooks/tekyz-estimation-and-prd-playbook.md` if present, else the bundled copy `templates/playbooks/tekyz-estimation-and-prd-playbook.md` in the GSD-T package (7 phases, produced on the HILO Figma ATOS project: 21 criticals → 32.73 eng-days → $13,090–$16,362). Supporting memories (in the originating project's memory dir): `tekyz-estimation-method`, `tekyz-familiarization-bump`, `tekyz-client-prd-structure`, `tekyz-tech-debt-numbering-caution`, `google-sheets-service-account-workaround`. This skill ENCODES those; read them for edge-case depth.
|
|
6
|
+
|
|
7
|
+
> **Client-billed work, not GSD-T build work.** This produces a paid client estimate — the "no cost estimates" rule (`feedback_no_human_hour_estimates`) governs GSD-T's OWN Max-funded build work, NOT client deliverables. Dollar figures here are correct and expected.
|
|
8
|
+
|
|
9
|
+
## Step 0: Inputs + Scope
|
|
10
|
+
|
|
11
|
+
1. Read `.gsd-t/techdebt.md` (the register). If absent → "No scan register found. Run `/gsd-t-scan` first." and stop.
|
|
12
|
+
2. **Scope** (from `$ARGUMENTS`): default = **all CRITICAL findings** ("close the critical gap"). `--severity high` (or `medium`/`low`/`all`) widens it. Confirm the scope + finding count with the user before sizing.
|
|
13
|
+
3. Confirm you have (or ask the user for):
|
|
14
|
+
- A copy of the Tekyz estimate template Google Sheet (tabs: **Overview**, **T-Shirt Size Estimate**, **Team Mix**, **Technology Stack**) + its sheet ID.
|
|
15
|
+
- The GCP project id for the service-account write path (Phase 5).
|
|
16
|
+
4. Decide whether this is a **new-team project** (triggers the familiarization bump, Step 3.5) — usually YES for a fresh client.
|
|
17
|
+
|
|
18
|
+
## Step 1: Renumber for the client (if scan TDs start high)
|
|
19
|
+
|
|
20
|
+
GSD-T continues TD numbering across scans (never resets) — a fresh/crashed-and-rerun scan can start at e.g. TD-618, which looks bad to a client ("why does finding #1 start at 618?"). **For a new client project, renumber the deliverables to start at TD-1.** (`tekyz-tech-debt-numbering-caution`.)
|
|
21
|
+
|
|
22
|
+
Renumber SAFELY (numbering-only, zero value changes):
|
|
23
|
+
- **Confirm the register IDs are contiguous** (`min..max`, no gaps) first, so a blind offset (`subtract base−1`) aligns.
|
|
24
|
+
- **Range-bounded regex** — remap ONLY numbers in the register's actual range, so you never corrupt `DC-n`, another project's `TD-4`, or a different repo's numbering.
|
|
25
|
+
- **Scope to CURRENT deliverables only:** register, plain-English companion, `.gsd-t/scan/*.md`, `docs/*.md`, README, the PRD, `share/*`, and the Google Sheet labels. **Leave `.gsd-t/scan/archive/`, transcripts, heartbeats UNTOUCHED** (historical run numbering).
|
|
26
|
+
- **Second pass for non-`TD-` formats:** bare `| 618 |` table cells, slashed chains (`TD-2/623`, `626/629/631`), header text ("begins at TD-618"). A first-pass `TD-NNN` regex misses these.
|
|
27
|
+
- **Back up files before the bulk edit.**
|
|
28
|
+
- Offer this as an option; a client that wants the original numbering keeps it.
|
|
29
|
+
|
|
30
|
+
## Step 2: Size each finding (T-Shirt Size tab)
|
|
31
|
+
|
|
32
|
+
For each in-scope finding, build a row — cols **A** Module · **B** User Type · **C** Functionality (**include the `(TD-n)`**) · **D** Low-Level Requirement · **E** Phase (MVP) · **F** Web Portal (frontend) size · **G** Backend/API size. **Leave H–L (formulas) alone.**
|
|
33
|
+
|
|
34
|
+
- **Size each column INDEPENDENTLY** (FE and BE each get their own letter; blank = 0). Sizes: **XS 0.25 · S 0.5 · M 1 · L 3 · XL 5 · XXL 7** person-days.
|
|
35
|
+
- The sheet computes: `Days = F+G` · `MFactor Days = Days × Total MF` · `Total Days = Days + MFactor` · `LOW $ = Total × 8hrs × $50/hr` · `HIGH $ = LOW × High Factor (1.25)`. **Ignore the Phase column.**
|
|
36
|
+
- **Cluster by fix-shape to size fast:** "add existing auth guard to N routes" (XS–S, repeated pattern) vs "new backend surface" (M, +FE) vs "config / single route" (XS). Size the cluster once, apply to its members.
|
|
37
|
+
- **Tune the MF per project:** `Total MF` (default 0.7) = QA 0.3 + PM 0.1 + Analysis 0.05 + Deployment 0.05 + Buffer 0.2. Raise Buffer/QA when confidence is low; raise **High Factor** above 1.25 for more unknowns.
|
|
38
|
+
|
|
39
|
+
## Step 2.5: Familiarization bump (new-team projects only)
|
|
40
|
+
|
|
41
|
+
Base sizes assume *familiar* devs. For a team new to the codebase, add ramp by **bumping each item's SIZE in proportion to its complexity — NOT the MF** (the Analysis MF is for a Business Analyst, not dev ramp). (`tekyz-familiarization-bump`.)
|
|
42
|
+
|
|
43
|
+
- Trivial config / single-route → **no bump**. Repeated-pattern guards, few routes → **+0–1 tier**. High-volume sweeps + new-surface builds → **+1 tier**.
|
|
44
|
+
- **⚠️ The scale is NON-LINEAR. M→L is a 3× cliff (1 day → 3 days).** A blind one-tier bump across M→L doubles the total. **Never push an item across M→L unless it is genuinely multi-day.** Cap bumps at M for routine work.
|
|
45
|
+
- Optionally add a one-time **"Codebase Onboarding & Downstream Analysis"** Common line (sized L–XL) for initial ramp on a large repo — separate from per-task build. Document it as an optional line the client can remove.
|
|
46
|
+
- Reference calibration: HILO 21 criticals = $8,700 familiar → $11,730 new-team (+35%, bumps capped at M) → $13,090 incl Project Setup.
|
|
47
|
+
|
|
48
|
+
## Step 3: Group by domain + blue headings (T-Shirt tab)
|
|
49
|
+
|
|
50
|
+
Reorder items into domains (**A–G to match the PRD sections**). Insert a **blue section-heading row** before each group (merge A:L, white bold on blue). **No subtotals** (they complicate formulas).
|
|
51
|
+
|
|
52
|
+
- **After reordering, WIDEN the rollup SUMIF ranges** (e.g. `E19:En`). Writing cells does NOT auto-expand hardcoded ranges — only `insertDimension` shifts them. A missed widen silently under-counts the total.
|
|
53
|
+
|
|
54
|
+
## Step 4: Team Mix cross-check
|
|
55
|
+
|
|
56
|
+
`Count` = fractional headcount per role (e.g. Backend 0.75 = one BE dev at 75% over the window). `Days (E) = Month(D) × 20` · `Total Days = Days × Count`.
|
|
57
|
+
|
|
58
|
+
- **Solve `Month` (D5:D12)** so `sum(Count) × (Month×20) = the T-shirt total`. Sync the Resource (J) column.
|
|
59
|
+
- **Check for hardcoded cells** breaking the formula chain (restore `=E×B`, `=J` where a static number was pasted — the Testing row is a known offender).
|
|
60
|
+
- **Verify BOTH halves (F13, J13) equal the T-shirt total.**
|
|
61
|
+
|
|
62
|
+
## Step 5: Write to the Google Sheet (service-account path)
|
|
63
|
+
|
|
64
|
+
**gcloud's `spreadsheets` scope is blocked by Google** — use a throwaway service account (`google-sheets-service-account-workaround`):
|
|
65
|
+
|
|
66
|
+
1. Confirm Sheets API enabled: `gcloud services list --enabled --project=<proj> --filter="config.name:sheets.googleapis.com"` (else `gcloud services enable sheets.googleapis.com`).
|
|
67
|
+
2. Create a THROWAWAY SA (don't reuse a prod SA): `gcloud iam service-accounts create sheets-writer-tmp --project=<proj>`. **SA creation is eventually-consistent** — poll `describe` before minting the key.
|
|
68
|
+
3. Mint a key: `gcloud iam service-accounts keys create key.json --iam-account=sheets-writer-tmp@<proj>.iam.gserviceaccount.com`.
|
|
69
|
+
4. **PROMPT THE USER to share the sheet with the SA email as Editor** — the robot has no access until shared. (If the SA is deleted+recreated the identity changes → must re-share even if the email string is identical.)
|
|
70
|
+
5. Sign a JWT (RS256 via `openssl dgst -sha256 -sign key.pem`), scope `https://www.googleapis.com/auth/spreadsheets`, exchange at `oauth2.googleapis.com/token`, call Sheets v4 REST (`values.../PUT?valueInputOption=USER_ENTERED` for cells; `:batchUpdate` for inserts/formatting/merges). Pure Python stdlib + openssl, no libs. **URL-encode sheet ranges** (spaces in tab names break the URL). Token expires in 1h — regenerate.
|
|
71
|
+
6. **CLEANUP:** `gcloud iam service-accounts delete` the throwaway SA (removes its keys) + `rm` the local key — but leave the SA alive until the user confirms they're done editing, to avoid re-share churn.
|
|
72
|
+
|
|
73
|
+
## Step 6: Generate the PRD
|
|
74
|
+
|
|
75
|
+
**ONE document** (ATOS contractor-handoff template, sections 0–15) with **domain sub-sections (A–G) inside each numbered section** — not one PRD per item. (`tekyz-client-prd-structure`.)
|
|
76
|
+
|
|
77
|
+
- **§0 Metadata + top-of-doc ⚠️ Estimate Basis & Disclaimer** — planning estimates, NOT a quote/bid/fixed price; will change; no not-to-exceed; no delivery guarantee. **Purge all quote/fixed/guarantee/binding language.**
|
|
78
|
+
- **§3.0 FR↔TD crosswalk** — per-domain tables (Requirement · Finding · Fix). `FR-xN` (domain-sequenced requirement id) and `TD-n` (permanent scan finding id) do NOT run in parallel — always crosswalk them.
|
|
79
|
+
- **§3.1 FR tables** — a **dedicated Finding column** (never bury `TD-n` in trailing prose).
|
|
80
|
+
- **§3.2 NFR** — an **"Applies to" column listing EVERY `TD-n`** each cross-cutting NFR touches.
|
|
81
|
+
- **§4 enforcement, §8 API, §10 estimate** — explicit `TD-n` refs (not bare numbers).
|
|
82
|
+
- **§10 total MUST equal the live sheet rollup** — verify against the sheet's rollup cell, not memory. Watch that Project Setup carries its MF (M/M = 2 raw → 3.4 total, not 2.0). Point-in-time sync is fine; note it.
|
|
83
|
+
- **§15 sign-off = "Approved to proceed (scope, not fixed cost)".**
|
|
84
|
+
- Group tables **by domain with a bold header per group** (no repeating "Domain" column — reads as broken).
|
|
85
|
+
- **Save to `share/<Repo-Name>-PRD-*.md`** (repo-name prefix, matching `/gsd-t-scan`'s `share/` convention).
|
|
86
|
+
|
|
87
|
+
## Step 7: Verify + Deliver
|
|
88
|
+
|
|
89
|
+
**Reconcile the three totals — they MUST agree:** T-Shirt Size total = Team Mix total (F13/J13) = PRD §10 total. If any differ, find the break (usually a hardcoded cell or an un-widened SUMIF range) and fix before reporting done.
|
|
90
|
+
|
|
91
|
+
All client-facing files land in `share/` with the repo-name prefix. Report: scope + finding count, the eng-days + LOW–HIGH dollar range, the sheet URL, and the PRD path.
|
|
92
|
+
|
|
93
|
+
## Document Ripple
|
|
94
|
+
|
|
95
|
+
- `share/<Repo>-PRD-*.md` (new PRD deliverable) + the Google Sheet (external).
|
|
96
|
+
- If renumbering (Step 1) ran: the register + plain-English + `scan/*.md` + `docs/*` + README + `share/*` were remapped (archives untouched) — note it in the report so the numbering change is traceable.
|
|
97
|
+
|
|
98
|
+
## ▶ Next Up
|
|
99
|
+
|
|
100
|
+
Standalone command — no auto-successor. After delivering, the user shares the sheet + PRD with the client.
|
package/commands/gsd-t-help.md
CHANGED
|
@@ -358,6 +358,12 @@ Use these when user asks for help on a specific command:
|
|
|
358
358
|
- **Updates**: `.gsd-t/roadmap.md`, `.gsd-t/techdebt.md`
|
|
359
359
|
- **Use when**: Ready to address technical debt items
|
|
360
360
|
|
|
361
|
+
### estimate
|
|
362
|
+
- **Summary**: Turn a completed scan (`.gsd-t/techdebt.md`) into a Tekyz client estimate (Google Sheet: T-Shirt Size + Team Mix) and a matching PRD deliverable
|
|
363
|
+
- **Auto-invoked**: No
|
|
364
|
+
- **Updates**: the Tekyz estimate Google Sheet + `share/<Repo>-PRD-*.md` (and, if renumbered, the register/docs/scan files)
|
|
365
|
+
- **Use when**: A scan is done and you need a client-facing paid estimate + PRD (T-shirt sizing, dollar range, sign-off). Encodes the 7-phase Tekyz playbook (`~/.claude/playbooks/tekyz-estimation-and-prd-playbook.md`)
|
|
366
|
+
|
|
361
367
|
### populate
|
|
362
368
|
- **Summary**: Auto-populate all living docs from existing codebase analysis
|
|
363
369
|
- **Auto-invoked**: No
|
package/commands/gsd-t-scan.md
CHANGED
|
@@ -110,11 +110,11 @@ Present a summary: headline volume totals, findings by severity, the top critica
|
|
|
110
110
|
|
|
111
111
|
The scan Workflow updates ALL of these deterministically (no manual follow-on):
|
|
112
112
|
|
|
113
|
-
- `.gsd-t/techdebt.md` — fresh register (synthesis; prior
|
|
113
|
+
- `.gsd-t/techdebt.md` — fresh register (synthesis; **the prior register + all prior dimension files are archived with a datetime stamp to `.gsd-t/scan/archive/<name>-YYYYMMDD-HHMM.md`** so you can diff new-vs-prior — #47)
|
|
114
114
|
- `.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)
|
|
115
115
|
- `.gsd-t/scan/{architecture,security,quality,business-rules,contract-drift}.md` — dimension analysis files (document phase)
|
|
116
|
-
- `docs/architecture.md`, `docs/workflows.md`, `docs/infrastructure.md`, `docs/requirements.md`, `README.md` — living docs, **merged not overwritten** (document phase)
|
|
117
|
-
-
|
|
116
|
+
- `docs/architecture.md`, `docs/workflows.md`, `docs/infrastructure.md`, `docs/requirements.md`, `README.md` — living docs, **merged not overwritten** (document phase). These keep their fixed names (GSD-T reads them by hardcoded path).
|
|
117
|
+
- **`share/` — team-shareable, repo-name-labeled COPIES (#47):** the LAST scan step copies the living docs + scan reports into `share/` with the project's repo name suffixed (`share/architecture-<repo>.md`, `share/techdebt-<repo>.md`, …). Originals untouched. This solves "which file is for which project?" when sharing across repos — your team reads from `share/`. Regenerated each scan.
|
|
118
118
|
|
|
119
119
|
The document phase + render commit these via git on the feature branch (no push). The lead agent should still add a `.gsd-t/progress.md` Decision Log entry with the scan summary stats.
|
|
120
120
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekyzinc/gsd-t",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.16.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",
|
|
@@ -452,7 +452,7 @@ Add `**Also available:**` with `- /gsd-t-{alt} — {desc}` lines if alternatives
|
|
|
452
452
|
| `integrate` | `verify` | |
|
|
453
453
|
| `verify` | *(auto-invokes complete-milestone)* | |
|
|
454
454
|
| `complete-milestone` | `status` | |
|
|
455
|
-
| `scan` | `promote-debt` | `milestone` |
|
|
455
|
+
| `scan` | `promote-debt` | `milestone`, `estimate` (client estimate + PRD) |
|
|
456
456
|
| `init` | `scan` | `milestone` |
|
|
457
457
|
| `init-scan-setup` | `milestone` | |
|
|
458
458
|
| `gap-analysis` | `milestone` | `feature` |
|
|
@@ -460,7 +460,7 @@ Add `**Also available:**` with `- /gsd-t-{alt} — {desc}` lines if alternatives
|
|
|
460
460
|
| `setup` | `status` | |
|
|
461
461
|
| `design-decompose` | `design-build` | `partition` (if domains needed first) |
|
|
462
462
|
|
|
463
|
-
Commands with no successor (standalone): `quick`, `debug`, `brainstorm`, `status`, `help`, `resume`, `prompt`, `log`, `health`, `pause`, backlog commands.
|
|
463
|
+
Commands with no successor (standalone): `quick`, `debug`, `brainstorm`, `status`, `help`, `resume`, `prompt`, `log`, `health`, `pause`, `estimate`, backlog commands.
|
|
464
464
|
|
|
465
465
|
Skip the hint if auto-advancing (Level 3 mid-wave) — only show when the user needs to manually invoke the next step.
|
|
466
466
|
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Tekyz Estimation + PRD Playbook
|
|
2
|
+
|
|
3
|
+
> Reusable procedure for producing a Tekyz client estimate (Google Sheet: T-Shirt
|
|
4
|
+
> Size + Team Mix) and a matching PRD deliverable, from a GSD-T tech-debt scan.
|
|
5
|
+
> Proven on the HILO Figma ATOS project (21 criticals → 32.73 eng-days →
|
|
6
|
+
> $13,090–$16,362). Apply to E-Learning and any other GSD-T client project.
|
|
7
|
+
|
|
8
|
+
Related memory: `tekyz-estimation-method`, `tekyz-familiarization-bump`,
|
|
9
|
+
`tekyz-client-prd-structure`, `tekyz-tech-debt-numbering-caution`,
|
|
10
|
+
`google-sheets-service-account-workaround`.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Phase 0 — Inputs
|
|
15
|
+
|
|
16
|
+
1. A completed GSD-T scan (`.gsd-t/techdebt.md`) with findings by severity.
|
|
17
|
+
2. A copy of the Tekyz estimate template Google Sheet (tabs: **Overview**,
|
|
18
|
+
**T-Shirt Size Estimate**, **Team Mix**, **Technology Stack**).
|
|
19
|
+
3. The ATOS contractor-handoff PRD template (sections 0–15).
|
|
20
|
+
4. Decide the scope: usually **all CRITICAL findings** = "close the critical gap."
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Phase 1 — Renumber for the client (if scan numbers start high)
|
|
25
|
+
|
|
26
|
+
GSD-T continues TD numbering across scans; a fresh/crashed-and-rerun scan can start
|
|
27
|
+
at e.g. TD-618. **For a new client project, renumber to TD-1** before sharing.
|
|
28
|
+
|
|
29
|
+
- Verify the register IDs are contiguous (`min..max`, no gaps) → clean offset.
|
|
30
|
+
- Remap **only** numbers in the register's range (range-bounded regex) so you don't
|
|
31
|
+
touch `DC-n`, other projects' TDs, or another repo's numbering.
|
|
32
|
+
- Scope: register, plain-English, `scan/*.md`, `docs/*.md`, README, PRD, `share/*`,
|
|
33
|
+
and the Google Sheet labels. **Leave archives / transcripts / heartbeats alone.**
|
|
34
|
+
- Second pass for non-`TD-` formats: bare `| 618 |`, chains `TD-2/623`, header text.
|
|
35
|
+
- Back up files first.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Phase 2 — Size each finding (T-Shirt tab)
|
|
40
|
+
|
|
41
|
+
For each finding, write a row (cols A–G; leave H–L formulas alone):
|
|
42
|
+
`A` Module · `B` User Type · `C` Functionality (include the `(TD-n)`) ·
|
|
43
|
+
`D` Low-Level Requirement · `E` Phase (MVP) · `F` Web Portal size · `G` Backend/API size.
|
|
44
|
+
|
|
45
|
+
- Size **each column independently** (FE and BE). Sizes: XS .25, S .5, M 1, L 3, XL 5, XXL 7.
|
|
46
|
+
- Sheet computes: `Days = F+G`, `MFactor = Days×MF`, `Total = Days+MFactor`,
|
|
47
|
+
`LOW$ = Total×8×$50`, `HIGH$ = LOW$×1.25`.
|
|
48
|
+
- **Cluster the work** to size fast: "add existing auth guard to routes" (XS–S,
|
|
49
|
+
repeated pattern) vs "new backend surface" (M, +FE) vs "config/1-route" (XS).
|
|
50
|
+
|
|
51
|
+
### Familiarization bump (new-team projects)
|
|
52
|
+
Base sizes assume *familiar* devs. For a new team, bump SIZE in proportion to
|
|
53
|
+
complexity (NOT the MF — Analysis MF is for a Business Analyst):
|
|
54
|
+
- Trivial → no bump. Repeated-pattern guards → +0-1 tier. High-volume sweeps +
|
|
55
|
+
new-surface → +1 tier. **Never cross the M→L cliff (3×) unless genuinely multi-day.**
|
|
56
|
+
- Optionally add a one-time "Codebase Onboarding & Downstream Analysis" Common line (L–XL).
|
|
57
|
+
|
|
58
|
+
### Tune the MF (per project)
|
|
59
|
+
`Total MF` = QA + PM + Analysis + Deployment + Buffer (default 0.7). Raise Buffer/QA
|
|
60
|
+
when confidence is low; raise **High Factor** above 1.25 for more unknowns.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Phase 3 — Group by domain + blue headings (T-Shirt tab)
|
|
65
|
+
|
|
66
|
+
Reorder items into domains (A–G to match the PRD). Insert a **blue section-heading
|
|
67
|
+
row** before each group (merge A:L, white bold on blue). No subtotals (they complicate
|
|
68
|
+
formulas). After reordering: **widen the rollup SUMIF ranges** (`E19:En`) — writing
|
|
69
|
+
cells does NOT auto-expand hardcoded ranges; only `insertDimension` shifts them.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Phase 4 — Team Mix cross-check
|
|
74
|
+
|
|
75
|
+
`Count` = fractional headcount per role (fixed team shape). Solve `Month (D)` so
|
|
76
|
+
`sum(Count) × (Month×20) = T-shirt total`. Write `Month` to D5:D12; sync the Resource
|
|
77
|
+
(J) column. **Check for hardcoded cells** that break the formula chain (restore `=E×B`,
|
|
78
|
+
`=J`). Verify both halves (F13, J13) equal the T-shirt total.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Phase 5 — Writing to the Google Sheet (auth)
|
|
83
|
+
|
|
84
|
+
gcloud's `spreadsheets` scope is **blocked by Google**. Use a **throwaway service
|
|
85
|
+
account** (see `google-sheets-service-account-workaround` memory): create SA → mint
|
|
86
|
+
key → user shares sheet with SA email as Editor → JWT (RS256 via openssl) → token →
|
|
87
|
+
Sheets v4 REST (`values PUT` / `:batchUpdate`). Clean up the SA + key when done.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Phase 6 — The PRD deliverable
|
|
92
|
+
|
|
93
|
+
One document, **domain sub-sections (A–G) inside each numbered section** (0–15).
|
|
94
|
+
|
|
95
|
+
- **§0 Metadata** + top-of-doc **⚠️ Estimate Basis & Disclaimer** (estimates, not a
|
|
96
|
+
quote; will change; no not-to-exceed / guarantee). Purge quote/fixed/binding language.
|
|
97
|
+
- **§3.0 FR↔TD crosswalk** (per-domain tables: Requirement · Finding · Fix).
|
|
98
|
+
- **§3.1 FR tables** — dedicated **Finding** column (never bury TD in prose).
|
|
99
|
+
- **§3.2 NFR** — **Applies to** column listing **every** TD each cross-cutting NFR touches.
|
|
100
|
+
- **§4 enforcement, §8 API, §10 estimate** — explicit `TD-n` refs (not bare numbers).
|
|
101
|
+
- **§10 total must equal the live sheet rollup** (verify against the cell; watch that
|
|
102
|
+
Project Setup carries its MF). Point-in-time sync is fine; note it.
|
|
103
|
+
- **§15 sign-off** = "Approved to proceed (scope, not fixed cost)".
|
|
104
|
+
- Group tables by domain with a bold header per group (no repeating "Domain" column).
|
|
105
|
+
- Save to `share/<Repo-Name>-PRD-*.md` (repo-name-prefixed).
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Phase 7 — Deliver
|
|
110
|
+
|
|
111
|
+
All client-facing files in `share/` with the repo-name prefix. Confirm the three
|
|
112
|
+
estimate views agree: T-Shirt total = Team Mix total = PRD §10 total.
|
|
@@ -88,6 +88,7 @@ const PREFLIGHT_SCHEMA = {
|
|
|
88
88
|
properties: {
|
|
89
89
|
ok: { type: "boolean" },
|
|
90
90
|
branch: { type: "string" },
|
|
91
|
+
repoName: { type: "string", description: "the project directory's basename (e.g. 'hilo-figma-atos') — used to suffix shared scan/doc files" },
|
|
91
92
|
priorRegisterExists: { type: "boolean" },
|
|
92
93
|
priorMaxTd: { type: "integer", description: "highest TD-NNN in the prior register, 0 if none" },
|
|
93
94
|
notes: { type: "string" },
|
|
@@ -287,6 +288,29 @@ async function runCli(verb, target, label) {
|
|
|
287
288
|
return r || { ok: false, reason: "graph-unavailable", via: "error" };
|
|
288
289
|
}
|
|
289
290
|
|
|
291
|
+
// Build the graph index (`gsd-t graph index`) when it is absent. The wired path
|
|
292
|
+
// is documented "build index if absent, then query" but the BUILD step was never
|
|
293
|
+
// wired — so on any project without a pre-built index (the common case), scan
|
|
294
|
+
// silently grep-fell-back and the graph was NEVER used (observed on hilo-figma-atos
|
|
295
|
+
// 2026-06-30: a 30M-token scan grep-fell-back because the index was never built).
|
|
296
|
+
// `graph index` is a longer command than the verb queries → bigger timeout.
|
|
297
|
+
// [RULE] scan-builds-index-when-absent
|
|
298
|
+
async function runCliBuild() {
|
|
299
|
+
const prompt = [
|
|
300
|
+
`Build the GSD-T code-graph index for the project at \`${projectDir}\`, then report. Steps:`,
|
|
301
|
+
`1. If \`${projectDir}/bin/gsd-t.js\` exists, run: \`node ${projectDir}/bin/gsd-t.js graph index\` (via="local"). Otherwise run: \`gsd-t graph index\` (via="global"). Use cwd \`${projectDir}\`. This may take up to a few minutes on a large repo — wait for it to finish. Do NOT redirect stderr.`,
|
|
302
|
+
`2. Set ok=true if the command exits 0 (the index built). Set ok=false with a short reason + first ~200 chars of stderr otherwise.`,
|
|
303
|
+
`Do NOT do any other work. ONLY run this one build command and report the structured result.`,
|
|
304
|
+
].join("\n");
|
|
305
|
+
const r = await agent(prompt, {
|
|
306
|
+
label: "graph:index-build",
|
|
307
|
+
phase: "Graph-Wiring",
|
|
308
|
+
model: "haiku",
|
|
309
|
+
schema: GRAPH_BUILD_SCHEMA,
|
|
310
|
+
}).catch((e) => ({ ok: false, reason: `agent-error: ${e && e.message}` }));
|
|
311
|
+
return r || { ok: false, reason: "build-failed" };
|
|
312
|
+
}
|
|
313
|
+
|
|
290
314
|
// M99 D2: persist a kind:'wiring' ledger line for this workflow.
|
|
291
315
|
// M81 sandbox: all I/O through agent() Bash; no require/fs in the sandbox.
|
|
292
316
|
// Uses the `gsd-t graph wiring-log` CLI shim (avoids embedding require() in strings).
|
|
@@ -312,8 +336,9 @@ const pre = await agent(
|
|
|
312
336
|
`You are the preflight check for a GSD-T deep scan of the project at \`${projectDir}\`.`,
|
|
313
337
|
`Using Bash/Read tools, determine:`,
|
|
314
338
|
`1. The current git branch (\`git -C ${projectDir} rev-parse --abbrev-ref HEAD\`; if not a git repo, report branch "(no-git)").`,
|
|
315
|
-
`2.
|
|
316
|
-
`3.
|
|
339
|
+
`2. The repo name = the basename of the resolved project dir (\`basename "$(cd ${projectDir} && pwd)"\`) — e.g. "hilo-figma-atos". Report as repoName (used to label the team-shared share/ copies).`,
|
|
340
|
+
`3. Whether \`${projectDir}/.gsd-t/techdebt.md\` exists (priorRegisterExists).`,
|
|
341
|
+
`4. If it exists, the HIGHEST TD-NNN number in it (grep \`### TD-\`, parse the max integer; priorMaxTd). If absent, priorMaxTd=0.`,
|
|
317
342
|
`Set ok=true unless something makes scanning impossible (e.g. projectDir does not exist). Return JSON per the schema.`,
|
|
318
343
|
].join("\n"),
|
|
319
344
|
{ label: "preflight", phase: "Preflight", schema: PREFLIGHT_SCHEMA, model: "haiku" }
|
|
@@ -323,7 +348,12 @@ if (!pre || !pre.ok) {
|
|
|
323
348
|
return { status: "failed", reason: "preflight-failed", preflight: pre };
|
|
324
349
|
}
|
|
325
350
|
const tdStart = (pre.priorRegisterExists ? (pre.priorMaxTd || 0) : 0) + 1;
|
|
326
|
-
|
|
351
|
+
// #47: repo-name suffix for the TEAM-SHARED copies only. INTERNAL files keep their
|
|
352
|
+
// fixed names (.gsd-t/techdebt.md, .gsd-t/scan/<dim>.md, docs/*.md) so all internal
|
|
353
|
+
// tooling (promote-debt, gap-analysis, complete-milestone, …) keeps working — zero
|
|
354
|
+
// blast radius. The repo suffix appears ONLY on the share/ exports at the end.
|
|
355
|
+
const repoName = (pre.repoName && /^[A-Za-z0-9._-]+$/.test(pre.repoName)) ? pre.repoName : "project";
|
|
356
|
+
log(`preflight ok — branch=${pre.branch}, repo=${repoName}, priorRegister=${pre.priorRegisterExists}, TD numbering starts at TD-${tdStart}`);
|
|
327
357
|
|
|
328
358
|
// Volume probe — an agent measures the codebase (its own Bash) and carves slices.
|
|
329
359
|
phase("Probe");
|
|
@@ -376,12 +406,26 @@ if (graphMode === "disabled") {
|
|
|
376
406
|
} else {
|
|
377
407
|
// graphMode === "wired": build index if absent, then query structural slice.
|
|
378
408
|
// Step 1: check if index exists and is queryable.
|
|
379
|
-
|
|
409
|
+
let statusResult = await runCli("status", null, "status");
|
|
410
|
+
// Step 1b: if the index is absent/unqueryable, BUILD it once, then re-probe.
|
|
411
|
+
// This is the previously-missing build step — without it scan grep-fell-back on
|
|
412
|
+
// every project lacking a pre-built index (hilo-figma-atos 2026-06-30).
|
|
413
|
+
// [RULE] scan-builds-index-when-absent
|
|
380
414
|
if (!statusResult || !statusResult.ok) {
|
|
381
|
-
|
|
382
|
-
|
|
415
|
+
log(`graph-wiring: index not queryable (${(statusResult && statusResult.reason) || "graph-unavailable"}) — building it now (gsd-t graph index)...`);
|
|
416
|
+
const buildResult = await runCliBuild();
|
|
417
|
+
if (buildResult && buildResult.ok) {
|
|
418
|
+
log(`graph-wiring: index build OK — re-probing status.`);
|
|
419
|
+
statusResult = await runCli("status", null, "status");
|
|
420
|
+
} else {
|
|
421
|
+
log(`graph-wiring: index build FAILED [${(buildResult && buildResult.reason) || "build-failed"}] — falling back to grep-mode.`);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
if (!statusResult || !statusResult.ok) {
|
|
425
|
+
// Graph still unavailable after a build attempt — announce fallback, continue
|
|
426
|
+
// with intact grep-mode scan. [RULE] parser-fail-disables-loud-never-silent
|
|
383
427
|
graphWiringMode = "fallback-announced";
|
|
384
|
-
log(`⚠ GRAPH-FALLBACK (ANNOUNCED): graph
|
|
428
|
+
log(`⚠ GRAPH-FALLBACK (ANNOUNCED): graph unavailable after build attempt [reason=${(statusResult && statusResult.reason) || "graph-unavailable"}, via=${(statusResult && statusResult.via) || "?"}] — scan continues in full grep-mode (today's architecture, intact). Structural findings from LLM reconstruction only.`);
|
|
385
429
|
await persistWiringMode("fallback-announced"); // M99 D2 [RULE] wiring-mode-three-states
|
|
386
430
|
} else {
|
|
387
431
|
// Step 2: query the structural slice (dead-code + dangling + clusters).
|
|
@@ -799,10 +843,15 @@ const today = (typeof todayAgent === "string" && /\d{4}-\d{2}-\d{2}/.test(todayA
|
|
|
799
843
|
|
|
800
844
|
let archivePath = "";
|
|
801
845
|
if (pre.priorRegisterExists) {
|
|
846
|
+
// #47: archive the prior register + ALL prior dimension files into
|
|
847
|
+
// .gsd-t/scan/archive/ with a DATETIME stamp so the user can diff new-vs-prior.
|
|
848
|
+
// Handles BOTH the new suffixed names and any legacy unsuffixed leftovers.
|
|
802
849
|
const arch = await agent(
|
|
803
850
|
[
|
|
804
|
-
`Archive the existing
|
|
805
|
-
`
|
|
851
|
+
`Archive the existing scan outputs in \`${projectDir}\` into a dated archive folder so the user can diff new-vs-prior, then report the archive dir. Steps (via Bash):`,
|
|
852
|
+
`1. STAMP="$(date +%Y%m%d-%H%M)". ARCH="${projectDir}/.gsd-t/scan/archive". mkdir -p "$ARCH".`,
|
|
853
|
+
`2. Move each existing scan output into "$ARCH" with the STAMP appended before .md. For EACH that exists, move it: \`${projectDir}/.gsd-t/techdebt.md\`, \`${projectDir}/.gsd-t/techdebt_in_plain_english.md\`, and \`${projectDir}/.gsd-t/scan/<dim>.md\` for each dim in {architecture,security,quality,business-rules,contract-drift}. Target name: same basename + "-$STAMP.md" (e.g. techdebt-20260630-1542.md). Use \`git mv\` if a git repo else \`mv\`. Skip any that don't exist (no error).`,
|
|
854
|
+
`3. Reply with ONLY the archive dir path "$ARCH".`,
|
|
806
855
|
].join("\n"),
|
|
807
856
|
{ label: "synthesis:archive", phase: "Synthesis", model: "haiku" }
|
|
808
857
|
).catch(() => null);
|
|
@@ -815,7 +864,7 @@ const { chunks, lastTd } = fmtChunks(today);
|
|
|
815
864
|
// each subsequent chunk is APPENDED. Done SEQUENTIALLY so the file builds in order and
|
|
816
865
|
// each agent's prompt+output stays small enough to pass intact. The register path is
|
|
817
866
|
// passed to each chunk; only the chunk content varies.
|
|
818
|
-
const regPath = `${projectDir}/.gsd-t/techdebt.md`;
|
|
867
|
+
const regPath = `${projectDir}/.gsd-t/techdebt.md`; // internal fixed name (shared copy suffixed in share/)
|
|
819
868
|
let chunkOk = 0;
|
|
820
869
|
for (let ci = 0; ci < chunks.length; ci++) {
|
|
821
870
|
const isFirst = ci === 0;
|
|
@@ -933,7 +982,7 @@ log(`document phase: ${docsOk.length}/${docTargets.length} written/merged${docsF
|
|
|
933
982
|
// out bounded generator agents (each writes its batch's entries via the shared gate),
|
|
934
983
|
// then ASSEMBLE deterministically with severity section headers, and chunk-write.
|
|
935
984
|
phase("Plain-English");
|
|
936
|
-
const peTarget = `${projectDir}/.gsd-t/techdebt_in_plain_english.md`;
|
|
985
|
+
const peTarget = `${projectDir}/.gsd-t/techdebt_in_plain_english.md`; // internal fixed name (shared copy suffixed in share/)
|
|
937
986
|
const sevLabel = { CRITICAL: "fix before launch", HIGH: "fix soon", MEDIUM: "schedule", LOW: "clean up eventually" };
|
|
938
987
|
// Attach the deterministic TD number (matches the register: severity-sorted, tdStart+).
|
|
939
988
|
const peItems = finalFindings.map((f, i) => ({
|
|
@@ -1023,11 +1072,27 @@ const peComplete = peActual === peExpectedEntries;
|
|
|
1023
1072
|
if (!peComplete) log(`⚠ plain-english INCOMPLETE: wrote ${peActual}/${peExpectedEntries} entries (writer said ${typeof peWriteRes === "string" ? peWriteRes.trim().slice(0, 20) : JSON.stringify(peWriteRes).slice(0, 40)})`);
|
|
1024
1073
|
log(`plain-english: ${peExpectedEntries}/${peItems.length} entries, grouped by severity, ${peChunks.length} chunks, on-disk count ${peActual ?? "?"} (${peComplete ? "COMPLETE" : "INCOMPLETE"})${peFailed ? `; ${peFailed} gen batch(es) failed` : ""}`);
|
|
1025
1074
|
|
|
1026
|
-
//
|
|
1075
|
+
// #47: EXPORT-COPY the living docs into a share/ folder with the repo-name suffix —
|
|
1076
|
+
// the LAST scan step. Originals stay at their fixed docs/ names (GSD-T reads them by
|
|
1077
|
+
// hardcoded path under the No-Re-Research rule); the share/ copies are the team-shareable,
|
|
1078
|
+
// project-labeled set. Regenerated each scan (overwrite). The scan reports themselves are
|
|
1079
|
+
// already suffixed in place (techdebt-<repo>.md, scan/<dim>-<repo>.md).
|
|
1080
|
+
const shareAgent = await agent(
|
|
1081
|
+
[
|
|
1082
|
+
`Create a shareable, repo-labeled copy of this project's living docs in \`${projectDir}\` via Bash. Steps:`,
|
|
1083
|
+
`1. \`mkdir -p ${projectDir}/share\`.`,
|
|
1084
|
+
`2. COPY (do NOT move — keep the original at its fixed name) each of these that EXISTS into \`${projectDir}/share/\` with the repo name "${repoName}" suffixed before .md. Living docs: \`docs/architecture.md\`→\`share/architecture-${repoName}.md\`, \`docs/requirements.md\`→\`share/requirements-${repoName}.md\`, \`docs/workflows.md\`→\`share/workflows-${repoName}.md\`, \`docs/infrastructure.md\`→\`share/infrastructure-${repoName}.md\`, \`README.md\`→\`share/README-${repoName}.md\`. Scan reports: \`.gsd-t/techdebt.md\`→\`share/techdebt-${repoName}.md\`, \`.gsd-t/techdebt_in_plain_english.md\`→\`share/techdebt_in_plain_english-${repoName}.md\`, and each \`.gsd-t/scan/<dim>.md\`→\`share/<dim>-${repoName}.md\` for dim in {architecture,security,quality,business-rules,contract-drift} (NOTE these scan dimension files share basenames with the living-doc architecture — keep them distinct: prefer \`share/scan-<dim>-${repoName}.md\` for the .gsd-t/scan/ ones to avoid colliding with docs/architecture). Overwrite existing share/ files (always fresh). Skip any source that doesn't exist (no error).`,
|
|
1085
|
+
`3. Reply with ONLY the count of files copied.`,
|
|
1086
|
+
].join("\n"),
|
|
1087
|
+
{ label: "share-export", phase: "Document", model: "haiku" }
|
|
1088
|
+
).catch(() => null);
|
|
1089
|
+
log(`share/ export: ${typeof shareAgent === "string" ? shareAgent.trim().slice(0, 40) : "done"} → ${projectDir}/share/`);
|
|
1090
|
+
|
|
1091
|
+
// Commit the docs + dimension files + plain-english + share/ via a small agent (Bash git).
|
|
1027
1092
|
const commitAgent = await agent(
|
|
1028
1093
|
[
|
|
1029
1094
|
`Commit the GSD-T scan's generated documents in \`${projectDir}\` via Bash git, IF it is a git repo (else report skipped).`,
|
|
1030
|
-
`Stage: \`.gsd-t/scan\`, \`.gsd-t/techdebt_in_plain_english.md\`, \`docs\`, \`README.md\` (do NOT stage \`.gsd-t/scan/.doc-backup\` if present). Commit message: "scan: deep document cross-population (${docsOk.length} docs) + dimension files". Do NOT push. Return JSON per the schema (status "rendered" if committed, "skipped" if not a git repo / nothing to commit, "failed" on error; outputPath optional).`,
|
|
1095
|
+
`Stage: \`.gsd-t/scan\`, \`.gsd-t/techdebt.md\`, \`.gsd-t/techdebt_in_plain_english.md\`, \`share\`, \`docs\`, \`README.md\` (do NOT stage \`.gsd-t/scan/.doc-backup\` if present; \`.gsd-t/scan/archive\` MAY be staged — the dated history is worth keeping). Commit message: "scan: deep document cross-population (${docsOk.length} docs) + dimension files + share/ export". Do NOT push. Return JSON per the schema (status "rendered" if committed, "skipped" if not a git repo / nothing to commit, "failed" on error; outputPath optional).`,
|
|
1031
1096
|
].join("\n"),
|
|
1032
1097
|
{ label: "commit-docs", phase: "Document", schema: RENDER_SCHEMA, model: "haiku" }
|
|
1033
1098
|
).catch((e) => ({ status: "failed", notes: String(e && e.message) }));
|