convergence.report
Every holding of this repository with its disposition, the evidence read for it and the command that would move it out of danger, the tallies per disposition, how many holdings exist on one disk only, and the one verdict over them. Read from git on every call: a commit, a push or an editor's save changes the answer between two calls.
Every holding of this repository with its disposition, the evidence read for it and the command that would move it out of danger, the tallies per disposition, how many holdings exist on one disk only, and the one verdict over them. Read from git on every call: a commit, a push or an editor's save changes the answer between two calls.
- query
- behaviorally_verified
- module convergence
- #convergence
- #git
- #worktree
- #integration
Exposure
Where this one definition is reachable. Absence is explicit: a surface not listed does not carry it.
| surface | as |
|---|---|
| MCP | tool majordomus_convergence resource majordomus://convergence |
| HTTP | GET /api/v1/convergence operationId convergence.report |
| command line | majordomus convergence |
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 · ConvergenceReport
use majordomus_cli::convergence::{ConvergenceReport, SCHEMA};
let empty = ConvergenceReport {
schema: SCHEMA.into(),
repository: "/tmp/r".into(),
trunk: Some("master".into()),
holdings: vec![],
tallies: Default::default(),
at_risk: 0,
converged: true,
};
// the verdict is the one word a gate reads; the count is what a person reads next to it
assert!(empty.converged && empty.at_risk == 0);
assert_eq!(serde_json::to_value(&empty).unwrap()["schema"], "convergence/v1");| property | type | required | description |
|---|---|---|---|
| at_risk | integer | yes | The holdings that exist on one disk only. |
| converged | boolean | yes | Nothing is held where it can be lost. |
| holdings | array | yes | Every holding, at-risk ones first, then by kind and identity. |
| repository | string | yes | The primary checkout this was measured from. |
| schema | string | yes | SCHEMA. |
| tallies | object | yes | How many holdings carry each disposition, by its word. |
| trunk | string | null | no | The trunk the containment was decided against, when there is one. |
JSON Schema
{
"$defs": {
"Disposition": {
"description": "Where the work a holding carries can be reached from.\n\nThe order is the order of safety: everything above `Disposition::LocalOnly` is\nreachable by somebody who is not the worker that made it.\n\n```\nuse majordomus_cli::convergence::Disposition;\n\n// declared in the order of safety, so the derived order says which is worse\nassert!(Disposition::Integrated < Disposition::Published);\nassert!(Disposition::Published < Disposition::LocalOnly);\nassert_eq!(serde_json::to_string(&Disposition::LocalOnly).unwrap(), \"\\\"local_only\\\"\");\n```",
"oneOf": [
{
"const": "integrated",
"description": "The trunk reaches it: it is in the repository's own history.",
"type": "string"
},
{
"const": "published",
"description": "A remote reaches it: another checkout can fetch it, and it survives this disk.",
"type": "string"
},
{
"const": "local_only",
"description": "Committed here and nowhere else. One disk away from being lost.",
"type": "string"
},
{
"const": "uncommitted",
"description": "Not committed at all: files in a work tree, or a stash entry.",
"type": "string"
}
]
},
"Holding": {
"description": "One thing holding work, and what is known about where that work can be reached from.\n\n```\nuse majordomus_cli::convergence::{Disposition, Holding, HoldingKind};\n\nlet branch = Holding {\n kind: HoldingKind::Branch,\n identity: \"feature/x\".into(),\n disposition: Disposition::LocalOnly,\n evidence: \"abc123 is on no remote-tracking ref of this checkout\".into(),\n remedy: \"git push -u origin feature/x\".into(),\n at_risk: true,\n};\n// an at-risk holding always carries the command that would move it out of danger\nassert!(branch.at_risk && !branch.remedy.is_empty());\n// and a reachable one carries none, so the field is left out of the document\nlet safe = Holding { disposition: Disposition::Published, remedy: String::new(), at_risk: false, ..branch };\nassert!(!serde_json::to_string(&safe).unwrap().contains(\"remedy\"));\n```",
"properties": {
"at_risk": {
"description": "This holding's work exists on one disk only.",
"type": "boolean"
},
"disposition": {
"$ref": "#/$defs/Disposition",
"description": "Where the work can be reached from."
},
"evidence": {
"description": "What was actually read — never a restatement of the disposition.",
"type": "string"
},
"identity": {
"description": "How it is named: a branch name, an absolute worktree path, a stash ref.",
"type": "string"
},
"kind": {
"$ref": "#/$defs/HoldingKind",
"description": "What kind of thing holds it."
},
"remedy": {
"description": "The command that would move it out of danger. Empty when it is not at risk.",
"type": "string"
}
},
"required": [
"kind",
"identity",
"disposition",
"evidence",
"at_risk"
],
"type": "object"
},
"HoldingKind": {
"description": "What kind of thing is holding the work.\n\n```\nuse majordomus_cli::convergence::HoldingKind;\n\n// the word a report and a persisted record use; renaming a variant must not rename it\nassert_eq!(HoldingKind::Worktree.as_str(), \"worktree\");\nassert_eq!(serde_json::to_string(&HoldingKind::Stash).unwrap(), \"\\\"stash\\\"\");\n```",
"oneOf": [
{
"const": "worktree",
"description": "A registered work tree, holding files that are not committed.",
"type": "string"
},
{
"const": "branch",
"description": "A local branch, holding commits.",
"type": "string"
},
{
"const": "stash",
"description": "An entry of `git stash`.",
"type": "string"
}
]
}
},
"description": "The repository's convergence: every holding, and the one verdict over them.\n\n```\nuse majordomus_cli::convergence::{ConvergenceReport, SCHEMA};\n\nlet empty = ConvergenceReport {\n schema: SCHEMA.into(),\n repository: \"/tmp/r\".into(),\n trunk: Some(\"master\".into()),\n holdings: vec![],\n tallies: Default::default(),\n at_risk: 0,\n converged: true,\n};\n// the verdict is the one word a gate reads; the count is what a person reads next to it\nassert!(empty.converged && empty.at_risk == 0);\nassert_eq!(serde_json::to_value(&empty).unwrap()[\"schema\"], \"convergence/v1\");\n```",
"properties": {
"at_risk": {
"description": "The holdings that exist on one disk only.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"converged": {
"description": "Nothing is held where it can be lost.",
"type": "boolean"
},
"holdings": {
"description": "Every holding, at-risk ones first, then by kind and identity.",
"items": {
"$ref": "#/$defs/Holding"
},
"type": "array"
},
"repository": {
"description": "The primary checkout this was measured from.",
"type": "string"
},
"schema": {
"description": "`SCHEMA`.",
"type": "string"
},
"tallies": {
"additionalProperties": {
"format": "uint",
"minimum": 0,
"type": "integer"
},
"description": "How many holdings carry each disposition, by its word.",
"type": "object"
},
"trunk": {
"description": "The trunk the containment was decided against, when there is one.",
"type": [
"string",
"null"
]
}
},
"required": [
"schema",
"repository",
"holdings",
"tallies",
"at_risk",
"converged"
],
"title": "ConvergenceReport",
"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.