* Refresh OpenProse skill conventions * Align OpenProse skill with service system conventions * Fix OpenProse PR review inconsistencies * Clarify OpenProse state backend loading * Enforce OpenProse smoke run state gate
3.5 KiB
name, kind
| name | kind |
|---|---|
| race | pattern |
Race
Multiple delegates work on the same task in parallel. First acceptable result wins. Others are cancelled.
Metadata
version: 0.1.0role: coordinator
Slots
candidates
Config
acceptance_criteria(string, default: none): Optional description of what makes a candidate result acceptable
Invariants
- Every candidate receives the same task brief
- Candidates run independently and do not see each other's outputs
- The first acceptable result wins; if multiple results are available, earlier slot order breaks ties
- If no candidate is acceptable, the pattern returns
nullwith no winner
Shape
self: dispatch same brief to all candidates, accept first good result, cancel restdelegates:candidate_1..candidate_N: attempt the task
prohibited: waiting for all candidates when one has already succeeded
Requires
- Pattern instance receives: candidates: string[] -- service or system names for each candidate task_brief: string -- the task (same brief goes to all candidates) acceptance_criteria: string -- (optional) declarative description of what makes a result acceptable. Default: any non-error result is accepted.
Ensures
- All candidates receive the same brief and start in parallel
- First result that meets acceptance criteria is returned immediately
- Remaining candidates are cancelled (best-effort)
- No candidate knows other candidates exist
- If no candidate produces an acceptable result: return null with all attempts in failure_history
result: the winning result, ornullwinner: the winning candidate name, ornullattempts: number of candidates that completed before a winnerfailure_history: rejected or failed candidate attempts
Delegation
let attempts = parallel for candidate in candidates:
try:
let candidate_result = call candidate
task_brief: task_brief
return {
candidate: candidate,
result: candidate_result,
error: null
}
catch as error:
return {
candidate: candidate,
result: null,
error: error
}
for attempt in attempts:
if attempt.error is present:
continue
if acceptance_criteria says attempt.result is acceptable:
return {
result: attempt.result,
winner: attempt.candidate,
attempts: "number of completed attempts before winner",
failure_history: attempts
}
return {
result: null,
winner: null,
attempts: candidates.length,
failure_history: attempts
}
Notes
No candidate knows other candidates exist. Each receives the same brief and works independently.
True cancellation depends on the runtime. In environments without preemption, all candidates run to completion and the first acceptable result (in preference order) wins. The candidates array order expresses preference — if two candidates both succeed, the earlier-listed one wins.
Different from fan-out: fan-out waits for ALL results and returns the full collection. Race returns the FIRST acceptable result. Use race for speculative execution, redundancy, or when multiple approaches might work but you only need one.
Different from fallback-chain: fallback-chain tries candidates sequentially (A, then B if A fails, then C). Race tries all candidates simultaneously. Use fallback-chain when later candidates are cheaper or less preferred and should only run if earlier ones fail. Use race when all candidates are worth trying in parallel.