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
rules.show
What proves this rule
What it is
One rule with its full proof: the validator and the cases it names, the execution behind each, the gates that run them, the rules it depends on and the rules that depend on it — each with the state it is in, because a rule is proven only as far as its dependencies are — and, when it is not proven, the one sentence saying what would have to be true for it to be. A rule this repository does not declare is a not-found rather than an empty answer, because a typo that read as 'this rule has no proof' is the one answer this capability must never give.
Descriptor
- Canonical id
rules.show- Module
rules- Kind
- query
- Stability
- behaviorallyverified
- Provenance
- declaredcached
- Source
apps/majordomus-cli/src/capability/builtin/rules.rs- Cache
process, 32 entries, per checkout state- Benchmark
required- Tags
- rulesgovernanceverificationevidence
Run
queryA query. It reads and changes nothing.
Projections
| Interface | As | Where |
|---|---|---|
| MCP tool | majordomus_rule | - |
| MCP resource | not exposed | - |
| HTTP | GET /api/v1/rules/rule | Swagger |
| Command line | majordomus rules show | - |
Schemas
Input · RuleInput
{
"type": "object",
"additionalProperties": false,
"properties": {
"rule": {
"type": "string",
"description": "The rule id, with or without its version: `project.scope-is-declared`, or the\nidentity the index holds."
}
},
"required": [
"rule"
],
"description": "One rule of the corpus.\n# Example\n\nOne rule of the corpus, named by its id or by the identity the index holds; a client\nthat has either spelling should not need to know the other.\n\n```\nuse majordomus_cli::capability::builtin::rules::RuleInput;\nlet i = RuleInput { rule: \"project.scope-is-declared\".into() };\nassert_eq!(i.rule, \"project.scope-is-declared\");\n```",
"title": "RuleInput"
}Output · RuleDetail
{
"type": "object",
"properties": {
"proof": {
"$ref": "#/$defs/RuleProof",
"description": "The rule, joined to the tree and the ledger."
},
"depends_on": {
"type": "array",
"items": {
"$ref": "#/$defs/RuleSummary"
},
"description": "The rules this one depends on, with the state each is in — a rule whose dependency\nis unproven is proven only as far as that dependency is."
},
"required_by": {
"type": "array",
"items": {
"$ref": "#/$defs/RuleSummary"
},
"description": "The rules that depend on this one."
},
"missing": {
"type": [
"string",
"null"
],
"description": "What would have to be true for this rule to reach `proven`, in words, or nothing\nwhen it is there already."
}
},
"required": [
"proof",
"depends_on",
"required_by"
],
"description": "One rule, with everything that proves it and everything that depends on it.\n# Example\n\nWhat `rules show` answers: the proof, the rules either side of it in the dependency\ngraph, and the one sentence saying what would make it proven.\n\n```\nuse majordomus_cli::capability::builtin::rules::RuleSummary;\nuse majordomus_cli::rules::{Class, RuleState};\n// a RuleDetail carries these summaries for depends_on and required_by\nlet dep = RuleSummary {\n id: \"project.dep\".into(), title: \"Dep\".into(),\n class: Class::Blocking, state: RuleState::NotRun,\n};\nassert_eq!(dep.class, Class::Blocking);\n```",
"title": "RuleDetail",
"$defs": {
"RuleProof": {
"type": "object",
"properties": {
"rule": {
"$ref": "#/$defs/RuleDefinition",
"description": "The canonical definition."
},
"validator": {
"anyOf": [
{
"$ref": "#/$defs/RuleValidator"
},
{
"type": "null"
}
],
"description": "The validator, when the mode is dispatched."
},
"tests": {
"type": "array",
"items": {
"$ref": "#/$defs/RuleTestProof"
},
"description": "Every test the rule names, joined to the ledger."
},
"gates": {
"type": "array",
"items": {
"type": "string"
},
"description": "Every CI gate that runs something this rule names, deduplicated."
},
"required_by": {
"type": "array",
"items": {
"type": "string"
},
"description": "The rules that depend on this one, by id — the converse of `depends_on`, which no\nrule declares and which a reader always wants."
},
"state": {
"$ref": "#/$defs/RuleState",
"description": "What the repository can say, as a whole."
},
"meaning": {
"type": "string",
"description": "That state, in one sentence."
},
"satisfied": {
"type": "boolean",
"description": "Whether the state is one this rule's class can live with."
}
},
"required": [
"rule",
"state",
"meaning",
"satisfied"
],
"description": "One rule, joined to everything the repository can show about it.\n# Example\n\nA `RuleProof` is what `report` produces per rule; `satisfied` is whether the state\nsupports the class the rule declares, which is the whole question.\n\n```\nuse majordomus_cli::rules::{report, RuleProof, RuleState};\nuse majordomus_cli::evidence::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 first: &RuleProof = &r.rules[0];\nassert_eq!(first.state, RuleState::Unproven);\nassert!(first.satisfied, \"an advisory rule owes no executable proof\");\n```"
},
"RuleDefinition": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The rule id, `<namespace>.<stem>`, without the version."
},
"identity": {
"type": "string",
"description": "The identity the index holds, with the version."
},
"uri": {
"type": "string",
"description": "`majordomus://rule/<identity>`."
},
"version": {
"type": "integer",
"format": "uint64",
"minimum": 0,
"description": "The declared version."
},
"title": {
"type": "string",
"description": "The title."
},
"description": {
"type": [
"string",
"null"
],
"description": "The one-line description."
},
"statement": {
"type": [
"string",
"null"
],
"description": "The normative sentence."
},
"status": {
"type": "string",
"description": "`active`, or whatever else the front matter declares."
},
"class": {
"$ref": "#/$defs/RuleClass",
"description": "How strongly it binds."
},
"namespace": {
"type": "string",
"description": "Whether it came with the vendored package or belongs to this project."
},
"depends_on": {
"type": "array",
"items": {
"type": "string"
},
"description": "The rules it depends on, by id."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "The declared tags."
},
"path": {
"type": "string",
"description": "Repository-relative path of the rule object."
},
"enforcement": {
"$ref": "#/$defs/RuleEnforcement",
"description": "How it is enforced, as declared."
}
},
"required": [
"id",
"identity",
"uri",
"version",
"title",
"status",
"class",
"namespace",
"path",
"enforcement"
],
"description": "One rule, as the repository canonically declares it.\n# Example\n\nBuilt by `definitions` from the index rather than by hand. Its ordering is the one\nthe crate has, so a report over the same tree reads the same twice.\n\n```\nuse majordomus_cli::rules::{Class, RuleDefinition};\n# use majordomus_cli::rules::{Enforcement, Mode};\nlet d = RuleDefinition {\n id: \"project.scope-is-declared\".into(),\n identity: \"project.scope-is-declared@1\".into(),\n uri: \"majordomus://rule/project.scope-is-declared@1\".into(),\n version: 1,\n title: \"Scope is declared\".into(),\n description: None,\n statement: None,\n status: \"active\".into(),\n class: Class::Blocking,\n namespace: \"project\".into(),\n depends_on: vec![],\n tags: vec![],\n path: \".ai/repo/rules/project/scope-is-declared.v1.md\".into(),\n enforcement: Enforcement {\n mode: Mode::Declarative, validator: None, category: None, exit_code: None,\n enforced_by: None, tests: vec![], reviewed_because: None,\n },\n};\nassert_eq!(d.class, Class::Blocking);\n```"
},
"RuleClass": {
"oneOf": [
{
"type": "string",
"const": "blocking",
"description": "A gate refuses work that violates it."
},
{
"type": "string",
"const": "advisory",
"description": "Normative for whoever reads it; nothing refuses a violation."
},
{
"type": "string",
"const": "unknown",
"description": "The front matter declared no class, or one this repository does not know."
}
],
"description": "What a rule declares about how strongly it binds.\n\nThe repository has exactly two, and they are not severities on a scale: `blocking` means\na gate refuses the work, `advisory` means a reader is expected to have read it. A rule\nwhose front matter says neither is reported as `Class::Unknown` rather than defaulted,\nbecause guessing here is how a blocking rule quietly becomes advice.\n# Example\n\n```\nuse majordomus_cli::rules::Class;\nassert_eq!(Class::Blocking.label(), \"blocking\");\nassert_eq!(Class::parse(\"advisory\"), Class::Advisory);\n```"
},
"RuleEnforcement": {
"type": "object",
"properties": {
"mode": {
"$ref": "#/$defs/RuleMode",
"description": "Which of the two canonical modes, or neither."
},
"validator": {
"type": [
"string",
"null"
],
"description": "The validator the dispatcher calls, when the mode is dispatched."
},
"category": {
"type": [
"string",
"null"
],
"description": "The diagnostic category the validator reports under."
},
"exit_code": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "The exit code the validator uses to refuse."
},
"enforced_by": {
"type": [
"string",
"null"
],
"description": "Which boundary enforces it: the word the rule's own block uses."
},
"tests": {
"type": "array",
"items": {
"type": "string"
},
"description": "Every test the block names, in the order it names them."
},
"reviewed_because": {
"type": [
"string",
"null"
],
"description": "Why nothing executable can express this rule, when the mode is reviewed. Required\nthere: a declared exemption with no reason is the debt it exists to replace."
}
},
"required": [
"mode"
],
"description": "The enforcement block of a rule, read from `x-majordomus`.\n# Example\n\nRead from front matter rather than built by hand; this is the shape a gated rule\nproduces, and the mode is decided by what the block actually names.\n\n```\nuse majordomus_cli::rules::{Enforcement, Mode};\nlet e = Enforcement {\n mode: Mode::Gated,\n validator: None,\n category: None,\n exit_code: None,\n enforced_by: None,\n tests: vec![\"test/cases/07_scope.sh\".into()],\n reviewed_because: None,\n};\nassert_eq!(e.mode, Mode::Gated);\n```"
},
"RuleMode": {
"oneOf": [
{
"type": "string",
"const": "dispatched",
"description": "Names a validator the doctrine dispatcher calls at run time."
},
{
"type": "string",
"const": "gated",
"description": "Names behavioural cases and no validator; a gate runs them."
},
{
"type": "string",
"const": "reviewed",
"description": "Carries a reason why nothing executable can express it, and so declares that a\nreader enforces it. An honest declaration, not an absence: the reason *is* the\ndeclaration — there is no flag beside it, because a flag can be set and a reason\ncannot be set without writing one — it is counted apart from every executable mode,\nand it separates a rule nobody could automate from a rule nobody got round to."
},
{
"type": "string",
"const": "declarative",
"description": "Names neither. Correct for a rule nothing executable can express; a defect for a\nblocking one."
}
],
"description": "How a rule is enforced, as its own front matter declares it.\n# Example\n\n```\nuse majordomus_cli::rules::Mode;\nassert_eq!(Mode::Dispatched.label(), \"dispatched\");\nassert_eq!(Mode::Declarative.label(), \"declarative\");\n```"
},
"RuleValidator": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The name the rule declares, without the `mj_validate_` prefix."
},
"function": {
"type": "string",
"description": "The function the dispatcher calls."
},
"defined_in": {
"type": [
"string",
"null"
],
"description": "The file that defines it, when one does."
},
"present": {
"type": "boolean",
"description": "Whether anything in `lib/` defines it."
}
},
"required": [
"name",
"function",
"present"
],
"description": "The validator a dispatched rule names, and whether anything defines it.\n\nA validator is **not a path**. `validator: adr` names the shell function\n`mj_validate_adr`, which the doctrine dispatcher calls; the tool finds it by scanning\n`lib/`, exactly as `majordomus doctor` does. Reading it as a path is a mistake worth\nrecording here, because it is the one this type was introduced to fix: it makes every\ndispatched rule in the vendored package report as naming something that is not in the\ntree, which is the opposite of true — those are the best-enforced rules there are.\n# Example\n\n```\nuse majordomus_cli::rules::ValidatorRef;\nlet v = ValidatorRef {\n name: \"adr\".into(),\n function: \"mj_validate_adr\".into(),\n defined_in: Some(\"lib/adr.sh\".into()),\n present: true,\n};\nassert_eq!(v.function, \"mj_validate_adr\");\n```"
},
"RuleTestProof": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "The path the rule names."
},
"kind": {
"$ref": "#/$defs/RuleArtifactKind",
"description": "What drives it: a runner, a CI gate, or nothing."
},
"present": {
"type": "boolean",
"description": "Whether that path is in the tree."
},
"test": {
"type": [
"string",
"null"
],
"description": "The canonical test identity (`suite:<case>`, `crate:<binary>`), when a runner owns\nthe path. Absent means no runner drives it, so no run of it can ever be recorded."
},
"state": {
"$ref": "#/$defs/ProofState",
"description": "What the repository can say about this test's latest run."
},
"meaning": {
"type": "string",
"description": "That state, in one sentence, from the one place it is worded."
},
"execution": {
"anyOf": [
{
"$ref": "#/$defs/EvidenceExecution"
},
{
"type": "null"
}
],
"description": "The execution behind the state, when there is one."
},
"reproduce": {
"type": [
"string",
"null"
],
"description": "The command that runs this test again."
},
"gates": {
"type": "array",
"items": {
"type": "string"
},
"description": "The CI gates that run this test, derived from the repository's own CI model."
}
},
"required": [
"path",
"kind",
"present",
"state",
"meaning"
],
"description": "One test a rule names, joined to what was recorded against it.\n# Example\n\n```\nuse majordomus_cli::rules::{ArtifactKind, TestProof};\nuse majordomus_cli::evidence::ProofState;\nlet t = TestProof {\n path: \"test/cases/07_scope.sh\".into(),\n kind: ArtifactKind::Case,\n present: true,\n test: Some(\"suite:07_scope\".into()),\n state: ProofState::NotRun,\n meaning: ProofState::NotRun.meaning().into(),\n execution: None,\n reproduce: Some(\"bash test/run.sh 07_scope\".into()),\n gates: vec![\"shell-suite\".into()],\n};\nassert_eq!(t.kind, ArtifactKind::Case);\n```"
},
"RuleArtifactKind": {
"oneOf": [
{
"type": "string",
"const": "case",
"description": "A behavioural case a runner drives; executions of it are recorded."
},
{
"type": "string",
"const": "gate",
"description": "An executable check a CI gate runs as its own command, or a unit-test module the\ngate running the crate's `cargo test` compiles."
},
{
"type": "string",
"const": "unknown",
"description": "Neither. Nothing can run it, so nothing can ever record it."
}
],
"description": "What a path a rule names actually is, decided by what drives it rather than by where it\nsits.\n\nThe corpus names two kinds and this distinction is the difference between a verdict and\na mechanism. A **case** is driven by a runner, so an execution of it can be recorded and\nthe repository can show that it passed. A **gate** is an executable check a CI gate runs\nas its own command, or a unit-test module (`src/<module>/tests.rs`) the gate running the\ncrate's `cargo test` compiles: it refuses violations on every run, and this repository\nrecords no verdict for it, so what can be shown is the mechanism and not the result.\nAnything else a rule names is proof only in prose.\n# Example\n\n```\nuse majordomus_cli::rules::ArtifactKind;\nassert_eq!(ArtifactKind::Case.label(), \"case\");\nassert_eq!(ArtifactKind::Gate.label(), \"gate\");\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```"
},
"EvidenceExecution": {
"type": "object",
"properties": {
"test": {
"type": "string",
"description": "The test, in `TestId::as_string` form."
},
"runner": {
"$ref": "#/$defs/EvidenceRunner",
"description": "Which runner produced it."
},
"source": {
"type": "string",
"description": "The test's own source, repository-relative."
},
"outcome": {
"$ref": "#/$defs/EvidenceOutcome",
"description": "What it said."
},
"seconds": {
"type": "integer",
"format": "uint64",
"minimum": 0,
"description": "How long it took, in whole seconds."
},
"commit": {
"type": "string",
"description": "The full commit id the run was made against."
},
"working_tree": {
"type": "string",
"description": "`clean`, `dirty` or `unknown`: whether the tree the run measured was the commit."
},
"digest": {
"type": "string",
"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."
},
"at": {
"type": "string",
"description": "When it was recorded, RFC 3339, UTC."
},
"origin": {
"$ref": "#/$defs/EvidenceOrigin",
"description": "Where the run happened."
},
"command": {
"type": "string",
"description": "The exact command that runs this one test again."
},
"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."
}
},
"required": [
"test",
"runner",
"source",
"outcome",
"seconds",
"commit",
"working_tree",
"digest",
"at",
"origin",
"command"
],
"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```"
},
"EvidenceRunner": {
"oneOf": [
{
"type": "string",
"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`."
}
],
"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```"
},
"EvidenceOutcome": {
"oneOf": [
{
"type": "string",
"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."
}
],
"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```"
},
"EvidenceOrigin": {
"oneOf": [
{
"type": "string",
"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."
}
],
"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```"
},
"EvidenceRun": {
"type": "object",
"properties": {
"provider": {
"type": "string",
"description": "The provider that ran it, as the adapter that recorded it names it."
},
"id": {
"type": "string",
"description": "The provider's identifier of the run."
},
"attempt": {
"type": "integer",
"format": "uint32",
"minimum": 0,
"description": "Which attempt of the run, counted from 1."
},
"workflow": {
"type": "string",
"description": "The workflow the run belongs to."
},
"job": {
"type": "string",
"description": "The job within the run that recorded the execution."
},
"url": {
"type": "string",
"description": "Where a reader finds the run, as the provider addressed it at the time."
},
"head_sha": {
"type": [
"string",
"null"
],
"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."
},
"event": {
"type": [
"string",
"null"
],
"description": "The event that started the run: `push`, `pull_request`, `schedule`,\n`workflow_dispatch`."
}
},
"required": [
"provider",
"id",
"attempt",
"workflow",
"job",
"url"
],
"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```"
},
"RuleState": {
"oneOf": [
{
"type": "string",
"const": "proven",
"description": "Every artifact it names is present, and every test it names has a passing run that\nnothing has invalidated."
},
{
"type": "string",
"const": "inputs_unchanged",
"description": "Every artifact is present and every test passed, but at least one run is only\nun-invalidated rather than measured against this tree."
},
{
"type": "string",
"const": "stale",
"description": "A passing run exists, but something it is about has changed since."
},
{
"type": "string",
"const": "gated",
"description": "An executable gate runs what this rule names, on every CI run that selects it. The\nmechanism is in the tree and wired; no verdict for it is recorded here."
},
{
"type": "string",
"const": "failing",
"description": "The latest run of a test this rule names did not pass."
},
{
"type": "string",
"const": "not_run",
"description": "Every artifact is present, and no run of at least one named test was ever recorded."
},
{
"type": "string",
"const": "reviewed",
"description": "The rule declares, with a stated reason, that nothing executable can express it. An\nhonest exemption: counted apart from every proven rule, never counted as one."
},
{
"type": "string",
"const": "unrunnable",
"description": "The rule names a path no runner in this repository drives."
},
{
"type": "string",
"const": "dangling",
"description": "The rule names a path that is not in the tree. A proof that does not exist is worse\nthan no proof, because the rule reads as proven."
},
{
"type": "string",
"const": "unproven",
"description": "The rule names neither a validator nor a test. Correct for a rule nothing executable\ncan express; a defect for a blocking one."
}
],
"description": "What the repository can say about one rule's proof, as a whole.\n\nOrdered strongest to weakest so that a summary sorted by this reads as a ranking. A rule's\nstate is made from its parts' by `crate::evidence::freshness::aggregate`: a failing part\nmakes it failing, and otherwise the weakest part that can carry proof decides.\n# Example\n\n```\nuse majordomus_cli::rules::RuleState;\nassert!(RuleState::Proven < RuleState::Stale);\nassert!(RuleState::Stale.passing());\nassert!(!RuleState::Dangling.passing());\n```"
},
"RuleSummary": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The rule id."
},
"title": {
"type": "string",
"description": "The title."
},
"class": {
"$ref": "#/$defs/RuleClass",
"description": "How strongly it binds."
},
"state": {
"$ref": "#/$defs/RuleState",
"description": "What the repository can say about its proof."
}
},
"required": [
"id",
"title",
"class",
"state"
],
"description": "A rule named from somewhere else, with just enough to decide whether to follow it.\n# Example\n\n```\nuse majordomus_cli::capability::builtin::rules::RuleSummary;\nuse majordomus_cli::rules::{Class, RuleState};\nlet s = RuleSummary {\n id: \"project.x\".into(),\n title: \"X\".into(),\n class: Class::Advisory,\n state: RuleState::Reviewed,\n};\nassert_eq!(s.state, RuleState::Reviewed);\n```"
}
}
}Examples
These are the capability's own benchmark cases: the same inputs the benchmark runs and the OpenAPI document shows.
first
{
"rule": "majordomus.adr-integrity@1"
}