Skip to content
Cockpit0.29.0
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

query
A query. It reads and changes nothing.

This capability takes no input.

GET /api/v1/lifecycle/closed

Projections

InterfaceAsWhere
MCP toolmajordomus_lifecycle_closed-
MCP resourcenot exposed-
HTTPGET /api/v1/lifecycle/closedSwagger
Command linenot 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
{}