obligations.closure
Každý závazek, který aktivní úloha deklarovala, spojený s tím, co o něm říká slovník, a s důkazy, které ho splňují, nebo ne: co se dluží, co je splněno a co zastaralo — se zaznamenaným hashem vstupu a aktuálním hashem stromu, nebo zaznamenaným commitem a jeho štítkem, aby čtenář viděl, proti čemu. Posouzení je to, které aplikuje `finish`, reprodukované, ne znovu rozhodnuté, a slova zastarání jsou jediná čtyři v repozitáři. Checkout bez úlohy to hlásí, místo aby hlásil, že se nedluží nic.
Každý závazek, který aktivní úloha deklarovala, spojený s tím, co o něm říká slovník, a s důkazy, které ho splňují, nebo ne: co se dluží, co je splněno a co zastaralo — se zaznamenaným hashem vstupu a aktuálním hashem stromu, nebo zaznamenaným commitem a jeho štítkem, aby čtenář viděl, proti čemu. Posouzení je to, které aplikuje `finish`, reprodukované, ne znovu rozhodnuté, a slova zastarání jsou jediná čtyři v repozitáři. Checkout bez úlohy to hlásí, místo aby hlásil, že se nedluží nic.
- query
- behaviorally_verified
- moduly obligations
- #obligations
- #completion
- #continuity
Zpřístupnění
Kde je tato jedna definice dosažitelná. Absence je explicitní: povrch, který není uveden, ji nenese.
| povrch | jako |
|---|---|
| MCP | nástroj majordomus_obligation_closure zdroj majordomus://obligations/closure |
| HTTP | GET /api/v1/obligations/closure operationId obligations.closure |
| příkazová řádka | — |
Schémata
Kanonický vstup a výstup z typů Rustu; schéma nástroje MCP a parametry a odpovědi OpenAPI se odvozují z nich.
vstup · Prázdné
Žádné vlastnosti: schopnost nebere žádný vstup.
JSON Schema
{
"additionalProperties": false,
"description": "No input.",
"title": "Empty",
"type": "object"
}výstup · Closure
Klon, který nikdy nespustil životní cyklus, odpovídá i na toto, a odpovídá jako na absenci: present false, žádná úloha a zjištění, které to říká. „Nic nedlužíme“ a „není komu dlužit“ jsou různé skutečnosti a obsluhovaná instance nesmí hlásit druhou jako první.
use majordomus_cli::capability::builtin::obligations::Closure;
let fresh: Closure = serde_json::from_str(
r#"{"present":false,"worktree":"/srv/clone","branch":"master","closed":false,
"tallies":{},
"findings":["no active task in this checkout (.ai/local/state/current.yaml); nothing owes anything here"]}"#,
)
.unwrap();
assert!(!fresh.present && !fresh.closed, "nothing that does not exist is closed");
assert!(fresh.task.is_none() && fresh.obligations.is_empty());
assert_eq!(fresh.findings.len(), 1, "absence is reported, not implied");| vlastnost | typ | povinné | popis |
|---|---|---|---|
| větev | string | ano | Branch, nebo DETACHED. |
| uzavřeno | boolean | ano | Pravda, když úloha deklaruje povinnosti a každá z nich je splněna a aktuální — tedy když by majordomus.obligation-closure neodmítl finish --outcome completed. Nepravda, když je cokoli dlužné, zastaralé nebo nedeklarované, a nepravda, když žádná úloha není: co neexistuje, není uzavřeno. |
| zjištění | array | ne | Co by měl čtenář vědět, než čemukoli z uvedeného uvěří: nečitelný slovník, knihu, kterou nešlo přečíst, úlohu, která nic nedeklaruje. Prázdné je běžný případ. |
| head | string | ne | Commit, na kterém tento checkout stojí. |
| závazky | array | ne | Každý závazek, který úloha deklarovala, v pořadí, v jakém je deklarovala. |
| přítomno | boolean | ano | Zda tento checkout vůbec má úlohu, o které by se dalo hlásit. False v klonu, který nikdy nespustil životní cyklus, což není porucha a není to „nic nedlužíme“. |
| součty | object | ano | Kolik závazků stojí kde, podle slova stavu. Chybějící stavy chybějí místo nuly, takže čtenář nemusí znát slovník, aby četl součty. |
| úloha | jedno ze 2 | ne | Aktivní úloha, nebo None. Její requires je seznam, který rozbalují záznamy níže. |
| working_tree | string | ne | clean nebo dirty. |
| worktree | string | ano | Worktree, kterého se tato odpověď týká. Každé čtení níže se vztahuje k němu a k žádnému jinému checkoutu téhož repozitáře. |
JSON Schema
{
"$defs": {
"ActiveTask": {
"description": "The active task of this checkout, when there is one.",
"properties": {
"binding": {
"description": "The standing `intents.binding` answered when the task started — what `start` was\ntold then, not where the work stands now.",
"type": "string"
},
"evidence_standing": {
"description": "The pin of where the served criteria's evidence stood when the task started.",
"type": "string"
},
"exemption": {
"description": "The exemption class the worker gave instead (`start --exempt`).",
"type": "string"
},
"exemption_because": {
"description": "The reason given with the exemption.",
"type": "string"
},
"head": {
"description": "The commit it started at.",
"type": "string"
},
"id": {
"description": "The task id.",
"type": "string"
},
"intent": {
"description": "The intent the worker said this task serves (`start --intent`).",
"type": "string"
},
"issue": {
"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).",
"type": "string"
},
"outcome": {
"description": "Its typed outcome so far: `active`, `handed_over`, or a finished one.",
"type": "string"
},
"plan_revision": {
"description": "The pin of what the work was for when the task started.",
"type": "string"
},
"profile": {
"description": "The execution profile it runs under.",
"type": "string"
},
"requires": {
"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.",
"items": {
"type": "string"
},
"type": "array"
},
"scope": {
"description": "The paths it claims.",
"items": {
"type": "string"
},
"type": "array"
},
"started_at": {
"description": "When it started.",
"type": "string"
},
"task": {
"description": "What is being worked on.",
"type": "string"
}
},
"required": [
"id",
"task",
"profile",
"outcome"
],
"type": "object"
},
"Divergence": {
"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.",
"oneOf": [
{
"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`.",
"type": "string"
}
]
},
"Evidence": {
"description": "The `task.evidence` line that discharged an obligation, as the ledger holds it.\n\nNothing older is consulted: evidence is superseded by evidence, and the ledger keeps\nthe history for a reader that wants it.\n```\nuse majordomus_cli::capability::builtin::obligations::Evidence;\nlet e: Evidence = serde_json::from_str(\n r#\"{\"recorded_at\":\"2026-09-09T21:01:00Z\",\"head\":\"f00ba7\",\"branch\":\"master\",\n \"kind\":\"ci\",\"command\":\"scripts/ci/reference-check\",\"inputs_hash\":\"7f68b9\"}\"#,\n)\n.unwrap();\nassert_eq!(e.head, \"f00ba7\", \"the envelope's commit is what a remote fact is judged against\");\nassert!(e.artifact.is_empty(), \"one of command and artifact; narrative is not evidence\");\n```",
"properties": {
"artifact": {
"description": "The reference it points at, such as a published URL.",
"type": "string"
},
"branch": {
"description": "The branch it was recorded on.",
"type": "string"
},
"command": {
"description": "The command that produced it. Narrative is not evidence, so one of this and\n`artifact` is always present.",
"type": "string"
},
"head": {
"description": "The commit the ledger's envelope stamped on it.",
"type": "string"
},
"inputs_hash": {
"description": "The hash of the token's declared inputs at the moment it was taken. Empty for a\ntoken that declares none.",
"type": "string"
},
"kind": {
"description": "How it was taken: `test`, `build`, `ci`, `artifact` or `manual`.",
"type": "string"
},
"recorded_at": {
"description": "When the line was appended.",
"type": "string"
},
"result": {
"description": "What the command said, when its output was the point.",
"type": "string"
},
"session": {
"description": "The episode that recorded it, when one was open.",
"type": "string"
}
},
"required": [
"recorded_at",
"head"
],
"type": "object"
},
"ObligationClosure": {
"description": "One obligation the task declared, joined with what the vocabulary says about it and\nwith the evidence that does or does not discharge it.\n\nThe vocabulary's fields are repeated here on purpose: a client asking what this task\nowes gets the token's title, its summary and the command that would discharge it in the\nsame answer, and needs no second call to render a report.\n\n```\nuse majordomus_cli::capability::builtin::obligations::{ObligationClosure, ObligationState};\nlet owed: ObligationClosure = serde_json::from_str(\n r#\"{\"id\":\"pages\",\"title\":\"The published site serves this commit\",\"remote\":true,\n \"state\":\"owed\",\"detail\":\"owed, and no evidence was recorded\",\n \"reproduce\":\"majordomus evidence --covers pages --command 'scripts/pages verify'\"}\"#,\n)\n.unwrap();\nassert_eq!(owed.state, ObligationState::Owed);\nassert!(owed.evidence.is_none() && owed.staleness.is_none(), \"nothing to label\");\nassert!(owed.reproduce.starts_with(\"majordomus evidence\"), \"a finding carries its repair\");\n```",
"properties": {
"detail": {
"description": "One line: what this obligation's standing actually is, in the words the validator\nuses when it refuses.",
"type": "string"
},
"discharged_by": {
"description": "From the vocabulary: the command that produces the evidence.",
"type": "string"
},
"evidence": {
"anyOf": [
{
"$ref": "#/$defs/Evidence"
},
{
"type": "null"
}
],
"description": "The line that discharged it, or `None`."
},
"id": {
"description": "The token, as the task's `requires` names it.",
"type": "string"
},
"inputs": {
"description": "From the vocabulary: the pathspecs the evidence is hashed over.",
"items": {
"type": "string"
},
"type": "array"
},
"inputs_files": {
"description": "How many tracked files that hash was taken over. Reported because the shell's\nselection and this one are not always the same set — see the module header — and a\ncount is the cheapest way for a reader to see it rather than be told it.",
"format": "uint",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"inputs_hash_now": {
"description": "What the token's inputs hash to in this tree now — the other half of \"stale against\nwhat\". `None` for a token that declares no inputs, and `None` when git could not be\nasked which files they select.",
"type": [
"string",
"null"
]
},
"remote": {
"description": "From the vocabulary: whether the fact is remote.",
"type": "boolean"
},
"reproduce": {
"description": "The command that would discharge it. Every finding here carries the way to act on\nit, as `project.finding-carries-reproduce` asks.",
"type": "string"
},
"staleness": {
"anyOf": [
{
"$ref": "#/$defs/Divergence"
},
{
"type": "null"
}
],
"description": "How far the evidence is from this checkout, in the repository's one staleness\nvocabulary. `None` when there is no evidence to label.\n\nA remote fact is labelled against the commit it was taken at, because the site that\nserves a commit goes on serving it while the tree moves underneath. A tree-bound\nfact is labelled by re-hashing: equal hashes are `exact`, and a difference takes the\ncommit's label, which is `advanced` when the working tree has merely moved on and\n`diverged` when the history it named is gone. A token that declares neither inputs\nnor a remote fact is bound to nothing and stays `exact` once recorded — that is the\nvalidator's behaviour, and it is reproduced rather than tightened here."
},
"state": {
"$ref": "#/$defs/ObligationState",
"description": "Where it stands."
},
"summary": {
"description": "From the vocabulary.",
"type": "string"
},
"title": {
"description": "From the vocabulary; the token itself when it declares none.",
"type": "string"
}
},
"required": [
"id",
"title",
"remote",
"state",
"detail",
"reproduce"
],
"type": "object"
},
"ObligationState": {
"description": "Where one obligation stands.\n\nThe words are the validator's verdicts, not a severity scale: `stale` is not a worse\n`owed`, it is evidence that was true and no longer describes what it proved.\n\n```\nuse majordomus_cli::capability::builtin::obligations::ObligationState;\n// only one of the four lets a task be called completed\nlet completable = |s: ObligationState| s == ObligationState::Discharged;\nassert!(completable(ObligationState::Discharged));\nassert!(!completable(ObligationState::Stale), \"evidence that no longer describes the tree\");\nassert!(!completable(ObligationState::Owed));\nassert!(!completable(ObligationState::Undeclared));\n```",
"oneOf": [
{
"const": "owed",
"description": "Declared, and no evidence for it was ever recorded.",
"type": "string"
},
{
"const": "discharged",
"description": "Evidence exists and still describes this tree, or this commit.",
"type": "string"
},
{
"const": "stale",
"description": "Evidence exists and no longer describes what it proved: the inputs changed, or the\ncommit it named is not this one.",
"type": "string"
},
{
"const": "undeclared",
"description": "The task requires a token the shipped vocabulary does not declare. Nothing can\ndischarge it, because nothing knows what would.",
"type": "string"
}
]
}
},
"description": "What this checkout's active task owes, and how much of it is still true.\n\nA clone that has never run the lifecycle answers this too, and answers it as absence:\n`present` false, no task, and a finding saying so. \"Nothing owed\" and \"nothing to owe\nit\" are different facts, and a served instance must not report the second as the first.\n\n```\nuse majordomus_cli::capability::builtin::obligations::Closure;\nlet fresh: Closure = serde_json::from_str(\n r#\"{\"present\":false,\"worktree\":\"/srv/clone\",\"branch\":\"master\",\"closed\":false,\n \"tallies\":{},\n \"findings\":[\"no active task in this checkout (.ai/local/state/current.yaml); nothing owes anything here\"]}\"#,\n)\n.unwrap();\nassert!(!fresh.present && !fresh.closed, \"nothing that does not exist is closed\");\nassert!(fresh.task.is_none() && fresh.obligations.is_empty());\nassert_eq!(fresh.findings.len(), 1, \"absence is reported, not implied\");\n```",
"properties": {
"branch": {
"description": "The branch, or `DETACHED`.",
"type": "string"
},
"closed": {
"description": "True when the task declares obligations and every one of them is discharged and\ncurrent — that is, when `majordomus.obligation-closure` would not refuse\n`finish --outcome completed`. False when anything is owed, stale or undeclared, and\nfalse when there is no task: nothing that does not exist is closed.",
"type": "boolean"
},
"findings": {
"description": "What a reader should know before trusting any of the above: an unreadable\nvocabulary, a ledger that could not be read, a task that declares nothing. Empty is\nthe ordinary case.",
"items": {
"type": "string"
},
"type": "array"
},
"head": {
"description": "The commit this checkout is on.",
"type": "string"
},
"obligations": {
"description": "Every obligation the task declared, in the order it declared them.",
"items": {
"$ref": "#/$defs/ObligationClosure"
},
"type": "array"
},
"present": {
"description": "Whether this checkout has a task to report about at all. False in a clone that has\nnever run the lifecycle, which is not a fault and is not \"nothing owed\".",
"type": "boolean"
},
"tallies": {
"additionalProperties": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"description": "How many obligations stand where, by state word. Absent states are absent rather\nthan zero, so a reader never has to know the vocabulary to read the tallies.",
"type": "object"
},
"task": {
"anyOf": [
{
"$ref": "#/$defs/ActiveTask"
},
{
"type": "null"
}
],
"description": "The active task, or `None`. Its `requires` is the list the entries below expand."
},
"working_tree": {
"description": "`clean` or `dirty`.",
"type": "string"
},
"worktree": {
"description": "The worktree this answer is about. Every reading below is scoped to it, and to no\nother checkout of the same repository.",
"type": "string"
}
},
"required": [
"present",
"worktree",
"branch",
"closed",
"tallies"
],
"title": "Closure",
"type": "object"
}Politiky
- benchmark
- povinné — cíl na každém transportu, který expozice deklaruje; případy jsou ty ze vstupního typu
- cache
- process — až 2 záznamy v procesu, po 2 s každý, vymezené otiskem registru
Cíle benchmarku
Odvozeno z registru pro tento repozitář: jeden požadavek na transport a případy, které poskytuje typ vstupu. Celá matice je na stránce měření výkonu.