Foundational Manual: Executable Baseline-Lock Loop
This note captures the current drafting doctrine for the first executable baseline-lock loop.
It is not a production-readiness claim.
It is not a Phase 2 completion claim.
It is not formal partner authorization.
It is not an implementation issue.
It complements:
- `FOUNDATIONAL_MANUAL_BASELINE_LOCK.md`
- `FOUNDATIONAL_MANUAL_STATE_PROJECTION_AND_COMPACTION.md`
- `FOUNDATIONAL_MANUAL_IDENTITY_RECOVERY_AND_CAPABILITIES.md`
- `FOUNDATIONAL_MANUAL_TRUSTLESS_CLIENT_BOUNDARY.md`
- `FOUNDATIONAL_MANUAL_ECONOMIC_STATE_RESOLUTION.md`
The goal is to turn the Foundational Manual from doctrine into an executable proof.
Proposed first PR
Recommended PR title:
test(runtime): add executable baseline-lock loop fixture
Purpose:
Prove one institution-local process can move from receipted history to sealed facts to WASM validation to Rust authorization to new receipts to evidence export to member-legible Action Card state.
This PR should not attempt the whole system.
It should not include live federation, live gossip, production mobile routing, real bridge execution, or production readiness claims.
It should prove one spine.
If the test does not pass, the doctrine is not yet real.
Core target
The first executable proof should deliberately ignore the network.
No federation.
No live gossip.
No mobile multipath routing.
No external bridge.
No production persistence claims.
The first sprint should prove the core constitutional spine in a single-node, deterministically mocked integration test.
The test should be named something like:
cargo test test_baseline_lock_loop
The goal:
Prove that ICN can move one institution-local process from receipted history to canonical facts to WASM validation to Rust authorization to new receipts to evidence export to member-legible Action Card state.
If that loop works, the manual has a runtime spine.
Runtime sequence
sequenceDiagram
participant DAG as Receipt DAG Fixture
participant Host as Rust Host / Process Substrate
participant Projector as State Projector
participant WASM as WASM Guest
participant Receipts as Receipt Store
participant UX as Action Card Projection
DAG->>Host: Load signed process receipts
Host->>Projector: Resolve process frontier
Projector->>Projector: Verify signatures, standing, notice, votes
Projector-->>Host: Sealed StateResolutionCapsule
Projector-->>Host: CanonicalFacts
Host->>Host: Build ExecutionInputEnvelope
Host->>WASM: evaluate(input_bytes)
WASM->>WASM: Validate bounded facts only
WASM-->>Host: ExecutionOutputEnvelope
Host->>Host: Validate output as hostile
Host->>Host: Check process_id, target_ref, schema, transition kind
Host->>Receipts: Emit ProcessGateResultReceipt
Host->>Receipts: Emit AllocationAuthorizedReceipt
Host->>Receipts: Emit economic receipt if applicable
Receipts-->>Host: Updated receipt frontier
Host->>UX: Export evidence packet
UX-->>Host: ActionCard: Allocation Authorized
The Meaning Firewall is enforced at the narrowest point:
WASM receives facts.
WASM returns evaluation.
Rust owns authority.
Rust emits receipts.
The institution supplies meaning.
Test fixture: build the receipt DAG
Before the host can resolve state, there must be state to resolve.
The first test fixture should manually instantiate a hardcoded Merkle-DAG of process receipts.
The fixture should fake history, not final state.
The fixture should create:
test cooperative key
test host key
three dummy member keys
one process id
one target allocation object
one simple charter rule: approvals > 50%
one simple economic limit
The fixture should manually sign and link:
ProcessSessionOpenedReceipt
StandingContextSnapshotReceipt or StandingContextHash
Recovery/identity material omitted or mocked for this first loop
NoticeDeliveredReceipt entries
DeliberationEntryRecordedReceipt entries representing votes
For the first test:
eligible members = 3
approvals = 2
rejections = 1
threshold rule = approvals > 50%
allocation requested = within local limit
This creates a static, mathematically valid, offline history that the Rust host can traverse.
No database magic.
No ambient state.
Just receipts.
Fixture safety notes
Toy cryptography is acceptable only for an early smoke-test sketch.
The actual PR should use deterministic test helpers backed by the project's real hash/signature primitives where possible.
Avoid collision-prone helpers like:
Hash([data.len() as u8; 32])
That proves nothing about content addressing.
Use a stable hash over canonical bytes.
Mock signers may be test-only, but they should still bind:
receipt type
receipt fields
prior receipt hash
process_id
target_ref
signer id
Otherwise the test can pass while the causal chain is fake.
Rust projector and envelope builder
The Rust host then runs a pure projection function against the fixture.
The projector takes:
receipt_dag
process_id
target_ref
required_rule_ref
It verifies:
receipt signatures
receipt hashes
causal links
process_id matches the target process
receipt target_ref matches the target object where relevant
standing snapshot exists
eligible voter set
notice receipts
vote receipt validity
vote signers are eligible at the standing frontier
notice was delivered to every eligible voter
no duplicate votes unless an explicit rule resolves replacement
vote receipts belong to the process window
allocation request is linked to the target object
reservation has not already been consumed
frontier sufficiency for this mocked institution-local process
It outputs a sealed fact snapshot:
CanonicalFacts
eligible_voters = 3
votes_cast = 3
approvals = 2
rejections = 1
abstentions = 0
required_approvals = 2
notice_delivered = true
allocation_requested = N
allocation_limit = M
reservation_not_consumed = true
The projector should fail before WASM if the institutional history is insufficient.
Missing notice should not merely become a polite false unless the process rule explicitly allows the guest to evaluate that condition.
For baseline lock, the stronger rule is:
If a required due-process fact is missing, the host does not seal the envelope.
This keeps civil-rights constraints out of the guest's discretion.
The host then wraps sealed facts in an ExecutionInputEnvelope:
ExecutionInputEnvelopeV1
abi_version
schema_id
workload_id
module_hash
process_id
target_ref
state_resolution_capsule_hash
canonical_fact_snapshot_hash
authority_context_hash
standing_context_hash
agreement_context_hash
mandate_ref
rule_ref
determinism_class
privacy_class
finality_class
fuel_limit
input_artifact_refs
canonical_facts
expected_output_schema
Serialization must be deterministic.
Use a typed canonical binary format.
No JSON for the governance-grade envelope unless it is strictly canonicalized.
No unordered maps.
No floating point.
No timestamps generated inside the WASM guest.
WASM validation guest
The first WASM guest should be intentionally stupid.
That is the point.
It should not know cooperatives.
It should not know democracy.
It should not know Alice.
It should not know money.
It should expose one function:
evaluate(input_bytes) -> output_bytes
The actual ABI must return both output pointer and output length, either through a packed return, an out-parameter, or an allocation ABI.
A naked output pointer is not sufficient.
Fixture implementation (icn-baseline-lock-guest): The reference guest is #![no_std] + alloc on wasm32-unknown-unknown. It is excluded from the root icn/ workspace and ships its own Cargo.lock so workspace dependency feature unification cannot pull serde/postcard defaults (and thus std) onto the WASM target. icn-boundary likewise pins serde and postcard with explicit default-features = false instead of inheriting them from [workspace.dependencies]. The checked-in icn_baseline_lock_guest.wasm is produced by ./scripts/build-baseline-lock-guest.sh (uses cargo … --locked) and must match sources in PRs that touch the guest.
It deserializes the input envelope, performs bounded checks, and returns an output envelope.
For the first test, it checks:
approvals >= required_approvals
notice_delivered == true
allocation_requested <= allocation_limit
reservation_not_consumed == true
It returns:
ExecutionOutputEnvelopeV1
abi_version
schema_id
workload_id
process_id
result_kind = GateValidation
passed = true
diagnostics
proposed_transition_ref
consumed_fuel
The guest does not write receipts.
The guest does not query state.
The guest does not call authority functions.
The guest does not mutate anything.
It computes over bounded facts.
That is all.
Paranoid host orchestrator
The Rust host runs the WASM module as untrusted code.
This is the final execution bridge in the single-node baseline-lock loop.
The host is not a convenience wrapper around WASM.
It is the authority boundary.
It must place the guest in a silent vacuum, inject the sealed input envelope, read the output envelope, and validate every identity-bearing field before any receipt can be emitted.
The runtime must disable ambient authority.
No WASI filesystem.
No network.
No host clock.
No random source.
No environment variables.
No database handle.
No callback to fetch state.
No callback to write receipts.
The host configures:
fuel limit
memory limit
expected ABI version
expected input schema
expected output schema
module hash
runtime profile
maximum output length
The host must validate the WASM module before execution:
hash wasm_bytes
compare to input.module_hash
reject mismatch before instantiation or execution
The host then serializes the input envelope, allocates guest memory through a narrow guest ABI, writes the input bytes into guest memory, and calls:
evaluate(input_ptr, input_len) -> packed_result
The result must include both output pointer and output length.
A naked pointer is not sufficient.
Candidate packed return:
high 32 bits = output_ptr
low 32 bits = output_len
The host must reject outputs that exceed the configured maximum size before reading the guest memory.
Then the host reads output bytes, deserializes the output envelope, records consumed fuel, and treats the result as hostile until validation succeeds.
Hostile-output validation must check more than process_id:
abi_version
schema_id == expected_output_schema
workload_id
process_id
result_kind
proposed_transition_ref allowed for this workload
module_hash binding
fuel consumed <= fuel limit
output length <= max output length
no unauthorized transition kind
Only after those checks should the host consider passed meaningful.
Only after that should the host emit receipts.
Candidate orchestrator shape:
WasmOrchestrator::execute_workload_safely(
wasm_bytes,
ExecutionInputEnvelopeV1
) -> Result<ExecutionOutputEnvelopeV1, HostExecutionError>
The orchestrator sequence is:
- Hash and verify the WASM module against
module_hash. - Configure
wasmtimewith fuel consumption enabled. - Instantiate without WASI.
- Extract
memory,alloc, andevaluateexports. - Serialize the input envelope with deterministic encoding.
- Allocate guest memory.
- Write input bytes.
- Execute the guest.
- Unpack output pointer and length.
- Reject oversized output.
- Read output bytes.
- Deserialize output envelope.
- Record consumed fuel.
- Validate ABI, schema, workload, process, result kind, and transition permissions.
- Return output to the Rust Process Substrate for receipt emission.
This closes the execution loop.
The guest computes.
The host validates.
The host authorizes.
The host emits receipts.
Receipt emitter
If the WASM result passes and the host independently validates the output envelope, Rust binds the result to institutional reality.
The host emits:
ProcessGateResultReceipt
Then it applies the authorized mutation plan and emits:
AllocationAuthorizedReceipt
If the allocation consumes or reserves a scarce claim, the host also emits the appropriate economic receipt:
ResourceReservationOpenedReceipt
or:
ResourceReservationConsumedReceipt
Each new receipt must link to:
prior_receipt_hash
process_id
target_ref
state_resolution_capsule_hash
canonical_fact_snapshot_hash
input_envelope_hash
output_envelope_hash
module_hash
authority_context_hash
agreement_context_hash
mandate_ref
signature
This proves the central law:
WASM validates bounded facts.
Rust authorizes state transition.
Receipts preserve institutional memory.
Evidence packet and Action Card export
The final step is human legibility.
The test should export an evidence packet containing:
process_id
target_ref
input_envelope_hash
output_envelope_hash
module_hash
state_resolution_capsule_hash
canonical_fact_snapshot_hash
ProcessGateResultReceipt
AllocationAuthorizedReceipt
economic receipt if applicable
signature set
frontier hash
Then it should project member-facing Action Card state:
ActionCard
title = "Allocation authorized"
status = InstitutionFinal or InstitutionReserved
authority_summary
decision_summary
receipt_refs
evidence_packet_ref
challenge_path
accessibility_summary
This proves that the system did not merely execute.
It explained itself.
A constitutional machine that cannot explain itself to a member is just admin software with better cryptography.
Acceptance criteria
The first baseline-lock integration test passes only if all of the following are true:
- Receipt fixture signatures verify.
- Receipt causal links verify.
- Standing projection produces the expected eligible set.
- Vote projection produces the expected canonical facts.
- State Resolution Capsule seals only after required facts are present.
- Execution input envelope hash is stable across repeated runs.
- WASM module hash is stable.
- WASM executes without WASI, network, filesystem, host clock, or database access.
- WASM output envelope hash is stable across repeated runs.
- Host rejects malformed or mismatched output envelopes.
- Host emits
ProcessGateResultReceiptonly after validating the output. - Host emits
AllocationAuthorizedReceiptonly after the process gate passes. - Economic validation rejects an over-limit or double-reserved allocation in a negative test.
- Evidence packet exports all required hashes and receipt refs.
- Action Card projection renders the final status and receipt references.
- Re-running the test from the same fixture produces identical hashes.
- Changing one vote, signature, module hash, or allocation limit fails the expected validation path.
This is baseline lock in miniature.
Not the full system.
The seed crystal.
Negative tests
The first executable loop should include negative cases immediately.
Required negative tests:
invalid member signature is rejected
non-member vote is excluded or rejected
duplicate vote is rejected or resolved by rule
missing notice prevents gate sealing
threshold failure prevents ProcessGateResultReceipt
WASM output with wrong process_id is rejected
WASM output with unexpected transition kind is rejected
allocation above limit is rejected
double reservation is rejected
changed module hash invalidates expected execution
stale state frontier prevents envelope sealing where freshness is required
wrong process_id in fixture receipt is rejected
wrong target_ref in fixture receipt is rejected
broken prior_receipt link is rejected
oversized WASM output is rejected
module hash mismatch is rejected before execution
The negative tests matter as much as the happy path.
A constitutional substrate that only proves success has not proven safety.
First runtime spine
The implementation target can be summarized as:
receipt fixture
↓
state projector
↓
StateResolutionCapsule
↓
CanonicalFacts
↓
ExecutionInputEnvelope
↓
WASM evaluate(bytes)
↓
ExecutionOutputEnvelope
↓
Rust validation
↓
ProcessGateResultReceipt
↓
AllocationAuthorizedReceipt
↓
evidence packet
↓
Action Card projection
That is the first runtime spine.
If this passes in a terminal, the manual is no longer only a manual.
It is documentation for a functioning digital constitution.
Suggested first implementation tasks
The first code PR should stay small enough to review.
Suggested task breakdown:
- Add or reuse typed test-only receipt structs for the fixture.
- Add deterministic hashing helpers for the fixture receipts.
- Add test key generation and signing helpers.
- Build a fixture receipt DAG for one institution-local proposal.
- Implement a pure projection function that derives
CanonicalFacts. - Add deterministic envelope serialization.
- Add a tiny WASM guest crate with
evaluate(input_bytes) -> output_bytes. - Add host-side WASM execution with no WASI imports.
- Add output-envelope validation and hostile-output rejection.
- Emit
ProcessGateResultReceiptandAllocationAuthorizedReceiptin the test harness. - Export a minimal evidence packet.
- Project a minimal Action Card JSON object.
- Add negative tests before expanding scope.
Review rule:
Any change that requires live networking, federation, bridge execution, production persistence, or real mobile routing is out of scope for the first PR.
Immediate next priority
After the boundary crate and fixture/projector skeleton exist, build the wasmtime host orchestrator before CI polish.
CI should run the test once it exists.
But the next architectural risk is not whether CI can execute cargo test.
The next architectural risk is whether the Rust host can run the WASM guest in a silent vacuum:
no WASI
no filesystem
no network
no host clock
no random source
no environment variables
no database handle
no authority callback
no receipt-writing callback
The build order is:
boundary crate
receipt DAG fixture
state projector
WASM guest
wasmtime host orchestrator
full integration test
CI gate
CI is the enforcement layer.
The host orchestrator is the firewall layer.
Build the firewall first.
Manual insertion points
When integrating this into the full Foundational Manual:
- Add this after economic state resolution and before field-demonstration readiness.
- Keep it explicitly single-node and mocked.
- Do not include live gossip, federation, bridge execution, or production persistence claims.
- Treat negative tests as baseline-lock requirements, not optional hardening.
- Preserve the no-overclaim rule: this document is doctrine and drafting guidance, not a claim that the runtime is complete.
Closing doctrine
Do not start with the whole world.
Start with one honest loop.
Receipts first.
Facts sealed.
WASM bounded.
Rust authoritative.
Evidence exported.
Member state legible.
Then expand.