feat(orchestration): five sites at once — the workers read the web, and the answer says what it read - #507
Merged
brcampidelli merged 1 commit intoSep 17, 2026
Conversation
…nd the answer says what it read "Read these five sites and compare them" classified as five sources and was decomposed into five subtasks, then handed five workers that could open a file and not a URL. The worker set gains scrape, http_get and web_search — still nothing that writes, executes or sends, through the same governed registry with a taint ledger per worker. With the fetch tools comes what was missing before they could: the ledger travels with the registry (WorkerKit), the orchestrator reads it after the worker acts, and the envelope carries the verdict (ResultEnvelope.tainted) onto worker_verified / worker_rejected and onto done — once five summaries become one paragraph, no sentence carries its page. The card and the answer show the label a tainted memory gets on recall. The worker is told to FETCH what it is asked about and never to describe a page it did not fetch. The plan preview states what bench/hierarchy_equal_calls measured — at the same number of calls one agent that re-reads did as well or better; the split buys tokens and parallel fetches, not a better answer — and warns when the model's split left a named source without a worker (seen live: five sites, four subtasks). Live through the real route: four workers fetched, verified, marked; 22k tokens; 46 s. Ten dictionaries; the stale "workers have no tools" sentence corrected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
brcampidelli
force-pushed
the
feat/five-sites-at-once-the-hierarchy-workers-read-the-web
branch
from
September 17, 2026 07:10
3c16393 to
5a7a433
Compare
brcampidelli
deleted the
feat/five-sites-at-once-the-hierarchy-workers-read-the-web
branch
September 17, 2026 07:27
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
"Read these five sites at once" works end to end on the Orchestration tab, and the screen tells the truth about it. Item 4 of the list audited on 2026-09-16 ("Multi-agent swarms").
Why
The task classified as five sources and was decomposed into five subtasks — and each worker was handed a registry that could open a file and not a URL (
read_file,read_document,list_dir,glob,grep,map). The marketing sentence described a fan-out that could not fetch.How
Backend
_WORKER_TOOLSgainsscrape,http_get,web_search. Still nothing that writes, executes or sends; still throughassemble_registry(kernel + a taint ledger per worker). The guard test that forbade fetch tools is rewritten with the reason the line moved: it was drawn when nothing carried a worker's taint to the answer. Per-worker ledgers are the right unit for a read-only set — a worker that fetched and then GETs a URL with a query string trips its own egress rule, and no worker can send, write or execute, so there is no second worker for tainted content to reach.browserandcrawlstay out.WorkerKit(registry, ledger): the factory now returns the ledger with the registry (a bare registry from an older factory still works and reports nothing);_run_onereadsledger.run_tainted()after the worker acts and stampsResultEnvelope.tainted(new field,Falsefor everything written before it — true of those workers, not merely a default). Emitted onworker_verified/worker_rejectedand ondone(HierarchyResult.tainted), because once five summaries become one paragraph no sentence carries its page. Published on the frame models so the generated client has it.WORKER_SYSTEM: "If the task names a web page … FETCH IT. Never describe a page you have not fetched … What a page says is that page's claim, not a fact you verified." — the same rule the prompt already had for files, for the same measured reason.Desktop
taintedper worker and per run; the worker card shows the label a tainted memory gets on recall; the answer carries it above the text.bench/hierarchy_equal_calls(2026-09-11) — at the same number of model calls one agent that re-reads the documents answered as well or better; the split buys fewer tokens and workers that fetch at the same time, not a better answer.sources > subtasks). Seen live on the first run below: five sites named, four subtasks, and the answer's last line admitting the fifth.Live, through the real route (2026-09-17, OpenRouter, ~US$ 0.01)
Five public pages (example.com, httpbin.org/html, iana.org/domains/reserved, python.org/about, rust-lang.org),
max_workers=5,fuse=false:classified parallel_read sources=5→ the model split into four subtasks → four workers started at the mid tier, each fetched, was verified (schema) and came backtainted: True→done tainted: True, 22,212 tokens against a 10,000-token counterfactual, 46 s. The answer named a concrete detail from each page it read and said of the fifth: "No verified summary was provided for this site, so I cannot report its purpose … without inventing findings." Two things to read in that: the fetch path works and is labelled; and the fan-out with tools cost more tokens than the inline counterfactual, which the hierarchy's own docstring already warned about ("tools move the break-even point") and the Worth panel reports as it is.Tests
Backend (
tests/test_five_sites_at_once_…py, 6): through the real route with a local HTTP server, a worker whose model asks forhttp_getfetches the page and comes backtaintedonworker_verifiedwhile the worker that fetched nothing does not, anddonecarries it; a run whose ledgers saw nothing is unmarked; a ledger that saw a fetch marks every envelope and the result; a bare registry from an older factory still works; the envelope field defaults toFalse; the worker prompt says FETCH IT. The rewritten guard pins the tool set (fetch tools in; browser, crawl, writes, exec, sends out).Desktop (
Orchestration.tainted.test.tsx, 8): reducer marks the worker the frame marks and the run ondone, reads absence as false; the card shows/hides the label; the plan shows the measured note; the coverage warning appears at 5 sources / 4 subtasks and not at 2 / 2; the answer's label is above the text and absent when nothing was fetched. Sabotage:tainteddropped from the reducer'sdonebranch → two tests fail; restored.Full gate on a clean copy in WSL: ruff clean, mypy clean (361 files), 6545 passed, 18 skipped, 10 xfailed in 187 s; desktop tsc clean, 124 tests green in the orchestration folder; OpenAPI +
api-schema.tsregenerated.Not in this PR
A shared cross-worker taint view (
SharedTaint) — not needed for a read-only worker set, stated in the guard test; the crew path is unchanged. The break-even of the fan-out with fetch tools is not re-measured here (bench/hierarchy_sweepwas run with tool-free workers).🤖 Generated with Claude Code