Summary
The end-of-turn Stop hook is slow (~16s per stop on a dev machine; observed ~1m40s in the Claude UI on a OneDrive/AV machine, which also includes the model's own cogitating). Surfaced during the feature-185 (host-neutral gate enforcement / FR-011 conformance Stop-provider) dogfood on real Claude in a throwaway test-f185 project.
The latency is dominated by repeated transcript parsing, and the largest share is pre-existing (F-174 handover provider) — not introduced by feature 185.
Evidence (measured against the deployed providers + a real ~0.25 MB / 80-line transcript)
| Component |
Time |
Origin |
| Handover provider (Stop, order 30) |
11.3 s |
pre-existing (F-174) |
| Conformance provider (Stop, order 40) |
4.2 s |
feature 185 (FR-011) |
| Full dispatcher Stop run |
~16 s |
sum |
Other factors ruled out by measurement: cold pwsh -NoProfile spawn = 0.53 s; shared-governance.ps1 load = 0.74 s; a single Get-Module -ListAvailable Specrew scan = 0.61 s. So the dominant cost is not spawns or module load — it is transcript parsing: Get-SpecrewConversationTurnFromLine does ConvertFrom-Json -Depth 40 per line, and the readers each re-read + re-parse -Tail 500:
- Handover calls it ~3x per stop:
Get-SpecrewCapturedBoundaryVerdict + Get-SpecrewCapturedBoundaryPacket + the conversation-tail capture (each ~2.9 s on this small transcript).
- Conformance adds another parse (the last-assistant read + the false-positive guard's packet read).
- Cost scales with session size, so it degrades as the conversation grows.
Already done (feature 185, commit 9834354b)
The conformance provider was optimized so it no longer compounds the cost unnecessarily:
- Lazy
Get-Module (only scans when the direct path / SPECREW_MODULE_PATH miss).
- Skips the per-line parse entirely when no trigger is structurally possible (e.g. the pre-spec design workshop).
#3 raw-Spec-Kit detection is now a cheap raw-text tail scan (no per-line JSON parse).
This trims feature 185's ~4 s share but leaves the dominant ~11 s handover cost unaddressed.
Proposed fix (the real unblock)
Parse the transcript tail ONCE per stop and share the parsed turns across the handover readers (verdict + packet + conversation tail) and the conformance provider, instead of each re-reading and re-parsing. Secondary: cap the parse window / ConvertFrom-Json -Depth, and/or stop scanning once the needed marker is found (scan from the end backward).
This is primarily an F-174 handover change (the dominant cost), composing with the FR-011 conformance provider.
Acceptance
Repro
Import-Module <worktree>\Specrew.psd1 -Force; specrew init --project-path <tmp> --force (deploys the FR-011 conformance Stop-provider).
- Launch Claude in
<tmp> and drive a few turns.
- Time a Stop:
Measure-Command { <dispatcher> -Event Stop -HostKind claude } against the session transcript.
Refs
- Feature 185 (FR-011 conformance Stop-provider), drift-log D-005/D-006.
- Conformance perf fix: commit
9834354b.
- Suggested labels:
performance, tech-debt (only enhancement applied — others did not exist).
Summary
The end-of-turn Stop hook is slow (~16s per stop on a dev machine; observed ~1m40s in the Claude UI on a OneDrive/AV machine, which also includes the model's own cogitating). Surfaced during the feature-185 (host-neutral gate enforcement / FR-011 conformance Stop-provider) dogfood on real Claude in a throwaway
test-f185project.The latency is dominated by repeated transcript parsing, and the largest share is pre-existing (F-174 handover provider) — not introduced by feature 185.
Evidence (measured against the deployed providers + a real ~0.25 MB / 80-line transcript)
Other factors ruled out by measurement: cold
pwsh -NoProfilespawn = 0.53 s;shared-governance.ps1load = 0.74 s; a singleGet-Module -ListAvailable Specrewscan = 0.61 s. So the dominant cost is not spawns or module load — it is transcript parsing:Get-SpecrewConversationTurnFromLinedoesConvertFrom-Json -Depth 40per line, and the readers each re-read + re-parse-Tail 500:Get-SpecrewCapturedBoundaryVerdict+Get-SpecrewCapturedBoundaryPacket+ the conversation-tail capture (each ~2.9 s on this small transcript).Already done (feature 185, commit
9834354b)The conformance provider was optimized so it no longer compounds the cost unnecessarily:
Get-Module(only scans when the direct path /SPECREW_MODULE_PATHmiss).#3raw-Spec-Kit detection is now a cheap raw-text tail scan (no per-line JSON parse).This trims feature 185's ~4 s share but leaves the dominant ~11 s handover cost unaddressed.
Proposed fix (the real unblock)
Parse the transcript tail ONCE per stop and share the parsed turns across the handover readers (verdict + packet + conversation tail) and the conformance provider, instead of each re-reading and re-parsing. Secondary: cap the parse window /
ConvertFrom-Json -Depth, and/or stop scanning once the needed marker is found (scan from the end backward).This is primarily an F-174 handover change (the dominant cost), composing with the FR-011 conformance provider.
Acceptance
specrew init: Install missing Spec Kit/Squad #3 + fail-open) unchanged — existing suites green (conformance-detection,dispatcher-stop-block,ProviderMirrorParity, the handover/bootstrap suites).Repro
Import-Module <worktree>\Specrew.psd1 -Force; specrew init --project-path <tmp> --force(deploys the FR-011 conformance Stop-provider).<tmp>and drive a few turns.Measure-Command { <dispatcher> -Event Stop -HostKind claude }against the session transcript.Refs
9834354b.performance,tech-debt(onlyenhancementapplied — others did not exist).