os-me-extract: structured DecisionModel answers, per-session cursor, Haiku model #1256
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#1256
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?
Problem
os-me-extractcrashed on its first session.ReplyShapesends the model a bare JSON blob with no instruction, nochoicekey and no list of allowed choices.HeadlessClauderunsJSON.parseon the free-text reply. The model replied**none**, and the parse error killed the run:Two more defects sit on the same path.
MomentExtractor#runmarks sessions read only after the whole loop, so a crash after some appends makes a rerun duplicate those moments.MomentExtractor.buildsets no model, so the CLI default runs instead of Haiku (docs/decision-system/decision-model.md:50).Approach
Required work:
Questioncarriesoptions;ReplyShapesets the four shapes as options and puts an instruction before the memo and reply. check: presentoptionsinplugins/os-me/lib/os_me/decision_model/question.rbHeadlessRunnerpasses--json-schema(one requiredchoicekey, enum of the options), a system prompt, and--setting-sources '', followingplugins/os-adr/lib/adr/judge/claude_command.rb. check: present--json-schemainplugins/os-me/lib/**/*.rbHeadlessClaudereadsstructured_output, validateschoiceagainst the options, and raisesDecisionModel::UnreadableAnswerwith the raw text otherwise. check: presentUnreadableAnswerinplugins/os-me/lib/**/*.rbMomentExtractormarks each session read right after its moments are appended.MomentExtractor.buildpasses the Haiku model toHeadlessClaude. check: presenthaikuinplugins/os-me/lib/os_me/moment_extractor.rbAcceptance criteria
ReplyShapeclassifies a pair, then the prompt holds an instruction and all four options.--json-schemawith the four-value enum and--setting-sources.structured_output{"choice":"modify"}, whenHeadlessClaudeis called, then the answer choice ismodify.**none**and nostructured_output, whenHeadlessClaudeis called, then it raisesUnreadableAnswerthat carries the text.HeadlessClaudeis called, then it raisesUnreadableAnswer.UnreadableAnswer, whenMomentExtractorruns, then the cursor marks the first session read and not the second.MomentExtractor.build, when it builds the adapter, then the adapter uses the Haiku model.Owner sketch
Blocks: #1245 (S3 needs the extracted moments). Found while running the #1244 orchestrator step.
Origin
plugins/os-me/lib/os_me/decision_model/headless_claude.rb:14,plugins/os-me/lib/os_me/reply_shape.rb:70,plugins/os-me/lib/os_me/moment_extractor.rb:27-33VERDICT: CREATE
Work started on branch ticket-1256 (worktree). Found during the #1244 orchestrator extraction run.
Run 122 failed at test-reviewer (verdict:error, brief test_changes null): the orchestrator session cwd was the main checkout at dispatch time, so the brief diffed the wrong tree. Red tests from run 122 are in the worktree. Reopening with the session inside the worktree.
Hook note (ticket-skeptic DROP): implementation 121 stalled in await_completion after a fast-batch finding-builder and a SendMessage resume were dispatched while it was open. That was an out-of-policy, hand-orchestrated run; no hook source was read to prove the SubagentStart hook records foreign dispatches. Workaround used: no other Agent dispatch while an implementation is open.
Resolution
Done: HeadlessClaude asks through --json-schema with an enum of Question#options and reads structured_output; any other reply raises UnreadableAnswer. ReplyShape sends an instruction plus the four options. MomentExtractor marks each session read after its moments are appended, runs ReplyShape on Haiku, and stamps the labeler model on each moment. Hand-finished after escalation 65 (two pre-ticket tests pinned the free-text parse; fixed their fakes).
Evidence: Commits
76ce0addand4d6508d7on ticket-1256. ruby plugins/os-me/test/all.rb: 160 runs, 0 failures. rubocop plugins/os-me: no offenses. Design audit (opus): F1-F5 fixed, F6 kept (require 'time' load fix), F7 kept (only test that pins the question text reaching the runner).Follow-ups: none