site-fleet — Sequential fleet orchestration
Recon a LIST of sources one at a time, reusing site-recon per source, with a durable ledger that survives compaction and a deterministic completeness gate.
Reuses, never replaces: each source is a full site-recon (Subsystem A). This skill only adds the ledger, the sequential loop, and the completeness sweep. One source at a time — no parallelism (that is the deferred B2 subsystem).
Entry — branch on arguments (REQUIRED)
- With URLs / a file arg → start a new fleet:
(A file of URLs, one per line: expand it to the arg list first.) Record the printedpython3 "${CLAUDE_PLUGIN_ROOT}/skills/site-recon/scripts/fleet.py" init {url1} {url2} …[FLEET:{ledger}]. If it prints[FLEET-ERROR] … already active, do NOT retry init — go to resume. - With no args, OR after
[FLEET-ERROR] already active→ resume; never callinit:python3 "${CLAUDE_PLUGIN_ROOT}/skills/site-recon/scripts/fleet.py" pending
The loop (sequential)
Repeat until fleet.py pending prints nothing:
- Take the next slug from
fleet.py pending(it also re-arms a paused fleet). - Reconcile: if that source's
docs/sites/{slug}/research/INDEX.mdis already complete (python3 …/okf_validate.py --is-complete <INDEX>), mark it and skip:fleet.py update {slug} --status complete --verdict complete. - Otherwise mark it in flight:
fleet.py update {slug} --status reconning. - Recon the whole source (Phases 1–12) in ONE context. Dispatch the
site-analystsubagent for{url}and await its completion — a foregroundsite-analystagent can run the entire recon, including the browser phases, end to end. This is the primary path. (Fallback only: if a future environment denies subagents Bash/browser access, run thesite-reconskill for{url}yourself in the main session instead.) Do NOT split Phases 1–9 from 10–11 across contexts — that re-opens the content seam (prohibited in B1). - Record the outcome:
- completed (INDEX flipped
status: complete) →fleet.py update {slug} --status complete --verdict complete - blocked for a concrete reason (e.g. auth wall) →
fleet.py update {slug} --status blocked --verdict blocked:{reason} - errored / produced nothing →
fleet.py update {slug} --status inconclusive --verdict inconclusive, then retry once; if still not complete,waiveit so it reaches a terminal status (inconclusiveis NOT terminal — leaving it inconclusive would makefleet.py pendingre-list it forever):fleet.py waive {slug} --reason inconclusive-after-retry. Each--status inconclusiveupdate bumps the row's durableretriescount in the ledger (survives compaction) — the retry policy is bounded to one retry, so onceretriesreaches 2 for a slug, waive it rather than retrying again; do not rely on in-context memory of how many times you've retried, checkretriesin the ledger.
- completed (INDEX flipped
Close
python3 …/fleet.py sweep→ prints[FLEET-COMPLETE]or[FLEET-INCOMPLETE:{slug}:{reason}].- Report a slug → status table and the incomplete list.
- Pausing across sessions: before an intentional mid-fleet stop, run
fleet.py pause(preserves the resume handle; the Stop gate will not block). Resume next session with/beacon:fleet(no args) orfleet.py pending. - A source that genuinely cannot complete:
fleet.py waive {slug} --reason {why}. - Abandon the fleet:
fleet.py close.
If you stop with unresolved sources and have not paused, the fleet-sweep.sh Stop hook blocks
with [FLEET-SWEEP-PENDING:…] — finish, waive, pause, or close.