5.1 KiB
5.1 KiB
T7.6 — Tournament as a join stage
| Field | Value |
|---|---|
| Phase | P7 — Distribution |
| Size | L — over 3 days |
| Status | Not started |
| Flags | — |
| Spec | inlined below |
| Blocks | — |
Goal
Repartition from the run key to the group key, close groups on a completeness trigger, and cap burst concurrency so grading cannot starve execution.
Facts (inlined — no spec read needed)
ingest ──► execute ──► verify ──► tournament ──► aggregate ──► decide
│ │ │ │ │ │
(T,Run) (T,Run) (T,Run) (T,Task,Class, (T,Variant) (T,Workflow)
Epoch)
▲ ▲ ▲
shuffle 1 shuffle 2 single writer
- Three keys, two shuffles, one single-writer stage. Everything up to
verification keys on
(TenantId, RunId)and is embarrassingly parallel. - Grading is a join — a comparison group must be co-located — keyed on
(TenantId, TaskId, VerifierOutcome, GroupEpoch): the outcome class because brackets exist only within one, and the epoch because a closed group never reopens for a late arrival. - The decide stage is single-writer per
(TenantId, WorkflowId); a CAS on a generation counter is sufficient (T6.1). - A group closes on quorum or timeout, grading whatever arrived, with group size attached to the confidence interval (T5.11).
- Grading yields to agent work. When both contend, agent inference wins and grading queues — a framework that lets a judge call delay the work it is judging has inverted its first principle.
- Tournament and reduction backlogs are the two lags that grow silently, so both are metered.
Steps
- Implement the repartition from
(TenantId, RunId)to(TenantId, TaskId, VerifierOutcome, GroupEpoch)after verification. - Maintain group state per key: members, open/closed, quorum target, deadline.
- Completeness trigger: close on quorum reached or deadline passed.
Increment
GroupEpochat closure; route later arrivals to the next epoch. - Cap concurrent tournament work with a semaphore sized independently of the executor's. Make the cap and its saturation observable in metrics.
- Give agent inference priority over grading when both want the same resident model (enforced fully in T8.6).
- Emit stage-boundary lag for the tournament stage.
- Test with a 64-episode group while runs are executing, asserting execution throughput is not degraded past a bound.
Acceptance
- A 64-episode group does not starve run execution.
- The cap is observable in metrics.
Verify
Harness: a load generator producing runs continuously while a large group fills, so starvation is observable rather than theoretical.
Integration test — tests/it_tournament_join.rs:
- Establish a baseline: run-execution throughput and agent-call latency with no grading load.
- Trigger a 64-episode group. Assert execution throughput and agent latency stay within a configured bound of baseline — assert on the numbers, not on the absence of an error.
- Assert the concurrency cap is observable in metrics: read the saturation gauge and assert it reflects the burst.
- Group key: assert repartition uses all four components. Feed episodes
differing only in
VerifierOutcome; assert they land in different groups. Repeat forGroupEpoch. - Closure: a group that never reaches quorum closes on timeout, with size
recorded, and
GroupEpochincrements. - Late arrival after closure lands in epoch N+1; epoch N's stored strengths are unchanged.
- Single-writer decide stage: two schedulers attempt to adjust allocation for
one
(TenantId, WorkflowId); assert CAS behaviour (cross-check T6.1). - Emit and assert stage-boundary lag for the tournament stage.
Command: cargo test -p distribution tournament_join -- --test-threads=1
False pass:
- Step 2 asserting only that both finished. Grading that delays agent work still finishes — the latency and throughput comparison against baseline is the test, because the principle being enforced is a priority, not a liveness property.
- Sharing the executor's concurrency limiter with grading: step 2 may still pass under light load and the cap becomes invisible. Step 3 is the guard.
- Step 4 omitted: dropping
VerifierOutcomefrom the key puts passes and failures in one bracket, which produces plausible results and violates the one rule with no exemptions.
Traps
- Omitting
VerifierOutcomefrom the group key, which puts passes and failures in one bracket — the one rule with no exemptions. - Omitting
GroupEpoch, which lets a late arrival reopen a published fit. - Sharing the executor's concurrency limiter with grading. Then a burst of grading is indistinguishable from a burst of work.
Background (not required to do this task): rust-agentic-sys.md §9.1, §11.6, §11.8, §14.2, §15 · rust-agentic-task.md