@tekyzinc/gsd-t 5.14.11 → 5.16.11

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,182 @@
2
2
 
3
3
  All notable changes to GSD-T are documented here. Updated with each release.
4
4
 
5
+ ## [5.16.11] - 2026-08-27
6
+
7
+ ### Fixed — the voice fix was the wrong fix, and the gate was measuring the wrong thing
8
+
9
+ Both corrections came from running the shipped pipeline against real work, and
10
+ both invalidate advice published hours earlier in 5.16.10.
11
+
12
+ **Pick a text-to-speech service whose voice is a fixed trained speaker.** The
13
+ source run had fought drift with batching — 8 sentences per request so one
14
+ request meant one performance, audio split back apart on silences, splits
15
+ verified, whole takes re-rendered when they measured as drifted. All of that was
16
+ mitigation for a property of the wrong kind of service. A language model's audio
17
+ output treats a voice name as a style hint it re-interprets on every request, so
18
+ the narrator genuinely changes part-way through a video; batching reduces how
19
+ often that happens and cannot stop it, because a batch boundary is still a
20
+ boundary between two readings. Moving to a dedicated speech service, where a
21
+ voice id is a fixed trained speaker, ended it in one change — and took batch
22
+ boundaries, silence splitting, miscut clips and per-model daily quotas with it.
23
+ One sentence per request became both the simple thing and the correct thing. The
24
+ batching guidance is kept, demoted to what to do when you cannot switch.
25
+
26
+ **Gate on mean pitch, not within-video pitch spread.** The published gate failed
27
+ **nine of the twelve videos its own project had already shipped** — every one
28
+ confirmed by ear as a single steady narrator. A ±35 Hz spread threshold is right
29
+ for a language-model TTS, where a wide spread means a different reading, and
30
+ wrong for a fixed speaker, where it measures ordinary sentence intonation: a
31
+ question rising, a list falling, a short line sitting higher. Flattening that
32
+ would make the narration robotic. The speaker-identity signal is the mean, which
33
+ across those twelve videos sat inside a 7 Hz band. So the gate now checks the
34
+ mean against a calibrated band and reports the spread without gating it — ten of
35
+ twelve pass, and the two that still fail do so on volume, which is real.
36
+
37
+ The rule this produces, now in the command: **calibrate a gate against output a
38
+ human has already approved before trusting it.** A gate that fails most of your
39
+ known-good work is measuring the wrong thing, and believing it costs you
40
+ re-rendering audio that was already correct.
41
+
42
+ **Narration lines must be full sentences of 8 words or more.** Integrated
43
+ loudness needs enough audio to measure against; a two-word clip ("Create
44
+ Curriculum.") lands off target, blows the video's volume spread and trips the
45
+ miscut check. This cost two full render cycles before it was diagnosed. When a
46
+ step needs an action the narration does not describe, run it untimed rather than
47
+ inventing a stub line.
48
+
49
+ **Templates:** `choose()` opens a dropdown, holds it open long enough to read,
50
+ and picks — the choice is the most informative moment in a create-flow, and a
51
+ highlighted select shows the viewer nothing. `enter()` types a value visibly
52
+ rather than filling it instantly. `act()` performs either outside a narrated
53
+ beat, because both only build an action and a bare `await` on one silently does
54
+ nothing. New `cast.mjs` carries every name said aloud in one place.
55
+
56
+ **Narration guidance rewritten around two woven stories** — the operator's, told
57
+ in their own voice and shown on screen, and the customer's, which is why every
58
+ value typed is that value. The test: a sentence that survives with the names
59
+ removed is explaining the software, not telling the story.
60
+
61
+ - `commands/gsd-t-demo-videos.md`: Stage 1 rewritten; cast step gains the
62
+ two-story weave, the products/pricing rule and the dropdown mandate
63
+ - `templates/demo-videos/e2e/cast.mjs`: new
64
+ - `templates/demo-videos/e2e/runtime.ts`: `enter()`, `choose()`, `act()`
65
+ - `templates/demo-videos/e2e/example.{lines.mjs,spec.ts}`: rewritten as a story
66
+
67
+ ## [5.16.10] - 2026-08-27
68
+
69
+ ### Added — `/gsd-t-demo-videos`, narrated walkthrough videos of a running app
70
+
71
+ Distilled from a real production run that shipped twelve narrated walkthroughs
72
+ of a live application over two long sessions. Nearly every re-record in that run
73
+ traced back to one of ten mistakes, so each is now a gate rather than a lesson
74
+ to be re-learned.
75
+
76
+ **Narration is the master clock.** A step lasts exactly as long as its measured
77
+ spoken sentence — never a constant, never an estimate. The first version of that
78
+ pipeline gave every step a fixed five seconds, and that single number is why the
79
+ words drifted away from the picture. It also assembled the video from per-screen
80
+ clips and stills, which cannot show a transition or how the interface actually
81
+ behaves. One continuous recording per walkthrough, clipped afterward.
82
+
83
+ **The voice was the expensive problem, and its cause was confirmed.** The
84
+ narrator audibly changed tone and volume partway through a video because every
85
+ sentence was a separate API call, so the model re-decided its delivery dozens of
86
+ times. Describing the speaker in the prompt did not fix it. Two deterministic
87
+ fixes replace it:
88
+
89
+ - **Batched.** Eight sentences per request, numbered, with an instruction to
90
+ leave two seconds of silence between them; the audio is cut back apart on
91
+ those silences and the split is verified, never assumed. Eight is measured:
92
+ the same eighteen-line script rendered as a single take spread 46 Hz of pitch,
93
+ and in eight-line batches spread 16 Hz — the narrator holds around 100-115 Hz
94
+ for a dozen lines and then slips to 140, losing the persona the further it
95
+ gets from the instruction.
96
+ - **Normalised.** Every clip goes through a two-pass loudnorm to the same target
97
+ loudness. Within-video volume drift went from as much as 7.5 dB to about
98
+ 0.5 dB, and every video now sits at the same level as the others.
99
+
100
+ **The check is the gate, not the report.** Loudness, pitch and speaking rate are
101
+ measured per clip and the spread reported across the video, along with miscut
102
+ clips whose length does not match what their sentence should take to say. A take
103
+ that drifts is thrown away and re-rendered, up to three times, then halts rather
104
+ than shipping. This is not theoretical — one video's first take came back at
105
+ 46 Hz and was discarded for a 15 Hz one. It exists because two renders of the
106
+ same prompt genuinely differ: a "persona anchor" prompt looked like a large win
107
+ on one A/B run and reversed on the next.
108
+
109
+ **Other gates, each from a failure it would have prevented:**
110
+
111
+ - A preflight walks every selector without recording. One bad selector used to
112
+ fail a whole six-minute recording at the first sentence whose target was
113
+ missing, so three bad selectors cost three recordings to find.
114
+ - The runtime throws when a narrated sentence has no visible target, and asserts
115
+ the page as well. Narration had repeatedly described screens the spec never
116
+ opened, and a failed click produced confident narration about a screen that
117
+ was never on camera.
118
+ - Silence removal is mandatory after every mux. Page loads left 20-60 seconds of
119
+ dead air per video — 7.4 minutes across twelve.
120
+ - When a recording fails, look at the failure screenshot the run already saved.
121
+ Every wrong theory in the source run came from reasoning about the DOM
122
+ instead; one three-recording failure was diagnosed twice-wrongly before the
123
+ screenshot showed the answer immediately.
124
+ - Coverage is planned against the running app, not the code. The first nine
125
+ videos covered about 25 of 55 populated screens, and probing the live site
126
+ reversed four of five "this screen is empty" verdicts that had been written
127
+ from the seed scripts.
128
+ - Seeders drive the real forms as a real user, and report a refusal instead of
129
+ working around it. One such refusal turned out to be a genuine app bug: an
130
+ enabled button whose click handler was inert.
131
+
132
+ **The pipeline ships as templates**, not as prose to re-implement:
133
+ `templates/demo-videos/` carries the seven scripts and six test files with the
134
+ reasoning for every threshold in their headers. The command resolves them
135
+ through the installed package directory and halts if they are absent.
136
+
137
+ ## [5.15.10] - 2026-08-27
138
+
139
+ ### Added — open questions, a fourth build status, and a fallbacks column
140
+
141
+ Four corrections from running the client-deliverable gap analysis live on a
142
+ second project.
143
+
144
+ **Open questions.** Column D now ends with an `OPEN QUESTIONS:` block: the
145
+ decisions someone must make before the work can be built or priced — which
146
+ settings are non-overridable, whether a mid-enrollment version change moves the
147
+ student. Six of eight rows on the proven sheet carry one. A row without the
148
+ block is asserting there are no unknowns, which is usually false; the test is
149
+ whether two reasonable people could build the row differently from what it
150
+ says. Questions are never invented to fill the block and never self-answered —
151
+ an unknown resolved by assumption is an assumption, and belongs in the
152
+ requirement bullets.
153
+
154
+ **A fourth build status, and a colour for it.** The status list carried four
155
+ values inherited from report mode while only three had colours, so `Incorrect`
156
+ rendered plain. Now green Implemented, yellow Partial, light-blue Incorrect,
157
+ red Not Implemented. Incorrect is not a shade of Partial: Partial needs
158
+ finishing, Incorrect needs undoing first, and pricing them alike understates
159
+ the second. Both must name specifics.
160
+
161
+ **Fallbacks in the shipped code (column P).** For every feature with code, the
162
+ places that code continues after a failure — the branches that make a system do
163
+ something quietly wrong instead of stopping. Reuses the existing detector.
164
+ Three states, not two: **approved** (recorded with a written reason),
165
+ **pre-existing** (grandfathered when the rule was adopted — not approved,
166
+ merely old, and still a finding for a client), and **unapproved**. A fallback
167
+ that contradicts the row's own requirements is the strongest finding on the
168
+ sheet; the requirements already ban several by name. A feature with no code
169
+ gets a blank cell, never "none", which reads as a clean result.
170
+
171
+ **Column layout.** Fallbacks take P, where an earlier sheet held Scope and then
172
+ hardening tasks; hardening moves to Q. Columns A, B and C are the reading
173
+ columns and are now specified exactly — bold feature name, blank line, italic
174
+ purpose — with the purpose verb tracking build status, conditional on an
175
+ unbuilt row and present tense on a built one. A column map under the mode table
176
+ states the layout once instead of restating it per step.
177
+
178
+ - `commands/gsd-t-gap-analysis.md`
179
+ - `.gsd-t/pseudocode/PseudoCode-GapAnalysis.md`
180
+
5
181
  ## [5.14.11] - 2026-08-25
6
182
 
7
183
  ### Fixed — gap analysis harvests the tracker instead of asking for a spec
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # GSD-T: Contract-Driven Development for Claude Code
2
2
 
3
- **v5.14.11** - A methodology for reliable, parallelizable development using Claude Code with optional Agent Teams support.
3
+ **v5.16.11** - 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-promote-debt` | Convert techdebt items to milestones | Manual |
187
187
  | `/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 |
188
188
  | `/gsd-t-stories` | Generate a dev-team handoff doc in the Tekyz user-stories format (stories + workflows + acceptance criteria + Mermaid flow diagrams + mapped test cases) from any source | Manual |
189
+ | `/gsd-t-demo-videos` | Narrated screen-recording walkthroughs of a running app — coverage plan, UI-driven seeding, batched TTS with a measured one-voice gate, continuous recording, mux, silence trim | 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