pub struct PlanTransitionInput {
pub issue: String,
pub transition: Transition,
}Expand description
The input of plan.transition: which issue to move, and which way.
Two fields and no third. There is no timestamp — the move is stamped with the moment it happened, never with one the caller supplies, because a lifecycle a caller can backdate is not a record of what happened. There is no force or reason field either: a transition the model refuses is refused, and the way to make it legal is to satisfy the guard rather than to ask past it.
use majordomus_cli::capability::builtin::plan::PlanTransitionInput;
use majordomus_cli::plan::Transition;
// The wire form an MCP client or an HTTP POST sends.
let input: PlanTransitionInput =
serde_json::from_str(r#"{"issue":"I0001","transition":"done"}"#).unwrap();
assert_eq!(input.issue, "I0001");
assert_eq!(input.transition, Transition::Done);
assert_eq!(input.transition.field(), "completed_at");
assert_eq!(input.transition.event(), "plan_done");
// Unknown fields are refused rather than ignored: a caller that misspells `transition`
// is told so instead of having its move silently dropped.
assert!(serde_json::from_str::<PlanTransitionInput>(
r#"{"issue":"I0001","transition":"done","force":true}"#).is_err());Fields§
§issue: StringThe issue to move, by its id — which is also its file name.
transition: TransitionWhich move: start, verify or done.
Trait Implementations§
Source§impl BenchmarkCases for PlanTransitionInput
The benchmark cases of the one capability here that writes.
impl BenchmarkCases for PlanTransitionInput
The benchmark cases of the one capability here that writes.
Every case is a refusal, and that is deliberate rather than a gap. A case is executed —
by majordomus bench against this repository, and by the HTTP and MCP suites against a
fixture — so a case that moved an issue would change the plan every time the suite ran,
and a measurement whose cost is a changed record is not a measurement. The runner states
the principle that makes this sound: “a refusal is an answer, and answering is the work
a benchmark exists to measure”, and only Internal is fatal.
The refusal path is also the honest thing to time: it builds the plan, resolves the issue and evaluates the guard, which is everything the write path does except the two syscalls at the end.
The refusal must be a refusal and not a lookup miss. An earlier version named an issue
that could not exist, which answered 404 rather than 422, and tests/http_serve.rs holds
every route to answering its own cases — 200, or 422 for a command that turns a caller
down. Choosing the move from the record keeps the case inside that contract.
So a plan with no issue yields no case, and the handler is not bent to make one: naming
an issue the plan does not have is NotFound whether or not the plan holds other issues,
and a 422 that appeared only when the plan is empty would make the same request’s answer
depend on records it never named. The descriptor declares the requirement conditional on
BenchmarkPrecondition::PlanHoldsAnIssue instead, and coverage reports it inapplicable in
such a repository — and missing, as before, in one whose plan holds an issue.
Source§fn benchmark_cases(ctx: &CaseContext<'_>) -> Vec<NamedCase<Self>>
fn benchmark_cases(ctx: &CaseContext<'_>) -> Vec<NamedCase<Self>>
Source§fn benchmark_cases_json(ctx: &CaseContext<'_>) -> Vec<NamedCase<Value>>
fn benchmark_cases_json(ctx: &CaseContext<'_>) -> Vec<NamedCase<Value>>
Source§impl Debug for PlanTransitionInput
impl Debug for PlanTransitionInput
Source§impl<'de> Deserialize<'de> for PlanTransitionInput
impl<'de> Deserialize<'de> for PlanTransitionInput
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl JsonSchema for PlanTransitionInput
impl JsonSchema for PlanTransitionInput
Source§fn schema_id() -> Cow<'static, str>
fn schema_id() -> Cow<'static, str>
Source§fn json_schema(generator: &mut SchemaGenerator) -> Schema
fn json_schema(generator: &mut SchemaGenerator) -> Schema
Source§fn inline_schema() -> bool
fn inline_schema() -> bool
$ref keyword. Read more