Repository navigation
fix(manager): stamp event ids with the run identity readers validate - #72
Huang-404-Q wants to merge 1 commit into
Conversation
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… open question Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Upper9527
left a comment
There was a problem hiding this comment.
The explicit run identity is useful for the embedded dashboard, but it introduces a regression in the standalone reader. I tested this on current main with this PR applied, including the new tests (which pass).
lh-harness run --log-dir /.../custom/logs now stamps the reserved run ID. However, run_web_server(log_dir=...) still sets its run ID to Path(log_dir).parent.name (custom), so opening that same directory with lh-harness web --log-dir ... rejects every new event. In an HTTP reproduction through the actual standalone server setup, the legacy path-derived record yields 1 event, while the new configured run ID yields 0.
Please persist and resolve one canonical run identity across both embedded and standalone readers, with a backward-compatible fallback for existing logs. Add integration coverage that writes through the CLI/config path and reopens through web --log-dir, including snapshot, replay, and reconnect behavior. The current tests give the EventTailer the desired ID directly and therefore miss the reader/writer disagreement. Keeping this unmerged until that regression is addressed.
…aders The CLI stamped event ids with the reserved run id, but the standalone reader derived its id from the log directory's parent, so `lh-harness web --log-dir` rejected every event of a run started with a custom --log-dir. Thread the reserved run id through HarnessConfig, stamp event ids with it, and persist it as run_id.txt beside the events. Both run_web_server and DashboardState.current_run_id resolve that file first and keep the path-derived fallback for logs written before it existed. Adds tests for the persisted identity and the legacy fallback.
de85ae7 to
972fe2e
Compare
|
@Upper9527 Thanks — rebuilt from current main so the diff is only the run-identity change, and addressed the reader/writer disagreement:
Added tests for the persisted identity and the legacy fallback. The event-append path needs POSIX ( |
Upper9527
left a comment
There was a problem hiding this comment.
Re-reviewed 972fe2e. Persisting the identity and using it in standalone readers addresses the earlier writer/reader disagreement, but the new resolver introduces an unsafe read in the dashboard/API path.
resolve_run_id() directly calls Path.read_text() on a worker-writable file. I reproduced both: a run_id.txt symlink to an outside file is accepted as the run identity; replacing it with a FIFO blocks the call indefinitely (the reproduction subprocess was killed after a 1-second timeout). The read is also unbounded, unlike the surrounding hardened metadata readers.
Use the existing anchored no-follow opening primitive, require an unaliased regular file, cap the byte length, and validate the run-ID syntax. Reject malformed/unsafe identities and retain the legacy fallback. Add real standalone HTTP snapshot/event replay coverage plus symlink, hard-link, FIFO, and oversized-file rejection tests. Also scope _RUN_EVENT_ID with a ContextVar token and reset it in a finally in the public run boundary: setting it without reset leaks the prior identity to subsequent direct event writes in the same async context. Keep this unmerged until those boundaries are covered.
What this fixes
With a custom
--log-dir(anything outside<runs-root>/<run-id>/lh_harness), the dashboard's event feed stays empty for a healthy run: every record is silently dropped withevent_id does not belong to the requested run.Why: the worker stamps event ids from the event log's grandparent path component (
manager.py_append_event):but the dashboard/API validates each id against the run id it derives — the reserved id under
--runs-root, orlog_dir.parent.namefor a pinned--log-dir. Those only coincide for the default layout. Concretely,lh-harness run --log-dir /x/myrun --dashboardstamps idsmyrun:000001…while the embedded dashboard reads with the reserved id20260828T000000Z_abcd1234— the strict identity guard (webapi/events.py) then rejects every record, so REST replay, WebSocket deltas, and the snapshot's last-200 events all come back empty. The standaloneweb --log-dirpath hits the same wall through its"local"fallback.The change
HarnessConfiggains an optionalrun_id— the reader-facing run identity._append_eventacceptsrun_event_idand prefers it over the path-derived stamp; every manager call site passesconfig.run_id.Tests
tests/test_event_run_id.py(3 tests):run_idoverrides the path-derived stamp;Red/green verified: the first and third fail on
main(empty feed for a pinned--log-dir), all pass with the fix. Full suite: 408 passed, 1 skipped; ruff clean on the touched files.