Auto-generated from
CHANGELOG.mdat the repo root. Edits to this file will be overwritten on the next docs build.
All notable changes to ARCIVE. Versions track the phases in
docs/00_MASTER_PLAN.md §3.
The format follows Keep a Changelog. Versioning matches the master plan’s phase ladder (V0, V0.1, V0.2, …) — so 0.1.0 is the V0.1 release, 0.2.0 is V0.2, and so on.
Unreleased — V0.3 in progress
Added
- Mobile Universe — Skia renderer + Obsidian-style layout
(
feature/mobile-universe, 2026-05-06). Migrated the mobile graph fromreact-native-svgto@shopify/react-native-skia(GPU-backed, Expo-Go bundled). Continuous d3-force with ambient drift; long-press-and-drag a node pins it viafx/fyso connected nodes follow via the link force; tap-to-focus dim- everything-else;forceRadialpushes orphan nodes onto an outer ring (Obsidian’s globe silhouette); pinned “You” anchor at canvas centre. Filter persists viaAsyncStorage. Auto-fit-to-viewport on first paint, double-tap to re-fit.
Pending:
- Voice talk-back client on mobile (port web Pipecat client to RN).
- MCP wiring on the voice service for in-call retrieval.
- Real end-to-end pipeline test on a deployed Supabase.
- Group conversation mode (LiveKit transport,
interject()). - DoA fusion with Pyannote re-ID.
- App Store / Play Store submissions (deferred with the Apple Developer account decision until release prep).
0.2.0 — 2026-05-04 — V0.2 (mobile slice + cross-platform polish)
V0.2 closes out with the Expo mobile app, the audio transcode worker, and a cross-platform polish pass that makes the recording → transcript flow continuous and offline-tolerant on every device.
Added
- Expo mobile app (
apps/mobile/, SDK 54 + Expo Router 6) — magic- link sign-in (with the same dev-skip path the web has), Today feed grouped by date bucket, full-text search across transcript + summary, Memory detail with audio playback + drag-to-seek progress bar, share-to-space, delete, sign-out. Press-to-record dictation viaexpo-audio. Routes to the same hosted Supabase as the web app — no LAN trickery. - Audio transcode worker (Modal,
backend/workers/audio-transcode/) — every uploaded recording is always re-encoded to m4a/AAC for cross-device playback (iOS AVPlayer can’t decode Opus, Android can’t decode some Apple-MIME containers). ingest-audio fires the worker per upload; a 10-minute cron sweeper catches anything missed. Single source of truth for “what plays everywhere”:recordings.playback_storage_path. Both web and mobile audio readers prefer it when set. - Offline upload queue (
apps/mobile/lib/upload-queue.ts) backed byexpo-sqlite. Recorder always enqueues first then triggers a flush — so the row appears in Today the moment recording stops, whether online or off. Flush retries on app foreground + every 30s while there are pending rows. Each recording is persisted to a unique path underdocumentDirectory/arcive/pending/immediately after stop, so consecutive recordings can’t overwrite each other’s bytes. - Flow continuity for recordings. Pending row stays visible
through the entire upload → transcribe → memory pipeline,
transitioning “Uploading…” → “Transcribing…” → real memory row.
When the matching
memoriesINSERT arrives via Realtime, the pending row is dismissed in the same frame the real one appears. No more “row vanishes for 5 seconds, comes back” gap. - Per-recording resume position via AsyncStorage. Player resumes mid-clip after navigating away or relaunching. Saves on pause/stop and every 5s while playing.
- Single global audio player (
apps/mobile/lib/audio-context.tsx) — oneuseAudioPlayerinstance shared across Today inline rows and the Memory detail screen. Fixes the iOS bug where two per-row players step on each other and one never reachesisLoaded: true. Cross-screen continuation works for the same memory; tapping into a different memory’s detail stops the previous audio. - Resend SMTP for magic-link delivery (sender
noreply@send.arcive.io, verified via SPF + DKIM + MX). Replaces Supabase’s built-in 4-emails-per-hour shared sender. - Subtle animations on the mobile feed (built-in RN
LayoutAnimation+Animated; no Reanimated/worklets dep): rows fade/slide on update, dot pulses on Uploading→Transcribing, record button breathes while capturing. - Offline browse + on-device search. Last unfiltered fetch is cached in memory; on network failure the feed falls back to filtering that cache locally with the same ILIKE behaviour. Subtle red banner indicates locally-cached results.
- MCP wiring on
/api/chat— whenMCP_SERVER_URLis set, retrieval routes through the internal MCP server instead of running inline. Falls back to the existing inline path when unset or unreachable. - Consent gate on agent retrieval —
search_memories_semanticandmatch_memoriesaccept a newrespect_consentparameter. MCP server tool and/api/chat’s inline-fallback path always passtrue; user-facing search keeps the defaultfalse. See ADR-0007. - Per-role system prompt lookup in voice service. Resolves the
prompt from the
rolestable byrole_idquery param (RLS scopes to built-in + own roles), appends the sharedVOICE_MODE_ADDENDUM, falls back to the Reviewer default. Voice channel can now run any built-in or user-authored role without code changes.
Changed
- Hosted-Supabase only. Dropped Path A (local Supabase / Docker)
from setup. Removed
db:start,db:stop,db:reset,functions:servefrom root scripts; keptdb:push,db:diff --linked,functions:deploy. README, env templates, mobile setup, and01_SOFTWARE_PLAN §1.7updated. - Realtime client wiring. Both web and mobile now call
realtime.setAuth(jwt)before.subscribe()so the channel join payload carries the user JWT — required by the newsb_publishable_*key model. Without this, the WS connected anonymously and RLS-scoped postgres_changes silently never arrived. - Audio playback identity moved from URL to
memoryIdin inline- detail players, so a 5-minute signed-URL refresh doesn’t mis- identify the active row.
Fixed
- Empty-string sentinel for
playback_storage_pathswapped forplayback_content_type = 'missing'so consumers’||fallback tostorage_pathworks cleanly. - Periodic position-save interval in the audio context was being
torn down and re-installed on every position tick (deps included
currentTime); now reads live status from a ref and gates the effect onplayingonly — the 5s callback actually fires now. flushPendingUploadshas a top-levelflushingguard so concurrent foreground + pull-to-refresh + AppState-active triggers can’t all walk the queue in parallel and mint duplicaterecordingsrows.- Recorder no longer reuses a single temp file path. Persists each take to a unique URI immediately after stop; the queue uploads what was actually recorded, not whatever’s in the slot when the network came back.
Production hardening (landed in this release)
- pgmq DLQ + max-retry policy. Sibling
pipeline_jobs_dlqqueue +pipeline_dead_lettersdiagnostics table +pipeline_stuck_jobsview.pipeline-tickenforces the retry ceiling at the dispatch boundary (PIPELINE_MAX_RETRIES, default 5). 30-day TTL on diagnostics (pruning job is a follow-up). See ADR-0008. - Rate limits on Stripe + ingest routes. New
consume_rate_limit(p_uid, p_bucket, p_cap, p_window_seconds)RPC. Stripe checkout/portal: 10/hour/user. Ingest-audio: 15/min/user. Stripe webhook unchanged (signature-gated). - Explicit Sentry captures. Hand-rolled Deno envelope helper
for Edge Functions (no @sentry/deno dep); used by
pipeline-tick(on dead-letter promotion), all 6 step functions,ingest-audio,delete-memory. Web app captures wired into/api/chatdriver errors and the three Stripe routes via@sentry/nextjs. dev_passproduction prep. Default flipped tofalse; existing rows bulk-updated.<DevPassSection />hidden whenNODE_ENV === "production"; the server action refuses there too (defense-in-depth). Vault placeholderservice_role_keyremoved by migration with aRAISE WARNINGpointing at the SQL to set the real value.- MCP server in CI. Standalone
pnpm install --ignore-workspacepnpm typecheckstep onbackend/mcp/arcive-memory-mcp/.
- Universe pagination. Keyset on
recorded_atdesc via?before=<iso>. Edges restricted server-side to those with both endpoints in the visible window — closes the silent 2000-edge cap.
Deferred to release prep
- Apple Developer account + EAS development build → gates background- audio capture (always-on listening), BLE pairing, TestFlight, and store submission. Punted on 2026-05-04 to keep the iteration loop in Expo Go.
- App Store / Play Store submissions.
- Mobile background capture + Universe view + voice talk-back client
- role conversations + BLE pairing UX.
0.2.0-rc.1 — 2026-05-03 — V0.2 (web slice + voice scaffold)
V0.2 web-only scope. Mobile app and store submissions are not in this RC.
Added
- Claude Agent SDK driver (
packages/agents/src/drivers/claude-agent-sdk.ts) — tool use + streaming + prompt caching. The model invokessearch_memoriesonly when it needs context. Drop-in swap behind theAgentDriverinterface. - Tutor, Brainstorm Partner, Caregiver built-in roles.
- Spaces UX (Family tier) — list, create, member view, token-based invite links, share-to-space toggle on memory detail. RLS lets members read shared memories.
- Family Stripe price — checkout accepts
{tier: "pro" | "family"}, webhook readsarcive_tierfrom subscription metadata to flip the right tier. - Tool-call indicator in chat UI (“Searching memories for X…”).
- Internal MCP server scaffold (
backend/mcp/arcive-memory-mcp/) —search_memories,get_person,timeline_windowtools, Streamable HTTP transport, Supabase JWT auth. - Voice talk-back service (
backend/workers/voice-talkback/) — Pipecat orchestrator: Deepgram Nova-3 → Claude Haiku 4.5 → Cartesia Sonic. WebSocket transport with Silero VAD./talkbackweb client uses the Pipecat JS client SDK. - Spoken-register system prompt +
composeVoiceSystemPrompt(role)helper so any role’s prompt can be composed with phone-call register rules. - Dev pass —
user_profiles.dev_passshort-circuits all tier gates and usage caps. Settings has an On/Off toggle.<ProBadge />still shows on premium features so you can see what would be gated in production. /aboutpage — version, build SHA, phase status, changelog link.
Changed
/api/chatswitched from stateless RAG to the Claude Agent SDK driver.- Settings shows three checkout CTAs (Upgrade Pro · Family · Switch to Family) based on current tier.
- Universe and Spaces stop blocking free users; instead they render content
with a
Pro/Familybadge in the header.
Fixed
- Server-side billed duration in
ingest-audio(floors to byte-size estimate, caps at 30s/chunk per the contract). Client can no longer under-report duration to dodge the cap. - Conversations persist to
role_sessionsand rehydrate from?session=<id>in the URL. - Per-tier
/api/chatrate limit (50 free / 500 pro per day). - Storage cleanup on memory delete via
delete-memoryEdge Function.
0.1.0 — 2026-05-03 — V0.1 (pipeline + retrieval + first AI features)
Added
- pgmq queue + pg_cron drain replacing the synchronous transcribe chain.
Step workers:
transcribe,diarize,reid,summarize,embed,compute_edges. Each idempotent and retryable. - Diarization — Deepgram Nova-3 batch fills
memory_participantsrows. - Speaker re-ID — Pyannote.audio worker scaffold on Modal
(
backend/workers/pyannote-reid/). Cosine match againstpeople.voice_embedding; auto-creates “Unknown speaker” when no match. - Voyage-3-lite embeddings + HNSW index on
memories.embedding. - Semantic search on the Today search box (merges with FTS).
- Markdown export — single memory + full archive.
- Universe view —
react-force-graph-2dovermemory_edges. - Reviewer role — first AI feature, stateless RAG driver, streaming chat UI with “memories used” drawer.
- Stripe Pro tier — checkout, billing portal, webhook handling.
- Tier gates +
consume_recording_secondsRPC for monthly cap. - PostHog feature flags — server-side
isEnabled()helper.
Changed
- Hardened the pgmq migration with extension-/vault-fallback DO blocks so a missing extension can’t abort the migration suite.
0.0.1 — 2026-05-03 — V0 (web PWA dictaphone)
Added
- Next.js 15 PWA — Tailwind, magic-link auth, consent screen, Today feed with FTS search, memory detail, settings.
- Recorder —
getUserMedia+MediaRecorder, posts to/functions/v1/ingest-audio. Pulsing “Recording” badge for the consent contract. - Edge Functions —
ingest-audio(accepts phone and hardware uploads on the same endpoint per master plan §6.1) andtranscribe-step(Groq Whisper-large-v3-turbo). - V0 schema — people, devices (with full variant enum), recordings,
memories, edges, roles, sessions, spaces. Auto-create
user_profileand “Self” person on signup. - Realtime — Today feed live-refreshes on insert/update, no polling.
- PWA layer — manifest, service worker (offline shell), placeholder icons (192/512/maskable + apple-touch).
- CI — GitHub Actions runs
pnpm -r typecheck+pnpm --filter web buildon push and PR. - Observability + billing scaffolds — PostHog, Sentry, Stripe customer pre-create. All no-op without env keys.
- Shared contracts — Zod API contracts + BLE UUID placeholders for the firmware track.