release.currency
How much landed work the trunk holds past the last release, since when, and at which version, measured when asked (I3070). The last release is the newer of the release the layer records and the newest version tag the trunk contains: a tag is pushed before its record lands. Landed work is every commit of the trunk past it except merges and release commits. A landing is a commit of the trunk's first-parent history, and the work has waited since the oldest landing that brought anything but release commits. The stance is current when nothing has landed past the release, owed when work has, and overdue once it has waited longer than six hours. The version the public contract requires is decided by the version selection release.version makes, but only from a recorded release and only in a checkout at the trunk; otherwise the answer says which it is not. Ask with next false to leave the version out, as the brief and doctor do. It reads git and the clock, so it is never committed into derived data.
How much landed work the trunk holds past the last release, since when, and at which version, measured when asked (I3070). The last release is the newer of the release the layer records and the newest version tag the trunk contains: a tag is pushed before its record lands. Landed work is every commit of the trunk past it except merges and release commits. A landing is a commit of the trunk's first-parent history, and the work has waited since the oldest landing that brought anything but release commits. The stance is current when nothing has landed past the release, owed when work has, and overdue once it has waited longer than six hours. The version the public contract requires is decided by the version selection release.version makes, but only from a recorded release and only in a checkout at the trunk; otherwise the answer says which it is not. Ask with next false to leave the version out, as the brief and doctor do. It reads git and the clock, so it is never committed into derived data.
- query
- implemented
- module release
- #release
- #version
- #delivery
Exposure
Where this one definition is reachable. Absence is explicit: a surface not listed does not carry it.
| surface | as |
|---|---|
| MCP | tool majordomus_release_currency |
| HTTP | GET /api/v1/release/currency operationId release.currency |
| command line | — |
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 · ReleaseCurrencyInput
release.currency: whether to decide the version as well.
use majordomus_cli::capability::builtin::release::CurrencyInput;
// the version is decided unless the caller says it does not need it
assert!(CurrencyInput::default().next());
assert!(!CurrencyInput { next: Some(false) }.next());| property | type | required | description |
|---|---|---|---|
| next | boolean | null | no | Whether to decide the version the public contract requires for the landed work, which reads the last release's registry: yes when absent. The brief and doctor say no. |
JSON Schema
{
"additionalProperties": false,
"description": "The input of `release.currency`: whether to decide the version as well.\n\n```\nuse majordomus_cli::capability::builtin::release::CurrencyInput;\n// the version is decided unless the caller says it does not need it\nassert!(CurrencyInput::default().next());\nassert!(!CurrencyInput { next: Some(false) }.next());\n```",
"properties": {
"next": {
"description": "Whether to decide the version the public contract requires for the landed work, which\nreads the last release's registry: yes when absent. The brief and doctor say no.",
"type": [
"boolean",
"null"
]
}
},
"title": "ReleaseCurrencyInput",
"type": "object"
}output · ReleaseCurrency
release.currency: whether the trunk's landed work is released.
use majordomus_cli::release::currency::{measure, Currency, Stance};
let nowhere = tempfile::tempdir().unwrap();
let answer: Currency = measure(nowhere.path(), &[], std::time::SystemTime::now());
// a directory with no trunk is not measured, and says why
assert_eq!(answer.stance, Stance::Unknown);
assert!(answer.summary.contains("trunk"), "{}", answer.summary);| property | type | required | description |
|---|---|---|---|
| changes | array | no | The landed changes, newest first, at most LISTED. |
| landed | integer | yes | Landed commits past the last release, merges and release commits left out. |
| landed_at | one of 2 | no | How oldest_landing was dated: when this clone saw it arrive
on the trunk, or its commit time as an upper bound on the wait. |
| landings | integer | yes | The landings of the trunk's first-parent history that brought them. |
| next | string | null | no | The version the public contract requires for the landed work (ADR 0051), when it was decided. |
| next_unmeasured | string | null | no | Why that version was not decided, when it was asked for and could not be. |
| oldest_landing | string | null | no | When the oldest of those landings landed, RFC 3339, dated as landed_at
says. |
| overdue_after_seconds | integer | yes | How long it may wait before it is overdue (OVERDUE_AFTER). |
| release | one of 2 | no | The last release. |
| stance | reference | yes | Whether the landed work is released. |
| summary | string | yes | The answer in one sentence: the brief's and doctor's line. |
| trunk | string | null | no | The remote-tracking ref of the trunk it was measured on (origin/master). |
| waited_seconds | integer | null | no | How long the work has waited since then, in seconds. |
JSON Schema
{
"$defs": {
"ReleaseChange": {
"description": "One change, from one commit.",
"properties": {
"breaking": {
"description": "Whether the commit marked itself breaking, with `!` or a `BREAKING CHANGE:` trailer.",
"type": "boolean"
},
"commit": {
"description": "The abbreviated commit.",
"type": "string"
},
"kind": {
"$ref": "#/$defs/ReleaseChangeKind",
"description": "What it did."
},
"references": {
"description": "The records of the layer this commit names — issues, milestones — resolved against\nwhat the layer actually holds.",
"items": {
"$ref": "#/$defs/ReleaseReference"
},
"type": "array"
},
"scope": {
"description": "The area it did it in, when the subject named one: `commands`, `ci`, `site`.",
"type": [
"string",
"null"
]
},
"subject": {
"description": "The subject, without the type and scope that prefixed it.",
"type": "string"
},
"url": {
"description": "Where that commit can be read, when the repository's own URL is known. Derived from\n`about::REPOSITORY`, never written beside each entry.",
"type": [
"string",
"null"
]
}
},
"required": [
"kind",
"subject",
"breaking",
"commit"
],
"type": "object"
},
"ReleaseChangeKind": {
"description": "What a conventional commit says it did.\n\nThe set is the one the repository's own commit convention uses; a commit whose subject\ndoes not parse is `ChangeKind::Other` and still appears, because a changelog that\nsilently drops what it cannot classify is a changelog that lies by omission.",
"oneOf": [
{
"const": "feat",
"description": "A capability a person did not have before.",
"type": "string"
},
{
"const": "fix",
"description": "Behaviour that was wrong and is not any more.",
"type": "string"
},
{
"const": "perf",
"description": "Performance, with the behaviour unchanged.",
"type": "string"
},
{
"const": "refactor",
"description": "Structure, with the behaviour unchanged.",
"type": "string"
},
{
"const": "docs",
"description": "Documentation.",
"type": "string"
},
{
"const": "test",
"description": "Tests.",
"type": "string"
},
{
"const": "chore",
"description": "The build, the pipeline, the tooling.",
"type": "string"
},
{
"const": "ci",
"description": "Continuous integration.",
"type": "string"
},
{
"const": "style",
"description": "Formatting, with the behaviour unchanged.",
"type": "string"
},
{
"const": "build",
"description": "The build system or its dependencies.",
"type": "string"
},
{
"const": "revert",
"description": "A change that undoes another.",
"type": "string"
},
{
"const": "merge",
"description": "An integration: one line of work brought into another.\n\nNot in the conventional-commit specification, and in this repository's history 38\ntimes and counting, because integration here is a deliberate act with a subject\nsomebody writes — `merge: bring origin/master into feature/x` — and not the sentence\n`git merge` composes. Declaring it is what lets the validator hold those subjects to\nthe same width and the same references as every other commit, instead of either\nrefusing a convention this project practises or exempting it from being checked at\nall. The changelog never renders it: `commits::in_range` reads the log with\n`--no-merges`, so a merge commit is not a release entry however its subject is\nspelled.",
"type": "string"
},
{
"const": "other",
"description": "A commit whose subject does not parse as a conventional commit.",
"type": "string"
}
]
},
"ReleaseCurrencyLandedAt": {
"description": "How the oldest landing was dated, and so which way its wait may be wrong (the plan\ncritique of 2026-10-19: a top lands by a fast-forward push hours after its commits).\n\n```\nuse majordomus_cli::release::currency::LandedAt;\nassert_eq!(serde_json::to_value(LandedAt::Reflog).unwrap(), \"reflog\");\nassert_eq!(serde_json::to_value(LandedAt::Commit).unwrap(), \"commit\");\n```",
"oneOf": [
{
"const": "reflog",
"description": "When this clone's remote-tracking trunk first held it, from that ref's reflog. A landing\nis seen no earlier than it lands, so the wait counted from here is a lower bound, and it\nis the one date that can make the stance overdue.",
"type": "string"
},
{
"const": "commit",
"description": "Its commit time, where the reflog does not show it arrive: a commit lands no earlier than\nit is made, so the wait counted from here is an upper bound, and it never makes the\nstance overdue by itself.",
"type": "string"
}
]
},
"ReleaseCurrencyRelease": {
"description": "The release the trunk is measured from.\n\n```\nuse majordomus_cli::release::currency::Released;\nlet tagged = Released {\n version: \"0.30.1\".into(),\n reference: \"v0.30.1\".into(),\n at: \"v0.30.1\".into(),\n recorded: false,\n};\n// a tag pushed before its record landed is read at the tag itself\nassert_eq!(tagged.at, tagged.reference);\n```",
"properties": {
"at": {
"description": "What the trunk is measured from: the commit its record names, else its tag.",
"type": "string"
},
"recorded": {
"description": "Whether the layer holds a record for it yet.",
"type": "boolean"
},
"reference": {
"description": "`v0.30.1`: the release as a reader recognises it.",
"type": "string"
},
"version": {
"description": "`0.30.1`.",
"type": "string"
}
},
"required": [
"version",
"reference",
"at",
"recorded"
],
"type": "object"
},
"ReleaseCurrencyStance": {
"description": "Whether the trunk's landed work is released.\n\n```\nuse majordomus_cli::release::currency::{Stance, OVERDUE_AFTER};\nuse std::time::Duration;\nassert_eq!(Stance::of(0, OVERDUE_AFTER), Stance::Current, \"nothing landed, nothing owed\");\nassert_eq!(Stance::of(2, Duration::from_secs(60)), Stance::Owed);\nassert_eq!(Stance::of(2, OVERDUE_AFTER), Stance::Overdue);\nassert_eq!(Stance::Overdue.as_str(), \"overdue\");\n```",
"oneOf": [
{
"const": "current",
"description": "Nothing has landed past the last release.",
"type": "string"
},
{
"const": "owed",
"description": "Work has landed past it, and has waited less than `OVERDUE_AFTER`.",
"type": "string"
},
{
"const": "overdue",
"description": "Work has landed past it, and has waited at least `OVERDUE_AFTER`.",
"type": "string"
},
{
"const": "unknown",
"description": "It could not be measured: no trunk, no release, or a release this clone cannot read.",
"type": "string"
}
]
},
"ReleaseReference": {
"description": "A record of the layer that a commit names in its own text.\n\nInferred, never declared beside the commit: an issue id or a milestone id appearing in a\nsubject or a body is a reference, and the layer already holds the object it refers to. A\nreference to something the layer does not have is not carried — a link to a record that\ndoes not exist is worse than no link, because the reader cannot tell until they follow it.\n\n```\nuse majordomus_cli::release::model::Reference;\nlet r = Reference {\n kind: \"issue\".into(),\n id: \"I1305\".into(),\n title: \"An observed contract has a fingerprint\".into(),\n route: Some(\"/plan/i1305/\".into()),\n};\nlet json = serde_json::to_value(&r).unwrap();\nassert_eq!(json[\"id\"], \"I1305\");\nassert_eq!(json[\"route\"], \"/plan/i1305/\");\n// a reference the site has no page for carries no route rather than an invented one\nlet bare = Reference { route: None, ..r };\nassert!(serde_json::to_value(&bare).unwrap().get(\"route\").is_none());\n```",
"properties": {
"id": {
"description": "`I1305`, `M000`.",
"type": "string"
},
"kind": {
"description": "`issue` or `milestone`.",
"type": "string"
},
"route": {
"description": "Where it is published on this site, when it has a page.",
"type": [
"string",
"null"
]
},
"title": {
"description": "What it is, from the record itself.",
"type": "string"
}
},
"required": [
"kind",
"id",
"title"
],
"type": "object"
}
},
"description": "The answer of `release.currency`: whether the trunk's landed work is released.\n\n```\nuse majordomus_cli::release::currency::{measure, Currency, Stance};\nlet nowhere = tempfile::tempdir().unwrap();\nlet answer: Currency = measure(nowhere.path(), &[], std::time::SystemTime::now());\n// a directory with no trunk is not measured, and says why\nassert_eq!(answer.stance, Stance::Unknown);\nassert!(answer.summary.contains(\"trunk\"), \"{}\", answer.summary);\n```",
"properties": {
"changes": {
"description": "The landed changes, newest first, at most `LISTED`.",
"items": {
"$ref": "#/$defs/ReleaseChange"
},
"type": "array"
},
"landed": {
"description": "Landed commits past the last release, merges and release commits left out.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"landed_at": {
"anyOf": [
{
"$ref": "#/$defs/ReleaseCurrencyLandedAt"
},
{
"type": "null"
}
],
"description": "How `oldest_landing` was dated: when this clone saw it arrive\non the trunk, or its commit time as an upper bound on the wait."
},
"landings": {
"description": "The landings of the trunk's first-parent history that brought them.",
"format": "uint",
"minimum": 0,
"type": "integer"
},
"next": {
"description": "The version the public contract requires for the landed work (ADR 0051), when it was\ndecided.",
"type": [
"string",
"null"
]
},
"next_unmeasured": {
"description": "Why that version was not decided, when it was asked for and could not be.",
"type": [
"string",
"null"
]
},
"oldest_landing": {
"description": "When the oldest of those landings landed, RFC 3339, dated as `landed_at`\nsays.",
"type": [
"string",
"null"
]
},
"overdue_after_seconds": {
"description": "How long it may wait before it is overdue (`OVERDUE_AFTER`).",
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"release": {
"anyOf": [
{
"$ref": "#/$defs/ReleaseCurrencyRelease"
},
{
"type": "null"
}
],
"description": "The last release."
},
"stance": {
"$ref": "#/$defs/ReleaseCurrencyStance",
"description": "Whether the landed work is released."
},
"summary": {
"description": "The answer in one sentence: the brief's and doctor's line.",
"type": "string"
},
"trunk": {
"description": "The remote-tracking ref of the trunk it was measured on (`origin/master`).",
"type": [
"string",
"null"
]
},
"waited_seconds": {
"description": "How long the work has waited since then, in seconds.",
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
}
},
"required": [
"stance",
"summary",
"landed",
"landings",
"overdue_after_seconds"
],
"title": "ReleaseCurrency",
"type": "object"
}Policies
- benchmark
- waived — waived: published_history
- 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.
| transport | state | cases | targets |
|---|---|---|---|
| direct | waived (published_history) | 0 | |
| mcp | waived (published_history) | 0 | |
| http | waived (published_history) | 0 |