A snapshot: read at commit 707a04c7ce8 on 2026-10-18T00:06:01Z by majordomus 0.29.0. Nothing on this page is read again. See it live
lifecycle.closed
The records a clone receives
What it is
The tracked, durable projection of closed episodes: how many there are, how many closed on this branch, and the newest twenty. This is the only half of the subsystem that survives a clone; everything under .ai/local/ names this machine and travels nowhere.
Descriptor
- Canonical id
lifecycle.closed- Module
lifecycle- Kind
- query
- Stability
- behaviorallyverified
- Provenance
- declaredcached
- Source
apps/majordomus-cli/src/capability/builtin/lifecycle.rs- Cache
process, 2 entries, 30s- Benchmark
required- Tags
- continuitysessionrecord
Run
queryA query. It reads and changes nothing.
Projections
| Interface | As | Where |
|---|---|---|
| MCP tool | majordomus_lifecycle_closed | - |
| MCP resource | not exposed | - |
| HTTP | GET /api/v1/lifecycle/closed | Swagger |
| Command line | not exposed | - |
Schemas
Input · Empty
{
"type": "object",
"additionalProperties": false,
"description": "No input.",
"title": "Empty"
}Output · ClosedSessions
{
"type": "object",
"properties": {
"total": {
"type": "integer",
"format": "uint",
"minimum": 0,
"description": "How many closed records the index holds. Exact."
},
"on_this_branch": {
"type": "integer",
"format": "uint",
"minimum": 0,
"description": "How many of them closed on the branch this checkout is on."
},
"newest": {
"type": "array",
"items": {
"$ref": "#/$defs/ClosedSession"
},
"description": "The newest `CLOSED_WINDOW`, newest first."
},
"window": {
"type": "integer",
"format": "uint",
"minimum": 0,
"description": "How many are carried in `newest`, against the total."
}
},
"required": [
"total",
"on_this_branch",
"window"
],
"description": "The tracked half of the subsystem: the records a clone receives.\n\n`total` is exact and `newest` is a window, and keeping them as two numbers is the whole\ndesign of this type. The tracked directory grows without bound and a Cockpit card is not\na listing page, so the rows are capped — but a capped list that did not carry the true\ntotal would quietly understate the repository, which is the shape of defect this\nrepository has been bitten by often enough to name. `window` says how many rows came\nback, so a reader can see the cap rather than infer it.\n\n```\nuse majordomus_cli::capability::builtin::lifecycle::ClosedSessions;\nuse serde_json::json;\n\nlet row = |id: &str| json!({\n \"session_id\": id,\n \"uri\": format!(\"majordomus://session/{id}\"),\n \"path\": format!(\".ai/repo/project/sessions/{id}.md\"),\n \"branch\": \"master\",\n});\nlet c: ClosedSessions = serde_json::from_value(json!({\n \"total\": 137,\n \"on_this_branch\": 41,\n \"newest\": [row(\"s-0137\"), row(\"s-0136\")],\n \"window\": 2,\n})).unwrap();\n\n// the window is what came back; the total is what exists\nassert_eq!(c.window, c.newest.len());\nassert!(c.total > c.window, \"the rows are capped and the total is not\");\nassert!(c.on_this_branch <= c.total);\n```",
"title": "ClosedSessions",
"$defs": {
"ClosedSession": {
"type": "object",
"properties": {
"session_id": {
"type": "string",
"description": "The episode id."
},
"uri": {
"type": "string",
"description": "`majordomus://session/<identity>`, for the object page."
},
"path": {
"type": "string",
"description": "Repository-relative path."
},
"created_at": {
"type": "string",
"description": "When it closed, as recorded."
},
"branch": {
"type": "string",
"description": "The branch it closed on."
},
"head": {
"type": "string",
"description": "The commit it closed at."
},
"outcome": {
"type": "string",
"description": "The typed outcome the close recorded."
},
"title": {
"type": "string",
"description": "Its title, when the record carries one."
}
},
"required": [
"session_id",
"uri",
"path"
],
"description": "One closed episode of the tracked, durable projection — the half of this subsystem that\nsurvives a clone.\n\nIt carries both a `path` and a `uri` because they answer different questions: the path\nis where the record is in this checkout, and the `majordomus://session/<identity>`\nidentifier is what every other surface addresses the same record by, so a reader can\nfollow it to the object page without constructing one.\n\nEverything but the identity, the identifier and the path is optional, because a record\nwritten by an older close carries fewer fields and is still a record.\n\n```\nuse majordomus_cli::capability::builtin::lifecycle::ClosedSession;\nuse serde_json::json;\n\nlet s: ClosedSession = serde_json::from_value(json!({\n \"session_id\": \"s-0042\",\n \"uri\": \"majordomus://session/2026-09-12-s-0042\",\n \"path\": \".ai/repo/project/sessions/2026-09-12-s-0042.md\",\n \"created_at\": \"2026-09-12T15:44:00Z\",\n \"branch\": \"master\",\n \"head\": \"cd04012f1\",\n \"outcome\": \"landed\",\n})).unwrap();\n\nassert!(s.uri.starts_with(\"majordomus://session/\"), \"addressable as an object\");\nassert_eq!(s.outcome, \"landed\");\n\n// an older record with less in it is still one, and says so by absence\nlet sparse: ClosedSession = serde_json::from_value(json!({\n \"session_id\": \"s-0001\",\n \"uri\": \"majordomus://session/2026-08-01-s-0001\",\n \"path\": \".ai/repo/project/sessions/2026-08-01-s-0001.md\",\n})).unwrap();\nassert!(sparse.outcome.is_empty() && sparse.title.is_empty());\n```"
}
}
}Examples
These are the capability's own benchmark cases: the same inputs the benchmark runs and the OpenAPI document shows.
default
{}