gates.model
Každá validační kontrola, kterou tento repozitář deklaruje — job, který ji spouští, příkaz, který spouští, co dokazuje, zda ji vybírá každý plán a zda lze její runner vůbec získat na požádání — s třídami cest, které rozhodují, která změna vybírá kterou kontrolu, a pathspecy, nad kterými se berou důkazy každé kontroly, odvozenými z těchto tříd.
Každá validační kontrola, kterou tento repozitář deklaruje — job, který ji spouští, příkaz, který spouští, co dokazuje, zda ji vybírá každý plán a zda lze její runner vůbec získat na požádání — s třídami cest, které rozhodují, která změna vybírá kterou kontrolu, a pathspecy, nad kterými se berou důkazy každé kontroly, odvozenými z těchto tříd.
- query
- behaviorally_verified
- moduly gates
- #gates
- #ci
- #completion
- #introspection
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_gates zdroj majordomus://gates |
| HTTP | GET /api/v1/gates operationId gates.model |
| 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 · GateModelReport
Dvě věci o této zprávě je dobré vědět, než se přečte. count se měří z gates, ne zapisuje, takže se obojí nikdy nemůže rozejít tak, jak se rozchází ručně udržovaný součet. A unreadable je způsob, jak čtenář pozná „tento repozitář nedeklaruje žádný model CI“ od „volání selhalo“: repozitář vrstvy není povinen deklarovat kontroly, takže prázdný model je odpověď a říká, proč je prázdný.
use majordomus_cli::capability::builtin::gates::GateModelReport;
use serde_json::json;
// the shape every surface serves: `unreadable` is skipped when the model was read
let r: GateModelReport = serde_json::from_value(json!({
"version": 1,
"source": ".ai/repo/ci/gates.yaml",
"count": 0,
"on_demand": [],
"gates": [],
"classes": [],
})).unwrap();
assert_eq!(r.count, r.gates.len(), "the total is measured, never declared");
assert!(r.unreadable.is_none(), "read, and it declares nothing");
// and the other empty answer, which a reader must not confuse with that one
let absent: GateModelReport = serde_json::from_value(json!({
"version": 0,
"source": ".ai/repo/ci/gates.yaml",
"count": 0,
"on_demand": [],
"gates": [],
"classes": [],
"unreadable": "no such file",
})).unwrap();
assert_eq!(absent.unreadable.as_deref(), Some("no such file"));| vlastnost | typ | povinné | popis |
|---|---|---|---|
| třídy | array | ano | Každá třída cest v pořadí deklarace. |
| počet | integer | ano | Kolik kontrol deklaruje; změřeno, ne napsáno. |
| kontroly | array | ano | Každá kontrola v pořadí deklarace s pathspecy, nad nimiž se berou její důkazy. |
| on_demand | array | ano | Kontroly, jejichž runner nelze mít na požádání, takže je žádný rutinní plán nevybírá. Kontrola, která nikdy neběží, nic nechrání, a tady se to říká nahlas. |
| zdroj | string | ano | Odkud byl přečten, relativně k repozitáři. |
| nečitelné | string | null | ne | Proč není co hlásit, když žádný model neexistuje. Repozitář vrstvy nemusí deklarovat model CI a čtenář má nárok na rozdíl mezi „tento repozitář nedeklaruje žádné kontroly“ a „toto volání selhalo“. |
| verze | integer | ano | Verze schématu, kterou soubor uvádí. |
JSON Schema
{
"$defs": {
"GateClass": {
"description": "```\nuse majordomus_cli::gates::GateClass;\n\n// one path class as the CI model declares it: which paths select which gates\nlet class: GateClass = serde_json::from_value(serde_json::json!({\n \"id\": \"docs\",\n \"paths\": [\"docs/**\"],\n \"gates\": [\"reference-check\"]\n}))\n.unwrap();\nassert_eq!(class.id, \"docs\");\nassert_eq!(class.paths, [\"docs/**\"]);\n```\nOne path class: the paths it covers and the gates a change to them selects.",
"properties": {
"except": {
"default": [],
"description": "Single paths its patterns cover and the class does not: a data file under an\nescalating directory, read by named gates only. Each one is a path, never a\npattern, so a file that appears under the directory tomorrow still falls in it.",
"items": {
"type": "string"
},
"type": "array"
},
"gates": {
"anyOf": [
{
"$ref": "#/$defs/GateClassSelects"
},
{
"type": "null"
}
],
"default": null,
"description": "`full`, or the gates it names."
},
"id": {
"description": "The class's identity.",
"type": "string"
},
"paths": {
"default": [],
"description": "The pathspecs it covers, in the subset the model's header defines.",
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"id"
],
"type": "object"
},
"GateClassSelects": {
"anyOf": [
{
"description": "`gates: full` — any change in this class escalates the whole plan.",
"type": "string"
},
{
"description": "`gates: [a, b]` — exactly these, and `gates: []` — nothing.",
"items": {
"type": "string"
},
"type": "array"
}
],
"description": "What a class selects: the word `full`, or the gates it names."
},
"GateModelEntry": {
"description": "```\nuse majordomus_cli::capability::builtin::gates::GateModelEntry;\nuse majordomus_cli::gates::GateDecl;\n\nlet decl: GateDecl = serde_json::from_value(serde_json::json!({\n \"id\": \"site-check\",\n \"job\": \"site\",\n \"runs\": \"scripts/site-check\",\n \"summary\": \"the site is whole\"\n}))\n.unwrap();\nlet entry = GateModelEntry { declared: decl, inputs: vec![\"site/**\".into()] };\n// the declaration as the file carries it, plus the paths its evidence is taken over —\n// derived from the classes that select it, never written down a second time\nassert_eq!(entry.declared.id, \"site-check\");\nassert_eq!(entry.inputs, [\"site/**\"]);\n```\nOne gate of the model, with what the model implies about it.",
"properties": {
"always": {
"default": false,
"description": "True when every plan selects it, whatever changed.",
"type": "boolean"
},
"at-finish": {
"default": false,
"description": "True when the gate measures the deployment rather than the tree, so no change to\nany file can select it and the path classes can never reach it. `finish` asks it\ninstead: the question \"is what the public is being served still a projection of\nthe trunk\" has no answer a commit can give, and its moment is when a session\nclaims to be done.",
"type": "boolean"
},
"id": {
"description": "The gate's identity, unique in the model.",
"type": "string"
},
"implies": {
"default": [],
"description": "Gates that are selected whenever this one is.",
"items": {
"type": "string"
},
"type": "array"
},
"inputs": {
"description": "The pathspecs a run of this gate is evidence over, derived from the classes that\nselect it. A change to any of them makes a recorded run stale.",
"items": {
"type": "string"
},
"type": "array"
},
"job": {
"description": "The CI job that runs it.",
"type": "string"
},
"on-demand": {
"default": false,
"description": "True when only a plan that asks for it selects it: its runner cannot be had on\ndemand, so planning it on every push is planning a verdict that never arrives.",
"type": "boolean"
},
"requires": {
"default": [],
"description": "Gates this one cannot run without.",
"items": {
"type": "string"
},
"type": "array"
},
"runs": {
"description": "The command it runs.",
"type": "string"
},
"summary": {
"default": "",
"description": "One line saying what it proves.",
"type": "string"
}
},
"required": [
"id",
"job",
"runs",
"inputs"
],
"type": "object"
}
},
"description": "The CI model this repository declares: what may refuse a change, and what selects each.\n\nTwo things about this report are worth knowing before reading one. `count` is measured\nfrom `gates` rather than written down, so the two can never disagree the way a\nhand-maintained total does. And `unreadable` is how a reader tells \"this repository\ndeclares no CI model\" from \"the call failed\": a repository of the layer is not obliged\nto declare gates, so the empty model is an answer, and it says why it is empty.\n\n```\nuse majordomus_cli::capability::builtin::gates::GateModelReport;\nuse serde_json::json;\n\n// the shape every surface serves: `unreadable` is skipped when the model was read\nlet r: GateModelReport = serde_json::from_value(json!({\n \"version\": 1,\n \"source\": \".ai/repo/ci/gates.yaml\",\n \"count\": 0,\n \"on_demand\": [],\n \"gates\": [],\n \"classes\": [],\n})).unwrap();\nassert_eq!(r.count, r.gates.len(), \"the total is measured, never declared\");\nassert!(r.unreadable.is_none(), \"read, and it declares nothing\");\n\n// and the other empty answer, which a reader must not confuse with that one\nlet absent: GateModelReport = serde_json::from_value(json!({\n \"version\": 0,\n \"source\": \".ai/repo/ci/gates.yaml\",\n \"count\": 0,\n \"on_demand\": [],\n \"gates\": [],\n \"classes\": [],\n \"unreadable\": \"no such file\",\n})).unwrap();\nassert_eq!(absent.unreadable.as_deref(), Some(\"no such file\"));\n```",
"properties": {
"classes": {
"description": "Every path class, in declaration order.",
"items": {
"$ref": "#/$defs/GateClass"
},
"type": "array"
},
"count": {
"description": "How many gates it declares; measured, not written down.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"gates": {
"description": "Every gate, in declaration order, with the pathspecs its evidence is taken over.",
"items": {
"$ref": "#/$defs/GateModelEntry"
},
"type": "array"
},
"on_demand": {
"description": "The gates whose runner cannot be had on demand, so no routine plan selects them.\nA gate that never runs protects nothing, and this is where that is said out loud.",
"items": {
"type": "string"
},
"type": "array"
},
"source": {
"description": "Where it was read from, repository-relative.",
"type": "string"
},
"unreadable": {
"description": "Why there is no model to report, when there is none. A repository of the layer does\nnot have to declare a CI model, and a reader is entitled to the difference between\n\"this repository declares no gates\" and \"this call failed\".",
"type": [
"string",
"null"
]
},
"version": {
"description": "The schema version the file states.",
"format": "uint32",
"minimum": 0,
"type": "integer"
}
},
"required": [
"version",
"source",
"count",
"on_demand",
"gates",
"classes"
],
"title": "GateModelReport",
"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ž 4 položky v procesu, každá 5 s, v rozsahu otisku 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.