I3192 — An operation started from /ui/mesh is authorised, executed, audited and its result streamed back
First propose the ADR amending ADR 0126 that decides which credential admits a remote write and how a mesh event names its human author; then take the one mesh action I3139 offers on /ui/mesh through executions.start, authorise it by the caller's identity and the capability's declared effect, record its audit as the signed mesh journal event the write produces (author, operation, policy, result, evidence), stream the result to the page, and refuse it from an unauthenticated remote caller.
BLOCKED wave 6 · p2 · implementation profile · parallel safe
Blocked. This issue cannot start until I1205, I3139, I3196, milestone:the-mesh-is-operated-from-one-page are done. The status is derived from that, not declared.
Objective
First propose the ADR amending ADR 0126 that decides which credential admits a remote write and how a mesh event names its human author; then take the one mesh action I3139 offers on /ui/mesh through executions.start, authorise it by the caller's identity and the capability's declared effect, record its audit as the signed mesh journal event the write produces (author, operation, policy, result, evidence), stream the result to the page, and refuse it from an unauthenticated remote caller.
Why
The 10-18 Lumen critique: do not defer identity, authorisation, typed commands, freshness and reconnect; one authorised action end to end is v0.1. The 10-08 pack asked for a self-update with rollback from the UI; that is the same path with a riskier effect. Critique 10-18: ExecutionStore is in-memory and bounded, and the shared server stops when idle, so an execution cannot be the audit. ADR 0126 leaves open who may write remotely and how a mesh event names its human author, and this issue's first step is the ADR that decides both. I3139 (prismatic-lumen) is the same action, so this issue builds on it rather than beside it. Proposed in ADR 0201 (The persistent runtime is the authority; every operator surface, Lumen included, is a client of it) (proposed; it carries no authority until the owner accepts it). Sources: chatgpt-majordomus:c296#12, chatgpt-majordomus:c200#5.
Current state
Verified: capabilities declare effects; executions are recorded with events (ADR 0033); ADR 0126 refuses remote writes; no UI action reaches a mesh write.
Desired state
One authorised action on /ui/mesh; its audit is the signed journal event and executions.get is only its live view; a running execution holds off the shared server's idle stop.
Scope
- apps/majordomus-cli/src/ui/mesh.rs
- apps/majordomus-cli/src/capability/builtin/executions.rs
- apps/majordomus-cli/src/execution
- apps/majordomus-cli/src/mesh/journal.rs
- apps/majordomus-cli/src/commands/serve.rs
- apps/majordomus-cli/src/execution/store.rs
- .ai/repo/adrs/0126-a-caller-beyond-loopback-reads-and-changes-nothing-it-cannot-authenticate.md
- .ai/repo/adrs/0201-the-persistent-runtime-is-the-authority-every-operator-surface-l.md
- .ai/repo/adrs/0033-an-execution-is-a-watched-capability-call-not-a-second-registry.md
Out of scope
- Natural-language operations
- Self-update from the UI before I2722
- The action button, its journal-rendered result and the disabled snapshot rendering already delivered by I3139
- An audit kept only in the in-memory ExecutionStore
Dependencies
- I1205BLOCKED Identity is resolved once, in the router, and every surface reads it from there
- I3139BLOCKED The mesh page offers one authorised action through an existing capability, and shows its result from the journal
- I3196BLOCKED A deployment's external URL, trusted hosts and forwarded headers are one typed fact read by every surface
Acceptance criteria
- The action is refused without authentication from beyond loopback
- Text from logs or peer output never triggers it
- A proposed ADR amending ADR 0126 decides which credential admits a remote write (web-sign-in session per I1205, an identity asserted only by a declared ingress per I3196, or a device key) and how a mesh event names its human author apart from the node that relays it; it is accepted before any code of this issue
- The action is the one I3139 offers. This issue adds authorisation by the caller's identity and the refusal, not a second action path
- The audit record is the signed mesh journal event the write produces, naming author, operation, policy, result and evidence; executions.get is only its live view
- A test shows the audit record is still readable after the shared server restarts
- A test shows that closing the page while the action runs does not stop the execution, and a running execution holds off the shared server's idle stop
- The published Pages snapshot renders the action disabled with a 'live only' state and the live link
Validation
- majordomus plan validate
- cargo test --test remote_callers
- bash test/run.sh 1086_a_remote_caller_cannot_write
Evidence required
- case_an_operation_from_the_ui_is_audited
Evidence
None recorded. Every token above needs a command or an artifact behind it before this issue can be completed; narrative is refused.
Timeline
- started
- —
- verified
- —
- completed
- —
Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.
Canonical record: .ai/repo/project/issues/I3192.yaml. Read it back with majordomus plan show I3192.