feat(storage): add portable session artifact gateway
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
# ADR 0033: Central session artifacts and bounded operator-host cache
|
||||
|
||||
Date: 2026-07-30
|
||||
Status: accepted and implemented
|
||||
|
||||
## Decision
|
||||
|
||||
Mission Core stores portable recorded-session products in a provider-neutral,
|
||||
content-addressed artifact store. The current central provider is the existing
|
||||
Synology SMB mount:
|
||||
|
||||
```text
|
||||
/Volumes/docker/nodedc-mission-core/artifact-store
|
||||
```
|
||||
|
||||
This is product runtime data. It is not a deploy artifact, a Map Gateway cache,
|
||||
a Device Plane package, or a new Docker service. Authentication remains owned
|
||||
by the operating-system SMB mount; Mission Core does not receive a NAS password.
|
||||
|
||||
Every immutable object is stored under:
|
||||
|
||||
```text
|
||||
objects/sha256/<first-two-hex>/<full-sha256>
|
||||
```
|
||||
|
||||
Canonical JSON manifests are themselves addressed by SHA-256. Mutable names
|
||||
exist only as small, atomically replaced references:
|
||||
|
||||
```text
|
||||
refs/<namespace>/<key>.json -> manifest SHA-256
|
||||
```
|
||||
|
||||
An operator host never serves a central SMB file directly. It first streams the
|
||||
object into a temporary local file, proves the expected SHA-256 and byte length,
|
||||
and atomically publishes it into:
|
||||
|
||||
```text
|
||||
<MISSIONCORE_DATA_DIR>/artifact-cache
|
||||
```
|
||||
|
||||
The local cache has:
|
||||
|
||||
- an 8 GiB default byte quota;
|
||||
- a 2 GiB default free-space reserve;
|
||||
- persistent SQLite metadata;
|
||||
- persistent pin sets;
|
||||
- LRU eviction of unpinned objects only;
|
||||
- no automatic deletion of source evidence;
|
||||
- offline resolution through locally sealed reference and manifest snapshots.
|
||||
|
||||
The limits are configurable with:
|
||||
|
||||
```text
|
||||
MISSIONCORE_ARTIFACT_CACHE_MAX_BYTES
|
||||
MISSIONCORE_ARTIFACT_CACHE_FREE_SPACE_RESERVE_BYTES
|
||||
```
|
||||
|
||||
The central root is configured with:
|
||||
|
||||
```text
|
||||
MISSIONCORE_ARTIFACT_STORE_ROOT
|
||||
```
|
||||
|
||||
## Recorded playback behavior
|
||||
|
||||
The base RRD and integrated E10 overlay are separate immutable roles in one
|
||||
recorded-session manifest.
|
||||
|
||||
On a normal cache hit, recorded playback uses the existing private RRD cache.
|
||||
On a private-cache miss it may restore the exact `base-rrd` role from the
|
||||
bounded artifact cache. Restoration is admitted only when:
|
||||
|
||||
- the manifest type and subject match the requested session;
|
||||
- the RRD content digest and length match the manifest;
|
||||
- the local source evidence still hashes to `base-source-sha256`;
|
||||
- the manifest carries the exact session timeline bounds.
|
||||
|
||||
The restored RRD is republished through the existing private recording-cache
|
||||
transaction and receives a fresh sidecar bound to the current local evidence
|
||||
stats. The exporter is not run.
|
||||
|
||||
The integrated-perception endpoint resolves
|
||||
`integrated-overlay:<recording-id>` before scanning or validating local worker
|
||||
results. A sealed central/local CAS hit therefore needs neither Worker 006 nor
|
||||
the original E10 result tree. Invalid central metadata fails closed; a genuinely
|
||||
absent central role can still use the existing local materialization path.
|
||||
|
||||
## Persistent pins and offline use
|
||||
|
||||
The CLI surface is:
|
||||
|
||||
```bash
|
||||
k1link artifact publish ...
|
||||
k1link artifact pin ...
|
||||
k1link artifact unpin ...
|
||||
k1link artifact resolve ...
|
||||
k1link artifact status ...
|
||||
```
|
||||
|
||||
Pinning is a local operator-host decision. A pin downloads and verifies every
|
||||
member of the selected manifest. If any member fails, the new pin is removed;
|
||||
objects already downloaded remain ordinary unpinned cache entries.
|
||||
|
||||
When the central root is unavailable:
|
||||
|
||||
- a sealed local reference, manifest, and object resolve normally;
|
||||
- an absent local object returns an explicit offline-cache error;
|
||||
- Mission Core does not silently fetch from Worker 006 or start a heavy AI run.
|
||||
|
||||
## RAVNOVES00 migration acceptance
|
||||
|
||||
The source session is `20260720T065719Z_viewer_live`, displayed as
|
||||
`RAVNOVES00`.
|
||||
|
||||
The accepted central reference currently points to:
|
||||
|
||||
```text
|
||||
092f758c09965be98fd76d8191474c528ee20540dce5f4761c2a087f6056a6d5
|
||||
```
|
||||
|
||||
It contains nine logical roles totaling `721626746` bytes:
|
||||
|
||||
- the source evidence archive;
|
||||
- the base RRD and its original audit sidecar;
|
||||
- the accepted E10 result archive;
|
||||
- the compute-job manifest;
|
||||
- the LiDAR pack and its manifest;
|
||||
- the sealed integrated overlay and its sidecar.
|
||||
|
||||
The host pin is:
|
||||
|
||||
```text
|
||||
session:20260720T065719Z_viewer_live
|
||||
```
|
||||
|
||||
Acceptance facts:
|
||||
|
||||
- all nine roles are cached and pinned;
|
||||
- base RRD SHA-256:
|
||||
`4db5f2519caa61aca3683499094329b35cf3c24d1cc242953c54d2a228762e13`;
|
||||
- base source SHA-256:
|
||||
`70da0edad5cbf0e89b6e2355c0aac294f8c36a67249cd33b8918353fd88c83af`;
|
||||
- overlay SHA-256:
|
||||
`c2bb73fca8bb616a3929df236c6dc63d071b6466a6ca57d06487ef18ed985b57`;
|
||||
- an offline overlay resolve completed in 0.76 seconds;
|
||||
- an isolated offline base restore produced the exact RRD without invoking the
|
||||
exporter;
|
||||
- an isolated offline overlay materialization succeeded with nonexistent local
|
||||
worker-result, job, and LiDAR roots.
|
||||
|
||||
The migration was copy-only. Existing evidence, derived recordings, accepted
|
||||
worker results, and historical overlay generations were not deleted.
|
||||
|
||||
## Resource boundary
|
||||
|
||||
Artifact publication, fetch, hashing, and restoration are sequential and use a
|
||||
1 MiB streaming buffer. They do not start Docker or parallel workers. This is
|
||||
the required operating envelope for the 14-inch 2023 MacBook Pro with 18 GiB
|
||||
RAM used as the current combined operator and test host.
|
||||
Reference in New Issue
Block a user