97 lines
3.9 KiB
Markdown
97 lines
3.9 KiB
Markdown
# T10.5 — `TaskBoardFormat` plugin
|
|||
|
|
|
||
|
|
| Field | Value |
|
||
|
|
|---|---|
|
||
|
|
| Phase | P10 — Orchestration |
|
||
|
|
| Size | M — 1 to 3 days |
|
||
|
|
| Status | Not started |
|
||
|
|
| Flags | — |
|
||
|
|
| Spec | inlined below |
|
||
|
|
| Blocks | — |
|
||
|
|
|
||
|
|
## Goal
|
||
|
|
|
||
|
|
Front door (a): parse `tasks/*.md` — this board's own format — into a
|
||
|
|
`WorkflowDef` via the existing `WorkflowFormat` plugin trait. Zero kernel
|
||
|
|
change.
|
||
|
|
|
||
|
|
## Facts (inlined — no spec read needed)
|
||
|
|
|
||
|
|
- `WorkflowFormat` is already designed as a plugin point — this adds a third
|
||
|
|
format implementation, not a new mechanism. YAML and the Rust builder are
|
||
|
|
the other two; both canonicalize to the same IR (INDEX.md's customization
|
||
|
|
contract).
|
||
|
|
- Step order comes from **phase + row order in INDEX.md**, not
|
||
|
|
filename/id order. Id order is explicitly not execution order (INDEX.md's
|
||
|
|
own "Ordering" section).
|
||
|
|
- Each task file's Acceptance/Verify/Command sections map to a `StepDef`'s
|
||
|
|
verifier binding and completion criteria. Capability ids referenced
|
||
|
|
(verifier/judge/model) must already be registered (T3.9) or load fails
|
||
|
|
naming the id and file — same contract as YAML.
|
||
|
|
- Read-only relative to the board: this parses `tasks/*.md`, it does not
|
||
|
|
write `Status` back. That stays out of scope here.
|
||
|
|
|
||
|
|
## Steps
|
||
|
|
|
||
|
|
1. Implement `TaskBoardFormat: WorkflowFormat`, `load(path: &Path) ->
|
||
|
|
Result<WorkflowDef>` reading a directory of `T*.md` + `INDEX.md`.
|
||
|
|
2. Parse `INDEX.md`'s phase tables for execution order; parse each task
|
||
|
|
file's Goal/Acceptance/Verify sections into one `StepDef` per task.
|
||
|
|
3. Unresolved verifier/judge/model ids referenced in a task file fail at
|
||
|
|
load, naming the id and file — same contract as the other two front
|
||
|
|
doors.
|
||
|
|
4. Canonicalize through the same Blake3 hashing as the other two front doors
|
||
|
|
(T3.1) — same `WorkflowDef` IR.
|
||
|
|
5. Test: load this board's own `tasks/` directory, assert the canonicalized
|
||
|
|
IR is stable across two loads (determinism), and that step order matches
|
||
|
|
`INDEX.md`'s declared phase order, not directory-listing order.
|
||
|
|
|
||
|
|
## Acceptance
|
||
|
|
|
||
|
|
- `agent-rust/tasks/` loads into a `WorkflowDef` with step order matching
|
||
|
|
`INDEX.md`'s declared phase order.
|
||
|
|
- A task file referencing an unregistered verifier id fails at load, naming
|
||
|
|
the id and file — not at spawn.
|
||
|
|
|
||
|
|
## Verify
|
||
|
|
|
||
|
|
**Harness:** this repo's own `agent-rust/tasks/` directory as the test
|
||
|
|
fixture — self-hosting, no synthetic fixture needed.
|
||
|
|
|
||
|
|
**Integration test** — `tests/it_taskboard_format.rs`:
|
||
|
|
1. Load `agent-rust/tasks/`; assert no error.
|
||
|
|
2. Assert step count matches `INDEX.md`'s task count.
|
||
|
|
3. Assert step order matches `INDEX.md`'s phase-table order, not `ls`/
|
||
|
|
filename order — deliberately scramble the directory-read order in the
|
||
|
|
test harness to catch an implementation that trusts `readdir` order.
|
||
|
|
4. Load twice; assert canonicalized `WorkflowVersion` hash identical both
|
||
|
|
times.
|
||
|
|
5. Inject one task file referencing a made-up verifier id; assert load
|
||
|
|
fails, error names the id and file path.
|
||
|
|
|
||
|
|
**Command:** `cargo test -p formats taskboard_format`
|
||
|
|
|
||
|
|
**False pass:**
|
||
|
|
- Step 3 without deliberately scrambling directory-read order — most
|
||
|
|
filesystems return sorted-ish order by accident, hiding a bug that trusts
|
||
|
|
`readdir`.
|
||
|
|
- Skipping the unresolved-id failure test — a format that silently drops
|
||
|
|
unparseable tasks looks like it "works" until one goes missing at spawn.
|
||
|
|
|
||
|
|
## Traps
|
||
|
|
|
||
|
|
- Deriving step order from task-id string sort. `"T10.1" < "T2.1"` as
|
||
|
|
strings — `INDEX.md`'s declared order is the only authority, exactly the
|
||
|
|
bug the board's own "Ordering" section warns about at board scope.
|
||
|
|
- Making `TaskBoardFormat` also write `Status` back into task files. Turns a
|
||
|
|
read-only parser into a mutator with its own concurrency/conflict
|
||
|
|
problems, out of scope.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
Background (not required to do this task):
|
||
|
|
[../INDEX.md](../INDEX.md) (customization contract ~line 19-58, ordering
|
||
|
|
~line 88-103) ·
|
||
|
|
[T3.1-workflowdef-ir-canonicalization.md](T3.1-workflowdef-ir-canonicalization.md) ·
|
||
|
|
[T3.9-capability-registry.md](T3.9-capability-registry.md)
|