The orchestration
A Scout Agent meta-orchestrator sits above the stage workers. It never does stage work
itself — at each stage boundary it evaluates that stage’s output artifact against a structured rubric and
returns one of three decisions: PASS (proceed), RETRY (re-run, max 3
attempts, with the ability to target a specific deficient section rather than the whole batch), or
REWRITE (compress or restructure the handoff artifact without re-running the stage). Every
decision is logged. The Scout also compresses each handoff so downstream stages receive only what they need —
which is how context stays clean across a very long run.
Model routing
Sections are routed by analytical complexity. Sonnet writes the five scaffolding/structured
sections — Roth conversion, income sequencing, Medicare/IRMAA, liquidity, and the roadmap.
Opus writes the four analytically heavy ones — multi-year tax optimization, annuity
cost-benefit, concentrated-stock cost-basis recovery, and longevity/estate synthesis — plus the cross-section
synthesis and executive summary. Running Opus on every section was cost-inefficient; split routing keeps
quality where it matters and saves tokens where it doesn’t.
Resumability
State lives in phase_status.json — completed stages, current stage, failures, retry counts, and
the append-only Scout decision log. To resume an interrupted run you don’t delete it: the orchestration loop
reads it on startup, skips completed stages, and re-dispatches from current. A partial-run
failure therefore costs one stage, not the whole pipeline, and completed sections are never re-billed.
The deterministic formatting layer
Formatting was pulled out of the prompts entirely. After generation, five sequential deterministic passes
operate on the .docx OOXML directly via lxml XML surgery — dollar abbreviation
(tables only), header/column compression, font scaling, landscape promotion of wide tables, and a final bold
audit — followed by programmatic insertion of 175 native Word cross-reference hyperlinks against placed
bookmarks. The whole thing runs as one unpack/repack cycle and is fully repeatable, where prompt-controlled
formatting never was.
The synthetic build — and why it exists
A finished retirement plan is a permanently sensitive document, which created a real problem: the pipeline
worked, and its output could never be shown. The fix was to make the demo a first-class artifact. The
pipeline is exercised against “Robert” — a fully synthetic 66-year-old
single Engineering Manager with roughly $5.29M across fictional Vanguard, Schwab, and Jackson
National accounts, including a 401(k) consolidation, a fixed deferred annuity, and a legacy 3M stock lot with
missing cost basis. He was engineered to carry the same analytical surface as a real scenario — equivalent
hard problems, none of the real data — so the full pipeline is demonstrable and the output is freely
shareable. Synthetic-by-design is the credential, and the persona spec doubles as the regression corpus for
validating pipeline changes against a known-good output.
The parts that fought back
Reconciling 12 stages down to 7
The pipeline started as a 12-stage linear script (v1), grew a Scout wrapper (v2), then consolidated to
7 gated stages in v3 — RPM extraction folded into Stage 1, and table surgery + bold audit +
hyperlinking merged into a single Stage 6 unpack/repack cycle. The published architecture is the hardened
7-stage v3.0; the old 12-stage framing is retired.
A 30K-tokens/min rate limit as a design constraint
The current blocker on fully non-interactive batch runs is the Anthropic API rate limit of
30K input tokens per minute. That constraint is what shaped the split-model routing and the
Scout’s aggressive handoff compression — keeping per-call input small is a first-class design pressure here,
not an afterthought.
Formatting that couldn’t be unit-tested
Prompt-controlled formatting was non-deterministic across runs and impossible to test reliably. That is
precisely why formatting moved into deterministic lxml surgery — a pass either produces the
exact XML change or it doesn’t, and that’s checkable.