Skip to content

VNEXT-PERSIST-001: Append-only evidence persistence + replay parity #54

Description

@Thunderkill016

Goal

Per R3 research (#49) — workstream C, FIRST before any UI: the learner's evidence log must survive reload and replay into the same projection and same claim.

Contract

  • users/{uid}/vnext_events/{eventId} — doc id = EvidenceEvent.id.
  • CREATE + READ only — update AND delete denied (stricter than lesson_events): evidence is immutable, no client can rewrite history.
  • owner_id pins path uid; learner_id must equal uid — evidence for another learner is a forgery.
  • Fields: id, owner_id, learner_id, capability_id, task_id, task_revision, event_type, modality, occurred_at (number), recorded_at (timestamp), schema_version=1, policy_version, mission_run_id, context, attempt, support, feedback, evaluation, binding.
  • occurred_at (client-observed, drives lag) vs recorded_at (server arrival) are never conflated.

Adapter — src/vnext/persist.js

  • appendVnextEvents(fs, uid, events, {missionRunId, policyVersion}) — per-event transaction: absent → create; identical content → dedupe (lost-ack retry is a logical no-op); different content under same id → hard conflict, never overwrite.
  • loadVnextEvents(fs, uid) — canonical order (occurredAt, id).
  • Same fs surface as cloud-compat → emulator, fake, or real SDK.

Tests

  • tests/vnext-persist.test.mjs (fake fs): round-trip provenance, append→reload→replay parity (projection + claim identical), exactly-once retry, id-conflict throws, out-of-order canonicalization, learner isolation.
  • tests/firestore-vnext-emulator.test.mjs (real rules): owner CRUD, update/delete denied for owner too, cross-owner+anon denied, learner_id≠uid denied, malformed docs denied, e2e persist→reload→replay→identical claim.

Research basis: issue #49 round 3 — "persistence before UI; if offline/retry can duplicate learning evidence, UI can mint INDEPENDENT by accident."

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions