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

intents.preflight

Which intent a piece of work serves, or why it may not proceed

What it is

Given the issue a piece of work executes, or the paths it will touch, one verdict: `serves` when no issue is refused and at least one serves a criterion of a live intent through a link that holds, the plan of each such intent critiqued with no blocking finding open (issues judged maintenance beside it do not change the verdict); `maintenance` when the issues sit under milestones no live intent names and serve nothing, as `intent validate` allows; `refused` otherwise, each refusal with its issue, a cause — unknown_issue, no_issue_covers_paths, issue_serves_nothing, serves_another_intent, serves_unknown_criterion, intent_not_critiqued, open_blocking_finding — in path mode every issue judged and the worst verdict answered. The answer carries, for the intents reached and no others, the statement, the served criteria with the live state of their evidence, the invariants, non-goals and governance, the critique with its open blocking findings, and the recorded gap bounded to those criteria.

Descriptor

Canonical id
intents.preflight
Module
intents
Kind
query
Stability
behaviorallyverified
Provenance
declared
Source
apps/majordomus-cli/src/capability/builtin/intents.rs
Cache
disabled
Benchmark
required
Tags
intentprojectgovernance

Run

query
A query. It reads and changes nothing.

The issue the work executes, by id. When given, the paths are not consulted.

Repository-relative paths the work will touch, separated by commas.

GET /api/v1/intents/preflight

Projections

InterfaceAsWhere
MCP toolmajordomus_intent_preflight-
MCP resourcenot exposed-
HTTPGET /api/v1/intents/preflightSwagger
Command linemajordomus intent preflight-

Schemas

Input · IntentPreflightInput
{
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "issue": {
      "type": [
        "string",
        "null"
      ],
      "description": "The issue the work executes, by id. When given, the paths are not consulted."
    },
    "paths": {
      "type": "string",
      "description": "Repository-relative paths the work will touch, separated by commas.",
      "default": ""
    }
  },
  "description": "The work to preflight: an issue, or the paths it will touch.\n\n`paths` is one comma-separated string rather than a list because a preflight changes\nnothing and is therefore a `GET`, and this repository binds a `GET` input to the query\nstring.\n\n```\nuse majordomus_cli::capability::builtin::intents::IntentPreflightInput;\n// an issue, when the work executes one\nlet by_issue = IntentPreflightInput { issue: Some(\"I1900\".into()), paths: String::new() };\nassert!(by_issue.path_list().is_empty());\n// or the paths it will touch, when it names no issue yet\nlet by_paths = IntentPreflightInput {\n    issue: None,\n    paths: \"apps/majordomus-cli/src,docs\".into(),\n};\nassert_eq!(by_paths.path_list(), [\"apps/majordomus-cli/src\", \"docs\"]);\n```",
  "title": "IntentPreflightInput"
}
Output · IntentPreflight
{
  "type": "object",
  "properties": {
    "verdict": {
      "$ref": "#/$defs/IntentPreflightVerdict",
      "description": "`serves`, `maintenance` or `refused`: refused when any issue is, else serves when any\nissue serves an intent, else maintenance."
    },
    "issues": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/IntentPreflightIssue"
      },
      "description": "The issues the work was resolved to — the one named, or the open issues whose scope\ncovers a path — each with its own verdict."
    },
    "matches": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/IntentPreflightMatch"
      },
      "description": "Every intent an issue serves, with the link."
    },
    "intents": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/IntentPreflightIntent"
      },
      "description": "The intents the work serves, and no other, each with what it asks of the worker."
    },
    "governance": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "The governance of those intents, each entry once, in first-seen order."
    },
    "refusals": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/IntentPreflightRefusal"
      },
      "description": "Every reason the preflight refused, in issue order; empty unless the verdict is\n`refused`."
    },
    "refusal": {
      "type": [
        "string",
        "null"
      ],
      "description": "When refused: every refusal's sentence, joined, for a reader who wants one line."
    }
  },
  "required": [
    "verdict",
    "issues",
    "matches",
    "intents",
    "governance",
    "refusals"
  ],
  "description": "Which intent a piece of work serves, whether it is maintenance, or why it may not proceed:\nthe issues it resolved to with a verdict each, every intent reached with its link, what\nthose intents require of the worker, and every refusal with its cause.\n\n```\nuse majordomus_cli::intent::{\n    IntentPreflight, IntentPreflightCause, IntentPreflightRefusal, IntentPreflightVerdict,\n};\nlet refused = IntentPreflight {\n    verdict: IntentPreflightVerdict::Refused,\n    issues: vec![],\n    matches: vec![],\n    intents: vec![],\n    governance: vec![],\n    refusals: vec![IntentPreflightRefusal::new(\n        None,\n        IntentPreflightCause::NoIssueCoversPaths,\n        \"no open issue's scope covers README.md\".into(),\n    )],\n    refusal: Some(\"no open issue's scope covers README.md\".into()),\n};\nassert_eq!(refused.verdict, IntentPreflightVerdict::Refused);\nassert_eq!(refused.refusals[0].cause, IntentPreflightCause::NoIssueCoversPaths);\n```",
  "title": "IntentPreflight",
  "$defs": {
    "IntentPreflightVerdict": {
      "oneOf": [
        {
          "type": "string",
          "const": "serves",
          "description": "The work serves at least one criterion of a live intent, every link holds, and the\nplan of every intent it serves was critiqued with no blocking finding left open."
        },
        {
          "type": "string",
          "const": "maintenance",
          "description": "The work sits under milestones no live intent names and serves no criterion of a live\nintent: operational work, allowed where `majordomus intent validate` allows it."
        },
        {
          "type": "string",
          "const": "refused",
          "description": "A link is missing or points at nothing, or an intent it serves may not be executed yet."
        }
      ],
      "description": "What a preflight concluded, about one issue or about the whole piece of work.\n\n```\nuse majordomus_cli::intent::IntentPreflightVerdict;\n// the words every surface answers with\nassert_eq!(\n    serde_json::to_string(&IntentPreflightVerdict::Maintenance).unwrap(),\n    \"\\\"maintenance\\\"\"\n);\nassert_ne!(IntentPreflightVerdict::Serves, IntentPreflightVerdict::Refused);\n```"
    },
    "IntentPreflightIssue": {
      "type": "object",
      "properties": {
        "issue": {
          "type": "string",
          "description": "The issue id."
        },
        "milestone": {
          "type": "string",
          "description": "Its milestone."
        },
        "verdict": {
          "$ref": "#/$defs/IntentPreflightVerdict",
          "description": "What the preflight concluded about this issue."
        },
        "serves": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "The `<intent>#<criterion>` references it declares, as declared."
        },
        "intents": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "The live intents whose milestones include its milestone, sorted."
        }
      },
      "required": [
        "issue",
        "milestone",
        "verdict",
        "serves",
        "intents"
      ],
      "description": "One issue the work resolved to, and what the preflight concluded about it.\n\n```\nuse majordomus_cli::intent::{IntentPreflightIssue, IntentPreflightVerdict};\nlet i = IntentPreflightIssue {\n    issue: \"I0007\".into(),\n    milestone: \"ops\".into(),\n    verdict: IntentPreflightVerdict::Maintenance,\n    serves: vec![],\n    intents: vec![],\n};\n// a milestone no intent names carries maintenance, which is not a refusal\nassert_eq!(i.verdict, IntentPreflightVerdict::Maintenance);\n```"
    },
    "IntentPreflightMatch": {
      "type": "object",
      "properties": {
        "intent": {
          "type": "string",
          "description": "The intent."
        },
        "title": {
          "type": "string",
          "description": "Its title."
        },
        "stage": {
          "$ref": "#/$defs/IntentStage",
          "description": "Its derived stage."
        },
        "milestone": {
          "type": "string",
          "description": "The milestone that links the work to it."
        },
        "issue": {
          "type": "string",
          "description": "The issue that links the work to that milestone."
        },
        "criteria": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "The criteria of the intent the issue declares it serves, in the intent's order."
        }
      },
      "required": [
        "intent",
        "title",
        "stage",
        "milestone",
        "issue",
        "criteria"
      ],
      "description": "One intent a piece of work serves, and the link that says so: issue to the criteria it\ndeclares in `serves`, each criterion's intent naming the issue's milestone.\n\n```\nuse majordomus_cli::intent::{IntentPreflightMatch, IntentStage};\nlet m = IntentPreflightMatch {\n    intent: \"intent-lifecycle\".into(),\n    title: \"Work is traceable to the intent it serves\".into(),\n    stage: IntentStage::Executing,\n    milestone: \"intent-lifecycle\".into(),\n    issue: \"I1900\".into(),\n    criteria: vec![\"stage-is-derived\".into()],\n};\nassert_eq!(m.issue, \"I1900\");\n```"
    },
    "IntentStage": {
      "oneOf": [
        {
          "type": "string",
          "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."
        }
      ],
      "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```"
    },
    "IntentPreflightIntent": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "The identity."
        },
        "title": {
          "type": "string",
          "description": "One line."
        },
        "stage": {
          "$ref": "#/$defs/IntentStage",
          "description": "Its derived stage."
        },
        "statement": {
          "type": "string",
          "description": "What must become true."
        },
        "criteria": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/IntentCriterion"
          },
          "description": "The criteria the work serves, each with the state of its evidence now, in the intent's\norder."
        },
        "invariants": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "What must stay true."
        },
        "non_goals": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "What is deliberately not required."
        },
        "governance": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "The governance a worker on this intent loads."
        },
        "critique": {
          "anyOf": [
            {
              "$ref": "#/$defs/IntentPreflightCritique"
            },
            {
              "type": "null"
            }
          ],
          "description": "The critique of its plan; absent when none was ever recorded."
        },
        "gap": {
          "anyOf": [
            {
              "$ref": "#/$defs/IntentPreflightGap"
            },
            {
              "type": "null"
            }
          ],
          "description": "Its recorded gap, bounded to the criteria above; absent when none was recorded."
        }
      },
      "required": [
        "id",
        "title",
        "stage",
        "statement",
        "criteria",
        "invariants",
        "non_goals",
        "governance"
      ],
      "description": "One intent the work is held to, with what a worker needs before touching it: the statement,\nthe criteria the work serves with the live state of their evidence, the invariants and\nnon-goals, the governance, the critique and the gap. Only the intents the work reaches are\ncarried, never every intent.\n\n```\nuse majordomus_cli::intent::{IntentPreflightIntent, IntentStage};\nlet i = IntentPreflightIntent {\n    id: \"x\".into(),\n    title: \"X\".into(),\n    stage: IntentStage::Planned,\n    statement: \"It becomes true.\".into(),\n    criteria: vec![],\n    invariants: vec![],\n    non_goals: vec![],\n    governance: vec![],\n    critique: None,\n    gap: None,\n};\n// no critique recorded is carried as an absence, never as an empty review\nassert!(i.critique.is_none());\n```"
    },
    "IntentCriterion": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique within the intent."
        },
        "criterion": {
          "type": "string",
          "description": "What is observably true when it is met."
        },
        "evidence": {
          "type": "string",
          "description": "`test`, `claim`, `command` or `deployment`."
        },
        "ref": {
          "type": "string",
          "description": "What the evidence names, as authored."
        },
        "state": {
          "$ref": "#/$defs/IntentEvidenceState",
          "description": "Derived: what the evidence says."
        },
        "met": {
          "type": "boolean",
          "description": "Derived: the state is `current`."
        },
        "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."
        },
        "reproduce": {
          "type": [
            "string",
            "null"
          ],
          "description": "The command that produces the evidence again, when one is known."
        }
      },
      "required": [
        "id",
        "criterion",
        "evidence",
        "ref",
        "state",
        "met"
      ],
      "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```"
    },
    "IntentEvidenceState": {
      "oneOf": [
        {
          "type": "string",
          "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."
        }
      ],
      "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```"
    },
    "ProofState": {
      "oneOf": [
        {
          "type": "string",
          "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."
        }
      ],
      "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```"
    },
    "IntentPreflightCritique": {
      "type": "object",
      "properties": {
        "source": {
          "type": "string",
          "description": "Repository-relative path of the record."
        },
        "reviewed_at": {
          "type": "string",
          "description": "The commit the plan was reviewed at."
        },
        "reviewed_by": {
          "type": "string",
          "description": "Who or what reviewed it."
        },
        "open_blocking": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/CritiqueFinding"
          },
          "description": "Every blocking finding whose resolution is `open`; work may not start while one is."
        }
      },
      "required": [
        "source",
        "reviewed_at",
        "reviewed_by",
        "open_blocking"
      ],
      "description": "The critique of an intent as a preflight reads it: where it is, when and by whom the plan\nwas reviewed, and the blocking findings still open.\n\n```\nuse majordomus_cli::intent::IntentPreflightCritique;\nlet c = IntentPreflightCritique {\n    source: \".ai/repo/project/critiques/x.yaml\".into(),\n    reviewed_at: \"c3f20da\".into(),\n    reviewed_by: \"another session\".into(),\n    open_blocking: vec![],\n};\nassert!(c.open_blocking.is_empty());\n```"
    },
    "CritiqueFinding": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique within the critique."
        },
        "class": {
          "anyOf": [
            {
              "$ref": "#/$defs/CritiqueClass"
            },
            {
              "type": "null"
            }
          ],
          "description": "The class, or `None` for a class this module does not know."
        },
        "class_text": {
          "type": "string",
          "description": "As written."
        },
        "subject": {
          "type": "string",
          "description": "`<intent>#<criterion>`, an issue id or a milestone id."
        },
        "finding": {
          "type": "string",
          "description": "The finding."
        },
        "blocking": {
          "type": "boolean",
          "description": "Whether execution may not start while it is open."
        },
        "resolution": {
          "anyOf": [
            {
              "$ref": "#/$defs/ResolutionState"
            },
            {
              "type": "null"
            }
          ],
          "description": "The resolution, or `None` for a state this module does not know."
        },
        "resolution_text": {
          "type": "string",
          "description": "As written."
        },
        "issue": {
          "type": "string",
          "description": "The issue that carries it, when planned."
        },
        "because": {
          "type": "string",
          "description": "Why, when rejected."
        }
      },
      "required": [
        "id",
        "class_text",
        "subject",
        "finding",
        "blocking",
        "resolution_text",
        "issue",
        "because"
      ],
      "description": "One critique finding: what the review found, what it is about, whether it blocks execution,\nand how it was resolved. `class` and `resolution` are `None` when the record spells one this\nmodule does not know, and the `_text` fields keep what was written.\n\n```\nuse majordomus_cli::intent_review::{CritiqueFinding, CritiqueRecord, ResolutionState};\nlet c = CritiqueRecord::from_metadata(\"c.yaml\", &serde_json::json!({\n    \"intent\": \"x\",\n    \"findings\": [{\"id\": \"f1\", \"class\": \"regression_risk\", \"subject\": \"x#a\",\n                  \"blocking\": true, \"resolution\": {\"state\": \"planned\", \"issue\": \"I1\"}}],\n}));\nlet finding: &CritiqueFinding = &c.findings[0];\nassert!(finding.blocking);\nassert_eq!(finding.resolution, Some(ResolutionState::Planned));\nassert_eq!(finding.issue, \"I1\");\n```"
    },
    "CritiqueClass": {
      "oneOf": [
        {
          "type": "string",
          "const": "missed_requirement",
          "description": "Does the plan miss something the intent requires?"
        },
        {
          "type": "string",
          "const": "unproven_assumption",
          "description": "Which assumption is unproven?"
        },
        {
          "type": "string",
          "const": "insufficient_work",
          "description": "Which criterion lacks sufficient work?"
        },
        {
          "type": "string",
          "const": "unnecessary_work",
          "description": "Which work item is unnecessary?"
        },
        {
          "type": "string",
          "const": "regression_risk",
          "description": "What could regress?"
        },
        {
          "type": "string",
          "const": "surface_missing",
          "description": "Which related surface must also change?"
        },
        {
          "type": "string",
          "const": "delivery_verification",
          "description": "Which deployment or runtime verification is required?"
        }
      ],
      "description": "The class of a critique finding: the question the adversarial pass asked. Closed, so that a\nreview's findings can be counted by question rather than read as prose.\n\n```\nuse majordomus_cli::intent_review::CritiqueClass;\nassert_eq!(\n    serde_json::to_string(&CritiqueClass::DeliveryVerification).unwrap(),\n    \"\\\"delivery_verification\\\"\"\n);\n```"
    },
    "ResolutionState": {
      "oneOf": [
        {
          "type": "string",
          "const": "open",
          "description": "Not yet resolved."
        },
        {
          "type": "string",
          "const": "planned",
          "description": "Carried by an issue."
        },
        {
          "type": "string",
          "const": "rejected",
          "description": "Judged not to apply, with a reason."
        }
      ],
      "description": "How a critique finding was resolved: not yet, by planning work that serves the intent, or\nby rejecting it with a reason. A blocking finding left `Open` refuses execution.\n\n```\nuse majordomus_cli::intent_review::ResolutionState;\nassert_eq!(serde_json::to_string(&ResolutionState::Planned).unwrap(), \"\\\"planned\\\"\");\nassert_ne!(ResolutionState::Open, ResolutionState::Rejected);\n```"
    },
    "IntentPreflightGap": {
      "type": "object",
      "properties": {
        "source": {
          "type": "string",
          "description": "Repository-relative path of the record."
        },
        "observed_at": {
          "type": "string",
          "description": "The commit the observations were made on."
        },
        "conditions": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/GapCondition"
          },
          "description": "The gap's answer for each criterion the work serves, in the gap's order."
        },
        "risks": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "The risks it recorded."
        }
      },
      "required": [
        "source",
        "observed_at",
        "conditions",
        "risks"
      ],
      "description": "The recorded gap of an intent as a preflight reads it, bounded to the criteria the work\nserves: what was observed of each, at which commit, and the risks.\n\n```\nuse majordomus_cli::intent::IntentPreflightGap;\nlet g = IntentPreflightGap {\n    source: \".ai/repo/project/gaps/x.yaml\".into(),\n    observed_at: \"c3f20da\".into(),\n    conditions: vec![],\n    risks: vec![\"the schema may refuse old records\".into()],\n};\nassert_eq!(g.risks.len(), 1);\n```"
    },
    "GapCondition": {
      "type": "object",
      "properties": {
        "criterion": {
          "type": "string",
          "description": "The criterion id of the intent."
        },
        "state": {
          "anyOf": [
            {
              "$ref": "#/$defs/ConditionState"
            },
            {
              "type": "null"
            }
          ],
          "description": "The state, or `None` when the record spells one this module does not know."
        },
        "state_text": {
          "type": "string",
          "description": "As written, so a finding can quote an unknown state."
        },
        "because": {
          "type": "string",
          "description": "Why."
        },
        "observations": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "The observation ids it rests on."
        }
      },
      "required": [
        "criterion",
        "state_text",
        "because",
        "observations"
      ],
      "description": "One criterion's state against the observations, as the record spells it. `state` is `None`\nwhen the file names a state this module does not know, and `state_text` keeps what was\nwritten so the finding can quote it.\n\n```\nuse majordomus_cli::intent_review::{ConditionState, GapCondition};\nlet c = GapCondition {\n    criterion: \"criteria-are-covered\".into(),\n    state: Some(ConditionState::Missing),\n    state_text: \"missing\".into(),\n    because: \"nothing relates a criterion to an issue\".into(),\n    observations: vec![\"no-serves-field\".into()],\n};\nassert_eq!(c.state, Some(ConditionState::Missing));\nassert!(!c.observations.is_empty());\n```"
    },
    "ConditionState": {
      "oneOf": [
        {
          "type": "string",
          "const": "satisfied",
          "description": "Already true at the observed commit."
        },
        {
          "type": "string",
          "const": "missing",
          "description": "Not true; work is needed."
        },
        {
          "type": "string",
          "const": "conflicting",
          "description": "Something in the repository contradicts it."
        },
        {
          "type": "string",
          "const": "unknown",
          "description": "Not determined. Never read as satisfied."
        }
      ],
      "description": "The state of one criterion as the gap observed it. Four values, because \"not determined\"\nhas to be writable: an omitted criterion is refused, and `Unknown` is never a pass.\n\n```\nuse majordomus_cli::intent_review::ConditionState;\nassert_eq!(serde_json::to_string(&ConditionState::Conflicting).unwrap(), \"\\\"conflicting\\\"\");\nassert_ne!(ConditionState::Unknown, ConditionState::Satisfied);\n```"
    },
    "IntentPreflightRefusal": {
      "type": "object",
      "properties": {
        "issue": {
          "type": [
            "string",
            "null"
          ],
          "description": "The issue it is about; absent when no issue was resolved at all."
        },
        "cause": {
          "$ref": "#/$defs/IntentPreflightCause",
          "description": "The cause."
        },
        "message": {
          "type": "string",
          "description": "What is wrong, in one sentence."
        }
      },
      "required": [
        "cause",
        "message"
      ],
      "description": "One reason a preflight refused: which issue, the cause, and one sentence of what is wrong.\n\n```\nuse majordomus_cli::intent::{IntentPreflightCause, IntentPreflightRefusal};\nlet r = IntentPreflightRefusal::new(\n    Some(\"I1900\"),\n    IntentPreflightCause::IntentNotCritiqued,\n    \"intent x has no critique\".into(),\n);\nassert_eq!(r.cause, IntentPreflightCause::IntentNotCritiqued);\nassert_eq!(r.issue.as_deref(), Some(\"I1900\"));\n```"
    },
    "IntentPreflightCause": {
      "oneOf": [
        {
          "type": "string",
          "const": "unknown_issue",
          "description": "The issue named is not an issue of the plan."
        },
        {
          "type": "string",
          "const": "no_issue_covers_paths",
          "description": "No open issue's scope covers any of the paths."
        },
        {
          "type": "string",
          "const": "issue_serves_nothing",
          "description": "The issue's milestone realises a live intent and the issue serves none of its criteria."
        },
        {
          "type": "string",
          "const": "serves_another_intent",
          "description": "The issue serves a criterion of an intent whose milestones do not include its own."
        },
        {
          "type": "string",
          "const": "serves_unknown_criterion",
          "description": "The issue serves an intent or a criterion that does not exist, or a token that is not\n`<intent>#<criterion>`."
        },
        {
          "type": "string",
          "const": "intent_not_critiqued",
          "description": "An intent the issue serves has no critique: its plan was never reviewed."
        },
        {
          "type": "string",
          "const": "open_blocking_finding",
          "description": "The critique of an intent the issue serves has a blocking finding still open."
        }
      ],
      "description": "Why a preflight refused, as a word a reader greps for.\n\n```\nuse majordomus_cli::intent::IntentPreflightCause;\nassert_eq!(\n    serde_json::to_string(&IntentPreflightCause::OpenBlockingFinding).unwrap(),\n    \"\\\"open_blocking_finding\\\"\"\n);\nassert_ne!(\n    IntentPreflightCause::IntentNotCritiqued,\n    IntentPreflightCause::IssueServesNothing\n);\n```"
    }
  }
}

Examples

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

first-issue
{
  "issue": "I0001",
  "paths": ""
}