evidence.report
The whole claims matrix joined to the ledger and judged at the presented revision: the working tree by default, or the checked-out commit as committed, read from the ledger that commit holds. Per claim: the proof state, the sentence explaining how that state was derived, why when the state alone does not say, the execution behind it, the files that changed since it, and the command that produces it again. A run on a commit the presented revision does not contain is stale, a test that declined to run is not run, and a run the working ledger holds that the presented commit's does not can only withhold proven. The tallies count the whole matrix even when the answer is filtered, and the findings name every claim that declares a guarantee the evidence does not support. Kept per checkout state, never longer: the ledger is a file that changes outside this process, and an edit of it, of a test or of any tracked file, a new untracked file, a commit or a new ref is a new answer.
The whole claims matrix joined to the ledger and judged at the presented revision: the working tree by default, or the checked-out commit as committed, read from the ledger that commit holds. Per claim: the proof state, the sentence explaining how that state was derived, why when the state alone does not say, the execution behind it, the files that changed since it, and the command that produces it again. A run on a commit the presented revision does not contain is stale, a test that declined to run is not run, and a run the working ledger holds that the presented commit's does not can only withhold proven. The tallies count the whole matrix even when the answer is filtered, and the findings name every claim that declares a guarantee the evidence does not support. Kept per checkout state, never longer: the ledger is a file that changes outside this process, and an edit of it, of a test or of any tracked file, a new untracked file, a commit or a new ref is a new answer.
- query
- behaviorally_verified
- module evidence
- #evidence
- #claims
- #tests
- #verification
- #provenance
Exposure
Where this one definition is reachable. Absence is explicit: a surface not listed does not carry it.
| surface | as |
|---|---|
| MCP | tool majordomus_evidence resource majordomus://evidence |
| HTTP | GET /api/v1/evidence operationId evidence.report |
| command line | majordomus evidence show |
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 · EvidenceReportInput
Every filter narrows, and they compose; saying nothing asks for the whole matrix at the working tree. A key nothing recognises is refused rather than dropped, because a misspelled filter that read as "no filter" would answer a question nobody asked and look like a clean one.
use majordomus_cli::capability::builtin::evidence::EvidenceReportInput;
use majordomus_cli::evidence::{ProofState, TreeState};
let all: EvidenceReportInput = serde_json::from_str("{}").unwrap();
assert!(all.state.is_none() && all.status.is_none() && !all.findings_only);
assert!(all.presented.is_none(), "the working tree unless a commit is named");
let narrowed: EvidenceReportInput =
serde_json::from_str(r#"{"state": "stale", "findings_only": true}"#).unwrap();
assert_eq!(narrowed.state, Some(ProofState::Stale));
assert!(narrowed.findings_only);
let at: EvidenceReportInput =
serde_json::from_str(r#"{"presented": "HEAD", "presented_tree": "dirty"}"#).unwrap();
assert_eq!(at.presented.as_deref(), Some("HEAD"));
assert_eq!(at.presented_tree, Some(TreeState::Dirty));
assert!(serde_json::from_str::<EvidenceReportInput>(r#"{"states": "stale"}"#).is_err());| property | type | required | description |
|---|---|---|---|
| findings_only | boolean | no | Only the claims whose declared status the evidence does not support, with the findings. The tallies still count the whole matrix, so a filtered answer never misreports how much of it was examined. |
| presented | string | null | no | Judge at this revision, as committed, rather than at the working tree: HEAD, or
any name of the checked-out commit. It must be the checked-out commit; the ledger is
read as that commit holds it, and a run the working ledger holds that the commit's
does not can only withhold proven. Absent: the working tree. |
| presented_tree | one of 2 | no | What the caller knows about the presented commit's tree (clean, dirty,
unknown). It can only weaken the measured state, never assert a clean tree over a
dirty checkout, and it means nothing without presented. |
| state | one of 2 | no | Only claims in this proof state (proven, inputs_unchanged, stale, failing,
not_run, unrunnable, no_test). Absent: every claim. |
| status | string | null | no | Only claims declaring this status (guaranteed, advisory, planned, rejected).
Absent: every claim. |
JSON Schema
{
"$defs": {
"EvidenceTreeState": {
"description": "Whether a tree was the commit it sits on: the three words the ledger and git already\nuse, typed.\n\n`unknown` is not a softer `clean`. It is what is recorded when git could not be asked,\nand not knowing is not proof, so every rule here treats it as not clean.\n\n```\nuse majordomus_cli::evidence::freshness::TreeState;\n\nassert_eq!(TreeState::parse(\"clean\"), TreeState::Clean);\nassert_eq!(TreeState::parse(\"dirty\"), TreeState::Dirty);\n// a word nobody wrote down is not a clean tree\nassert_eq!(TreeState::parse(\"spotless\"), TreeState::Unknown);\nassert_eq!(TreeState::Dirty.as_str(), \"dirty\");\nassert_eq!(serde_json::to_value(TreeState::Unknown).unwrap(), \"unknown\");\n```",
"oneOf": [
{
"const": "clean",
"description": "The tree was the commit: nothing but the evidence ledger differed from it.",
"type": "string"
},
{
"const": "dirty",
"description": "Something other than the evidence ledger differed from the commit.",
"type": "string"
},
{
"const": "unknown",
"description": "Git could not be asked, or the word recorded is none of the three.",
"type": "string"
}
]
},
"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"
}
]
}
},
"additionalProperties": false,
"description": "Which part of the matrix to answer for, and at which revision.\n\nEvery filter narrows, and they compose; saying nothing asks for the whole matrix at the\nworking tree. A key nothing recognises is refused rather than dropped, because a\nmisspelled filter that read as \"no filter\" would answer a question nobody asked and look\nlike a clean one.\n\n```\nuse majordomus_cli::capability::builtin::evidence::EvidenceReportInput;\nuse majordomus_cli::evidence::{ProofState, TreeState};\n\nlet all: EvidenceReportInput = serde_json::from_str(\"{}\").unwrap();\nassert!(all.state.is_none() && all.status.is_none() && !all.findings_only);\nassert!(all.presented.is_none(), \"the working tree unless a commit is named\");\n\nlet narrowed: EvidenceReportInput =\n serde_json::from_str(r#\"{\"state\": \"stale\", \"findings_only\": true}\"#).unwrap();\nassert_eq!(narrowed.state, Some(ProofState::Stale));\nassert!(narrowed.findings_only);\n\nlet at: EvidenceReportInput =\n serde_json::from_str(r#\"{\"presented\": \"HEAD\", \"presented_tree\": \"dirty\"}\"#).unwrap();\nassert_eq!(at.presented.as_deref(), Some(\"HEAD\"));\nassert_eq!(at.presented_tree, Some(TreeState::Dirty));\n\nassert!(serde_json::from_str::<EvidenceReportInput>(r#\"{\"states\": \"stale\"}\"#).is_err());\n```",
"properties": {
"findings_only": {
"description": "Only the claims whose declared status the evidence does not support, with the\nfindings. The tallies still count the whole matrix, so a filtered answer never\nmisreports how much of it was examined.",
"type": "boolean"
},
"presented": {
"description": "Judge at this revision, as committed, rather than at the working tree: `HEAD`, or\nany name of the checked-out commit. It must be the checked-out commit; the ledger is\nread as that commit holds it, and a run the working ledger holds that the commit's\ndoes not can only withhold `proven`. Absent: the working tree.",
"type": [
"string",
"null"
]
},
"presented_tree": {
"anyOf": [
{
"$ref": "#/$defs/EvidenceTreeState"
},
{
"type": "null"
}
],
"description": "What the caller knows about the presented commit's tree (`clean`, `dirty`,\n`unknown`). It can only weaken the measured state, never assert a clean tree over a\ndirty checkout, and it means nothing without `presented`."
},
"state": {
"anyOf": [
{
"$ref": "#/$defs/ProofState"
},
{
"type": "null"
}
],
"description": "Only claims in this proof state (`proven`, `inputs_unchanged`, `stale`, `failing`,\n`not_run`, `unrunnable`, `no_test`). Absent: every claim."
},
"status": {
"description": "Only claims declaring this status (`guaranteed`, `advisory`, `planned`, `rejected`).\nAbsent: every claim.",
"type": [
"string",
"null"
]
}
},
"title": "EvidenceReportInput",
"type": "object"
}output · EvidenceReport
What the capability answers, what the gate judges and what the site renders are this one value; the totals and the findings are derived from the claims, never counted twice.
use majordomus_cli::evidence::{
EvidenceReport, Finding, Ledger, PresentedRevision, ProofState, Subject, TreeState,
};
let mut report = EvidenceReport {
head: None,
working_tree: "unknown".into(),
presented: PresentedRevision {
revision: "working_tree".into(),
tree: TreeState::Unknown,
uncommitted: vec![],
},
ledger: Ledger::empty().summary(),
subject: Subject { examined: 0, complete: true, excluded: vec![] },
claims: vec![],
totals: Default::default(),
findings: vec![],
};
assert!(report.satisfied(), "nothing claimed, so nothing unsupported");
// and the same report over a subject it could not wholly read is not a pass
let mut partial = report.clone();
partial.subject.complete = false;
assert!(!partial.satisfied(), "an absent answer is not a clean one");
report.findings.push(Finding {
claim: "scope-integrity".into(),
status: "guaranteed".into(),
state: ProofState::Failing,
reason: "the claim guarantees a behaviour whose test most recently failed".into(),
reproduce: None,
});
// one unsupported guarantee is enough: the gate is not a proportion
assert!(!report.satisfied());Example
The whole matrix joined to the ledger. satisfied is true when no claim declares a
guarantee the recorded evidence does not support.
use majordomus_cli::evidence::{report, EvidenceReport, Ledger};
use majordomus_cli::synthetic::SyntheticRepository;
let repo = SyntheticRepository::small().unwrap();
let ledger = Ledger::load(repo.root()).unwrap();
let r: EvidenceReport = report(&repo.index().unwrap(), &ledger);
assert!(r.satisfied(), "no claim, so no unsupported guarantee");| property | type | required | description |
|---|---|---|---|
| claims | array | yes | Every claim, in the matrix's own order. |
| findings | array | yes | Claims whose declared status the evidence does not support. |
| head | string | null | no | The commit the report was derived against. |
| ledger | reference | yes | The ledger this was joined against. |
| presented | reference | yes | What the verdicts are about: the working tree, or the checked-out commit judged as committed. |
| subject | reference | yes | What the report could reach. Read this before reading the tallies: they are counts over the claims the index held, and an index that dropped a file holds fewer. |
| totals | object | yes | How many claims are in each state. |
| working_tree | string | yes | clean, dirty or unknown. |
JSON Schema
{
"$defs": {
"EvidenceClaimProof": {
"description": "One claim, joined to whatever the repository actually recorded about it.\n\nThe claim's own fields are carried verbatim beside the derived ones, so that a reader\nwho disbelieves the state can check the join rather than take it.\n\n```\nuse majordomus_cli::evidence::{ClaimProof, ProofState};\n\nlet proof = ClaimProof {\n id: \"scope-integrity\".into(),\n claim: \"a commit outside the task's scope is refused\".into(),\n status: \"guaranteed\".into(),\n source: Some(\"docs/SCOPE.md\".into()),\n implementation: Some(\"apps/majordomus-cli/src/scope.rs\".into()),\n test_path: Some(\"test/cases/07_scope.sh\".into()),\n test: Some(\"suite:07_scope\".into()),\n state: ProofState::NotRun,\n meaning: ProofState::NotRun.meaning().to_string(),\n execution: None,\n changed: vec![],\n detail: None,\n reproduce: Some(\"bash test/run.sh 07_scope\".into()),\n};\n\nlet json = serde_json::to_value(&proof).unwrap();\n// `changed` is emitted empty rather than omitted: a client must not have to tell\n// \"no file changed\" from \"the server did not say\"\nassert_eq!(json[\"changed\"], serde_json::json!([]));\n// an execution that does not exist is absent, not a null standing in for one\nassert!(json.get(\"execution\").is_none());\n// and so is a detail the state did not need\nassert!(json.get(\"detail\").is_none());\nassert_eq!(json[\"meaning\"], serde_json::json!(ProofState::NotRun.meaning()));\n```\n# Example\n\nA `ClaimProof` is produced by `report`; its `state` is the whole answer and its\n`meaning` is that answer in a sentence, worded once for every surface.\n\n```\nuse majordomus_cli::evidence::{report, ClaimProof, Ledger};\nuse majordomus_cli::synthetic::SyntheticRepository;\nlet repo = SyntheticRepository::small().unwrap();\nlet ledger = Ledger::load(repo.root()).unwrap();\nlet r = report(&repo.index().unwrap(), &ledger);\nlet proofs: &[ClaimProof] = &r.claims;\nassert!(proofs.is_empty(), \"a synthetic tree declares no claims\");\n```",
"properties": {
"changed": {
"description": "The files this claim names that differ between the recorded commit and the working\ntree. Empty unless the state is `ProofState::Stale`.\n\nAlways emitted, empty included: the schema this capability publishes says the key is\nthere, and a client that has to tell \"no files changed\" from \"the server did not say\"\nis a client reading two different answers as one.",
"items": {
"type": "string"
},
"type": "array"
},
"claim": {
"description": "The claim sentence.",
"type": "string"
},
"detail": {
"description": "Why the state is what it is, in one sentence, when the state alone does not say: a\ntest that declined to run, a run on a commit the presented revision does not\ncontain, a tree that was not its commit, a failing run the checkout holds uncommitted.",
"type": [
"string",
"null"
]
},
"execution": {
"anyOf": [
{
"$ref": "#/$defs/EvidenceExecution"
},
{
"type": "null"
}
],
"description": "The execution the state was derived from, when there is one."
},
"id": {
"description": "The claim's id, as `docs/CLAIMS.yaml` spells it.",
"type": "string"
},
"implementation": {
"description": "The file that implements it.",
"type": [
"string",
"null"
]
},
"meaning": {
"description": "That state, in one sentence.",
"type": "string"
},
"reproduce": {
"description": "The command that produces the proof again, when a runner owns the test.",
"type": [
"string",
"null"
]
},
"source": {
"description": "The document that defines the behaviour.",
"type": [
"string",
"null"
]
},
"state": {
"$ref": "#/$defs/ProofState",
"description": "What the repository can say about the proof."
},
"status": {
"description": "The status the claim declares: `guaranteed`, `advisory`, `planned`, `rejected`.",
"type": "string"
},
"test": {
"description": "The test's stable identity, when a runner owns it.",
"type": [
"string",
"null"
]
},
"test_path": {
"description": "The path the claim names as its test, verbatim.",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"claim",
"status",
"state",
"meaning",
"changed"
],
"type": "object"
},
"EvidenceExecution": {
"description": "One recorded run of one test: the whole of what this repository durably remembers about\nit.\n\nEvery field is provenance. A result with no commit is an anonymous green, which is the\nthing a badge must never be derived from.\n\n```\nuse majordomus_cli::evidence::{digest_of, Execution, Origin, Outcome, Runner, TestId};\n\nlet id = TestId::of(\"apps/majordomus-cli/tests/why.rs\").unwrap();\nlet run = Execution {\n test: id.as_string(),\n runner: Runner::Crate,\n source: id.source(),\n outcome: Outcome::Pass,\n seconds: 12,\n commit: \"0\".repeat(40),\n working_tree: \"clean\".into(),\n digest: digest_of(b\"fn main() {}\"),\n at: \"2026-09-11T00:00:00Z\".into(),\n origin: Origin::Ci,\n command: id.reproduce(),\n run: None,\n};\n\n// it is a value in a tracked JSON file, so it has to survive the file unchanged\nlet back: Execution = serde_json::from_str(&serde_json::to_string(&run).unwrap()).unwrap();\nassert_eq!(back, run);\nassert_eq!(back.test, \"crate:why\");\nassert_eq!(back.command, \"cargo test --test why\");\n```\n# Example\n\nOne recorded run, with the provenance the runner did not carry: which commit, which\ntree state, the digest of the test's own source, when, and how to run it again.\n\n```\nuse majordomus_cli::evidence::{Execution, Origin, Outcome, Runner};\nlet e = Execution {\n test: \"suite:07_scope\".into(),\n runner: Runner::Suite,\n source: \"test/cases/07_scope.sh\".into(),\n outcome: Outcome::Pass,\n seconds: 3,\n commit: \"a04b65c9\".into(),\n working_tree: \"clean\".into(),\n digest: \"sha256:00\".into(),\n at: \"2026-09-11T00:00:00Z\".into(),\n origin: Origin::Local,\n command: \"bash test/run.sh 07_scope\".into(),\n run: None,\n};\nassert!(e.outcome.proves());\n```",
"properties": {
"at": {
"description": "When it was recorded, RFC 3339, UTC.",
"type": "string"
},
"command": {
"description": "The exact command that runs this one test again.",
"type": "string"
},
"commit": {
"description": "The full commit id the run was made against.",
"type": "string"
},
"digest": {
"description": "`sha256:<hex>` of the test's own source as it was when the run was recorded. An\nexecution whose test no longer hashes to this did not run the test that is there now.",
"type": "string"
},
"origin": {
"$ref": "#/$defs/EvidenceOrigin",
"description": "Where the run happened."
},
"outcome": {
"$ref": "#/$defs/EvidenceOutcome",
"description": "What it said."
},
"run": {
"anyOf": [
{
"$ref": "#/$defs/EvidenceRun"
},
{
"type": "null"
}
],
"description": "The continuous-integration run the execution was recorded in, when it was recorded in\none that could name itself. Absent for a local run, and absent from every row recorded\nbefore runs were named, which is why the ledger's version did not change."
},
"runner": {
"$ref": "#/$defs/EvidenceRunner",
"description": "Which runner produced it."
},
"seconds": {
"description": "How long it took, in whole seconds.",
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"source": {
"description": "The test's own source, repository-relative.",
"type": "string"
},
"test": {
"description": "The test, in `TestId::as_string` form.",
"type": "string"
},
"working_tree": {
"description": "`clean`, `dirty` or `unknown`: whether the tree the run measured was the commit.",
"type": "string"
}
},
"required": [
"test",
"runner",
"source",
"outcome",
"seconds",
"commit",
"working_tree",
"digest",
"at",
"origin",
"command"
],
"type": "object"
},
"EvidenceFinding": {
"description": "A claim whose declared status the evidence does not support.\n\nOnly a `guaranteed` claim can produce one: the other statuses already say that a current\nproof is not what they are claiming. A finding says what was claimed, what the evidence\nsupports instead, and — where running something would settle it — what to run.\n\n```\nuse majordomus_cli::evidence::{Finding, ProofState};\n\nlet finding = Finding {\n claim: \"scope-integrity\".into(),\n status: \"guaranteed\".into(),\n state: ProofState::NotRun,\n reason: \"the claim guarantees a behaviour and names a test, and no run of that \\\n test has ever been recorded\"\n .into(),\n reproduce: Some(\"bash test/run.sh 07_scope\".into()),\n};\n\n// the gap is the finding: what the matrix declares against what the ledger holds\nassert_ne!(finding.status, finding.state.label());\nassert!(finding.reproduce.unwrap().starts_with(\"bash test/run.sh\"));\n```\n# Example\n\n```\nuse majordomus_cli::evidence::{Finding, ProofState};\nlet f = Finding {\n claim: \"some-claim\".into(),\n status: \"guaranteed\".into(),\n state: ProofState::NotRun,\n reason: \"the claim names a test nobody has run\".into(),\n reproduce: Some(\"bash test/run.sh 07_scope\".into()),\n};\nassert_eq!(f.state, ProofState::NotRun);\n```",
"properties": {
"claim": {
"description": "The claim.",
"type": "string"
},
"reason": {
"description": "Why this is a finding.",
"type": "string"
},
"reproduce": {
"description": "What to run, when running something would settle it.",
"type": [
"string",
"null"
]
},
"state": {
"$ref": "#/$defs/ProofState",
"description": "What the evidence supports."
},
"status": {
"description": "What the claim says it is.",
"type": "string"
}
},
"required": [
"claim",
"status",
"state",
"reason"
],
"type": "object"
},
"EvidenceLedgerSummary": {
"description": "What the ledger is and whether it is there at all.\n\nA report that did not say where its evidence came from would be asking to be believed.\nThis is the provenance of the whole report: the file, how much it holds, how old the\nnewest entry is, and which commits anything was ever recorded against.\n\n```\nuse majordomus_cli::evidence::{Ledger, LedgerSummary, LEDGER_PATH};\n\nlet summary: LedgerSummary = Ledger::empty().summary();\nassert_eq!(summary.path, LEDGER_PATH);\nassert!(!summary.present, \"a ledger holding nothing has recorded nothing\");\nassert_eq!(summary.executions, 0);\nassert!(summary.newest.is_none());\nassert!(summary.commits.is_empty());\n```\n# Example\n\n```\nuse majordomus_cli::evidence::LedgerSummary;\nlet s = LedgerSummary {\n path: \".ai/repo/evidence/ledger.json\".into(),\n present: false,\n executions: 0,\n newest: None,\n commits: vec![],\n};\nassert!(!s.present, \"a repository that recorded nothing says so\");\n```",
"properties": {
"commits": {
"description": "The distinct commits its executions were recorded against. Always emitted, empty\nincluded, for the reason `ClaimProof::changed` is.",
"items": {
"type": "string"
},
"type": "array"
},
"executions": {
"description": "How many executions it holds.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"newest": {
"description": "The newest `at` in it, when it holds any.",
"type": [
"string",
"null"
]
},
"path": {
"description": "Where it lives, repository-relative.",
"type": "string"
},
"present": {
"description": "Whether the ledger holds at least one execution.\n\nNot whether the file exists. A ledger file holding nothing and no ledger file at\nall are the same answer to the only question a reader is asking — has anything\nbeen recorded — and both make every claim read `not_run`. `Ledger::present`\nanswers the filesystem question, and nothing derives a proof state from it.",
"type": "boolean"
}
},
"required": [
"path",
"present",
"executions",
"commits"
],
"type": "object"
},
"EvidenceOrigin": {
"description": "Where a run happened. The canonical model is provider-neutral: a CI adapter records\n`Ci`, and nothing here knows or cares which CI it was.\n\n```\nuse majordomus_cli::evidence::Origin;\n\nassert_eq!(Origin::parse(\"CI\"), Some(Origin::Ci));\nassert_eq!(Origin::parse(\"local\"), Some(Origin::Local));\n// naming the provider is the adapter's business; the ledger records the kind of run,\n// so a repository that changes CI does not change what its old evidence says\nassert!(Origin::parse(\"github-actions\").is_none());\n```\n# Example\n\n```\nuse majordomus_cli::evidence::Origin;\nassert_eq!(Origin::parse(\"ci\"), Some(Origin::Ci));\nassert_eq!(Origin::parse(\"nowhere\"), None);\n```",
"oneOf": [
{
"const": "local",
"description": "Someone ran it on their own machine.",
"type": "string"
},
{
"const": "ci",
"description": "A continuous-integration run.",
"type": "string"
},
{
"const": "release",
"description": "A release run.",
"type": "string"
}
]
},
"EvidenceOutcome": {
"description": "What a run said about one test.\n\n`NotRun` is deliberately absent: it is the absence of an execution, not an outcome one\nhad. Encoding it here would let a recorder write \"this did not run\" and have it counted\namong the things that did.\n\n```\nuse majordomus_cli::evidence::Outcome;\n\nassert!(Outcome::parse(\"ok\").proves());\nassert!(!Outcome::parse(\"timeout\").proves());\n// exactly one of the five is evidence of anything; the other four are reasons there\n// is none, kept apart because \"it declined\" and \"the harness broke\" are different bugs\nassert_eq!(Outcome::parse(\"skipped\"), Outcome::Skip);\nassert_eq!(Outcome::parse(\"nonsense\"), Outcome::Error);\n```\n# Example\n\n```\nuse majordomus_cli::evidence::Outcome;\nassert!(Outcome::parse(\"ok\").proves());\nassert_eq!(Outcome::parse(\"wat\"), Outcome::Error);\n```",
"oneOf": [
{
"const": "pass",
"description": "It passed.",
"type": "string"
},
{
"const": "fail",
"description": "It failed.",
"type": "string"
},
{
"const": "skip",
"description": "It declined to run and said so (an unmet precondition the case reports itself).",
"type": "string"
},
{
"const": "timeout",
"description": "The bound fired before it finished.",
"type": "string"
},
{
"const": "error",
"description": "The harness could not run it at all.",
"type": "string"
}
]
},
"EvidencePresentedRevision": {
"description": "What a report was judged at: the revision, its tree, and the runs the checkout holds that\nthe revision's own ledger does not.\n\nA verdict is always a verdict at something. `evidence show` judges the working tree;\n`evidence show --presented HEAD` judges the checked-out commit as committed, from the\nledger committed in it — which is the reading a site built from that commit needs.\n\n```\nuse majordomus_cli::evidence::{PresentedRevision, TreeState};\n\nlet here = PresentedRevision {\n revision: \"working_tree\".into(),\n tree: TreeState::Dirty,\n uncommitted: vec![],\n};\nlet json = serde_json::to_value(&here).unwrap();\nassert_eq!(json[\"tree\"], \"dirty\");\n// nothing held uncommitted is absent, not an empty list to read past\nassert!(json.get(\"uncommitted\").is_none());\n```",
"properties": {
"revision": {
"description": "`working_tree`, or the full id of the commit judged as committed.",
"type": "string"
},
"tree": {
"$ref": "#/$defs/EvidenceTreeState",
"description": "Whether that revision's tree was its commit: for the working tree, the checkout's\nstate; for a commit, the checkout measured ignoring the ledger's working copy and\nweakened by anything the caller knew."
},
"uncommitted": {
"description": "The tests whose execution in the working copy of the ledger the presented commit's\nledger does not hold, sorted. Read only to withhold `proven`, never to decide a\nverdict; always empty for the working tree, whose ledger is itself the authority.",
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"revision",
"tree"
],
"type": "object"
},
"EvidenceRun": {
"description": "The continuous-integration run an execution was recorded in: enough to navigate back to\nthe run that produced it.\n\n`Origin` says what kind of run it was and deliberately names no provider. This names the\none run, in the words the provider addressed it with when it happened — its identifier,\nits attempt, the workflow and job, and the address a reader follows — because a link built\nlater from a template would point wherever the template's idea of the provider had drifted\nto. Only an adapter constructs it; nothing in the model reads the provider's name.\n\n```\nuse majordomus_cli::evidence::RunRef;\n\nlet actions = |k: &str| {\n let v = match k {\n \"GITHUB_ACTIONS\" => \"true\",\n \"GITHUB_SERVER_URL\" => \"https://github.com\",\n \"GITHUB_REPOSITORY\" => \"owner/repo\",\n \"GITHUB_RUN_ID\" => \"42\",\n \"GITHUB_RUN_ATTEMPT\" => \"2\",\n \"GITHUB_WORKFLOW\" => \"validate\",\n \"GITHUB_JOB\" => \"evidence\",\n _ => return None,\n };\n Some(v.to_string())\n};\nlet run = RunRef::from_env(actions).unwrap();\nassert_eq!(run.id, \"42\");\nassert_eq!(run.attempt, 2);\nassert_eq!(run.url, \"https://github.com/owner/repo/actions/runs/42/attempts/2\");\n// a run that names neither its pull request's head nor its event still names itself\nassert_eq!((run.head_sha, run.event), (None, None));\n\nlet head = \"0123456789abcdef0123456789abcdef01234567\";\nlet pull = |k: &str| match k {\n \"MJ_RUN_HEAD_SHA\" => Some(head.to_string()),\n \"GITHUB_EVENT_NAME\" => Some(\"pull_request\".to_string()),\n _ => actions(k),\n};\nlet run = RunRef::from_env(pull).unwrap();\nassert_eq!(run.head_sha.as_deref(), Some(head));\nassert_eq!(run.event.as_deref(), Some(\"pull_request\"));\n\n// outside a run there is nothing to name, and a half-described run is not a run\nassert!(RunRef::from_env(|_| None).is_none());\nassert!(RunRef::from_env(|k| (k == \"GITHUB_ACTIONS\").then(|| \"true\".to_string())).is_none());\n```",
"properties": {
"attempt": {
"description": "Which attempt of the run, counted from 1.",
"format": "uint32",
"minimum": 0,
"type": "integer"
},
"event": {
"description": "The event that started the run: `push`, `pull_request`, `schedule`,\n`workflow_dispatch`.",
"type": [
"string",
"null"
]
},
"head_sha": {
"description": "The pull request's head commit when the run was a pull-request run (its `commit` is\nGitHub's merge commit, the tree that ran). Carried beside the commit, never\nsubstituted for it.",
"type": [
"string",
"null"
]
},
"id": {
"description": "The provider's identifier of the run.",
"type": "string"
},
"job": {
"description": "The job within the run that recorded the execution.",
"type": "string"
},
"provider": {
"description": "The provider that ran it, as the adapter that recorded it names it.",
"type": "string"
},
"url": {
"description": "Where a reader finds the run, as the provider addressed it at the time.",
"type": "string"
},
"workflow": {
"description": "The workflow the run belongs to.",
"type": "string"
}
},
"required": [
"provider",
"id",
"attempt",
"workflow",
"job",
"url"
],
"type": "object"
},
"EvidenceRunner": {
"description": "Which runner produced a result, and therefore how the test is named and re-run.\n\nThe repository has exactly two that a claim may name today. A third would be a variant\nhere and a branch in `TestId::of`; a claim naming something neither runner produces is\nreported as `ProofState::Unrunnable` rather than silently counted as covered.\n\n```\nuse majordomus_cli::evidence::{Runner, TestId};\n\n// which runner owns a test is read off where the test lives, never declared\nassert_eq!(TestId::of(\"test/cases/07_scope.sh\").unwrap().runner, Runner::Suite);\nassert_eq!(\n TestId::of(\"apps/majordomus-cli/tests/why.rs\").unwrap().runner,\n Runner::Crate\n);\n// and a path under neither directory belongs to no runner at all\nassert!(TestId::of(\"test/lib.sh\").is_none());\n```\n# Example\n\n```\nuse majordomus_cli::evidence::Runner;\nassert_eq!(Runner::Suite.prefix(), \"suite\");\nassert_eq!(Runner::Crate.prefix(), \"crate\");\n```",
"oneOf": [
{
"const": "suite",
"description": "A behavioural case under `test/cases/`, run by `test/run.sh`.",
"type": "string"
},
{
"const": "crate",
"description": "An integration test binary under `apps/majordomus-cli/tests/`, run by `cargo test`.",
"type": "string"
}
]
},
"EvidenceSubject": {
"description": "Whether the report could see its whole subject.\n\nA verdict over a matrix the index silently shrank is the failure this repository met\nfour times in one day: an object is excluded, every projection of the smaller index is a\nfaithful projection, and each check prints a true statement about the half it can see.\nA freshness check answers \"was this generated from this tree\" and cannot answer \"did the\ngenerator see everything in it\", so the answer has to carry its own denominator.\n\n```\nuse majordomus_cli::evidence::Subject;\nlet whole = Subject { examined: 149, complete: true, excluded: vec![] };\nassert!(whole.complete);\n\nlet partial = Subject {\n examined: 148,\n complete: false,\n excluded: vec![\"docs/CLAIMS.yaml: unknown_key\".into()],\n};\nassert!(!partial.complete, \"a shrunken index must not report a clean verdict\");\n```",
"properties": {
"complete": {
"description": "Whether the index that produced them carried no error diagnostic. When this is\nfalse, every count and every absence below is about a smaller world than the\nrepository, and no verdict over it means what it says.",
"type": "boolean"
},
"examined": {
"description": "How many claims the index held, and this report therefore examined.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"excluded": {
"description": "The diagnostics that excluded something, when any did: `<path>: <code>`.",
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"examined",
"complete",
"excluded"
],
"type": "object"
},
"EvidenceTreeState": {
"description": "Whether a tree was the commit it sits on: the three words the ledger and git already\nuse, typed.\n\n`unknown` is not a softer `clean`. It is what is recorded when git could not be asked,\nand not knowing is not proof, so every rule here treats it as not clean.\n\n```\nuse majordomus_cli::evidence::freshness::TreeState;\n\nassert_eq!(TreeState::parse(\"clean\"), TreeState::Clean);\nassert_eq!(TreeState::parse(\"dirty\"), TreeState::Dirty);\n// a word nobody wrote down is not a clean tree\nassert_eq!(TreeState::parse(\"spotless\"), TreeState::Unknown);\nassert_eq!(TreeState::Dirty.as_str(), \"dirty\");\nassert_eq!(serde_json::to_value(TreeState::Unknown).unwrap(), \"unknown\");\n```",
"oneOf": [
{
"const": "clean",
"description": "The tree was the commit: nothing but the evidence ledger differed from it.",
"type": "string"
},
{
"const": "dirty",
"description": "Something other than the evidence ledger differed from the commit.",
"type": "string"
},
{
"const": "unknown",
"description": "Git could not be asked, or the word recorded is none of the three.",
"type": "string"
}
]
},
"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": "The whole joined picture: every claim of the matrix against every execution recorded.\n\nWhat the capability answers, what the gate judges and what the site renders are this one\nvalue; the totals and the findings are derived from the claims, never counted twice.\n\n```\nuse majordomus_cli::evidence::{\n EvidenceReport, Finding, Ledger, PresentedRevision, ProofState, Subject, TreeState,\n};\n\nlet mut report = EvidenceReport {\n head: None,\n working_tree: \"unknown\".into(),\n presented: PresentedRevision {\n revision: \"working_tree\".into(),\n tree: TreeState::Unknown,\n uncommitted: vec![],\n },\n ledger: Ledger::empty().summary(),\n subject: Subject { examined: 0, complete: true, excluded: vec![] },\n claims: vec![],\n totals: Default::default(),\n findings: vec![],\n};\nassert!(report.satisfied(), \"nothing claimed, so nothing unsupported\");\n\n// and the same report over a subject it could not wholly read is not a pass\nlet mut partial = report.clone();\npartial.subject.complete = false;\nassert!(!partial.satisfied(), \"an absent answer is not a clean one\");\n\nreport.findings.push(Finding {\n claim: \"scope-integrity\".into(),\n status: \"guaranteed\".into(),\n state: ProofState::Failing,\n reason: \"the claim guarantees a behaviour whose test most recently failed\".into(),\n reproduce: None,\n});\n// one unsupported guarantee is enough: the gate is not a proportion\nassert!(!report.satisfied());\n```\n# Example\n\nThe whole matrix joined to the ledger. `satisfied` is true when no claim declares a\nguarantee the recorded evidence does not support.\n\n```\nuse majordomus_cli::evidence::{report, EvidenceReport, Ledger};\nuse majordomus_cli::synthetic::SyntheticRepository;\nlet repo = SyntheticRepository::small().unwrap();\nlet ledger = Ledger::load(repo.root()).unwrap();\nlet r: EvidenceReport = report(&repo.index().unwrap(), &ledger);\nassert!(r.satisfied(), \"no claim, so no unsupported guarantee\");\n```",
"properties": {
"claims": {
"description": "Every claim, in the matrix's own order.",
"items": {
"$ref": "#/$defs/EvidenceClaimProof"
},
"type": "array"
},
"findings": {
"description": "Claims whose declared status the evidence does not support.",
"items": {
"$ref": "#/$defs/EvidenceFinding"
},
"type": "array"
},
"head": {
"description": "The commit the report was derived against.",
"type": [
"string",
"null"
]
},
"ledger": {
"$ref": "#/$defs/EvidenceLedgerSummary",
"description": "The ledger this was joined against."
},
"presented": {
"$ref": "#/$defs/EvidencePresentedRevision",
"description": "What the verdicts are about: the working tree, or the checked-out commit judged as\ncommitted."
},
"subject": {
"$ref": "#/$defs/EvidenceSubject",
"description": "What the report could reach. Read this before reading the tallies: they are counts\nover the claims the index held, and an index that dropped a file holds fewer."
},
"totals": {
"additionalProperties": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"description": "How many claims are in each state.",
"type": "object"
},
"working_tree": {
"description": "`clean`, `dirty` or `unknown`.",
"type": "string"
}
},
"required": [
"working_tree",
"presented",
"ledger",
"subject",
"claims",
"totals",
"findings"
],
"title": "EvidenceReport",
"type": "object"
}Policies
- benchmark
- required — a target on every transport the exposure declares; the cases are the input type's
- cache
- checkout — up to 8 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.
| transport | state | cases | targets |
|---|---|---|---|
| direct | covered | 2 | all cold+warm findings cold+warm |
| mcp | covered | 2 | all cold+warm findings cold+warm |
| http | covered | 2 | all cold+warm findings cold+warm |
Claims implemented beside it
Attached by the file that implements each claim; every one links to its page with the implementation and the test that proves it.