Skip to content

feat: activate progressive context and freeze provider-free G1-G6 - #302

Merged
ictechgy merged 9 commits into
mainfrom
feature/explicit-progressive-context
Aug 12, 2026
Merged

feat: activate progressive context and freeze provider-free G1-G6#302
ictechgy merged 9 commits into
mainfrom
feature/explicit-progressive-context

Conversation

@ictechgy

@ictechgy ictechgy commented Aug 12, 2026

Copy link
Copy Markdown
Owner

Summary

  • activate explicit progressive-context mechanisms with independently gated adaptive-k pruning and symbol-memory graph expansion
  • record the corrected synthetic benchmark while keeping provider-token and savings conclusions explicitly inconclusive
  • freeze the provider-free G1–G6 roadmap: immutable evidence, four-arm corpus, deterministic rehearsal, honest claim gates, supported-observer preregistration, and a structurally non-authorizing prepared_unapproved packet
  • preserve exact fallback, hidden-oracle separation, captured-byte execution, freeze inventories, and deny-by-default authority boundaries

Verification

  • python3 scripts/prepublish_check.py — 1,638 tests passed, 4 skipped
  • python3 scripts/verify_gate_b_rollback.py --jsonstatus=ok, source_head=7a64032
  • env -i LANG=C.UTF-8 PATH=/opt/homebrew/bin:/usr/bin:/bin python3 -I -B scripts/verify_g4_provider_free.py — G1 inventory and G2–G6 authenticated profiles passed
  • direct provider-free suites: G2 45, G3 29 (1 expected skip), G4 15, G5 34, G6 19
  • independent final review found no P0/P1/P2 findings

Safety and claim boundary

This change does not authorize or perform provider calls, network access, credential access, runtime activation, npm publication, or a token-savings claim. G6 remains prepared_unapproved: every executable selection is blocking/unselected and integrity success grants no execution authority.

Summary by CodeRabbit

  • New Features
    • Added opt-in adaptive pruning and symbol-memory options for automatic context packing.
    • Context packing preserves explicit sources, includes relevant import neighbors, and excludes sensitive paths.
    • Receipt companion MCP now supports context storage, exact-range reads, task-scoped cleanup, diagnostics, and advisory inspection.
    • Added optional persistent state support for MCP.
  • Documentation
    • Expanded usage examples, safety guidance, roadmap status, and benchmark limitations.
  • Tests
    • Added comprehensive integrity, isolation, security, and verification coverage.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

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: eb21d70d-1254-4e49-bd0c-e3af7755499e

📥 Commits

Reviewing files that changed from the base of the PR and between 202f0c0 and 1af1872.

📒 Files selected for processing (2)
  • packages/context-guard-receipt/tests/contract/test_g008_runner.py
  • tests/test_contextguard_stage2_feasibility.py

📝 Walkthrough

<hidden_new_layer>
<cohort_id>contextguard_features</cohort_id>
<insert_after_layer_id>feature_implementation</insert_after_layer_id>

The provider-free roadmap adds contracts, schemas, fixtures, verifiers, freeze locks, isolated execution profiles, authenticated artifact checks, and regression tests. range_712913abc246 range_5a65daac9129 range_5c9596c6fade range_104a2a1a5710 range_4a6d256a6656 range_d51fcebb55d4 range_9ffcd8481efe range_3815a5237e4f range_c0fc1de4c241 range_26c58f1e2f2b range_418f7c04d587 range_ea2e1b038952 range_1baea26e51dd range_d607ad7a4e1c range_77af87bfc8bd range_a1c262a01854 range_0296212fdcad range_a642f0e8a96f range_22ea64399163 range_f31b7cd8d70b range_4e2ccc14d3d9 range_3c21ef0ebdfe range_3d4a2cd68445 range_de03bc576fad range_facde39ab2da range_7dd69867f56c range_92e5a17dd305 range_a476e11fac2c range_e524c1339d94 range_bd91209618a5 range_8356903ec555 range_38684d3dcc16 range_821f4f37ecb1 range_d6dc985cea9d range_6e0695da7959 range_d8f61523e172 range_9c47b7415588 range_748b65cca487 range_b3f7792aa76d range_bb4fc85d7306 range_f9b9e4922d0d range_ece85e3b0544 range_85e395e53753 range_a807969ed8e8 range_1b53131abda5 range_1bb934af43fc range_8fecf3d324e6 range_bf3d3ec72ea8 range_134c9ba18405 range_c703bfc39769 range_8a02867264a3 range_b9d795a56733 range_3bf763b59fc1 range_bf96ccb4a277 range_d63b7ef2c7fc range_9fc45c25bfda range_32962c99d33f range_d9aefe22cfb6 range_b236be9dcd5a range_4f622f52b7be range_7f5779bd65d0 range_cd6c8287ec49 range_efd2f20418df range_1259de8888fa range_81dadd6915c9 range_5797c04ab308 range_1f47d69c9f9f range_52970ad5dcf3 range_e49d335f2a95 range_7d0cf7b78cc3 range_53794167a837 range_18365ee76e02 range_ff3ceb5ddb88 range_41b93f505641 range_5be3a4fe0c9a range_e38ff4bf4ee8 range_68b07ac25ea1 range_66041c5d9e63 range_0f0d8ce5557b range_1a93769e299c range_15dbe94b9166 range_c135e7a32ca4 range_1c39dda907ad range_8b5f1d10a8a6 range_37c8cef90335 range_fc9a5ed88977 range_acec036a2afc range_b2e229a2f415 range_0b85f4d54ebe range_b91ccd4b8538 range_fb0fb756d5ff range_83298779ee4c range_c6de9c173455 range_9ef0dd52f5b8 range_9d94d833e09a range_1387c362b0f7 range_92684b80db2f range_44acc33e365c range_7badeb0e7776 range_f3b882469c40 range_eef1af9bdb92 range_458093dde72a range_e5bbb4f32e4f range_05a685fdbd81 range_1fe12734f631 range_1e4a3fa9ef64 range_0d26351f7cef range_d5a237b73dd8 range_a3c03472ef18 range_f25f556c5621 range_8612140634b3 range_67dd34b435e0 range_543c1997bf17 range_e6558fe3a216 range_cb692b22946a range_984b4f725ba6 range_0bf67f006274 range_c8591dd20eb7 range_749c644dd8a9 range_dbae1a2047be range_557f795ac9e3 range_72673172c525 range_cf0d206cedd6 range_bff16bdf25f6 range_119356105bcf range_e4b8aebcf373 range_a609e2319ef1 range_9306783a36d0 range_9eb0ae1ddf73 range_1ea33005dce6 range_8de01098a62e range_e621c0c155aa range_336d316236ba range_a04617656c74 range_958e99cb2b79 range_6cd7880200fe range_ae56003a2e03 range_2e8e6e17a09e range_6344d44d6666 range_2de7018362df range_f2a5d91bf5f1 range_218f55765fb9 range_3b11085fd9fe range_52e7bd0a9586 range_9507626ea2d2 range_4c8c4b345324 range_29928f3a1728 range_fbfb882dfe28 range_c1d0dab066d8 range_353819553ced range_cbc1d91b994b range_aafcc5c27011 range_170cd7d168e0 range_e26786d36a54 range_dde5bf3acb0c range_9d55226b19aa range_bf208b4296aa range_d54f4e8a81cf range_c5c1691289c3 range_4b1b44d58292 range_77d1846ca76d range_54a4965efc71 range_f773cdcdf826 range_80917dc8e5d3 range_9270dbf54c06 range_0852eda1c9b2 range_6be3b8466725 range_6e7df787495d range_12ab90d4eba8 range_443f991862fc range_beb44e2c0349 range_01c21998c51c range_fc180c17c9cd range_6e0695799dc5 range_226ad6b69432 range_0b40b1b4dfb2 range_07c5376bac6b range_262ce0da84fc range_a3171727ce8c range_0eb2a2e729ed range_75cce98d540c range_ae43b8dd578a range_96928e38076b range_c0d69e328aca range_57ea714c8658 range_44349c8b6973 range_0bc35b2d28e5 range_56ef48d85119 range_832dc82e58b4 range_3a64f2636910 range_8f3867c37d45 range_42d5e809075d range_9c66470be126 range_70d3a651950b range_f885a43cea27 range_46f43bbcf4e8 range_4cfb1d32f658 range_dcb9ed59f05d range_00480d5dc287 range_c4cc4761df11 range_4ef44c83ee70 range_177b275fdd5c range_d0b1b9ffbb97 range_a26cce5f5961 range_d3084314bd85 range_a06e8b11f84c range_5e61572baddb range_c00b0d6c3640 range_b3b916cc2c26 range_34dd82b3da26 range_96a9b2a69d26 range_167573331e79 range_cdf8963543c1 range_272f908475ef range_2c2bba5dc256 range_47163aea52b0 range_958d5be8caf4 range_6658878af0a3 range_c3890e9abcdd range_944f8fd0b181 range_b835c918ff16 range_b7a08098cdcc range_f61edb34eb45 range_1f00d3444b1b range_1ef7b08f315e range_f72f1d1d3a46 range_048f322606bd range_9f893baa7125 range_c075b6042d9f range_745fad83c9db range_a46923d85bbb range_e13421ba9adf range_5764e21e5084 range_48cdb43ff9e5 range_6270e5c92d75 range_ba64334ba9f5 range_f981c2009555 range_74c733021672 range_3ca20619ab6c range_5158cc138a53 range_a8ab0c590e45 range_a894e06c9213 range_216a4782a36f range_f4288ee6a497 range_3d49eb42f8b1 range_dfc1721f4c61 range_f016ecb8a29e range_5ea22615cbd9 range_f3ee7395d9a4 range_eb676ab8b9fc range_195e7366ffa3 range_bea0f5a0fbd5 range_2bfb85af9b00 range_93686da94ff3 range_476daa6d4072 range_675919f92fd6 range_5230d0f187ec range_f206cf649c54 range_1955b30b43da range_d3005841e0e2 range_fc78e12f1d7c range_9d880a712197 range_d83057121bd0 range_6d86879daad9 range_f59bdedb46fa range_8edef6b7af63 range_b5603011ada1 range_cde7f128bcb1 range_add8ce9f87e0 range_f6b435fa35b4 range_b558c23d6787 range_705573866bb9 range_44b2e0a52cc1 range_f1832a022791 range_57c9df595052 range_2b40a213c611 range_dacbb76f56c2 range_972e4631f1ec range_6b51d14a8b58 range_65f27f74c8a6 range_49d57c3c35a5 range_421839c158a1 range_27c10b051b4b range_9f946eb2690d range_2734d9ad98eb range_d701555556c1 range_d430d47930f7 range_57c3efe799f6 range_bccec145d110 range_58edc15328a6 range_b783591a11fc range_ec160f0817dc range_57c2de0c5b24 range_a5a73ee33ca4 range_6286ec14f511 range_ea8c7a4ec111 range_9687184109b1 range_6300dd3147e0 range_124670af692e range_15a57e8bbf0a range_cb153ba73c55 range_3765999c0526 range_8e8ebf1da0b5 range_c5df1883711c range_5851724a1a18 range_b1d5f77c0047 range_1220cbff5397 range_e484f115ada2 range_00e92d638529 range_de515bb0c63e range_16945bdc3a67 range_944ba1c8ecb9 range_03b6396289e8 range_e0d8a4b79c8a range_d355e5dc59f5 range_8560df8683cb range_1316b544fecc range_4bec3ed18faa range_8a9ad47989ed range_03337db934f2 range_e96400919c45 range_42f6ba451c52 range_112a7e097092 range_190fb5084875 range_efe3eaccddf4 range_71133398d009 range_58eced6df483 range_371d49dd5ddf range_3656772e50b3 range_1e10c5995303 range_c95766ccbe76 range_2478068f1584 range_8f76369ba165 range_f9b1e9a79044 range_0e9e2a7507ef range_23aeb7e36267 range_41a8b47b9442 range_1a3fca3a4e65 range_f43cd2722206 range_5e0bb0d1db71 range_150d6f210bcf range_1cb013c3c90f range_ce5b4d7fefed range_3285b1b8ff84 range_f410714ff6be range_526dddd3e447 range_652d9002d226 range_974d02236e66 range_dffd4d9e626d range_c6b0a3a08bd7 range_b615574453ac range_9ebc5f01ceea range_9c3acc5ff06e range_4b4d03d7dbfc range_30943f5d1cae range_9fb704ad33fd range_7ffc5de554a7 range_fbe1d8bb5649 range_6af91a800222 range_519b942f465e range_547cfbcdda3d range_f8020dcf9536 range_6b828a14453f range_3077a03cba4c range_80591abccd1e range_51ac13fd5a66 range_15ce687fc215 range_652d9cf350ae range_768b55b6325a range_ed839a0797ae range_8ab4421e5dc9 range_1a7ce0f4c00f range_100bb2f6b34c range_81e4d185433d range_6dea923e9c2a range_f684e83f8fe4 range_c48e958d2570 range_d84a7e2c0d76 range_830818b22071 range_c96cc60f570d range_976bbed568a8 range_3081ad91c04b range_e267e21f4dce range_47cee491f8a3 range_7765a8b5e797 range_27ec4b635209 range_1dec75b93e88 range_a31e4f2eaddb range_7d1a51eba334 range_f09ece17ecba range_10d1f54bae1b range_56a70a23a0a3 range_883e6ff87331 range_a4bd984884de range_50534b8d4dab range_88e9c25b6acb range_6edee584cd42 range_aba22f2a50ba range_f4952c7534e7 range_d4e7148362d4 range_f37bb15170aa range_ad4f4c9101e9 range_80ad3c387d0c range_073315020c93 range_88d65d7f1696 range_4c0c21a6955a range_0305a8de8f98 range_993927a1eaff range_f0ccaf6f99b9 range_b075919ba835 range_7f14cb256c3f range_0e5e874fcbb3 range_9ef7881d00ab range_2bc5b272f1bb range_d8a27219e79b range_f3077deea926 range_606b2c54c674 range_8c6444120972 range_4d3a006c3491 range_80ff84791afa range_afbfddf4705d range_d9bc6cf43568 range_f8b141f774a6 range_8a7a7bfdd860 range_22b1d3e7bd31 range_18eeb9c9653f range_ba2af1a5faa3 range_b5602c2aaa8a range_6862abd8f832 range_8e8ab8432eea range_9908df705b37 range_22c9c9011e2b range_a339854fed64 range_45615eb85730 range_7476fc059ebc range_4271fcdd5160 range_a5b04aa40eeb range_0fa033130cf0 range_0865f2b22ce8 range_980694be532b range_68d8e8cd5d42 range_5c0fce16156c range_f9e9631b17e9 range_fcedd90a2da8 range_8d45ee56e28b range_d84e0f279ebc range_4cf998f29a82 range_18d4f24140c6 range_ed38d22f757e range_cadd445a4ce1 range_ab0ad2289278
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.51% 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 two main changes: activating progressive context and freezing the provider-free G1–G6 roadmap.
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 feature/explicit-progressive-context

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: 12

🧹 Nitpick comments (11)
research/provider-free-roadmap/g2/v1/verify.py (2)

275-291: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Cache the pinned interpreter digest.

python_binding reads the whole CPython executable and hashes it. run_captured_packer_child calls it on every child launch, so the verifier hashes the interpreter at least 24 times during one verify_repository run. capture_public_snapshot and _post_capture_drift_check add more calls. A CPython binary is tens of megabytes, so this adds repeated large I/O with no added assurance inside a single run.

Cache the result with functools.cache. The pre-capture and post-capture drift checks still compare the recorded binding against the lock.

♻️ Proposed refactor
+import functools
+
+
+@functools.cache
 def python_binding() -> dict[str, object]:

Return a copy at each call site if any caller mutates the mapping. The current callers only read it and compare it for equality.

Also applies to: 1450-1450

🤖 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/provider-free-roadmap/g2/v1/verify.py` around lines 275 - 291, Cache
the computed interpreter binding in python_binding using functools.cache so the
executable is read and hashed only once per verification run. Preserve the
existing validation and returned mapping, and confirm current callers such as
run_captured_packer_child, capture_public_snapshot, and
_post_capture_drift_check continue to read or compare the cached result without
mutation.

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

Address the two flagged lint findings.

Ruff reports E731 at Line 200 for the identity lambda assignment, and B007 at Line 1230 for the unused loop variable path.

🧹 Proposed cleanup
-        identity = lambda item: (item.st_dev, item.st_ino, item.st_mode, item.st_nlink, item.st_size, item.st_mtime_ns)
+        def identity(item: os.stat_result) -> tuple[int, ...]:
+            return (
+                item.st_dev, item.st_ino, item.st_mode,
+                item.st_nlink, item.st_size, item.st_mtime_ns,
+            )
-    for path, raw in sorted(fixture.items()):
+    for _path, raw in sorted(fixture.items()):

Also applies to: 1230-1230

🤖 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/provider-free-roadmap/g2/v1/verify.py` at line 200, Replace the
identity lambda assignment with a regular function definition to resolve Ruff
E731, preserving the same tuple fields and ordering. In the loop near the
path-processing logic, rename the unused path variable to the conventional
underscore placeholder to resolve Ruff B007 without changing loop behavior.

Source: Linters/SAST tools

tests/test_context_guard_progressive_context.py (1)

117-134: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a text-output assertion for the gate-failed path.

This block already pins the JSON contract for a failed gate. The text renderer is not covered. print_adaptive_k_text reports apply=true whenever adaptive_k_application exists, including this gate_failed case where the manifest does not change. An assertion on the text output would pin the intended value and catch that mismatch.

♻️ Suggested addition
                 self.assertEqual(gated["manifest"], advisory["manifest"])
+
+                text_common = [
+                    item for item in common if item != "--json"
+                ]
+                gated_text = self._run_pack(
+                    script,
+                    root,
+                    *text_common,
+                    "--apply-adaptive-k",
+                    "--adaptive-k-min-precision-proxy",
+                    "1.0",
+                ).stdout
+                self.assertIn("gates=failed", gated_text)
+                self.assertIn("apply=false", gated_text)
🤖 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_context_guard_progressive_context.py` around lines 117 - 134, Add
an assertion in the gate-failed test path covering the text output from
print_adaptive_k_text, verifying it reports apply=false when
adaptive_k_application.status is gate_failed and the manifest remains unchanged.
Keep the existing JSON contract assertions intact.
research/provider-free-roadmap/g3/v1/rehearse.py (2)

876-881: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Guard omitted_source_count type before the comparison.

Line 878 calls application.get("omitted_source_count", 0) < 1. If the sealed value is null, Python raises TypeError instead of RehearsalError. The runner then fails outside the declared error contract, and the caller cannot report a boundary message. The value originates from the pinned G2 packer payload, so this is defensive hardening only.

♻️ Proposed type guard
-            application = outcomes[(task_id, arm)].get("adaptive_k_application")
-            if not isinstance(application, dict) or application.get("omitted_source_count", 0) < 1:
-                raise RehearsalError(f"adaptive application receipt mismatch: {task_id}/{arm}")
+            application = outcomes[(task_id, arm)].get("adaptive_k_application")
+            omitted = application.get("omitted_source_count") if isinstance(application, dict) else None
+            if isinstance(omitted, bool) or not isinstance(omitted, int) or omitted < 1:
+                raise RehearsalError(f"adaptive application receipt mismatch: {task_id}/{arm}")
🤖 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/provider-free-roadmap/g3/v1/rehearse.py` around lines 876 - 881,
Update the validation loop for each arm in the rehearsal flow to validate that
omitted_source_count is numeric before comparing it with 1. Treat null and other
non-numeric values as an adaptive application receipt mismatch by raising
RehearsalError, while preserving the existing required-source validation for
valid counts.

167-178: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Apply the strict JSON constant policy to sealed payloads.

unseal_json calls json.loads without parse_constant=reject_nonfinite. The canonical(parsed) != raw check rejects duplicate keys and noncanonical ordering, but NaN and Infinity survive that check because json.dumps re-emits the same tokens. parse_json already rejects those constants for every other input. Use the same policy for sealed payloads to keep one rule for all captured JSON.

♻️ Proposed hardening
-    parsed = json.loads(raw.decode("ascii"))
+    parsed = json.loads(
+        raw.decode("ascii"),
+        object_pairs_hook=reject_duplicate_keys,
+        parse_constant=reject_nonfinite,
+    )
🤖 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/provider-free-roadmap/g3/v1/rehearse.py` around lines 167 - 178,
Update unseal_json to pass the existing reject_nonfinite function as
json.loads(parse_constant=...) when parsing the decoded sealed payload. Preserve
the current canonicality and private-key validation checks while ensuring NaN
and Infinity are rejected consistently with parse_json.
tests/provider-free-roadmap/test_g3_rehearsal.py (1)

111-127: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated commitment formula diverges from bundle_commitment. Both sites recompute deterministic_evidence_sha256 with a hand-rolled digest that uses a 4-byte name length, omits the contextguard.g3-deterministic-bundle/v2 domain separator, and covers only four artifacts. bundle_commitment in research/provider-free-roadmap/g3/v1/rehearse.py (Lines 1029-1044) uses an 8-byte name length, a domain separator, and normalized timing artifacts. The shared root cause is a local reimplementation of a runner function.

  • tests/provider-free-roadmap/test_g3_rehearsal.py#L111-L127: call self.runner.bundle_commitment(artifacts, repro) directly and delete the fallback branch.
  • tests/provider-free-roadmap/test_g3_rehearsal.py#L317-L335: replace the inline digest block with a call to self.refresh_commitment(artifacts).
🤖 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/provider-free-roadmap/test_g3_rehearsal.py` around lines 111 - 127,
Remove the local fallback digest in refresh_commitment and call
self.runner.bundle_commitment(artifacts, repro) directly, preserving the
canonical artifact commitment logic. In
tests/provider-free-roadmap/test_g3_rehearsal.py lines 111-127, make that direct
call and delete the hand-rolled branch; at lines 317-335, replace the inline
digest block with self.refresh_commitment(artifacts).
research/provider-free-roadmap/g6/v1/verify.py (1)

324-342: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider passing the probe counters explicitly instead of using a module global.

sys.addaudithook installs _audit for the life of the interpreter. _audit then reads the module-level _ACTIVE_PROBE. While audited_negative_probes runs, any other code in the same interpreter that opens a socket, starts a subprocess, or opens a file for writing also receives PermissionError and increments the shared counters. That would corrupt the counter equality check at line 367.

The current caller is single-threaded, so this is not an active defect. A thread-local or explicit context object would remove the interpreter-wide coupling. Changing it also changes the pinned verifier hash, so it is optional.

🤖 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/provider-free-roadmap/g6/v1/verify.py` around lines 324 - 342,
Refactor the audit state used by _audit and audited_negative_probes to avoid the
module-global _ACTIVE_PROBE, preferably by passing or retrieving a
thread-local/context object containing the counters. Ensure only events
belonging to the active probe are denied and counted, preserving the counter
equality check while avoiding interference from unrelated interpreter activity.
scripts/verify_provider_free_roadmap.py (1)

681-704: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider a module-to-key-set mapping instead of the chained conditional.

expected_keys now chains six conditional branches. The contract it expresses is a fixed mapping from module to a required key set. A module-level dict states the same contract in one place and stays readable when a G7 profile is added.

♻️ Proposed refactor
+PROFILE_KEY_SETS = {
+    "g2_contract_tests": {"module", "test_artifact", "verifier_artifact"},
+    "g3_rehearsal_tests": {"g2_verifier_artifact", "g3_lock_artifact", "module", "test_artifact"},
+    "g4_claim_gate_tests": {
+        "g2_verifier_artifact", "g3_lock_artifact", "g4_lock_artifact",
+        "module", "test_artifact",
+    },
+    "g5_p2_preregistration_tests": {"g4_lock_artifact", "g5_lock_artifact", "module", "test_artifact"},
+    "g6_prepared_unapproved_tests": {"g5_lock_artifact", "g6_lock_artifact", "module", "test_artifact"},
+}
     module = profile.get("module")
-    expected_keys = (
-        {"module", "test_artifact", "verifier_artifact"}
-        if module == "g2_contract_tests"
-        else {
-            "g2_verifier_artifact", "g3_lock_artifact", "module", "test_artifact"
-        }
-        if module == "g3_rehearsal_tests"
-        else {
-            "g2_verifier_artifact", "g3_lock_artifact", "g4_lock_artifact",
-            "module", "test_artifact",
-        }
-        if module == "g4_claim_gate_tests"
-        else {
-            "g4_lock_artifact", "g5_lock_artifact", "module", "test_artifact",
-        }
-        if module == "g5_p2_preregistration_tests"
-        else {
-            "g5_lock_artifact", "g6_lock_artifact", "module", "test_artifact",
-        }
-        if module == "g6_prepared_unapproved_tests"
-        else {"module", "test_artifact"}
-    )
+    expected_keys = PROFILE_KEY_SETS.get(module, {"module", "test_artifact"})
🤖 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 `@scripts/verify_provider_free_roadmap.py` around lines 681 - 704, Replace the
chained conditional used to compute expected_keys with a module-to-key-set
mapping, using the existing module names and key sets from that expression.
Retrieve the mapped set with the current default {"module", "test_artifact"} for
unknown modules, then preserve the existing set(profile) validation and failure
behavior.
tests/provider-free-roadmap/test_g4_claim_gates.py (1)

130-140: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert each fail-closed stub separately so the whole chain is exercised.

self.gate.source_export(fabricated) at Line 131 raises GateError immediately, because source_export is the fail-closed stub at research/provider-free-roadmap/g4/v1/verify.py Lines 413-415. Lines 132-140 never run. The test passes, but it covers only one of the three legacy helpers. build_report and validate_public_artifacts stay untested, and boundary at Lines 125-129 is dead data.

The "duplicate" subTest at Line 239 has the same shape. Appending a record makes the list 25 long, so the count check at verify.py Line 249 fires before the duplicate check at Line 253. Replace a record instead of appending it to reach the duplicate path.

♻️ Proposed refactor to cover each stub
-        boundary = {
-            "claim": "audited_cpython_process_boundary_not_os_sandbox",
-            "dns_denials": 1, "network_denials": 1,
-            "process_denials": 1, "write_denials": 1,
-        }
-        with self.assertRaisesRegex(Exception, "authenticated G3|authenticated.*root"):
-            source = self.gate.source_export(fabricated)
-            report = self.gate.build_report(source, boundary)
-            self.gate.validate_public_artifacts(
-                {
-                    "claim-report.json": self.gate.canonical(report),
-                    "source-records.json": self.gate.canonical(source),
-                },
-                self.g4_inputs["g4_schema_bytes"],
-                self.g3_inputs["g2_verifier_bytes"],
-            )
+        boundary = {
+            "claim": "audited_cpython_process_boundary_not_os_sandbox",
+            "dns_denials": 1, "network_denials": 1,
+            "process_denials": 1, "write_denials": 1,
+        }
+        pattern = "authenticated G3|authenticated.*root"
+        for label, call in (
+            ("source_export", lambda: self.gate.source_export(fabricated)),
+            ("build_report", lambda: self.gate.build_report(fabricated, boundary)),
+            ("validate_public_artifacts", lambda: self.gate.validate_public_artifacts(
+                {"claim-report.json": b"{}\n", "source-records.json": b"{}\n"},
+                self.g4_inputs["g4_schema_bytes"],
+                self.g3_inputs["g2_verifier_bytes"],
+            )),
+        ):
+            with self.subTest(helper=label), self.assertRaisesRegex(Exception, pattern):
+                call()

For the duplicate subTest at Line 239:

-            "duplicate": lambda value: value["records"].append(copy.deepcopy(value["records"][0])),
+            "duplicate": lambda value: value["records"].__setitem__(1, copy.deepcopy(value["records"][0])),
🤖 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/provider-free-roadmap/test_g4_claim_gates.py` around lines 130 - 140,
Update the fail-closed gate tests to invoke each legacy helper independently,
asserting the expected GateError for source_export, build_report, and
validate_public_artifacts instead of chaining them behind the first failure;
remove the now-unused boundary setup. In the duplicate subTest, replace an
existing record with the duplicate rather than appending it, preserving the
expected record count so execution reaches the duplicate-validation branch.
tests/provider-free-roadmap/test_g5_p2_preregistration.py (1)

116-122: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Split the two validator calls into separate assertions.

Both validate_schema (Line 121) and validate_schedule (Line 122) run inside one assertRaises block. If Line 121 raises, Line 122 never executes. The context manager then passes without exercising validate_schedule at all.

Today every mutation raises somewhere, so the test passes. The coverage is still conditional: if a future schema change made validate_schema reject the pseudoreplication case, this test would keep passing while validate_schedule coverage disappears silently. Assert each validator separately so each rejection path is proven.

♻️ Proposed split assertion
         for label, mutation in mutations.items():
             with self.subTest(label=label):
                 changed = copy.deepcopy(self.schedule)
                 mutation(changed)
-                with self.assertRaises(Exception):
-                    self.verify.validate_schema(changed, schema, schema, "schedule")
-                    self.verify.validate_schedule(changed)
+                rejections = 0
+                for validate in (
+                    lambda: self.verify.validate_schema(changed, schema, schema, "schedule"),
+                    lambda: self.verify.validate_schedule(changed),
+                ):
+                    try:
+                        validate()
+                    except self.verify.VerificationError:
+                        rejections += 1
+                self.assertGreater(rejections, 0)
🤖 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/provider-free-roadmap/test_g5_p2_preregistration.py` around lines 116 -
122, In the mutation loop of the test, split the combined assertRaises block so
validate_schema and validate_schedule are each invoked in their own independent
exception assertion. Keep the same changed schedule and validator arguments,
ensuring both rejection paths execute even when the other validator raises.

Source: Linters/SAST tools

research/provider-free-roadmap/g5/v1/verify.py (1)

891-914: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Bind OBSERVATION_SCHEMA_SHA256 in validate_captured.

The function validates the observation schema structure but does not bind its bytes to the pinned hash. Add the hash check before parsing the captured documents.

🤖 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/provider-free-roadmap/g5/v1/verify.py` around lines 891 - 914,
Update validate_captured to verify the raw authoritative-observation.schema.json
bytes against OBSERVATION_SCHEMA_SHA256 before parsing the captured documents.
Reject a mismatch using the existing verification error mechanism, then retain
the current schema parsing and structural validation flow.

Source: Linters/SAST tools

🤖 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 `@context-guard-kit/context_pack.py`:
- Around line 4273-4282: The adaptive-k text output derives applied state from
dictionary presence rather than application status. In print_adaptive_k_text,
update applied to be true only when adaptive_k_application is a dictionary whose
status equals "applied"; make the identical change at
context-guard-kit/context_pack.py lines 4273-4282 and
plugins/context-guard/bin/context-guard-pack lines 4273-4282, preserving
byte-identical mirrored copies.
- Around line 3808-3818: Ensure graph neighbors always rank strictly below
explicit/query seed sources in both context-guard-kit/context_pack.py (lines
3808-3818) and plugins/context-guard/bin/context-guard-pack (lines 3808-3818).
Update the priority calculation or rebuilt-manifest ordering so a
lowest-priority seed of 1 cannot tie with a graph source, and keep both mirrored
copies byte-identical.
- Around line 4130-4165: After the graph-application build_pack call in
context-guard-kit/context_pack.py lines 4130-4165, refresh
suggest_payload["estimated_pack_bytes"] and suggest_payload["token_proxy"] from
the rebuilt build_payload, matching the adaptive-k update. Apply the identical
change in plugins/context-guard/bin/context-guard-pack lines 4130-4165 to keep
both mirrored copies consistent.
- Around line 3131-3179: Update apply_adaptive_k_manifest so
explicit_sources_retained verifies each protected entry by object identity
rather than dict-value equality, using the retained objects and avoiding a
quadratic membership scan. Also simplify the status assignment to express the
applied, no_change, and gate_failed outcomes once without overwriting status.

In `@research/provider-free-roadmap/g2/v1/result.example.json`:
- Around line 26-31: Update the selected_paths array in the evaluation_graph
example to match the frozen fixture and scorer requirements: replace runner.js
and indigo-validator.js with app/runner.js and validators/index.js, preserving
the existing task_id and structural status.

In `@research/provider-free-roadmap/g2/v1/tasks.json`:
- Around line 10-18: Add the required source files to the corresponding pack
configurations: include evidence.txt in train_closed.pack.files and matrix.json
in evaluation_closed.pack.files. Regenerate all task-result and integrity
artifacts that bind these packed inputs, preserving the existing
workspace-access restrictions.

In `@research/provider-free-roadmap/g2/v1/verify.py`:
- Around line 1445-1464: Update run_captured_packer_child to pass a bounded
timeout to subprocess.run, and catch the resulting subprocess.TimeoutExpired
exception. Convert that expiry into a VerificationError with useful context
identifying the packer child invocation, while preserving the existing
CompletedProcess return path for processes that finish normally.

In `@scripts/verify_g4_provider_free.py`:
- Line 2: Update the module docstring in verify_g4_provider_free.py to include
G5 and G6 alongside P1, G2, G3, and G4, matching the profiles processed by the
loop and the existing success message.
- Around line 17-22: Update the environment construction in run to read PATH
defensively with os.environ.get and the appropriate fallback, matching the
existing LANG handling. Preserve passing the resulting environment to
subprocess.run so missing PATH reaches the downstream validation flow instead of
raising KeyError.

In `@scripts/verify_provider_free_roadmap.py`:
- Around line 1372-1382: Update scripts/verify_provider_free_roadmap.py at lines
1372-1382 in enumerate_g6_scope to catch entry.stat OSError and fail with
“changed while enumerating g6 frozen scope”; at lines 1057-1070 in
enumerate_g4_scope, add matching guards for both os.scandir and entry.stat; at
lines 1210-1226 in enumerate_g5_scope, guard entry.stat and fail with “changed
while enumerating g5 frozen scope”.

In `@tests/test_contextguard_stage2_feasibility.py`:
- Around line 936-945: Update the Markdown read in the test around
PROGRESSIVE_BENCHMARK_SUMMARY_PATH to pass an explicit UTF-8 encoding to
read_text(), preserving the existing report assertions.

In `@tests/test_provider_free_roadmap_boundary.py`:
- Around line 398-408: Align the kind tuples with their branch ladders in
tests/test_provider_free_roadmap_boundary.py:398-408, 476-489, and 572-587. In
the first helper, add explicit hardlink and special handling; in the second,
include "hardlink" so the os.link branch runs; and in the third, include
"special" so the os.mkfifo branch runs. Preserve the aligned G6 helper pattern.

---

Nitpick comments:
In `@research/provider-free-roadmap/g2/v1/verify.py`:
- Around line 275-291: Cache the computed interpreter binding in python_binding
using functools.cache so the executable is read and hashed only once per
verification run. Preserve the existing validation and returned mapping, and
confirm current callers such as run_captured_packer_child,
capture_public_snapshot, and _post_capture_drift_check continue to read or
compare the cached result without mutation.
- Line 200: Replace the identity lambda assignment with a regular function
definition to resolve Ruff E731, preserving the same tuple fields and ordering.
In the loop near the path-processing logic, rename the unused path variable to
the conventional underscore placeholder to resolve Ruff B007 without changing
loop behavior.

In `@research/provider-free-roadmap/g3/v1/rehearse.py`:
- Around line 876-881: Update the validation loop for each arm in the rehearsal
flow to validate that omitted_source_count is numeric before comparing it with
1. Treat null and other non-numeric values as an adaptive application receipt
mismatch by raising RehearsalError, while preserving the existing
required-source validation for valid counts.
- Around line 167-178: Update unseal_json to pass the existing reject_nonfinite
function as json.loads(parse_constant=...) when parsing the decoded sealed
payload. Preserve the current canonicality and private-key validation checks
while ensuring NaN and Infinity are rejected consistently with parse_json.

In `@research/provider-free-roadmap/g5/v1/verify.py`:
- Around line 891-914: Update validate_captured to verify the raw
authoritative-observation.schema.json bytes against OBSERVATION_SCHEMA_SHA256
before parsing the captured documents. Reject a mismatch using the existing
verification error mechanism, then retain the current schema parsing and
structural validation flow.

In `@research/provider-free-roadmap/g6/v1/verify.py`:
- Around line 324-342: Refactor the audit state used by _audit and
audited_negative_probes to avoid the module-global _ACTIVE_PROBE, preferably by
passing or retrieving a thread-local/context object containing the counters.
Ensure only events belonging to the active probe are denied and counted,
preserving the counter equality check while avoiding interference from unrelated
interpreter activity.

In `@scripts/verify_provider_free_roadmap.py`:
- Around line 681-704: Replace the chained conditional used to compute
expected_keys with a module-to-key-set mapping, using the existing module names
and key sets from that expression. Retrieve the mapped set with the current
default {"module", "test_artifact"} for unknown modules, then preserve the
existing set(profile) validation and failure behavior.

In `@tests/provider-free-roadmap/test_g3_rehearsal.py`:
- Around line 111-127: Remove the local fallback digest in refresh_commitment
and call self.runner.bundle_commitment(artifacts, repro) directly, preserving
the canonical artifact commitment logic. In
tests/provider-free-roadmap/test_g3_rehearsal.py lines 111-127, make that direct
call and delete the hand-rolled branch; at lines 317-335, replace the inline
digest block with self.refresh_commitment(artifacts).

In `@tests/provider-free-roadmap/test_g4_claim_gates.py`:
- Around line 130-140: Update the fail-closed gate tests to invoke each legacy
helper independently, asserting the expected GateError for source_export,
build_report, and validate_public_artifacts instead of chaining them behind the
first failure; remove the now-unused boundary setup. In the duplicate subTest,
replace an existing record with the duplicate rather than appending it,
preserving the expected record count so execution reaches the
duplicate-validation branch.

In `@tests/provider-free-roadmap/test_g5_p2_preregistration.py`:
- Around line 116-122: In the mutation loop of the test, split the combined
assertRaises block so validate_schema and validate_schedule are each invoked in
their own independent exception assertion. Keep the same changed schedule and
validator arguments, ensuring both rejection paths execute even when the other
validator raises.

In `@tests/test_context_guard_progressive_context.py`:
- Around line 117-134: Add an assertion in the gate-failed test path covering
the text output from print_adaptive_k_text, verifying it reports apply=false
when adaptive_k_application.status is gate_failed and the manifest remains
unchanged. Keep the existing JSON contract assertions intact.
🪄 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: 490b9b4d-71a2-4b64-996d-74a401da81bd

📥 Commits

Reviewing files that changed from the base of the PR and between bc2e089 and 2dd128b.

⛔ Files ignored due to path filters (2)
  • research/provider-free-roadmap/g2/v1/fixtures/calibration/closed_pack/ledger.csv is excluded by !**/*.csv
  • research/provider-free-roadmap/g2/v1/fixtures/evaluation/closed_pack/crates.tsv is excluded by !**/*.tsv
📒 Files selected for processing (122)
  • README.ko.md
  • README.md
  • context-guard-kit/README.md
  • context-guard-kit/bash_reference_policy.py
  • context-guard-kit/context_pack.py
  • packages/context-guard-receipt/README.md
  • packages/context-guard-receipt/bin/launcher.cjs
  • packages/context-guard-receipt/package-files.json
  • packages/context-guard-receipt/python/context_guard_receipt/cli.py
  • packages/context-guard-receipt/python/context_guard_receipt/mcp.py
  • packages/context-guard-receipt/scripts/verify_protected_surfaces.py
  • packages/context-guard-receipt/tests/contract/test_boundary.py
  • packages/context-guard-receipt/tests/contract/test_g001_distribution_contract.py
  • packages/context-guard-receipt/tests/contract/test_g012_mcp.py
  • packages/context-guard-receipt/tests/contract/test_g012_mcp_cli.py
  • packages/context-guard-receipt/tests/e2e/test_g001_offline_distribution.py
  • packages/context-guard-receipt/tests/e2e/test_g012_mcp_stdio.py
  • plugins/context-guard/README.ko.md
  • plugins/context-guard/README.md
  • plugins/context-guard/bin/bash_reference_policy.py
  • plugins/context-guard/bin/context-guard-pack
  • research/comparator-mechanism-acceptance-matrix.md
  • research/p2-p6-provider-free-implementation.md
  • research/progressive-context-benchmark-2026-08-12.json
  • research/progressive-context-benchmark-2026-08-12.md
  • research/provider-free-roadmap/README.md
  • research/provider-free-roadmap/boundary-contract.json
  • research/provider-free-roadmap/g2/freeze-lock.json
  • research/provider-free-roadmap/g2/v1/README.md
  • research/provider-free-roadmap/g2/v1/arms.json
  • research/provider-free-roadmap/g2/v1/contract.json
  • research/provider-free-roadmap/g2/v1/fixtures/calibration/closed_pack/dispatch.md
  • research/provider-free-roadmap/g2/v1/fixtures/calibration/closed_pack/radio-notes.txt
  • research/provider-free-roadmap/g2/v1/fixtures/calibration/closed_pack/tides.txt
  • research/provider-free-roadmap/g2/v1/fixtures/calibration/realistic_fallback/colors.json
  • research/provider-free-roadmap/g2/v1/fixtures/calibration/realistic_fallback/operator-handbook.md
  • research/provider-free-roadmap/g2/v1/fixtures/calibration/realistic_fallback/src/calibration/amber-calibrator.ts
  • research/provider-free-roadmap/g2/v1/fixtures/calibration/realistic_fallback/src/controllers/entry.ts
  • research/provider-free-roadmap/g2/v1/fixtures/calibration/realistic_fallback/src/telemetry/probe.ts
  • research/provider-free-roadmap/g2/v1/fixtures/calibration/realistic_fallback/thermometer.txt
  • research/provider-free-roadmap/g2/v1/fixtures/calibration/realistic_fallback/window-guide.md
  • research/provider-free-roadmap/g2/v1/fixtures/evaluation/closed_pack/matrix.json
  • research/provider-free-roadmap/g2/v1/fixtures/evaluation/closed_pack/pruning.md
  • research/provider-free-roadmap/g2/v1/fixtures/evaluation/closed_pack/question.txt
  • research/provider-free-roadmap/g2/v1/fixtures/evaluation/realistic_fallback/app/runner.js
  • research/provider-free-roadmap/g2/v1/fixtures/evaluation/realistic_fallback/auditors/check.js
  • research/provider-free-roadmap/g2/v1/fixtures/evaluation/realistic_fallback/dye-catalog.txt
  • research/provider-free-roadmap/g2/v1/fixtures/evaluation/realistic_fallback/operator-handbook.md
  • research/provider-free-roadmap/g2/v1/fixtures/evaluation/realistic_fallback/queue.toml
  • research/provider-free-roadmap/g2/v1/fixtures/evaluation/realistic_fallback/release-notes.md
  • research/provider-free-roadmap/g2/v1/fixtures/evaluation/realistic_fallback/validators/index.js
  • research/provider-free-roadmap/g2/v1/fixtures/train/closed_pack/brief.txt
  • research/provider-free-roadmap/g2/v1/fixtures/train/closed_pack/distractor.txt
  • research/provider-free-roadmap/g2/v1/fixtures/train/closed_pack/evidence.txt
  • research/provider-free-roadmap/g2/v1/fixtures/train/closed_pack/history.md
  • research/provider-free-roadmap/g2/v1/fixtures/train/realistic_fallback/app/entry.py
  • research/provider-free-roadmap/g2/v1/fixtures/train/realistic_fallback/app/routing/checksum.py
  • research/provider-free-roadmap/g2/v1/fixtures/train/realistic_fallback/app/routing/constants.py
  • research/provider-free-roadmap/g2/v1/fixtures/train/realistic_fallback/cobalt_notes.md
  • research/provider-free-roadmap/g2/v1/fixtures/train/realistic_fallback/obsolete_map.txt
  • research/provider-free-roadmap/g2/v1/fixtures/train/realistic_fallback/operator-handbook.md
  • research/provider-free-roadmap/g2/v1/fixtures/train/realistic_fallback/supply.yaml
  • research/provider-free-roadmap/g2/v1/result.example.json
  • research/provider-free-roadmap/g2/v1/run.json
  • research/provider-free-roadmap/g2/v1/schemas/arms.schema.json
  • research/provider-free-roadmap/g2/v1/schemas/contract.schema.json
  • research/provider-free-roadmap/g2/v1/schemas/graph.schema.json
  • research/provider-free-roadmap/g2/v1/schemas/oracle.schema.json
  • research/provider-free-roadmap/g2/v1/schemas/result.schema.json
  • research/provider-free-roadmap/g2/v1/schemas/run.schema.json
  • research/provider-free-roadmap/g2/v1/schemas/tasks.schema.json
  • research/provider-free-roadmap/g2/v1/scorer-only/graph.json
  • research/provider-free-roadmap/g2/v1/scorer-only/oracle.json
  • research/provider-free-roadmap/g2/v1/tasks.json
  • research/provider-free-roadmap/g2/v1/verify.py
  • research/provider-free-roadmap/g3/freeze-lock.json
  • research/provider-free-roadmap/g3/v1/README.md
  • research/provider-free-roadmap/g3/v1/cost-model.json
  • research/provider-free-roadmap/g3/v1/manifest.json
  • research/provider-free-roadmap/g3/v1/rehearse.py
  • research/provider-free-roadmap/g3/v1/schemas/aggregate-results.schema.json
  • research/provider-free-roadmap/g3/v1/schemas/artifact-inventory.schema.json
  • research/provider-free-roadmap/g3/v1/schemas/event.schema.json
  • research/provider-free-roadmap/g3/v1/schemas/manifest.schema.json
  • research/provider-free-roadmap/g3/v1/schemas/reproducibility.schema.json
  • research/provider-free-roadmap/g3/v1/schemas/task-arm-results.schema.json
  • research/provider-free-roadmap/g3/v1/schemas/timing-event.schema.json
  • research/provider-free-roadmap/g3/v1/schemas/timing-summary.schema.json
  • research/provider-free-roadmap/g4/freeze-lock.json
  • research/provider-free-roadmap/g4/v1/README.md
  • research/provider-free-roadmap/g4/v1/claim-policy.json
  • research/provider-free-roadmap/g4/v1/schemas/claim-policy.schema.json
  • research/provider-free-roadmap/g4/v1/schemas/claim-report.schema.json
  • research/provider-free-roadmap/g4/v1/schemas/source-records.schema.json
  • research/provider-free-roadmap/g4/v1/verify.py
  • research/provider-free-roadmap/g5/freeze-lock.json
  • research/provider-free-roadmap/g5/v1/README.md
  • research/provider-free-roadmap/g5/v1/preregistration.json
  • research/provider-free-roadmap/g5/v1/schedule.json
  • research/provider-free-roadmap/g5/v1/schemas/authoritative-observation.schema.json
  • research/provider-free-roadmap/g5/v1/schemas/preregistration.schema.json
  • research/provider-free-roadmap/g5/v1/schemas/schedule.schema.json
  • research/provider-free-roadmap/g5/v1/verify.py
  • research/provider-free-roadmap/g6/freeze-lock.json
  • research/provider-free-roadmap/g6/v1/README.md
  • research/provider-free-roadmap/g6/v1/STATUS.md
  • research/provider-free-roadmap/g6/v1/preparation-packet.json
  • research/provider-free-roadmap/g6/v1/schemas/preparation-packet.schema.json
  • research/provider-free-roadmap/g6/v1/verify.py
  • research/provider-free-roadmap/p1-v8-evidence-manifest.json
  • research/token-savings-roadmap.md
  • scripts/verify_g4_provider_free.py
  • scripts/verify_provider_free_roadmap.py
  • tests/provider-free-roadmap/test_g2_ablation_contract.py
  • tests/provider-free-roadmap/test_g3_rehearsal.py
  • tests/provider-free-roadmap/test_g4_claim_gates.py
  • tests/provider-free-roadmap/test_g5_p2_preregistration.py
  • tests/provider-free-roadmap/test_g6_approval_packet.py
  • tests/test_context_guard_progressive_context.py
  • tests/test_contextguard_stage2_feasibility.py
  • tests/test_contextguard_stage2_protected_surfaces.py
  • tests/test_provider_free_roadmap_boundary.py

Comment thread context-guard-kit/context_pack.py
Comment thread context-guard-kit/context_pack.py
Comment thread context-guard-kit/context_pack.py
Comment thread context-guard-kit/context_pack.py
Comment on lines +26 to +31
"selected_paths": [
"runner.js",
"indigo-validator.js"
],
"structural_status": "selection_recorded",
"task_id": "evaluation_graph"

@coderabbitai coderabbitai Bot Aug 12, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Align the example selected_paths with the frozen evaluation fixture.

The example declares task_id evaluation_graph, but the listed paths do not exist in research/provider-free-roadmap/g2/v1/fixtures/evaluation/realistic_fallback/. That fixture contains app/runner.js and validators/index.js. scorer-only/oracle.json also declares required_paths app/runner.js and validators/index.js for this task. verify.py validates this file against schemas/result.schema.json only, so the mismatch does not fail verification, but the example misdescribes real packer output.

🔧 Proposed fix
   "selected_paths": [
-    "runner.js",
-    "indigo-validator.js"
+    "app/runner.js",
+    "validators/index.js"
   ],
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"selected_paths": [
"runner.js",
"indigo-validator.js"
],
"structural_status": "selection_recorded",
"task_id": "evaluation_graph"
"selected_paths": [
"app/runner.js",
"validators/index.js"
],
"structural_status": "selection_recorded",
"task_id": "evaluation_graph"
🤖 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/provider-free-roadmap/g2/v1/result.example.json` around lines 26 -
31, Update the selected_paths array in the evaluation_graph example to match the
frozen fixture and scorer requirements: replace runner.js and
indigo-validator.js with app/runner.js and validators/index.js, preserving the
existing task_id and structural status.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Confirmed as a low-severity example-only mismatch. It does not feed verification or scoring. We intentionally deferred it because this file is inside the recursively frozen G2 evidence tree and changing it would require another G2→G6 evidence re-freeze unrelated to the merge blockers.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@ictechgy, understood. The mismatch is valid but does not affect verification or scoring. Deferring the correction avoids an unrelated G2–G6 evidence re-freeze.

Would you like a follow-up issue for the example-path correction after the frozen evidence is updated?


✏️ Learnings added
Learnt from: ictechgy
Repo: ictechgy/context-guard PR: 302
File: research/provider-free-roadmap/g2/v1/result.example.json:26-31
Timestamp: 2026-08-12T16:42:30.402Z
Learning: In the provider-free roadmap, files inside the recursively frozen G2 evidence tree require a coordinated G2–G6 evidence re-freeze when changed. Example-only mismatches that do not affect verification or scoring can be deferred when that re-freeze is outside the pull request scope.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

@@ -0,0 +1,43 @@
#!/usr/bin/env python3
"""Clean provider-free P1/G2/G3/G4 validation command."""

@coderabbitai coderabbitai Bot Aug 12, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update the docstring to include G5 and G6.

The docstring says "P1/G2/G3/G4". The profile loop at lines 32-36 now also runs g5-p2-preregistration and g6-prepared-unapproved, and the success message at line 38 already names G5 and G6.

📝 Proposed fix
-"""Clean provider-free P1/G2/G3/G4 validation command."""
+"""Clean provider-free P1/G2/G3/G4/G5/G6 validation command."""
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"""Clean provider-free P1/G2/G3/G4 validation command."""
"""Clean provider-free P1/G2/G3/G4/G5/G6 validation command."""
🤖 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 `@scripts/verify_g4_provider_free.py` at line 2, Update the module docstring in
verify_g4_provider_free.py to include G5 and G6 alongside P1, G2, G3, and G4,
matching the profiles processed by the loop and the existing success message.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Acknowledged as a documentation-only wording nit. The executable profile list and success message already cover G5/G6; no runtime behavior is affected, so this was left for a follow-up rather than expanding the frozen patch.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@ictechgy, acknowledged. This is a non-blocking documentation inconsistency. The current patch behavior remains correct.

If you want, I can create a follow-up issue for the docstring update.


✏️ Learnings added
Learnt from: ictechgy
Repo: ictechgy/context-guard PR: 302
File: scripts/verify_g4_provider_free.py:2-2
Timestamp: 2026-08-12T16:42:38.246Z
Learning: For the frozen provider-free roadmap patch in PR `#302`, documentation-only wording changes can be deferred to a follow-up when they do not affect executable profile coverage or runtime behavior.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

Comment on lines +17 to +22
def run(arguments: list[str]) -> None:
environment = {"LANG": os.environ.get("LANG", "C.UTF-8"), "PATH": os.environ["PATH"]}
completed = subprocess.run(
[sys.executable, "-I", "-B", *arguments], cwd=ROOT, env=environment,
stdin=subprocess.DEVNULL,
)

@coderabbitai coderabbitai Bot Aug 12, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Give PATH the same defensive read as LANG.

Line 18 reads LANG with os.environ.get(...) and a default, but reads PATH with direct indexing. If PATH is not set, this raises a bare KeyError with a traceback. The downstream driver already produces a clear message for a missing PATH (validate_inherited_environment in scripts/verify_provider_free_roadmap.py, lines 458-460), so failing early with an unclear traceback loses that message.

🛡️ Proposed guard
 def run(arguments: list[str]) -> None:
-    environment = {"LANG": os.environ.get("LANG", "C.UTF-8"), "PATH": os.environ["PATH"]}
+    path = os.environ.get("PATH")
+    if not path:
+        raise SystemExit("PATH must be set for provider-free verification")
+    environment = {"LANG": os.environ.get("LANG", "C.UTF-8"), "PATH": path}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def run(arguments: list[str]) -> None:
environment = {"LANG": os.environ.get("LANG", "C.UTF-8"), "PATH": os.environ["PATH"]}
completed = subprocess.run(
[sys.executable, "-I", "-B", *arguments], cwd=ROOT, env=environment,
stdin=subprocess.DEVNULL,
)
def run(arguments: list[str]) -> None:
path = os.environ.get("PATH")
if not path:
raise SystemExit("PATH must be set for provider-free verification")
environment = {"LANG": os.environ.get("LANG", "C.UTF-8"), "PATH": path}
completed = subprocess.run(
[sys.executable, "-I", "-B", *arguments], cwd=ROOT, env=environment,
stdin=subprocess.DEVNULL,
)
🧰 Tools
🪛 ast-grep (0.45.1)

[error] 18-21: Command coming from incoming request
Context: subprocess.run(
[sys.executable, "-I", "-B", *arguments], cwd=ROOT, env=environment,
stdin=subprocess.DEVNULL,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)

🪛 Ruff (0.16.1)

[error] 19-19: subprocess call: check for execution of untrusted input

(S603)

🤖 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 `@scripts/verify_g4_provider_free.py` around lines 17 - 22, Update the
environment construction in run to read PATH defensively with os.environ.get and
the appropriate fallback, matching the existing LANG handling. Preserve passing
the resulting environment to subprocess.run so missing PATH reaches the
downstream validation flow instead of raising KeyError.

@ictechgy ictechgy Aug 12, 2026

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Acknowledged as a minor CLI-diagnostic improvement. The documented and CI invocation uses a closed environment with PATH present, and the downstream verifier rejects unsafe environments. We left this non-blocking wrapper nicety for follow-up.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@ictechgy, understood. The finding is non-blocking for the documented and CI environments. The wrapper can keep its current behavior in this PR.

Would you like me to create a follow-up GitHub issue for the PATH diagnostic improvement?


✏️ Learnings added
Learnt from: ictechgy
Repo: ictechgy/context-guard PR: 302
File: scripts/verify_g4_provider_free.py:17-22
Timestamp: 2026-08-12T16:42:39.174Z
Learning: For `scripts/verify_g4_provider_free.py`, the documented and CI invocation uses a closed environment that provides `PATH`. The downstream provider-free roadmap verifier validates the inherited environment. A missing-`PATH` wrapper diagnostic is a non-blocking CLI improvement and can be handled separately.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

Comment on lines +1372 to +1382
for entry in entries:
relative = f"{relative_directory}/{entry.name}"
metadata = entry.stat(follow_symlinks=False)
if stat.S_ISLNK(metadata.st_mode):
fail(f"symlink in g6 frozen scope: {relative}")
if stat.S_ISDIR(metadata.st_mode):
pending.append((Path(entry.path), relative))
elif stat.S_ISREG(metadata.st_mode) and metadata.st_nlink == 1:
result.add(relative)
else:
fail(f"unsafe path in g6 frozen scope: {relative}")

@coderabbitai coderabbitai Bot Aug 12, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Three scope walkers call entry.stat without error handling. enumerate_g3_scope wraps entry.stat(follow_symlinks=False) in try/except OSError and fails with "changed while enumerating g3 frozen scope" (lines 876-879). The G4, G5, and G6 walkers omit that guard. If an artifact is removed while a walker runs, the verifier exits with an unhandled OSError traceback instead of a boundary failure message. The shared root cause is one missing guard pattern, copied forward without the error handling.

  • scripts/verify_provider_free_roadmap.py#L1372-L1382: wrap the entry.stat call in enumerate_g6_scope and fail with "changed while enumerating g6 frozen scope".
  • scripts/verify_provider_free_roadmap.py#L1057-L1070: wrap the entry.stat call in enumerate_g4_scope, and wrap the os.scandir call the same way enumerate_g3_scope does.
  • scripts/verify_provider_free_roadmap.py#L1210-L1226: wrap the entry.stat call in enumerate_g5_scope and fail with "changed while enumerating g5 frozen scope".
📍 Affects 1 file
  • scripts/verify_provider_free_roadmap.py#L1372-L1382 (this comment)
  • scripts/verify_provider_free_roadmap.py#L1057-L1070
  • scripts/verify_provider_free_roadmap.py#L1210-L1226
🤖 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 `@scripts/verify_provider_free_roadmap.py` around lines 1372 - 1382, Update
scripts/verify_provider_free_roadmap.py at lines 1372-1382 in enumerate_g6_scope
to catch entry.stat OSError and fail with “changed while enumerating g6 frozen
scope”; at lines 1057-1070 in enumerate_g4_scope, add matching guards for both
os.scandir and entry.stat; at lines 1210-1226 in enumerate_g5_scope, guard
entry.stat and fail with “changed while enumerating g5 frozen scope”.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Acknowledged as a race-diagnostic hardening opportunity. The frozen-scope capture still fails closed on missing or changed artifacts; this affects whether a concurrent mutation yields the curated message or an OSError traceback, not acceptance. Deferred as a non-blocking follow-up.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@ictechgy, acknowledged. The verifier fails closed for this mutation case. The remaining gap is diagnostic consistency during concurrent scope changes.

Would you like me to create a GitHub follow-up issue for the G4, G5, and G6 scope-walker hardening?


✏️ Learnings added
Learnt from: ictechgy
Repo: ictechgy/context-guard PR: 302
File: scripts/verify_provider_free_roadmap.py:1417-1427
Timestamp: 2026-08-12T16:43:27.184Z
Learning: In `scripts/verify_provider_free_roadmap.py`, the G4, G5, and G6 frozen-scope walkers fail closed when artifacts are missing or changed. Missing `OSError` handling around `os.scandir` or `entry.stat(follow_symlinks=False)` affects only the curated race-diagnostic message versus an unhandled traceback. This hardening is non-blocking when the verifier acceptance behavior is unchanged.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

Comment on lines +936 to +945
report_text = PROGRESSIVE_BENCHMARK_SUMMARY_PATH.with_suffix(".md").read_text()
self.assertIn(summary["source_commit"], report_text)
self.assertIn(summary["candidate_hash"], report_text)
for evidence_digest in expected_evidence.values():
self.assertIn(evidence_digest, report_text)
self.assertIn("81,200", report_text)
self.assertIn("11,594", report_text)
self.assertIn("claim_allowed=false", report_text)
self.assertNotIn("/Users/", report_text)
self.assertNotIn("/tmp/", report_text)

@coderabbitai coderabbitai Bot Aug 12, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Set an explicit encoding on the Markdown read.

Line 936 calls read_text() without encoding. The decoding then depends on the platform locale. Every other artifact read in this module uses read_bytes() or an explicit encoding. If the report contains any non-ASCII byte and the runner locale is not UTF-8, this test fails for an unrelated reason.

🐛 Proposed fix
-        report_text = PROGRESSIVE_BENCHMARK_SUMMARY_PATH.with_suffix(".md").read_text()
+        report_text = PROGRESSIVE_BENCHMARK_SUMMARY_PATH.with_suffix(".md").read_text(
+            encoding="utf-8"
+        )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
report_text = PROGRESSIVE_BENCHMARK_SUMMARY_PATH.with_suffix(".md").read_text()
self.assertIn(summary["source_commit"], report_text)
self.assertIn(summary["candidate_hash"], report_text)
for evidence_digest in expected_evidence.values():
self.assertIn(evidence_digest, report_text)
self.assertIn("81,200", report_text)
self.assertIn("11,594", report_text)
self.assertIn("claim_allowed=false", report_text)
self.assertNotIn("/Users/", report_text)
self.assertNotIn("/tmp/", report_text)
report_text = PROGRESSIVE_BENCHMARK_SUMMARY_PATH.with_suffix(".md").read_text(
encoding="utf-8"
)
self.assertIn(summary["source_commit"], report_text)
self.assertIn(summary["candidate_hash"], report_text)
for evidence_digest in expected_evidence.values():
self.assertIn(evidence_digest, report_text)
self.assertIn("81,200", report_text)
self.assertIn("11,594", report_text)
self.assertIn("claim_allowed=false", report_text)
self.assertNotIn("/Users/", report_text)
self.assertNotIn("/tmp/", report_text)
🧰 Tools
🪛 ast-grep (0.45.1)

[info] 944-944: Do not hardcode temporary file or directory names
Context: "/tmp/"
Note: [CWE-377] Insecure Temporary File.

(hardcoded-tmp-file)

🪛 Ruff (0.16.1)

[error] 945-945: Probable insecure usage of temporary file or directory: "/tmp/"

(S108)

🤖 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_contextguard_stage2_feasibility.py` around lines 936 - 945, Update
the Markdown read in the test around PROGRESSIVE_BENCHMARK_SUMMARY_PATH to pass
an explicit UTF-8 encoding to read_text(), preserving the existing report
assertions.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Acknowledged as a locale-portability test nicety. CI and the bound profiles use UTF-8 locales and the artifact is canonical UTF-8. This does not affect production behavior and was left for follow-up.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@ictechgy, acknowledged. The explicit encoding remains a non-blocking locale-portability improvement. It does not affect production behavior or the stated UTF-8 CI and bound-profile environments.

If you want, I can open a follow-up GitHub issue for the test-only change.


✏️ Learnings added
Learnt from: ictechgy
Repo: ictechgy/context-guard PR: 302
File: tests/test_contextguard_stage2_feasibility.py:936-945
Timestamp: 2026-08-12T16:43:28.726Z
Learning: In `tests/test_contextguard_stage2_feasibility.py`, the progressive benchmark Markdown artifact is canonical UTF-8, and the CI and bound verification profiles use UTF-8 locales. An explicit `encoding="utf-8"` on the `Path.read_text()` call is a non-blocking locale-portability improvement.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

Comment thread tests/test_provider_free_roadmap_boundary.py Outdated

@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)
scripts/verify_provider_free_roadmap.py (1)

1032-1086: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Handle enumeration races in G4–G6. Catch OSError around entry.stat(follow_symlinks=False) and G4’s os.scandir so race failures produce controlled fail(...) diagnostics instead of tracebacks.

🤖 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 `@scripts/verify_provider_free_roadmap.py` around lines 1032 - 1086, Update the
G4–G6 enumeration logic, including verify_independently_pinned_g4_lock and the
relevant os.scandir callers, to catch OSError from os.scandir and
entry.stat(follow_symlinks=False). Convert each caught race failure into the
existing fail(...) diagnostic path with clear context, rather than allowing the
exception to escape as a traceback.
🤖 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 `@scripts/verify_provider_free_roadmap.py`:
- Around line 1032-1086: Update the G4–G6 enumeration logic, including
verify_independently_pinned_g4_lock and the relevant os.scandir callers, to
catch OSError from os.scandir and entry.stat(follow_symlinks=False). Convert
each caught race failure into the existing fail(...) diagnostic path with clear
context, rather than allowing the exception to escape as a traceback.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f8ca1ae8-2927-456a-839d-ee2fa0dd78e2

📥 Commits

Reviewing files that changed from the base of the PR and between 7a64032 and ec742b2.

📒 Files selected for processing (30)
  • context-guard-kit/context_pack.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-pack
  • research/provider-free-roadmap/boundary-contract.json
  • research/provider-free-roadmap/g2/freeze-lock.json
  • research/provider-free-roadmap/g2/v1/contract.json
  • research/provider-free-roadmap/g2/v1/verify.py
  • research/provider-free-roadmap/g3/freeze-lock.json
  • research/provider-free-roadmap/g3/v1/manifest.json
  • research/provider-free-roadmap/g4/freeze-lock.json
  • research/provider-free-roadmap/g4/v1/claim-policy.json
  • research/provider-free-roadmap/g4/v1/schemas/claim-policy.schema.json
  • research/provider-free-roadmap/g4/v1/verify.py
  • research/provider-free-roadmap/g5/freeze-lock.json
  • research/provider-free-roadmap/g5/v1/preregistration.json
  • research/provider-free-roadmap/g5/v1/schemas/preregistration.schema.json
  • research/provider-free-roadmap/g5/v1/verify.py
  • research/provider-free-roadmap/g6/freeze-lock.json
  • research/provider-free-roadmap/g6/v1/STATUS.md
  • research/provider-free-roadmap/g6/v1/preparation-packet.json
  • research/provider-free-roadmap/g6/v1/schemas/preparation-packet.schema.json
  • research/provider-free-roadmap/g6/v1/verify.py
  • scripts/verify_provider_free_roadmap.py
  • tests/provider-free-roadmap/test_g2_ablation_contract.py
  • tests/provider-free-roadmap/test_g3_rehearsal.py
  • tests/test_context_guard_progressive_context.py
  • tests/test_contextguard_stage2_feasibility.py
  • tests/test_contextguard_stage2_protected_surfaces.py
  • tests/test_provider_free_roadmap_boundary.py
🚧 Files skipped from review as they are similar to previous changes (23)
  • packages/context-guard-receipt/scripts/verify_protected_surfaces.py
  • research/provider-free-roadmap/g4/v1/claim-policy.json
  • research/provider-free-roadmap/g3/freeze-lock.json
  • packages/context-guard-receipt/tests/contract/test_boundary.py
  • research/provider-free-roadmap/g6/freeze-lock.json
  • research/provider-free-roadmap/g5/freeze-lock.json
  • research/provider-free-roadmap/g6/v1/STATUS.md
  • research/provider-free-roadmap/g3/v1/manifest.json
  • tests/test_contextguard_stage2_protected_surfaces.py
  • research/provider-free-roadmap/g4/v1/schemas/claim-policy.schema.json
  • research/provider-free-roadmap/boundary-contract.json
  • research/provider-free-roadmap/g2/v1/contract.json
  • research/provider-free-roadmap/g2/freeze-lock.json
  • research/provider-free-roadmap/g5/v1/schemas/preregistration.schema.json
  • research/provider-free-roadmap/g4/freeze-lock.json
  • research/provider-free-roadmap/g6/v1/schemas/preparation-packet.schema.json
  • tests/test_contextguard_stage2_feasibility.py
  • research/provider-free-roadmap/g6/v1/preparation-packet.json
  • research/provider-free-roadmap/g5/v1/preregistration.json
  • tests/provider-free-roadmap/test_g3_rehearsal.py
  • research/provider-free-roadmap/g5/v1/verify.py
  • research/provider-free-roadmap/g6/v1/verify.py
  • research/provider-free-roadmap/g4/v1/verify.py

@ictechgy
ictechgy merged commit 1211a58 into main Aug 12, 2026
6 of 7 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