Skip to content

Stage 12 stores not wired into production dispatch path (blocked on installer spec) #17

Description

@scc-tw

Stage 12 of the runtime redesign landed FileBackedEpochStore and FileBackedNonceStore (commit 2fddbef) with 11 unit-level tests covering roundtrip, monotonic rollback denial, corruption, and atomic persist. The stores are correct in isolation but are not yet wired into any production call path.

What's missing

Epoch store

runtime/src/vm_stub_entry.cpp still passes RuntimeEpochState{2, 1} as hard-coded numbers when calling accept_package. Across process restarts, minimum_accepted_epoch resets to 1, breaking the anti_downgrade_epoch monotonic guarantee from internal research doc 06 §10. A previously-advanced floor is lost on reboot, so an old package whose anti_downgrade_epoch is behind the in-memory floor gets re-accepted.

Nonce store

runtime/src/tokens.cpp's accept_reprovision_token / accept_migration_token take NonceStore& by reference. The only caller is test_tokens.cpp, which uses InMemoryNonceStore. No production site exists yet. When a production caller lands, it would currently lose every consumed nonce on process exit, breaking the replay-protection rules in internal research doc 10 §6.3 and doc 15 §9 #9.

Why this is not "just fix the call site"

The wiring patch is small (~20 lines + a process-level singleton for the two stores + a config knob for the path). But it requires decisions that belong in an installer spec, which does not exist yet:

  • Where does the file live? per-user (%LOCALAPPDATA% / $XDG_STATE_HOME / ~/Library/Application Support/)? per-machine? inside the artifact bundle (wrong — defeats per-install replay protection)? an install-time-seeded runtime data directory?
  • Who owns the path? CLI override for tests / debug? env var? compile-time constant? install-time parameter written to registry / plist / sysctl?
  • First boot (file missing): current behavior is EpochState{0, 0} treated as fresh state, i.e. the first signed package seen by a fresh install sets the floor. Probably correct, but needs to be stated as policy rather than an accidental default.
  • Corrupt-file policy: StoreError::Corrupt is returned to caller; should the runtime fail-closed or re-seed with fresh state?
  • Multi-process concurrency: std::mutex protects a single process. Across processes, atomic rename preserves file consistency but "latest write wins" loses a writer's consumed nonces.
  • Upgrade path: no v2 format migration story yet.

Full write-up in internal research doc 17 (runtime local-state wiring).

Suggested PR sequence (once installer spec lands)

  1. P1: runtime_init() layer instantiates both stores (test path uses in-memory, production uses file-backed behind a feature flag).
  2. P2: production path reads env var / config for store location; FileBackedEpochStore / FileBackedNonceStore hooked in.
  3. P3: installer seed() entry points on both stores.
  4. P4: store format v2 + migration hook.

Blocked on

  • Installer / deployment spec (does not exist).

Out of scope

  • Changing the Stage 12 store APIs themselves.
  • Highsec-specific TPM-sealed store (separate issue when we're ready to talk about provider-backed storage per internal research doc 14 §10).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions