From 97f361d39414fb41040143238be302faa38c21a7 Mon Sep 17 00:00:00 2001 From: lamemustafa Date: Thu, 23 Jul 2026 12:16:40 +0530 Subject: [PATCH 1/9] feat(tally): stage sealed canary dispatch coordinator --- .../compatibility/compatibility-matrix.json | 2 +- .../compatibility/compatibility-surface.json | 10 ++-- .../synthetic-write-canary-fixture.md | 7 +++ .../crates/bridge-tally-write/Cargo.toml | 6 ++ .../crates/bridge-tally-write/src/lib.rs | 59 +++++++++++++++++++ .../bridge-tally-write/tests/qualification.rs | 31 ++++++++++ 6 files changed, 109 insertions(+), 6 deletions(-) diff --git a/docs/tally/compatibility/compatibility-matrix.json b/docs/tally/compatibility/compatibility-matrix.json index 4fa90a2..52bd61f 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": "9ed75ba3e74fb72f090ac822994046a549997f54abcc8b3519898c5aaa8f44a1", + "compatibility_surface_sha256": "f2c1948dd95c25f71d92f8cd12377e47f7f495364fd441da1bf7bf81fb096aca", "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 338b8fa..88302c2 100644 --- a/docs/tally/compatibility/compatibility-surface.json +++ b/docs/tally/compatibility/compatibility-surface.json @@ -59,7 +59,7 @@ }, { "path": "docs/tally/compatibility/synthetic-write-canary-fixture.md", - "sha256": "95bae833d5a81e06a9cc0f054772820ec05acdf95033173b68cd01b4af00f206" + "sha256": "33528375331ceeaf28e104e79ad51b965ead5035a10e4cdea855e0dcd48d00d6" }, { "path": "docs/tally/support-matrix.md", @@ -219,15 +219,15 @@ }, { "path": "src-tauri/crates/bridge-tally-write/Cargo.toml", - "sha256": "c5fc0b9e3a6c473708f2f2e641dfe13792993176d65b0bd511f5b8cca021d3d7" + "sha256": "bf248bcfd9d527f2d7eb6463a79be887bc74b39169d5fcf4a9e378d102f8c7ae" }, { "path": "src-tauri/crates/bridge-tally-write/src/lib.rs", - "sha256": "499ccce167185c1d1d2bb1a7a5559cc3546d17d6c79bd2f4fd6f030d6d99a93f" + "sha256": "9a3bd8ffad3016045dff9abec1353f322f98ccbb8be299ea989b374aeeff2aeb" }, { "path": "src-tauri/crates/bridge-tally-write/tests/qualification.rs", - "sha256": "c3b471b175a8b2b8b2d12afa5fe36b22c2f7437001898fb1177ada46acd03a3d" + "sha256": "4054636c61b948c0c3082675295c72e12ddc0c2bf9c3760dece4cf7aed5d94cf" }, { "path": "src-tauri/crates/tally-protocol-simulator/Cargo.toml", @@ -402,5 +402,5 @@ "sha256": "5a5c6eaaba234c3cbda52dfa040ed3314f79e535f744b87bc14d8d76a2299811" } ], - "manifest_sha256": "9ed75ba3e74fb72f090ac822994046a549997f54abcc8b3519898c5aaa8f44a1" + "manifest_sha256": "f2c1948dd95c25f71d92f8cd12377e47f7f495364fd441da1bf7bf81fb096aca" } diff --git a/docs/tally/compatibility/synthetic-write-canary-fixture.md b/docs/tally/compatibility/synthetic-write-canary-fixture.md index bce335b..86b81f8 100644 --- a/docs/tally/compatibility/synthetic-write-canary-fixture.md +++ b/docs/tally/compatibility/synthetic-write-canary-fixture.md @@ -24,6 +24,13 @@ timestamps. It does not store fixture content, company names, GUIDs, backup locations, or free text in the enrollment evidence tables. The UI must continue to report `write capability: Unknown`. +The normal Bridge build also cannot materialize the canary's import payload. A +separate disabled build feature provides only a one-use, in-memory, redacted +payload capsule with no endpoint, HTTP client, retry loop, persistence hook, or +command. Enabling that feature alone cannot contact Tally; a later reviewed +dispatch coordinator must bind it to the durable exact preflight evidence and +one-time dispatch claim before any request can be introduced. + Revocation appends a local `operator_revoked` event. It changes the local candidate gate only and never alters Tally. A revoked fixture requires a new fresh review and a new complete attestation before it can be enrolled again. diff --git a/src-tauri/crates/bridge-tally-write/Cargo.toml b/src-tauri/crates/bridge-tally-write/Cargo.toml index 4058660..ca471ed 100644 --- a/src-tauri/crates/bridge-tally-write/Cargo.toml +++ b/src-tauri/crates/bridge-tally-write/Cargo.toml @@ -8,6 +8,12 @@ publish = false edition = "2021" rust-version = "1.96" +[features] +# This feature is intentionally disabled by Bridge. Enabling it only exposes +# the sealed, one-use in-memory payload capsule; it does not add HTTP or any +# Tally transport. A later reviewed coordinator must opt in explicitly. +fixture-canary-dispatch-seam = [] + [dependencies] bridge-tally-core = { path = "../bridge-tally-core" } bridge-tally-protocol = { path = "../bridge-tally-protocol" } diff --git a/src-tauri/crates/bridge-tally-write/src/lib.rs b/src-tauri/crates/bridge-tally-write/src/lib.rs index 257c806..b9dbc2a 100644 --- a/src-tauri/crates/bridge-tally-write/src/lib.rs +++ b/src-tauri/crates/bridge-tally-write/src/lib.rs @@ -576,6 +576,44 @@ pub struct PreparedFixtureCanary { prepared: PreparedLedgerImport, } +/// An opaque, single-use in-memory capsule for the fixed fixture-canary XML. +/// +/// This is deliberately feature-gated and unavailable to Bridge's normal +/// build. It carries no transport, endpoint, retry policy, or persistence +/// hook. A separately reviewed coordinator may consume it exactly once only +/// after it has claimed durable preflight evidence and a dispatch attempt. +#[cfg(feature = "fixture-canary-dispatch-seam")] +pub struct SealedFixtureCanaryDispatch { + wire_xml: String, + wire_digest: WirePayloadDigest, +} + +#[cfg(feature = "fixture-canary-dispatch-seam")] +impl std::fmt::Debug for SealedFixtureCanaryDispatch { + fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + formatter + .debug_struct("SealedFixtureCanaryDispatch") + .field("wire_digest", &self.wire_digest) + .field("payload", &"[redacted]") + .field("transport", &"absent") + .finish() + } +} + +#[cfg(feature = "fixture-canary-dispatch-seam")] +impl SealedFixtureCanaryDispatch { + pub fn wire_digest(&self) -> &WirePayloadDigest { + &self.wire_digest + } + + /// Transfers the sealed XML to one caller-owned operation without + /// returning or persisting it. This method consumes the capsule, has no + /// retry behavior, and does not itself make a request. + pub fn consume_once(self, operation: impl FnOnce(&str) -> T) -> T { + operation(&self.wire_xml) + } +} + impl std::fmt::Debug for PreparedFixtureCanary { fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { formatter @@ -610,6 +648,25 @@ impl PreparedFixtureCanary { pub const fn dispatch_eligible(&self) -> bool { false } + + /// Materializes the immutable fixture payload only in the separately + /// opted-in dispatch-seam build. The normal Bridge build cannot name this + /// type or invoke this method. + #[cfg(feature = "fixture-canary-dispatch-seam")] + pub fn seal_for_dispatch(&self) -> Result { + let wire_xml = build_import_xml(&self.prepared.company, &self.prepared.mutations); + let wire_digest = WirePayloadDigest(domain_digest( + b"bridge.tally.ledger-import-wire/1\0", + wire_xml.as_bytes(), + )); + if wire_digest != self.prepared.wire_digest { + return Err(QualificationError::FixtureCanaryPayloadMismatch); + } + Ok(SealedFixtureCanaryDispatch { + wire_xml, + wire_digest: self.prepared.wire_digest.clone(), + }) + } } /// Digest-only proof that the fixed fixture canary is absent before a possible @@ -1078,6 +1135,8 @@ pub enum QualificationError { BackupAcknowledgementRequired, #[error("approval evidence does not bind the exact preview commitments")] ApprovalMismatch, + #[error("fixture canary payload does not match its approved commitment")] + FixtureCanaryPayloadMismatch, #[error("controlled ledger write batch must contain between one and ten items")] InvalidBatchSize, #[error("controlled ledger write input is invalid: {0}")] diff --git a/src-tauri/crates/bridge-tally-write/tests/qualification.rs b/src-tauri/crates/bridge-tally-write/tests/qualification.rs index 5826698..3540170 100644 --- a/src-tauri/crates/bridge-tally-write/tests/qualification.rs +++ b/src-tauri/crates/bridge-tally-write/tests/qualification.rs @@ -8,6 +8,9 @@ use bridge_tally_write::{ FIXTURE_CANARY_MAPPING_VERSION, MAX_LEDGER_WRITE_BATCH, }; +#[cfg(feature = "fixture-canary-dispatch-seam")] +use bridge_tally_write::SealedFixtureCanaryDispatch; + const COMPANY_GUID: &str = "00000000-0000-4000-8000-000000000001"; const REMOTE_ID: &str = "bridge-synthetic-ledger-001"; const HASH: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; @@ -293,6 +296,34 @@ fn fixture_canary_is_fixed_reservation_bound_and_dispatch_ineligible() { ); } +#[cfg(feature = "fixture-canary-dispatch-seam")] +#[test] +fn sealed_fixture_dispatch_capsule_is_explicit_one_use_and_redacted() { + let synthetic_company = company(); + let authorization = fixture_authorization( + &synthetic_company, + "fixture-dispatch-seam-reservation", + "fixture-dispatch-seam-idempotency", + ); + let prepared = prepare_fixture_canary_ledger_import( + synthetic_company, + authorization, + &mut IdempotencyRegistry::default(), + ) + .expect("prepare fixed fixture canary"); + + let capsule: SealedFixtureCanaryDispatch = prepared + .seal_for_dispatch() + .expect("seal exact fixed fixture canary payload"); + assert_eq!(capsule.wire_digest(), prepared.wire_digest()); + let debug = format!("{capsule:?}"); + assert!(debug.contains("[redacted]")); + assert!(!debug.contains("BRIDGE-CANARY-LEDGER-V1")); + + let payload_length = capsule.consume_once(str::len); + assert!(payload_length > 0); +} + #[test] fn approval_must_bind_the_exact_preview_commitments() { let company = company(); From 66a21d095e10b0d224dc4482e14ecef38920dc73 Mon Sep 17 00:00:00 2001 From: lamemustafa Date: Thu, 23 Jul 2026 12:53:45 +0530 Subject: [PATCH 2/9] fix(tally): consume sealed canary preparation --- docs/tally/compatibility/compatibility-matrix.json | 2 +- docs/tally/compatibility/compatibility-surface.json | 8 ++++---- .../compatibility/synthetic-write-canary-fixture.md | 10 ++++++---- src-tauri/crates/bridge-tally-write/src/lib.rs | 5 ++--- .../crates/bridge-tally-write/tests/qualification.rs | 3 ++- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/docs/tally/compatibility/compatibility-matrix.json b/docs/tally/compatibility/compatibility-matrix.json index 52bd61f..05cf00c 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": "f2c1948dd95c25f71d92f8cd12377e47f7f495364fd441da1bf7bf81fb096aca", + "compatibility_surface_sha256": "5aac3c14212be9fffcaaf817115f0c580f04ea25ca988f1c396882c36b657813", "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 88302c2..debea27 100644 --- a/docs/tally/compatibility/compatibility-surface.json +++ b/docs/tally/compatibility/compatibility-surface.json @@ -59,7 +59,7 @@ }, { "path": "docs/tally/compatibility/synthetic-write-canary-fixture.md", - "sha256": "33528375331ceeaf28e104e79ad51b965ead5035a10e4cdea855e0dcd48d00d6" + "sha256": "ee2d641b1943f92f85eac3b85660e4827c34729591b519f6ad2567e6c9e46a7d" }, { "path": "docs/tally/support-matrix.md", @@ -223,11 +223,11 @@ }, { "path": "src-tauri/crates/bridge-tally-write/src/lib.rs", - "sha256": "9a3bd8ffad3016045dff9abec1353f322f98ccbb8be299ea989b374aeeff2aeb" + "sha256": "0c23adadc32dbb0629851e55157cdbeb32bb05800afbb31e3c3b9ba12029ccd6" }, { "path": "src-tauri/crates/bridge-tally-write/tests/qualification.rs", - "sha256": "4054636c61b948c0c3082675295c72e12ddc0c2bf9c3760dece4cf7aed5d94cf" + "sha256": "bda25fa384c928a2ed7879eda0bb9e93e4be28c858c37e7584971d100ba9298a" }, { "path": "src-tauri/crates/tally-protocol-simulator/Cargo.toml", @@ -402,5 +402,5 @@ "sha256": "5a5c6eaaba234c3cbda52dfa040ed3314f79e535f744b87bc14d8d76a2299811" } ], - "manifest_sha256": "f2c1948dd95c25f71d92f8cd12377e47f7f495364fd441da1bf7bf81fb096aca" + "manifest_sha256": "5aac3c14212be9fffcaaf817115f0c580f04ea25ca988f1c396882c36b657813" } diff --git a/docs/tally/compatibility/synthetic-write-canary-fixture.md b/docs/tally/compatibility/synthetic-write-canary-fixture.md index 86b81f8..2a5eff4 100644 --- a/docs/tally/compatibility/synthetic-write-canary-fixture.md +++ b/docs/tally/compatibility/synthetic-write-canary-fixture.md @@ -26,10 +26,12 @@ to report `write capability: Unknown`. The normal Bridge build also cannot materialize the canary's import payload. A separate disabled build feature provides only a one-use, in-memory, redacted -payload capsule with no endpoint, HTTP client, retry loop, persistence hook, or -command. Enabling that feature alone cannot contact Tally; a later reviewed -dispatch coordinator must bind it to the durable exact preflight evidence and -one-time dispatch claim before any request can be introduced. +payload capsule. Sealing consumes the non-cloneable prepared canary, so one +prepared instance cannot yield a second capsule. It has no endpoint, HTTP +client, retry loop, persistence hook, or command. Enabling that feature alone +cannot contact Tally; a later reviewed dispatch coordinator must bind it to the +durable exact preflight evidence and one-time dispatch claim before any request +can be introduced. Revocation appends a local `operator_revoked` event. It changes the local candidate gate only and never alters Tally. A revoked fixture requires a new diff --git a/src-tauri/crates/bridge-tally-write/src/lib.rs b/src-tauri/crates/bridge-tally-write/src/lib.rs index b9dbc2a..d9b6e9b 100644 --- a/src-tauri/crates/bridge-tally-write/src/lib.rs +++ b/src-tauri/crates/bridge-tally-write/src/lib.rs @@ -571,7 +571,6 @@ pub struct PreparedLedgerImport { /// the generic import lifecycle. A separately reviewed coordinator may derive /// sealed, non-dispatchable preflight evidence from an exact readback, but it /// can never obtain a transport, receipt, or generic qualified-import state. -#[derive(Clone)] pub struct PreparedFixtureCanary { prepared: PreparedLedgerImport, } @@ -653,7 +652,7 @@ impl PreparedFixtureCanary { /// opted-in dispatch-seam build. The normal Bridge build cannot name this /// type or invoke this method. #[cfg(feature = "fixture-canary-dispatch-seam")] - pub fn seal_for_dispatch(&self) -> Result { + pub fn seal_for_dispatch(self) -> Result { let wire_xml = build_import_xml(&self.prepared.company, &self.prepared.mutations); let wire_digest = WirePayloadDigest(domain_digest( b"bridge.tally.ledger-import-wire/1\0", @@ -664,7 +663,7 @@ impl PreparedFixtureCanary { } Ok(SealedFixtureCanaryDispatch { wire_xml, - wire_digest: self.prepared.wire_digest.clone(), + wire_digest: self.prepared.wire_digest, }) } } diff --git a/src-tauri/crates/bridge-tally-write/tests/qualification.rs b/src-tauri/crates/bridge-tally-write/tests/qualification.rs index 3540170..2005fa1 100644 --- a/src-tauri/crates/bridge-tally-write/tests/qualification.rs +++ b/src-tauri/crates/bridge-tally-write/tests/qualification.rs @@ -312,10 +312,11 @@ fn sealed_fixture_dispatch_capsule_is_explicit_one_use_and_redacted() { ) .expect("prepare fixed fixture canary"); + let approved_wire_digest = prepared.wire_digest().clone(); let capsule: SealedFixtureCanaryDispatch = prepared .seal_for_dispatch() .expect("seal exact fixed fixture canary payload"); - assert_eq!(capsule.wire_digest(), prepared.wire_digest()); + assert_eq!(capsule.wire_digest(), &approved_wire_digest); let debug = format!("{capsule:?}"); assert!(debug.contains("[redacted]")); assert!(!debug.contains("BRIDGE-CANARY-LEDGER-V1")); From 7d92c8514166de65d57347d04e520314a43c887b Mon Sep 17 00:00:00 2001 From: lamemustafa Date: Thu, 23 Jul 2026 13:05:34 +0530 Subject: [PATCH 3/9] fix(tally): remove sealed payload callback --- .../compatibility/compatibility-matrix.json | 2 +- .../compatibility/compatibility-surface.json | 8 ++++---- .../synthetic-write-canary-fixture.md | 15 ++++++++------- .../crates/bridge-tally-write/src/lib.rs | 19 ++++++------------- .../bridge-tally-write/tests/qualification.rs | 6 +++--- 5 files changed, 22 insertions(+), 28 deletions(-) diff --git a/docs/tally/compatibility/compatibility-matrix.json b/docs/tally/compatibility/compatibility-matrix.json index 05cf00c..2dd7784 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": "5aac3c14212be9fffcaaf817115f0c580f04ea25ca988f1c396882c36b657813", + "compatibility_surface_sha256": "8b103247549e683b9a5b232a9245a9ce6cb873f5c66c46185f6565fd1510882d", "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 debea27..95d84f7 100644 --- a/docs/tally/compatibility/compatibility-surface.json +++ b/docs/tally/compatibility/compatibility-surface.json @@ -59,7 +59,7 @@ }, { "path": "docs/tally/compatibility/synthetic-write-canary-fixture.md", - "sha256": "ee2d641b1943f92f85eac3b85660e4827c34729591b519f6ad2567e6c9e46a7d" + "sha256": "138b7d89149be5bd8b18d76d062b03a737b8df5e40af2e0703ac5371b8ce5ace" }, { "path": "docs/tally/support-matrix.md", @@ -223,11 +223,11 @@ }, { "path": "src-tauri/crates/bridge-tally-write/src/lib.rs", - "sha256": "0c23adadc32dbb0629851e55157cdbeb32bb05800afbb31e3c3b9ba12029ccd6" + "sha256": "361c242ec01e686c99cdfbdf92d9e7cefe87d094f6fb2d478cbebf1a43dae5b2" }, { "path": "src-tauri/crates/bridge-tally-write/tests/qualification.rs", - "sha256": "bda25fa384c928a2ed7879eda0bb9e93e4be28c858c37e7584971d100ba9298a" + "sha256": "6fce830053f833b3e52c209fbd1bbcc130fbd98a8af83851bb35a069cea2d27c" }, { "path": "src-tauri/crates/tally-protocol-simulator/Cargo.toml", @@ -402,5 +402,5 @@ "sha256": "5a5c6eaaba234c3cbda52dfa040ed3314f79e535f744b87bc14d8d76a2299811" } ], - "manifest_sha256": "5aac3c14212be9fffcaaf817115f0c580f04ea25ca988f1c396882c36b657813" + "manifest_sha256": "8b103247549e683b9a5b232a9245a9ce6cb873f5c66c46185f6565fd1510882d" } diff --git a/docs/tally/compatibility/synthetic-write-canary-fixture.md b/docs/tally/compatibility/synthetic-write-canary-fixture.md index 2a5eff4..cf21982 100644 --- a/docs/tally/compatibility/synthetic-write-canary-fixture.md +++ b/docs/tally/compatibility/synthetic-write-canary-fixture.md @@ -25,13 +25,14 @@ locations, or free text in the enrollment evidence tables. The UI must continue to report `write capability: Unknown`. The normal Bridge build also cannot materialize the canary's import payload. A -separate disabled build feature provides only a one-use, in-memory, redacted -payload capsule. Sealing consumes the non-cloneable prepared canary, so one -prepared instance cannot yield a second capsule. It has no endpoint, HTTP -client, retry loop, persistence hook, or command. Enabling that feature alone -cannot contact Tally; a later reviewed dispatch coordinator must bind it to the -durable exact preflight evidence and one-time dispatch claim before any request -can be introduced. +separate disabled build feature provides only an opaque, in-memory, redacted +payload-commitment capsule. Sealing consumes the non-cloneable prepared canary, +so one prepared instance cannot yield a second capsule; the capsule retains no +XML and has no callback escape hatch. It has no endpoint, HTTP client, retry +loop, persistence hook, or command. Enabling that feature alone cannot contact +Tally; a later reviewed dispatch coordinator must bind it to the durable exact +preflight evidence and one-time dispatch claim before it introduces a +constrained single-send operation. Revocation appends a local `operator_revoked` event. It changes the local candidate gate only and never alters Tally. A revoked fixture requires a new diff --git a/src-tauri/crates/bridge-tally-write/src/lib.rs b/src-tauri/crates/bridge-tally-write/src/lib.rs index d9b6e9b..51cc08a 100644 --- a/src-tauri/crates/bridge-tally-write/src/lib.rs +++ b/src-tauri/crates/bridge-tally-write/src/lib.rs @@ -575,15 +575,16 @@ pub struct PreparedFixtureCanary { prepared: PreparedLedgerImport, } -/// An opaque, single-use in-memory capsule for the fixed fixture-canary XML. +/// An opaque, non-dispatchable capability capsule for the fixed fixture-canary +/// payload commitment. /// /// This is deliberately feature-gated and unavailable to Bridge's normal /// build. It carries no transport, endpoint, retry policy, or persistence -/// hook. A separately reviewed coordinator may consume it exactly once only -/// after it has claimed durable preflight evidence and a dispatch attempt. +/// hook, and it does not expose the XML. A separately reviewed runtime +/// coordinator must bind this capsule to a durable dispatch claim before it +/// introduces the one-send operation. #[cfg(feature = "fixture-canary-dispatch-seam")] pub struct SealedFixtureCanaryDispatch { - wire_xml: String, wire_digest: WirePayloadDigest, } @@ -604,13 +605,6 @@ impl SealedFixtureCanaryDispatch { pub fn wire_digest(&self) -> &WirePayloadDigest { &self.wire_digest } - - /// Transfers the sealed XML to one caller-owned operation without - /// returning or persisting it. This method consumes the capsule, has no - /// retry behavior, and does not itself make a request. - pub fn consume_once(self, operation: impl FnOnce(&str) -> T) -> T { - operation(&self.wire_xml) - } } impl std::fmt::Debug for PreparedFixtureCanary { @@ -648,7 +642,7 @@ impl PreparedFixtureCanary { false } - /// Materializes the immutable fixture payload only in the separately + /// Seals the immutable fixture payload commitment only in the separately /// opted-in dispatch-seam build. The normal Bridge build cannot name this /// type or invoke this method. #[cfg(feature = "fixture-canary-dispatch-seam")] @@ -662,7 +656,6 @@ impl PreparedFixtureCanary { return Err(QualificationError::FixtureCanaryPayloadMismatch); } Ok(SealedFixtureCanaryDispatch { - wire_xml, wire_digest: self.prepared.wire_digest, }) } diff --git a/src-tauri/crates/bridge-tally-write/tests/qualification.rs b/src-tauri/crates/bridge-tally-write/tests/qualification.rs index 2005fa1..6d780ba 100644 --- a/src-tauri/crates/bridge-tally-write/tests/qualification.rs +++ b/src-tauri/crates/bridge-tally-write/tests/qualification.rs @@ -298,7 +298,7 @@ fn fixture_canary_is_fixed_reservation_bound_and_dispatch_ineligible() { #[cfg(feature = "fixture-canary-dispatch-seam")] #[test] -fn sealed_fixture_dispatch_capsule_is_explicit_one_use_and_redacted() { +fn sealed_fixture_dispatch_capability_is_explicit_and_redacted() { let synthetic_company = company(); let authorization = fixture_authorization( &synthetic_company, @@ -319,10 +319,10 @@ fn sealed_fixture_dispatch_capsule_is_explicit_one_use_and_redacted() { assert_eq!(capsule.wire_digest(), &approved_wire_digest); let debug = format!("{capsule:?}"); assert!(debug.contains("[redacted]")); + assert!(debug.contains("absent")); assert!(!debug.contains("BRIDGE-CANARY-LEDGER-V1")); - let payload_length = capsule.consume_once(str::len); - assert!(payload_length > 0); + assert_eq!(capsule.wire_digest(), &approved_wire_digest); } #[test] From 03c81d1eca13d28f843e432234f5c6727fe51c6e Mon Sep 17 00:00:00 2001 From: lamemustafa Date: Thu, 23 Jul 2026 13:24:49 +0530 Subject: [PATCH 4/9] fix(ci): run checks when draft PR becomes ready --- .github/workflows/ci.yml | 1 + .github/workflows/dependency-security.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7a3b150..05a7b16 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,7 @@ on: branches: [master] pull_request: branches: [master] + types: [opened, reopened, synchronize, ready_for_review] workflow_dispatch: concurrency: diff --git a/.github/workflows/dependency-security.yml b/.github/workflows/dependency-security.yml index afd1ae8..1dc1c86 100644 --- a/.github/workflows/dependency-security.yml +++ b/.github/workflows/dependency-security.yml @@ -5,6 +5,7 @@ on: branches: [master] pull_request: branches: [master] + types: [opened, reopened, synchronize, ready_for_review] workflow_dispatch: concurrency: From cae18a36b0d5a9bb0d6051b9134b410f81e10d1e Mon Sep 17 00:00:00 2001 From: lamemustafa Date: Thu, 23 Jul 2026 13:30:36 +0530 Subject: [PATCH 5/9] fix(tally): seal CI workflow compatibility surface --- docs/tally/compatibility/compatibility-matrix.json | 2 +- docs/tally/compatibility/compatibility-surface.json | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/tally/compatibility/compatibility-matrix.json b/docs/tally/compatibility/compatibility-matrix.json index 2dd7784..9812eee 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": "8b103247549e683b9a5b232a9245a9ce6cb873f5c66c46185f6565fd1510882d", + "compatibility_surface_sha256": "4d23b5c3808cae3ddd2ecea86ae407ce4dfbe9586cbfe1f76236223c37a76238", "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 95d84f7..fe07313 100644 --- a/docs/tally/compatibility/compatibility-surface.json +++ b/docs/tally/compatibility/compatibility-surface.json @@ -3,7 +3,11 @@ "files": [ { "path": ".github/workflows/ci.yml", - "sha256": "82d494e0bd68051ce0858b0f7f4f47da8666e583fb27b947a36f82435c749e36" + "sha256": "245124719902bbf22eeeec4da5e911168fd3eb9f138a28cb29dc65b3f60c7ea0" + }, + { + "path": ".github/workflows/dependency-security.yml", + "sha256": "c9cd4394235a82bda9149cd77c8c5bff81f3d4ad8091fc2022e536776f03dd9f" }, { "path": "docs/adr/0004-tally-write-safety.md", @@ -402,5 +406,5 @@ "sha256": "5a5c6eaaba234c3cbda52dfa040ed3314f79e535f744b87bc14d8d76a2299811" } ], - "manifest_sha256": "8b103247549e683b9a5b232a9245a9ce6cb873f5c66c46185f6565fd1510882d" + "manifest_sha256": "4d23b5c3808cae3ddd2ecea86ae407ce4dfbe9586cbfe1f76236223c37a76238" } From 6f10fb9dac9ee2b27cbe7605974c0ff0ec563b7d Mon Sep 17 00:00:00 2001 From: lamemustafa Date: Thu, 23 Jul 2026 13:37:25 +0530 Subject: [PATCH 6/9] fix(tally): bind CI surface to canonical bytes --- docs/tally/compatibility/compatibility-matrix.json | 2 +- docs/tally/compatibility/compatibility-surface.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tally/compatibility/compatibility-matrix.json b/docs/tally/compatibility/compatibility-matrix.json index 9812eee..af7ede7 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": "4d23b5c3808cae3ddd2ecea86ae407ce4dfbe9586cbfe1f76236223c37a76238", + "compatibility_surface_sha256": "917f0d774a0636d7681ce315e65cc8c8a85b1383e3a341c0829578f635cdd1ff", "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 fe07313..3710a7e 100644 --- a/docs/tally/compatibility/compatibility-surface.json +++ b/docs/tally/compatibility/compatibility-surface.json @@ -7,7 +7,7 @@ }, { "path": ".github/workflows/dependency-security.yml", - "sha256": "c9cd4394235a82bda9149cd77c8c5bff81f3d4ad8091fc2022e536776f03dd9f" + "sha256": "e3ca89eb7870a75391d3321fc10f5e01fc3f82200c58c31705cf240fe4b3426d" }, { "path": "docs/adr/0004-tally-write-safety.md", @@ -406,5 +406,5 @@ "sha256": "5a5c6eaaba234c3cbda52dfa040ed3314f79e535f744b87bc14d8d76a2299811" } ], - "manifest_sha256": "4d23b5c3808cae3ddd2ecea86ae407ce4dfbe9586cbfe1f76236223c37a76238" + "manifest_sha256": "917f0d774a0636d7681ce315e65cc8c8a85b1383e3a341c0829578f635cdd1ff" } From 4a363bd937f9180c07ace42bb9f4a0e23d03a663 Mon Sep 17 00:00:00 2001 From: lamemustafa Date: Thu, 23 Jul 2026 13:41:49 +0530 Subject: [PATCH 7/9] chore(ci): refresh final dispatch review checks From 67401fe55d477aa3c5e05d3832a0d487d3426af3 Mon Sep 17 00:00:00 2001 From: lamemustafa Date: Thu, 23 Jul 2026 21:46:34 +0530 Subject: [PATCH 8/9] feat(tally): guide explicit company discovery --- scripts/tally-company-selection.test.mjs | 28 +++++++++++++++++ src/main.tsx | 39 +++++++++++++++++++++++- src/styles.css | 34 +++++++++++++++++++++ src/tally-company-selection.ts | 37 ++++++++++++++++++++++ 4 files changed, 137 insertions(+), 1 deletion(-) diff --git a/scripts/tally-company-selection.test.mjs b/scripts/tally-company-selection.test.mjs index 2254abe..434c258 100644 --- a/scripts/tally-company-selection.test.mjs +++ b/scripts/tally-company-selection.test.mjs @@ -5,6 +5,7 @@ import test from "node:test"; import { applyProbeCompanySelectionTransition, + companyDiscoveryPrompt, clearCompanyScopedState, reconcileProbeCompanySelection, } from "../src/tally-company-selection.ts"; @@ -163,3 +164,30 @@ test("a selected company retained by the probe is not reported as dropped", () = { selectedCompany: "", dropped: false }, ); }); + +test("a successful probe prompts the operator to explicitly choose a discovered company", () => { + assert.deepEqual(companyDiscoveryPrompt("", ["company-a"]), { + companyCount: 1, + heading: "1 company discovered", + detail: "Bridge identified the current Tally company list. Choose one explicitly before reading or saving any company-scoped data.", + actionLabel: "Choose company", + }); + assert.deepEqual(companyDiscoveryPrompt("", ["company-a", "company-b"]), { + companyCount: 2, + heading: "2 companies discovered", + detail: "Bridge identified the current Tally company list. Choose one explicitly before reading or saving any company-scoped data.", + actionLabel: "Choose company", + }); + assert.equal(companyDiscoveryPrompt("company-a", ["company-a"]), null); + assert.equal(companyDiscoveryPrompt("", []), null); +}); + +test("a direct compatibility listing prompts verification instead of selecting an untrusted identity", () => { + assert.deepEqual(companyDiscoveryPrompt("", [], 1), { + companyCount: 1, + heading: "1 company listed for verification", + detail: "Tally returned a compatibility company listing. Verify the intended company before Bridge treats its identity as evidence or enables company-scoped reads.", + actionLabel: "Verify company", + }); + assert.equal(companyDiscoveryPrompt("selected-company", [], 1), null); +}); diff --git a/src/main.tsx b/src/main.tsx index fa033c2..52b4dc2 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -2,7 +2,11 @@ import React from "react"; import ReactDOM from "react-dom/client"; import { Activity, Building2, Cable, CircleHelp, Cloud, Database, FileText, FolderOpen, KeyRound, Play, RefreshCw, ShieldCheck, UploadCloud } from "lucide-react"; import { invoke } from "@tauri-apps/api/core"; -import { applyProbeCompanySelectionTransition, clearCompanyScopedState } from "./tally-company-selection"; +import { + applyProbeCompanySelectionTransition, + clearCompanyScopedState, + companyDiscoveryPrompt, +} from "./tally-company-selection"; import "./styles.css"; type TallyConfig = { @@ -977,6 +981,22 @@ function App() { ); setSelectedCompany(selection.selectedCompany); void refreshPersistedCompanyProfiles(); + setUntrustedDiscoveredCompanies([]); + setUntrustedDiscoveryError(null); + setUntrustedDiscoveryCompleted(false); + if (result.profile.transports.xml_http?.safe_reason_code === "direct_company_report_untrusted") { + try { + const discovered = await invoke("fetch_tally_companies", { config }); + if (resultsVersion === tallyResultsVersion.current) { + setUntrustedDiscoveredCompanies(discovered); + setUntrustedDiscoveryCompleted(true); + } + } catch (error) { + if (resultsVersion === tallyResultsVersion.current) { + setUntrustedDiscoveryError(toOperatorError(error)); + } + } + } } } catch (error) { if (resultsVersion === tallyResultsVersion.current) { @@ -1846,6 +1866,11 @@ function App() { const gstDraftComplete = draft !== null && draft.missing_fields.length === 0; const selectedCompanyRecord = companies.find((company) => tallyCompanyKey(company) === selectedCompany); const selectedCompanyLive = !!selectedCompanyRecord && liveCompanyKeys.includes(tallyCompanyKey(selectedCompanyRecord)); + const discoveredCompanyPrompt = companyDiscoveryPrompt( + selectedCompany, + liveCompanyKeys, + untrustedDiscoveredCompanies.length, + ); React.useEffect(() => { const mirrorCompanyId = selectedCompanyRecord?.mirror_company_id; setFixtureStatus(null); @@ -1995,6 +2020,18 @@ function App() { + {discoveredCompanyPrompt && ( +
+
+ {discoveredCompanyPrompt.heading} + {discoveredCompanyPrompt.detail} +
+ +
+ )} + {["dashboard", "companies", "mirror"].includes(view) && (
Verified baseline{verifiedBaseline}
diff --git a/src/styles.css b/src/styles.css index 7bdad60..6f3fa42 100644 --- a/src/styles.css +++ b/src/styles.css @@ -592,6 +592,34 @@ h2 { overflow-wrap: anywhere; } +.company-discovery-notice { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; + border: 1px solid #9bc9b6; + border-left: 4px solid #0f766e; + border-radius: 8px; + background: #f0fdf7; + color: #183b2e; + margin: 0 0 16px; + padding: 14px 16px; +} + +.company-discovery-notice div { + display: grid; + gap: 4px; +} + +.company-discovery-notice span { + color: #416257; + line-height: 1.45; +} + +.company-discovery-notice .primary { + flex: 0 0 auto; +} + .operator-question-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); @@ -1079,10 +1107,16 @@ summary:focus-visible, } .company-context-bar, + .company-discovery-notice, .company-profile-grid, .gap-item { grid-template-columns: 1fr; } + + .company-discovery-notice { + align-items: stretch; + flex-direction: column; + } } @media (max-width: 520px) { diff --git a/src/tally-company-selection.ts b/src/tally-company-selection.ts index 709226f..dde02ed 100644 --- a/src/tally-company-selection.ts +++ b/src/tally-company-selection.ts @@ -16,6 +16,13 @@ export type ProbeSelectionTransition = { dropped: boolean; }; +export type CompanyDiscoveryPrompt = { + companyCount: number; + heading: string; + detail: string; + actionLabel: string; +}; + export type ProbeSelectionEffects = { clearDroppedCompanyScope: () => void; installProbeState: () => void; @@ -43,6 +50,36 @@ export function applyProbeCompanySelectionTransition( return transition; } +export function companyDiscoveryPrompt( + selectedCompany: string, + liveCompanyKeys: readonly string[], + untrustedCompanyCount = 0, +): CompanyDiscoveryPrompt | null { + if (selectedCompany !== "") return null; + + if (liveCompanyKeys.length > 0) { + const companyCount = liveCompanyKeys.length; + const companyLabel = companyCount === 1 ? "company" : "companies"; + return { + companyCount, + heading: `${companyCount} ${companyLabel} discovered`, + detail: "Bridge identified the current Tally company list. Choose one explicitly before reading or saving any company-scoped data.", + actionLabel: "Choose company", + }; + } + + if (untrustedCompanyCount === 0) return null; + + const companyCount = untrustedCompanyCount; + const companyLabel = companyCount === 1 ? "company" : "companies"; + return { + companyCount, + heading: `${companyCount} ${companyLabel} listed for verification`, + detail: "Tally returned a compatibility company listing. Verify the intended company before Bridge treats its identity as evidence or enables company-scoped reads.", + actionLabel: "Verify company", + }; +} + export function clearCompanyScopedState(cleanup: CompanyScopeCleanup) { cleanup.clearQualifiedReadReview(); cleanup.clearPassportSnapshot(); From 04b65e1c0c931f3f64af9e25524e6c19318a1053 Mon Sep 17 00:00:00 2001 From: lamemustafa Date: Fri, 24 Jul 2026 02:14:06 +0530 Subject: [PATCH 9/9] Fix untrusted company discovery after selection drop --- docs/tally/compatibility/compatibility-matrix.json | 2 +- .../tally/compatibility/compatibility-surface.json | 6 +++--- scripts/tally-company-selection.test.mjs | 14 ++++++++++++++ src/main.tsx | 5 +++-- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/docs/tally/compatibility/compatibility-matrix.json b/docs/tally/compatibility/compatibility-matrix.json index cab896e..a7a0e45 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": "da2b848422d7738688ce1835430b07639cd67ac98c9ab0cb35425fea02465fd9", + "compatibility_surface_sha256": "5c8d498284805f92bf5c0b8c2804ceb90e54f1e0fa97c21a53d5fd3f30541117", "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 bc8d7f8..2704d4c 100644 --- a/docs/tally/compatibility/compatibility-surface.json +++ b/docs/tally/compatibility/compatibility-surface.json @@ -79,7 +79,7 @@ }, { "path": "scripts/tally-company-selection.test.mjs", - "sha256": "a8f1ba11dcd975f3eb0358992179c691fcf6a74617bb101f50602da7b8057fd8" + "sha256": "95fba10a4ffed1db0ea1f539578eb2eb4334f0c6fa8dba38c051cc1a4cfebbb3" }, { "path": "src-tauri/Cargo.lock", @@ -419,7 +419,7 @@ }, { "path": "src/main.tsx", - "sha256": "b383ed9b39cd6abd11501616e2387fe63aec107f00c402ed60b3a34e90ade54b" + "sha256": "919190e826f06940fbe2640c8e453f2e04de1262a6ad3e41f28430b8467491c2" }, { "path": "src/styles.css", @@ -430,5 +430,5 @@ "sha256": "dd033010711ca01a7a395a531285c6ef187a359640a156cbc8da7281e11a39ea" } ], - "manifest_sha256": "da2b848422d7738688ce1835430b07639cd67ac98c9ab0cb35425fea02465fd9" + "manifest_sha256": "5c8d498284805f92bf5c0b8c2804ceb90e54f1e0fa97c21a53d5fd3f30541117" } diff --git a/scripts/tally-company-selection.test.mjs b/scripts/tally-company-selection.test.mjs index 434c258..da526b9 100644 --- a/scripts/tally-company-selection.test.mjs +++ b/scripts/tally-company-selection.test.mjs @@ -118,6 +118,20 @@ test("an automatic probe drop clears old company state before installing a usabl ); }); +test("discovery requested after a dropped selection remains current after cleanup", () => { + const state = companyScopedState(); + const probeResultsVersion = state.tallyResultsVersion; + + applyProbeCompanySelectionTransition("old-company", [], { + clearDroppedCompanyScope: () => clearCompanyScopedState(cleanupFor(state)), + installProbeState: () => {}, + }); + const discoveryResultsVersion = state.tallyResultsVersion; + + assert.notEqual(probeResultsVersion, state.tallyResultsVersion); + assert.equal(discoveryResultsVersion, state.tallyResultsVersion); +}); + test("a manual company selection clears the existing review and all company-scoped state", () => { const state = companyScopedState(); diff --git a/src/main.tsx b/src/main.tsx index 52b4dc2..4938da1 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -985,14 +985,15 @@ function App() { setUntrustedDiscoveryError(null); setUntrustedDiscoveryCompleted(false); if (result.profile.transports.xml_http?.safe_reason_code === "direct_company_report_untrusted") { + const discoveryResultsVersion = tallyResultsVersion.current; try { const discovered = await invoke("fetch_tally_companies", { config }); - if (resultsVersion === tallyResultsVersion.current) { + if (discoveryResultsVersion === tallyResultsVersion.current) { setUntrustedDiscoveredCompanies(discovered); setUntrustedDiscoveryCompleted(true); } } catch (error) { - if (resultsVersion === tallyResultsVersion.current) { + if (discoveryResultsVersion === tallyResultsVersion.current) { setUntrustedDiscoveryError(toOperatorError(error)); } }