SectionCurrent referenceStatuslivingLast reviewed2026-09-13

ICN Organizational Technical Alpha — Control Plan

What this document is. One navigable reconstruction of the entire Organizational Technical Alpha program: the bounded claim, the proof chain, the dependency graph, the containment ledger, and the owner boundaries. It exists so that a maintainer who has never seen a planning conversation can reconstruct the program from the repository alone.

What this document is not. It is not a truth owner. It owns no domain fact. Every status below is a snapshot taken at one revision, and ops/state/truth/sources.json routes each underlying fact to its real owner. Where this document and an owner disagree, the owner wins and this document is the stale layer.

Live state is owned by live_issue_state / live_pr_state / live_ci_state (github-api), not by this file. Re-resolve with gh before acting on any status here. Snapshot revision: 82030804dc26003bf7e1d6e289166989108bcd63, taken 2026-09-13.

Post-snapshot addenda. A row that changed because of the commit carrying it is marked inline as a post-snapshot addendum rather than silently refreshed, so this file never reads as a single reproducible snapshot when it is really mixed. Re-taking the snapshot means re-verifying every row, which is a deliberate act and not a side effect of one row moving.


1. The bounded claim

The Technical Alpha is not "make ICN production ready." It is one bounded, independently witnessed proof at one exact reviewed revision and profile.

The strongest intended eventual claim, in full:

On one exact reviewed ICN Alpha profile, a fresh context-scoped human Subject used a separately keyed, explicitly delegated device Principal to act as a recognized member of an institution; that standing authorized participation in a frozen governance process over one exact bounded resource action; the resulting decision was cryptographically committed to a canonical decision hash; existing ICN economic and execution machinery carried that same hash through the bounded resource action and retained provenance; an independent Node B verified the retained evidence offline while Node A was unreachable; and the verifier/recovery node subsequently survived the separately specified encrypted destroy/restore proof.

Anything stronger is not part of A1 unless added through reviewed owner work.

The program's own exit criteria are owned by icn#2689 section 10 — seventeen checkboxes, all unchecked at this snapshot. They are not duplicated here.

Standing non-claims

A1 does not claim any of:

  • production readiness, availability, or operational maturity;
  • federation, multi-institution operation, or cross-institution identity;
  • that a contained defect is fixed;
  • hot or live backup;
  • generalized N3/N4/N5 protocol completeness;
  • that any downstream repository lock is human-signed;
  • that an HTTP fetch from Node A constitutes independent verification;
  • native cryptographic binding between a governance decision and a ledger entry (see 6.4 — this specifically does not exist today).

2. Proof chain, with every arrow resolved

Each arrow resolves to exactly one of: an existing reviewed owner primitive, a bounded implementation slice, an explicit containment, or an explicit non-claim. There is no "then somehow this works" edge.

# Link Resolves to State at snapshot
1 substrate to reproducible node/profile appliance image + manifest; icnctl appliance verify-manifest EXISTS; (post-snapshot addendum) ADR-0086 reached status: accepted on 2026-09-15 through ADR-0018's lifecycle and the profile is frozen at 860c6f6c22f1; at the snapshot revision it was still proposed. implementation_status remains a separate axis and is still partially implemented
2 to two-node communication isolated QEMU topology in the two-node plan EXISTS (plan, Canonical: no)
3 to institution package/domain InstitutionBootstrapManifest (icn-governance/src/bootstrap.rs:14); icnctl institution runtime-root EXISTS but disclaims canonical institution genesis (6.6)
4 to fresh current-semantic human Subject SubjectContextGenesisV1 SLICE — icn#2695 (design-reviewed, unimplemented)
5 to separately keyed delegated device Principal DeviceGrant (icn-identity/src/authority_log/derive.rs:25) PRIMITIVE EXISTS; unreferenced outside icn-identity
6 to explicit institutional recognition SubjectRecognitionV1 SLICE — no owner issue
7 to frozen governance process VotingProcessSnapshotV1 SLICE — no owner issue
8 to exact bounded resource-action commitment SemanticProposalCommitmentV1 SLICE — no owner issue
9 to signed Subject ballot(s) MemberVoteActionV1 + immutable ballot slot SLICE — no owner issue
10 to deterministic tally SubjectVoteSetHashV1 + tally SLICE — no owner issue
11 to GovernanceDecisionReceiptV4 V4 DOES NOT EXIST. V1 evidence is path-dependent across five separable surfaces — Rejected/NoQuorum construct no gate or chain-store V1 but do produce a signed V1 inside durable proof_bytes when a signing key is configured; non-executing and forced-accept closes persist no chain-store V1 (matrix in 6.3). A1 must pin a close path on two axes: decision-hash-addressable and proposal-id-addressable evidence are different things.
12 to canonical decision_hash compute_decision_hash_bytes (icn-governance/src/proof.rs:300) EXISTS and exposes canonical bytes
13 to existing AllocationReceipt icn-kernel-api/src/receipts.rs:121 EXISTS; canonical bytes private (6.2); unsigned in practice
14 to existing SettlementIntent icn-kernel-api/src/economics.rs:80 EXISTS; canonical bytes private; no signature field
15 to execution ExecutionRecord (execution.rs:78) EXISTS; mutable operational state, not a canonical receipt
16 to ledger/provenance evidence JournalEntry + ProvenanceRef EXISTS; provenance is not in the hash and not signed (6.4)
17 to self-contained offline evidence offline bundle contract SLICE — icn#2465 (spec only, no implementation)
18 to Node A unreachable two-node plan Gate 4 step 5 is literally "Disconnect Node A" — isolation, not a service or VM stop Gate 4 BLOCKED
19 to Node B independently verifies reviewed offline verifier SLICE — icn#2465
20 to encrypted destroy/restore continuity recovery bundle SLICE — icn#2466; Gate 6 BLOCKED
21 to same evidence still independently verifiable re-run of 19 post-restore depends on 19 + 20

Eleven of twenty-one links are unbuilt. Links 11, 13, 14 and 16 carry concrete owner problems documented in section 6, not merely missing code.


3. Dependency DAG

            SAFETY / CORRECTNESS FRONTIER
                       |
                       v
            EXACT ALPHA DEPLOYMENT PROFILE
                       |
        +--------------+--------------+
        v              v              v
    icn#2694       icn#2465       icn#2466
    semantic       offline        recovery
    convergence    evidence       proof
        |              |              |
        |              |              |
        +--------------+--------------+
                       v
              TWO-NODE A1 WITNESS
                       v
             FREEZE EXACT SHA/PROFILE
                       v
                 NYCN LOCK BUMP
                       v
            HUMAN REHEARSAL / A11Y
                       v
             BOUNDED PUBLIC CLAIM

This diagram is reconciled, not immutable. Two edges are sharper than the ASCII suggests:

  • #2465 depends on #2694 for its subject matter (there is no decision receipt to export until the ladder produces one), but its substrate work (slice B) does not — that can start immediately. Slice A is conditional and gates nothing until the verifier model selects a cross-language or raw-preimage requirement (5.6, 6.2).
  • #2466 is independent of #2694 entirely. It is a sovereignty proof about node state, not about semantics.

4. icn#2694 — semantic convergence ladder

The missing proof is generation convergence, not invention of another economic system. The target path, in the issue's own vocabulary:

context-bound N1 Subject genesis -> N1 device authorization
  -> institutional Subject recognition -> context-scoped session
  -> immutable voting-process snapshot -> preview
  -> device-signed member vote action -> immutable Subject ballot
  -> Subject tally -> GovernanceDecisionReceiptV4 -> canonical decision_hash
  -> existing AllocationReceipt -> existing SettlementIntent
  -> existing ExecutionRecord -> existing journal/provenance
  -> offline evidence bundle

#2694 states that each numbered item becomes a bounded child issue only when its direct owner contracts have been reverified and implementation is authorized. That gate has fired exactly once.

# Slice Owner issue Upstream contract owner State
1 GEN-A context binding + SubjectContextGenesisV1 icn#2695 #2602 GEN OPEN, status:needs-design, design-reviewed, unimplemented
2 N1-D restart-durable AuthorityFactStore none #2607 named by #2695 as the next child
3 GEN-B SubjectRecognitionV1 none #2602 GEN unowned
4 HumanActorModel / legacy-rail firewall none unowned; appears in no other issue
5 N4-alpha relying-party prefix evaluation none #2599 N4 unowned
6 G1-A commitment + frozen VotingProcessSnapshotV1 none #2600 G1 unowned
7 context-aware session rail none unowned; no artifact name
8 N5-A MemberVoteActionV1 + ballot slot none #2605 N5 unowned
9 Subject vote-set hash + deterministic tally none unowned
10 GovernanceDecisionReceiptV4 none unowned; see 6.3
11 V4 decision_hash through the economic chain none #2625 identifier domain unowned
12 offline evidence convergence partially #2465 / #2466 composition step itself unowned

None of the twelve artifact names exists in icn/crates or icn/apps at this revision. No PR references #2694 or #2695.


5. icn#2465 — offline evidence architecture

5.1 Architecture

bundle transport / exact bytes
            |
            v
existing owner artifact verification
            |
            v
cross-artifact binding verification
            |
            v
externally pinned A1 policy
            |
            v
        composed verdict

Do not invent a parallel evidence ontology. The repository already owns the verdict vocabulary: VerificationStatus at icn/crates/icn-governance/src/verify.rs:46Pass / Fail / Unresolved / NotApplicable, fail-closed, with fold severity Fail > Unresolved > Pass > NotApplicable. Normative spec: docs/spec/receipt-chain-verification.md (status: draft). Reuse it; do not mint a second verdict set.

Keep distinct: integrity, authenticity, authorization, legitimacy. verify.rs is explicit that a Pass means integrity — and authenticity when keyed — and never authorization or legitimacy.

5.2 Two hard criteria (verbatim, do not weaken)

  • The bundle exports no DIDs or credentials beyond the producer identity the contract explicitly requires.
  • Verification never falls back to contacting the producer — a network call in the verify path is a defect, not a convenience.

Neither admits tiering. Missing required evidence yields Unresolved or failure — never a network lookup. No gateway URL, no producer callback, no remote DID resolver, no HTTP client anywhere in the verify path.

If the chosen A1 economic action cannot satisfy the privacy criterion, that is a concrete owner/integration problem to surface — not a licence to redact a security-critical owner-canonical field and still call it independently verifiable.

5.3 Evidence strength — additive planning vocabulary

This taxonomy does not exist in the repository. It is proposed here, not established.

Tier Meaning Expected members
OwnerCanonical owner computes and owns the canonical identity GovernanceDecisionReceiptV4, AllocationReceipt, SettlementIntent
OwnerAuthenticated owner-canonical and signed by a named key none today — see 6.2
ProducerAttestedSnapshot producer asserts it exported this view ExecutionEvidenceSnapshotV1, JournalProvenanceWitnessV1

It must not be used to soften 5.2.

5.4 Two digest meanings — never collapse

Meaning Algorithm today Subject
owner canonical identity blake3 over bincode (receipts.rs:100); blake3 over a domain-tagged stream (governance) domain-semantic identity
exact exported payload SHA-256 these exact bytes were retained/exported

These are different algorithms over different subjects. Conflating them is a defect, because canonical hashes intentionally exclude fields — see 6.2.

5.5 Producer attestation

A producer signature means "this producer exported this exact manifest/artifact-byte set." It does not mean "everything in this bundle is legitimate." Policy and trust are pinned externally; the bundle must not choose how it is judged:

verify_offline_bundle(retained_bundle, externally_pinned_policy, externally_pinned_trust)

5.6 Decomposition

#2465 defines no bounded slices. A search of 400 issues found zero hits for TechnicalAlphaA1Policy, RecoveryBundle, JournalProvenanceWitness or ExecutionEvidenceSnapshot — in issues or in the checkout.

Slice Scope Owner
A owner canonical export surfaces expose owner-controlled canonical bytes for AllocationReceipt / SettlementIntent CONDITIONAL — do not schedule yet. Needed only if A1 selects a cross-language/non-linking verifier or a raw-preimage requirement (6.2). A Rust-linked verifier recomputes through the public trait, and 5.4's SHA-256 over the exported payload already catches changes to excluded fields such as memo.
B deterministic generic offline-bundle substrate byte-stable bundle, digest manifest, no network needs an issue
C bounded A1 execution/journal evidence adapters ExecutionEvidenceSnapshotV1, JournalProvenanceWitnessV1 needs an issue
D TechnicalAlphaA1PolicyV1 + composed proof externally pinned policy, tamper-negative test needs an issue

Slice A must not change the semantic hashes of those types merely to support export, and must not be scheduled at all until the A1 verifier model picks one of the two narrower requirements in 6.2. Together, the owner hash (recomputed through the public trait) and the exported-payload SHA-256 already cover both canonical-field tampering and tampering with fields the canonical hash excludes.


6. Owner boundaries, seams, and live contradictions

This section records what the code actually does. It is the part most likely to invalidate planning vocabulary.

6.1 No registered owner for economics

ops/state/truth/sources.json has 26 domains, and only two touch this proof chain: identity_semantics (docs/architecture/IDENTITY_SEMANTICS.md) and adr_decisions (docs/adr/). There is no registered truth domain for receipts, provenance, ledger, settlement, treasury or economics. For those, the ADRs plus the code are the only authority.

6.2 Canonical bytes are private for both economic receipts

AllocationReceiptCanonical (receipts.rs:148) and SettlementIntentCanonical (economics.rs:122) are module-private, and no API returns the preimage bytes — only the blake3 digest escapes. The governance path is the opposite: compute_decision_hash_bytes (proof.rs:300) is pub.

This is not a blocker for every verifier, and an earlier revision overstated it. AllocationReceipt, SettlementIntent and CanonicalReceipt are all publicly re-exported (lib.rs:83, :121), so a Rust verifier that links icn-kernel-api recomputes owner hashes through the public trait, exactly as the gateway already does (receipt_store.rs:504, api/receipts.rs:65). Slice A is therefore not a precondition for a Rust-linked verifier.

It remains a real limitation for exactly two cases, and A1 should state which it needs:

  1. a cross-language or non-linking verifier, which would have to reverse-engineer an unpublished bincode layout — field order, the exclusion of receipt_id/signature, and the sorting of intent_hashes;
  2. any verifier needing raw preimage bytes for a byte-level tamper manifest, since no public surface yields them.

Two live traps for any bundle contract, stated per type because they differ:

  • AllocationReceipt::canonical_hash sorts intent hashes, so the canonical identity is order-independent. Its signature is #[serde(skip_serializing_if = "Option::is_none")]serialized whenever present, not skipped — so an exported payload does carry a signature that the canonical hash excludes.
  • SettlementIntent has no signature field at all. Only intent_id is #[serde(skip)]; memo is skip_serializing_if, so it is exported when present while being excluded from the canonical hash.

So the exported payload is strictly wider than the canonical preimage, and mutating memo leaves canonical_hash unchanged. A digest manifest covering only canonical hashes would therefore pass #2465's "flip one byte, must fail" criterion on a genuinely tampered bundle.

This is not an argument for slice A, and an earlier revision wrongly called it "the sharpest reason slice A exists." Exposing the owner-canonical preimage cannot detect a changed memo either — SettlementIntentCanonical excludes that field for exactly the same reason canonical_hash does. The mutation is caught by 5.4's SHA-256 over the exact exported payload, which is a separate mechanism and needs no new API. Slice A's justification rests solely on the two narrower requirements above, if A1 selects one.

Also: AllocationReceipt::with_signature has no production caller (unsigned in practice), and SettlementIntent has no signature field at all. Hence OwnerAuthenticated in 5.3 currently has no members.

6.3 Governance receipt versions

V1 (proof.rs:226), V2 (:541, defined but never emitted), V3 (:820). V4 does not exist — zero repo-wide hits for ReceiptV4.

An earlier revision of this document described the seam as "V3 emitted, V1 persisted." Review corrected that, and re-verification against main agrees. The accurate shape is:

Treating "V1 constructed" and "V1 persisted" as one property is too coarse: there are five separable surfaces, and no close path has all of them.

  1. gate/hash V1 — a receipt built only to derive the gate/decision hash, never stored
  2. chain-store V1 — persisted via put_governance (decision-hash addressable)
  3. V1 inside GovernanceProofV2 — a receipt constructed during proof construction
  4. durable proof_bytes — those signed proof bytes written to the proposal state store
  5. V3 — persisted opaquely via put_opaque
Close path gate V1 chain-store V1 V1-in-ProofV2 durable proof_bytes V3
Actor Accepted, non-exec-required yes no if signing_key if signing_key if capability_scope and receipt_store
Actor Accepted, exec-required yes yes (fatal on failure) if signing_key if signing_key if capability_scope
Actor Rejected no no if signing_key if signing_key if capability_scope + receipt_store
Actor NoQuorum no no if signing_key if signing_key if capability_scope + receipt_store
Timer / scheduler by outcome by outcome if signing_key if signing_key nevercapability_scope: None is hardcoded
ForceCloseProposal Accept only no no no — bare save_proposal, no journal no
GovernanceManager::close_proposal_inner n/a yes, all outcomes (requires receipt_store) no no if capability_scope

The proof path is gated on signing_key alone — not on outcome, not on receipt_store, not on capability_scope — and it covers all three terminal outcomes. Its bytes are genuinely durable: close journal save_close_intent then commit then save_proof_bytes, landing under the sled key governance:proof:{proposal_id}.

So "no chain-store persistence" does not mean "no durable V1." An actor-driven Rejected, NoQuorum or non-execution-required Accepted close writes a complete signed GovernanceDecisionReceipt inside proof_bytes while put_governance is never called.

But that evidence is differently addressable: it lives in the proposal state store rather than the receipt backend, under a proposal-id key, behind a different reader, and it carries no decision_hash index. The chain read surfaces — get_governance_by_decision, the receipt-chain endpoint, and icnctl audit verify — structurally cannot see it.

  • V3 is emitted conditionally and additionally, not as a replacement: actor.rs:2561 gates on a present capability_scope and a configured receipt store.
  • V3 is persisted, but opaquely — receipt_backend.rs:509 writes it through put_opaque, so it never crosses the gateway's typed boundary.
  • The real seam is the read surface. The gateway store's typed API is V1 only (receipt_store.rs:386 put_governance, :426 get_governance), and icnctl audit verify recomputes the V1 decision hash (icnctl/src/main.rs:12752) through a local verify_receipt_chain (:12702) rather than through icn-governance::verify.

So a V4 does not have to reconcile a persistence mismatch. It has to decide what the typed chain/audit read surface returns, whether conditional V3 emission becomes unconditional, and whether decision-hash-addressable evidence is required at all when proposal-id-addressable signed evidence already exists.

A1 must pin a close path on two independent axes, not one:

  • signing_key: Some buys proposal-id-addressable V1 evidence for every terminal outcome, via proof_bytes;
  • only execution-required Accepted (actor), or any outcome under the standalone manager with a receipt store, buys decision-hash-addressable chain evidence.

If the A1 read surface is decision-hash-keyed — which every existing chain reader is — the proof-bytes route does not satisfy it. Note also that signing_key is a node-configuration fact, not a governance fact, so this evidence's existence depends on deployment wiring rather than on the decision itself.

A stale comment at proof.rs:817 still reads "No handler emits a v3 receipt yet — this is schema preparation only." That is now false, and is recorded here as a follow-up rather than fixed, because this is a control-plane document and that is a Rust change.

6.4 The ledger provenance limitation — be exact

compute_entry_hash (icn-ledger/src/hash.rs:9) is serde_json then SHA-256 over HashableEntry (hash.rs:37-45), which carries timestamp, author, contract_ref, accounts, parents, nonce. ProvenanceRef is absent. sign_entry (entry.rs:28) signs entry.id.

Therefore: the author signature does not bind the governance decision_hash. Provenance can be altered without invalidating either the hash or the signature.

An earlier revision went further and said no production code cross-verifies the correspondence at all, and that the gateway "only echoes" the hash. That was wrong. Correspondence is checked, at three clearly different strengths — A1 should neither duplicate the real ones nor inherit the weak one:

Strength Where What it establishes
Existence — real gateway loads the receipt by hash (api/receipts.rs:397) a hash with no stored receipt yields governance: None and fails closed (icnctl/src/main.rs:12628)
Self-consistency by recomputation — real recompute_decision_hash_matches (main.rs:12617), surfaced as "Decision hash integrity (recomputed)" (:12752) the V1 hash rebuilt from proposal_id/domain_id/outcome/tally/vote_hash matches
Journal-to-decision linkage — NOT established "check 13" (main.rs:12909) tautological. The gateway selects entries by that predicate (api/receipts.rs:515), so no entry with a different hash can be in the set. A filter restated as an assertion.

None of it is cryptographic: vote_hash and the tally come from the gateway response and are never checked against actual votes, and the receipt carries no verified signature. The recompute proves internal consistency of server-supplied fields, not authorization — as its own comment concedes. The A1 position is therefore unchanged in substance — the governance-to-ledger link is not owner-authenticated — but the plan must not claim the correspondence is wholly unchecked.

Do not rewrite ledger identity casually, and do not claim native cryptographic strength that does not exist. For A1 the bounded evidence architecture may use a producer-attested witness connecting entry_hash, decision_hash and provenance_kind, while explicitly reporting that proof strength. A future owner-defined governance-to-ledger binding receipt may supersede it.

6.5 Three incompatible canonical-hash schemes

Layer Scheme
kernel-api receipts bincode then blake3
governance proof domain-tagged byte stream then blake3
ledger journal serde_json then SHA-256

No single re-verification primitive spans them. A bundle verifier must dispatch per artifact class rather than assume one hash function.

6.6 Institution genesis is not canonical yet

icnctl institution runtime-root (shipped in #2744/#2749) creates two keystores, a cooperative record, a treasury registration, trust edges and a receipt — but its own doc comments disclaim canonical institution genesis: no EntityId, no signed founding act, no institution DID, and genesis_authority_did is today the same principal as node_did. It is not idempotent and not restartable. ADR-0083's "runtime root" is a different, not-started concept.

6.7 The fail-closed verifier is wired to nothing

icn-governance/src/verify.rs is a four-valued fail-closed verifier with zero callers repo-wide. But "just wire it up" understates the work, and an earlier revision implied otherwise.

What it actually provides is a reusable verdict framework (the VerificationStatus taxonomy and its fold) plus a V1 receipt verifier: its public functions cover the unversioned V1 GovernanceDecisionReceipt, the legacy GovernanceProof, generic chain links and hash-conflict claims. There are no V2/V3/V4 adapters, and none for AllocationReceipt, SettlementIntent, execution, or the journal — the module's own header records per-ladder recompute shims as follow-up.

So A1 should reuse the verdict framework and the V1 path rather than mint a third verification vocabulary, and must schedule the missing adapters explicitly as part of #2465 slice C. The gap is adapter work, not wiring.

6.8 Identity primitives exist but are unreferenced

N1's authority log (icn-identity/src/authority_log/) is described by its owner as "a library primitive only" with zero references outside icn-identity. AuthorityFactStore, SubjectContextGenesis, SubjectRecognition, HumanActorModel, VotingProcessSnapshot, MemberVoteAction and SubjectVoteSetHash do not exist in code. Session authority exists under different names (SessionAuthority, AuthorityProfile, AuthorityCapabilities in icn-gateway/src/session_authority.rs). ScopeLevel is network reach, not authority — do not conflate. NodeId is pub type NodeId = String; Node has no durable domain.

6.10 Gate 5 is not an executable sequence as written

This contradiction is in the linked source procedure, not introduced here, and this plan exposes rather than repairs it — correcting it is the two-node plan's own change, not #2783's.

docs/demo/TWO_NODE_APPLIANCE_PROOF_V0.2_PLAN.md Gate 5 requires all three of:

Step Requirement
2 restart icnd; wait for authenticated health and peer reconnection
3 re-run receipt verification on Node B while Node A remains disconnected
4 reboot both VMs; wait for first-boot marker, active service and peer reconnection

Steps 2 and 4 require the peer link to be up; step 3 requires it to be down. No single run satisfies all three as written, so Gate 5 cannot be executed and the critical path is blocked at it.

The owner decision that must be made — one of:

  1. offline isolation ends after Gate 4, the witness link is restored, and Gate 5 proves restart/reboot continuity rather than continued isolation (step 3's "while Node A remains disconnected" is then the clause to drop or reword); or
  2. Gate 5's intended topology is genuinely isolated, in which case steps 2 and 4 must stop requiring peer reconnection and the source procedure is corrected.

Until that is decided, this plan does not present Gate 5 as runnable, and no A1 claim may depend on having passed it.

6.9 Unresolved owner contradictions

  1. Two competing decompositions. #2694 defines a 12-step semantic ladder. #2689's 2026-09-02 checkpoint defines an overlapping P0-P10 proof ladder with six lanes, adds N3-A two-node authority reconciliation (which #2694 explicitly non-goals) and a mobile edge. Neither supersedes the other in writing. #2689's body still describes the older four-lane model. A maintainer decision is required.
  2. ops/state/truth/program.json does not exist on main. A checkpoint claimed the ladder was "durably encoded" in a registered program_structure domain. It is not. Verified at this snapshot: the file is absent from main, sources.json registers no program_structure domain, and PR #2690 (OPEN) carries both ops/state/truth/program.json and a sources.json change among its fifteen files. Note #2690's headline contract is the agent registry, so the program surface rides along inside a PR about something else — which is part of why it has not landed. Until it does, the only durable record of the ladder is the #2694 issue body and this document. This document deliberately does not create a competing machine-readable program surface; when #2690 lands, this file should link to it rather than duplicate it.
  3. The typed chain/audit read surface is V1-only (6.3). The dataflow is now traced, and the earlier "V3 emitted / V1 persisted" model is disproven — V3 is persisted, opaquely. What remains unresolved is what a V4 read surface should return, and whether decision-hash-addressable evidence is required when proposal-id-addressable signed evidence already exists.
  4. The two-node plan is Canonical: no, last reviewed 2026-07-27 — predating #2689. (Post-snapshot addendum.) It references ADR-0086, which was accepted 2026-09-15; at the snapshot revision that status was still proposed. The two-node plan's own Canonical: no and review date are what remain stale here, not the ADR's status.

7. icn#2466 — recovery

A separate sovereignty proof, independent of #2694.

#2466 specifies no field list and no ordered ceremony — it specifies a drill plus invariants. The expected artifact shape (planning vocabulary, RecoveryBundleV1) is: exact profile/revision, encrypted state, encrypted effective secret material, node identity commitment, config commitment, institutional/runtime-root commitments, retained evidence commitments, extent/completeness manifest, bundle root digest.

Its binding invariants, which are from the issue: secrets never written to an unencrypted archive at any point including temporary files; an explicit custody model; restore into a fresh overlay assumes the prior node's identity, state and relationships and reopens its keystore without operator re-entry outside the documented custody path; continuity asserted over identity, machine ID, configuration and genesis hashes; missing required material refuses to restore rather than half-restoring.

capture known state -> encrypt -> destroy/remove Node B
  -> recreate from fresh appliance overlay -> restore -> reopen keystore
  -> compare identity/config/state commitments
  -> independently verify retained Alpha evidence again

Do not claim hot backup. Do not let recovered-prefix behaviour masquerade as complete recovery proof.

Completeness dependencies

Issue Defect Effect on recovery claims
icn#2746 a truncated ledger reopens via sled recovery and scans short without error, and nothing in the artifact distinguishes that from a ledger that always held that many Still blocks completeness. (Post-snapshot addendum — see the note under the snapshot revision above; the rest of this row's evidence predates it.) At the snapshot revision the verifier still printed BACKUP VERIFICATION PASSED for a short ledger. icn#2787 stops that overclaim — it reports ledger completeness: unresolved and fails closed instead of certifying — which removes a false positive without being detection. A backup-time extent record does not close this: if the damage precedes the backup the count records the already-reduced extent, and post-capture damage is already caught by the whole-directory checksum. Detection needs an independent commitment that advances on append and survives loss of the journal: icn#2786.
icn#2739 the verifier writes into the tree it inspects (sled has no read-only open; the N2-A gate writes into the audited tree) Caps claim strength, does not falsify it. Blocks "verified a write-protected medium" and "two verifications observed the same bytes".

Note also: CI invokes the weak verify-backup form, without --verify-ledger (.github/workflows/ci.yml:530), and the command prints its own non-claims at icnctl/src/main.rs:7133-7134.


8. Two-node roles

Node A   institution host / producer / artifact source
Node B   independent technical witness / verifier

Node B is not a second institution, not federation, not a production peer and not a governance participant. Two-institution operation requires a later ratified enrollment ceremony.

For offline evidence, Node A must actually be unreachable from Node B. The selected procedure proves isolation, not shutdown: Gate 4 step 5 is "Disconnect Node A", and nothing in it stops the service or the VM. This plan therefore claims only what the procedure establishes — the verifier did not reach Node A — and deliberately does not say "stopped", which would be a stronger property nobody tests. Strengthening it would require changing the upstream procedure, which is out of scope here. A Node B curl back to Node A is transfer evidence only. The plan's Gate 4 step 5 is literally "Disconnect Node A"; Gate 5 re-runs verification while Node A remains disconnected.

For recovery, Node B is the natural destroy/restore witness.


9. Containment ledger

A contained flaw is not fixed. Each row names the exact profile restriction that prevents it from invalidating A1.

Issue Disposition Containment / profile restriction
#2750 trust bloom scores persisted edges 0.0 MUST FIX None available. Rejects entries authored by the institution treasury principal at the ledger author-trust gate — directly on the A1 economic chain.
#2779 snapshot-delete path traversal FIXED / LANDED (PR #2781, squash 08f5bc2cc)
#2748 keystore files at umask FIXED / LANDED (PR #2782, squash 82030804d)
#2777 exclusion domain (#2758/#2759) IN PROGRESS (draft PR)
#2746 truncated ledger certified complete MUST FIX for #2466 Cannot be contained if recovery completeness is claimed.
#2739 verifier writes the audited tree CONTAIN Claim recovery verification over a mutable copy; do not claim read-only-medium verification.
#2778 backup reads a data root with no exclusion CONTAIN or FIX Take A1 backups only with the node stopped.
#2755 native icnd ignores runtime-root config MUST FIX, or pin a unit The earlier entry excluded "the native service path", which is self-defeating: ADR-0086's appliance baseline is native systemd, and the two-node plan starts and restarts icnd under systemd in Gates 1, 2 and 5. Excluding it excludes the profile. The concrete defect is that deploy/icnd.service invokes icnd --data-dir ROOT without --config ROOT/icn.toml, so a provisioned runtime root has no effect. Containment therefore requires a pinned unit or drop-in that passes the managed runtime-root configuration, recorded as a profile artifact — otherwise this is a required fix.
#2747 init-coop emits an icn.toml icnd cannot load CONTAIN A1 uses institution runtime-root, not init-coop.
#2757 no trusted bootstrap authority for first gateway token CONTAIN Single-institution A1; trusted-local mint only; no generalized remote bootstrap.
#2772 node-authority migration across DID change EXCLUDE A1 does not rotate the node DID.
#2627 N2-A Did equality/hashing PARTIALLY LANDED Owns the legacy compute_vote_hash DID-spelling defect; must be resolved before Subject ballots are trusted.
TIME / deadline semantics (#2601) EXCLUDE Explicitly out of Alpha scope.
vote amendments EXCLUDE Frozen process snapshot only.
cross-institution identity federation EXCLUDE Node B is a witness, not an institution.
generalized N3/N4/N5 EXCLUDE Only the N4-alpha prefix slice is in scope.
mobile / QR workflow EXCLUDE Not on the A1 chain.
generic installer claims EXCLUDE One pinned appliance profile only.
live / hot backup EXCLUDE Cold ceremony only.
historical DID-member migration EXCLUDE Fresh context-scoped Subjects only.
Other .mode(0o600) creation sites (data_dir_lock.rs, institution_runtime_root.rs) reachable at mode 000 under an extreme umask FOLLOW-UP — not a blocker Surfaced by the #2782 review and deliberately left outside #2748. .mode() is a request and mode & !umask can clear owner bits, so an extreme umask could make a lock anchor or runtime-root file unusable. It cannot invalidate A1 provided the pinned appliance profile fixes the service umask — confirm that at profile freeze. No owner issue yet; it needs one only if the profile does not pin the umask.

10. Status snapshot

Program-level evidence maturity: how well-established a fact about the Alpha is. This is a different axis from the per-PR delivery lifecycle, whose states and transitions are owned by ops/state/truth/delivery.json — read them there. A PR can be DONE on that axis while the fact it delivered is still only LANDED / UNVERIFIED on this one.

The vocabulary below is this document's own, and is deliberately not a restatement of the owner's lifecycle.

Term Meaning
IDENTIFIED a defect or need is described, nothing built
IMPLEMENTED / UNLANDED code exists on a branch; not on main
LANDED / UNVERIFIED merged to main; not exercised on the Alpha profile
VERIFIED exercised and witnessed on the pinned profile
BLOCKED cannot proceed until a named dependency resolves
CONTAINED not fixed; excluded by a named profile restriction
DEFERRED deliberately out of A1

How merge readiness is actually gated here

Recorded because the first pass guessed wrong and the #2781/#2782 merges settled it. Live branch protection on main:

Gate Value
required_approving_review_count 0 — no second-identity approval is required
required_conversation_resolution true — unresolved review threads block the merge
strict true — the branch must be level with main, so every merge puts every other PR BEHIND
enforce_admins true — no admin bypass
required contexts 11 named checks. Security Audit and Compare Against Base are not among them.

So a mergeStateStatus of BLOCKED on this repository usually means unresolved threads, not red CI and not a missing approval; UNSTABLE means only non-required checks are red. Read the protection API before concluding a PR is waiting on a human.

Safety / correctness frontier

Item State Evidence at snapshot
PR #2781 (#2779 traversal) LANDED merged as 08f5bc2cc; #2779 CLOSED/COMPLETED.
PR #2782 (#2748 keystore mode) LANDED merged as 82030804d; #2748 CLOSED/COMPLETED. Also normalises a newly created keystore, since .mode() is a request and a hostile umask can clear owner bits.
PR #2777 (#2758/#2759 exclusion) IMPLEMENTED / UNLANDED draft; mergeStateStatus: BLOCKED.
#2750 trust bloom filter IDENTIFIED no PR. Next correctness blocker.
#2746 / #2739 verify-backup IDENTIFIED no PR.
N2-A principal-state lane LANDED / UNVERIFIED #2700-#2716 merged; not exercised on an Alpha profile.
Institutional genesis (#2744) LANDED / UNVERIFIED merged as fc9e7b8b6 (#2749); disclaims canonical genesis (6.6).

Alpha lanes

Lane State Blocking fact
Deployment profile FROZEN (Post-snapshot addendum.) ADR-0086 was accepted 2026-09-15 and the Alpha profile is frozen at 860c6f6c22f18de0f7bc4cfb55e35b1143b3b4f1. Freeze prerequisites closed: icn#2755 (native + every shipped drop-in pass the provisioned configuration) and the UMask=0077 pin on both units that create icnd's files. implementation_status stays partially implemented — a separate axis. Two-node plan is still Canonical: no.
#2694 semantic convergence IDENTIFIED 1 of 12 slices owned (#2695); none implemented; no artifact exists in code.
#2465 offline evidence IDENTIFIED spec only; 0 of 4 slices owned. Slice A is conditional, not a blocker (5.6).
#2466 recovery IDENTIFIED spec only; completeness blocked by #2746.
Two-node witness BLOCKED Gate 4 and Gate 6 blocked; Gate 5 is not executable as written (6.10).
NYCN lock bump BLOCKED requires a frozen SHA and a human signature.
Public claim BLOCKED requires all seventeen #2689 section 10 criteria.

11. Critical path and parallel work

Critical path

(Post-snapshot addendum: the first two rows below changed with the commit carrying them. At the snapshot revision #2750 was the open blocker and the profile freeze was pending status: accepted.)

#2750  MERGED 2026-09-14 (80a5faf2c) — was the ONLY uncontained defect here
   v
Alpha profile freeze  DONE 2026-09-15 -> frozen at 860c6f6c22f1
   v
#2694 slice 1 (#2695 GEN-A) -> slice 2 (N1-D) -> ... -> slice 10 (V4)
   v
V4 decision_hash through AllocationReceipt / SettlementIntent
   v
#2465 slice C  (execution/journal evidence adapters)
   v
#2465 slice D  (composes C; tamper-negative proof)
   v
Gate 4  (Node A disconnected — isolation, not shutdown)
   v
Gate 5  (restart + reboot continuity)  <-- BLOCKED: see 6.10
   v
#2466  -> Gate 6
   v
freeze SHA -> NYCN lock -> rehearsal/a11y -> bounded public claim

Safely parallel right now

  • #2465 slice B (bundle substrate) — generic and deterministic, and the only #2465 slice that is unconditionally ready. Slice A is conditional (5.6) and should not be started until the verifier model requires it.
  • #2466 completeness prerequisite (#2746 extent record) — independent of #2694 entirely.
  • #2627 DID-spelling defect in legacy compute_vote_hash — must precede trusting Subject ballots.
  • Resolving the 6.9 decomposition contradiction — a maintainer decision, no code.

Blocked, not worth starting

Slices 3-12 of #2694 (each gated on its predecessor and on owner-contract reverification); #2465 slice C (needs the execution/journal shape the ladder produces); Gates 4, 5 and 6; anything downstream of the profile freeze.


12. Navigation

Question Authority
What is being worked on right now? gh issue list / gh pr list — domain live_issue_state
Program control surface and exit criteria icn#2689
Semantic convergence ladder icn#2694; GEN-A child icn#2695
Offline evidence contract icn#2465
Encrypted recovery contract icn#2466
Two-node acceptance gates docs/demo/TWO_NODE_APPLIANCE_PROOF_V0.2_PLAN.md (Canonical: no)
Identity semantics docs/architecture/IDENTITY_SEMANTICS.md (normative)
Receipt/provenance envelope docs/adr/ADR-0026-receipt-and-provenance-proof-envelope.md
Verification vocabulary icn/crates/icn-governance/src/verify.rs; docs/spec/receipt-chain-verification.md
Fact ownership ops/state/truth/sources.json
PR delivery lifecycle ops/state/truth/delivery.json
Merge policy ops/state/truth/policy.json
Contract document conventions docs/contracts/ (.md + .schema.json + .example.json)

13. Maintainer decisions outstanding

  1. Reconcile the two decompositions (6.9.1): #2694's 12-step ladder versus #2689's P0-P10 proof ladder. Pick one, or state how they compose. Until then the program has two disagreeing structures.
  2. Land or close PR #2690 (6.9.2), which carries the machine-readable program_structure domain this document deliberately does not duplicate.
  3. Move ADR-0086 to status: accepted, or decline itRESOLVED 2026-09-15. Accepted through ADR-0018's lifecycle after the freeze prerequisites closed; the Alpha profile is frozen at 860c6f6c22f18de0f7bc4cfb55e35b1143b3b4f1. implementation_status remains partially implemented, which is a separate axis. Still open: whether the two-node plan should be promoted from Canonical: no.
  4. Decide what the typed chain/audit read surface returns (6.3) before a V4 is specified, and whether conditional V3 emission becomes unconditional first.
  5. Accept or reject the 5.3 evidence-strength taxonomy, which is proposed here and exists nowhere in the repository.
  6. Decide whether economics needs a registered truth domain (6.1).