A snapshot: read at commit 707a04c7ce8 on 2026-10-18T00:06:01Z by majordomus 0.29.0. Nothing on this page is read again. See it live
plan.next
The one issue to take now
What it is
The lowest-wave READY issue of the active milestone, highest priority first, then id. The active milestone can have nothing ready while another one does — one waiting on its own acceptance evidence, for instance — so the search widens to the whole plan rather than answering `none` and sending a worker away from work that is genuinely executable. This is what an agent asks before it starts.
Descriptor
- Canonical id
plan.next- Module
plan- Kind
- query
- Stability
- behaviorallyverified
- Provenance
- declaredcached
- Source
apps/majordomus-cli/src/capability/builtin/plan.rs- Cache
process, 16 entries, per generation- Benchmark
required- Tags
- planprojectnext
Run
queryA query. It reads and changes nothing.
Projections
| Interface | As | Where |
|---|---|---|
| MCP tool | majordomus_plan_next | - |
| MCP resource | not exposed | - |
| HTTP | GET /api/v1/plan/next | Swagger |
| Command line | not exposed | - |
Schemas
Input · PlanMilestoneFilter
{
"type": "object",
"additionalProperties": false,
"properties": {
"milestone": {
"type": [
"string",
"null"
],
"description": "Restrict the answer to one milestone. Default: the whole plan, and for `next` the\nactive milestone with the rest of the plan as the fallback."
}
},
"description": "Which part of the plan to answer about.",
"title": "PlanMilestoneFilter"
}Output · PlanNextIssue
{
"type": "object",
"properties": {
"issue": {
"anyOf": [
{
"$ref": "#/$defs/PlanIssue"
},
{
"type": "null"
}
],
"description": "The issue, when the plan has one that is executable."
},
"active_milestone": {
"type": "string",
"description": "The milestone the search started in."
},
"reason": {
"type": [
"string",
"null"
],
"description": "Why there is none, when there is none: what to run to see what is in the way."
}
},
"required": [
"active_milestone"
],
"description": "The one issue a worker should take now.",
"title": "PlanNextIssue",
"$defs": {
"PlanIssue": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The identity, which is also the file name."
},
"milestone": {
"type": "string",
"description": "The milestone it belongs to."
},
"status": {
"type": "string",
"description": "The derived status. Never stored: an issue records what happened to it and the\nstatus follows from that and from the state of its dependencies."
},
"wave": {
"type": "integer",
"format": "uint32",
"minimum": 0,
"description": "The execution wave: one past the longest path to it through the dependency graph."
},
"priority": {
"type": "string",
"description": "`p0` … `p3`."
},
"profile": {
"type": "string",
"description": "The execution profile the issue is worked under."
},
"parallel_safe": {
"type": "boolean",
"description": "Whether it may run beside another issue of its wave."
},
"title": {
"type": "string",
"description": "One line naming the outcome."
},
"slug": {
"type": "string",
"description": "The slug, when the record carries one."
},
"depends_on": {
"type": "array",
"items": {
"type": "string"
},
"description": "Every issue it declares a dependency on, as declared — including one that does not\nexist, which is a finding rather than a silent omission."
},
"blocked_by": {
"type": "array",
"items": {
"type": "string"
},
"description": "The dependencies that are not DONE, plus `milestone:<id>` when the milestone gate\nholds the whole outcome back."
},
"dependents": {
"type": "array",
"items": {
"type": "string"
},
"description": "The issues that depend on this one."
},
"scope": {
"type": "array",
"items": {
"type": "string"
},
"description": "The paths it touches; two issues of one wave that share a path are serialised."
},
"serves": {
"type": "array",
"items": {
"type": "string"
},
"description": "The intent criteria it exists to make true, each `<intent>#<criterion>`, as declared.\nEmpty for maintenance work under a milestone no intent names; whether a named\ncriterion exists is the intent coverage's question, not the plan's."
},
"objective": {
"type": "string",
"description": "One line: what the issue is for."
},
"evidence_have": {
"type": "integer",
"format": "uint32",
"minimum": 0,
"description": "Evidence entries attached."
},
"evidence_need": {
"type": "integer",
"format": "uint32",
"minimum": 0,
"description": "Evidence tokens the record requires before it may be DONE."
},
"started_at": {
"type": "string",
"description": "When execution began, when it did."
},
"verified_at": {
"type": "string",
"description": "When implementation was declared complete."
},
"completed_at": {
"type": "string",
"description": "When completion was recorded."
}
},
"required": [
"id",
"milestone",
"status",
"wave",
"priority",
"profile",
"parallel_safe",
"title",
"slug",
"depends_on",
"blocked_by",
"dependents",
"scope",
"serves",
"objective",
"evidence_have",
"evidence_need",
"started_at",
"verified_at",
"completed_at"
],
"description": "One issue, as its record declares it and as the graph derives it."
}
}
}Examples
These are the capability's own benchmark cases: the same inputs the benchmark runs and the OpenAPI document shows.
whole-plan
{}one-milestone
{
"milestone": "M000"
}