integration.cleanup
The cleanup plan, decided offline from the recorded observation: every open pull request cleanup would close — redundant (its work is on master already) or superseded (by a declared successor that landed) — and every one it leaves for a person — possibly redundant (weak evidence) or obsolete (a person marked it, owner decision D3) — each with its disposition and the reasons that decided it, in rank order; beside it, the branches merged pull requests left on origin as `majordomus prs cleanup` last read them, with when and how long ago. A read: it closes, deletes and asks the forge for nothing — `majordomus prs cleanup` reads the forge and `--apply` closes. `observed: false` with the reason when this checkout has recorded no observation.
The cleanup plan, decided offline from the recorded observation: every open pull request cleanup would close — redundant (its work is on master already) or superseded (by a declared successor that landed) — and every one it leaves for a person — possibly redundant (weak evidence) or obsolete (a person marked it, owner decision D3) — each with its disposition and the reasons that decided it, in rank order; beside it, the branches merged pull requests left on origin as `majordomus prs cleanup` last read them, with when and how long ago. A read: it closes, deletes and asks the forge for nothing — `majordomus prs cleanup` reads the forge and `--apply` closes. `observed: false` with the reason when this checkout has recorded no observation.
- query
- experimental
- module integration
- #integration
- #pull-requests
- #cleanup
Exposure
Where this one definition is reachable. Absence is explicit: a surface not listed does not carry it.
| surface | as |
|---|---|
| MCP | tool majordomus_pull_requests_cleanup |
| HTTP | GET /api/v1/pull-requests/cleanup operationId integration.cleanup |
| 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 · Empty
No properties: the capability takes no input.
JSON Schema
{
"additionalProperties": false,
"description": "No input.",
"title": "Empty",
"type": "object"
}output · IntegrationCleanup
prs cleanup recorded.| property | type | required | description |
|---|---|---|---|
| branches | one of 2 | no | The branches merged pull requests left on origin, as prs cleanup last read them;
None when it never ran in this checkout. Never read from the network here. |
| branches_age_seconds | integer | null | no | How old that report is, in seconds, when its time reads. |
| items | array | yes | The plan, in rank order: would_close for what is provably on master or superseded by
a successor that landed, left_for_a_person for weak evidence and for what a person
marked obsolete. Nothing here closes anything. |
| observed | boolean | yes | Whether a forge observation is recorded in this checkout. |
| observed_at | string | null | no | When the forge was observed, when it was. |
| reason | string | null | no | Why there is no plan, when there is none. |
JSON Schema
{
"$defs": {
"CleanupItem": {
"description": "What cleanup would do, or did, for one pull request.",
"properties": {
"action": {
"description": "`would_close`, `closed`, `left_for_a_person`, or `close_failed: <why>`.",
"type": "string"
},
"disposition": {
"$ref": "#/$defs/PullRequestDisposition",
"description": "Its disposition when decided."
},
"pr": {
"description": "The pull request.",
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"reasons": {
"description": "The evidence, as reason codes.",
"items": {
"description": "A reason code, `code` or `code:payload`, one of: `stacked_on:#N`, `base_is:BRANCH`, `draft`, `label:NAME`, `auto_merge_armed`, `merge_commit_not_allowed`, `superseded_by:#N`, `successor_open:#N`, `successor_not_landed:#N`, `successor_unread:#N`, `head_reachable_from_master`, `merge_changes_nothing`, `patch_ids_upstream`, `only_derived_artifacts_differ`, `relation_unknown:WHY`, `conflicts_on:COUNT`, `depends_on:#N`, `review:STATE`, `review_policy_unread`, `required_check_failed`, `behind_master:COMMITS`, `fork_head`, `version_unallocated:VERSION`, `required_checks:STATE`, `no_required_checks`, `required_checks_unread`, `contains_master`, `carries_master`, `required_checks_passed`, `required_checks_skipped`, `executor_merge_refused:HEAD`, `executor_refresh_failed:MASTER`, `label_obsolete:NAME`, `dependency_cycle:#N`, `dependency_closed_unmerged:#N`, `dependency_unread:#N`, `declarations_unread`. A code outside this list (an older trail's) is carried verbatim.",
"type": "string"
},
"type": "array"
}
},
"required": [
"pr",
"disposition",
"reasons",
"action"
],
"type": "object"
},
"LeftBranch": {
"description": "A branch a merged pull request left on origin, as cleanup reports it. Reported, never\ndeleted: the forge's `delete_branch_on_merge` decides deletion (owner decision D4), so the\nexecutor holds no branch-deleting write at all.",
"properties": {
"action": {
"description": "`left_for_a_person`, or `kept: checked out at <path>` when a worktree of this\nrepository has the branch checked out: somebody may still be standing on it.",
"type": "string"
},
"branch": {
"description": "The branch on origin.",
"type": "string"
},
"merged_at": {
"description": "When that pull request merged.",
"type": "string"
},
"next_step": {
"description": "What would clear it, in the setting's own terms.",
"type": "string"
},
"pr": {
"description": "The pull request that merged it.",
"format": "uint64",
"minimum": 0,
"type": "integer"
},
"tip": {
"description": "Its tip: the head that merged.",
"type": "string"
}
},
"required": [
"branch",
"tip",
"pr",
"merged_at",
"action",
"next_step"
],
"type": "object"
},
"LeftBranchReport": {
"description": "The last report of the branches merged pull requests left on origin, as `prs cleanup`\nread it. Written by `prs cleanup` alone — the one place that asks the forge for them —\nand rendered offline, with its age, by every surface that cannot reach the network.",
"properties": {
"base": {
"description": "The base the report excludes.",
"type": "string"
},
"branches": {
"description": "The branches, or `None` when origin or the merged pull requests could not be read:\nunread is not \"nothing left behind\".",
"items": {
"$ref": "#/$defs/LeftBranch"
},
"type": [
"array",
"null"
]
},
"delete_branch_on_merge": {
"description": "The forge's `delete_branch_on_merge`, from the observation; `None` when unread.",
"type": [
"boolean",
"null"
]
},
"read_at": {
"description": "When cleanup read origin and the merged pull requests.",
"type": "string"
},
"refreshed_by": {
"description": "The command that reads it afresh.",
"type": "string"
}
},
"required": [
"read_at",
"base",
"refreshed_by"
],
"type": "object"
},
"PullRequestDisposition": {
"description": "The one classification of an open pull request. Every value carries a machine-readable\nreason in `PullRequestAssessment::reasons`; there is no `mergeable: bool`.",
"oneOf": [
{
"const": "ready",
"description": "Contains the current master, every required check passed on its head, nothing\nblocks it: the executor may merge it.",
"type": "string"
},
{
"const": "needs_refresh",
"description": "Merges cleanly but does not contain master: the executor may bring master in (a\nmerge commit on the branch, never a rewrite), after which CI must run again.",
"type": "string"
},
{
"const": "waiting_for_checks",
"description": "Contains master; a required check has not finished on this head.",
"type": "string"
},
{
"const": "waiting_for_review",
"description": "A required review is missing or changes were requested.",
"type": "string"
},
{
"const": "waiting_for_dependency",
"description": "A declared dependency has not landed.",
"type": "string"
},
{
"const": "draft",
"description": "A draft.",
"type": "string"
},
{
"const": "needs_repair",
"description": "A required check failed on this head.",
"type": "string"
},
{
"const": "conflicting",
"description": "Conflicts on authored paths: a person resolves them.",
"type": "string"
},
{
"const": "blocked",
"description": "A label whose policy is to hold holds it, or the repository allows no merge commit,\nwhich is the only way the executor merges.",
"type": "string"
},
{
"const": "unsafe",
"description": "The forge has auto-merge armed on it: the forge would merge it on its own, outside the\nexecutor and against whatever master is then. Held until a person disarms it.",
"type": "string"
},
{
"const": "redundant",
"description": "Its head already landed, its merge changes nothing, or every one of its commits is on\nmaster as an equal patch: strong evidence from git, eligible for closure under policy.\n(Before 0.13 this was the word `superseded`.)",
"type": "string"
},
{
"const": "superseded",
"description": "A successor was declared for it by someone the repository lets declare one — an owner,\nmember or collaborator, in a pull request of this repository — and that successor\nlanded: git finds its head or its merge commit in master. The successor is\n`PullRequestAssessment::superseded_by`. Eligible for closure under policy.",
"type": "string"
},
{
"const": "possibly_redundant",
"description": "Weak evidence: only derived artifacts would change, or its declared successor was merged\nsomewhere master does not contain. Surfaced for a person; never closed automatically.",
"type": "string"
},
{
"const": "other_base",
"description": "Targets a branch other than the integration base.",
"type": "string"
},
{
"const": "unknown",
"description": "Something needed to decide could not be observed.",
"type": "string"
},
{
"const": "obsolete",
"description": "A person marked it obsolete with a label the label policy declares (owner decision\nD3): the only evidence that reaches this word. Listed for a person by cleanup and\nnever closed automatically; age, shared paths or a similar title never make one.",
"type": "string"
}
]
}
},
"description": "What cleanup would do, decided offline: the pull requests it would close or leave for a\nperson, from the recorded observation, and the last branch report `prs cleanup` recorded.",
"properties": {
"branches": {
"anyOf": [
{
"$ref": "#/$defs/LeftBranchReport"
},
{
"type": "null"
}
],
"description": "The branches merged pull requests left on origin, as `prs cleanup` last read them;\n`None` when it never ran in this checkout. Never read from the network here."
},
"branches_age_seconds": {
"description": "How old that report is, in seconds, when its time reads.",
"format": "uint64",
"minimum": 0,
"type": [
"integer",
"null"
]
},
"items": {
"description": "The plan, in rank order: `would_close` for what is provably on master or superseded by\na successor that landed, `left_for_a_person` for weak evidence and for what a person\nmarked obsolete. Nothing here closes anything.",
"items": {
"$ref": "#/$defs/CleanupItem"
},
"type": "array"
},
"observed": {
"description": "Whether a forge observation is recorded in this checkout.",
"type": "boolean"
},
"observed_at": {
"description": "When the forge was observed, when it was.",
"type": [
"string",
"null"
]
},
"reason": {
"description": "Why there is no plan, when there is none.",
"type": [
"string",
"null"
]
}
},
"required": [
"observed",
"items"
],
"title": "IntegrationCleanup",
"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.