Skip to main content

Module intent_review

Module intent_review 

Source
Expand description

The two planning records an intent is held to before execution: the gap and the critique.

Majordomus does not reason about what is missing or what a plan overlooked. A worker does — a person, Claude, Codex, Gemini — and writes what it found into a typed record, so that planning starts from a recorded analysis rather than from a prompt, and so that the analysis can be refused (ADR 0073):

  • a gap (.ai/repo/project/gaps/<intent>.yaml, majordomus.gap/v1) states, at one commit, the observations made of the repository, the state of every criterion of the intent against them (satisfied, missing, conflicting or unknown), the risks, and the work it suggests;
  • a critique (.ai/repo/project/critiques/<intent>.yaml, majordomus.critique/v1) records the adversarial pass over the plan: each finding has a class, a subject, whether it blocks execution, and a resolution — open, planned into an issue that serves the intent, or rejected with a reason.

What this module decides is only whether the records hold together and whether the plan honours them. A gap must answer every criterion and cite an observation for every answer that is not unknown. A criterion the gap observed satisfied needs no planned work; every other criterion still does (that is the coverage’s question). A finding planned into an issue must name an issue that exists and serves the intent. And no issue serving an intent may have started while the intent has no critique, or while a blocking finding is open.

Every function here is pure over parsed records, the intent outlines and the plan.

use majordomus_cli::intent_plan::IntentOutline;
use majordomus_cli::intent_review::{review, GapRecord};
use majordomus_cli::plan::Plan;
let intent = IntentOutline {
    id: "x".into(),
    criteria: vec!["a".into(), "b".into()],
    milestones: vec!["m".into()],
    ..Default::default()
};
// a gap that answers one criterion and leaves the other out is refused, by name
let gap = GapRecord::from_metadata(".ai/repo/project/gaps/x.yaml", &serde_json::json!({
    "intent": "x", "observed_at": "c3f20da",
    "observations": [{"id": "o1", "statement": "nothing there", "source": "file:src"}],
    "conditions": [{"criterion": "a", "state": "missing", "observations": ["o1"]}],
}));
let findings = review(&[intent], &plan, &[gap], &[]);
assert!(findings.iter().any(|f| f.code == "gap_criterion_unanswered" && f.subject == "x#b"));

Structs§

CritiqueFinding
One critique finding: what the review found, what it is about, whether it blocks execution, and how it was resolved. class and resolution are None when the record spells one this module does not know, and the _text fields keep what was written.
CritiqueRecord
A critique record: the adversarial pass over one intent’s plan, at the commit it was reviewed at, with every finding and its resolution. One per intent, named by it.
GapCondition
One criterion’s state against the observations, as the record spells it. state is None when the file names a state this module does not know, and state_text keeps what was written so the finding can quote it.
GapObservation
One observation of the current state, with the place it was observed in — a file, a command, a test or a URL — so a reader can go and look at the same thing.
GapRecord
A gap record: the observations a worker made of the repository at one commit, the state of every criterion of the intent against them, the risks, and the work it suggests. One per intent, named by it.
GapWork
One work item the gap suggests: what it would do, the criteria it would make true, and the issue it became once somebody planned it. Nothing turns this into an issue automatically; the link is recorded when a worker writes the issue.

Enums§

ConditionState
The state of one criterion as the gap observed it. Four values, because “not determined” has to be writable: an omitted criterion is refused, and Unknown is never a pass.
CritiqueClass
The class of a critique finding: the question the adversarial pass asked. Closed, so that a review’s findings can be counted by question rather than read as prose.
ResolutionState
How a critique finding was resolved: not yet, by planning work that serves the intent, or by rejecting it with a reason. A blocking finding left Open refuses execution.

Constants§

CRITIQUE
The kind of a critique record.
GAP
The kind of a gap record.

Functions§

observed_satisfied
The criteria a gap observed already satisfied, by intent: the ones coverage does not ask work of. A condition counts only if it is satisfied and cites at least one observation the gap declares.
review
The findings of the gap and critique records against the intents and the plan: whether each record holds together, and whether execution waited for the review.