The application¶
Status: draft. Expanded as a plan in PLAN-0004. This file stays the behaviour sketch.
Written because the honest answer to "have we planned the
application?" was no. PROC-0004 §6 lists packaging, checksums, signing
and app notes — six checkboxes about shipping a thing whose behaviour was
never specified.
0. Correction — 2026-09-23¶
v0.1 said "a CLI and not a GUI" and argued that a GUI would obscure whether a rendered sentence came from the vocabulary or from the programmer. The sponsor has since specified a graphic UI for two specific applications, in October. That supersedes the argument, and the argument was wrong anyway: the way to show a rendering came from the vocabulary is to render two unrelated domains through one UI — which a GUI demonstrates more convincingly than a terminal does.
v0.2 therefore specifies a wallet application with a graphic UI, with the CLI retained as the scriptable surface underneath it.
1. What it is¶
A wallet. It holds keys, trust roots and statements; it makes attestations; and it evaluates a set of statements to decide whether to believe a claim.
| surface | for |
|---|---|
| graphic UI | the two use-case applications. October |
| CLI | the same operations, scriptable. Already prototyped |
| library | the reduction and encoding underneath both |
Why "wallet" rather than "tool": the noun matters because it names what the
user actually has — a set of keys and a set of things other people have said,
which they carry and present. PROC-0004 and PLAN-0001 both under-specified
this, and the sponsor flagged it as missing on 2026-09-22.
2. What a wallet does¶
| hold | keys, and trust roots — "I trust Pa for email in *@foo.com" |
| collect | statements others have made, including ones about you |
| make | attestations, and delegations |
| present | the set of statements a relying party needs to believe a claim |
| evaluate | reduce a presented set against your own roots, and say why |
Trust roots are the part that is easy to miss. They are unsigned — nobody
said them to you, you decided them. That is the fixed floor: if a key could
define its own trustworthiness there would be no floor at all, and it is why
ARCH-0001's AclEntry has no speaker.
3. Commands¶
# domains of discourse — the PICS-like layer
mofn domain init supply-chain --key paul.key
mofn domain add-type supply-chain build-provenance \
--value reproducible:"built reproducibly from published sources" \
--value attested:"built by an attested pipeline" \
--value unverified:"origin not verified"
mofn domain id supply-chain # the hash that identifies the SET
# statements
mofn make --key tool.key --subject dist/app.pyz \
--type paul:build-provenance --claim reproducible > prov.stmt
mofn make --key paul.key --subject-key david.pub \
--type paul:name --claim david > name.stmt
mofn make --key paul.key --subject-key david.pub \
--type paul:may-speak \
--domain supply-chain --topic build-provenance > deleg.stmt
# checking and reading
mofn check prov.stmt --domain supply-chain
mofn render prov.stmt --lang es
mofn reduce deleg.stmt prov.stmt --ask "may david attest build-provenance?"
4. What a user sees — the verdict¶
check prints the six dimensions of R-O-06, separately, and then says what it
does not prove.
statement prov.stmt
integrity ok subject digest re-derives
authenticity ok signature valid under key 9f2a…
names ok no name chain to resolve
authorization FAIL tool.key is not entitled to assert
paul:build-provenance about this subject
acceptance — not evaluated: authorization failed
semantics ok domain 2104d6d4… resolved, value in range
"The artifact sha256:8e1c… was built reproducibly from published sources."
— asserted by key 9f2a…, which has no standing to say so.
This proves origin and integrity. It does not prove truth.
The authorization line is the product. Everything else is available
elsewhere; a valid signature from a key with no standing to make the claim is
the distinction nothing mainstream surfaces.
4b. The UI, phase by phase¶
Added 2026-10-14 from sponsor direction. The object model behind these
screens is ARCH-0003. A persona is a key-identified principal — controlled
by a person, an organisation, a service, an AI agent or a device. A wallet
holds personas: it owns some (it has their private keys) and knows
others. Every card is a held statement rendered by a definition
identified by its hash. The three "personas" earlier drafts named — domain
author, issuer, relying party — are roles, and one persona plays all of
them.
Think Apple Wallet at the surface: a stack of cards you carry and present. The difference underneath is that anyone can publish the card format (a definition, by hash), and whether to believe a card is your decision, made by reduction from your own trust anchors — not the platform's.
| phase | role | where it starts | the screen | the one thing it must make unmistakable |
|---|---|---|---|---|
| 0. Set up | — | first run; + Persona | Persona card for an owned persona: identity key, cipher suite, controller kind, keys as chips with capability badges (define claim delegate review approve), contexts as tabs |
which keys exist, under which suite, what each may sign — and that private keys never leave the device |
| 0b. Discover & trust | — | People & services → Add (scan, file, introduction, from a presentation) | Known persona card: fingerprint to compare, controller kind and who asserts it, how and when it was discovered, introductions, then Trust in context… | known ≠ trusted (ARCH-0003 W-14): a newly met persona has no standing until you anchor it, or a chain from an anchor reaches it |
| 1. Define | define | Definitions → New | Definition editor: types, permitted values, names and descriptions per language, review tags — with a live preview of the sentence a claim will render as | the hash: Publish computes DefinitionId, shows it as a fingerprint, and signs it with a define-capable key. After that it is immutable; edits make a new version |
| 2. Claim | claim | a context → Make | Claim form generated from the definition — no type-specific UI code (PLAN-0004 §3's test) — then constraints (valid until, scope), then the rendered sentence | who is speaking: persona, context and key, auto-selected by capability, shown above Sign |
| 3. Delegate | delegate | a persona or context → Allow… | an iOS-style permission sheet: who · may speak about (definition, topics) · until when · may re-delegate? | the scope and the expiry, in words: "David may attest build-provenance for m-of-n until Friday 17:00, and may not pass this on" |
| 4. Review & approve | review, approve | Inbox — requests arriving by file or wallet-to-wallet transport (ARCH-0003 §7) | the claim rendered, its chain, its verdict so far, the definition's review tags as a checklist; actions Approve · Request changes · Decline with comment; threshold progress (2 of 3 approved) | review ≠ approval: the Approve button appears only when this key holds an approve delegation for that definition (ARCH-0003 W-08) |
| 5. Present | present | a card → Share | choose the statements to send (the claim and its chain), the audience, and the channel — file, QR, link | exactly what is disclosed, listed before sending |
| 6. Check & accept | rely | drop or scan a presentation | the verdict (§4): six lines, the sentence, the chain, the limit line; then Accept into context… or Reject | authorization as its own line — and that accepting records why, under which anchors, so it can be re-examined |
| Trust settings | — | a context → Trust | the context's anchors, styled differently from every card | anchors are your decisions, unsigned — nobody said them to you |
What the CS Night demo walks through is ARCH-0003 §8: publish a template (1) → introduce and delegate to a build-bot persona (0b, 3) → issue from the template (2) → present (5) → discover and check in a second wallet (0b, 6) — then the failures: out of scope (authorization ✘), template not met (expected ✘), review without approval (4), and the archives domain on the same screens.
PLAN-0004 §5's five views are a subset of this table: Wallet ≈ phase 0 and the card stack, Domain ≈ phase 1, Make ≈ phase 2, Present ≈ phase 5, Verdict ≈ phase 6. Phases 3 and 4 are new.
5. What it deliberately does not do¶
- No key management. Keys are files. No agent, no keychain, no rotation.
- No network. No fetching domains, no transparency log, no registry. A domain is a file you already have.
- No revocation. Short validity or nothing.
- No web UI, no server. A local graphic UI is in scope (PLAN-0004). It is not a site.
- No cryptographic primitives of our own — a vetted library, always.
- No knowledge-graph engine. Delegation is graph-shaped
(speaker, statement, target; chains compose), but the operation is deterministic
reduction — match subject to next issuer, intersect tag and validity — not an
open graph query. Store statements as files (a simple index is enough) and run
reduce/check. A graph database or RDF stack is out of scope for the wallet.
6. Relationship to the demo floor¶
They are the same deliverable, and that is the useful finding.
PLAN-0001 §9's I3 floor is name resolution, reduction, thresholds and a
multi-dimensional verdict. That is reduce plus check. The application is
not additional work after the floor — it is the floor, with a CLI on it.
| demo moment | command |
|---|---|
| show a statement, read it aloud | render |
| verify — six dimensions green | check |
| tamper, the verifier names the break | check |
| valid but unauthorized key | check + reduce |
| different subject type, same code path | render with a second domain |
Consequence: D8 should not be scheduled after D6. Packaging is the only part that is genuinely later.
7. What exists already¶
prototype/statements/ — statement creation, reduced-CBOR encoding, signing
shape, subject modes, domains, hash-identification, range checking, multilingual
rendering, and now reduction.
demo_email.py runs the sponsor's Alice/Bob/Carol/Dave example end to end,
including the three cases that must fail. Reduction is no longer the gap.
8. The gap now¶
The graphic UI, and the two use-case applications it serves. October work, and nothing exists for it.
Also missing: signature checking inside reduction (reduce.py takes statements
as given), revocation, validity windows, thresholds, and a real range language
in place of globs.
9. Build order¶
| why | ||
|---|---|---|
| 1 | ~~reduce~~ | done — reduce.py, with the email example |
| 2 | the two use cases | they determine what the UI must show |
| 3 | graphic UI | October |
| 4 | signature checking into reduction | reduction currently trusts its inputs |
| 5 | packaging | genuinely last |
The use cases come before the UI, not after: a UI built before knowing what it presents ends up presenting the data model, which is exactly the failure the PICS-like layer exists to avoid.
10. Open questions¶
- Is
mofnthe command name? It matches the repo; it says nothing about what the tool does. - Does
checktake--domainas a file, or resolve by hash from a search path? The second is closer to how this should work and needs a lookup rule. - Output format. Human text is specified above; a
--jsonverdict for scripting is obvious but unspecified. - Does the app ship the prototype's reduced CBOR, or wait for DEC-002?
Shipping it makes the spike normative by accident — which is exactly what
prototype/exists to prevent. - Threshold subjects in
reducefor the floor, or v2?PLAN-0001§12 risk 7 already offers the cut.