Skip to content

Completion discharges obligations and never decides whether an intent is satisfied

Completion discharges obligations and never decides whether an intent is satisfied

majordomus://adr/adr-0107proposed intentcompletionevidencegovernance

it references

referenced by

107. Completion discharges obligations and never decides whether an intent is satisfied

Context

ADR 0070 made an intent a typed record whose stage is derived from the plan and whose satisfaction is derived from the evidence ledger. Its first consequence planned the opposite direction for later: once completion policy landed (pull request 292, cited there as ADR 0057, which exists only on an unmerged branch), whether an intent is satisfied would become a completion-policy question over the same evidence, and the intent engine would answer the stage only. Slice 2 of the intent-lifecycle milestone carries that plan.

Completion answers a different question. majordomus finish judges whether a task discharged the obligations its profile and policy declare: scope, verification, the note, the regression test, the gates. An intent asks whether something is observably true for the people it is for. A task can be finished and its intent still false, and an intent can become true without any task finishing — a test that starts passing, a claim whose inputs stop changing. If completion policy decided satisfaction, a finished task would be one policy edit away from stamping an intent satisfied, which is the merge-stamping ADR 0070 rejected under another name.

The engine couples two answers today: intent::stage returns satisfied only when every counted milestone is DONE and every criterion is met, so a reader cannot ask whether the evidence alone settles an intent while its milestones are still open.

Decision

  • One authority. Whether a satisfaction criterion is met is decided by the intent engine (apps/majordomus-cli/src/intent.rs) over the evidence ledger and the claim join, and by nothing else. No other module, policy file, capability or gate computes, stores or overrides a criterion's verdict or an intent's satisfaction.
  • Completion reads, never decides. Completion policy decides whether work is done. It may read an intent's derived standing as an input to a question (for example, to report which criteria a task advanced), but it never declares a question whose answer is that an intent is satisfied, never writes an intent record, and never stores a stage or a verdict. A finish with outcome completed leaves every intent's stage and criterion states exactly as the plan and the evidence derive them.
  • The stage stays plan-derived. stage keeps its meaning: satisfied is the stage of an intent whose counted milestones are DONE and whose criteria are all met; no surface changes here.
  • Satisfaction gets its own verdict. A separate derived verdict answers the evidence question alone: satisfied when every criterion is met, unsatisfied when a criterion the ledger can settle is not met, unknown when the unmet criteria are only of kinds the ledger cannot yet settle (command, deployment). DONE neither implies it nor is required for it. The field is named verdict, because satisfaction already names the criteria array in the record and in IntentView. Slice S07 implements it, with drift findings where the verdict and the stage disagree.
  • ADR 0070's first consequence is superseded by this decision, and slice 2 of the intent-lifecycle milestone is restated to match.

Alternatives rejected

Satisfaction as a completion-policy question (ADR 0070's plan). It would put a policy file between the evidence and the answer, and a finished task would become a route to a satisfied intent. Completion is about the task; satisfaction is about the world the task was for.

Keeping satisfaction coupled to DONE. It is true of today's stage, but it hides an answer the evidence already has: an intent whose criteria all hold while a milestone is open is exactly the drift a reader needs to see, and a coupled answer cannot show it.

Renaming the existing satisfaction array to free the name. It is in the schema, the distribution skeleton, the documentation examples and every surface's output; renaming it breaks readers to save choosing a new word.

Consequences

  • project.completion-never-decides-satisfaction states the boundary, and test/cases/895_a_finished_task_does_not_satisfy_an_intent.sh proves it through the built executable: a completed finish next to a DONE milestone with unmet criteria leaves the stage verifying, the criterion not_run and the intent record unchanged.
  • The completion batch's policy (share/completion.yaml) must never gain an intent-satisfaction question; a question that reads intent standing is an input, never a verdict.
  • S07 adds verdict to IntentView on every surface; until it lands, the stage is the only derived answer and it stays coupled to DONE.
  • Evidence-first acceptance at the plan transition — plan done on an issue that serves a criterion requiring that criterion's evidence — is not decided here; it belongs to the plan, not to completion, and is left to a later slice.

Where this comes from

canonical file
.ai/repo/adrs/0107-completion-discharges-obligations-and-never-decides-whether-an-intent-is-satisfied.md
identity
adr-0107
also served as
MCP resource majordomus://adr/adr-0107 · majordomus entity show adr/adr-0107 · GET /api/v1/entity?uri=majordomus://adr/adr-0107
in the Cockpit
/cockpit/objects/adr/adr-0107

This page is generated from the file above by scripts/generate-site-data; editing the page changes nothing, editing the file changes every surface. The relations above are edges of docs/generated/graph.json, which the executable writes from the same index.

Searches the titles and descriptions of every page this site publishes.