feat(storage): add portable session artifact gateway

This commit is contained in:
DCCONSTRUCTIONS
2026-07-30 10:05:48 +03:00
parent 2ab9e45548
commit e56fa0c074
11 changed files with 1889 additions and 2 deletions
+7
View File
@@ -230,6 +230,13 @@ export MISSIONCORE_RRD_FREE_SPACE_RESERVE_BYTES=2147483648
uv run k1link serve
```
Portable session products can additionally use the content-addressed central
artifact gateway described in
[`ADR 0033`](adr/0033-central-session-artifacts-and-bounded-host-cache.md).
This does not move or delete the source-of-record evidence. It adds verified
central manifests plus a quota-bound, pinnable local working set for exact base
RRDs and perception overlays.
The directories and derived recording cache use owner-only permissions where
the host filesystem permits them. A new acquisition writer is assigned only a
direct child of the private evidence root; it no longer writes a new run to the
@@ -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.