Repository navigation
Start the free Asimov collector on the writer, not the handle warm-up caught - #6472
Merged
Merged
Conversation
… caught The daemon has never ingested an Asimov journal on an install that had already registered a node. sync.py warms local_store.get_store up at boot and keeps that handle, then starts local_server, which is what calls mark_writer_owner(). Until that call, get_store answers a registered-daemon process with the dashboard's read-only _ProxyStore, so the handle the warm-up captured is a proxy. Every later caller in the daemon gets the real writer from _store_rw, but the Asimov collector is handed the stale one and refuses: RuntimeError: Asimov ingestion requires the daemon writer WARNING Asimov collection could not start. Other collectors will continue. That warning has been in this node's log on every boot since the feature shipped, and /api/asimov/runs has always been empty, so /asimov is a view that can never hold anything. The warning swallowed the traceback, which is why it read as an optional collector declining rather than a failure. Resolve the writer at start instead of trusting the caller's handle. A caller that already holds a writer keeps it. Verified on this node: with the fix hot-patched into site-packages and the daemon restarted, an imported recording now reaches asimov_runs and /asimov renders it (lab-asimov-1, Recorded, WALK, 20 joints), with no new "could not start" warning. Guard: a start() handed a read-only proxy must resolve and ingest, and a start() handed a writer must not re-resolve. Revert-proofed: without the fix the first test raises the same RuntimeError at store.py:74. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
✅ Drift Bot (ClawMetry): no drift detectedDrift Bot analyzed the changed files against this project's blueprints and requirements and found no drift. |
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.
No-PRD: fixes a shipped capability that never ran; the behaviour it restores is REQ-ASIMOV-001 in https://factory.8090.ai/project/b415065f-ab2f-4f53-8864-0c009fd098cb/requirements/a508a5c5-8821-4964-8930-3561b7d02f2b
The bug
/api/asimov/runshas always returned{"runs":[]}on this node, and the daemon log carries this on every boot since the connector shipped:The
except Exceptionlogged no traceback, so it read as an optional collector declining rather than a failure. It is a failure. Withexc_infoturned on:Why it happens
Ordering inside
sync.py::run_daemon:_startup_store = get_store(read_only=False)— but nothing has calledmark_writer_owner()yet, so for a process whose node is already registered,get_storetakes the_daemon_registered()branch and returns the dashboard's read-only_ProxyStore. The log line after it still says "owned".local_server.start()— this is what callsmark_writer_owner()and opens the real writer, caching it in_store_rw._start_asimov(_startup_store)— passes the handle from step 1.Every other caller in the daemon calls
get_store()after step 2 and gets the real writer, which is why only Asimov collection is affected. Pro's robotics ingester resolves its own store (robotics/plugin.py:43) and has been ingesting the same journals fine, which is how an Asimov run can sit inrobotics_runswhileasimov_runsstays empty.The fix
daemon.daemon_writer(store)returns the handle it was given when that handle can write, and askslocal_store.get_store(read_only=False)when it cannot. By step 3 that answers with the real writer. One function, no change to global store semantics, and no change for a caller that already holds a writer.Verification
Hot-patched into
site-packagesand restarted the daemon on this machine:/api/asimov/runsnow returns the imported run:lab-asimov-1 | asimov_recording | hardware | 95 events/asimovrenders it: robotlab-asimov-1, statusRecorded, modeWALK, 20 joint rows, zero page errorsGuards in
tests/test_asimov_daemon.py: astart()handed a read-only proxy resolves and ingests; astart()handed a writer must not re-resolve (the fakeget_storeraises if it does). Revert-proofed: without the fix the first test fails with the sameRuntimeErroratstore.py:74.Found while checking that the free Asimov view still works for installs without the Physical AI workbench (#6471).
🤖 Generated with Claude Code