Skip to content

development-runtime — The runtime has a development surface

A development transition is decided in exactly one place — a `capability!` of kind `command` in the Rust registry — and every surface that offers it is a projection: the CLI, the MCP tool, the HTTP route, the OpenAPI operation and the Cockpit's generated runner form, none of them written by hand. The lifecycle stops being a second program with no surfaces, and the execution history a development surface would show exists somewhere durable.

ACTIVE 55 of 85 issues done

ready
19
blocked
10
active
0
verify
1
done
55
cancelled
0

Problem

The Cockpit is a faithful projection of a registry that has almost nothing development-shaped in it. Re-measured on today's master, the registry declares exactly three capabilities of kind `command` — executions.start, executions.cancel, peers.announce — and the OpenAPI document the server serves has exactly those three non-GET operations to match. Every command of the development lifecycle lives in a second program, bin/majordomus, and every one of its nodes in the command graph is withheld from every machine surface. So no development surface can be built by adding pages: there is nothing behind the pages to call, and `majordomus_plan_done` answers `unknown tool` because there is no capability for a plan transition. docs/COCKPIT_IDE_AUDIT.md is the evidence; ADR 0040 is the decision it argues for. Until this milestone existed, none of it was in the plan at all: a keyword search of the issues and milestones for palette, diff view, CI status and syntax highlighting returned nothing, so the work could not be scheduled, blocked or reported.

Outcome

A development transition is decided in exactly one place — a `capability!` of kind `command` in the Rust registry — and every surface that offers it is a projection: the CLI, the MCP tool, the HTTP route, the OpenAPI operation and the Cockpit's generated runner form, none of them written by hand. The lifecycle stops being a second program with no surfaces, and the execution history a development surface would show exists somewhere durable.

Current state

Three command capabilities, all of them about executions or peers. The lifecycle transitions exist only in lib/plan.sh and lib/start.sh. `majordomus run` executes in its own process and never reaches the running server, so the execution plane the Cockpit shows and the one a person uses are disjoint. A server whose executable has been replaced still reports itself `ready`. Two capabilities — devtask.issue and devtask.milestone — landed after the audit's base and give the runtime its first canonical read of an issue and a milestone as work; neither of them writes anything.

Desired state

Phase A of the audit's plan has landed end to end — one transition, one capability, four surfaces, no hand-written projection — and the phases that depend on it are schedulable against it. The three load-bearing defects named in the audit's F-table are fixed or explicitly deferred with a record, rather than carried silently under every later measurement.

Scope

  • apps/majordomus-cli/src/capability/builtin
  • apps/majordomus-cli/src/cockpit
  • lib
  • share
  • docs
  • test/cases

Out of scope

  • A terminal, a PTY or shell execution on any surface. The audit records this as a non-goal and share/cockpit/palette.js already states the boundary in terms.
  • Editing repository source in the browser. The Cockpit refuses every non-GET route by decision, and this milestone does not reopen that decision.
  • Retries and a scheduler. apps/majordomus-cli/src/execution/mod.rs states in its own module documentation that it has none, by decision.
  • A second datastore or a second project model. The records stay canonical and the runtime reads them.
  • The `/cockpit/worktrees` response time. It is F3 in the audit's table and is being fixed on fix/cockpit-answers-quickly; this milestone references that work rather than duplicating it.
  • A wholesale port of lib/*.sh. Phase A is one transition; the rest is scheduled behind it or not at all.

Acceptance criteria

  • The registry declares at least one capability of kind command that changes a development record, and the generated OpenAPI carries its non-GET operation without anyone editing the document
  • The same transition is reachable from the CLI, from MCP and over HTTP, and the Cockpit's existing generic runner drives it with no Cockpit source edited
  • An execution a person starts is visible to the server that serves the repository, or the record says which decision was taken instead and why
  • A surface that reports a runtime as ready cannot be serving an executable that no longer exists on disk
  • No claim in docs/COCKPIT_IDE_AUDIT.md is left standing that a command in this repository contradicts

Validation

  • majordomus plan validate
  • bin/majordomus-cli capabilities validate
  • bin/majordomus-cli generate --check
  • bash test/run.sh

Evidence required

  • suite
  • one_mutating_development_capability
  • projection_not_handwritten

Risks

  • Phase A is the whole architecture in miniature. If the pattern does not land cleanly on one transition, no later phase would have worked either, and the correct response is to stop rather than to widen.
  • A second name for an existing concept can land in parallel. One already has: the devtask module documents itself as a join over plan and trace rather than a second model, and holds an equality assertion against plan.issues. It is additive and should stay, but its readiness vocabulary refines the canonical statuses, and Phase A should converge the naming rather than grow a third.
  • Master moves during the work. It moved eleven times during the audit that produced this milestone, and again between that audit and this record.

Issues

Each one is an execution contract with its own acceptance criteria, validation command and required evidence. The wave column is the layer of the dependency graph it sits in.

issuestatuswavedepends ontitle
I1501 DONE 0 — An execution a person starts is an execution the server can see
I1502 DONE 0 — A server serving code that no longer exists stops calling itself ready
I1503 DONE 0 — A closed session is not closed a second time under the same identity
I1504 READY 0 — One development transition is a capability, end to end
I1505 BLOCKED 1 I1504 A mutating capability leaves a durable event, and the ledger can be read back
I1506 BLOCKED 2 I1504, I1505 The lifecycle commands become non-interactive capabilities
I1507 BLOCKED 3 I1505, I1506 Issues, milestones, sessions and peers reach the Cockpit as projections
I1508 DONE 0 — The navigation is derived from the dispatcher, not kept beside it
I1509 DONE 0 — A detail page that pages nothing has outgrown the reason it pages nothing
I1510 DONE 0 — A gap the audit calls planned names a plan object that exists
I1511 DONE 0 — The documentation surface answers in a checkout that has not built the site
I1512 READY 0 — Gate state is something the runtime can answer
I1520 DONE 0 — A step that runs out of time says so itself
I1967 DONE 0 — A reporter that sets a flag is a reporter
I1992 DONE 0 — A rebuild that fails consumes no change: the next request retries it
I1995 DONE 0 — Work a session left uncommitted in a worktree is named, not found by luck
I1997 READY 0 — The peer board can be read from the command line
I2054 DONE 0 — A tag does not turn every other pull request red until its record lands
I2059 READY 0 — A rebuild never replaces the executable a live lease names
I2114 READY 0 — A task's scope admits what its derive writes
I2301 DONE 0 — Whether the work is done is answered by measurement: the done invariant asks about debt, what was left behind and the backlog
I2398 DONE 0 — A derive offloaded to another machine waits its turn in a declared queue
I2399 DONE 0 — Every session briefs itself on an interval, without being asked
I2460 DONE 0 — The overview asks its sources at once, so it costs its slowest source and not their sum
I2461 DONE 0 — majordomus ui is served at /ui as its own product, with screens composed from capabilities
I2462 DONE 1 I2461 The UI has every screen, and its mesh is a graph whose nodes open an inspector
I2463 DONE 0 — A train of stacked pull requests is a typed object, served everywhere and drawn as a graph
I2470 DONE 2 I2462 The pull requests drain in the UI: a queue a reader narrows, inspects and follows to what each depends on
I2471 DONE 3 I2470 The roadmap opens a milestone: what it holds, what can start, its critical path, and what it waits for
I2472 DONE 4 I2471 How long CI takes is measured, from when each run started to when it completed, and the CI/CD screen draws it
I2473 DONE 3 I2470 A pull request shows its trail: what the executor did to it, and the drain what the lane did lately
I2474 DONE 4 I2473 The drain draws its merge throughput: each day's merges over the fortnight its trail ends on
I2475 DONE 4 I2470, I2471 The issues are browsed: every issue of the plan by status, milestone, priority or text, each a link onward
I2476 DONE 4 I2471 An intent opens what serves it: its statement, its criteria and their evidence, and the milestones and issues that serve it
I2477 DONE 2 I2462 A claim opens its proof: what settles it, its last run, what changed since, how to see it again
I2478 DONE 2 I2462 A rule opens its proof: what it states, the tests that prove it, what is missing, and the rules around it
I2481 DONE 3 I2478 The UI links every entity it names, and says none where a source has no value
I2482 DONE 4 I2481 Every screen of the UI has a case, and no link on the UI is dead
I2483 DONE 2 I2462 The UI is published as a snapshot: read once at the published commit and carried by the site at /ui
I2484 READY 1 I2461 majordomus ui ensures the shared server and opens the UI's dashboard
I2485 READY 3 I2489 The bench measures the first request after the repository moved, and a budget bounds it
I2486 DONE 1 I2461 No screen waits for a source: a page shows the latest reading with its age, read again behind the reader
I2487 READY 2 I2486 A screen is streamed, and one stream tells an open page which readings changed
I2488 READY 2 I2486 The HTTP stack is chosen by measurement: the same routes and several hundred open streams on tiny_http and on axum
I2489 DONE 2 I2486 A screen over its budget fails the build: the UI's latency budgets are benchmark policy, and bench --check holds them
I2495 DONE 3 I2483 The Cockpit is published as a snapshot at /cockpit, and the UI's evidence links lead to it
I2652 DONE 2 I2486 The UI shows what the knowledge base holds: the candidates awaiting review and whether the deriver still writes, read and never acted on
I2670 READY 0 — A build-cache offer is a typed model and its selection is a pure, explained function
I2671 BLOCKED 1 I2670 A provider offers its cache as a signed, expiring mesh record, and a stopped provider goes stale
I2672 BLOCKED 1 I2670 The offers and the selection are one read, projected to CLI, MCP, HTTP and OpenAPI
I2673 BLOCKED 2 I2670, I2672 The sccache client configuration is derived from the selected offer, local disk first
I2674 BLOCKED 1 I2670 A node is provisioned as an S3 cache provider, idempotently, with no secret in the repository
I2675 BLOCKED 2 I2672 Build-cache health, headroom and hit statistics are visible where the mesh is
I2676 BLOCKED 3 I2673, I2674 The build cache is verified and validated: failure paths, security and a real second-node hit
I2677 BLOCKED 2 I2672 The build cache is documented, governed by a rule and described on the site and the Pages
I2678 DONE 0 — The public Observatory replays events that were recorded, and says it is a replay
I2679 DONE 0 — The Observatory follows a stream with a cursor instead of asking for its page again
I2680 DONE 0 — The Observatory's gates are closed with evidence: screenshots, measured frame rates, a soak, the recovery drills
I2694 READY 0 — A promoted note resolves in every checkout, not only where it was promoted
I2695 DONE 0 — The Observatory draws the proof, claim, surface, wave and release scenes from the capabilities that already answer them
I2696 DONE 0 — p5 is a built, optional asset of the UI and the page says where it is
I2697 DONE 0 — The public snapshot carries the p5 library, or says which scenes it cannot draw
I2698 READY 0 — The new scenes have screenshot evidence at 1080p and 4K on a named revision
I2712 DONE 1 I2054 release-check treats a tag whose release run is still going as pending, not as a missing record
I2713 DONE 0 — A build never lets idle incremental sessions fill the disk
I2714 READY 0 — One build directory never serves two worktrees' jobs at once
I2715 DONE 0 — New public Rust code meets rust-quality before the structure job does
I2718 DONE 0 — A linked worktree runs its own hooks, never the primary checkout's
I2760 DONE 0 — A scope entry is one path, and a path context would refuse is refused at start
I2787 DONE 1 I2713 A build never lets the shared build directory's crate artifacts fill the disk
I2813 DONE 0 — A published page that answers 503, or does not answer, is asked again before it is called missing
I2882 DONE 0 — A remote derive builds only inside its own run directory
I2962 DONE 0 — What the served surfaces change is said as the registry says it
I2963 DONE 0 — The README's exit codes are the commands' contract
I2964 DONE 0 — Every step that reads a surface into the published snapshot can ask the forge
I2965 DONE 0 — The site says a test proves a guarantee only as far as recorded evidence supports it
I2966 DONE 0 — A forge setting that could not be read is unknown, never \"allows nothing\"
I2967 DONE 0 — The site's own pages name the layout in force
I3098 VERIFY 0 — Waiting derives take the machine's derive lock in the order they arrived
I3171 READY 0 — The compiled context names source ranges with their reason and confidence, not only whole objects of the layer
I3172 READY 0 — The compiled context names the small set of capabilities the work needs
I3312 READY 0 — An ADR may name the paths it governs, and the compiled context for those paths includes it
I3316 READY 0 — The rescue command a stranded worktree is offered is proved by a drill that restores its work byte-identical
I3317 READY 0 — An execution records the commit it started at, and a writing execution the paths it changed
I3836 READY 0 — An offload derive observes the bundle's base commit, not its throwaway snapshot, so what it derives passes CI's check

The graph

development-runtime dependency graphfrom .ai/repo/project
flowchart LR
    I1501["I1501<br/>An execution a person starts is an execution the server can see"]:::done
    I1502["I1502<br/>A server serving code that no longer exists stops calling itself ready"]:::done
    I1503["I1503<br/>A closed session is not closed a second time under the same identity"]:::done
    I1504["I1504<br/>One development transition is a capability, end to end"]:::ready
    I1505["I1505<br/>A mutating capability leaves a durable event, and the ledger can be read back"]:::blocked
    I1506["I1506<br/>The lifecycle commands become non-interactive capabilities"]:::blocked
    I1507["I1507<br/>Issues, milestones, sessions and peers reach the Cockpit as projections"]:::blocked
    I1508["I1508<br/>The navigation is derived from the dispatcher, not kept beside it"]:::done
    I1509["I1509<br/>A detail page that pages nothing has outgrown the reason it pages nothing"]:::done
    I1510["I1510<br/>A gap the audit calls planned names a plan object that exists"]:::done
    I1511["I1511<br/>The documentation surface answers in a checkout that has not built the site"]:::done
    I1512["I1512<br/>Gate state is something the runtime can answer"]:::ready
    I1520["I1520<br/>A step that runs out of time says so itself"]:::done
    I1967["I1967<br/>A reporter that sets a flag is a reporter"]:::done
    I1992["I1992<br/>A rebuild that fails consumes no change: the next request retries it"]:::done
    I1995["I1995<br/>Work a session left uncommitted in a worktree is named, not found by luck"]:::done
    I1997["I1997<br/>The peer board can be read from the command line"]:::ready
    I2054["I2054<br/>A tag does not turn every other pull request red until its record lands"]:::done
    I2059["I2059<br/>A rebuild never replaces the executable a live lease names"]:::ready
    I2114["I2114<br/>A task's scope admits what its derive writes"]:::ready
    I2301["I2301<br/>Whether the work is done is answered by measurement: the done invariant asks about debt, what was left behind and the backlog"]:::done
    I2398["I2398<br/>A derive offloaded to another machine waits its turn in a declared queue"]:::done
    I2399["I2399<br/>Every session briefs itself on an interval, without being asked"]:::done
    I2460["I2460<br/>The overview asks its sources at once, so it costs its slowest source and not their sum"]:::done
    I2461["I2461<br/>majordomus ui is served at /ui as its own product, with screens composed from capabilities"]:::done
    I2462["I2462<br/>The UI has every screen, and its mesh is a graph whose nodes open an inspector"]:::done
    I2463["I2463<br/>A train of stacked pull requests is a typed object, served everywhere and drawn as a graph"]:::done
    I2470["I2470<br/>The pull requests drain in the UI: a queue a reader narrows, inspects and follows to what each depends on"]:::done
    I2471["I2471<br/>The roadmap opens a milestone: what it holds, what can start, its critical path, and what it waits for"]:::done
    I2472["I2472<br/>How long CI takes is measured, from when each run started to when it completed, and the CI/CD screen draws it"]:::done
    I2473["I2473<br/>A pull request shows its trail: what the executor did to it, and the drain what the lane did lately"]:::done
    I2474["I2474<br/>The drain draws its merge throughput: each day's merges over the fortnight its trail ends on"]:::done
    I2475["I2475<br/>The issues are browsed: every issue of the plan by status, milestone, priority or text, each a link onward"]:::done
    I2476["I2476<br/>An intent opens what serves it: its statement, its criteria and their evidence, and the milestones and issues that serve it"]:::done
    I2477["I2477<br/>A claim opens its proof: what settles it, its last run, what changed since, how to see it again"]:::done
    I2478["I2478<br/>A rule opens its proof: what it states, the tests that prove it, what is missing, and the rules around it"]:::done
    I2481["I2481<br/>The UI links every entity it names, and says none where a source has no value"]:::done
    I2482["I2482<br/>Every screen of the UI has a case, and no link on the UI is dead"]:::done
    I2483["I2483<br/>The UI is published as a snapshot: read once at the published commit and carried by the site at /ui"]:::done
    I2484["I2484<br/>majordomus ui ensures the shared server and opens the UI's dashboard"]:::ready
    I2485["I2485<br/>The bench measures the first request after the repository moved, and a budget bounds it"]:::ready
    I2486["I2486<br/>No screen waits for a source: a page shows the latest reading with its age, read again behind the reader"]:::done
    I2487["I2487<br/>A screen is streamed, and one stream tells an open page which readings changed"]:::ready
    I2488["I2488<br/>The HTTP stack is chosen by measurement: the same routes and several hundred open streams on tiny_http and on axum"]:::ready
    I2489["I2489<br/>A screen over its budget fails the build: the UI's latency budgets are benchmark policy, and bench --check holds them"]:::done
    I2495["I2495<br/>The Cockpit is published as a snapshot at /cockpit, and the UI's evidence links lead to it"]:::done
    I2652["I2652<br/>The UI shows what the knowledge base holds: the candidates awaiting review and whether the deriver still writes, read and never acted on"]:::done
    I2670["I2670<br/>A build-cache offer is a typed model and its selection is a pure, explained function"]:::ready
    I2671["I2671<br/>A provider offers its cache as a signed, expiring mesh record, and a stopped provider goes stale"]:::blocked
    I2672["I2672<br/>The offers and the selection are one read, projected to CLI, MCP, HTTP and OpenAPI"]:::blocked
    I2673["I2673<br/>The sccache client configuration is derived from the selected offer, local disk first"]:::blocked
    I2674["I2674<br/>A node is provisioned as an S3 cache provider, idempotently, with no secret in the repository"]:::blocked
    I2675["I2675<br/>Build-cache health, headroom and hit statistics are visible where the mesh is"]:::blocked
    I2676["I2676<br/>The build cache is verified and validated: failure paths, security and a real second-node hit"]:::blocked
    I2677["I2677<br/>The build cache is documented, governed by a rule and described on the site and the Pages"]:::blocked
    I2678["I2678<br/>The public Observatory replays events that were recorded, and says it is a replay"]:::done
    I2679["I2679<br/>The Observatory follows a stream with a cursor instead of asking for its page again"]:::done
    I2680["I2680<br/>The Observatory's gates are closed with evidence: screenshots, measured frame rates, a soak, the recovery drills"]:::done
    I2694["I2694<br/>A promoted note resolves in every checkout, not only where it was promoted"]:::ready
    I2695["I2695<br/>The Observatory draws the proof, claim, surface, wave and release scenes from the capabilities that already answer them"]:::done
    I2696["I2696<br/>p5 is a built, optional asset of the UI and the page says where it is"]:::done
    I2697["I2697<br/>The public snapshot carries the p5 library, or says which scenes it cannot draw"]:::done
    I2698["I2698<br/>The new scenes have screenshot evidence at 1080p and 4K on a named revision"]:::ready
    I2712["I2712<br/>release-check treats a tag whose release run is still going as pending, not as a missing record"]:::done
    I2713["I2713<br/>A build never lets idle incremental sessions fill the disk"]:::done
    I2714["I2714<br/>One build directory never serves two worktrees' jobs at once"]:::ready
    I2715["I2715<br/>New public Rust code meets rust-quality before the structure job does"]:::done
    I2718["I2718<br/>A linked worktree runs its own hooks, never the primary checkout's"]:::done
    I2760["I2760<br/>A scope entry is one path, and a path context would refuse is refused at start"]:::done
    I2787["I2787<br/>A build never lets the shared build directory's crate artifacts fill the disk"]:::done
    I2813["I2813<br/>A published page that answers 503, or does not answer, is asked again before it is called missing"]:::done
    I2882["I2882<br/>A remote derive builds only inside its own run directory"]:::done
    I2962["I2962<br/>What the served surfaces change is said as the registry says it"]:::done
    I2963["I2963<br/>The README's exit codes are the commands' contract"]:::done
    I2964["I2964<br/>Every step that reads a surface into the published snapshot can ask the forge"]:::done
    I2965["I2965<br/>The site says a test proves a guarantee only as far as recorded evidence supports it"]:::done
    I2966["I2966<br/>A forge setting that could not be read is unknown, never \&quot;allows nothing\&quot;"]:::done
    I2967["I2967<br/>The site's own pages name the layout in force"]:::done
    I3098["I3098<br/>Waiting derives take the machine's derive lock in the order they arrived"]:::verify
    I3171["I3171<br/>The compiled context names source ranges with their reason and confidence, not only whole objects of the layer"]:::ready
    I3172["I3172<br/>The compiled context names the small set of capabilities the work needs"]:::ready
    I3312["I3312<br/>An ADR may name the paths it governs, and the compiled context for those paths includes it"]:::ready
    I3316["I3316<br/>The rescue command a stranded worktree is offered is proved by a drill that restores its work byte-identical"]:::ready
    I3317["I3317<br/>An execution records the commit it started at, and a writing execution the paths it changed"]:::ready
    I3836["I3836<br/>An offload derive observes the bundle's base commit, not its throwaway snapshot, so what it derives passes CI's check"]:::ready
    I1504 --> I1505
    I1504 --> I1506
    I1505 --> I1506
    I1505 --> I1507
    I1506 --> I1507
    I2054 --> I2712
    I2461 --> I2462
    I2461 --> I2484
    I2461 --> I2486
    I2462 --> I2470
    I2462 --> I2477
    I2462 --> I2478
    I2462 --> I2483
    I2470 --> I2471
    I2470 --> I2473
    I2470 --> I2475
    I2471 --> I2472
    I2471 --> I2475
    I2471 --> I2476
    I2473 --> I2474
    I2478 --> I2481
    I2481 --> I2482
    I2483 --> I2495
    I2486 --> I2487
    I2486 --> I2488
    I2486 --> I2489
    I2486 --> I2652
    I2489 --> I2485
    I2670 --> I2671
    I2670 --> I2672
    I2670 --> I2673
    I2670 --> I2674
    I2672 --> I2673
    I2672 --> I2675
    I2672 --> I2677
    I2673 --> I2676
    I2674 --> I2676
    I2713 --> I2787
    classDef done stroke:#16a34a,fill:#dcfce7,color:#14532d,stroke-width:2px
    classDef active stroke:#2563eb,fill:#eff6ff,color:#1e3a8a,stroke-width:2px
    classDef verify stroke:#7c3aed,fill:#f5f3ff,color:#4c1d95,stroke-width:2px
    classDef ready stroke:#0891b2,fill:#ecfeff,color:#164e63,stroke-width:2px
    classDef planned stroke:#0891b2,fill:#ecfeff,color:#164e63,stroke-width:2px
    classDef blocked stroke:#b45309,fill:#fffbeb,color:#78350f,stroke-width:2px
    classDef cancelled stroke:#6b7280,fill:#f9fafb,color:#374151,stroke-width:2px
    classDef superseded stroke:#6b7280,fill:#f9fafb,color:#374151,stroke-width:2px

Canonical record: .ai/repo/project/milestones/development-runtime.yaml. Read it back with majordomus plan show development-runtime.

Searches the titles and descriptions of every page this site publishes.