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

continuity.state

What the lifecycle is holding

What it is

The open episode, the active task, the handover and checkpoint that resolve for this worktree and branch, each with its divergence label, the unresolved questions that refuse completion, and the record tallies. Selection is two-tiered and never repository-wide: a record from an unrelated worktree or branch is not offered, because a briefing that is quietly about somebody else is worse than none. Absence is reported as absence.

Descriptor

Canonical id
continuity.state
Module
continuity
Kind
query
Stability
behaviorallyverified
Provenance
declaredcached
Source
apps/majordomus-cli/src/capability/builtin/continuity.rs
Cache
process, 2 entries, 2s
Benchmark
required
Tags
continuitysessionhandover

Run

query
A query. It reads and changes nothing.

This capability takes no input.

GET /api/v1/continuity

Projections

InterfaceAsWhere
MCP toolmajordomus_continuity-
MCP resourcemajordomus://continuity-
HTTPGET /api/v1/continuitySwagger
Command linenot exposed-

Schemas

Input · Empty
{
  "type": "object",
  "additionalProperties": false,
  "description": "No input.",
  "title": "Empty"
}
Output · Continuity
{
  "type": "object",
  "properties": {
    "present": {
      "type": "boolean",
      "description": "Whether this checkout's lifecycle has ever run: a ledger line, a task, an episode or\na record. False in a fresh clone, which is not a fault.\n\nIt is not \"the directory exists\". Several things create that directory before\nanything has been recorded in it, so a reader that took its presence for evidence\nwould be told the lifecycle had run in a checkout where it never had."
    },
    "worktree": {
      "type": "string",
      "description": "The worktree this answer is about. Every selection below is scoped to it."
    },
    "branch": {
      "type": "string",
      "description": "The branch, or `DETACHED`."
    },
    "head": {
      "type": "string",
      "description": "The commit this checkout is on."
    },
    "working_tree": {
      "type": "string",
      "description": "`clean` or `dirty`."
    },
    "session": {
      "anyOf": [
        {
          "$ref": "#/$defs/OpenSession"
        },
        {
          "type": "null"
        }
      ],
      "description": "The open episode, or `None`."
    },
    "task": {
      "anyOf": [
        {
          "$ref": "#/$defs/ActiveTask"
        },
        {
          "type": "null"
        }
      ],
      "description": "The active task, or `None`."
    },
    "handover": {
      "anyOf": [
        {
          "$ref": "#/$defs/Record"
        },
        {
          "type": "null"
        }
      ],
      "description": "The record the next worker would resume from, or `None` when nothing resolves here."
    },
    "checkpoint": {
      "anyOf": [
        {
          "$ref": "#/$defs/Record"
        },
        {
          "type": "null"
        }
      ],
      "description": "The newest progress note for this worktree and branch, or `None`."
    },
    "blockers": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Unresolved questions on this branch. Every one refuses `finish --outcome completed`,\nwhichever task opened it."
    },
    "tallies": {
      "type": "object",
      "additionalProperties": {
        "type": "integer",
        "format": "uint",
        "minimum": 0
      },
      "description": "How many records of each kind this checkout holds, against the policy's caps."
    },
    "findings": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "What a reader should know before trusting any of the above: a diverged record, a\nforeign open session, a malformed file that was skipped. Empty is the good case."
    }
  },
  "required": [
    "present",
    "worktree",
    "branch",
    "tallies"
  ],
  "description": "What the lifecycle of this checkout is holding.",
  "title": "Continuity",
  "$defs": {
    "OpenSession": {
      "type": "object",
      "properties": {
        "session_id": {
          "type": "string",
          "description": "The episode's id."
        },
        "started_at": {
          "type": "string",
          "description": "When it opened."
        },
        "owner": {
          "type": "string",
          "description": "Who opened it."
        },
        "worker": {
          "type": "string",
          "description": "The worker identity, when one was supplied. Never inferred."
        },
        "provider": {
          "type": "string",
          "description": "The provider whose event opened it, when one did."
        },
        "provider_session": {
          "type": "string",
          "description": "That provider's own session identity — the string the prompt archive stamps on the\nsame worker's records, and the name this episode is keyed by. Empty for an episode\nopened by hand, which is the one episode no provider session owns."
        },
        "branch": {
          "type": "string",
          "description": "The branch it opened on."
        },
        "start_head": {
          "type": "string",
          "description": "The commit it opened at."
        },
        "foreign": {
          "type": "boolean",
          "description": "True when the open record here belongs to another checkout. Such a record is\nreported and never treated as this checkout's episode."
        }
      },
      "required": [
        "session_id",
        "started_at",
        "foreign"
      ],
      "description": "The open episode this checkout points at, when there is one.\n\nOne execution episode belongs to one provider session, and several can be open in one\ncheckout at once — two windows of the same provider are two workers. What is read here\nis `state/session-current.yaml`, the pointer to the episode of this checkout; a worker\nthat knows its own provider session resolves its own episode instead, which is what\n`mj_session_here_file` in `lib/common.sh` does and what stamps each ledger line."
    },
    "ActiveTask": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "The task id."
        },
        "task": {
          "type": "string",
          "description": "What is being worked on."
        },
        "profile": {
          "type": "string",
          "description": "The execution profile it runs under."
        },
        "outcome": {
          "type": "string",
          "description": "Its typed outcome so far: `active`, `handed_over`, or a finished one."
        },
        "scope": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "The paths it claims."
        },
        "requires": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "The obligations it owes before the outcome `completed` is available.\n\nBeside `scope` and not inside it, because the two are different promises: scope is\ncontainment — where a worker may write — and this is delivery. A change can sit\nentirely inside its scope and still be uncommitted on a laptop (ADR 0030).\n`super::obligations` is what judges each of these against its evidence; here it\nis reported as declared."
        },
        "started_at": {
          "type": "string",
          "description": "When it started."
        },
        "head": {
          "type": "string",
          "description": "The commit it started at."
        },
        "issue": {
          "type": "string",
          "description": "The issue the worker said this task executes (`start --issue`). A name, never state:\nwhat it serves is answered by `intents.binding` on every read (ADR 0111)."
        },
        "intent": {
          "type": "string",
          "description": "The intent the worker said this task serves (`start --intent`)."
        },
        "exemption": {
          "type": "string",
          "description": "The exemption class the worker gave instead (`start --exempt`)."
        },
        "exemption_because": {
          "type": "string",
          "description": "The reason given with the exemption."
        },
        "binding": {
          "type": "string",
          "description": "The standing `intents.binding` answered when the task started — what `start` was\ntold then, not where the work stands now."
        },
        "plan_revision": {
          "type": "string",
          "description": "The pin of what the work was for when the task started."
        },
        "evidence_standing": {
          "type": "string",
          "description": "The pin of where the served criteria's evidence stood when the task started."
        }
      },
      "required": [
        "id",
        "task",
        "profile",
        "outcome"
      ],
      "description": "The active task of this checkout, when there is one."
    },
    "Record": {
      "type": "object",
      "properties": {
        "path": {
          "type": "string",
          "description": "Repository-relative path. The body is at the path; it is not copied here."
        },
        "created_at": {
          "type": "string",
          "description": "When the record says it was written."
        },
        "task_id": {
          "type": "string",
          "description": "The task it belongs to, or `none`."
        },
        "branch": {
          "type": "string",
          "description": "The branch it was written on."
        },
        "head": {
          "type": "string",
          "description": "The commit it was written at."
        },
        "working_tree": {
          "type": "string",
          "description": "Whether the working tree was clean or dirty then."
        },
        "matched": {
          "$ref": "#/$defs/Match",
          "description": "Which tier of the resolution rule matched."
        },
        "divergence": {
          "$ref": "#/$defs/Divergence",
          "description": "How far its commit is from this one."
        },
        "freshness": {
          "$ref": "#/$defs/Freshness",
          "description": "How old it is, judged against `session.freshness`. Independent of `divergence`: a\nrecord is routinely `advanced` and `stale` at once, and that pair is what a reader\nmust not collapse into \"trustworthy\"."
        },
        "age_minutes": {
          "type": [
            "integer",
            "null"
          ],
          "format": "int64",
          "description": "Its age in whole minutes, when it has a timestamp that parses."
        },
        "freshness_reason": {
          "type": "string",
          "description": "Why it was judged that way, in one phrase. Never empty: a verdict a reader cannot\nact on is the failure this subsystem is being corrected for."
        },
        "next_action": {
          "type": "string",
          "description": "The section a resuming worker acts on, when the record has one and is still current.\nA handover's `Next Action`; empty for a record that carries no sections, and\ndeliberately empty for one that is `stale` or `invalid` — see `next_action_withheld`."
        },
        "next_action_withheld": {
          "type": "string",
          "description": "Why `next_action` is empty despite the record having one. Set only when it was\nwithheld, never when the record simply carries no such section, so that a reader can\ntell \"there is nothing to do\" from \"what there was to do is six days old\"."
        }
      },
      "required": [
        "path",
        "created_at",
        "task_id",
        "branch",
        "head",
        "working_tree",
        "matched",
        "divergence",
        "freshness",
        "freshness_reason"
      ],
      "description": "One durable record of the local half, as much of it as a reader needs to decide whether\nto open the file."
    },
    "Match": {
      "oneOf": [
        {
          "type": "string",
          "const": "same_worktree_same_branch",
          "description": "Same repository, same worktree, same branch."
        },
        {
          "type": "string",
          "const": "same_branch",
          "description": "Same repository, same branch, another worktree of it."
        }
      ],
      "description": "Which tier of the resolution rule matched. There is no third tier on purpose: a record\nfrom an unrelated worktree or branch is never offered."
    },
    "Divergence": {
      "oneOf": [
        {
          "type": "string",
          "const": "exact",
          "description": "Written at this commit. Trust it."
        },
        {
          "type": "string",
          "const": "advanced",
          "description": "Git has moved forward since. Trust it, and expect some of it to be done."
        },
        {
          "type": "string",
          "const": "diverged",
          "description": "The recorded commit is not an ancestor: history was rewritten. Trust git, not this."
        },
        {
          "type": "string",
          "const": "different_context",
          "description": "Another branch or another worktree. This record is not about your work."
        },
        {
          "type": "string",
          "const": "unknown",
          "description": "Git could not answer, so this process says so rather than guessing `exact`."
        }
      ],
      "description": "How far a record's recorded commit is from the commit this checkout is on.\n\nThe four words are the shell tool's, deliberately. A reader that met `advanced` from one\nsurface and `stale` from another would have to learn the same four facts twice."
    },
    "Freshness": {
      "oneOf": [
        {
          "type": "string",
          "const": "fresh",
          "description": "Inside `session.freshness.fresh_minutes`. Current; act on it."
        },
        {
          "type": "string",
          "const": "aging",
          "description": "Between the two thresholds. Still current, but its age is worth stating."
        },
        {
          "type": "string",
          "const": "stale",
          "description": "At or beyond `session.freshness.stale_minutes`. History, never current."
        },
        {
          "type": "string",
          "const": "unknown",
          "description": "Nothing to judge it by: no timestamp, or no thresholds declared."
        },
        {
          "type": "string",
          "const": "invalid",
          "description": "A timestamp that does not parse, or one in the future."
        }
      ],
      "description": "How old a record is, judged against `session.freshness` in the policy.\n\nThis is the second of two independent judgements every record carries, and it exists\nbecause the first one cannot answer this question. `Divergence` says where a record's\ncommit sits relative to HEAD; `advanced` means that commit is an ancestor of this one,\nwhich sounds like agreement and is identically true on the day the record is written and\na month later. Between 2026-09-05 and 2026-09-11 this repository served a handover that\nwas `advanced` and six days dead, and every surface that read this model — MCP, the HTTP\nAPI, the Cockpit — presented its `Next Action` as the thing to do (ADR 0052).\n\nThe thresholds are policy and are read, never restated here: a constant in this file\nwould be a second source of truth for a number the policy owns, and a repository whose\npolicy predates the key is reported as `Freshness::Unknown` naming the missing key\nrather than judged against a default nobody declared.\n\nThe five words divide into two groups, and the division is the one a caller acts on:\n`fresh` and `aging` are current and may be presented as the instruction, `stale` and\n`invalid` must be shown as history, and `unknown` is neither — a record nobody can date\nis not thereby an old record, and treating it as one would quietly discard a briefing\nthat is perfectly good. `Freshness::history` is that division, and it is the only\nplace it is decided.\n\n```\nuse majordomus_cli::capability::builtin::continuity::Freshness;\n\n// the two renderings are one value: the serialised word is the word `as_str` gives,\n// so a reader who met `stale` from MCP and from the command line met one fact\nlet stale = serde_json::to_value(Freshness::Stale).unwrap();\nassert_eq!(stale, serde_json::json!(\"stale\"));\nassert_eq!(stale.as_str(), Some(Freshness::Stale.as_str()));\n\n// and the division a caller acts on: absence of a judgement is not a bad judgement\nassert!(Freshness::Stale.history() && Freshness::Invalid.history());\nassert!(!Freshness::Unknown.history(), \"undated is not old\");\nassert!(!Freshness::Fresh.history() && !Freshness::Aging.history());\n```"
    }
  }
}

Examples

These are the capability's own benchmark cases: the same inputs the benchmark runs and the OpenAPI document shows.

default
{}