From b7177a47675e28e550ad7c5774d3cf3fa6838d44 Mon Sep 17 00:00:00 2001 From: t Date: Wed, 16 Sep 2026 00:44:26 +0530 Subject: [PATCH] Raise the surface cap to 217 and pin the scheduled audit workflow `dependency-security-scheduled.yml` landed in #404 unpinned, because the surface held exactly 216 entries against a cap of 216 and `reseal.sh --pins-changed` refuses a 217th with `surface_file_count_invalid`. Raising a cap the count sits exactly on is the deliberate decision that constant exists to force, so it was left for review rather than taken as a side effect of adding a workflow. This is that decision. The constant's own rule is one file for one named reason, not headroom, so the reason is recorded beside it. It differs in kind from the three raises above it. Those bound files that decide what Bridge admits -- `agent_ledgers.rs`, `master_binding.rs`, the voucher-presence engine. This one binds a file that decides what Bridge is allowed to do to its own repository while nobody is watching: it is the only workflow that runs unattended on a schedule holding `issues: write`, and it was the only one of the five whose sibling is pinned while it was not. Left unpinned, an edit that widened its permissions or pointed its audit at a different lockfile would leave the surface digest unchanged and let existing evidence attest a workflow it never covered. That is not asserted. Widening the job's `contents: read` to `contents: write` now fails `reseal.sh --verify` and fails the gate with `surface_file_changed`; before this change the same edit passed both. The file was restored byte-identically afterwards and verify returns to exit 0. The comment's closing sentence reserved the 216th slot for `agent_catalog.rs`. That slot has since been taken by it, as intended, so the sentence is replaced rather than left reading as a pending claim. `RESERVED_SURFACE_FILES` is untouched at 15 and the invariant it guards still holds: `MAX_SURFACE_FILES - files.len()` is 0, well inside it, because the cap moved by exactly one alongside exactly one pin. Resealed through the documented inverted order for a changed pin list -- `reseal.sh --pins-changed` seals the new file list before rehashing, since `rehash-surface` validates `manifest_sha256` before it does anything and the ordinary order fails with `surface_checksum_mismatch`. Verified with every exit status read directly: tools workspace 11 binaries, 53 passed, 0 failed, including `surface_file_cap_refuses_one_entry_above_the_cap` and `real_tree_has_complete_migration_and_report_surface_coverage`, the two tests that assert on this constant. Compatibility gate passes. `reseal.sh --verify` exit 0. Co-Authored-By: Claude Opus 5 --- .../compatibility/compatibility-matrix.json | 2 +- .../compatibility/compatibility-surface.json | 8 +++-- tools/bridge-tally-compatibility/src/lib.rs | 31 +++++++++++++------ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/docs/tally/compatibility/compatibility-matrix.json b/docs/tally/compatibility/compatibility-matrix.json index 60a4f488..318d495a 100644 --- a/docs/tally/compatibility/compatibility-matrix.json +++ b/docs/tally/compatibility/compatibility-matrix.json @@ -1,7 +1,7 @@ { "schema_version": 1, "bridge_commit_sha": "be1c20cc3fd66fa1ece196505c69f26e555e4b8e", - "compatibility_surface_sha256": "c86a3689f0981f6015ddb908999701cb795bd8650330fd47d0d15414e5262986", + "compatibility_surface_sha256": "d573ae4e46106bc243cd3494fdb365226edc47e7f19908722110a81408e8e683", "claims": [ { "claim_id": "erp9-6-6-3-windows-education-xml-one-company", diff --git a/docs/tally/compatibility/compatibility-surface.json b/docs/tally/compatibility/compatibility-surface.json index d59de4e6..7395d77d 100644 --- a/docs/tally/compatibility/compatibility-surface.json +++ b/docs/tally/compatibility/compatibility-surface.json @@ -5,6 +5,10 @@ "path": ".github/workflows/ci.yml", "sha256": "c986297046d65dc1d218583410e693c9d017e1d72e3891d667012c8474db2ed1" }, + { + "path": ".github/workflows/dependency-security-scheduled.yml", + "sha256": "48b337dae3cf06d3cb6c3f9cef38dc1213608224626eb139cf6e12763aa9a543" + }, { "path": ".github/workflows/dependency-security.yml", "sha256": "fd70b9a317677100d6b760a369495f9e3c6a083d7cdbf8f1916267d97eaa250f" @@ -831,7 +835,7 @@ }, { "path": "tools/bridge-tally-compatibility/src/lib.rs", - "sha256": "993dfd51072f81d9f8b115d666de0d7830a10eec3a077d7fb690f6f206773b25" + "sha256": "e61a4815ce3d887fdb46481917546002f7d90d0ec913752aebaa68d232aa79e1" }, { "path": "tools/bridge-tally-compatibility/src/main.rs", @@ -866,5 +870,5 @@ "sha256": "a8ac2714fecf51947f2822c8c46d7ce2e8602c732780ff60566a7771f0836f9a" } ], - "manifest_sha256": "c86a3689f0981f6015ddb908999701cb795bd8650330fd47d0d15414e5262986" + "manifest_sha256": "d573ae4e46106bc243cd3494fdb365226edc47e7f19908722110a81408e8e683" } \ No newline at end of file diff --git a/tools/bridge-tally-compatibility/src/lib.rs b/tools/bridge-tally-compatibility/src/lib.rs index acb90a33..3af66c4d 100644 --- a/tools/bridge-tally-compatibility/src/lib.rs +++ b/tools/bridge-tally-compatibility/src/lib.rs @@ -31,22 +31,33 @@ pub const RESERVED_SURFACE_FILES: usize = 15; /// and manifest) but makes further unreviewed additions an explicit /// compatibility-surface decision. /// -/// **Raised three times by branches that did not see each other.** 210 to 211 -/// on master for `src-tauri/src/agent_ledgers.rs`, 211 to 212 for -/// `src-tauri/crates/bridge-tally-core/src/master_binding.rs`, and 212 to 215 -/// for the voucher-presence engine plus its adapter and admission-contract -/// assertion. Each reason stands; a merge that keeps a raise but loses its pin -/// would pass the gate with behavior silently outside the evidence boundary, -/// which is the failure this constant exists to make loud. +/// **Raised four times, the first three by branches that did not see each +/// other.** 210 to 211 on master for `src-tauri/src/agent_ledgers.rs`, 211 to +/// 212 for `src-tauri/crates/bridge-tally-core/src/master_binding.rs`, 212 to +/// 215 for the voucher-presence engine plus its adapter and admission-contract +/// assertion, and 216 to 217 for +/// `.github/workflows/dependency-security-scheduled.yml`. Each reason stands; a +/// merge that keeps a raise but loses its pin would pass the gate with behavior +/// silently outside the evidence boundary, which is the failure this constant +/// exists to make loud. /// /// `master_binding.rs` decides `validate_masters` results and, through them, /// import admission. Left unpinned, an edit confined to the matcher would leave /// the surface digest unchanged and let existing evidence attest behaviour it /// never covered. That is the deliberate decision the paragraph above requires, /// and it is one file for one named reason — not headroom. -/// The next slot binds `agent_catalog.rs`: its recursively executed proposal -/// schema changes presence admission, so existing receipts must cover its bytes. -pub const MAX_SURFACE_FILES: usize = 216; +/// +/// The slot this paragraph once reserved for `agent_catalog.rs` has been taken +/// by it, as intended. The raise to 217 binds +/// `dependency-security-scheduled.yml`, and the named reason is different in +/// kind from the ones above: it is the only workflow that runs unattended on a +/// schedule holding `issues: write`, and the only one of the five whose sibling +/// is pinned while it is not. Left unpinned, an edit that widened its +/// permissions or pointed its audit at a different lockfile would leave the +/// surface digest unchanged. Every other raise here bound a file that decides +/// what Bridge admits; this one binds a file that decides what Bridge is +/// allowed to do to its own repository while nobody is watching. +pub const MAX_SURFACE_FILES: usize = 217; pub const MAX_OPERATIONS: usize = 16; pub const MAX_CLAIMS: usize = 128; pub const MAX_KEYS: usize = 32;