release.analysis
Veřejný povrch schopností tohoto stromu proti tomu, který publikoval poslední release, každý jeho pohyb pojmenovaný s důvodem, proč se počítá tak, jak se počítá, a nejmenší verze, kterou tento strom smí proto deklarovat. Úroveň kompatibility se měří z kontraktu, ne čte z předmětů commitů: schopnost, trasa, nástroj MCP, příkaz nebo povinné pole kteréhokoli ze dvou schémat, které volající mohl držet a už nemůže, je zásadní změna, ať se commit, který je odstranil, nazval jakkoli. Co o sobě commity řekly, se nese vedle verdiktu jako důkaz a odpověď říká, kdy se obojí rozchází.
Veřejný povrch schopností tohoto stromu proti tomu, který publikoval poslední release, každý jeho pohyb pojmenovaný s důvodem, proč se počítá tak, jak se počítá, a nejmenší verze, kterou tento strom smí proto deklarovat. Úroveň kompatibility se měří z kontraktu, ne čte z předmětů commitů: schopnost, trasa, nástroj MCP, příkaz nebo povinné pole kteréhokoli ze dvou schémat, které volající mohl držet a už nemůže, je zásadní změna, ať se commit, který je odstranil, nazval jakkoli. Co o sobě commity řekly, se nese vedle verdiktu jako důkaz a odpověď říká, kdy se obojí rozchází.
- query
- implementováno
- module release
- #release
- #version
- #compatibility
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_release_analysis |
| HTTP | GET /api/v1/release/analysis operationId release.analysis |
| 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 · ReleaseAnalysisInput
use majordomus_cli::capability::builtin::release::AnalysisInput;
// Absent means the last release the layer records, which is the canonical baseline.
let input = AnalysisInput::default();
assert!(input.since.is_none());
let explicit = AnalysisInput { since: Some("v0.4.0".into()) };
assert_eq!(explicit.since.as_deref(), Some("v0.4.0"));| vlastnost | typ | povinné | popis |
|---|---|---|---|
| od | string | null | ne | Ref, se kterým porovnávat místo posledního release: v0.4.0 nebo jakýkoli commit, který nese commitnutý registr. |
JSON Schema
{
"additionalProperties": false,
"description": "Which release to measure this tree against.\n\n```\nuse majordomus_cli::capability::builtin::release::AnalysisInput;\n// Absent means the last release the layer records, which is the canonical baseline.\nlet input = AnalysisInput::default();\nassert!(input.since.is_none());\nlet explicit = AnalysisInput { since: Some(\"v0.4.0\".into()) };\nassert_eq!(explicit.since.as_deref(), Some(\"v0.4.0\"));\n```",
"properties": {
"since": {
"description": "A ref to compare with instead of the last release: `v0.4.0`, or any commit that\ncarries a committed registry.",
"type": [
"string",
"null"
]
}
},
"title": "ReleaseAnalysisInput",
"type": "object"
}výstup · ReleaseVersionPlan
Jedna hodnota, kterou vykresluje každý povrch — příkazový řádek, /api/v1/release/analysis, nástroj MCP, panel Cockpitu, vygenerovaný dokument i kontrola CI. Nikde neexistuje druhý výpočet, což je vlastnost, díky níž číslo něco znamená.
use majordomus_cli::release::compat::{Status, VersionPlan};
#### use majordomus_cli::release::compat::{Baseline, CommitEvidence, Impact, Policy};
#### use majordomus_cli::release::version::Version;
let plan = VersionPlan {
policy: Policy::for_version(Version::parse("0.5.0").unwrap()),
baseline: Baseline {
version: "0.5.0".into(), reference: "v0.5.0".into(), read_at: "3a032c1e".into(),
commit: "3a032c1e".into(), recorded: true, atoms: 300, fingerprint: "sha256:a".into(),
},
declared_version: "0.5.0".into(),
tool_version: "0.5.0".into(),
writers_agree: true,
atoms: 333,
fingerprint: "sha256:b".into(),
implied: Impact::Minor,
required: Impact::Minor,
declared: Impact::None,
required_version: "0.6.0".into(),
status: Status::Blocked,
breaking: false,
changes: Vec::new(),
commits: CommitEvidence { commits: 24, implied: Impact::Patch, breaking: Vec::new() },
understated: true,
diagnostics: Vec::new(),
};
// The contract requires a minor and the version declares none: this tree may not land.
assert_eq!(plan.status, Status::Blocked);
assert!(plan.declared < plan.required);
assert!(plan.understated, "the commit subjects claim less than the contract did");| vlastnost | typ | povinné | popis |
|---|---|---|---|
| atomy | integer | ano | Kolik veřejných atomů tento strom nese. |
| baseline | reference | ano | Release, vůči kterému se měřilo. |
| zpětně nekompatibilní | boolean | ano | Zda zmizelo něco, co mohl volající držet. |
| změny | array | ano | Každý pohyb kontraktu, od nejhoršího. |
| commity | reference | ano | Co o sobě commity řekly. |
| deklarováno | reference | ano | Co již ta dvě čísla verzí představují. |
| declared_version | string | ano | Verze, kterou deklaruje manifest crate — jediné místo, kde se tvoří. |
| diagnostika | array | ne | Cokoli nekoherentního na stavu release, ať je verdikt jakýkoli. |
| otisk | string | ano | Otisk povrchu tohoto stromu. |
| implikováno | reference | ano | Co samotný posun povrchu představuje. |
| policy | reference | ano | Politika, za které bylo dosaženo verdiktu. |
| povinné | reference | ano | Co od toho politika vyžaduje. |
| required_version | string | ano | Nejmenší verze, kterou tento strom smí deklarovat. |
| status | reference | ano | Zda ano. |
| tool_version | string | ano | Verze, kterou vypisuje bin/majordomus: to, co uvádí její projekce, share/version.txt. |
| podhodnoceno | boolean | ano | Zda předměty commitů podhodnocují to, co smlouva skutečně udělala. |
| writers_agree | boolean | ano | Zda je tato projekce aktuální — uvádí, co manifest deklaruje. Název zůstal z doby, kdy měla verze dva zapisovatele; nyní je jediným manifest. |
JSON Schema
{
"$defs": {
"ReleaseBaseline": {
"description": "The release this tree is measured against, and how it was found.\n\n```\nuse majordomus_cli::release::compat::Baseline;\nlet baseline = Baseline {\n version: \"0.5.0\".into(),\n reference: \"v0.5.0\".into(),\n read_at: \"3a032c1e033b\".into(),\n commit: \"3a032c1e033b\".into(),\n recorded: true,\n atoms: 300,\n fingerprint: \"sha256:…\".into(),\n};\n// `recorded` is the half that matters: a baseline taken from a tag alone is reported.\nassert!(baseline.recorded);\nassert_eq!(baseline.reference, \"v0.5.0\");\n```",
"properties": {
"atoms": {
"description": "How many public atoms it published.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"commit": {
"description": "The commit that ref resolved to.",
"type": "string"
},
"fingerprint": {
"description": "The fingerprint of the surface it published.",
"type": "string"
},
"read_at": {
"description": "The ref the surface was actually read from — the commit the release record names,\nwhich a clone always has, rather than a tag it may not.",
"type": "string"
},
"recorded": {
"description": "Whether the layer holds a release record for it, which is what makes it canonical\nrather than the newest thing that looked like a tag.",
"type": "boolean"
},
"reference": {
"description": "`v0.5.0`: the release, as a reader recognises it.",
"type": "string"
},
"version": {
"description": "`0.5.0`.",
"type": "string"
}
},
"required": [
"version",
"reference",
"read_at",
"commit",
"recorded",
"atoms",
"fingerprint"
],
"type": "object"
},
"ReleaseChangeDirection": {
"description": "Whether a change added, removed or altered part of the contract.\n\n```\nuse majordomus_cli::release::compat::Direction;\nassert_eq!(Direction::Removed.sign(), '-');\n```",
"oneOf": [
{
"const": "added",
"description": "It was not there before.",
"type": "string"
},
{
"const": "removed",
"description": "It was there before and is not now.",
"type": "string"
},
{
"const": "changed",
"description": "It is there in both, and differs.",
"type": "string"
}
]
},
"ReleaseCommitEvidence": {
"description": "What the commit subjects since the baseline said about themselves.\n\nEvidence, never authority. It is here so that a person can see the human account and the\nmeasured one side by side, and so that `VersionPlan::understated` can say when the two\ndisagree — which is the case this whole subsystem exists to catch.\n\n```\nuse majordomus_cli::release::compat::{CommitEvidence, Impact};\nlet commits = CommitEvidence {\n commits: 24,\n implied: Impact::Patch,\n breaking: Vec::new(),\n};\n// The contract moved by a minor and the subjects claim a patch: the plan reports that\n// disagreement rather than deferring to the words.\nassert!(commits.implied < Impact::Minor);\n```",
"properties": {
"breaking": {
"description": "The subjects of the ones that claimed to be breaking.",
"items": {
"type": "string"
},
"type": "array"
},
"commits": {
"description": "How many commits since the baseline.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"implied": {
"$ref": "#/$defs/ReleaseImpact",
"description": "What their conventional-commit types alone would have implied."
}
},
"required": [
"commits",
"implied"
],
"type": "object"
},
"ReleaseDiagnostic": {
"description": "Something about the release state that a person should be told, whatever the verdict.\n\n```\nuse majordomus_cli::release::compat::{Diagnostic, Severity};\nlet d = Diagnostic {\n id: \"tag-without-record\".into(),\n severity: Severity::Warning,\n message: \"v0.1.0 is tagged and the layer holds no release record for it\".into(),\n};\nassert_eq!(d.severity, Severity::Warning, \"a warning states the plan still stands\");\n```",
"properties": {
"id": {
"description": "`tag-without-record`, `tag-predates-records`, `record-without-tag`,\n`tag-commit-mismatch`.",
"type": "string"
},
"message": {
"description": "What is wrong, in one sentence.",
"type": "string"
},
"severity": {
"$ref": "#/$defs/ReleaseSeverity",
"description": "Whether it stops a release, only warns, or only informs."
}
},
"required": [
"id",
"severity",
"message"
],
"type": "object"
},
"ReleaseImpact": {
"description": "How much a change moves the contract.\n\nOrdered, so that \"the declared bump covers what is required\" is a comparison rather than\na table:\n\n```\nuse majordomus_cli::release::compat::Impact;\nassert!(Impact::Major > Impact::Minor);\nassert!(Impact::Minor > Impact::Patch);\nassert!(Impact::Patch > Impact::None);\n```",
"oneOf": [
{
"const": "none",
"description": "The contract did not move.",
"type": "string"
},
{
"const": "patch",
"description": "It moved behind the boundary: a caller cannot tell.",
"type": "string"
},
{
"const": "minor",
"description": "Something arrived; every existing caller still works.",
"type": "string"
},
{
"const": "major",
"description": "Something a caller could hold is gone or changed under it.",
"type": "string"
}
]
},
"ReleasePolicy": {
"description": "The compatibility policy, named and versioned.\n\n```\nuse majordomus_cli::release::compat::{Impact, Policy, POLICY_SCHEMA};\nuse majordomus_cli::release::version::Version;\nlet policy = Policy::for_version(Version::parse(\"0.5.0\").unwrap());\nassert_eq!(policy.schema, POLICY_SCHEMA, \"a verdict carries the rules it was reached under\");\nassert_eq!(policy.required_of(Impact::Major), Impact::Minor);\n```",
"properties": {
"mode": {
"$ref": "#/$defs/ReleasePolicyMode",
"description": "Which rule is in force, decided by the baseline version alone."
},
"schema": {
"description": "`majordomus/version-policy/v1`.",
"type": "string"
}
},
"required": [
"schema",
"mode"
],
"type": "object"
},
"ReleasePolicyMode": {
"description": "How this project turns a measured impact into the version it owes.\n\nSemantic versioning hands `0.y.z` a blanket exemption — \"anything MAY change at any\ntime\" — and Elm refuses the exemption by starting every package at `1.0.0`, because a\nrule with an escape hatch is a rule about when to use the hatch. This repository is `0.x`\nand has not earned `1.0.0`, so neither answer is available: demanding `major` would\ndemand `1.0.0` for a single removal, and granting the exemption would let a breaking\nchange ship as a patch.\n\nSo below `1.0.0` the floor is a minor. Any movement of the surface, gone or new, is at\nleast a minor release; only an unchanged surface owes nothing. That is the strongest\nsignal `0.x` has, and a removal is still *named* as breaking whatever the verdict, so the\nevidence does not quietly become a minor along with the number.\n\nAt `1.0.0` the shift ends: `Mode::Semver` is the ordinary rule, and the transition is\none line of `Policy::required_of`.\n\n```\nuse majordomus_cli::release::compat::{Mode, Policy};\nuse majordomus_cli::release::version::Version;\nassert_eq!(Policy::for_version(Version::parse(\"0.9.0\").unwrap()).mode, Mode::Pre1_0Strict);\nassert_eq!(Policy::for_version(Version::parse(\"1.0.0\").unwrap()).mode, Mode::Semver);\n```",
"oneOf": [
{
"const": "pre1-0-strict",
"description": "Below `1.0.0`: breaking changes are allowed, and cost a minor rather than nothing.",
"type": "string"
},
{
"const": "semver",
"description": "At or above `1.0.0`: the impact is the requirement.",
"type": "string"
}
]
},
"ReleaseSeverity": {
"description": "How much a diagnostic matters.\n\nAn error says the plan itself cannot be trusted and blocks the verdict; a warning says\nsomething about the release state is wrong and the verdict stands anyway; a note says\nsomething true and not wrong, so that the warnings keep meaning what they say.\n\n```\nuse majordomus_cli::release::compat::Severity;\nassert_ne!(Severity::Error, Severity::Warning);\nassert_ne!(Severity::Warning, Severity::Note);\n```",
"oneOf": [
{
"const": "error",
"description": "The plan cannot be trusted; the verdict is blocked.",
"type": "string"
},
{
"const": "warning",
"description": "The plan stands, and something is still wrong.",
"type": "string"
},
{
"const": "note",
"description": "Nothing is wrong; the reader is told something about the release state anyway.",
"type": "string"
}
]
},
"ReleaseStatus": {
"description": "Whether the tree may land or ship as it stands.\n\n```\nuse majordomus_cli::release::compat::Status;\nassert_ne!(Status::Ok, Status::Blocked);\n```",
"oneOf": [
{
"const": "ok",
"description": "The declared version covers what the contract did.",
"type": "string"
},
{
"const": "blocked",
"description": "It does not, and the plan says by how much.",
"type": "string"
}
]
},
"ReleaseSurfaceChange": {
"description": "One movement of the public contract, with the reason it counts for what it does.\n\n```\nuse majordomus_cli::release::compat::{Direction, Impact, SurfaceChange, SurfaceKind};\nlet change = SurfaceChange {\n impact: Impact::Major,\n direction: Direction::Removed,\n surface: SurfaceKind::Http,\n capability: \"alpha.list\".into(),\n id: \"GET /api/v1/alpha\".into(),\n detail: \"the capability survives; this way of reaching it does not\".into(),\n};\nassert_eq!(change.to_string(), \"- route GET /api/v1/alpha\");\n```",
"properties": {
"capability": {
"description": "The capability it belongs to.",
"type": "string"
},
"detail": {
"description": "Why this impact and not a smaller one, in one clause.",
"type": "string"
},
"direction": {
"$ref": "#/$defs/ReleaseChangeDirection",
"description": "Added, removed, or altered."
},
"id": {
"description": "The thing itself: `GET /api/v1/foo`, `majordomus_release_analysis`, `release.analysis`.",
"type": "string"
},
"impact": {
"$ref": "#/$defs/ReleaseImpact",
"description": "How much it moves the contract on its own."
},
"surface": {
"$ref": "#/$defs/ReleaseSurfaceKind",
"description": "Which promise it is."
}
},
"required": [
"impact",
"direction",
"surface",
"capability",
"id",
"detail"
],
"type": "object"
},
"ReleaseSurfaceKind": {
"description": "Which projection of the contract a change is in.\n\nNot where it was *found* — everything here is found in the registry — but which promise\nit is, so that a reader sees \"a route is gone\" rather than a JSON pointer.\n\n```\nuse majordomus_cli::release::compat::SurfaceKind;\nassert_eq!(SurfaceKind::Http.as_str(), \"route\");\n```",
"oneOf": [
{
"const": "capability",
"description": "The capability itself.",
"type": "string"
},
{
"const": "kind",
"description": "Whether calling it changes anything.",
"type": "string"
},
{
"const": "mcp_tool",
"description": "An MCP tool name.",
"type": "string"
},
{
"const": "mcp_resource",
"description": "An MCP resource URI.",
"type": "string"
},
{
"const": "http",
"description": "An HTTP method and path.",
"type": "string"
},
{
"const": "cli",
"description": "A command-line path.",
"type": "string"
},
{
"const": "input",
"description": "What a caller may send.",
"type": "string"
},
{
"const": "output",
"description": "What a caller is promised back.",
"type": "string"
}
]
}
},
"description": "The whole answer: what moved, what that requires, and what the tree declares.\n\nOne value, and every surface renders it — the command line, `/api/v1/release/analysis`,\nthe MCP tool, the Cockpit panel, the generated document and the CI gate. There is no\nsecond computation anywhere, which is the property that makes the number mean something.\n\n```\nuse majordomus_cli::release::compat::{Status, VersionPlan};\n# use majordomus_cli::release::compat::{Baseline, CommitEvidence, Impact, Policy};\n# use majordomus_cli::release::version::Version;\nlet plan = VersionPlan {\n policy: Policy::for_version(Version::parse(\"0.5.0\").unwrap()),\n baseline: Baseline {\n version: \"0.5.0\".into(), reference: \"v0.5.0\".into(), read_at: \"3a032c1e\".into(),\n commit: \"3a032c1e\".into(), recorded: true, atoms: 300, fingerprint: \"sha256:a\".into(),\n },\n declared_version: \"0.5.0\".into(),\n tool_version: \"0.5.0\".into(),\n writers_agree: true,\n atoms: 333,\n fingerprint: \"sha256:b\".into(),\n implied: Impact::Minor,\n required: Impact::Minor,\n declared: Impact::None,\n required_version: \"0.6.0\".into(),\n status: Status::Blocked,\n breaking: false,\n changes: Vec::new(),\n commits: CommitEvidence { commits: 24, implied: Impact::Patch, breaking: Vec::new() },\n understated: true,\n diagnostics: Vec::new(),\n};\n// The contract requires a minor and the version declares none: this tree may not land.\nassert_eq!(plan.status, Status::Blocked);\nassert!(plan.declared < plan.required);\nassert!(plan.understated, \"the commit subjects claim less than the contract did\");\n```",
"properties": {
"atoms": {
"description": "How many public atoms this tree carries.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"baseline": {
"$ref": "#/$defs/ReleaseBaseline",
"description": "The release this was measured against."
},
"breaking": {
"description": "Whether anything a caller could hold is gone.",
"type": "boolean"
},
"changes": {
"description": "Every movement of the contract, worst first.",
"items": {
"$ref": "#/$defs/ReleaseSurfaceChange"
},
"type": "array"
},
"commits": {
"$ref": "#/$defs/ReleaseCommitEvidence",
"description": "What the commits said about themselves."
},
"declared": {
"$ref": "#/$defs/ReleaseImpact",
"description": "What the two version numbers already represent."
},
"declared_version": {
"description": "The version the crate manifest declares — the one place it is authored.",
"type": "string"
},
"diagnostics": {
"description": "Anything incoherent about the release state, whatever the verdict.",
"items": {
"$ref": "#/$defs/ReleaseDiagnostic"
},
"type": "array"
},
"fingerprint": {
"description": "The fingerprint of this tree's surface.",
"type": "string"
},
"implied": {
"$ref": "#/$defs/ReleaseImpact",
"description": "What the surface movement amounts to on its own."
},
"policy": {
"$ref": "#/$defs/ReleasePolicy",
"description": "The policy the verdict was reached under."
},
"required": {
"$ref": "#/$defs/ReleaseImpact",
"description": "What the policy requires of it."
},
"required_version": {
"description": "The smallest version this tree may declare.",
"type": "string"
},
"status": {
"$ref": "#/$defs/ReleaseStatus",
"description": "Whether it does."
},
"tool_version": {
"description": "The version `bin/majordomus` prints: what its projection, `share/version.txt`, states.",
"type": "string"
},
"understated": {
"description": "Whether the commit subjects understate what the contract actually did.",
"type": "boolean"
},
"writers_agree": {
"description": "Whether that projection is current — states what the manifest declares. The name is\nkept from when the version had two writers; the manifest is the only one now.",
"type": "boolean"
}
},
"required": [
"policy",
"baseline",
"declared_version",
"tool_version",
"writers_agree",
"atoms",
"fingerprint",
"implied",
"required",
"declared",
"required_version",
"status",
"breaking",
"changes",
"commits",
"understated"
],
"title": "ReleaseVersionPlan",
"type": "object"
}Politiky
- benchmark
- waived — prominuto: published_history
- cache
- vypnuto — každé volání spustí handler
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.
| transport | state | případy | targets |
|---|---|---|---|
| direct | prominuto (published_history) | 0 | |
| mcp | prominuto (published_history) | 0 | |
| http | prominuto (published_history) | 0 |