feat: show full escalation context before the operator decides - #3
Merged
Conversation
When the host (Claude Code) prompted the operator to decide an escalated deadlock, it showed only the bare operator_question — not the finding — so the operator decided without the context (claim, evidence, both positions) that resolved items DO get in `report show`. - New `impasse_report.py escalations <reconciliation.json>` renders ONLY the still-open deadlocks in full, reusing `_render_finding` for parity with `show`: claim, anchored evidence, both positions, deadlock kind, and the operator_question. - SKILL.md step 5 now requires the host to render + paste that full context BEFORE invoking AskUserQuestion. The command GUARANTEES full context or refuses: `_escalation_problems` is a total validator, and the CLI exits 2 (diagnostic on stderr, nothing on stdout) unless it can show, for every deadlock, the finding's claim + real anchored evidence (so the reviewer-response must be recorded under this review_id), both positions (item- or escalation-level), and a non-blank operator_question. It also rejects unrecognized/typo'd states (which would silently hide an escalation), duplicate finding_ids, and a reviewer-response whose own review_id doesn't match. Hardening surfaced by three cross-provider Impasse review rounds (18 findings, all verified + fixed): the shared render helpers now degrade rather than crash on untrusted reviewer data (non-dict evidence/anchor/ external_source, unhashable severity/state/result), required text is judged AFTER _clean (a control-char-only value counts as blank), and the whole load+validate+render runs inside one exception boundary. Tests: 33 escalations assertions (full-context render, only-deadlocks filter incl. resolved-but-escalated exclusion, positions-in-escalation, every refusal branch, totality on malformed input, CLI exit codes + stderr/no-stdout). 330 tests pass; ruff + schema gates green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X8XaW2bqgYnp7oRVgfHXid
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When the host prompts the operator to decide an escalated deadlock, it showed only the bare
operator_question— not the finding. So the operator decided without the context (claim, evidence, both positions) that resolved items already get viareport show. (Reported from real use.)Change
impasse_report.py escalations <reconciliation.json>renders only the still-open deadlocks in full, reusing_render_findingfor parity withshow: claim, anchored evidence, both positions, deadlock kind, and theoperator_question.AskUserQuestion.Guarantee: full context or refuse
_escalation_problemsis a total validator; the CLI exits 2 (diagnostic on stderr, nothing on stdout) unless it can show, for every deadlock, the finding's claim + real anchored evidence (so the reviewer-response must be recorded under thisreview_id), both positions (item- or escalation-level), and a non-blankoperator_question. It also rejects unrecognized/typo'd states (which would silently hide an escalation), duplicatefinding_ids, and a reviewer-response whose ownreview_iddoesn't match.Reviewed cross-provider (dogfood) — 3 rounds, 18 findings, all fixed
strip()but rendered blank. Made the validator total + comprehensive.state/severitycould crash. Tightened evidence to require real anchored content; made lookups crash-safe.Scope note: stopped after round 3 — the remaining tail is exotic malformed/hostile-input cases already contained by the CLI exit-2 boundary; diminishing returns, not a clean bill.
Verification
🤖 Generated with Claude Code