Marmot-TS
    Preparing search index...

    Function validateCommitAccountIdentityProofs

    • Ported from validate_staged_commit_account_identity_proofs (D-01, D-02, D-03), extended in Phase 9 (UPD-01) with replacement-leaf identity binding. Rejects a commit that drifts the GroupContext account-identity-proof profile away from "current", that carries an invalid 0x8009 proof on any new or re-signed member leaf, or that replaces an existing member's leaf with one bound to a different account identity. Pure and non-throwing — returns a CommitLegalityOutcome rather than throwing or returning undefined.

      Three checks, in order: (a) Profile drift (D-01a). Both parentState and resultingState must classify as the current profile (getGroupProfileSupport). Both are checked — not just the resulting one — so a commit can never "fix" an already-drifted parent into passing; the profile must already have been, and remain, current. (b) Changed-leaf proof validity (D-01b, D-02, D-03). Every entry diffChangedLeaves reports between the two ratchet trees — every non-blank leaf that is new (Add) or re-signed (Update proposal, or the committer's own update-path leaf) — is validated with validateLeafAccountIdentityProof against the RESULTING epoch's ciphersuite. Unchanged leaves are trusted and never re-validated (D-01). This runs BEFORE bucket classification for every changed leaf, so UPD-02/UPD-03 keep reporting their existing proof reasons regardless of which bucket the leaf falls into. (c) Replacement-leaf identity binding (UPD-01, D-01/D-02/D-03). Each changed leaf is classified with classifyChangedLeaf against args.classification (when supplied): - add — a new member in a freed slot legitimately carries a different identity than whoever occupied the slot before removal; no prior-identity comparison runs (D-01). - update-proposal / committer-update-path — a genuine replacement of an existing member's leaf. Its ChangedLeaf.parentLeaf MUST be defined (a replacement always has a prior occupant); if it is not, or if getCredentialPubkey throws for either leaf, this is a fail-closed violation. Otherwise the replacement leaf's account identity is compared against the prior leaf's; a mismatch is a terminal member-identity-changed violation (UPD-01) — per account-identity-proof-v2.md, a change of account identity is not a self-update. - unattributable — the changed leaf matches no Add, no Update sender, and is not the committer's own leaf, with full classification information available: fail closed as unattributable-leaf (D-02). - undecidable — classification information was incomplete (no args.classification, or an undefined committerLeafIndex with no matching proposal). This does NOT return immediately: the loop continues, because a definite violation elsewhere in the commit must always outrank an undecidable leaf (D-03) — otherwise a provably illegal commit could be pooled and retried until it ages out instead of being rejected. The first undecidable leaf's detail is remembered and returned only if the whole loop completes with no violation.

      Every thrown AccountIdentityProofError (or any other unexpected throw) is caught and mapped to a typed violation, never left to escape — fork-recovery and tree-fed convergence call validateCommitLegality unwrapped. Every detail string this function builds names only the numeric leafIndex and a reason literal — never credential bytes, account identity, pubkey hex, or err.message (D-06, diagnostics-privacy rule).

      Parameters

      Returns CommitLegalityOutcome

      • refs/mdk/crates/cgka-engine/src/account_identity_proof.rs validate_staged_commit_account_identity_proofs, validate_leaf_account_identity_proof_for_member
      • refs/marmot/app-components/account-identity-proof-v2.md "Validation"
      • refs/marmot/foundation/errors.md lines 63-68 (deferred vs terminal authorization_failed)