Milestone 1 - lambdasistemi/singular GitHub Wiki

Permanent two-edge registry for KERI, with Demo 1

Last reconciled: 2026-10-13T17:36:11.624Z. Team: RUNNING. Milestone.

As a KERI integrator, I want a permanent registry that admits only register (insertActive) and permanent termination (updateTerminal), shown through Demo 1, so that later Singular capabilities never change my instance. Scope settled 8 October 2026; see the delivery roadmap.

Closing bar: the open-datum demos are complete: the Demo 1 application runs on preprod against the restricted contract, and protected rejection has landed. KERI's own integration is not a condition of this milestone. Payload updates are application spends, not registry edges. Registries made by earlier releases are abandoned when identities change. Review date: 22 October 2026 (review card).

How the work is organised since 9 October: nine journey epics, each a user journey, with the desk at the milestone. Two epics change code logic at any time, plus one that is almost conflict-free; the rest wait at a safe boundary. Merges go one at a time through a desk-granted slot. Cleanup that moves code without changing behaviour takes the stage ahead of logic changes, because the layout is coupled: the command-line split (#528) merged on 11 October in an exclusive window. A separate quality epic (#545, milestone M4) makes effects and state explicit on main in parallel; the product stays single-threaded unless there is a written reason (operator, 11 October). Ticket owners are Sonnet 5.5 and epic owners Opus 5.5; Muse and GLM write source, alternating and racing on difficult code, and Codex audits every slice (11 October).

Rulings in force: a provable rejection forfeits a new registry parameter, the bond, carried by every request beside its deposit and burned as a treasury donation; the owner gets the whole deposit and the approval back, enforced on chain (operator, 13 October; replaces the forfeit taken from the deposit); Demo 1 reads the chain through Koios only (operator, 13 October). Several providers is a valid requirement, deferred: under the Lockness rules Koios answers are unverified (no ledger proofs, and Demo 1 has no anchor), and a second unverified indexer would not change that. Every page and readback states its provider claims as unverified; the request keeps carrying its datum inline and the application decides its size (9 October); every request will carry a Singular-minted tag with a bond, and a rejection forfeits, burned as a treasury donation (#529, settled 9 October); the registry command line is create, fold, reject, reclaim, inspect, and every application is its own executable on the Singular library (#528).

State on 13 October, evening: merged today: create funded from several outputs and refused up front (PR 613), the bookkeeping clean-up (PR 617, milestone M4), the fold machinery for several requests (PR 622, bound still one) and the wallet floor (PR 619). In flight on the demo path: the registry page from chain (PR 614, merging next), create from one output, and the fold bound raised to nine with Alice and Bob in one fold (due 18 October). Protected rejection and its economics are paused: the paper draft got a major-revision review and the first of four design rulings is with the operator. Restoring reference scripts is parked until after the review.

Rehearsable today on preprod (current broad contract): create (fragile), register name and payload, token payload update, Bob refused on Alice's payload, Bob joins by token (devnet-proven only), Bob books and folds alone, Alice terminates with deposit returned. Not yet: both requests pending at once, protected rejection, the page from chain, chain refusals through the negative host, recovery after interruption shown live.

Moved out on 8 October: the conformance-bible epic and its children to assurance; shared scripts and Demo 2 to the new milestone M1.5; the registry-interface page to M2; fold batch capacity (#530) and the dead journey programs (#375) to tooling.

Stories describe outcomes; tickets are delivery containers. The mapping is many-to-many. Unticketed work, decisions and standing obligations are named explicitly. A landed enabler does not mean the product outcome is delivered.

Delivery map

Dependency-stage Gantt — not a calendar forecast. Each equal-width bar occupies one dependency stage; positions are calculated from the prerequisites below. Synthetic dates are rendering coordinates only. Widths are not effort, duration or completion percentages. Standing obligations are checkpoints. Same-stage rows may be independent, but this chart grants no dispatch authority.

Labels report delivery state; only in-progress rows use active colouring.

%%{init: {"gantt": {"leftPadding": 380, "sectionFontSize": 12, "fontSize": 12}}}%%
gantt
    title Permanent two-edge registry for KERI, with Demo 1 - dependency stages
    dateFormat YYYY-MM-DD
    axisFormat Stage %j
    tickInterval 1day
    todayMarker off
    section Permanent two-edge contract
    Keep the broader registry work for a later release [landed] :done, preserve-broader-work, 2025-01-01, 1d
    Run a contract that admits only register and terminate [landed] :done, restrict-runnable-contract, 2025-01-02, 1d
    See every deferred edge refused by the packaged contract [planned] :deferred-edges-refuse, 2025-01-03, 1d
    Keep registries made by earlier releases working [superseded] :abandon-earlier-registries, 2025-01-01, 1d
    Integrate Singular inside KERI [superseded] :keri-integration, 2025-01-01, 1d
    Read the registry interface in the documentation [superseded] :registry-interface-docs, 2025-01-03, 1d
    section Open-datum application and protected requests
    Register a name with a payload and update it [in-progress] :active, register-and-update-payload, 2025-01-03, 1d
    Terminate permanently and get the deposit back [in-progress] :active, terminate-with-deposit, 2025-01-05, 1d
    Define protected rejection in the Lean model [blocked] :crit, protected-rejection-model, 2025-01-03, 1d
    Refuse unjustified rejection on chain [planned] :protected-rejection-enforced, 2025-01-04, 1d
    Every request carries a Singular-minted tag and has an exit [planned] :request-tag, 2025-01-05, 1d
    section Independent actors from public chain data
    Join a registry from its state token alone [landed] :done, join-from-state-token, 2025-01-01, 1d
    Run every command against live Koios [in-progress] :active, live-koios-client, 2025-01-01, 1d
    Publish missing reference scripts safely [planned] :publish-reference-scripts, 2025-01-02, 1d
    Retire reference carriers I own [planned] :retire-owned-carriers, 2025-01-03, 1d
    Read the registry page generated from chain [in-progress] :active, registry-page-from-chain, 2025-01-01, 1d
    Join from the state token alone and prove two actors share no directory [landed] :done, independent-actor-harness, 2025-01-02, 1d
    Fold every settleable pending request at once [landed] :done, fold-every-settleable, 2025-01-01, 1d
    Admit a request only inside its processing window [in-progress] :active, processing-window-admission, 2025-01-02, 1d
    section Demo 1 rehearsal and packaging
    Create a registry without a stranded partial run [in-progress] :active, create-registry-reliably, 2025-01-03, 1d
    Let the chain refuse a forbidden transaction [landed] :done, negative-host, 2025-01-03, 1d
    Act on the 7 October rehearsal findings [landed] :done, rehearsal-findings, 2025-01-01, 1d
    Clean up the preprod registries left by earlier attempts [planned] :clean-up-preprod, 2025-01-01, 1d
    Rehearse Demo 1 with Alice and Bob on preprod [planned] :two-player-rehearsal, 2025-01-06, 1d
    Run Demo 1 on preprod against the restricted contract [planned] :demo1-on-restricted-contract, 2025-01-07, 1d
    Every test the repository declares runs in hosted CI [landed] :done, main-tests-are-real, 2025-01-01, 1d
    Read the test suite in the documentation [planned] :test-suite-in-docs, 2025-01-01, 1d
    section Speed, recovery and readable command output
    Wait less for confirmations [landed] :done, reduce-waiting, 2025-01-01, 1d
    Shorten the evidence campaign [in-progress] :active, faster-evidence-campaign, 2025-01-01, 1d
    Watch commands narrate their protocol activity [planned] :live-narration, 2025-01-01, 1d
    Keep the command journal bounded [planned] :bounded-journal, 2025-01-01, 1d
    Decide whether a failed trace file warns [decision] :crit, trace-warning, 2025-01-01, 1d
    Reuse the reconstructed registry between commands [planned] :cached-replay, 2025-01-02, 1d
    Receipts name the right party and every transaction expires [planned] :truthful-receipts, 2025-01-03, 1d
    The Koios retry-ceiling test passes under full-suite load [landed] :done, koios-retry-flake, 2025-01-01, 1d
    The negative host and its devnets clean up after themselves and check every mutant [planned] :negative-host-hardening, 2025-01-01, 1d
    section Registry command line and application binaries
    The registry command line is five commands applications are their own executables [landed] :done, command-line-split, 2025-01-03, 1d
    The documented invocations are derived from the binaries [planned] :documented-flags-from-binaries, 2025-01-01, 1d

State key: landed/delivered = evidence linked; review/ready = not landed; blocked/decision = unresolved prerequisite; planned = not commissioned; standing = continuing obligation.

Permanent two-edge contract

Story Kind Tracking State Owner
Keep the broader registry work for a later release enabler Ticketed — #504 preserve broader work, #507 bounded-contract epic landed Epic #507 owner
Run a contract that admits only register and terminate product Ticketed — #505 restrict the runnable contract, #507 bounded-contract epic landed Epic #507 owner
See every deferred edge refused by the packaged contract enabler Ticketed — #506 verify deferred-edge refusals, #507 bounded-contract epic planned Epic #507 owner
Keep registries made by earlier releases working operation Decision — #480 earlier-release registries superseded Project owner (ruling 8 October 2026)
Integrate Singular inside KERI outcome Decision superseded Project owner (ruling 8 October 2026)
Read the registry interface in the documentation enabler Ticketed — #159 interface page (M2) superseded Milestone 1 owner

Keep the broader registry work for a later release

As a future registry consumer, I want the five deferred edges, their Lean model, validators, candidates and evidence kept on a permanent branch with a recoverable manifest, so that restricting the first contract loses no work the registry-extension milestone will reuse.

Tracking: Ticketed. First of three serial children of the bounded-contract epic. #504 preserve broader work, #507 bounded-contract epic.

Now — landed: Merged on 8 October. The broader sources, candidates and evidence are preserved and excluded from cleanup.

Acceptance: Exact Lean and on-chain source, relevant candidates and evidence retained on a remote branch with a manifest that restores them.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: None for this story; the restriction builds on it.

Evidence: PR #510 preserve broader registry sources and candidates

Run a contract that admits only register and terminate

As a KERI integrator, I want the deployed registry to admit only insertActive (register) and updateTerminal (permanent termination), so that later Singular capabilities cannot change what my instance accepts.

Tracking: Ticketed. Second serial child. Lean boundary first, then compiled admission, builders, codecs and identities, reusing Demo 1. #505 restrict the runnable contract, #507 bounded-contract epic.

Now — landed: Merged 9 October 10:16 UTC as e3c9ab01 (PR 523, all 69 checks green): the runnable contract admits only insertActive and updateTerminal.

Acceptance: Lean admits exactly the two edges; compiled validators, builders and codecs agree; new identities are bound to the release; Demo 1 runs on them.

Dependencies: Keep the broader registry work for a later release

Next: #506 verifies the packaged contract and every deferred-edge refusal after protected rejection lands.

Evidence: PR 523 merged e3c9ab01

See every deferred edge refused by the packaged contract

As a KERI integrator, I want packaged evidence that each of the five deferred edges is refused, including independent transactions, alternate paths and mixed batches, so that the two-edge boundary is enforced by the contract, not by a hidden CLI command.

Tracking: Ticketed. Third serial child, delivered in the same cycle as the restriction. #506 verify deferred-edge refusals, #507 bounded-contract epic.

Now — planned: After #505; last of the validator and Lean sequence.

Acceptance: Allowed behaviour reproduced and an intended refusal shown for each deferred edge, with accepting controls, against the packaged artifact.

Dependencies: Run a contract that admits only register and terminate

Next: Dispatch after protected rejection lands.

Evidence: No completion evidence claimed.

Keep registries made by earlier releases working

As an operator of an earlier preprod registry, I want registries made by earlier releases to keep working after the script identities change, so that earlier deployments are not stranded.

Tracking: Decision. Ruled 8 October: registries made by earlier releases are abandoned when identities change; #480 closed as not planned. #480 earlier-release registries.

Now — superseded: Superseded by ruling. Earlier registries are abandoned rather than migrated; their cleanup on preprod is a rehearsal chore (#481).

Acceptance: None; no compatibility work is required for the first milestone.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: None.

Evidence: No completion evidence claimed.

Integrate Singular inside KERI

As a KERI integrator, I want a demonstrated KERI integration consuming the two-edge registry, so that KERI itself proves the registry fits.

Tracking: Decision. Ruled 8 October: KERI integration is not a first-milestone condition; the open-datum demos close the milestone.

Now — superseded: Not required for this milestone. The milestone closes on the Demo 1 open-datum application against the restricted contract.

Acceptance: None in this milestone.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: None in this milestone.

Evidence: No completion evidence claimed.

Read the registry interface in the documentation

As a KERI integrator, I want one documentation page and an aligned site describing the registry interface as delivered, so that I can integrate without following the design conversation.

Tracking: Ticketed. Not a first-milestone deliverable; the site was reconciled by PR #353. #159 interface page (M2).

Now — superseded: Moved to milestone M2 on 8 October: the page documents the seven-edge interface.

Acceptance: Docs state the two delivered edges, mark the five deferred edges as later, and do not claim unimplemented behaviour.

Dependencies: Run a contract that admits only register and terminate

Next: None in this milestone.

Evidence: PR #353 site reconciled with registry mode

Open-datum application and protected requests

Story Kind Tracking State Owner
Register a name with a payload and update it product Ticketed — #310 open-datum application, #301 Demo 1 epic in-progress Epic #301 owner
Terminate permanently and get the deposit back product Ticketed — #310 open-datum application in-progress Epic #301 owner
Define protected rejection in the Lean model enabler Ticketed — #494 Lean admission, #498 protected rejection, #618 rejection and termination economics blocked Milestone 1 owner
Refuse unjustified rejection on chain product Ticketed — #495 validators, #496 production fold path, #497 verify across layers, #487 fold rejects justified requests in the same transaction, #532 a reject refunds the owner, not the folder planned Milestone 1 owner
Every request carries a Singular-minted tag and has an exit product Ticketed — #529 request tag, bond and forfeit, #500 pollution research (evidence) planned Epic #498 owner

Register a name with a payload and update it

As Alice, I want to register my key with an arbitrary payload and later update that payload with my key, while Bob is refused on my payload, so that my application data stays under my control without any registry edge.

Tracking: Ticketed. Payload updates are application spends, not registry edges. Slice: registration and payload update. #310 open-datum application, #301 Demo 1 epic.

Now — in-progress: Rehearsable today on preprod against the current broad contract: register name and payload, token payload update, Bob refused on Alice's payload. Must be shown again on the restricted contract identities.

Acceptance: On the restricted contract: register, update payload with the controlling key, unauthorized update refused, token and protected fields preserved.

Dependencies: Run a contract that admits only register and terminate

Next: Re-run on the restricted contract once #505 merges.

Evidence: #484 rehearsal findings, 7 October

Terminate permanently and get the deposit back

As Alice, I want to terminate my registration permanently and recover the protected deposit, so that termination is final and costs me nothing beyond fees.

Tracking: Ticketed. Slice: termination and protected deposit. The remaining protected-deposit part of #310 follows the same sequence as protected rejection. #310 open-datum application.

Now — in-progress: Rehearsable today on the broad contract: Alice terminates and the deposit returns. The remaining protected-deposit work lands after #505, in the protected rejection sequence.

Acceptance: On the restricted contract: token burned through updateTerminal, Terminal observed, original deposit returned, early withdrawal refused.

Dependencies: Run a contract that admits only register and terminate; Refuse unjustified rejection on chain

Next: Follow #505, then protected rejection.

Evidence: #484 rehearsal findings, 7 October

Define protected rejection in the Lean model

As Bob, I want the model to admit a rejection of my request only with proof that it is justified, so that a processor cannot cancel my request and collect its tip without cause.

Tracking: Ticketed. First child of protected rejection; a first-milestone closing condition. #494 Lean admission, #498 protected rejection, #618 rejection and termination economics.

Now — blocked: Lean rule steps one to three landed on PR 615 (rejection needs bound evidence; in-window rows). The economics model and a paper derived from it were started for an early review; the first draft (14 pages) got a major-revision review on 13 October (eight findings, all accepted by the desk). Paused until the operator rules on how forfeiture is triggered, the carried termination fee, termination retraction, and the flood and incentive claims. Model, papers and research are now written by Codex gpt-6-astra high.

Acceptance: Lean rejection admission requires proof; theorems and conformance rows updated; required checks green.

Dependencies: Run a contract that admits only register and terminate

Next: Operator decision 1 of 4 (forfeit trigger), then resume the model and the paper.

Evidence: PR #508 proof-backed rejection in Lean

Refuse unjustified rejection on chain

As Bob, I want the state and request validators to refuse an unjustified rejection, shown through the production fold and the packaged CLI, so that the protection holds on chain, not only in the model.

Tracking: Ticketed. Children of epic #498. #495 validators, #496 production fold path, #497 verify across layers, #487 fold rejects justified requests in the same transaction, #532 a reject refunds the owner, not the folder.

Now — planned: Blocked on #505 and the Lean rule; then the request tag (#529).

Acceptance: Validators refuse unjustified rejection with accepting controls; evidence built through the production fold; model, validators and packaged CLI agree.

Dependencies: Define protected rejection in the Lean model

Next: After the 22 October Demo 1 review (operator, 13 October).

Evidence: No completion evidence claimed.

Every request carries a Singular-minted tag and has an exit

As a registry user and a processor, I want a request to exist only with a tag minted by the registry's request policy with a bond, untagged outputs at the request address spendable by anyone, and every tagged request promised an exit by fold, proof-backed rejection, owner reclaim or expiry, so that pollution of the request address is collectible rather than permanent, and a rejection flood costs its author more than the fold capacity it consumes.

Tracking: Ticketed. Child of epic #498 since 8 October; the forfeit destination is an open decision. #529 request tag, bond and forfeit, #500 pollution research (evidence).

Now — planned: After the protected-rejection validators; before the one new preprod registry, because it changes the request wire. On 13 October the operator replaced the forfeit taken from the deposit with a new registry parameter, the bond: every request carries it beside its deposit, a provable rejection forfeits only the bond, and the deposit and approval return to the owner, enforced on chain.

Acceptance: Mint refuses an unauthenticated request; untagged outputs spent by a stranger; a tagged request exited permissionlessly after expiry with its refund.

Dependencies: Refuse unjustified rejection on chain

Next: After the 22 October Demo 1 review (operator, 13 October).

Evidence: No completion evidence claimed.

Independent actors from public chain data

Story Kind Tracking State Owner
Join a registry from its state token alone product Ticketed — #501 join from state token, #437 join-by-token feature epic, #371 independent actors epic landed Epic #371 owner
Run every command against live Koios enabler Ticketed — #389 live Koios client in-progress Epic #371 owner
Publish missing reference scripts safely product Ticketed — #471 publish reference scripts, #437 join-by-token feature epic, #603 fold refused naming the missing script, #604 preview what is missing, #605 publish and read back, #606 another actor folds after restoration, #607 recover an interrupted publication, #608 ordinary writes never spend a carrier, #609 funding views only, #610 raw ledger kernel in its own component, #611 hosted check against raw ledger access, #612 public controls planned Epic #371 owner
Retire reference carriers I own product Ticketed — #502 retire owned carriers, #437 join-by-token feature epic planned Epic #371 owner
Read the registry page generated from chain product Ticketed — #503 page from chain, #437 join-by-token feature epic in-progress M1 desk (standalone ticket lane)
Join from the state token alone and prove two actors share no directory enabler Ticketed — #485 CLI-managed state, no per-registry directory, #381 independent-actor journey, #492 inspect shows the registry landed Epic #371 owner
Fold every settleable pending request at once product Ticketed — #518 fold every settleable pending, #488 no stuck request blocks the others, #396 epic: several users book concurrently, #545 epic (M4): command effects ownership, lands first landed Epic #396 owner
Admit a request only inside its processing window product Ticketed — #519 processing-window admission in-progress Epic #396 owner

Join a registry from its state token alone

As Bob, I want to join, book, fold and inspect a registry using only its state token, my wallet and Koios, so that I need no files from the registry creator.

Tracking: Ticketed. First of four serial children of #437. #501 join from state token, #437 join-by-token feature epic, #371 independent actors epic.

Now — landed: Landed with PR #476 (#501): join, book, fold and inspect from a state token on a devnet.

Acceptance: Join, book, fold and inspect from token, release and public data, with no creator files or reference hints.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: Show it on preprod in the next rehearsal.

Evidence: PR #476 join, book, fold and inspect from a state token

Run every command against live Koios

As Alice, I want to run registry commands with only singular, a wallet and a Koios URL, with every fact reported unverified with its session, so that no node and no shared directory are needed.

Tracking: Ticketed. Reopened; evidence retention for create previews merged 7 October. #389 live Koios client.

Now — in-progress: Live Koios routing is in use; the ticket was reopened for remaining evidence gaps.

Acceptance: Commands read, replay and submit through live Koios, with recorded and live responses sharing one client and decoder.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: Close the remaining evidence gaps named on #389.

Evidence: PR #499 preserve session evidence for local-key create previews

Publish missing reference scripts safely

As Bob, I want to publish or restore missing reference scripts explicitly, funded so my token holdings and carriers are never spent by accident, so that a fold never fails for want of a reference script.

Tracking: Ticketed. Second child of #437. Re-cut 13 October into slices #603 to #612. #471 publish reference scripts, #437 join-by-token feature epic, #603 fold refused naming the missing script, #604 preview what is missing, #605 publish and read back, #606 another actor folds after restoration, #607 recover an interrupted publication, #608 ordinary writes never spend a carrier, #609 funding views only, #610 raw ledger kernel in its own component, #611 hosted check against raw ledger access, #612 public controls.

Now — planned: Off the Demo 1 path (checked 13 October against the review card and the Demo 1 epic). Re-cut into small slices; the first slice is planned; the lane is parked until after the 22 October review. The old work is kept on the pushed backup branch.

Acceptance: Explicit publish and restore with protected wallet funding, followed by a successful consuming fold.

Dependencies: Join a registry from its state token alone

Next: Wake after the 22 October review.

Evidence: PR #516 publish reference scripts with protected wallet funding (draft)

Retire reference carriers I own

As Bob, I want to retire reference-script carriers I own and recover their funds, then restore and fold again, so that publication does not lock my funds forever.

Tracking: Ticketed. Third child of #437. #502 retire owned carriers, #437 join-by-token feature epic.

Now — planned: Not started.

Acceptance: Owned carriers retired with assets returned; missing, restore and fold demonstrated; ordinary funding protection unchanged.

Dependencies: Publish missing reference scripts safely

Next: Start after #471.

Evidence: No completion evidence claimed.

Read the registry page generated from chain

As Alice, I want the packaged CLI to generate the registry page from public replay, so that Alice and Bob see the same registry with only a web page, Koios and a wallet.

Tracking: Ticketed. Fourth child of #437. #503 page from chain, #437 join-by-token feature epic.

Now — in-progress: Both pull requests merged (PR 614 on 13 October; PR 628 on 14 October, 7dbe3568). Alice extracts the release archive, runs create, and the receipt prints the exact describe command; run as printed from the archive it shows the registry identity, release, rules and live state from public replay, provenance naming Koios as unverified. Demo 1 run page and the hosted archive journey read the page after create and after the lifecycle. Issue stays open for accepted follow-ups: block anchor of the last fold, documentation links checked against a published asset, independently derived action identity in the public conformance report.

Acceptance: The packaged CLI generates the release-bound page from public replay and it matches the chain.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: Follow-ups only; Demo 1 rehearsal reads it.

Evidence: PR 628 merged (7dbe3568): archive version, create prints the describe command, Demo 1 reads the page from the archive

Join from the state token alone and prove two actors share no directory

As a demo reviewer, I want evidence that Alice and Bob rebuild registry state from provider history with no shared directory, so that independence is demonstrated, not asserted.

Tracking: Ticketed. Children of epic #371, Bob joins and operates independently. #485 CLI-managed state, no per-registry directory, #381 independent-actor journey, #492 inspect shows the registry.

Now — landed: #485 merged on 9 October (PR 525). #381 merged on 11 October 11:03 UTC (f6783383, PR 433): two actors on separate machines join, book and fold from the state token alone, the public replay rebuilds the registry, and the journey runs the open-datum executable after the command-line split. #492 (inspect shows the whole registry) stays open in the same epic, paused.

Acceptance: Two actors in separate empty directories rebuild the same tries from provider history, with controls.

Dependencies: Join a registry from its state token alone

Next: Next release; #492 when the epic is released.

Evidence: PR 433 merged (f6783383)

Fold every settleable pending request at once

As a processor, I want one fold transaction to settle every settleable pending request, whoever booked it, naming each one left out and why, so that two users booking at the same moment do not block each other.

Tracking: Ticketed. Children of epic #396, several users book concurrently. #489 closed into the epic; #486 moved to the command-line split, #487 to protected rejection (desk answer A-002, 9 October). #518 fold every settleable pending, #488 no stuck request blocks the others, #396 epic: several users book concurrently, #545 epic (M4): command effects ownership, lands first.

Now — landed: Landed on 14 October: #518 closed by PR 627 (38c7fbc1) after pull requests 556, 569, 591, 622 and 626. One fold settles every settleable pending request up to nine; journal, reconciliation and replay bind every transition; the receipt names settled and excluded requests; devnet evidence covers two actors in one fold, an excluded request named, and an interrupted two-request fold recovered. Epic #396 stays open for its remaining children.

Acceptance: Fold settles all settleable pending requests in one transaction; receipt names settled and excluded requests with reasons.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: Epic #396 owner: residuals mapped at #518 closure; Demo 1 rehearsal reads it.

Evidence: PR 556 merged (9d5f4c7a), PR 569 merged (e3af83c1): receipts carry the settled list, PR 622 merged (71fd4547): fold, builder and journal carry a selection of any size, PR 626 merged (33ed29fc): recovery reads every transition, bound nine, receipt readers, Demo 1 with two actors in one fold, PR 627 merged (38c7fbc1): an interrupted two-request fold reconciles both keys on a devnet; #518 closed

Admit a request only inside its processing window

As a processor, I want a fold to include a request only while it is inside its processing window, judged against the transaction validity bound, so that batching never breaks the window rules.

Tracking: Ticketed. Follows #518. #519 processing-window admission.

Now — in-progress: Released 14 October by the operator for Demo 1. Four pull requests: (1) merged 14 October (d4f8d94a): the model refuses a batch whose termination burns a holding an earlier request of the same batch created; (2) merged 14 October (55a64aa9): the model admits a fold only inside every request window; (3) builder and receipt say the same in the model words; (4) tests against the compiled validator (after #495 and #529). No pull request moves a script identity: the deployed validator already refuses the late fold.

Acceptance: Lean, off-chain builder and validators agree on window admission; a batch never consumes an output it creates.

Dependencies: Fold every settleable pending request at once

Next: Pull request 3 (builder and receipt) now, in parallel with the first wallet-preparation pull request; first green merges first.

Evidence: PR 630 merged (d4f8d94a): the model refuses a batch that terminates a key it just registered, PR 634 merged (55a64aa9): the model admits a fold only inside every request window

Demo 1 rehearsal and packaging

Story Kind Tracking State Owner
Create a registry without a stranded partial run product Ticketed — #406 funding judged before the first submission, #478 no stranded partial creation, #479 covering funding output, #491 wallet outputs prepared by the command, #520 epic: Carl creates a usable registry in-progress Epic #520 owner
Let the chain refuse a forbidden transaction enabler Ticketed — #358 singular-negative host, #521 epic: forbidden actions refused by the chain, #559 a mutant for the registry-insertion pairs landed Epic #521 owner
Act on the 7 October rehearsal findings operation Ticketed — #484 rehearsal findings landed Epic #301 owner
Clean up the preprod registries left by earlier attempts operation Ticketed — #481 preprod cleanup planned Epic #301 owner
Rehearse Demo 1 with Alice and Bob on preprod operation Ticketed — #359 two-player rehearsal planned Epic #301 owner
Run Demo 1 on preprod against the restricted contract outcome Ticketed — #301 Demo 1 epic, #300 pinned archive and preprod evidence, #261 review card, 22 October planned Epic #301 owner
Every test the repository declares runs in hosted CI enabler Ticketed — #562, #563, #564, #565 landed M1 desk (standalone lane #562)
Read the test suite in the documentation product Ticketed — #576 test suite in the documentation planned M1 desk (no lane yet)

Create a registry without a stranded partial run

As a demo operator, I want registry create to fund publications from suitable outputs, check funding for all scripts up front, and leave a run that can be used or resumed, so that the next rehearsal starts from a working registry.

Tracking: Ticketed. Children of epic #520, Carl creates a usable registry. #406 funding judged before the first submission, #478 no stranded partial creation, #479 covering funding output, #491 wallet outputs prepared by the command, #520 epic: Carl creates a usable registry.

Now — in-progress: #478 closed by PR 613; #406 and #479 closed by PR 625 on 14 October (0272dadc): create works from one ada-only output, refuses up front naming the short step and total, and covers the create part of #491. The rest of #491 (the command prepares wallet outputs) is the next slice.

Acceptance: Create succeeds from an ordinary wallet or refuses before booting; a partial run is usable or resumable.

Dependencies: Publish missing reference scripts safely

Next: #406 lane slice 3 (#491 remainder): plan to the desk, then writer.

Evidence: PR 598 merged (4b76b326): Demo 1 docs fund a create from one output (#491 docs), PR 613 merged (f8b902cf): funded from several outputs, refused up front, PR 625 merged (0272dadc): create from one ada-only output, seed from the first publication change

Let the chain refuse a forbidden transaction

As a demo reviewer, I want the singular-negative host to submit transactions the CLI would refuse, so the chain itself refuses them, so that refusals are shown at the contract, not only in the CLI.

Tracking: Ticketed. Sole child of epic #521, Bob attempts forbidden actions. #358 singular-negative host, #521 epic: forbidden actions refused by the chain, #559 a mutant for the registry-insertion pairs.

Now — landed: Slices 1 and 2 merged on 9 October. Slice 3 part A merged on 11 October 14:04 UTC (d8bc7dbc, PR 550): a stranger or owner registering a taken key, reviving a terminated key, and a fold paying the controller short are each refused by the chain beside their accepted control, all thirteen pairs green from the release archive. Part B1 merged on 11 October 17:51 UTC (403b4800, PR 558): each of the nine application pairs has a mutant validator job that turns its row red when the rule is removed, with a control pair that stays green, and two aggregate checks gather the pair and mutant jobs. Part B2 merged on 12 October 08:56 UTC (1d9f8b0d, PR 567): the reclaim of a booking a refused insertion strands, with the ordinary singular registry reclaim, and the documentation page "What singular-negative shows". #358 is closed. Follow-ups, each its own issue: the update-deposit pair (#552), shared crafting (#551), a finished local part run leaving its devnet (#560), the two-actor job timing (#573). The registry-insertion pairs got their mutant on 12 October 13:19 UTC (3bff7e6c, PR 577): one mutant removes both layers of the occupied-key defence and all four pairs turn red, so every one of the 13 pairs is shown able to fail.

Acceptance: Each refused subcommand reaches the chain and is refused by the intended script.

Dependencies: Run a contract that admits only register and terminate

Next: Follow-ups only: #559, #552, #551, #560, #573.

Evidence: PR 550 merged (d8bc7dbc), PR 558 merged (403b4800): a mutant job per application pair, PR 567 merged (1d9f8b0d): reclaim and docs page, PR 577 merged (3bff7e6c): the registry occupied-key mutant

Act on the 7 October rehearsal findings

As a demo operator, I want every finding of the 7 October preprod rehearsal mapped to a ticket or ruled out, so that the next rehearsal does not repeat known failures.

Tracking: Ticketed. Findings record; carries no milestone on GitHub. #484 rehearsal findings.

Now — landed: Every finding placed on 8 October: joining, batching and inspect under their journey epics; wallet and vault to tooling; replay cache under recovery.

Acceptance: Every finding resolved or explicitly excluded.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: None; the epics carry the work.

Evidence: #484 placement table

Clean up the preprod registries left by earlier attempts

As a demo operator, I want the registries left by the 7 October attempts cleaned up and their funds recovered, so that preprod holds only the registry the demo uses.

Tracking: Ticketed. Earlier-release registries are abandoned by ruling; this recovers what can be recovered. #481 preprod cleanup.

Now — planned: Not started.

Acceptance: Each left-over registry is inventoried and closed or recorded as unrecoverable.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: Run before the authorized new preprod registry.

Evidence: No completion evidence claimed.

Rehearse Demo 1 with Alice and Bob on preprod

As a demo reviewer, I want a recorded two-player rehearsal on preprod with singular and singular-negative, so that the demo is proven end to end before packaging.

Tracking: Ticketed. Rehearsal only; packaging is separate. #359 two-player rehearsal.

Now — planned: Waits on the restricted contract, independent actors, batch fold and the negative host.

Acceptance: Alice and Bob in separate empty directories run the full journey on the restricted contract, with refusals shown by the chain.

Dependencies: Create a registry without a stranded partial run; Let the chain refuse a forbidden transaction; Clean up the preprod registries left by earlier attempts; Join from the state token alone and prove two actors share no directory; Read the registry page generated from chain; Admit a request only inside its processing window; Register a name with a payload and update it; Terminate permanently and get the deposit back; Keep the command journal bounded; Reuse the reconstructed registry between commands

Next: Schedule once its dependencies land.

Evidence: No completion evidence claimed.

Run Demo 1 on preprod against the restricted contract

As a KERI integrator, I want the Demo 1 open-datum application packaged and run on preprod against the two-edge contract, so that the first milestone closes on a demonstrated permanent registry.

Tracking: Ticketed. The milestone closing bar. Protected rejection is also a closing condition. #301 Demo 1 epic, #300 pinned archive and preprod evidence, #261 review card, 22 October.

Now — planned: Review date 22 October. Not yet: depends on the restricted contract, protected rejection and the rehearsal.

Acceptance: Pinned application archive, preprod transactions and readbacks for register, payload update, refusals and termination with deposit return, bound to the restricted contract. Public readback uses Koios only (operator, 13 October): one indexer, not two.

Dependencies: Rehearse Demo 1 with Alice and Bob on preprod; Refuse unjustified rejection on chain

Next: Package after the rehearsal passes.

Evidence: No completion evidence claimed.

Every test the repository declares runs in hosted CI

As a maintainer, I want every test, control and check that the repository declares, and that anyone cites as evidence, to run in a hosted job and pass on main, so that a green main means what it says, and a broken check is seen the day it breaks.

Tracking: Ticketed. Opened 2026-10-11 after an audit found four recovery parts and seven checks run by no hosted job, and three red on main; the operator paused other work to fix main first. #562, #563, #564, #565.

Now — landed: Landed 12 October. PR 571 hosted seven unhosted checks; PR 572 added the census of declared checks; PR 575 (758897ae) runs the recovery parts in parallel partitions and closed #563 and #564; PR 578 (d1a97a31) made the release review archive check pass and hosted it, closing #565; #562 closed 12 October. Follow-ups #587 (a release control discards the verifier output when no refusal line is printed) and #590 (the mutant self-check runs for one mutant of eight, outside the aggregate) are open under the negative-host hardening and release story.

Acceptance: Every declared check either runs in a hosted job or is a marked tool never cited as evidence; rollback and trie-capability pass on main; the release review archive check passes and is hosted.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: None for this story; follow-ups are tracked in their own stories.

Evidence: PR 571 merged (2c61a1c2): seven checks get hosted jobs, PR 568 merged (d20f88e9): recovery parts judged in a hosted job, hooks out of the release, Release 0.10.1, PR 572 merged (6cb27c70): the census of declared checks, PR 575 merged (758897ae): recovery parts in parallel partitions, PR 578 merged (d1a97a31): the release review archive check passes and is hosted, PR 593 merged (2a8ec380): superseded main runs are cancelled, PR 600 merged (2c5855aa): the CI summary skips cancelled runs

Read the test suite in the documentation

As a reviewer outside the project, I want the test suite presented in the documentation, acceptance tests as manuals and folders by test class, so that the evidence behind each claim can be read without the source tree.

Tracking: Ticketed. Filed 12 October. #576 test suite in the documentation.

Now — planned: Filed, not started.

Acceptance: Acceptance tests appear as manuals in the documentation, grouped by test class.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: Assign after the Demo 1 critical path.

Evidence: No completion evidence claimed.

Speed, recovery and readable command output

Story Kind Tracking State Owner
Wait less for confirmations product Ticketed — #509 reduce waiting landed Milestone 1 owner
Shorten the evidence campaign enabler Ticketed — PR #515 speed up evidence copies, #592 skip tests already verified green (result cache) in-progress Milestone 1 owner
Watch commands narrate their protocol activity product Ticketed — #416 live narration planned Epic #522 owner
Keep the command journal bounded enabler Ticketed — #477 journal growth, #522 epic: live narration and safe recovery planned Epic #522 owner
Decide whether a failed trace file warns operation Decision — #483 trace warning decision Epic #522 owner
Reuse the reconstructed registry between commands product Ticketed — #493 cached replay checkpoint planned Epic #522 owner
Receipts name the right party and every transaction expires product Ticketed — #415 Koios transport error is not a node refusal, #526 wallet floor shortfall is not node-unavailable, #334 validity upper bound on every transaction, #335 stranded booking reconciled, #623 typed wallet shortfall for the other commands, #624 devnet insert from an empty wallet planned Epic #522 owner
The Koios retry-ceiling test passes under full-suite load enabler Ticketed — #531 retry-ceiling test fails under load landed M1 desk
The negative host and its devnets clean up after themselves and check every mutant enabler Ticketed — #590 mutant self-check runs for one mutant of eight, #552 pair for the protected-deposit update rule, #551 one home for forbidden-transaction crafting, #560 a finished part run leaves its devnet behind, #553 devnets stopped by recorded pids, #557 pinned node clients predate the unique devnet directory fix, #587 a release control discards the verifier output planned M1 desk (no lane yet)

Wait less for confirmations

As a demo reviewer, I want commands to wait less for confirmation, with bounded query overhead, so that the demo runs at a watchable pace.

Tracking: Ticketed. Closed by PR #512. #509 reduce waiting.

Now — landed: Merged 8 October.

Acceptance: Confirmation waiting reduced with measured query overhead.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: None.

Evidence: PR #512 reduce confirmation waiting

Shorten the evidence campaign

As a Singular developer, I want the evidence campaign to run faster with stable recovery fixtures, so that each change gets its evidence sooner.

Tracking: Ticketed. Pull request only, following #509. PR #515 speed up evidence copies, #592 skip tests already verified green (result cache).

Now — in-progress: PR 515 merged. #592 skips negative-host jobs whose exact inputs were already verified green (Nix-hash result cache): slice 1 is draft PR 597, paused since 12 October and woken on 13 October for a rebase only.

Acceptance: Campaign faster with all required checks green.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: Release #592 to finish slice 1.

Evidence: PR 515 merged: faster evidence copies, stable recovery fixtures

Watch commands narrate their protocol activity

As a demo reviewer, I want commands to narrate live, grouped by registry, request, edge and transaction, so that the audience follows what happens on chain.

Tracking: Ticketed. Moved under epic #371 on 8 October. #416 live narration.

Now — planned: Typed events merged (PR 418); sinks, timed reads and the recording remain; last in epic #522.

Acceptance: Each command narrates its protocol steps live in the stated grouping.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: Schedule under epic #371.

Evidence: No completion evidence claimed.

Keep the command journal bounded

As a demo operator, I want the command journal not to keep every raw provider answer, so that long runs do not grow without bound.

Tracking: Ticketed. Moved under epic #371 on 8 October. #477 journal growth, #522 epic: live narration and safe recovery.

Now — planned: Plan reviewed 9 October; parked ready to code; builds in the library session layer after #528 and #518 PR 2.

Acceptance: Journal size bounded while replay evidence is preserved.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: Coding released by the desk in merge-queue order.

Evidence: No completion evidence claimed.

Decide whether a failed trace file warns

As a demo operator, I want a decision on whether a failed trace file write warns on stderr, so that trace failures are neither silent nor noisy by accident.

Tracking: Decision. Moved under epic #371 on 8 October. #483 trace warning.

Now — decision: One question to the desk when epic #522 reaches it.

Acceptance: Decision recorded and implemented.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: Epic #371 owner decides.

Evidence: No completion evidence claimed.

Reuse the reconstructed registry between commands

As Alice, Bob or Carl inspecting a registry repeatedly, I want my own local state to keep the rebuilt trie and its chain checkpoint so the next command processes only new history and detects history that no longer extends it, so that a second command does not cost what the first did, and a rollback or fork is never reported as current state.

Tracking: Ticketed. Supersedes #436; child of epic #522. #493 cached replay checkpoint.

Now — planned: Plan reviewed 9 October (five pull requests; a public replay partition beside the wallet folders, desk answer A-003); parked ready to code after #477.

Acceptance: Cold and warm runs agree; incremental update, rollback and fork recovery and an interrupted write are covered with measured provider and replay work.

Dependencies: Keep the command journal bounded

Next: Coding released by the desk in merge-queue order.

Evidence: No completion evidence claimed.

Receipts name the right party and every transaction expires

As a CLI user, I want a provider transport error or a wallet shortfall never reported as a node refusal, every built transaction carrying a validity upper bound, and a booked request whose fold died picked up by the next command, so that recovery after an interruption is complete and the outcome words tell the truth.

Tracking: Ticketed. Children of epic #522, placed 8 October. #415 Koios transport error is not a node refusal, #526 wallet floor shortfall is not node-unavailable, #334 validity upper bound on every transaction, #335 stranded booking reconciled, #623 typed wallet shortfall for the other commands, #624 devnet insert from an empty wallet.

Now — planned: After the cached replay. #526 landed 13 October (PR 619, 6ec6b7f8): a write asks the wallet for what the operation costs; a shortfall is a client refusal naming the wallet, with the faucet step for an empty one. Follow-ups #623 and #624.

Acceptance: Each outcome word is produced by a control for its real cause; an excluded fold is proven excluded; a stranded booking is folded or retracted, never doubled.

Dependencies: Reuse the reconstructed registry between commands

Next: After #493.

Evidence: No completion evidence claimed.

The Koios retry-ceiling test passes under full-suite load

As a maintainer, I want the retry-ceiling test to pass whether it runs alone or inside the full suite, so that a green suite is believed.

Tracking: Ticketed. Filed 9 October; fixed as a standalone change 13 October. #531 retry-ceiling test fails under load.

Now — landed: Fixed by PR 601, merged 13 October (745d85c7); #531 closed.

Acceptance: The test passes in the full suite on three consecutive hosted runs.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: None.

Evidence: PR 601 merged (745d85c7): retry-ceiling test fixed

The negative host and its devnets clean up after themselves and check every mutant

As a maintainer, I want every negative-host pair and mutant to run in a hosted aggregate, and every devnet to stop and clean up by its own recorded identity, so that red means a real refusal failed, never a leftover devnet or an unchecked mutant.

Tracking: Ticketed. Follow-ups of the negative host (#358) and of the main-tests work, filed 9 to 12 October. #590 mutant self-check runs for one mutant of eight, #552 pair for the protected-deposit update rule, #551 one home for forbidden-transaction crafting, #560 a finished part run leaves its devnet behind, #553 devnets stopped by recorded pids, #557 pinned node clients predate the unique devnet directory fix, #587 a release control discards the verifier output.

Now — planned: Filed, not started. #573 (devnet epochs long enough for a fold window, PR 602) landed 13 October.

Acceptance: All eight mutants checked inside the hosted aggregate; no devnet, node or directory left after any part run; concurrent devnets cannot delete each other.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: Assign to a lane after the Demo 1 critical path.

Evidence: PR 602 merged (e7b55ac9): 20000-slot devnet epochs (#573)

Registry command line and application binaries

Story Kind Tracking State Owner
The registry command line is five commands; applications are their own executables enabler Ticketed — #528 registry-only CLI, open datum as its own executable, #486 booking refuses what the state rules out, #547 one shared flag reader for every binary landed M1 desk (standalone lane singular-ms1-t528-cli-split)
The documented invocations are derived from the binaries enabler Ticketed — #538 derive documented invocations from the binaries planned M1 desk (no lane yet)

The registry command line is five commands; applications are their own executables

As an application author, the open datum today and cardano-keri next, I want singular to offer only create, fold, reject, reclaim and inspect, and my application to be its own executable built on the Singular library, accepting Singular's flags unchanged, minting its own approval and having the library build the request around it, so that the registry carries no application code and the second application does not unpick the first.

Tracking: Ticketed. Cleanup, not a logic change: runs in an exclusive window after #505 so every later slice is built on the new layout. #528 registry-only CLI, open datum as its own executable, #486 booking refuses what the state rules out, #547 one shared flag reader for every binary.

Now — landed: PR 535 merged on 11 October 06:41 UTC (c6748950): singular offers only create, fold, reject, reclaim and inspect; the open datum is its own executable in its own trees (applications/open-datum/, its own Aiken project and cabal package); the registry trees hold no open-datum code; every published script hash is unchanged; the booking refusal (#486) refuses before signing in every ordinary command. The one acceptance item left unmet, a single reader for the common flags, was closed by PR 554 (#547), merged on 11 October 16:32 UTC (95e1d880): singular, open-datum and the negative host read the common flags through one function in registry-cli. The cardano-keri stub merged on 12 October 12:55 UTC (6d2de3a5, PR 561): a second application registers, convicts and folds its own key on a devnet with its own policy through the library, needing nothing from the open datum. #528 is closed.

Acceptance: singular accepts only registry commands; the open-datum executable covers insert, update and terminate; no registry module imports the open-datum package; a cardano-keri stub registers and convicts through the library on a devnet.

Dependencies: Run a contract that admits only register and terminate

Next: Done.

Evidence: PR 535 merged (c6748950), #538 follow-up: structured documented-commands check, PR 554 merged (95e1d880): one shared flag reader, PR 561 merged (6d2de3a5): the cardano-keri stub

The documented invocations are derived from the binaries

As a reader of the documentation, I want every documented command invocation checked against what the shipped binaries accept, so that the docs never show a flag the command refuses.

Tracking: Ticketed. Follow-up of the command-line split (#528, #547). #538 derive documented invocations from the binaries.

Now — planned: Filed, not started.

Acceptance: The documented-flags check reads the binaries, not prose.

Dependencies: No prerequisite story recorded; this is not dispatch authority.

Next: Assign after the Demo 1 critical path.

Evidence: No completion evidence claimed.

Maintenance

This page and its Gantt are generated from the adjacent story register. The milestone owner must reconcile it on material state changes and before handoff. Updating the timestamp alone is not reconciliation. A normal debrief reads this page; an authorised state sweep updates and publishes it. If publication is blocked, the desk must name the stale publication and pending changes.

Register schema: milestone-stories/v1. Parsed-register SHA-256: d00765151be39c0d5fac6d740e3c3b3adabeab84dc5ac52dd133ab595ef4d9e9.