Files
troupe-standup/wizard-work/null/deporder/README.md
T

4.5 KiB
Raw Blame History

deporder — deterministic build-order planner for task DAGs

Lane: Codeforge (hard coding / agentic reasoning). Author: null. Location of record: /root/.hermes/wizard-outputs/null/deporder/.

What it is

A stdlib-only Python module + CLI that turns a task/dependency spec (JSON) into a build plan:

  • topological_order — serial order, lexicographically smallest ready task first
  • waves — maximal parallelism batches (wave k = longest dependency chain has k edges)
  • critical_path — weighted longest path (the makespan floor), with a unique, lexicographically canonical path
  • schedule — greedy list scheduling on N identical workers, with precedence and capacity guarantees
  • find_cycle — reports one cycle as a real path x -> y -> ... -> x

Every ordering decision is deterministic: ties break on lexicographically smallest name, so two runs over the same spec — and runs over specs whose keys were inserted in a different order — produce byte-identical output.

CLI

python3 deporder.py plan examples/pipeline.json [--workers N]

Exit codes: 0 ok · 2 dependency cycle · 3 unknown dependency · 4 malformed spec. Success prints the plan as JSON on stdout; failures print one diagnostic line on stderr and nothing on stdout.

Run the tests

python3 test_deporder.py          # 42 tests, stdlib unittest, no pytest needed
python3 mutate_teeth.py           # mutation harness: do the tests bite?

Evidence (measured on this box, Python 3.14.7)

Claim How measured Result
42 tests pass python3 test_deporder.py Ran 42 tests in 1.902s — OK (exit 0)
Differential vs naive reference 200 random DAGs × (order, waves, critical path) compared against O(V·E) fixpoint / O(V²) reference implementations inside the suite all equal
Schedule invariants 150 random DAGs × 1–4 workers: each task placed once, precedence end[d] ≤ start[n], ≤ N tasks in flight (event sweep), per-worker non-overlap, makespan ≥ critical path all hold
1 worker == serial makespan == Σest exact
≥N workers == critical path makespan == critical_path exact
Scale 20 000 nodes / 39 987 edges: order + waves + critical path + 8-worker schedule 0.92 s (budget in-suite: 10 s)
Determinism shuffled spec key insertion order → identical json.dumps(sort_keys=True) identical
Tests have teeth python3 mutate_teeth.py: 11 literal source mutations 10/10 required mutants caught, 1 documented equivalent, harness exit 0
CLI contract exit 0 on examples/pipeline.json; exit 2 + dependency cycle: draft -> review -> publish -> draft; exit 3 + unknown dependencies: app -> missing_module as specified

Bugs this suite actually caught while building it

All three were found by running things, not by reading the code:

  1. Scheduler stall (infinite loop). The clock-advance step took min(free_time, completion_time) even when a worker was already free at now with nothing ready — now stopped moving and schedule() never returned. Caught by PlanTests hanging. Fixed by advancing only to strictly-future events and raising RuntimeError on stall (unreachable for a DAG).
  2. O(V²) critical path. min(n for n in dist if dist[n] == max(dist.values())) recomputed the max inside the generator: a 20k-node plan took 15.98 s. Hoisting max() gave 0.85 s (≈19× faster) with identical results.
  3. Dead branch found by the mutation harness. The first version of the fix above also consulted future worker-release times when choosing the next event. The mutation that deleted that branch survived — it was unreachable, since workers are only ever released by completions already drained at now. The branch was removed rather than left as decoration.

Mutation harness (mutate_teeth.py)

Each mutation is a literal source edit applied to a copy of deporder.py in a temp dir; the mutation is caught if the suite exits non-zero on the mutant. Mutations tagged equivalent are expected to survive — they document a genuinely redundant guard rather than a hole in the tests.

See the harness output in EVIDENCE.txt (verbatim run log).

Files

deporder.py           implementation (module + CLI)
test_deporder.py      42-test stdlib suite (unit + differential + CLI + perf)
mutate_teeth.py       mutation harness
examples/pipeline.json  worked example (makespan 14.0 vs 18.0 serial, 3 workers)
EVIDENCE.txt          verbatim transcripts of the runs quoted above