Skip to content

fix: seal failed P1 canary evidence - #289

Merged
ictechgy merged 2 commits into
mainfrom
fix/p1-failed-canary-decision
Aug 9, 2026
Merged

fix: seal failed P1 canary evidence#289
ictechgy merged 2 commits into
mainfrom
fix/p1-failed-canary-decision

Conversation

@ictechgy

@ictechgy ictechgy commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Outcome

A terminal failed P1 canary now emits the promised ledger-bound P1-X decision instead of refusing analysis with exit 2. The failed root remains permanently closed and no provider identity is replayed.

Live checkpoint

  • Exact candidate 2489f99 completed prepare.
  • First legacy_trim canary terminated because Claude CLI was not logged in.
  • Provider API duration, input/output tokens, and cost were all zero.
  • Second canary and all analytic identities were not launched.
  • One of 218 authorized identities is accounted; a fresh full run needs separate authorization for a total ceiling of at least 219.

Verification

  • TDD regression for failed terminal canary to P1-X
  • v2 suite: 39/39
  • Stage2/Receipt boundary: 18/18
  • offline v2 rehearsal: 122 fake processes, no provider/network
  • full non-TTY prepublish: 1561 tests, 3 skips, OK
  • Gate-B rollback proof: status ok at exact commit
  • canonical/plugin mirror: synchronized

npm next/latest are not authorized or invoked.

Summary by CodeRabbit

  • Bug Fixes

    • Failed terminal canaries are now detected and classified as invalid decisions.
    • Invalid-decision records identify affected canaries and preserve bounded failure evidence.
    • Failed canaries now prevent further provider calls and study-report creation.
  • Documentation

    • Updated release-readiness materials with current canary results, verification status, and remaining authorization requirements.
    • Clarified that P1 and subsequent phases remain blocked until sufficient identity capacity is available.
  • Tests

    • Added coverage confirming correct handling and reporting of failed canaries.

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The v2 benchmark detects failed terminal canaries, emits bounded invalid-decision evidence, identifies affected canaries, validates ledger integrity, and updates protected-surface hashes and readiness records.

Changes

Failed canary evidence

Layer / File(s) Summary
Detect and report failed canaries
context-guard-kit/benchmark_runner.py, plugins/context-guard/bin/context-guard-bench
The v2 invalid-decision logic detects terminal canary records with passed not equal to True. It records the applicable stop reason and failed canary identities.
Validate failed-canary analysis
tests/test_benchmark_study_v2.py
The end-to-end test verifies canary and resume failure behavior, the canonical P1-X decision, failed identity metadata, ledger bindings, and the absence of additional provider calls.
Refresh protected surfaces and readiness records
packages/context-guard-receipt/..., tests/test_contextguard_stage2_*.py, research/*.md
Protected-surface hashes and readiness documents reflect the updated implementation, candidate status, failed canary checkpoint, and authorization requirements.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CanaryProcess
  participant Analyze
  participant InvalidDecision
  participant CanaryLedger
  CanaryProcess->>Analyze: terminal canary state
  Analyze->>InvalidDecision: evaluate canary evidence
  InvalidDecision->>CanaryLedger: preserve ledger state
  InvalidDecision-->>Analyze: P1-X stop reason and failed identities
  Analyze-->>CanaryProcess: no replay or further provider calls
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: sealing evidence for failed P1 canaries.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/p1-failed-canary-decision

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/test_benchmark_study_v2.py (2)

611-613: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Test permanent closure after a failed canary.

The test proves that analyze adds no provider calls. It does not prove that a later resume or run cannot launch another identity. Invoke resume immediately after the failed canary and assert refusal plus unchanged ledger and provider-log bytes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_benchmark_study_v2.py` around lines 611 - 613, Extend the
failed-canary test around the existing analyze assertions to invoke resume
immediately afterward and assert that it refuses to proceed. Verify that both
the ledger bytes and provider_log bytes remain unchanged after the refused
resume, preserving the existing no-provider-call checks.

567-610: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Assert the complete P1-X payload contract.

The test name promises a P1-X decision, but the assertions check only stop_reason. Assert decision == "P1-X", descriptive_only is True, claim_allowed is False, claim is None, the schema version, and the attempts-ledger hash.

Proposed assertions
             canary_path = output_root / "canary-events.jsonl"
             canary_raw = canary_path.read_bytes()
+            attempts_path = output_root / "attempts.jsonl"
+            attempts_raw = attempts_path.read_bytes()
             provider_log = output_root / "fake-cli-calls.jsonl"
             provider_calls_before = provider_log.read_bytes()

             completed = subprocess.run(
...
             self.assertEqual(
                 decision_raw, self.runner._study_canonical_json_bytes(decision),
             )
+            self.assertEqual(
+                decision["schema_version"],
+                "contextguard.bench.study-invalid-decision.v1",
+            )
+            self.assertEqual(decision["decision"], "P1-X")
+            self.assertTrue(decision["descriptive_only"])
+            self.assertFalse(decision["claim_allowed"])
+            self.assertIsNone(decision["claim"])
...
+            self.assertEqual(
+                decision["ledgers"]["attempts"]["sha256"],
+                hashlib.sha256(attempts_raw).hexdigest(),
+            )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_benchmark_study_v2.py` around lines 567 - 610, Extend the decision
assertions in the analyze test after loading decision to validate the full P1-X
payload: assert the decision value, descriptive_only, claim_allowed, and claim
fields, along with the expected schema version and the attempts ledger SHA-256.
Reuse the existing canonical decision and ledger data, keeping the current
stop_reason and canary assertions unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@research/p1-live-authorization-packet.md`:
- Around line 27-30: Update the later P1-X execution rule to recognize both
stopped ambiguous roots and failed terminal canary evidence as valid P1-X
outcomes. Preserve the existing rule while adding the newly introduced
failed_canary_terminal_evidence case.

---

Nitpick comments:
In `@tests/test_benchmark_study_v2.py`:
- Around line 611-613: Extend the failed-canary test around the existing analyze
assertions to invoke resume immediately afterward and assert that it refuses to
proceed. Verify that both the ledger bytes and provider_log bytes remain
unchanged after the refused resume, preserving the existing no-provider-call
checks.
- Around line 567-610: Extend the decision assertions in the analyze test after
loading decision to validate the full P1-X payload: assert the decision value,
descriptive_only, claim_allowed, and claim fields, along with the expected
schema version and the attempts ledger SHA-256. Reuse the existing canonical
decision and ledger data, keeping the current stop_reason and canary assertions
unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 53fbb253-af01-49aa-b1a9-7be8c90efda3

📥 Commits

Reviewing files that changed from the base of the PR and between 2489f99 and 87e7339.

📒 Files selected for processing (9)
  • context-guard-kit/benchmark_runner.py
  • packages/context-guard-receipt/scripts/verify_protected_surfaces.py
  • packages/context-guard-receipt/tests/contract/test_boundary.py
  • plugins/context-guard/bin/context-guard-bench
  • research/p1-live-authorization-packet.md
  • research/token-savings-roadmap.md
  • tests/test_benchmark_study_v2.py
  • tests/test_contextguard_stage2_feasibility.py
  • tests/test_contextguard_stage2_protected_surfaces.py

Comment thread research/p1-live-authorization-packet.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/test_benchmark_study_v2.py (1)

569-585: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Assert the initial failed-canary evidence.

The test only compares the canary ledger and provider log before and after resume. It does not verify that the initial event is the reported legacy_trim terminal failure, that provider duration, token counts, and cost are zero, or that no second canary ran. Parse the terminal canary records and provider log after the first canary action. Assert those conditions explicitly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_benchmark_study_v2.py` around lines 569 - 585, The test around the
initial canary and subsequent resume must validate the failed-canary evidence
before checking resume immutability. Parse the terminal canary records and
provider log immediately after the first canary action, assert the reported
terminal failure is legacy_trim with zero provider duration, token counts, and
cost, and verify exactly one canary ran; retain the existing assertions that
resume does not alter the canary ledger, attempts file, or provider log.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/test_benchmark_study_v2.py`:
- Around line 569-585: The test around the initial canary and subsequent resume
must validate the failed-canary evidence before checking resume immutability.
Parse the terminal canary records and provider log immediately after the first
canary action, assert the reported terminal failure is legacy_trim with zero
provider duration, token counts, and cost, and verify exactly one canary ran;
retain the existing assertions that resume does not alter the canary ledger,
attempts file, or provider log.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c360ddb9-b801-4cdd-8bbf-3206d9a6bb9f

📥 Commits

Reviewing files that changed from the base of the PR and between 87e7339 and 3c44f07.

📒 Files selected for processing (2)
  • research/p1-live-authorization-packet.md
  • tests/test_benchmark_study_v2.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • research/p1-live-authorization-packet.md

@ictechgy
ictechgy merged commit 6bde86b into main Aug 9, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant