@tekyzinc/gsd-t 4.15.10 → 4.17.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 CHANGED
@@ -2,6 +2,42 @@
2
2
 
3
3
  All notable changes to GSD-T are documented here. Updated with each release.
4
4
 
5
+ ## [4.17.10] - 2026-07-01
6
+
7
+ ### Changed — `/gsd-t-estimate` v2: generalized + supervised + adversarial, with a permanent Sheets service account
8
+
9
+ Reshaped the estimator from scan-only to a general work-document pricer, made it human-in-the-loop, added an operator-arbitrated Estimate Red Team, and replaced the throwaway-per-run Google service account with a permanent reusable one.
10
+
11
+ - **Input generalized** — scan register OR new-feature/new-app requirements doc OR PRD-in; line-items become findings or requirements (Step 0 classifies + picks id vocabulary).
12
+ - **Numbering hygiene** — renumber only when numbering is absent / non-sequential / doesn't start at 1; preserve hierarchical numbering (`1`/`1.1`/`1.1.1`), never flatten.
13
+ - **Estimate Adjustments** (Step 2.5) broadened from familiarization-only to familiarization + R&D/unknown-approach/spike risk, documented per-item; M→L 3× cliff caution retained.
14
+ - **Parameterized** — rate / hoursPerDay / sizeScale / totalMF / highFactor / sheet template / GCP project via `$ARGUMENTS` or `.gsd-t/estimate-config.json`; defaults are Tekyz values, always named in the report (no silent default).
15
+ - **Human-in-the-loop** — judgment phases (sizing, adjustments, PRD, Red Team) pause for operator review; mechanical phases flow-but-show.
16
+ - **NEW Step 8 Estimate Red Team** — adversarial pass on under-sizing / missing line-items / optimistic multipliers / cross-check integrity; **operator is the final arbiter** (argue until concede or a definitive ruling; Red Team then grudgingly accepts and may document overridden objections to `share/<Repo>-estimate-redteam-notes.md`).
17
+ - **Sheet write: permanent reusable service account** — Step 0 asks for the sheet URL first + extracts the id; Step 5 reuses a permanent SA (`gsd-t-sheets-writer@ai-estimator-415612.iam.gserviceaccount.com`, key at `~/.claude/gsd-t-secrets/…`, chmod 600, outside any repo) instead of creating+deleting a throwaway each run. Recreation breaks existing sheet shares, so the SA is never deleted; each sheet is shared with it once.
18
+
19
+ - `commands/gsd-t-estimate.md`: full rewrite (generalization, HITL, Step 8 Red Team, Step 0 URL-first, Step 5 permanent SA, config table).
20
+ - `templates/estimate-config.json`: new optional documented override (installed to `~/.claude/templates/` via `SHARED_TEMPLATES`, not auto-scaffolded into projects).
21
+ - `bin/gsd-t.js`: `estimate-config.json` added to `SHARED_TEMPLATES`.
22
+ - `templates/playbooks/tekyz-estimation-and-prd-playbook.md`: header + Phase 5 updated to match.
23
+ - `commands/gsd-t-help.md`, `README.md`, `GSD-T-README.md`: description + version-history ripple.
24
+ - `.gsd-t/contracts/graph-metrics-contract.md`: `doMetrics` line citation 4742→4743 (shifted by the `SHARED_TEMPLATES` edit; keeps the M99 T6 line-ref test green).
25
+
26
+ Also captured two HIGH-priority framework-default backlog items (#47 universal build-number rule, #48 universal trace + audit logging) — promote-later; no code yet.
27
+
28
+ ## [4.16.10] - 2026-07-01
29
+
30
+ ### Added — `/gsd-t-estimate`: Tekyz client estimate + PRD from a scan
31
+
32
+ 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).
33
+
34
+ - `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.
35
+ - `templates/playbooks/tekyz-estimation-and-prd-playbook.md` — bundled reference (ships in the package so the skill works in a fresh install).
36
+ - `commands/gsd-t-help.md`, `templates/CLAUDE-global.md`, `README.md` — doc-ripple (help summary, successor mapping `scan → estimate`, commands table).
37
+ - `test/filesystem.test.js` — command count 45→46 / 51→52.
38
+
39
+ Note: this produces a paid CLIENT estimate — the "no cost estimates" rule governs GSD-T's own Max-funded build work, not client deliverables.
40
+
5
41
  ## [4.15.10] - 2026-06-30
6
42
 
7
43
  ### Added — scan builds the graph index when absent + repo-labeled `share/` export
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # GSD-T: Contract-Driven Development for Claude Code
2
2
 
3
- **v4.15.10** - A methodology for reliable, parallelizable development using Claude Code with optional Agent Teams support.
3
+ **v4.17.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 any work doc (scan, requirements, feature/app spec) into a Tekyz client estimate (Google Sheet: T-Shirt Size + Team Mix) + matching PRD — supervised, with an operator-arbitrated Estimate Red Team | 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
 
package/bin/gsd-t.js CHANGED
@@ -1708,6 +1708,7 @@ const SHARED_TEMPLATES = [
1708
1708
  "page-contract.md",
1709
1709
  "design-contract.md",
1710
1710
  "shared-services-contract.md",
1711
+ "estimate-config.json",
1711
1712
  ];
1712
1713
 
1713
1714
  function installSharedTemplates() {
@@ -0,0 +1,189 @@
1
+ # GSD-T: Estimate — Tekyz Client Estimate + PRD from any Work Document
2
+
3
+ You are turning a **structured work document** into a **Tekyz client estimate** (a Google Sheet with a T-Shirt-Size tab + a Team-Mix cross-check) and a matching **PRD deliverable**. The input can be a GSD-T tech-debt scan register, a **new-feature requirements doc**, a **new-application requirements doc**, an existing PRD, or any comparable spec. `$ARGUMENTS` may carry the input path + a scope override (e.g. `--severity high`, `--input docs/requirements.md`).
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 (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
+ ## Human-in-the-Loop (MANDATORY — this command is SUPERVISED, not auto)
10
+
11
+ This process is judgment-heavy. **You (the operator) are the final arbiter of every estimate.** The command does NOT run end-to-end autonomously.
12
+
13
+ - **Judgment phases PAUSE for review** before advancing: **Step 2 (sizing)**, **Step 2.5 (adjustments)**, **Step 6 (PRD)**, **Step 8 (Red Team)**. Present the output, wait for the user's `continue` or corrections.
14
+ - **Mechanical phases FLOW but SHOW their result**: Step 1 (numbering), Step 5 (sheet write), Step 7 (reconcile). Don't block on these, but display what happened so nothing is invisible.
15
+ - **Escape hatch:** if the user says e.g. "run through sizing and grouping, then stop," batch those phases and pause where they asked.
16
+
17
+ ## Configuration (parameterized — defaults are Tekyz values)
18
+
19
+ Read these from `$ARGUMENTS` or `.gsd-t/estimate-config.json` if present; otherwise use the Tekyz defaults. **Always name the active values in the report** (no silent defaults). This config is **optional and NOT auto-created** (it's Tekyz-estimate-specific, not every-project state) — to override the defaults, copy the documented template `templates/estimate-config.json` (in the GSD-T package, or `~/.claude/templates/estimate-config.json`) to `.gsd-t/estimate-config.json` and edit. Every field is individually optional; an omitted field falls back to its Tekyz default.
20
+
21
+ | Param | Default (Tekyz) | Meaning |
22
+ |-------|-----------------|---------|
23
+ | `rate` | `$50/hr` | Blended hourly rate for the LOW figure. |
24
+ | `hoursPerDay` | `8` | Hours per person-day. |
25
+ | `sizeScale` | `XS 0.25 · S 0.5 · M 1 · L 3 · XL 5 · XXL 7` | T-shirt → person-days. |
26
+ | `totalMF` | `0.7` | Overhead multiplier = QA 0.3 + PM 0.1 + Analysis 0.05 + Deployment 0.05 + Buffer 0.2. |
27
+ | `highFactor` | `1.25` | HIGH = LOW × this. |
28
+ | `sheetTemplateId` | (blank) | Optional template to clone; normally blank — operator pastes the target sheet URL at Step 0. |
29
+ | `gcpProject` | `ai-estimator-415612` | GCP project hosting the permanent Sheets-writer SA. |
30
+ | `serviceAccountEmail` | `gsd-t-sheets-writer@ai-estimator-415612.iam.gserviceaccount.com` | **Permanent** SA — share each sheet with this as Editor. |
31
+ | `serviceAccountKeyPath` | `~/.claude/gsd-t-secrets/gsd-t-sheets-writer-key.json` | SA key (chmod 600, outside any repo). |
32
+
33
+ ## Step 0: Inputs + Scope + Sheet
34
+
35
+ 1. **ASK FOR THE GOOGLE SHEET URL FIRST.** The operator ALWAYS provides an existing sheet to edit — this command never creates the sheet. Prompt: *"Paste the Google Sheet URL for this estimate."* Extract the **sheet ID** = the segment between `/d/` and the next `/` in `https://docs.google.com/spreadsheets/d/<ID>/edit`. Confirm the ID back to the operator.
36
+ 2. **Ensure the sheet is shared with the permanent estimate service account** (details in Step 5). The reusable SA email is **`gsd-t-sheets-writer@ai-estimator-415612.iam.gserviceaccount.com`**. Do a quick read-probe (Step 5's JWT→token→`GET spreadsheets/<id>`): if it returns `403`, the sheet isn't shared yet → prompt the operator to share it with that email as **Editor** ("Notify people" unchecked), wait for confirmation, re-probe. If the SA/key doesn't exist yet, Step 5 provisions it once.
37
+ 3. **Resolve the input document** (from `$ARGUMENTS --input`, else default to `.gsd-t/techdebt.md`). If none found → "No input document found. Pass `--input <path>` or run `/gsd-t-scan` first." and stop.
38
+ 4. **Classify the input** so the parser + line-item vocabulary match:
39
+ - **Scan register** (`.gsd-t/techdebt.md`) → line-items are *findings* (`TD-n`), scoped by severity.
40
+ - **Requirements doc / feature spec / app spec / PRD-in** → line-items are *requirements* (`FR-n` or the doc's own numbering).
41
+ 5. **Scope** (from `$ARGUMENTS`): scan default = **all CRITICAL findings** ("close the critical gap"); `--severity high|medium|low|all` widens it. Requirements default = **all requirements** unless the user narrows. Confirm the scope + item count with the user before sizing.
42
+ 6. Confirm the active config values above (rate/MF/highFactor — from `.gsd-t/estimate-config.json` or Tekyz defaults).
43
+ 7. Decide whether this is a **new-team project** (triggers the familiarization adjustment, Step 2.5) — usually YES for a fresh client.
44
+
45
+ ## Step 1: Numbering hygiene (MECHANICAL — show result)
46
+
47
+ Client-facing line-items must carry **sequential, rational numbering starting at 1**. Requirements docs often have NO numbers, or hierarchical numbers, or (rarely) a scan that crashed-and-reran starts high (e.g. TD-618, which looks bad — "why does #1 start at 618?"). (`tekyz-tech-debt-numbering-caution`.)
48
+
49
+ **Renumber ONLY when the numbering is absent, non-sequential, or doesn't start at 1.** If it is already sequential and rational, LEAVE IT.
50
+
51
+ - **Unnumbered input** → assign sequential ids (`FR-1, FR-2, …` or `TD-1, …`).
52
+ - **Hierarchical numbering** (`1`, `1.1`, `1.1.1` = requirement / sub / sub-sub) → **preserve the hierarchy**; renumber only to make each level sequential-and-rational (no gaps, starts at 1 within its parent). Never flatten a hierarchy.
53
+ - **Already-clean numbering** → no change.
54
+ - When you DO renumber, do it SAFELY (numbering-only, zero value changes):
55
+ - Confirm the id range is contiguous first, so a blind offset aligns.
56
+ - **Range-bounded regex** — remap ONLY numbers in the doc's actual range, so you never corrupt `DC-n`, another project's `TD-4`, or a different repo's numbering.
57
+ - **Scope to CURRENT deliverables only:** the input doc, 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.**
58
+ - **Second pass for non-prefixed formats:** bare `| 618 |` table cells, slashed chains (`TD-2/623`), header text. A first-pass `PREFIX-NNN` regex misses these.
59
+ - **Back up files before the bulk edit.**
60
+ - A client that wants the original numbering keeps it — offer, don't force.
61
+
62
+ ## Step 2: Size each line-item (T-Shirt Size tab) — JUDGMENT · PAUSE FOR REVIEW
63
+
64
+ For each in-scope item, build a row — cols **A** Module · **B** User Type · **C** Functionality (**include the `(TD-n)` / `(FR-n)`**) · **D** Low-Level Requirement · **E** Phase (MVP) · **F** Web Portal (frontend) size · **G** Backend/API size. **Leave H–L (formulas) alone.**
65
+
66
+ - **Size each column INDEPENDENTLY** (FE and BE each get their own letter; blank = 0). Sizes per `sizeScale`: **XS 0.25 · S 0.5 · M 1 · L 3 · XL 5 · XXL 7** person-days.
67
+ - The sheet computes: `Days = F+G` · `MFactor Days = Days × totalMF` · `Total Days = Days + MFactor` · `LOW $ = Total × hoursPerDay × rate` · `HIGH $ = LOW × highFactor`. **Ignore the Phase column.**
68
+ - **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.
69
+ - **Tune the MF per project:** raise Buffer/QA when confidence is low; raise `highFactor` above 1.25 for more unknowns.
70
+ - **PAUSE:** present the sized rows (or the clusters + representative sizes) and the running total. Wait for `continue` or corrections before Step 2.5.
71
+
72
+ ## Step 2.5: Estimate Adjustments (familiarization + risk/unknowns) — JUDGMENT · PAUSE FOR REVIEW
73
+
74
+ Base sizes assume *familiar* devs on *well-understood* work. Adjust for the two things that make real work heavier than the naive size. Document each adjustment per-item so the client sees **why** an item is heavier. (`tekyz-familiarization-bump`.)
75
+
76
+ **(a) New-team familiarization** — ramp for a team new to the codebase. Bump each item's SIZE in proportion to its complexity — **NOT the MF** (the Analysis MF is for a Business Analyst, not dev ramp).
77
+ - Trivial config / single-route → **no bump**. Repeated-pattern guards, few routes → **+0–1 tier**. High-volume sweeps + new-surface builds → **+1 tier**.
78
+ - Optionally add a one-time **"Codebase Onboarding & Downstream Analysis"** Common line (sized L–XL) — document as optional, client can remove.
79
+
80
+ **(b) R&D / unknown-approach / spike risk** — an item needing research, an unproven approach, or an unknown integration gets an uplift for the uncertainty. Either bump its SIZE, or raise its per-item risk contribution (and consider raising `highFactor` for the whole estimate if unknowns dominate). Name the unknown explicitly ("requires spike: undocumented 3rd-party API").
81
+
82
+ **⚠️ 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 routine-work bumps at M.
83
+ - Reference calibration: HILO 21 criticals = $8,700 familiar → $11,730 new-team (+35%, bumps capped at M) → $13,090 incl Project Setup.
84
+ - **PAUSE:** present every adjustment (item, reason, before→after size, total delta). Wait for `continue` or corrections.
85
+
86
+ ## Step 3: Group by domain + blue headings (T-Shirt tab)
87
+
88
+ 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).
89
+
90
+ - **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.
91
+
92
+ ## Step 4: Team Mix cross-check
93
+
94
+ `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`.
95
+
96
+ - **Solve `Month` (D5:D12)** so `sum(Count) × (Month×20) = the T-shirt total`. Sync the Resource (J) column.
97
+ - **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).
98
+ - **Verify BOTH halves (F13, J13) equal the T-shirt total.**
99
+
100
+ ## Step 5: Write to the Google Sheet (PERMANENT reusable service account) — MECHANICAL · show result
101
+
102
+ **gcloud's `spreadsheets` OAuth scope is blocked by Google** (browser shows "This app is blocked"; `gcloud auth print-access-token` is unusable for Sheets), so a **service account with a self-signed JWT** is the only working path (`google-sheets-service-account-workaround`). A **PERMANENT, reusable SA already exists** — do NOT create a throwaway per run.
103
+
104
+ **The permanent estimate SA (provisioned once, reused every run):**
105
+ - **Email (the sheet share-target):** `gsd-t-sheets-writer@ai-estimator-415612.iam.gserviceaccount.com`
106
+ - **GCP project:** `ai-estimator-415612` · **Sheets API:** enabled
107
+ - **Key file:** `~/.claude/gsd-t-secrets/gsd-t-sheets-writer-key.json` (chmod 600, outside any repo — never commit an SA key)
108
+
109
+ 1. **Self-heal / provision-once (idempotent):** if the key file is missing, recreate the SA + mint a key before proceeding — this is the ONLY create path, and it runs at most once ever:
110
+ ```bash
111
+ PROJECT=ai-estimator-415612
112
+ SA=gsd-t-sheets-writer@$PROJECT.iam.gserviceaccount.com
113
+ KEY=~/.claude/gsd-t-secrets/gsd-t-sheets-writer-key.json
114
+ gcloud services enable sheets.googleapis.com --project=$PROJECT
115
+ gcloud iam service-accounts describe "$SA" --project=$PROJECT >/dev/null 2>&1 || \
116
+ gcloud iam service-accounts create gsd-t-sheets-writer \
117
+ --display-name="GSD-T Estimate Sheets Writer (permanent, reusable)" --project=$PROJECT
118
+ # SA creation is eventually-consistent — poll describe before minting the key
119
+ [ -f "$KEY" ] || { mkdir -p ~/.claude/gsd-t-secrets && chmod 700 ~/.claude/gsd-t-secrets && \
120
+ gcloud iam service-accounts keys create "$KEY" --iam-account="$SA" --project=$PROJECT && chmod 600 "$KEY"; }
121
+ ```
122
+ 2. **Share check:** the SA has no access until the sheet is shared with it. If a read-probe (below) returns `403`, **prompt the operator to share the sheet with `gsd-t-sheets-writer@ai-estimator-415612.iam.gserviceaccount.com` as Editor** (uncheck "Notify people"), wait for confirmation, re-probe. Because the SA is permanent, this is a **one-time** share per sheet — no re-share churn.
123
+ 3. **Auth = self-signed JWT** (pure stdlib + openssl, no client libraries): read the key file, sign an RS256 JWT (`openssl dgst -sha256 -sign`), scope `https://www.googleapis.com/auth/spreadsheets`, exchange at `oauth2.googleapis.com/token` (grant `urn:ietf:params:oauth:grant-type:jwt-bearer`) for a Bearer token. JWT `exp = now + 3600`; **mint fresh each run** (1h expiry).
124
+ 4. **Write via Sheets v4 REST** with the Bearer token: `values/<range>/PUT?valueInputOption=USER_ENTERED` for cell values; `:batchUpdate` for inserts/formatting/merges. **Reads:** `GET spreadsheets/<id>?ranges=...&includeGridData=true` (used for the 403 share-probe too).
125
+ 5. **Gotcha fixes (all proven on HILO):**
126
+ - **403 quota-project** on the Sheets API → add header `X-Goog-User-Project: ai-estimator-415612`.
127
+ - **URL-encode every range** (`urllib.parse.quote`) — spaces in tab names (e.g. `'T-Shirt Size Estimate'!A19`) break the URL.
128
+ - **Hardcoded SUMIF/total ranges don't auto-expand** on a plain values-write → use `insertDimension` (which shifts ranges) when inserting rows (ties back to Step 3's WIDEN note).
129
+ - **`drive.file` scope 404s on a pre-existing sheet** → must use the full `spreadsheets` scope.
130
+ 6. **No cleanup / no delete.** The SA is PERMANENT and reused — never delete it, never delete the key. (Deleting + recreating an SA changes its internal id and silently breaks every existing sheet share even with an identical email → 403. Keeping it permanent is the whole point.)
131
+
132
+ ## Step 6: Generate the PRD — JUDGMENT · PAUSE FOR REVIEW
133
+
134
+ **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`.)
135
+
136
+ - **§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.**
137
+ - **§3.0 requirement↔finding 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. (For a pure requirements input with no scan, the "Finding" column becomes the source requirement id.)
138
+ - **§3.1 FR tables** — a **dedicated Finding/Source column** (never bury the id in trailing prose).
139
+ - **§3.2 NFR** — an **"Applies to" column listing EVERY id** each cross-cutting NFR touches.
140
+ - **§4 enforcement, §8 API, §10 estimate** — explicit id refs (not bare numbers).
141
+ - **§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.
142
+ - **§15 sign-off = "Approved to proceed (scope, not fixed cost)".**
143
+ - Group tables **by domain with a bold header per group** (no repeating "Domain" column — reads as broken).
144
+ - **Save to `share/<Repo-Name>-PRD-*.md`** (repo-name prefix, matching `/gsd-t-scan`'s `share/` convention).
145
+ - **PAUSE:** present the PRD (or its outline + disclaimer + §10 total) for review before finalizing.
146
+
147
+ ## Step 7: Verify — reconcile the three totals (MECHANICAL · show result)
148
+
149
+ **The three totals 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 advancing to the Red Team.
150
+
151
+ ## Step 8: Estimate Red Team (adversarial) — JUDGMENT · PAUSE · YOU ARE THE ARBITER
152
+
153
+ An independent adversarial pass that challenges the estimate before it reaches the client — the estimate-time analogue of GSD-T's build Red Team. **Its job is to protect Tekyz from a money-losing under-estimate AND to keep the estimate competitive** (paired realism, per `feedback_red_team_realism_gate` — don't pad every item to XXL "to be safe").
154
+
155
+ **What it attacks:**
156
+ - **Under-sized items** — "this 'S' implies a DB migration + backfill → really M; +2 days."
157
+ - **Missing line-items** — work a requirement implies but nothing sized (migrations, tests, auth, error states, rollout).
158
+ - **Optimistic multipliers** — Buffer/QA too low for the stated confidence; `highFactor` too tight for the unknowns.
159
+ - **Adjustment gaps** — an R&D/unknown item (Step 2.5b) sized as if it were routine.
160
+ - **Cross-check integrity** — do the three totals ACTUALLY reconcile, or is a hardcoded cell hiding a break.
161
+ - **Assumption / scope gaps** — unstated assumptions that would blow up mid-project.
162
+
163
+ **Verdict:** `FAIL` (material under-estimate or missing scope found) / `GRUDGING-PASS` (exhaustive search, nothing material).
164
+
165
+ ### The arbitration protocol (David is the final judge — NOT bot ping-pong)
166
+
167
+ When the Red Team returns `FAIL`, it does **NOT** loop back-and-forth with the skill until it grudgingly passes. It surfaces to **the operator**:
168
+
169
+ 1. **Present each objection PLAINLY:** *what* shouldn't pass, *why*, and *the estimate impact* (which item, before→after size, dollar delta). One clear list, ranked by dollar impact.
170
+ 2. **The operator decides, per objection:**
171
+ - **Agree** → operator says `continue` → apply the fix.
172
+ - **Disagree** → operator gives feedback → **the Red Team argues back.** The argument continues until **one side concedes** OR the operator ends it definitively.
173
+ 3. **Definitive-decision override:** if the operator says anything conclusive — e.g. *"No more argument. I've decided on X,"* or any clearly final ruling — the Red Team **MUST grudgingly accept the operator's decision immediately, regardless of how many rounds have passed.** It **MAY document its unresolved objection** (in the PRD as a footnote or a `share/<Repo>-estimate-redteam-notes.md` file) **for later consideration** — but it does not re-litigate.
174
+ 4. The Red Team **never self-satisfies into a pass** and **never overrides the operator.** It either persuades the operator or defers to them.
175
+
176
+ **PAUSE** at every objection — this phase is inherently interactive.
177
+
178
+ ## Step 9: Deliver
179
+
180
+ All client-facing files land in `share/` with the repo-name prefix. Report: input type + scope + item count, the active config values (rate/MF/highFactor), the eng-days + LOW–HIGH dollar range, the sheet URL, the PRD path, the Red Team verdict, and any documented-but-overridden Red Team objections.
181
+
182
+ ## Document Ripple
183
+
184
+ - `share/<Repo>-PRD-*.md` (new PRD deliverable) + the Google Sheet (external) + optional `share/<Repo>-estimate-redteam-notes.md` (overridden objections).
185
+ - If renumbering (Step 1) ran: the input + plain-English + `scan/*.md` + `docs/*` + README + `share/*` were remapped (archives untouched) — note it in the report so the numbering change is traceable.
186
+
187
+ ## ▶ Next Up
188
+
189
+ Standalone command — no auto-successor. After delivering, the user shares the sheet + PRD with the client.
@@ -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 any structured work document — a scan register, a new-feature or new-app requirements doc, or a PRD-in — 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 source doc/docs/scan files) + optional `share/<Repo>-estimate-redteam-notes.md`
365
+ - **Use when**: You need a client-facing paid estimate + PRD (T-shirt sizing, dollar range, sign-off) from a scan OR a requirements/feature/app spec. **SUPERVISED** — judgment phases (sizing, adjustments, PRD, Red Team) pause for your review; **you are the final arbiter** of an Estimate Red Team that challenges the numbers. Rate + sheet template + factors are parameterized (default Tekyz). Encodes the 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tekyzinc/gsd-t",
3
- "version": "4.15.10",
3
+ "version": "4.17.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,39 @@
1
+ {
2
+ "$schema": "Optional config for /gsd-t-estimate. Copy to .gsd-t/estimate-config.json and edit. ALL fields are optional — any omitted field falls back to the Tekyz default shown here. The active values are always named in the estimate report (no silent defaults).",
3
+
4
+ "rate": 50,
5
+ "_rate": "Blended hourly rate (USD) used for the LOW dollar figure. Tekyz default: 50.",
6
+
7
+ "hoursPerDay": 8,
8
+ "_hoursPerDay": "Hours per person-day. Default: 8.",
9
+
10
+ "sizeScale": { "XS": 0.25, "S": 0.5, "M": 1, "L": 3, "XL": 5, "XXL": 7 },
11
+ "_sizeScale": "T-shirt size -> person-days. NON-LINEAR: M->L is a 3x cliff (1 -> 3 days). Do not push routine work across M->L.",
12
+
13
+ "totalMF": 0.7,
14
+ "_totalMF": "Overhead multiplier applied to raw Days. Tekyz 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.",
15
+
16
+ "mfBreakdown": { "qa": 0.3, "pm": 0.1, "analysis": 0.05, "deployment": 0.05, "buffer": 0.2 },
17
+ "_mfBreakdown": "Optional itemized breakdown of totalMF (must sum to totalMF). Tune per project; e.g. raise buffer for low-confidence scope.",
18
+
19
+ "highFactor": 1.25,
20
+ "_highFactor": "HIGH dollar figure = LOW x this. Raise above 1.25 when unknowns dominate (many R&D / spike items).",
21
+
22
+ "currency": "USD",
23
+ "_currency": "Currency label for the report. Default: USD.",
24
+
25
+ "sheetTemplateId": "",
26
+ "_sheetTemplateId": "Optional. Google Sheet ID of a template to clone. Normally BLANK — the operator pastes the target sheet URL at run start (Step 0) and the command extracts the ID.",
27
+
28
+ "gcpProject": "ai-estimator-415612",
29
+ "_gcpProject": "GCP project hosting the PERMANENT reusable Sheets-writer service account. Default: ai-estimator-415612 (AI Estimator).",
30
+
31
+ "serviceAccountEmail": "gsd-t-sheets-writer@ai-estimator-415612.iam.gserviceaccount.com",
32
+ "_serviceAccountEmail": "The PERMANENT reusable SA — share each target sheet with THIS email as Editor. Never deleted/recreated (recreation breaks existing shares).",
33
+
34
+ "serviceAccountKeyPath": "~/.claude/gsd-t-secrets/gsd-t-sheets-writer-key.json",
35
+ "_serviceAccountKeyPath": "Local path to the SA JSON key (chmod 600, outside any repo — NEVER commit). Step 5 self-provisions the SA+key here if missing.",
36
+
37
+ "newTeamDefault": true,
38
+ "_newTeamDefault": "Whether to assume a new-team familiarization adjustment (Step 2.5a) by default. Usually true for a fresh client."
39
+ }
@@ -0,0 +1,130 @@
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 **any structured work
5
+ > document** — a GSD-T tech-debt scan register, a new-feature or new-application
6
+ > requirements doc, or an existing PRD. Proven on the HILO Figma ATOS project
7
+ > (21 criticals → 32.73 eng-days → $13,090–$16,362). Apply to E-Learning and any
8
+ > other GSD-T client project.
9
+ >
10
+ > **This process is SUPERVISED and JUDGMENT-HEAVY.** The operator reviews the
11
+ > judgment phases (sizing, adjustments, PRD) and is the FINAL ARBITER of the
12
+ > Estimate Red Team (Phase 8). It does not run autonomously. Rate + sheet template
13
+ > + factors are parameterized (defaults are the Tekyz values below). See
14
+ > `commands/gsd-t-estimate.md` for the authoritative, current phase list.
15
+
16
+ Related memory: `tekyz-estimation-method`, `tekyz-familiarization-bump`,
17
+ `tekyz-client-prd-structure`, `tekyz-tech-debt-numbering-caution`,
18
+ `google-sheets-service-account-workaround`.
19
+
20
+ ---
21
+
22
+ ## Phase 0 — Inputs
23
+
24
+ 1. A completed GSD-T scan (`.gsd-t/techdebt.md`) with findings by severity.
25
+ 2. A copy of the Tekyz estimate template Google Sheet (tabs: **Overview**,
26
+ **T-Shirt Size Estimate**, **Team Mix**, **Technology Stack**).
27
+ 3. The ATOS contractor-handoff PRD template (sections 0–15).
28
+ 4. Decide the scope: usually **all CRITICAL findings** = "close the critical gap."
29
+
30
+ ---
31
+
32
+ ## Phase 1 — Renumber for the client (if scan numbers start high)
33
+
34
+ GSD-T continues TD numbering across scans; a fresh/crashed-and-rerun scan can start
35
+ at e.g. TD-618. **For a new client project, renumber to TD-1** before sharing.
36
+
37
+ - Verify the register IDs are contiguous (`min..max`, no gaps) → clean offset.
38
+ - Remap **only** numbers in the register's range (range-bounded regex) so you don't
39
+ touch `DC-n`, other projects' TDs, or another repo's numbering.
40
+ - Scope: register, plain-English, `scan/*.md`, `docs/*.md`, README, PRD, `share/*`,
41
+ and the Google Sheet labels. **Leave archives / transcripts / heartbeats alone.**
42
+ - Second pass for non-`TD-` formats: bare `| 618 |`, chains `TD-2/623`, header text.
43
+ - Back up files first.
44
+
45
+ ---
46
+
47
+ ## Phase 2 — Size each finding (T-Shirt tab)
48
+
49
+ For each finding, write a row (cols A–G; leave H–L formulas alone):
50
+ `A` Module · `B` User Type · `C` Functionality (include the `(TD-n)`) ·
51
+ `D` Low-Level Requirement · `E` Phase (MVP) · `F` Web Portal size · `G` Backend/API size.
52
+
53
+ - Size **each column independently** (FE and BE). Sizes: XS .25, S .5, M 1, L 3, XL 5, XXL 7.
54
+ - Sheet computes: `Days = F+G`, `MFactor = Days×MF`, `Total = Days+MFactor`,
55
+ `LOW$ = Total×8×$50`, `HIGH$ = LOW$×1.25`.
56
+ - **Cluster the work** to size fast: "add existing auth guard to routes" (XS–S,
57
+ repeated pattern) vs "new backend surface" (M, +FE) vs "config/1-route" (XS).
58
+
59
+ ### Familiarization bump (new-team projects)
60
+ Base sizes assume *familiar* devs. For a new team, bump SIZE in proportion to
61
+ complexity (NOT the MF — Analysis MF is for a Business Analyst):
62
+ - Trivial → no bump. Repeated-pattern guards → +0-1 tier. High-volume sweeps +
63
+ new-surface → +1 tier. **Never cross the M→L cliff (3×) unless genuinely multi-day.**
64
+ - Optionally add a one-time "Codebase Onboarding & Downstream Analysis" Common line (L–XL).
65
+
66
+ ### Tune the MF (per project)
67
+ `Total MF` = QA + PM + Analysis + Deployment + Buffer (default 0.7). Raise Buffer/QA
68
+ when confidence is low; raise **High Factor** above 1.25 for more unknowns.
69
+
70
+ ---
71
+
72
+ ## Phase 3 — Group by domain + blue headings (T-Shirt tab)
73
+
74
+ Reorder items into domains (A–G to match the PRD). Insert a **blue section-heading
75
+ row** before each group (merge A:L, white bold on blue). No subtotals (they complicate
76
+ formulas). After reordering: **widen the rollup SUMIF ranges** (`E19:En`) — writing
77
+ cells does NOT auto-expand hardcoded ranges; only `insertDimension` shifts them.
78
+
79
+ ---
80
+
81
+ ## Phase 4 — Team Mix cross-check
82
+
83
+ `Count` = fractional headcount per role (fixed team shape). Solve `Month (D)` so
84
+ `sum(Count) × (Month×20) = T-shirt total`. Write `Month` to D5:D12; sync the Resource
85
+ (J) column. **Check for hardcoded cells** that break the formula chain (restore `=E×B`,
86
+ `=J`). Verify both halves (F13, J13) equal the T-shirt total.
87
+
88
+ ---
89
+
90
+ ## Phase 5 — Writing to the Google Sheet (auth)
91
+
92
+ gcloud's `spreadsheets` OAuth scope is **blocked by Google** (user ADC unusable).
93
+ Use the **PERMANENT reusable service account** (see
94
+ `google-sheets-service-account-workaround` memory + `commands/gsd-t-estimate.md`
95
+ Step 5 for the authoritative runbook):
96
+ - **SA (share-target):** `gsd-t-sheets-writer@ai-estimator-415612.iam.gserviceaccount.com`
97
+ - **Project:** `ai-estimator-415612` · **Key:** `~/.claude/gsd-t-secrets/gsd-t-sheets-writer-key.json` (chmod 600).
98
+
99
+ Flow: operator pastes sheet URL → extract id → shares sheet with the SA email as
100
+ Editor (one-time per sheet — SA is permanent) → JWT (RS256 via openssl) → token →
101
+ Sheets v4 REST (`values PUT` / `:batchUpdate`; reads via `GET ...includeGridData`).
102
+ Gotchas: `X-Goog-User-Project` header for 403 quota; `urllib.parse.quote` every
103
+ range; `insertDimension` to shift hardcoded SUMIF ranges; full `spreadsheets` scope
104
+ (not `drive.file`); JWT `exp=now+3600`, mint fresh each run.
105
+ **NEVER delete/recreate the SA** — recreation breaks every existing sheet share.
106
+
107
+ ---
108
+
109
+ ## Phase 6 — The PRD deliverable
110
+
111
+ One document, **domain sub-sections (A–G) inside each numbered section** (0–15).
112
+
113
+ - **§0 Metadata** + top-of-doc **⚠️ Estimate Basis & Disclaimer** (estimates, not a
114
+ quote; will change; no not-to-exceed / guarantee). Purge quote/fixed/binding language.
115
+ - **§3.0 FR↔TD crosswalk** (per-domain tables: Requirement · Finding · Fix).
116
+ - **§3.1 FR tables** — dedicated **Finding** column (never bury TD in prose).
117
+ - **§3.2 NFR** — **Applies to** column listing **every** TD each cross-cutting NFR touches.
118
+ - **§4 enforcement, §8 API, §10 estimate** — explicit `TD-n` refs (not bare numbers).
119
+ - **§10 total must equal the live sheet rollup** (verify against the cell; watch that
120
+ Project Setup carries its MF). Point-in-time sync is fine; note it.
121
+ - **§15 sign-off** = "Approved to proceed (scope, not fixed cost)".
122
+ - Group tables by domain with a bold header per group (no repeating "Domain" column).
123
+ - Save to `share/<Repo-Name>-PRD-*.md` (repo-name-prefixed).
124
+
125
+ ---
126
+
127
+ ## Phase 7 — Deliver
128
+
129
+ All client-facing files in `share/` with the repo-name prefix. Confirm the three
130
+ estimate views agree: T-Shirt total = Team Mix total = PRD §10 total.