Skip to content

6. User stories

Commit
5ca6b8a
Version
0.4.27
Status
draft
Rendered
2026-10-17T19:30:18Z
Source
SPEC.md, last changed in 5ca6b8a

Each story has acceptance criteria in Given/When/Then form. Stories are the unit of traceability. Every story below traces to at least one requirement, invariant or error (§15).

US-A1 — As an identity holder, I get a usable ledger account at once. I do not wait for anything external, and I do not need to hold any external balance.

  • AC-A1.1 Given a valid identity, When I open an account, Then by the time the response returns it exists, is addressable and can be credited (REQ-LA-1, INV-9).
  • AC-A1.2 Given I hold no balance on the settlement layer, Then no cost is shown to me at any point (REQ-SN-1).
  • AC-A1.3 Given I repeat with the same client key, Then I get the same account, not a second one (REQ-OP-11, ERR-ClientKeyReused).
  • AC-A1.4 Given an account exists, When value arrives for it, Then it is credited. There is no state in which an account exists but cannot be credited (INV-9).

US-A2 — As an identity holder, I hold several accounts under one identity. I open the further ones myself, under my own authority, and I move value between them instantly.

  • AC-A2.1 Given one identity, When I open a second account under my own authority, Then both are distinct and separately addressable (REQ-LA-1, REQ-ID-6).
  • AC-A2.2 Given two of my accounts, When I transfer between them, Then it is one posting and is final when accepted (INV-1, REQ-OP-1).

US-A4 — As an organisation, I control one account that many identities draw on. This arrangement is modelled, not improvised.

  • AC-A4.1 Given a pooled arrangement, Then each drawing identity holds an explicit, bounded authority over the account (REQ-LA-6, REQ-AU-2).
  • AC-A4.2 Given no such authority, When a drawing is attempted, Then it is refused with ERR-NotAuthorised. It is never allowed through with only a log entry.

US-A5 — As an identity holder, I choose whether the operator can act for my account. I can see the answer, and it is honoured.

  • AC-A5.1 Given owned custody, Then no operator authority exists over the account, and aledgent cannot move its value (REQ-AU-6, INV-20).
  • AC-A5.2 Given delegated custody, Then every operator action on my account is recorded as an operator action and is visible to me (REQ-AU-7).
  • AC-A5.3 Given I choose owned custody, Then I am shown which recovery mechanisms apply to the account before the choice takes effect (REQ-AU-9).
  • AC-A5.4 Given several credentials of mine, When any one of them acts on an owned account it is not scoped away from, Then my owner authority is what acts. And When I add or remove a credential without an existing credential or a completed recovery, Then it is refused with ERR-NotAuthorised (REQ-AU-20).

US-A6 — As an identity holder, closing an account never leaves value stranded.

  • AC-A6.1 Given a non-zero balance, When closure is attempted, Then it fails with ERR-AccountNotEmpty (REQ-LA-4).
  • AC-A6.2 Given a balance is moved out, Then it moves by posting to a named destination (INV-2).

US-A7 — As an identity holder, I move my account from self-custody to delegated custody and back. Only I can trigger the direction that gives the operator power.

  • AC-A7.1 Given an owned account, When I delegate custody with my own credential, Then operator authority exists after that, and the change is recorded as mine (REQ-AU-11, REQ-AU-12).
  • AC-A7.2 Given an owned account, When the operator tries to delegate its custody, Then it is refused with ERR-NotAuthorised (REQ-AU-12).
  • AC-A7.3 Given a delegated account and a proven holder credential, When I reclaim custody, Then no operator authority remains. In-flight operations finish under the authority that started them. Any encumbrance the operator placed was lifted, or carried over with my consent (REQ-AU-13).
  • AC-A7.4 Given a delegated account and no working holder credential, When I reclaim custody, Then it is refused with ERR-CredentialInvalid (REQ-AU-13).
  • AC-A7.5 Given agents I have granted authority to, When custody changes, Then their grants do not change (REQ-AU-14).

US-A8 — As an identity holder who has lost my credential, I recover my owned-custody account through a party that is not the operator. This happens after a delay during which I could cancel it.

  • AC-A8.1 Given a recovery started for my account, Then it cannot complete without the recovery authority’s approval. The operator alone cannot complete it (REQ-AU-15).
  • AC-A8.2 Given a pending recovery, Then it is visible on my account. Presenting my existing credential to cancel_recovery before the delay ends cancels it. Using my credential for anything else does not (REQ-AU-16, INV-20).
  • AC-A8.3 Given the delay has ended and the recovery authority has approved, Then a new credential is issued to me and the previous one stops working. The audit trail names every approving principal (REQ-AU-16, REQ-AT-1).
  • AC-A8.4 Given a recovery attempted before the delay has ended, Then completion is refused with ERR-RecoveryNotElapsed (REQ-AU-16).
  • AC-A8.5 Given I named a successor, When the successor claims after the delay and I did not cancel, Then the successor holds owner authority and I no longer do (REQ-AU-17).
  • AC-A8.6 Given I registered a holder-held recovery credential, When I present it, Then it acts as my owner authority at once, with no delay (REQ-AU-18).

US-A9 — As an identity holder brought in without a credential, I enrol my first credential from my own device, through the integrating party’s client.

  • AC-A9.1 Given a principal with the operator’s authority to open identities, When it opens an identity with no credential, Then the identity exists with an empty set. Given any other principal, Then the opening without a credential is refused with ERR-NotAuthorised (REQ-ID-8).
  • AC-A9.2 Given an identity with an empty set, When an owned-custody account is opened for it, or one of its accounts is changed to owned custody, Then it is refused with ERR-NotAuthorised (REQ-ID-8).
  • AC-A9.3 Given an open enrolment, When I present its secret and a valid proof of possession over its challenge, Then my credential is a member of the set, marked enrolled, with the stated scope. The enrolment is closed, and the completion is attributed, audited, notified to the opener and shown to every authority holder (REQ-AU-22, REQ-AT-1, INV-20).
  • AC-A9.4 Given an enrolment that is expired, used or cancelled, or a wrong secret or proof, When I complete it, Then it is refused with ERR-CredentialInvalid and the set is unchanged. Given failed completions past the deployment’s limit, Then the enrolment is cancelled (REQ-AU-22).
  • AC-A9.5 Given an identity whose set holds a credential, When an enrolment is opened or completed for it, Then it is refused with ERR-NotAuthorised (REQ-AU-22, REQ-AU-20).
  • AC-A9.6 Given an enrolled credential, When it reclaims custody, Then the reclaim needs its proof that it works, as for any other credential (REQ-AU-13, REQ-AU-22).

US-B1 — As an identity holder, I move value to another account instantly and privately. No external network is involved.

  • AC-B1.1 Given enough available balance, When I transfer, Then my account is debited and the payee’s credited by postings that each balance: one posting when both accounts are in one partition, otherwise the debit, final when accepted, and the credit, applied within NFR-19’s bound (REQ-RT-11, REQ-OP-1, INV-1).
  • AC-B1.2 Given not enough available balance, Then it fails with ERR-InsufficientAvailable and nothing changes (REQ-LA-2, INV-3).
  • AC-B1.3 Given the transfer happens, Then the settlement layer is not touched and no cost is incurred (REQ-SL-5).
  • AC-B1.4 Given a zero amount, Then it fails with ERR-ZeroAmount. It does not silently succeed or silently fail.

US-B2 — As a caller, concurrent spends against one account can never overdraw it.

  • AC-B2.1 Given many concurrent spends that total more than the balance, Then exactly as many succeed as the balance covers. The final balance is not negative (INV-3, REQ-KER-4).
  • AC-B2.2 Given the check succeeds, Then the reduction of available is atomic with the check (REQ-BA-4).

US-B3 — As a caller, I submit several transfers as one unit and know whether the unit applied.

  • AC-B3.1 Given a multi-leg submission, Then either every leg applies or none does (REQ-KER-10).
  • AC-B3.2 Given legs that debit the same account and asset, Then their amounts are added together for the availability check (REQ-BA-4).
  • AC-B3.3 Given the submission exceeds the published maximum, Then it is refused at submission with ERR-BatchTooLarge, and nothing is taken in (REQ-CS-10).
  • AC-B3.4 Given I read limits(), Then it states the most legs one submission may carry. Given a submission of exactly that many legs, Then it is taken in (REQ-CS-10).

Epic C — Reservations, capture and release

Section titled “Epic C — Reservations, capture and release”

US-C1 — As a caller authorising a spend, I reserve funds. My request is acknowledged at once, and the decision follows fast enough for a payment network.

  • AC-C1.1 Given an authorisation from a principal acknowledged at Received (the default, REQ-CS-9), When I reserve, Then the reply acknowledges the request at Received with its operation reference, as for every command that moves value (REQ-CS-8, NFR-1). The decision, Reserved or Rejected with the refusal named, follows by query and by notification, not after any external event. Once Reserved, available has fallen by the amount, in the same step that decided it (REQ-BA-4, REQ-CS-3, NFR-15).
  • AC-C1.2 Given the reservation succeeds, Then no later read shows that value as spendable (REQ-BA-3).
  • AC-C1.3 Given not enough available balance, Then the decision is a refusal. Refusal is also the default when the decision cannot be made (REQ-AU-1).

US-C2 — As a caller, I capture a reservation for the cleared amount. This may be less than I reserved.

  • AC-C2.1 Given a capture at or below the reserved amount, Then the difference returns to available in the same posting. A repeat is a no-op that returns the original outcome (REQ-OP-2, REQ-OP-3).
  • AC-C2.2 Given a capture above the reserved amount, Then it fails with ERR-AmountMismatch and nothing changes (REQ-OP-2).

US-C3 — As a caller, I release a reservation I will not capture.

  • AC-C3.1 Given a release, Then value returns to available in one posting (REQ-OP-1).
  • AC-C3.2 Given the underlying external leg may still execute, Then release is refused and the operation moves to Needs-Review (REQ-OP-9).

US-C4 — As the operator, no reservation is lost or forgotten.

  • AC-C4.1 Given a reservation past its deadline, Then it appears in a queue with an owner and a service level (REQ-OP-5, REQ-OP-6).
  • AC-C4.2 Given any point in time, Then the age of the oldest non-terminal operation can be observed (REQ-OP-8).

US-C5 — As the operator, I encumber value under a standing rule, and it does not look like a spend.

  • AC-C5.1 Given an encumbrance, Then available falls and total does not. The encumbrance can be told apart from a reservation (REQ-BA-1).
  • AC-C5.2 Given an encumbrance, Then no operation deadline applies to it, and there is no automatic release (REQ-BA-1).

US-C6 — As a caller that reserves, I know at any moment, and on a schedule, exactly what I hold reserved, per holder and asset.

  • AC-C6.1 Given open reservations I made on several accounts and assets, When I read my open reservations, Then I get, per (account, asset), their count, their sum and their earliest and latest deadline, and each one itemised with its reference, amount and deadline, all from one view that names its position (REQ-QR-7, REQ-QR-2).
  • AC-C6.2 Given a reservation captured, released, or expired and released, Then it is not in the answer of any view that includes that closing (REQ-QR-7).
  • AC-C6.3 Given reservations another principal made on an account I hold no authority over, Then they are not in my answer, and their amounts are not in my aggregate (REQ-QR-7, REQ-QR-4).
  • AC-C6.4 Given I registered a report cadence, When a period closes, Then I receive one report for it, delivered at least once under one identity, carrying the same aggregate a query at its view would return, and the latest final anchor (REQ-EV-8, REQ-EV-3).

Epic D — Inbound from the settlement layer

Section titled “Epic D — Inbound from the settlement layer”

US-D1 — As an identity holder, value sent to me from outside appears in my balance once it cannot be taken back.

  • AC-D1.1 Given an inbound arrival observed provisionally, Then nothing is credited (REQ-OP-1).
  • AC-D1.2 Given the arrival reaches finality, and the settlement layer’s record at that position still matches, Then it is credited in one posting (REQ-IN-3).
  • AC-D1.3 Given the record no longer matches, Then the operation is Orphaned and no reversal is needed (REQ-IN-4).
  • AC-D1.4 Given an arrival for an account aledgent tracks, Then it is credited whether or not aledgent started anything (REQ-IN-1).

US-D2 — As the operator, I can tell whether the ledger saw everything the settlement layer recorded.

  • AC-D2.1 Given any window, Then a comparison of the settlement layer’s records with ingested observations is available. Any difference is an incident (REQ-IN-5, NFR-9).
  • AC-D2.2 Given a range that could not be read, Then it is recorded as an explicit gap, not silently skipped (REQ-SA-7).

US-D3 — As a caller, I cannot make aledgent believe a credit happened.

  • AC-D3.1 Given a submitted observation, Then aledgent works out the status itself and ignores any status the submitter claims (REQ-IN-2, INV-11).
  • AC-D3.2 Given the same coordinate twice, Then it is applied once (REQ-IN-1, INV-12).
  • AC-D3.3 Given two sources observe one event, Then exactly one of them writes (REQ-IN-6).

Epic E — Outbound to the settlement layer

Section titled “Epic E — Outbound to the settlement layer”

US-E1 — As an identity holder, I send value to a counterparty on the settlement layer. The amount that leaves my balance and the amount that leaves aledgent are the same.

  • AC-E1.1 Given a withdrawal, Then value is reserved before anything is submitted (REQ-SO-1, INV-13).
  • AC-E1.2 Given execution succeeds, Then value leaves reserved only at finality (REQ-OP-1, REQ-IN-3).
  • AC-E1.3 Given the executed amount differs from the reserved amount, Then it is ERR-AmountMismatch, and the difference is posted explicitly (REQ-OP-2).
  • AC-E1.4 Given execution is refused before it could take effect, Then value returns to available (REQ-SA-4).
  • AC-E1.5 Given the outcome is unknown, Then the operation is non-terminal and no release happens (REQ-SO-4, REQ-OP-6).

US-E3 — As the operator, a settlement-layer cost or liquidity shortfall is a named condition that clears itself. It is not a failure.

  • AC-E3.1 Given an external leg cannot proceed because liquidity is lacking, Then the operation parks and no value is released. One alert is raised per affected position, not per operation (REQ-SA-4, REQ-SN-2).
  • AC-E3.2 Given liquidity is restored, Then parked operations resume without an operator acting (REQ-SN-2).
  • AC-E3.3 Given an operation partially executed, Then it MUST NOT park. It moves to Needs-Review (REQ-OP-6).

US-E4 — As a caller, I learn that the settlement layer cannot do what I asked before I have committed anything.

  • AC-E4.1 Given an operation or asset the settlement adapter does not support, Then it is refused at submission with ERR-UnsupportedLeg (REQ-SA-1).
  • AC-E4.2 Given an adapter whose connected network is not the declared settlement layer, Then the adapter refuses to serve (REQ-SA-2).
  • AC-E4.3 Given a change to the settlement layer’s rules that leaves what an instruction must carry unchanged, Then the adapter keeps serving, with no new release or configuration (REQ-SA-9).
  • AC-E4.4 Given a change that alters what an instruction must carry, or an instruction the layer does not confirm as valid, Then the adapter refuses to serve until it has a format the layer confirms (REQ-SA-9).

US-F1 — As an identity holder, I hold several assets in one account.

  • AC-F1.1 Given several assets, Then balances are kept separate per asset and never mixed (INV-4).
  • AC-F1.2 Given an unregistered asset, Then any operation naming it fails with ERR-UnknownAsset (REQ-AS-1).

US-F2 — Withdrawn by amendment 0012 (OQ-17 closed): a conversion is a redemption and an issuance by the integrating party (§13). The identifier is not reused.

US-F3 — As a caller, precision is never lost.

  • AC-F3.1 Given an amount with more precision than the asset has, Then it is refused with ERR-PrecisionExceeded, not rounded. Every amount at every boundary is an exact integer count of minor units (REQ-AS-4, INV-7).

US-F4 — As an issuer, I bring value into the book against my own reserve, and this is visible.

  • AC-F4.1 Given issuance authority for an asset, When I issue, Then the destination is credited in one posting against the issuance counterparty. The trial balance still sums to zero (REQ-AS-6, INV-5).
  • AC-F4.2 Given no issuance authority for the asset, Then issuance fails with ERR-NotAuthorised (REQ-AU-10).
  • AC-F4.3 Given a redemption, Then value leaves available and is posted against the issuance counterparty (REQ-AS-6).

US-F5 — As an issuer, I move an asset I issued in the book onto the settlement layer, without a window and without a difference.

  • AC-F5.1 Given a book-only asset, Then an external leg in it is refused at submission with ERR-UnsupportedLeg, and issuance in it works (REQ-AS-7).
  • AC-F5.2 Given a binding whose settlement-layer asset is missing, not live, or has another symbol or precision in its own fields, Then it is refused with ERR-UnsupportedLeg. A name is never read (REQ-AS-8).
  • AC-F5.3 Given a binding where the settlement layer’s holding differs from the book’s outstanding balance by one minor unit, Then it is refused, and the asset stays book-only with its issuance authority (REQ-AS-8).
  • AC-F5.4 Given a binding at zero divergence, Then while it is pending the asset’s issuance and redemption are refused with ERR-NotAuthorised; and When it is final, Then the asset is bound, its external legs are supported, and NFR-9’s third axis finds no difference (REQ-AS-8, NFR-9).
  • AC-F5.5 Given a bound asset, When the settlement layer’s description of it changes, Then nothing in the book changes, and nothing is held or refused (REQ-AS-9).

US-G1 — As an identity holder, I grant an agent authority to act on my account within bounds I set.

  • AC-G1.1 Given a grant, Then it names the permitted operations and at least one bound. A grant with no bound cannot be expressed (REQ-AU-2, REQ-AG-1).
  • AC-G1.2 Given the agent acts within its bounds, Then it succeeds. The audit trail records the action as the agent’s, on my behalf, and separate from mine (REQ-PN-1, REQ-AU-7, REQ-AT-1).
  • AC-G1.3 Given the agent exceeds a bound, Then it fails with ERR-BoundExceeded and nothing changes (REQ-AG-2).

US-G2 — As an agent, I hold my own credential and do not impersonate my principal.

  • AC-G2.1 Given an agent, Then it has its own identity and its own credential (REQ-AG-1).
  • AC-G2.2 Given an agent’s credential, Then it cannot widen its own scope (REQ-AU-4).

US-G3 — As an identity holder, I revoke an agent completely, within a stated bound.

  • AC-G3.1 Given a revocation, Then every credential derived from the revoked authority stops working within the bound of NFR-20 (REQ-AU-3).
  • AC-G3.2 Given an operation already reserved, Then revocation does not release it. The operation runs to a terminal state (REQ-OP-9).

US-G4 — As an organisation, I delegate a spending allowance over a window to an agent.

  • AC-G4.1 Given a window allowance, Then aledgent enforces it and refuses the operation that would exceed it (REQ-AG-2).
  • AC-G4.2 Given an operation is released or reversed, Then the allowance it used is restored (REQ-AG-3).

US-H1 — As an identity holder, I see what I hold across everything I own, in one answer.

  • AC-H1.1 Given an identity, Then balances across all its accounts and assets are returned as one result (REQ-BA-5).
  • AC-H1.2 Given the result, Then available and total are both present, each with its own label. Both come from one consistent view (REQ-BA-2, REQ-QR-2).

US-H2 — As an identity holder, I list my movements with filters and pages, and the paging is stable.

  • AC-H2.1 Given a movement list, Then it pages on the entry sequence, not on time (REQ-PO-2).
  • AC-H2.2 Given a filter by account, asset, direction, counterparty or time range, Then aledgent applies it (REQ-QR-1).
  • AC-H2.3 Given a movement, Then its status comes from its posting kind, never from parsing a string (REQ-PO-1).

US-H3 — As an identity holder or verifier, I get a statement for a period, and it balances.

  • AC-H3.1 Given a period, Then opening balance plus movements equals closing balance exactly (INV-6).
  • AC-H3.2 Given the same period is requested twice, Then the statement is identical (REQ-QR-2).

US-H4 — As a caller, a query never changes anything.

  • AC-H4.1 Given any query, Then it has no effect on any ledger fact (REQ-QR-3).

US-H5 — As an account’s authority holder, nothing about that account is hidden from me.

  • AC-H5.1 Given any entry against the account, Then I can see it, including one made under operator authority (REQ-QR-4, INV-20).

US-I1 — As an identity holder, nobody without authority over my accounts can see what I hold or who I transact with.

  • AC-I1.1 Given the public record, Then it reveals no account, identity, balance, counterparty or internal movement (REQ-PV-2, REQ-PR-2).
  • AC-I1.2 Given any read of a ledger fact, Then it is authorised against an authority over that fact’s subject. A principal with no such authority can reach nothing of mine (REQ-PV-1, INV-16).

US-I2 — As an identity holder, I prove a fact about my holdings to a party I choose, and nothing else.

  • AC-I2.1 Given a disclosure, Then the recipient can verify it without aledgent’s cooperation at verification time (REQ-PR-4).
  • AC-I2.2 Given a disclosure, Then it reveals only the fact asserted. It grants no capability to read anything else, now or later (REQ-PV-6).
  • AC-I2.3 Given the disclosure is a signed assertion and not a construction that can be checked independently, Then it says so (REQ-PR-6).

US-I3 — As a verifier, I verify a subject’s position for a period without gaining the ability to read their account.

  • AC-I3.1 Given a scoped disclosure, Then I can check it against an anchor (REQ-PR-4).
  • AC-I3.2 Given the subject’s account, Then I cannot read it (REQ-PV-6).
  • AC-I3.3 Given a disclosure, Then it carries the deployment’s assurance level (REQ-AR-5).

US-I4 — As an identity holder, my personal data is not in anything permanent.

  • AC-I4.1 Given any identifier or anchored value, Then it contains no personal data (REQ-PV-3, INV-17).
  • AC-I4.2 Given an erasure request, Then meeting it does not require rewriting an identifier that other systems hold (REQ-ID-1).

US-J1 — As the operator, I commit to the state of the book so that I cannot rewrite it later.

  • AC-J1.1 Given a bounded interval, Then a checkpoint is anchored (REQ-PR-1).
  • AC-J1.2 Given an anchor, Then it commits to every entry up to and including a stated sequence, and to nothing else (REQ-PR-7).
  • AC-J1.3 Given an anchor whose publication did not reach finality, Then it establishes nothing and is not cited (REQ-PR-8).
  • AC-J1.4 Given anchoring is unavailable, Then holders’ operations continue (REQ-PR-9).
  • AC-J1.5 Given a checkpoint a disclosure rests on, Then it names the construction of its state commitment, and its anchor binds that name: the same checkpoint with another construction named does not match the anchor (REQ-PR-10).

US-J2 — As anyone holding an earlier anchor, I detect a later revision of the history it covered.

  • AC-J2.1 Given a revision of anchored history, Then a holder of the earlier anchor can detect it without the operator’s cooperation (REQ-PR-4).
  • AC-J2.2 Given the interval between anchors, Then a revision inside it cannot be detected this way, and this is stated (REQ-PR-3).

US-J3 — As the operator, I know that the book’s record of what aledgent holds on the settlement layer is compared continuously with what the settlement layer itself says.

  • AC-J3.1 Given any day, Then the comparison has run and its result is recorded (REQ-PR-5, NFR-9).
  • AC-J3.2 Given a difference of one minor unit, Then it is detected. Tolerance is zero (NFR-9).

US-K1 — As the operator, I resolve an operation whose outcome cannot be established. I do this through an interface, and a record is kept.

  • AC-K1.1 Given a Needs-Review operation, Then I can resolve it through an authenticated, audited operation (REQ-AT-3, REQ-RC-1).
  • AC-K1.2 Given a resolution, Then it records who acted and why. No direct change to storage was needed or possible (REQ-AT-1, REQ-AT-3).
  • AC-K1.3 Given a Needs-Review operation with an external leg, When one operator resolves it to Released without proof that the leg did not and cannot take effect, or to Settled without a final record that names the operation, Then the resolution is refused and the operation stays in Needs-Review (REQ-RC-5).
  • AC-K1.4 Given a Needs-Review operation, When the settlement adapter reports records that prove its outcome, Then aledgent resolves it on that proof at once, with no human: Settled on a final record naming it, Released on a proved rejection or proven non-inclusion, or on an inbound arrival’s record withdrawn from the canonical chain (REQ-RC-5 step 1).
  • AC-K1.5 Given a Needs-Review operation the adapter could not prove on its own, When one authority submits evidence, meaning a block and a transaction hash, Then nothing moves until the adapter has fetched and verified that evidence on its own. If the evidence proves the outcome, aledgent applies it with no second principal. The submission is audited like any operator action (REQ-RC-5 step 2, REQ-AT-3).
  • AC-K1.6 Given a Needs-Review operation whose submitted evidence the adapter checked and found no proof in, When a principal proposes releasing it without proof, Then nothing moves until a second, distinct principal agrees. Then it is released and an incident is raised. The same principal twice is ERR-ApprovalRequired. Before the adapter found no proof, the proposal is ERR-EvidenceInsufficient. A settlement of an external leg without proof is never made (REQ-RC-5 step 3, INV-10).

US-K2 — As the operator, reversing a finalised movement is possible, rare and never automatic.

  • AC-K2.1 Given a finalised posting, When a reversal is proposed, Then it needs deliberate human approval and raises an incident (REQ-RC-2).
  • AC-K2.2 Given a reversal, Then it is a new posting that references the original. It is never a mutation (INV-2, REQ-PO-3).
  • AC-K2.3 Given a reversal whose posting does not mirror the reversed postings exactly and whole, Then it is refused, whoever approved it (REQ-RC-5, REQ-PO-3).

US-K3 — As the operator, after a restart I can answer “did we tell them?” from storage alone.

  • AC-K3.1 Given a restart, Then for every operation the record states what was attempted, what happened, and whether every party owed a notification received one (REQ-RT-4, REQ-SA-5).
  • AC-K3.2 Given an undelivered notification, Then it is redelivered under one identity (REQ-EV-3).

US-K4 — As the operator, a correction to the book is itself a value-moving operation.

  • AC-K4.1 Given a correction, Then it is submitted through the ordinary command surface, with idempotency and authority (REQ-OP-11, REQ-AU-1).
  • AC-K4.2 Given a correction, Then it is a posting and is subject to every invariant in §9 (INV-1, INV-2).

US-K5 — As the operator, after a restore the book re-derives from its entries.

  • AC-K5.1 Given a restore from backup, Then every balance can be re-derived from entries alone. No acknowledged or decided operation is missing (INV-6, NFR-4, NFR-10).
  • AC-K5.2 Given an export and a re-import, Then the observable state is identical (REQ-RC-3).

US-K6 — As the operator, I add capacity, replace any execution node, or lose one, without an outage of the book and without losing an operation.

  • AC-K6.1 Given a deployment under load, When I add execution nodes, Then its capacity grows with no change to the book, to any identifier in it or to any operation. Every balance is unchanged, and every command is acknowledged, answered and completed within its bound (NFR-21 (a), NFR-17, NFR-18).
  • AC-K6.2 Given a deployment under load, When I replace any execution node with a new one that starts with no local state, Then the new node is admitted online and brought up to date. No operation that was acknowledged or answered with its decision is missing, and every command is acknowledged, answered and completed within its bound (NFR-21 (b), NFR-4, NFR-5).
  • AC-K6.3 Given a deployment under load, When the local storage of any single execution node is destroyed at an arbitrary instant, Then no operation that was acknowledged or answered with its decision is missing, every balance re-derives from entries alone, and no restore from backup was needed (NFR-21 (c), NFR-4, INV-6).

US-K7 — As the operator, I upgrade aledgent’s code online, and anyone I give the book’s archive can still replay all of it, under the code that ran each part.

  • AC-K7.1 Given an upgrade naming code version H from input n, When it is taken, Then every input before n keeps its outcome, every input from n runs under H, and the next checkpoint and its anchor name H (REQ-RT-15, REQ-RT-16).
  • AC-K7.2 Given an upgrade naming a version whose artefacts no source returns, or returns with another digest, Then it is refused and the code does not change (REQ-RT-16, REQ-RT-17).
  • AC-K7.3 Given an archived history that spans upgrades, When it is replayed from genesis under its code map, Then every writer reaches, at every input, the roots and the log it archived (REQ-RT-3, REQ-RT-17).
  • AC-K7.4 Given a migration of construction at input n, Then checkpoints before n name the old construction and after it the new, the checkpoint at n carries both roots, and a proof against any anchor of either side checks (REQ-PR-10, REQ-PR-11).
  • AC-K7.5 Given a new node, When it is brought up to date from the latest anchor-verified snapshot and the inputs since, or from genesis and every input, Then it reaches the same roots (NFR-21 (b), REQ-RT-17).
  • AC-K7.6 Given two builds of the same source with different build settings, Then they are two code versions with two digests, and moving between them is an upgrade (REQ-RT-16).
  • AC-K7.7 Given a book whose genesis fixes the mode “one principal”, When that principal changes the mode to “a proposer and a different approver”, Then every later upgrade needs both, and the change is in the audit trail and in the next anchor (REQ-RT-18).
  • AC-K7.8 Given a mode change that is not authorised under the mode in force, or that names a principal who does not exist, Then it is refused and the mode does not change (REQ-RT-18).
  • AC-K7.9 Given an upgrade naming code version H from input n, When input n reaches a writer whose code is not of H’s code generation, Then it is refused, nothing changes, its number is not taken, and once the code is switched the same input runs under H (REQ-RT-20).
  • AC-K7.10 Given a writer continued at input n, Then the book keeps its genesis and its construction, input n’s log entry chains to input n − 1’s, the first writer takes no input from n once the founding record exists, and a replay from genesis crosses the boundary and reaches the archived roots and log at every input (REQ-RT-21, REQ-RT-17).
  • AC-K7.11 Given a checkpoint, When a writer is restored from it under a code version that names a different platform than the one it was taken on, and the inputs after it are replayed, Then the writer reaches the checkpoint’s roots and every archived root after it (REQ-RT-19).
  • AC-K7.12 Given a writer fenced at input n, When an input that moves the upgrade to a later input or cancels it, authorised under the mode in force, reaches it, Then the old code takes it as input n; and When the writer stays fenced longer than the deployment’s bound, Then an alert is raised (REQ-RT-20).
  • AC-K7.13 Given an upgrade made to change only the runtime that executes a writer’s code, Then the new code version still raises the code generation and carries it in its code’s bytes, a writer whose switch was missed refuses input n, and an execution node whose runtime is not the one the current range’s code version names refuses to drive the writer (REQ-RT-20).
  • AC-K7.14 Given a continuation founded at input n, When a second founding at the same n with a different record is attempted, Then it is refused and nothing is founded; When a founding’s writer state differs from the first writer’s after n − 1 in any field that is not host-local, Then no record is written, nothing is founded, and a corrected founding can still be made; When a founding is retried after a crash and finds its own record, byte for byte, Then it resumes; When the next queued input moves or cancels the upgrade, Then no founding is made until the first writer has decided it; When a founding record exists, Then an input that moves or cancels the upgrade it was founded for is refused with ERR-InvalidTransition, its number is not taken, and the next input runs as n under H, while one that moves or cancels a later upgrade is taken; and When a log holds two founding records at one n, Then its replay is refused (REQ-RT-21).
  • AC-K7.15 Given a range whose replayer the code archive holds, When the platform’s execution of that range is checked with it, Then every input reaches its archived log hash; and When that replayer is replaced, Then no code version changes (REQ-RT-19).
  • AC-K7.16 Given a writer whose generation in force is g + 1 after an upgrade, When code of generation g is installed again and an input reaches it, Then the input is refused and nothing changes; and Given an upgrade whose code version names a generation other than the writer’s plus one, Then it is refused and nothing changes (REQ-RT-20).
  • AC-K7.17 Given an upgrade scheduled from input n, When an input that moves or cancels it is not authorised under the mode in force, Then it is refused, nothing changes, and the upgrade stays scheduled (REQ-RT-20, REQ-RT-18).
  • AC-K7.18 Given an upgrade scheduled from input n and an authorised input that moves or cancels it, arriving as input n, When it is decided by the old code, and When it is decided by the new code because the switch was already made, Then both commit the same outcome: the upgrade does not take effect at n and the generation stays the old one; and a replay assigns every input the generation the code map, read from the inputs alone, names (REQ-RT-20, REQ-RT-17).
  • AC-K7.19 Given a logical writer whose input n is archived, When a second entry numbered n reaches the archive, Then it is refused; and Given an upgrade scheduled from n, When a move or cancellation committed at the first writer and a continuation’s founding both claim n, Then whichever claims first stands and the other is refused, whether the first writer’s entry reaches the archive before or after the continuation’s first segment; When an entry at n reaches the archive from a continuation instance that is not the one recorded beside the founding record, or at an n whose claim is not a founding record, Then it is refused; and a log holding both is refused by replay (REQ-RT-21).
  • AC-K7.20 Given a founding being made for an upgrade scheduled from n, When a move or cancellation of that upgrade commits at the first writer before the founding’s checks, before or after the build, have passed, Then no founding record is written, nothing is founded, and the first writer continues (REQ-RT-21).

US-N1 — As the operator, I bring holders across from a prior system with the credentials they already hold, so that they do not enrol again.

  • AC-N1.1 Given a credential’s public material from the prior system, of a kind the deployment accepts, When I import it into the holder’s identity with a justification, Then it is a member of the identity’s set, marked as imported. The import is audited, attributed to me, and shown to the identity’s authority holders (REQ-MG-7, REQ-AT-1, INV-20).
  • AC-N1.2 Given a credential of a kind the deployment does not accept, or one already in the set, When I import it, Then the import is refused with ERR-CredentialInvalid and nothing changes (REQ-MG-7).
  • AC-N1.3 Given an identity with an account in owned custody, When I import into its set, Then the import is refused with ERR-NotAuthorised (REQ-MG-8).
  • AC-N1.4 Given an imported credential, When the holder reclaims custody with it, Then the reclaim needs the credential’s proof that it works, as for any other credential (REQ-AU-13, REQ-MG-8).

US-N2 — As the operator, I start a book from a sealed seed of the prior system’s identities, accounts, aliases, balances and grants, so that the migration takes minutes and not hours.

  • AC-N2.1 Given a genesis that commits a seed, When the book is founded, Then its first state is the one the commands its records stand for would have made, and it is sealed (REQ-RC-6).
  • AC-N2.2 Given a seeded book that is not sealed, When any command is submitted, Then it is refused with ERR-InitialStateNotSealed and nothing changes (REQ-RC-6).
  • AC-N2.3 Given a part that is not the committed one at its position, or one already applied, When I apply it, Then it takes no effect: a part already applied answers as it did (REQ-RC-6, INV-18).
  • AC-N2.4 Given a seeded book, When its first state is derived again from the seed, or a seeding in parts is interrupted and resumed, Then the book is the same (REQ-RC-6, REQ-RT-3).
  • AC-N2.5 Given a seed whose opening balances do not reconcile with every required source, When I apply it, Then it is refused before any part takes effect (REQ-RC-4, REQ-RC-6).

US-M2 — As an integrating party, I am told what happened without polling.

  • AC-M2.1 Given a terminal outcome, Then a notification is delivered at least once. It carries the operation reference and can be deduplicated (REQ-EV-1, REQ-EV-3).
  • AC-M2.2 Given notifications for one operation, Then arrival order is not guaranteed. Each one carries enough to be understood on its own (REQ-EV-2).
  • AC-M2.3 Given a notification, Then the recipient can verify its authenticity, and it cannot be replayed (REQ-EV-4).
  • AC-M2.4 Given a notification, Then it names the latest anchor that was final when its transition was recorded, or says that none was. Every delivery of it names the same one (REQ-EV-1, REQ-EV-3).

US-M3 — As an integrating party, aledgent never calls me to decide an outcome.

  • AC-M3.1 Given an operation, Then aledgent reaches its outcome and a terminal state without a synchronous call into any caller (REQ-EV-5).

US-M4 — As an integrating party, I never need to hold a balance of my own to know what my users hold.

  • AC-M4.1 Given any account, Then the authoritative balance is aledgent’s. Any copy I keep is a cache with no standing (INV-8).

US-M5 — As an integrating party, when I change an identity, an account, a credential, an authority or custody, the reply tells me whether the change was made. I do not wait for a notification to know it.

  • AC-M5.1 Given an account or security command (REQ-CS-8), When I send it, Then the reply carries its decision: the result, or the refusal named. It is never Received. If the decision cannot be made in time, the reply is ERR-DecisionUnavailable, and a retry with the same client key returns the decision (REQ-CS-7, NFR-16).

US-M6 — As an integrating party that must answer its own caller at once, I have my principal’s transfers and reservations answered with their decision.

  • AC-M6.1 Given my principal’s answering setting says “decided”, When it reserves or transfers, Then the reply carries the decision: Reserved or the transfer’s terminal state, or the refusal named. It is never Received (REQ-CS-9, NFR-16).
  • AC-M6.2 Given the decision is not made within the setting’s wait, Then the reply is ERR-DecisionUnavailable. The command is decided later, its decision is notified, and a retry with the same client key returns it (REQ-CS-9, REQ-CS-7, REQ-EV-1).
  • AC-M6.3 Given no setting, Then my principal’s transfers and reservations are acknowledged at Received. Given the setting changes, Then a command taken in before the change is answered, and re-answered, as it was taken in (REQ-CS-9).
  • AC-M6.4 Given a setting whose wait exceeds the bound of REQ-CS-7, When I set it, Then it is refused with ERR-NotAuthorised and the setting is unchanged (REQ-CS-9).

US-M7 — As an integrating party, I learn when value lands in an account I serve, whoever moved it.

  • AC-M7.1 Given a transfer, a capture, an issuance or a reversal that credits an account another principal serves, Then that account’s serving principal receives a credit notification for it. The notification carries the account, asset, amount, posting kind, operation reference and latest final anchor (REQ-EV-9).
  • AC-M7.2 Given a release of a reservation, or an opening, Then no credit notification is sent (REQ-EV-9).
  • AC-M7.3 Given a credit to an account the requester also serves, Then the requester receives the transition notification and the credit notification, each with its own identity, and a redelivery of either carries the same identity (REQ-EV-9, REQ-EV-3).
  • AC-M7.4 Given an account its own identity opened, Then its credit notifications reach the principal that opened that identity (REQ-EV-9).

US-M8 — As an integrating party, my own reference for an operation comes back with it everywhere I read it.

  • AC-M8.1 Given a command with pass-through data, Then its reply, operation(reference), every notification of its transitions and its movements carry the same data (REQ-PO-5).
  • AC-M8.2 Given a repeat under the same client key with different pass-through data, Then it is refused with ERR-ClientKeyReused (REQ-PO-5, REQ-OP-10).
  • AC-M8.3 Given pass-through data over 1 KiB, or not one JSON value, Then the command is refused with ERR-MalformedCommand and nothing is taken in (REQ-PO-5, REQ-ER-3).
  • AC-M8.4 Given another party’s principal that reads a movement of the operation, or receives its credit notification, Then the pass-through data is not in what it reads (REQ-PO-5, REQ-EV-9).