intents.list
Every intent the project model declares, each with the status the plan derives for its milestones, the state of the evidence behind each satisfaction criterion, the stage those two derive — declared, planned, executing, verifying or satisfied, or cancelled or superseded when the record says so — and the verdict the criteria alone derive (ADR 0107): satisfied when every criterion is met, unsatisfied when a test or claim criterion is not, unknown when only command or deployment criteria are unmet or none is declared, with the criteria holding it back.
Every intent the project model declares, each with the status the plan derives for its milestones, the state of the evidence behind each satisfaction criterion, the stage those two derive — declared, planned, executing, verifying or satisfied, or cancelled or superseded when the record says so — and the verdict the criteria alone derive (ADR 0107): satisfied when every criterion is met, unsatisfied when a test or claim criterion is not, unknown when only command or deployment criteria are unmet or none is declared, with the criteria holding it back.
- query
- behaviorally_verified
- module intents
- #intent
- #project
Exposure
Where this one definition is reachable. Absence is explicit: a surface not listed does not carry it.
| surface | as |
|---|---|
| MCP | tool majordomus_intents resource majordomus://intents |
| HTTP | GET /api/v1/intents operationId intents.list |
| command line | majordomus intent list |
Schemas
The canonical input and output, from the Rust types; the MCP tool schema and the OpenAPI parameters and responses are derived from these.
input · Empty
No properties: the capability takes no input.
JSON Schema
{
"additionalProperties": false,
"description": "No input.",
"title": "Empty",
"type": "object"
}output · IntentList
majordomus intent list, GET /api/v1/intents and the majordomus_intents tool all answer
with, out of one derivation.
use majordomus_cli::capability::builtin::intents::IntentList;
let empty = IntentList {
count: 0,
stages: std::collections::BTreeMap::new(),
verdicts: std::collections::BTreeMap::new(),
intents: vec![],
};
// a repository that declares no intent answers the route, with nothing in it
assert_eq!(empty.count, 0);| property | type | required | description |
|---|---|---|---|
| count | integer | yes | How many intents. |
| intents | array | yes | Every intent, in identity order. |
| stages | object | yes | How many in each stage, keyed by the stage word. |
| verdicts | object | yes | How many with each verdict, keyed by the verdict word. |
JSON Schema
{
"$defs": {
"IntentCriterion": {
"description": "One criterion with the evidence behind it: what the record declared, what the ledger says\nabout it, whether that meets it, and the command that would produce the evidence again.\n\n```\nuse majordomus_cli::evidence::ProofState;\nuse majordomus_cli::intent::{IntentCriterion, IntentEvidenceState};\nlet c = IntentCriterion {\n id: \"stage-is-derived\".into(),\n criterion: \"the stage follows the plan\".into(),\n evidence: \"test\".into(),\n reference: \"apps/majordomus-cli/tests/intent.rs\".into(),\n state: IntentEvidenceState::NotRun,\n met: false,\n proof: Some(ProofState::NotRun),\n reproduce: None,\n};\n// nothing recorded is not a pass\nassert!(!c.met);\n```",
"properties": {
"criterion": {
"description": "What is observably true when it is met.",
"type": "string"
},
"evidence": {
"description": "`test`, `claim`, `command` or `deployment`.",
"type": "string"
},
"id": {
"description": "Unique within the intent.",
"type": "string"
},
"met": {
"description": "Derived: the state is `current`.",
"type": "boolean"
},
"proof": {
"anyOf": [
{
"$ref": "#/$defs/ProofState"
},
{
"type": "null"
}
],
"description": "Derived: the evidence module's own verdict behind `state`, for a `test` or `claim`\ncriterion whose reference resolves. A met criterion rests on `proven` (a pass at this\nrevision) or `inputs_unchanged` (a pass whose named inputs have not moved since, which\nis not proof at this revision), and every surface shows which, so `met` is never the\none tick for both."
},
"ref": {
"description": "What the evidence names, as authored.",
"type": "string"
},
"reproduce": {
"description": "The command that produces the evidence again, when one is known.",
"type": [
"string",
"null"
]
},
"state": {
"$ref": "#/$defs/IntentEvidenceState",
"description": "Derived: what the evidence says."
}
},
"required": [
"id",
"criterion",
"evidence",
"ref",
"state",
"met"
],
"type": "object"
},
"IntentEvidenceState": {
"description": "What the evidence behind one criterion says, as a word. Only `Current` meets a criterion:\na stale, failing, unrecorded or underivable reference never does, and neither does one that\nresolves to nothing.\n\nWhether a recorded run is current is not decided here. A `test` or `claim` criterion is\njudged by the evidence module's one truth table (`evidence::freshness()`) at the working\ntree and read through `evidence::current`, the same judgement the claim report and the\nsubject pages make; `IntentEvidenceState::judged` is the whole of the translation. So\nthe state follows the evidence both ways: a criterion met today reads stale or failing\nthe moment the ledger or the tree says so, and met again once a current pass is recorded.\n\n```\nuse majordomus_cli::intent::IntentEvidenceState;\nassert_eq!(serde_json::to_string(&IntentEvidenceState::NotRun).unwrap(), \"\\\"not_run\\\"\");\nassert_ne!(IntentEvidenceState::Stale, IntentEvidenceState::Current);\n```",
"oneOf": [
{
"const": "current",
"description": "A passing run that is current evidence at the working tree: its commit is in this\nhistory, it measured a tree that was its commit, the test still hashes to what ran,\nand nothing the criterion names has changed since — for a test, its source and the\nsource and implementation of every claim that test proves; for a claim, what the\nclaim names. A change the criterion does not name, the evidence ledger's own included,\nleaves it current. A test that proves no claim naming an implementation names no code\nunder test, so for it nothing but the ledger may have changed since the run. The only\nstate that meets a criterion; the criterion's `proof` says whether it rests on\n`proven` or on `inputs_unchanged`.",
"type": "string"
},
{
"const": "stale",
"description": "A pass that is not current evidence: something the criterion names has changed since\nit, it names no code under test and anything but the ledger and the plan's own records\nhas changed since, the\ntest no longer hashes to what ran, the run's commit is not in this history (or git\ncould not compare it), or the run measured a tree that was not its commit — a run on a\ndirty tree, which no later tree can be matched against.",
"type": "string"
},
{
"const": "failing",
"description": "The latest recorded run failed, timed out or errored.",
"type": "string"
},
{
"const": "not_run",
"description": "The reference resolves and no run counts for it: none was recorded, the latest run\ndeclined to run (a skip), or the claim names no test a runner drives.",
"type": "string"
},
{
"const": "not_derivable",
"description": "The reference resolves, and this kind of evidence (`command`, `deployment`) is not\nderivable from the ledger, so it never meets a criterion by itself.",
"type": "string"
},
{
"const": "unresolved",
"description": "The reference is empty or names nothing this repository holds.",
"type": "string"
}
]
},
"IntentMilestone": {
"description": "One milestone an intent names, as the plan derives it. A milestone that does not resolve is\ncarried with `resolved: false` rather than dropped, because a name that points at nothing is\na finding and not an absence.\n\n```\nuse majordomus_cli::intent::IntentMilestone;\nlet named = IntentMilestone { id: \"no-such\".into(), resolved: false, status: None };\nassert!(!named.resolved);\nassert!(named.status.is_none());\n```",
"properties": {
"id": {
"description": "The id the intent names.",
"type": "string"
},
"resolved": {
"description": "Whether the plan holds a milestone with that id.",
"type": "boolean"
},
"status": {
"description": "The status the plan derives for it; absent when it does not resolve.",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"resolved"
],
"type": "object"
},
"IntentStage": {
"description": "Where an intent stands, derived on every read and stored nowhere.\n\n```\nuse majordomus_cli::intent::IntentStage;\n// one word every surface prints, and an order that follows the work\nassert_eq!(IntentStage::Executing.as_str(), \"executing\");\nassert!(IntentStage::Declared < IntentStage::Satisfied);\n```",
"oneOf": [
{
"const": "declared",
"description": "A named milestone does not resolve, or none is named.",
"type": "string"
},
{
"const": "planned",
"description": "Every milestone resolves and none has started.",
"type": "string"
},
{
"const": "executing",
"description": "A milestone is under way.",
"type": "string"
},
{
"const": "verifying",
"description": "Every milestone that counts is DONE; satisfaction is not yet evidenced.",
"type": "string"
},
{
"const": "satisfied",
"description": "Verifying, and every criterion has current evidence.",
"type": "string"
},
{
"const": "cancelled",
"description": "The record says it was abandoned.",
"type": "string"
},
{
"const": "superseded",
"description": "The record names the intent that replaced it.",
"type": "string"
}
]
},
"IntentVerdict": {
"description": "Whether the evidence alone settles an intent, and which criteria hold it back: every\nunmet criterion, in the order the record declares them. Empty when the verdict is\n`satisfied`, and when it is `unknown` because the intent declares no criterion.\n\n```\nuse majordomus_cli::intent::{verdict, IntentVerdict, IntentVerdictState};\n// an intent that declares no criterion cannot be settled by evidence\nlet v: IntentVerdict = verdict(&[]);\nassert_eq!(v.state, IntentVerdictState::Unknown);\nassert!(v.reasons.is_empty());\n```",
"properties": {
"reasons": {
"description": "Every criterion that is not met, with the state of its evidence.",
"items": {
"$ref": "#/$defs/IntentVerdictReason"
},
"type": "array"
},
"state": {
"$ref": "#/$defs/IntentVerdictState",
"description": "Derived: what the evidence says."
}
},
"required": [
"state",
"reasons"
],
"type": "object"
},
"IntentVerdictReason": {
"description": "One criterion that holds a verdict back from `satisfied`: which one, the kind of evidence\nit names, and the state that evidence is in — the criterion's own words, not new ones.\n\n```\nuse majordomus_cli::intent::{IntentEvidenceState, IntentVerdictReason};\nlet r = IntentVerdictReason {\n criterion: \"probe-passes\".into(),\n evidence: \"test\".into(),\n state: IntentEvidenceState::NotRun,\n};\nassert_eq!(r.state, IntentEvidenceState::NotRun);\n```",
"properties": {
"criterion": {
"description": "The criterion's id.",
"type": "string"
},
"evidence": {
"description": "Its kind of evidence: `test`, `claim`, `command` or `deployment`.",
"type": "string"
},
"state": {
"$ref": "#/$defs/IntentEvidenceState",
"description": "The state of that evidence, as the criterion reports it."
}
},
"required": [
"criterion",
"evidence",
"state"
],
"type": "object"
},
"IntentVerdictState": {
"description": "What the evidence alone says about an intent, as a word: derived from its criteria and\nnever from the plan, so it can read `satisfied` while a milestone is still open (ADR 0107).\n\n```\nuse majordomus_cli::intent::IntentVerdictState;\nlet word = serde_json::to_string(&IntentVerdictState::Unsatisfied).unwrap();\nassert_eq!(word, \"\\\"unsatisfied\\\"\");\nassert_eq!(IntentVerdictState::Satisfied.as_str(), \"satisfied\");\n```",
"oneOf": [
{
"const": "satisfied",
"description": "Every criterion has current evidence.",
"type": "string"
},
{
"const": "unsatisfied",
"description": "A criterion the ledger or the claim join can settle (`test`, `claim`) is not met.",
"type": "string"
},
{
"const": "unknown",
"description": "Every unmet criterion is of a kind the ledger cannot yet settle (`command`,\n`deployment`), or the intent declares no criterion: the evidence cannot answer.",
"type": "string"
}
]
},
"IntentView": {
"description": "One intent, as its record declares it and as the plan and the ledger derive it: the\nstatement and invariants as authored, each milestone with its derived status, each criterion\nwith the state of its evidence, the stage that follows from both, and the verdict that\nfollows from the evidence alone.\n\n```\nuse majordomus_cli::intent::{verdict, IntentStage, IntentVerdictState, IntentView};\nlet view = IntentView {\n id: \"intent-lifecycle\".into(),\n title: \"Work is traceable to the intent it serves\".into(),\n statement: \"A reader can ask what work is for.\".into(),\n invariants: vec![\"no intent status is stored\".into()],\n stage: IntentStage::Declared,\n milestones: vec![],\n satisfaction: vec![],\n met: 0,\n verdict: verdict(&[]),\n governance: vec![\"adr:adr-0070\".into()],\n non_goals: vec![],\n superseded_by: None,\n source: \".ai/repo/project/intents/intent-lifecycle.yaml\".into(),\n};\n// a record naming no milestone that resolves has not been planned\nassert_eq!(view.stage, IntentStage::Declared);\n// and one declaring no criterion cannot be settled by evidence\nassert_eq!(view.verdict.state, IntentVerdictState::Unknown);\n```",
"properties": {
"governance": {
"description": "The governance a worker on this intent loads.",
"items": {
"type": "string"
},
"type": "array"
},
"id": {
"description": "The identity, which is also the file name.",
"type": "string"
},
"invariants": {
"description": "What must stay true.",
"items": {
"type": "string"
},
"type": "array"
},
"met": {
"description": "Derived: how many criteria are met.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"milestones": {
"description": "The milestones, each with its derived status.",
"items": {
"$ref": "#/$defs/IntentMilestone"
},
"type": "array"
},
"non_goals": {
"description": "What is deliberately not required.",
"items": {
"type": "string"
},
"type": "array"
},
"satisfaction": {
"description": "The criteria, each with its evidence state.",
"items": {
"$ref": "#/$defs/IntentCriterion"
},
"type": "array"
},
"source": {
"description": "Repository-relative path of the record.",
"type": "string"
},
"stage": {
"$ref": "#/$defs/IntentStage",
"description": "Derived: the stage."
},
"statement": {
"description": "What must become true.",
"type": "string"
},
"superseded_by": {
"description": "The replacement, when the record names one.",
"type": [
"string",
"null"
]
},
"title": {
"description": "One line.",
"type": "string"
},
"verdict": {
"$ref": "#/$defs/IntentVerdict",
"description": "Derived from the criteria alone, never from the plan: whether the evidence settles the\nintent, and which criteria hold it back."
}
},
"required": [
"id",
"title",
"statement",
"invariants",
"stage",
"milestones",
"satisfaction",
"met",
"verdict",
"governance",
"non_goals",
"source"
],
"type": "object"
},
"ProofState": {
"description": "What the repository can say about one claim's proof, right now.\n\nOrdered from strongest to weakest, so a summary that sorts by this reads as a ranking.\n\n```\nuse majordomus_cli::evidence::ProofState;\n\nlet mut states = vec![ProofState::NotRun, ProofState::Stale, ProofState::Proven];\nstates.sort();\nassert_eq!(\n states,\n vec![ProofState::Proven, ProofState::Stale, ProofState::NotRun]\n);\n\n// the two strongest are deliberately not one state: `inputs unchanged` is the absence\n// of a known invalidation, and collapsing it into `proven` is the unaccountable badge\nassert_ne!(ProofState::Proven, ProofState::InputsUnchanged);\nassert!(ProofState::Proven < ProofState::InputsUnchanged);\nassert!(ProofState::InputsUnchanged.passing());\n```\n# Example\n\n```\nuse majordomus_cli::evidence::ProofState;\nassert!(ProofState::Proven.passing());\nassert!(!ProofState::NotRun.passing());\nassert!(!ProofState::InputsUnchanged.meaning().is_empty());\n```",
"oneOf": [
{
"const": "proven",
"description": "A passing run, and nothing has changed since it — the diff against the execution's\nown commit is empty but for the ledger. Proof of the tree in front of you.",
"type": "string"
},
{
"const": "inputs_unchanged",
"description": "A passing run, and nothing this claim names has changed since. Not proof at HEAD:\nsomething the claim does not name may have broken it.",
"type": "string"
},
{
"const": "stale",
"description": "A passing run, but something this claim names has changed since. The proof is older\nthan its subject.",
"type": "string"
},
{
"const": "failing",
"description": "The latest run of this claim's test did not pass.",
"type": "string"
},
{
"const": "not_run",
"description": "The claim names a test a runner owns, and no run of it has ever been recorded.",
"type": "string"
},
{
"const": "unrunnable",
"description": "The claim names a path no runner in this repository drives. Nothing can record it,\nso nothing can prove it this way.",
"type": "string"
},
{
"const": "no_test",
"description": "The claim names no test at all. Correct for a `planned` or `rejected` claim, and a\ndefect for any other.",
"type": "string"
}
]
}
},
"description": "Every intent, with its derived stage and verdict, and how many there are in each: what\n`majordomus intent list`, `GET /api/v1/intents` and the `majordomus_intents` tool all answer\nwith, out of one derivation.\n\n```\nuse majordomus_cli::capability::builtin::intents::IntentList;\nlet empty = IntentList {\n count: 0,\n stages: std::collections::BTreeMap::new(),\n verdicts: std::collections::BTreeMap::new(),\n intents: vec![],\n};\n// a repository that declares no intent answers the route, with nothing in it\nassert_eq!(empty.count, 0);\n```",
"properties": {
"count": {
"description": "How many intents.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"intents": {
"description": "Every intent, in identity order.",
"items": {
"$ref": "#/$defs/IntentView"
},
"type": "array"
},
"stages": {
"additionalProperties": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"description": "How many in each stage, keyed by the stage word.",
"type": "object"
},
"verdicts": {
"additionalProperties": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"description": "How many with each verdict, keyed by the verdict word.",
"type": "object"
}
},
"required": [
"count",
"stages",
"verdicts",
"intents"
],
"title": "IntentList",
"type": "object"
}Policies
- benchmark
- required — a target on every transport the exposure declares; the cases are the input type's
- cache
- checkout — up to 2 entries in the process, scoped by the registry fingerprint, the context's reading of the repository and the checkout's state (HEAD, the index, the refs, every changed path)
Benchmark targets
Derived from the registry for this repository: one requirement per transport, and the cases the input type provides. The whole matrix is on the benchmarks page.