I3376 — One capability states each task's wall time and episodes from every checkout's ledger, and names every field it cannot yet fill as not observed
Add economics.tasks over a new module apps/majordomus-cli/src/economics/tasks.rs. It folds the ledgers of every checkout git worktree list reports, following ledger.rotated archives, into one record per task: task id, issue and intent, checkout and branch, first start, last finish or refusal, elapsed wall seconds, refusal count, the episodes that carried it with their spans, and the finish outcome as recorded. It fixes the full record shape now: interventions, ci_reruns, spend and accepted, each not_observed with a reason naming what will supply it. It takes an optional --since/--until window and lists each ledger read with its line and skipped-line counts and each checkout not read. It reuses intent_realization::tasks_from_ledger.
READY wave 0 · p0 · implementation profile · parallel safe
Ready. Every dependency is done, so majordomus plan start I3376 will be accepted.
Objective
Add economics.tasks over a new module apps/majordomus-cli/src/economics/tasks.rs. It folds the ledgers of every checkout git worktree list reports, following ledger.rotated archives, into one record per task: task id, issue and intent, checkout and branch, first start, last finish or refusal, elapsed wall seconds, refusal count, the episodes that carried it with their spans, and the finish outcome as recorded. It fixes the full record shape now: interventions, ci_reruns, spend and accepted, each not_observed with a reason naming what will supply it. It takes an optional --since/--until window and lists each ledger read with its line and skipped-line counts and each checkout not read. It reuses intent_realization::tasks_from_ledger.
Why
T3 of the owner's report of 2026-10-19 asks for each task's time, interventions, CI reruns, spend and accepted result, and T2 and T4 need one instrument. The ledger already records task steps and episodes; intent_realization folds them but only from the root checkout. Fixing the whole shape here lets later issues fill fields without changing the response type. I3130 plans the same fold and should reuse this one.
Current state
lib/start.sh:158-160 appends task.started; share/events.yaml:48-62 declares task.finished and task.refused; ledger.rs:10-12 says the ledger is per checkout and untracked; share/events.yaml:92-98 declares ledger.rotated; intent_realization.rs:1185 tasks_from_ledger, and gather at :1282-1284 reads only the root checkout's ledger; docs/generated/openapi.json already defines Delivery* components.
Desired state
majordomus economics tasks (CLI, HTTP, MCP) answers every task in the ledgers it read; wall time and episodes are measured; other fields read not_observed with their supplier.
Scope
- apps/majordomus-cli/src/economics
- apps/majordomus-cli/src/economics/mod.rs
- apps/majordomus-cli/src/capability/builtin/economics.rs
- apps/majordomus-cli/src/commands/economics.rs
- apps/majordomus-cli/src/cli.rs
- apps/majordomus-cli/src/intent_realization.rs
- apps/majordomus-cli/tests/economics.rs
- docs/ECONOMICS.md
- .ai/repo/mcp-tool-run-baseline.txt
Out of scope
- Filling interventions, CI reruns, spend or acceptance (I3377 to I3381)
- Benchmark runs (I3382)
- A stored join or second ledger
- Publishing any aggregate
Dependencies
None. This issue is a root of the graph.
What waits on this
- I3355BLOCKED majordomus economics proof serves the scorecard on the command line, HTTP and MCP from one capability declaration
- I3377BLOCKED A task's prompt records, restarts and manual changes are counted by type from the records that already hold them, each with the ids behind it
- I3378BLOCKED A permission request the provider reports leaves a receipt with its own elapsed time, and economics.tasks counts it as an approval
- I3379BLOCKED Each issue's CI reruns and rounds are counted from the Actions run record, attributed through plan.delivery
- I3380BLOCKED A task's spend is the usage attributed to it, as reported tokens with their class, and money stays not observed until it is a separate field
- I3381BLOCKED A task counts as accepted only by the written definition of an accepted outcome, with the issue's furthest delivery stage shown beside it
- I3382BLOCKED Every recorded benchmark run answers the same delivery-economics shape as a task
- I3390BLOCKED One conservation reading counts completions per issue, unreachable task commits, stranded claims and multiply-consumed handovers, each violation with its records
Acceptance criteria
- A fixture of two checkouts' ledgers, one rotated, yields one record per distinct task_id and the count equals that number
- A task started, refused twice and finished reports wall seconds between its started and finished ts and a refusal count of 2
- A task with no finish reads open, never finished
- A task whose lines carry two session stamps lists two episodes
- interventions, ci_reruns, spend and accepted are present as not_observed with a reason on every record
- A window filters by task.started ts, and a missing ledger is listed as not read
- Response types use a TaskEconomics prefix and no OpenAPI component collides
- CLI JSON, HTTP and MCP return the same reading
Validation
- cargo test --manifest-path apps/majordomus-cli/Cargo.toml --test economics
- majordomus generate --check
- majordomus plan validate
Evidence required
- test_task_economics_per_task
- test_task_economics_reads_every_checkout
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/I3376.yaml. Read it back with majordomus plan show I3376.