Skip to content

T-EJ3P-gs-stateful-tracker

Status: planning/backlog · Impact: low · Complexity: small

Add the stateful convenience wrapper graph_scheduler::tracker, behind an optional tracker Cargo feature.

Deferred until after cutover. Not part of graph-scheduler v0.1. The engine holds its own state on the lease and the run journal and re-reads it each tick, so it calls the pure get_ready directly and has no use for a wrapper that owns state. This task is parked at planning/backlog and is re-promoted when a consumer that wants the convenience actually exists — which is the P-0012-rust-core-adapters-as-needed test, applied to a layer rather than a language.

Impact is lowered to low for the same reason: StatusSource, landed by T-CLV1-gs-status-model-and-trigger-rules, already removes most of the plumbing this wrapper was meant to remove.

LocationRole today
packages/rust/graph-scheduler/src/tracker.rsDoes not exist. Not scaffolded by T-ROJC-gs-test-corpus-and-disabled-suites
packages/rust/graph-scheduler/src/status.rsStatusSource already covers the “derive state from the caller’s store” half of this capability
packages/rust/intersect/Cargo.tomlThe precedent for a layer behind an optional Cargo feature — its fs feature mirrors a TypeScript subpath export

src/tracker.rs, gated by an optional tracker feature.

ItemShape
Tracker::new(Graph)Owns an internal BTreeMap<NodeId, NodeStatus>, all Pending
Tracker::with_status(Graph, impl StatusSource)Reads state from the caller’s source instead
ready(&ReadyOptions) -> Vec<ReadyNode>Same frontier as get_ready on equivalent state
start(&NodeId)Sets Running
complete(&NodeId, NodeStatus)Defaults to Success, re-opening the frontier
explain(&NodeId) -> ExplanationDelegates to Schedule::explain

D-BPD8 lists the tracker as the graph-scheduler/tracker subpath. Rust has no export map, so the closest idiom for an opt-in layer is a Cargo feature — exactly how packages/rust/intersect expresses its fs entry point. Default-off here, since the engine does not want it.

The wrapper adds no behaviour. It must return the same frontier the pure engine returns for equivalent state, and the parity fixture is what proves it.

  1. Add the optional tracker feature and implement src/tracker.rs over Schedule and get_ready.
  2. Land the Layer 8 fixture table from T-ROJC’s matrix as a const table in tests/tracker.rs, un-ignored, and make it green.
  3. Extend moon.yml’s test task to --all-features so the gated layer is covered in CI, matching intersect.
LocationKindChange
packages/rust/graph-scheduler/src/tracker.rsnewTracker over the pure engine
packages/rust/graph-scheduler/Cargo.tomlmodifyAdd the optional tracker feature
packages/rust/graph-scheduler/src/lib.rsmodifyFeature-gated module declaration and re-export
packages/rust/graph-scheduler/moon.ymlmodifyRun test with --all-features
packages/rust/graph-scheduler/tests/tracker.rsnewLayer 8 fixtures, including the parity case
  • AC-1: Tracker supports ready, start, complete and explain, over either an internal map or a supplied StatusSource.
  • AC-2: start excludes a node from the next frontier; complete with the default outcome re-opens its dependents.
  • AC-3: Tracker results equal get_ready on equivalent state at every step, asserted by the parity fixture rather than by inspection.
  • AC-4: The layer is behind a default-off tracker feature, and cargo build -p graph-scheduler without features compiles nothing from tracker.rs.
  • AC-5: Every row of T-ROJC’s Layer 8 fixture table passes under --all-features.
  • Any change to the pure engine. If the tracker needs one, that is a defect in the engine’s surface, not tracker work.
  • Pull resolution (T-0WNK-gs-pull-resolution).

T-8L0G-gs-goal-directed-frontier


← Back to Tasks