feat(fusion): a contract between the parts of a fan-out, truthful delegate outcomes (F7, F2) - #431
Open
plombeer31 wants to merge 2 commits into
Open
plombeer31 wants to merge 2 commits into
plombeer31 wants to merge 2 commits into
Conversation
…f a fan-out
Workers never see each other, and in the benchmark that cost two turns:
one worker wrote HD.Ship as a class while its sibling called it as an
object, and main.js looked for launch-btn against a btn-launch in the
markup. Each brief was consistent on its own; the disagreement lived
between them, where nothing was written down.
`fusion.delegate` gains an optional call-level `contract`:
{ owners?: {path: taskId},
provides?: [{task, kind: symbol|file|id|endpoint|env|flag|other, name, in?}],
requires?: [{task, name}],
checks?: [{task?, ...verify.run args}] }
- delegate-args.ts validates it against the task ids; every error names
the field. A `requires` name must match a `provides` name (the
launch-btn / btn-launch mismatch is refused before any worker runs),
and a non-file provide must have somewhere to be looked for (`in`, an
owned path or a declared file). Limits: 64 provides, 16 checks, 8,000
rendered chars. A contract sent as JSON text is parsed like `tasks`.
- worker-prompt.ts renders the shared CONTRACT block (owners, provides,
requires, checks) above every TASK, followed by "You own / You provide
/ You may rely on" for that task, and a RULE to end the reply with a
PROVIDED: list. Briefs without a contract are byte-identical.
- contract-checks.ts checks presence after the fan-out by
language-agnostic means: a file exists; a symbol appears as a whole
word in `in` or the owned/declared files; an id appears as
id="…"/id='…'; anything else as a literal. Missing provides land as a
note on the owner's row and on a `contract:` line under the head line
of the status table. `checks` run through an injected
`deps.runChecks` (verify's runner; undefined-safe — declared checks
with no runner are reported as not run, never as passed); a task
whose declared check fails becomes `failed` with `checks: …` as its
error. The report also rides on `details.contract`.
- The descriptor's argsSchema and the native-tools JSON schema carry the
new field (the descriptor is mounted only in fusion mode).
…r fusion.delegate Two lies the fan-out result could still tell after patch 1: - A worker that declared `files`, read them, and replied "I'm done!" without writing anything came back `ok` (run 14, repair 1). New task status `no_changes`: an `ok` task that declared `files`, made no successful write / edit / patch call (the collector now counts them as `tools.writes`) and changed none of its declared files on disk (`DeclaredFileReport.modified`). Both halves are needed — the call count alone misreads a worker that wrote through the shell, the disk alone misreads declared globs. Tasks without `files` never get it; statuses that already say why the work is incomplete are left alone. The feed line reads "no changes — …" and the row carries the reason. - A fan-out where every worker failed returned `status: "ok"`. The call's status now summarises its tasks (`details.outcome`: `all_ok` / `partial` / `all_failed`) and is `error` only when every task failed or was cancelled — partial results stay `ok` because they are the value of a fan-out. The head line counts every status in a fixed order: `7 tasks: 5 ok, 1 no_changes, 1 failed`. AGENTS.md's fusion section is updated to match.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Before:
DelegateTaskwas{ id, title, instructions, deliverable?, files? }and nothing described or checked the interface between parts — one worker wrote a class another called as an object, button ids differed between markup and script; a task that declared files and wrote nothing wasok; a fan-out where every worker failed still returnedokfor the call.After:
fusion.delegatetakes an optionalcontract(owners,providesof kind symbol/file/id/endpoint/env/flag/other,requires,checksasverify.runspecs; ≤ 64 provides, ≤ 16 checks, ≤ 8,000 rendered chars), prepended to every brief with a per-task "You own / You provide / You may rely on", and after the fan-out each provide is checked for presence by language-agnostic means and the checks run through an injectedrunChecksseam (wired to the verify family in the next PR); results land in the status table. A task with declared files and no successful write/edit/patch isno_changes; the call'sdetails.outcomeisall_ok/partial/all_failedand the head line counts every status.Why
Design call D3: a shared contract, no approval step — workers stay at the orchestrator's disposal. A wrong contract makes every part consistently wrong, which is cheaper to fix than inconsistent parts. Truthful statuses make the orchestrator re-delegate where it used to accept a false ok.
How it was verified
npm run lintcleannpx vitest run --minWorkers=1 --maxWorkers=3 src/llm/provider/openai src/prompt src/tools/fusion— 44 files / 728 tests green (baseline failures: none)no_changesalthough its reply claimed the files were corrected; a contract with provides and requires was accepted on a live fan-outStacked on #430; merge in order.