## Summary
- monitor the proxied OpenCode health endpoint from the stable
ArchiveBox parent page
- reload the iframe once after an unavailable -> healthy transition
- trigger an immediate check again when the browser comes online or the
tab becomes visible
## Why
A real RC416 -> RC417 DigestBox restart left the already-open OpenCode
1.17.14 SPA showing its fatal error page against the newly started
OpenCode 1.17.15 server. A full page reload recovered immediately. The
parent ArchiveBox document survives the container restart, so it can
perform that one iframe reload automatically after the server is healthy
again.
## Verification
- `test_opencode_agent_superuser_gets_admin_wrapper` passes with
assertions for the recovery monitor
- focused pre-commit hooks pass
- real stale-tab restart reproduction will be repeated on DigestBox
after release
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Reloads stale OpenCode iframes after the ArchiveBox server recovers from
a restart, so the previously fatal error page is replaced automatically.
The parent page polls the OpenCode health endpoint every 3 seconds,
reloading the iframe once when the server transitions from unavailable
to healthy or when the server version changes, and also re-checks
immediately when the browser comes online or the tab becomes visible.
- Health monitoring uses a separate endpoint that reports status without
starting the server; recovery restarts a running but unhealthy OpenCode
process, and polling skips while hidden when the server is down.
**Verification**
- `test_opencode_agent_superuser_gets_admin_wrapper` passes with
assertions for the recovery monitor.
- Focused pre-commit hooks pass.
<sup>Written for commit a33b333b6a.
Summary will update on new commits.</sup>
<a
href="https://cubic.dev/pr/ArchiveBox/ArchiveBox/pull/1860?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
## Summary
- return OpenCode SSE headers before waiting for a stopped server to
restart
- run reconnect-driven OpenCode startup in a non-thread-sensitive worker
inside the async stream
- remove the obsolete global `ThreadSensitiveContext` monkeypatch now
that asgiref 3.12.1 implements non-blocking shutdown upstream
- add a real ASGI regression test that holds the real startup lock and
verifies headers arrive before restart can finish
## Why
After deploying RC416, a stale `/admin/agent` tab successfully recovered
across the container restart, but Daphne logged three
`CurrentThreadExecutor already quit or is broken` exceptions while early
EventSource reconnects were cancelled during synchronous OpenCode
startup. Normal proxy traffic subsequently returned 200 and no data was
lost, but the request cleanup path was not clean.
## Verification
- `uv run pytest archivebox/tests/test_opencode_agent.py -q` — 15 passed
- focused SSE tests after final refactor — 2 passed
- `uv run prek run --all-files` — passed
- no OpenCode server remained after fixture teardown
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Makes OpenCode SSE reconnects return headers before the stopped server
finishes restarting, so early EventSource reconnects no longer cancel
while startup runs on a blocked ASGI request thread. This removes the
`CurrentThreadExecutor already quit or is broken` exceptions Daphne
logged after container restarts.
- Runs reconnect-driven OpenCode startup in a non-thread-sensitive
worker inside the async stream instead of blocking the request thread.
- Surfaces OpenCode startup failures as an error event on the SSE stream
instead of returning an error response.
- Removes the obsolete global `ThreadSensitiveContext` monkeypatch from
`archivebox/core/asgi.py`; asgiref 3.12.1 handles non-blocking shutdown
upstream.
- Adds an ASGI regression test that holds the real startup lock,
verifies headers arrive before restart can finish, avoids starting a
background server, and joins the startup worker before teardown.
<sup>Written for commit 7d7e219962.
Summary will update on new commits.</sup>
<a
href="https://cubic.dev/pr/ArchiveBox/ArchiveBox/pull/1859?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
## Summary
- remove archivebox update and internal pseudo crawl URL paths
- parse submitted documents directly through abx-dl and project
discovered snapshots at depth zero
- keep ArchiveBox ownership at Crawl to Snapshot while abx-dl owns
Snapshot to ArchiveResult execution
- replace queued ArchiveResult search backfills with indexed
missing-result discovery and snapshot-scoped execution that leaves
sealed snapshots sealed
- make update schedules direct maintenance dispatches instead of
synthetic crawls
- keep filesystem migrations explicit, resumable, keyset-batched, and
indexed by fs_version
- preserve live Process and ArchiveResult projection for the progress UI
## Related PRs
- ArchiveBox/abx-dl#21 provides direct input parsing and explicit
event-bus orchestration
- ArchiveBox/abx-plugins#60 removes the obsolete pseudo URL and Sonic
consolidation branches
## Verification
- abx-dl full suite: 167 passed
- ArchiveBox runner and ArchiveResult projection suite: 89 passed
- add, API, and UI input coverage: 78 passed
- schedule suite: 9 passed
- filesystem migration coverage: 9 passed
- live progress coverage: 16 passed
- real https://sweeting.me abx-dl run: 80.74 seconds, 34 succeeded, 11
noresults, 0 failed, no surviving processes
- commit hooks and diff checks passed
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Simplifies snapshot orchestration by having `abx-dl` parse crawl inputs
and run snapshot hooks directly, replacing internal pseudo-URLs and
pre-created `ArchiveResult` queues. Scheduled maintenance now dispatches
directly, while concurrent snapshot completion preserves retry work
owned by the active run.
- Store submitted URLs and imported documents directly on `Crawl`;
remove pseudo-URL and input-root snapshots, and reject multiline URL
items.
- Keep Crawl-to-Snapshot ownership in ArchiveBox while `abx-dl` owns
Snapshot-to-ArchiveResult execution.
- Discover missing indexed results and dispatch snapshot-scoped
maintenance for sealed snapshots without changing their lifecycle.
- Preserve unbounded maintenance pagination and run filesystem
migrations explicitly in resumable keyset batches using indexed
`fs_version`.
- Bound retry scheduling and correlate completion leases so stale or
concurrent completions cannot consume newer retry work.
- Preserve live `Process` and `ArchiveResult` projections for progress
reporting.
**Migration**
- Apply the database migration before rollout; it removes `current_step`
and adds the `fs_version` index.
<sup>Written for commit a29dd2edbc.
Summary will update on new commits.</sup>
<a
href="https://cubic.dev/pr/ArchiveBox/ArchiveBox/pull/1853?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->