[L1-6] (Phase A) ed25519 signing + 8-event contract chain primitives#1447
Closed
joelteply wants to merge 2 commits into
Closed
[L1-6] (Phase A) ed25519 signing + 8-event contract chain primitives#1447joelteply wants to merge 2 commits into
joelteply wants to merge 2 commits into
Conversation
* feat(commands): add typed execution scope * chore: lower linux eslint baseline --------- Co-authored-by: Test <test@test.com>
…n primitives Roadmap item L1-6 — Phase A. Builds on L1-1 (#1445) for the event-class registry. Phase B (verify-on-replay via L1-4's peer-manifest + airc-cursor replay over L1-2 transport) lands in a follow-up once L1-4 merges. Closes roadmap item L1-6 (Phase A — primitives + types + registration + tests) Depends on: L1-1 (PR #1445, pending review) Defers: L1-4 (presence:peer-manifest, in flight by claude-tab-1) + L1-2 (AircEventTransport trait, already merged as #1443) Spec: GRID-BUS-ARCHITECTURE §4.4 + MULTI-PEER-COMMANDS §7 Why split Phase A vs B - Phase A is pure crypto + types + declarations — zero runtime deps on L1-4 or L1-2 transports. - Phase B wires the verifier-side: pulls signer pubkeys from L1-4's peer-manifest index, hooks into L1-2's AircEventTransport.replay() for audit-replayable chain verification. - Shipping A now means review can focus on the cryptographic substance before transport plumbing layers on top. What this lands Rust truth (continuum-core::contracts): - signing.rs — ed25519 primitives matching airc-protocol's pinned ed25519-dalek = "2". Wrappers ContractSigningKey + ContractVerifyingKey give future migration room (HSM, secure enclave) without touching call sites. Deterministic ed25519 → replay-equivalent signatures across peers. canonical_hash() uses serde_json's BTreeMap-backed Value for key-sorted SHA-256 input — same bytes regardless of build, the keystone for cross-peer verify-equality. Verify returns Err on failure (NOT Ok(false)) so callers can't accidentally treat a failed verify as success. - event_classes.rs — the 8 contract event class names (constants) + typed payload structs (ts-rs export to shared/generated/contracts/). Each payload carries contract_id for chain correlation. declare_contract_event_classes() registers all 8 with the L1-1 registry, broadcast=true, channel=Global, schemaVersion=v1. - envelope.rs — generic SignedContractEvent<P> wrapper. Signature pins (event_name, payload) together so relabeling attacks (presenting a bid sig as proposed) fail verification. Hex-encoded pubkey + signature on the wire. Tests (31 pass via cargo test --features metal,accelerate contracts) - signing: keygen→sign→verify roundtrip, pubkey roundtrip-through-bytes, bad-signature-fail-loud, wrong-payload-fail-loud, cross-key-verify-fail, ed25519-determinism, canonical-hash-stable-across-field-order, signature/pubkey length validation. - event_classes: all-8-names-distinct, all-use-contract-prefix, declare-registers-all-eight (dogfoods the L1-1 registry). - envelope: sign-then-verify roundtrip, relabeling-attack-fails, payload-mutation-fails, signature-mutation-fails, pubkey-swap-fails, JSON-round-trips-bit-exact, hex-helpers roundtrip + reject-bad-input. - chain_tests: full 8-event proposed→bid→accepted→executing→delivered→ verified→paid worked example (zero-LP household tier "ping grid dispatch"), disputed-event-signs-and-verifies, JSON-bit-exact round trip on the full chain. What this does NOT do (Phase B follow-up) - Pull signer pubkeys from L1-4's presence:peer-manifest index at verify time. Today verify returns the pubkey-that-signed; callers must cross-check against an external trust source. - Subscribe to airc-cursor replay over L1-2's AircEventTransport for audit-reproducible chain verification. - TS thin SDK wrapper (parallel to @system/events/shared/EventClass.ts). Deferred until a TS consumer materializes — Phase A consumers are Rust-side (router daemon, persona admission). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
06957a5 to
25156a5
Compare
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
L1-6 Phase A — pure Rust primitives. The verifier-side integration (Phase B) lands after L1-4 (presence:peer-manifest) merges.
AircEventTransport, already merged) — Phase B will subscribe itsreplay()for audit-reproducible chain verificationWhy Phase A / Phase B split
Phase A is pure crypto + types + declarations. Zero runtime deps on L1-4 or L1-2 transports. Shipping it now means review can focus on the cryptographic substance before transport plumbing layers on top.
Phase B wires:
presence:peer-manifestindex at verify timeAircEventTransport.replay()for audit-reproducible chain verificationWhat this lands
Rust truth (
continuum-core::contracts)signing.rs— ed25519 primitives matching airc-protocol's pinneded25519-dalek = "2".ContractSigningKey/ContractVerifyingKeywrappers — gives future migration room (HSM, secure enclave) without touching call sitescanonical_hash()usesserde_json'sBTreeMap-backedValueto produce key-sorted SHA-256 input — same bytes regardless of build, the keystone for cross-peer verify-equalityverify()returnsErr(NOTOk(false)) so callers can't accidentally treat a failed verify as successevent_classes.rs— the 8 contract event class names + typed payload structs (ts-rs export toshared/generated/contracts/)contract_idfor chain correlationdeclare_contract_event_classes()registers all 8 with the L1-1 registry —broadcast: true,channel: Global,schemaVersion: v1envelope.rs— genericSignedContractEvent<P>wrapper(event_name, payload)together so relabeling attacks (presenting a bid sig as proposed) fail verificationCrypto choices
ed25519-dalek = "2"airc-protocol's pinned version — peer signing keys advertised through L1-4'spresence:peer-manifestuse the SAME byte layout this module verifies. No re-encoding, no protocol bridging.verify() -> Result<>notResult<bool>Tests (31 pass via
cargo test --features metal,accelerate contracts)proposed → bid → accepted → executing → delivered → verified → paidworked example (zero-LP household tier "ping grid dispatch"); disputed-event signs + verifies; JSON-bit-exact round trip on the full chainOut of scope (Phase B follow-up)
presence:peer-manifestindex at verify timeAircEventTransportfor audit-reproducible chain verification@system/events/shared/EventClass.ts). Deferred until a TS consumer materializes — Phase A consumers are Rust-side (router daemon, persona admission)Test plan
cd src/workers/continuum-core && cargo test --features metal,accelerate contracts(31 tests)🤖 Generated with Claude Code