Deliver an oversized dispatch brief through a brief CLI when the SubagentStart hook exceeds the 10,000-character cap #627
Labels
No labels
P0
P1
P2
P3
bug
category/code-change
category/cross-repo
category/eval-run
category/investigation
category/no-test-target
category/owner-ruling
category/prose-artifact
category/recurring-chore
category/structure
category/umbrella
crc-refactor
create
delete
enhancement
filed-by/agent
filed-by/user
frozen
lint-rule
needs-info
needs-triage
next
plugin/cc-architect
plugin/os
plugin/os-adr
plugin/os-aidd-lint
plugin/os-backlog
plugin/os-context
plugin/os-doc-hygiene
plugin/os-sdlc
plugin/os-vault
project/cc-os
ready-for-agent
ready-for-human
recurring
review
rule-proposal
update
waiting
wayfinder:grilling
wayfinder:map
wayfinder:map
wayfinder:research
wayfinder:task
wayfinder:task
wontfix
worklist/deviations
worklist/lint-rule
worklist/new-implement-build
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
jared/cc-os#627
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Claude Code caps each hook
additionalContextstring at 10,000 characters. Above the cap it writes the string to a file in the session directory and gives the agent the file path plus the first 2,000 characters. No setting raises the cap. Source: https://code.claude.com/docs/en/hooks.md, section "Hook input and output". The os-sdlc SubagentStart hook sends the whole enriched brief inline as one string. After #618 (ADR-0204)code_changesis a full staged diff with no limit. Any diff past about 10,000 characters pushes the string over the cap. Supersedes #623, which routed the symptom (verifierverdict: error) to a retry that resends the same payload.Observed
Dispatch 140 (behavior-verifier) of implementation 11 on #621 settled in 9 s with no model call.
Reproduce
Expected
Illustration
Origin
verdict: error← agent preview showedbrief: null← Claude Code persisted the hook string over 10,000 characters (UPSTREAM-TOOL, documented cap at https://code.claude.com/docs/en/hooks.md, no override) ← os-sdlc sends the full brief inline through oneadditionalContextstring (DESIGN, hook/pipe.rb, pipeline/start_subagent.rb) ← #618 removed thecode_changestruncation (DESIGN, ADR-0204)Owner sketch
Cases
os-sdlc-runner brief --dispatch-id <id>, and holds no enriched fact.os-sdlc-runner brief --dispatch-id <id>runs, then it prints the full brief that BriefComposer builds for that dispatch on stdout and exits 0.os-sdlc-runner brief --dispatch-id <id>runs, then it prints one error naming the id and exits nonzero.tools:line is read, then it includes Bash.bashOutputMaxCharsis 128000.Approach
Keep the zero-tool-call path for every brief that fits. Measure the final serialized
additionalContextstring, not the brief object, in UTF-16 code units, because Claude Code counts JavaScript string length. Over the cap, emit the routing envelope plus the command; the CLI rebuilds the full brief from the same BriefComposer at call time rather than caching it. The CLI must exit 0, because a failing Bash command gets only a 10,000-character excerpt with no file path.Rejected: always pass a file path (costs a tool call on every dispatch). Rejected: one SubagentStart hook per fact (a single diff over 10,000 still fails). Rejected: retry the verifier on error (#623; resends the same payload). Rejected: trim brief contents near 30 KB (YAGNI; a ticket that large should be split).
Depends on: Bash tool default ceiling 30,000 characters, raised by
bashOutputMaxChars(max 128,000, Claude Code v2.1.261+). Run /os-adr:find on hook/pipe.rb, pipeline/start_subagent.rb, pipeline/brief_composer.rb before the first edit; record the delivery decision as an ADR alongside ADR-0204.Structural follow-through
Work started via /os-sdlc:implement on branch ticket-627 (worktree).
Resolution
Done: HookPayload caps the SubagentStart additionalContext at 10,000 UTF-16 units; over the cap the routing envelope carries os-sdlc-runner brief --dispatch-id N and BriefLookup recomposes the full brief while the dispatch is open; wiring charter gains Bash for that command; bashOutputMaxChars 128000. All 7 cases have tests. ADR-0206 amends ADR-0109/0141/0204.
Evidence: Branch ticket-627 commit
023183a6. Suite 1395 runs, 0 failures; changed files lint-clean. Live check: brief --dispatch-id 99999 exits 3 naming the id; a settled dispatch exits 3 with 'already settled'. Pipeline implementation 12 escalated at behavior-verifier (evidence scope, see #629); hand-finished from the green increment.Follow-ups: #629 behavior-verifier misses changes outside code_path (workflow defect that caused the escalation); #630 HookPayload fallback can still exceed the cap on a large handoff. Live check that the cap is exactly 10,000 UTF-16 units in a real session is still owed (ADR-0206 consequences).