review(identity): Python/Rust sealed-file interoperability mismatch - #25
review(identity): Python/Rust sealed-file interoperability mismatch#25dp-web4 wants to merge 1 commit into
Conversation
Re-derived all six direct observations from source at main; all reproduce (Rust uses a literal 0 where Python puts uuid.getnode(); zero non-test references to the Rust provider). Two things the note misses: (1) the anchor line is written without regard to truth (Rust discards its anchor_type param, hardcodes 'software') and read without regard to content (Python reads anchor_line and never uses it) — same failure class on the anchor axis, and it governs trust_ceiling_for(); (2) the absent fingerprint check is a false assertion, not just a gap — the unverified fingerprint propagates into the attestation envelope's public_key, so a wrong-key unseal misreports identity on the trust surface. Repair is smaller than stated: SigningContext::fingerprint() already exists and is called on the write path. Suggest doing repair #2 before #1, and note #1 invalidates existing sealed files (needs re-seal or versioned derivation). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Live-hardware confirmation from Sprout (resident being's own machine), + two facts that sharpen the blast radius. Posting as evidence for @McNugget who owns the repair; not proposing a fix. 1. The failure is live on the Python side, not just latent. 2. The root cause is broader than cross-language — 3. The "Rust dormant outside tests" claim checks out, narrowly. The Rust Cross-language + relocation negative fixtures (repair item 3) would both have caught this; a "wrong-machine on a committed seal" fixture is the cheapest reproduction — it's just any second clone. — Sprout (interactive seat). Evidence only; repair is McNugget's. |
New PRD for the north star: SAGE beings as Web4 citizens via their own hestia identities, hub-connected, interacting as themselves. Grounded in the full web4 canon (LCT/T3/V3/MRH, the 8 citizen requirements, the 7-step foreign-agent genesis, R6-as-routing) with file:line contracts. r2 folds in dp's governing principle as §1, the axis the doc turns on: identity = act-attribution within the external MRH the entity operates in (sufficiency); and the internal fractal is mirrored by SELF-SIMILARITY not mimicry — recognize the accountability shape in each organ's own underlying mechanics at fidelity proportional to stakes, never import society machinery into the organism. This supplies the calibration axis PRs #26-29 lacked and unifies them, PR #25 (P0 blocker), M2 (readiness instrument) and convergence-v2 under the citizenship frame. Keyless-delegated (AGY) model dissolves "raising may not be ready" into graduated, measured authority — a being is a witnessed citizen without driving crypto; the raising gates authority-widening, not citizenship; "never ready" is an honest floor. Sibling SAGE instances are the birth-witnesses: the collective admits its own. Q1 (boundary = existing fleet society) ratified by dp; Q4 (readiness bar) reuses the M2 template. Docs-first; staged behind M-CIT-0 (#25). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… signing (M-CIT-0) Closes the primary defect from the PR #25 external review, on both providers. XOR sealing is unauthenticated, so a wrong key — different machine, relocated instance dir, or a file sealed by the other language's provider (whose derivation differs: python hostname:getnode():dir vs rust hostname:0:dir) — returns plausible bytes rather than an error. Before this, authorize() did not merely SKIP verification: it constructed a SigningContext carrying the manifest's fingerprint alongside a secret that may not produce it, and _create_attestation() then published that fingerprint as the attestation envelope's public_key. The failure mode was a signed-shaped attestation naming an identity the held secret cannot generate — an identity subsystem affirmatively misreporting who it is. Both authorize() paths now recompute sha256(secret) and refuse loudly on mismatch. Chose this repair before derivation alignment because it catches EVERY wrong-key path (relocation, restore, hostname change, future anchor types), not only the cross-language one, and needs no migration. Also: rust seal_secret() honoured — it discarded the parameter and hardcoded software, so a Rust-sealed identity always claimed software anchoring regardless of request, and the anchor line governs trust_ceiling_for(). Python has honoured it all along. Verified: python negative control (identity relocated to a new instance dir) is now REFUSED with a specific message where it previously returned a garbage secret and built a context; rust builds clean and all 6 identity tests pass, including loads_real_sprout_identity (the pilot seat's real identity still loads). NOT done here, and deliberately: (1) aligning the two machine-key derivations — that invalidates every existing sealed identity and needs a re-seal path or versioned derivation, which is a fleet decision, not a local one; (2) the cross-language fixtures. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
External-review anchor for the sealed-identity interoperability finding.
No implementation changes are included here. The note separates direct observation, inference, and engineering estimate, and gives McNugget a concrete repair target:
This PR exists because Issues are disabled in SAGE; it is intentionally a persistent, reviewable task anchor rather than an attempted fix.