layout.check
Every path a declared layout excludes, named with the contract it violates: a tracked file under the tracked half that git's ignore rules match (state that does not travel, under a contract that excludes cache or runtime), and a file under the local half that is a byte copy of a tracked canonical file or declares the schema of a kind share/kinds.yaml calls canonical (under the manifest's `local.excludes: [canonical]`). Only what a contract declares is judged. Reads git and the local half's files; no build and no network.
Every path a declared layout excludes, named with the contract it violates: a tracked file under the tracked half that git's ignore rules match (state that does not travel, under a contract that excludes cache or runtime), and a file under the local half that is a byte copy of a tracked canonical file or declares the schema of a kind share/kinds.yaml calls canonical (under the manifest's `local.excludes: [canonical]`). Only what a contract declares is judged. Reads git and the local half's files; no build and no network.
- query
- behaviorally_verified
- module layout
- #layout
- #governance
- #two-folder
Exposure
Where this one definition is reachable. Absence is explicit: a surface not listed does not carry it.
| surface | as |
|---|---|
| MCP | tool majordomus_layout_check |
| HTTP | GET /api/v1/layout/check operationId layout.check |
| command line | majordomus layout check |
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 · Empty
No properties: the capability takes no input.
JSON Schema
{
"additionalProperties": false,
"description": "No input.",
"title": "Empty",
"type": "object"
}output · LayoutReport
use majordomus_cli::layout::LayoutReport;
let clean = LayoutReport::of(true, None, 12, Vec::new());
assert!(clean.passes);
assert_eq!(clean.checked, 12);
let unread = LayoutReport::of(false, Some("git could not start".into()), 0, Vec::new());
assert!(!unread.passes, "nothing found because nothing was read");
assert_eq!(unread.reason.as_deref(), Some("git could not start"));| property | type | required | description |
|---|---|---|---|
| checked | integer | yes | How many paths were judged. |
| findings | array | yes | Every path a contract excludes, in canonical order. Empty is the passing answer. |
| measured | boolean | yes | Whether the halves could be read at all. false is not a pass. |
| passes | boolean | yes | true when the halves were read and nothing was found. |
| reason | string | null | no | Why they could not, when they could not. |
JSON Schema
{
"$defs": {
"LayoutFinding": {
"description": "One misplaced artifact: a path found in a half whose declared layout excludes it, with the\ncontract that excludes it and why, so a refusal names what to move and where it belongs.\n\nIt travels as the JSON of the `layout.check` capability, so its member names are the\nwire contract every projection reads:\n\n```\nuse majordomus_cli::layout::LayoutFinding;\nlet finding = LayoutFinding {\n path: \".ai/local/notes/rule.md\".into(),\n contract: \"manifest local\".into(),\n excludes: \"canonical\".into(),\n reason: \"a copy of .ai/repo/rules/rule.md\".into(),\n};\nlet json = serde_json::to_value(&finding).unwrap();\nassert_eq!(json[\"contract\"], \"manifest local\");\nassert_eq!(json[\"excludes\"], \"canonical\");\nlet back: LayoutFinding = serde_json::from_value(json).unwrap();\nassert_eq!(back, finding);\n```",
"properties": {
"contract": {
"description": "The contract it violates: a context document's id, or `manifest local`.",
"type": "string"
},
"excludes": {
"description": "What the contract excludes that this path is.",
"type": "string"
},
"path": {
"description": "The path, repository-relative.",
"type": "string"
},
"reason": {
"description": "What the path was found to be, and how.",
"type": "string"
}
},
"required": [
"path",
"contract",
"excludes",
"reason"
],
"type": "object"
}
},
"description": "The answer of the layout check: whether the halves were read, how many paths were\njudged, and every path a contract excludes. A report that could not read the halves\nnever passes, so silence about a tree nobody measured cannot read as a clean tree.\n\n```\nuse majordomus_cli::layout::LayoutReport;\nlet clean = LayoutReport::of(true, None, 12, Vec::new());\nassert!(clean.passes);\nassert_eq!(clean.checked, 12);\nlet unread = LayoutReport::of(false, Some(\"git could not start\".into()), 0, Vec::new());\nassert!(!unread.passes, \"nothing found because nothing was read\");\nassert_eq!(unread.reason.as_deref(), Some(\"git could not start\"));\n```",
"properties": {
"checked": {
"description": "How many paths were judged.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"findings": {
"description": "Every path a contract excludes, in canonical order. Empty is the passing answer.",
"items": {
"$ref": "#/$defs/LayoutFinding"
},
"type": "array"
},
"measured": {
"description": "Whether the halves could be read at all. `false` is not a pass.",
"type": "boolean"
},
"passes": {
"description": "`true` when the halves were read and nothing was found.",
"type": "boolean"
},
"reason": {
"description": "Why they could not, when they could not.",
"type": [
"string",
"null"
]
}
},
"required": [
"measured",
"checked",
"findings",
"passes"
],
"title": "LayoutReport",
"type": "object"
}Policies
- benchmark
- required — a target on every transport the exposure declares; the cases are the input type's
- cache
- disabled — every call runs the handler
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.