diff --git a/docs/OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md b/docs/OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md index 1a902cf..ff9424a 100644 --- a/docs/OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md +++ b/docs/OBSERVATORY_REALTIME_PROFILES_EXECPLAN.md @@ -54,6 +54,26 @@ compute packages/registries сохранены. Старые agents stopped/rest Следующий шаг: verified published-cache projection. Этап1 по-прежнему открыт; готовый cache/selector/progress и полный расчёт записей ещё не доказаны. +**Третий инкремент, 2026-09-03: verified cache реализован в коде.** Каталог и +preflight принимают только successful/published job с точным source snapshot, +RunDefinition, Session provenance и целым пакетом артефактов. Фронтенд читает +проверенную привязку вместо прежнего запрета непустых `existing_results`. +Готовый результат доступен без dispatch/подготовки raw source; повреждённый +не скрывает возможность нового расчёта. Повторный submit и гонка с публикацией +защищены внутри queue INSERT transaction; холодная проверка больших файлов +требует Refresh и не выполняется под write lock. История не удаляется. + +120 focused backend tests,23 frontend/architecture tests, Ruff, mypy пяти +source files и focused TypeScript check PASS. Полная production build и browser +QA **пока не выполнены**: Mac memory-pressure=2 при swap~7.6–7.8GiB, чужие постоянные +сервисы не остановлены. Canonical8000/PID57796 оставлен на прежнем согласованном +backend/frontend release, health200; новый cache ещё не активирован. Worker, +модели и живые очереди не изменялись. Полный LAB-run не запускался. +[Проверки и следующий шаг](../experiments/perception/OBSERVATORY_PUBLISHED_CACHE_2026-09-03.md). +Этап1 остаётся открытым до сборки/активации согласованного release и проверки +каталога; затем этап2 — селектор, прогресс и полный цикл на записях. Не повторять +уже закрытый ремонт claim/v3 и не возвращаться к сетевым latency canary. + - Сверить каталог, очередь, публикацию и просмотр для текущих M4.9T5 и LAB V1. - Связать готовность с точной исходной записью и immutable RunDefinition, включающей image/model/config/adapter/result-contract identities. diff --git a/docs/adr/0050-recorded-observatory-first.md b/docs/adr/0050-recorded-observatory-first.md index 41d3d01..695f436 100644 --- a/docs/adr/0050-recorded-observatory-first.md +++ b/docs/adr/0050-recorded-observatory-first.md @@ -81,6 +81,39 @@ All pre-existing queue row hashes are unchanged. This repairs dispatch polling, not published-cache verification or full recorded-workflow acceptance. See the [repair evidence and rollback boundary](../../experiments/perception/OBSERVATORY_RECORDED_CLAIM_REPAIR_2026-09-02.md). +## Third increment: exact published-result cache (2026-09-03) + +Implemented in source; activation of the matching backend/frontend release is +pending the local resource gate. This does not claim a completed recorded run. + +The portable catalog now joins successful **published** queue receipts to the +current per-source catalog snapshot, immutable definition, Session publication +binding, calculation profile, package contract, central manifest and every +artifact. No matching by LAB name, operator label, or the newest 100-job page. +The queue receives two indexes, with no deletion or rewriting of history. +The existing computation identity remains the only computation key. + +An exact usable result projects `existing / open-existing`, its result ID and +path-free source/definition/package identities. It disables new submission but +does not require Worker dispatch or raw-source preparation for cached review. +Missing/corrupt artifacts do not count as coverage; the older evidence remains. +The newest verified exact candidate is returned; other versions are not hidden +from the evidence catalog or mistaken for the current calculation. + +Large immutable result objects are hashed in 1 MiB chunks on first use or file +metadata change. A bounded 4096-entry memo rechecks dev/inode/size/mtime/ctime; +normal refresh does not reread unchanged large objects. This is result-integrity +IO, not source upload, source decoding, model inference, or an FPS measurement. +The queue INSERT fence rechecks the published candidate atomically. It never +streams large files while holding the write lock: cold/concurrent/changed +verification returns HTTP409 requesting Refresh. Exact idempotency retries still +return the original job. Verified corruption permits a new request. + +The frontend's existing portable decoder now accepts only bound, internally +consistent cached results. No per-LAB page, renderer or selector implementation +was introduced. Full selector/progress/product acceptance remains stage 2. +See [verification and activation status](../../experiments/perception/OBSERVATORY_PUBLISHED_CACHE_2026-09-03.md). + ## Boundaries No Synology deployment, hardware actuation, motor integration, new capture, diff --git a/experiments/perception/OBSERVATORY_PUBLISHED_CACHE_2026-09-03.md b/experiments/perception/OBSERVATORY_PUBLISHED_CACHE_2026-09-03.md new file mode 100644 index 0000000..ac6026f --- /dev/null +++ b/experiments/perception/OBSERVATORY_PUBLISHED_CACHE_2026-09-03.md @@ -0,0 +1,92 @@ +# Observatory published-cache increment — 2026-09-03 + +## Status and scope + +Implemented and contract-tested; **not activated on canonical8000 yet**. +Implementation commit: `1e4ddc2` on `codex/m5-1-observatory` (no push). +This is stage1 source/provenance/cache work, not model or recorded-run evidence. +No Worker containers, model profiles, raw recordings, result history, capture, +network settings or physical controls were changed. No Synology deployment. + +## Contract + +- Exact key: admitted source snapshot + immutable RunDefinition (including + executor image/release, models, adapter, resource and result contracts). +- Candidate: successful queue job with durable `publication_state=published`. + Legacy `succeeded/not-required`, pending or failed publication is not a hit. +- Verify full job/source/definition/profile provenance, Session binding, sealed + package and CAS manifest identity, exact artifact inventory and file hashes. +- Return the newest usable exact result with `existing / open-existing`, + `submission_allowed=false` and path-free evidence identities. Different source, + changed snapshot or profile version remains a distinct computation. +- Existing catalog/preflight/viewer contracts are reused. No per-LAB UI branch. + Full selector filtering and progress are deliberately the next product stage. +- Cached preflight does not prepare raw data or call a Worker; read-only result + review is independent of current source compatibility/dispatch availability. + Source snapshot comparison reads the catalog, not all source media. +- Corrupt/missing/symlinked result objects do not suppress a fresh calculation. + History is retained. Cached review is not a navigation/safety acceptance. + +## IO and concurrency + +First use or changed metadata streams result objects in 1MiB chunks. Content +checks use a bounded4096-entry fingerprint memo; each lookup rechecks file +device/inode/size/mtime_ns/ctime_ns. Contracts/manifests remain independently +parsed and checked. Warm refresh does not reread unchanged large result objects. +Cold verification can cost result-store IO and is not advertised as constant-time. + +Two additive queue indexes support exact published-source and computation lookup. +Publication/INSERT races are fenced in the existing transaction. Its verifier +does not re-enter the queue DB or hash large files under the write lock. A cold, +concurrent or changed verification requests Refresh with HTTP409, never silently +creates another job. Confirmed corruption permits retry with a new key; the +original idempotency key always refers to the original job. + +## Verification + +- 120 focused backend tests PASS: portable publisher/cache, setup API/projector, + queue binding, recorded queue, Worker API, publication retry/reconciliation. +- 23 focused frontend tests PASS: portable catalog/decoder and application + architecture, sequential Node runner with192MiB heap cap. Peak RSS~108MiB. +- Focused strict TypeScript check of the portable decoder/fetch contract PASS, + 192MiB heap cap; peak process RSS~366MiB including compiler/native memory. +- Ruff on all changed Python files PASS; mypy five changed core/API modules PASS. +- Tests use synthetic filesystem/SQLite packages, not historical LAB outputs as + an inference substitute. They cover complete publish→cache→view, missing and + same-size corruption with restored mtime, symlink substitution, changed central + manifest/provenance/source/version, publication race, idempotent retry and no + source preparation/model submission when an exact result is available. +- First fixture run correctly rejected legacy `succeed()` as no publication + outbox. Fixture now exercises `complete_for_publication()` followed by actual + publisher and durable `mark_published()`; the production gate was not relaxed. +- Existing FastAPI/httpx test deprecation warning remains; dependencies unchanged. +- Legacy SQLite migration is covered: indexes are created after publication + columns are added, preserving the pre-existing job and idempotency identity. + +Reproduce backend tests with `.venv/bin/pytest -o addopts='' -q` and these files: +`tests/test_observatory_portable_result_publisher.py`, +`tests/test_observatory_portable_setup_api.py`, +`tests/test_observatory_portable_setup_projection.py`, +`tests/test_observatory_portable_queue_binding.py`, +`tests/test_observatory_recorded_jobs.py`, `tests/test_observatory_worker_api.py`, +`tests/test_observatory_publication_retry_api.py`, +`tests/test_observatory_publication_reconciler.py`. + +Frontend, from `apps/control-station`: +`NODE_OPTIONS=--max-old-space-size=192 node --test --test-concurrency=1 test/observatoryLaboratorySetups.test.mjs test/applicationArchitecture.test.mjs`. + +## Activation still required + +Mac pressure rose from1 to2 during the turn, swap~7.6–7.8GiB; no temporary heavy job +remains. Existing operator Docker services were inspected, not stopped. The +resource gate in `mission-core-product-ui` defers full build and browser QA. +Canonical8000 remains PID57796 on the previous matched release, `/api/health` +HTTP200. No listeners on8765/4173; unrelated launcher5173 is not this project. +Do not claim that the new cache is already live in the operator interface. + +After memory pressure normalizes: sequential production typecheck/tests/build, +activate the matching backend/frontend on canonical8000, verify health/catalog +and browser decoder behavior without creating inference jobs, then update this +status. Do not start a second backend or replay process. Stage2 then implements +the selector/progress/full recorded calculation and sequential M4.9T5/LAB V1 +acceptance. Neither this report nor a cached viewer FPS proves onboard realtime.