Skip to content

fix: close P1 v8 source and spend stop paths - #300

Merged
ictechgy merged 2 commits into
mainfrom
fix/p1-v8-source-spend-closure
Aug 11, 2026
Merged

fix: close P1 v8 source and spend stop paths#300
ictechgy merged 2 commits into
mainfrom
fix/p1-v8-source-spend-closure

Conversation

@ictechgy

@ictechgy ictechgy commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • bind live v2 prepare to the approved source commit and credential-free retained-ref resolution
  • treat error_max_budget_usd as a hard spend stop and persist verifiable P1-X decisions automatically
  • version the manifest contract, update offline rehearsal, protected hashes, tests, and roadmap

Verification

  • python3 -m unittest -v tests.test_benchmark_study_v2 (51 passed)
  • Receipt contract discovery (595 passed, 1 skipped)
  • benchmark surfaces + npm candidates (183 passed)
  • Stage2/Receipt boundary focused suites (18 passed)
  • package check, protected surfaces, mirror sync, Gate-B, py_compile, diff check
  • full prepublish reached 1599 tests with one unrelated process-timing failure; the exact test passed 3/3 and the complete 595-test Receipt suite then passed

Summary by CodeRabbit

  • New Features

    • Added approved source-commit and retained-reference validation for benchmark studies.
    • Added offline rehearsal mode with explicit unverified-source status.
    • Advanced the study manifest format to version 6.
    • Added clearer handling for retryable versus terminal budget failures.
  • Bug Fixes

    • Prevented further provider execution after terminal failures.
    • Preserved invalid-decision reports when canary, run, or resume actions are refused.
    • Improved consistency checks across candidate and executable study records.
    • Added conflict detection for repeated analysis results.
  • Documentation

    • Updated live authorization and measurement guidance for commit validation and failure handling.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 339b2162-9d09-4b6d-b903-59c3c0eac5a8

📥 Commits

Reviewing files that changed from the base of the PR and between 504aa13 and 492455f.

📒 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
🚧 Files skipped from review as they are similar to previous changes (9)
  • tests/test_contextguard_stage2_protected_surfaces.py
  • packages/context-guard-receipt/scripts/verify_protected_surfaces.py
  • tests/test_contextguard_stage2_feasibility.py
  • packages/context-guard-receipt/tests/contract/test_boundary.py
  • research/p1-live-authorization-packet.md
  • research/token-savings-roadmap.md
  • tests/test_benchmark_study_v2.py
  • plugins/context-guard/bin/context-guard-bench
  • context-guard-kit/benchmark_runner.py

📝 Walkthrough

Walkthrough

The executable v2 benchmark now binds studies to an approved source commit, validates retained Git references, supports offline rehearsal, advances the manifest schema to v6, classifies budget failures as terminal, and persists canonical invalid-decision evidence after lifecycle refusals.

Changes

Benchmark v2 hardening

Layer / File(s) Summary
Approved source binding and preparation
context-guard-kit/benchmark_runner.py, plugins/context-guard/bin/context-guard-bench, tests/test_benchmark_study_v2.py
Candidate and executable manifests require matching approved commits. Live preparation verifies retained refs with bounded credential-free git ls-remote. Offline rehearsal records an unverified source binding.
Terminal failure and evidence persistence
context-guard-kit/benchmark_runner.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
The manifest advances to v6. Budget exhaustion is no longer retryable. Analysis and invalid-decision reports use canonical idempotent persistence.
CLI and rehearsal contract
context-guard-kit/benchmark_runner.py, plugins/context-guard/bin/context-guard-bench, scripts/rehearse_measurement_study.py, research/p1-live-authorization-packet.md, research/token-savings-roadmap.md, tests/test_benchmark_study_v2.py
CLI options validate approved commits, retained refs, and prepare-only offline rehearsal. The rehearsal tool emits the configured bounded-failure subtype.
Protected-surface integrity updates
packages/context-guard-receipt/scripts/verify_protected_surfaces.py, packages/context-guard-receipt/tests/contract/test_boundary.py, tests/test_contextguard_stage2_feasibility.py, tests/test_contextguard_stage2_protected_surfaces.py
Frozen hashes and receipt inventory expectations are updated for the changed protected surfaces.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant context_guard_bench
  participant GitHub
  participant StudyManifest
  Operator->>context_guard_bench: prepare with approved commit and retained ref
  context_guard_bench->>GitHub: resolve retained ref with git ls-remote
  GitHub-->>context_guard_bench: commit for retained ref
  context_guard_bench->>StudyManifest: validate candidate and source binding
  StudyManifest-->>context_guard_bench: validated v6 executable manifest
  context_guard_bench-->>Operator: prepared study or refusal
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 summarizes the primary changes: closing P1 v8 source-binding and spending-stop paths.
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-v8-source-spend-closure

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.

🧹 Nitpick comments (4)
context-guard-kit/benchmark_runner.py (2)

14066-14083: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Narrow the swallowed exception surface or record the suppression.

_benchmark_study_v2_persist_invalid_after_refusal discards OSError, SystemExit, TypeError, and ValueError without any trace. The original refusal message stays authoritative, which is correct. However, the operator receives no signal that canonical P1-X persistence was attempted and failed. In this workflow the missing decision file is itself evidence.

Print a short, non-sensitive note to stderr before returning.

♻️ Proposed refactor
-    except (OSError, SystemExit, TypeError, ValueError):
+    except (OSError, SystemExit, TypeError, ValueError) as exc:
         # The original refusal remains authoritative when damaged or incomplete
         # evidence cannot safely support a canonical P1-X decision.
+        print(
+            f"v2 invalid-decision persistence skipped: {exc}", file=sys.stderr,
+        )
         return
🤖 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 `@context-guard-kit/benchmark_runner.py` around lines 14066 - 14083, Update
_benchmark_study_v2_persist_invalid_after_refusal to emit a short, non-sensitive
diagnostic to stderr inside the existing exception handler before returning,
while preserving the original refusal authority and current exception handling
behavior.

12162-12164: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider resolving git instead of hardcoding /usr/bin/git.

The verifier fails closed when /usr/bin/git is absent. Several environments install Git at /opt/homebrew/bin/git, /usr/local/bin/git, or a Nix store path. Live prepare then refuses with "v2 retained ref verifier is unavailable" even though Git is present and usable.

A bounded lookup over a fixed allowlist of absolute paths keeps the no-PATH-trust property and removes the environment dependency.

♻️ Proposed refactor
-    git = Path("/usr/bin/git")
-    if not git.is_file() or not os.access(git, os.X_OK):
-        raise ValueError("v2 retained ref verifier is unavailable")
+    git = next(
+        (
+            candidate
+            for candidate in (
+                Path("/usr/bin/git"),
+                Path("/usr/local/bin/git"),
+                Path("/opt/homebrew/bin/git"),
+            )
+            if candidate.is_file() and os.access(candidate, os.X_OK)
+        ),
+        None,
+    )
+    if git is None:
+        raise ValueError("v2 retained ref verifier is unavailable")
🤖 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 `@context-guard-kit/benchmark_runner.py` around lines 12162 - 12164, Update the
Git validation in the v2 retained ref verifier to resolve an executable from a
bounded allowlist of approved absolute paths, including common Homebrew, system,
and Nix locations, instead of checking only /usr/bin/git. Reuse the resolved
executable for subsequent verifier operations while preserving the existing
fail-closed “v2 retained ref verifier is unavailable” behavior when no allowed
path is usable.
research/p1-live-authorization-packet.md (1)

227-232: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the --study-v2-offline-rehearsal boundary in both contracts. Both documents now require an approved source commit and a retained ref verified by a bounded credential-free git ls-remote. Neither document mentions the new --study-v2-offline-rehearsal flag, which skips that verification and records an offline-rehearsal-unverified-v1 binding. An operator reading either document cannot tell that a rehearsal-prepared root is not eligible for live work.

  • research/p1-live-authorization-packet.md#L227-L232: state in step 2 that live prepare must never pass --study-v2-offline-rehearsal, and that a root prepared with that flag is rehearsal-only.
  • research/token-savings-roadmap.md#L387-L392: add the same restriction to ordered item 2, next to the --study-v2-source-commit and --study-v2-retained-ref requirements.
🤖 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 `@research/p1-live-authorization-packet.md` around lines 227 - 232, Update step
2 in research/p1-live-authorization-packet.md (lines 227-232) to state that live
prepare must never use --study-v2-offline-rehearsal and that roots prepared with
it are rehearsal-only; add the same restriction to ordered item 2 in
research/token-savings-roadmap.md (lines 387-392), alongside the source-commit
and retained-ref requirements.
tests/test_benchmark_study_v2.py (1)

477-518: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Assert the Git argv and environment in the retained-ref test.

The test mocks run_bounded_command and checks only the return value and the mismatch refusal. It does not check the command that the verifier builds. The credential-free properties are the security-relevant part of _benchmark_study_v2_verify_retained_ref: the fixed repository URL, --exit-code, --refs, the empty credential.helper and core.askPass settings, and GIT_TERMINAL_PROMPT=0. A regression that drops one of them keeps this test green.

Capture the mock call and assert those values.

💚 Proposed test addition
         with mock.patch.object(
             self.runner, "run_bounded_command", return_value=completed,
-        ):
+        ) as bounded:
             self.assertEqual(
                 helper(retained_ref, expected_commit),
                 {
                     "commit_sha": expected_commit,
                     "ref": retained_ref,
                     "repository": "ictechgy/context-guard",
                     "verification": "git-ls-remote-v1",
                 },
             )
+        argv, keyword = bounded.call_args
+        command = argv[0]
+        self.assertEqual(command[-3:], [
+            "--refs",
+            "https://github.com/ictechgy/context-guard.git",
+            retained_ref,
+        ])
+        self.assertIn("credential.helper=", command)
+        self.assertIn("core.askPass=", command)
+        self.assertIn("--exit-code", command)
+        self.assertEqual(keyword["env"]["GIT_TERMINAL_PROMPT"], "0")
+        self.assertEqual(keyword["env"]["GIT_CONFIG_NOSYSTEM"], "1")
🤖 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 477 - 518, Update
test_v2_retained_ref_requires_exact_remote_resolution to capture the
run_bounded_command mock call and assert the verifier invokes the fixed
repository URL with --exit-code and --refs, includes empty credential.helper and
core.askPass settings, and sets GIT_TERMINAL_PROMPT=0 in the environment. Apply
these assertions to the retained-ref verification call while preserving the
existing success and mismatch checks.
🤖 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 `@context-guard-kit/benchmark_runner.py`:
- Around line 14066-14083: Update
_benchmark_study_v2_persist_invalid_after_refusal to emit a short, non-sensitive
diagnostic to stderr inside the existing exception handler before returning,
while preserving the original refusal authority and current exception handling
behavior.
- Around line 12162-12164: Update the Git validation in the v2 retained ref
verifier to resolve an executable from a bounded allowlist of approved absolute
paths, including common Homebrew, system, and Nix locations, instead of checking
only /usr/bin/git. Reuse the resolved executable for subsequent verifier
operations while preserving the existing fail-closed “v2 retained ref verifier
is unavailable” behavior when no allowed path is usable.

In `@research/p1-live-authorization-packet.md`:
- Around line 227-232: Update step 2 in research/p1-live-authorization-packet.md
(lines 227-232) to state that live prepare must never use
--study-v2-offline-rehearsal and that roots prepared with it are rehearsal-only;
add the same restriction to ordered item 2 in research/token-savings-roadmap.md
(lines 387-392), alongside the source-commit and retained-ref requirements.

In `@tests/test_benchmark_study_v2.py`:
- Around line 477-518: Update
test_v2_retained_ref_requires_exact_remote_resolution to capture the
run_bounded_command mock call and assert the verifier invokes the fixed
repository URL with --exit-code and --refs, includes empty credential.helper and
core.askPass settings, and sets GIT_TERMINAL_PROMPT=0 in the environment. Apply
these assertions to the retained-ref verification call while preserving the
existing success and mismatch checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1e2b25ed-4618-4c82-a1c1-57f738633de5

📥 Commits

Reviewing files that changed from the base of the PR and between 538cc56 and 504aa13.

📒 Files selected for processing (10)
  • 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
  • scripts/rehearse_measurement_study.py
  • tests/test_benchmark_study_v2.py
  • tests/test_contextguard_stage2_feasibility.py
  • tests/test_contextguard_stage2_protected_surfaces.py

@ictechgy
ictechgy merged commit fb2e177 into main Aug 11, 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