Skip to content

North Star Build Plan

Single source of truth (North Star). Supersedes PROJECT_HANDOVER.md as the authoritative scope/architecture/security/roadmap document. The handover remains the verified raw-fact snapshot; this document is the elevated, atomic, testable plan built on it.

Snapshot: main @ 3531c6f · 2026-06-12 · architecture map v0.3 · product line V1.2 (Multi-Tenant Native Scaling, Sprint W27 closed) · Apache-2.0 · github.com/number7even/CONTINUUM (private at snapshot).

Document contents (three deliverables, one file, per spec): §0 Gap Analysis · §1 Ultra North Star Document · §2 Ultra Build Roadmap (atomic tasks) · §3 Validation Checklist · §4 Risk & Fallback Plan · §5 Version & Change Log.


§0 — Gap Analysis (run first, per Model Execution Contract)

Section titled “§0 — Gap Analysis (run first, per Model Execution Contract)”

The input handover is unusually disciplined (verify-before-assertion baked in). The gaps below are what separate a good handover from a North Star a weaker model can execute mechanically. Each gap is resolved later in this document at the cited section.

#Gap in PROJECT_HANDOVER.mdSeverityResolved at
G1ADRs referenced by ID (D0–D8) but rationale + alternatives not inlined; cross-cutting choices (JWT-over-OAuth, SQLite-over-Postgres, Fly-over-K8s, SSE-over-WebSocket, Path-A-over-Dolt) have no ADR at allHigh§1.4 ADRs
G2No formal threat model. Security is described prose-style, not as enumerated attack vectors with mitigation + residual riskHigh§1.5 STRIDE
G3Compliance stated as “no program exists” but no matrix mapping features→GDPR/SOC2/EU AI Act/HIPAA controlsMedium§1.6 Compliance Matrix
G4No cost model. Infra cost per component and scaling projection absentMedium§1.7 Cost Model
G5Performance numbers scattered (15.4 ms p95, 177 MB RSS) with no consolidated SLO table or benchmark methodMedium§1.8 Performance SLOs
G6”Voice AI Specifics” required by spec but handover correctly says CONTINUUM is not voice — the integration contract to ARIA/V3 is undefinedMedium§1.9 ARIA/V3 binding
G7Instructions are descriptive (“publish npm packages”) not atomic/executable (exact files, fields, commands, pass/fail)High§2 Roadmap
G8No machine-runnable acceptance suite tying claims to exit codesHigh§1.10 + §3
G9Doc-vs-code divergence (ARCHITECTURE §6 worker-daemon vs shipped direct stdio/HTTP) flagged but not given a reconciliation taskMedium§2 P6-T2
G10CODE_OF_CONDUCT.md missing (confirmed absent at snapshot); launch-blocking governanceLow (effort) / High (blocker)§2 P5-T3
G11The “~10x token savings” claim is design-intent, never benchmarkedMedium§1.8 + §2 P6-T4
G12No RPO/RTO; Fly volume is the only copy of hosted state, no backup cadenceHigh (ops)§1.5 + §2 P5-T5

Blocked-section policy (per contract): no section below is blocked. Where a fact is unverifiable at generation time it is marked ⚠️ and converted into a roadmap task that produces the verification, rather than omitted.


§1.1 North Star Principles (the non-negotiables)

Section titled “§1.1 North Star Principles (the non-negotiables)”

These nine principles govern every downstream decision. They are derived from AGENTS.md (The Nine) and the locked product identity, restated as executable law.

  1. Verify-then-dissolve is the product. No checkpoint entry may be marked active until its verifyCommand exits 0. Test: record-checkpoint rejects any entry whose verify command is absent or non-zero. The tagline is law: “the only AI memory layer that refuses to mark work done until a shell command proves it.”
  2. Append-only, hash-sealed history. Checkpoints are never mutated or deleted; corrections are new rows. Test: the ledger contains the known “broken-draft” rows a63eb576, c6291935 — their presence proves the invariant held.
  3. One engine, configuration-only customer differences. Dogfood, OSS, and ARIA V3 share identical code; only env vars differ. Test: no customer name appears in a src/** conditional.
  4. The storage seam is sacred (D2). All persistence flows through openStorage() (packages/core/src/factory.ts). Test: grep -rn "new SQLiteStorageBackend\|new HybridStorageBackend" packages --include=*.ts returns hits only inside factory.ts.
  5. Privacy filter runs before every write. Secrets are scrubbed at observation.ts:insertObservation, not at a call site. Test: scripts/privacy-smoke.mjs exits 0 (13 checks).
  6. Tenant isolation is mechanical, not promised. One tenant can never read, write, or enumerate another’s data. Test: scripts/verify-w27-isolation.mjs exits 0.
  7. Memory law: ≥150 MB headroom under the 512 MB VM budget. Test: /healthz reports process memory RSS ≤ 362 MB on the default (sqlite) backend.
  8. Zero-config for the solo OSS developer. Default config requires no external service (local SQLite, template digest, no API key). Test: continuum init && continuum start succeeds on a clean machine with no env vars set beyond CONTINUUM_PROJECT_ID.
  9. The trust-leap is the human’s (P9). The system proves; it never coerces adoption. Test (governance): SECURITY.md + CODE_OF_CONDUCT.md define a freely-chosen, safely-endable contributor path.

§1.2 Mandatory Deliverables (definition of the launch)

Section titled “§1.2 Mandatory Deliverables (definition of the launch)”

The V1 OSS launch is done when, and only when, all of the following are simultaneously true (each is a pass/fail gate, cross-referenced to §2 tasks and §3 checklist):

IDDeliverablePass conditionRoadmap task
MD1npm packages publishednpm view @continuum/core version returns a version (not E404), same for @continuum/cli, @continuum/mcp-serverP5-T1, P5-T2
MD2Repo public + governance completeRepo visibility = public; SECURITY.md, CODE_OF_CONDUCT.md, LICENSE, CONTRIBUTING.md, AGENTS.md all present at rootP5-T3, P5-T4
MD3One-line install worksOn a clean machine, npx @continuum/cli init && npx @continuum/cli start yields a live stdio MCP serverP5-T6
MD4Full test suite greennpm test → 120/120 passing across all workspacesP6-T1
MD5CI green on mainLatest GitHub Actions run on main = successP6-T1
MD6Hosted engine + frontend upcurl -fsSL https://continuum-engine.fly.dev/healthz → 200; curl -fsSL https://continuum-kohl.vercel.app → 200P5-T7
MD7Secret-history scan cleangitleaks detect --no-banner (or equivalent) over full history → 0 leaks before flipping publicP5-T3
MD8Docs site liveA built docs site renders README + ARCHITECTURE + this North StarP6-T3
MD9Semver tag cutgit tag v1.0.0 exists and is pushedP6-T5
MD10RPO defined + volume backupA documented Fly volume snapshot cadence exists and one snapshot has been takenP5-T5

CONTINUUM is a TypeScript monorepo (npm workspaces, Node ≥20). The runtime is an MCP server exposing 10 tools / 4 resources / 2 prompts to any MCP-aware client, backed by a pluggable StorageBackend (SQLite default; hybrid SQLite+RuVector opt-in). Source adapters normalize external truth into canonical Observation rows; the checkpoint engine seals append-only, hash-sealed product_state[] snapshots.

flowchart TD
subgraph Clients["AI Clients (MCP-aware)"]
CC["Claude Code / Desktop / Cursor / Cline"]
end
subgraph Transport["MCP Transport"]
STDIO["stdio — continuum start"]
HTTP["HTTP/SSE Express — continuum serve<br/>Bearer + JWT tenant routing"]
end
subgraph Server["@continuum/mcp-server"]
BUILD["buildServer(projectId)<br/>per-session / per-tenant"]
TOOLS["10 Tools"]
RES["4 Resources"]
PROMPTS["2 Prompts"]
REG["TenantRegistry<br/>LRU + refcount + idle evict"]
end
subgraph Core["@continuum/core"]
CKPT["Checkpoint engine<br/>hash-sealed, append-only"]
TODO["Todo state machine"]
PRIV["Privacy filter (scrub)"]
FACT["openStorage() factory — the D2 seam"]
end
subgraph Storage["StorageBackend (pluggable)"]
SQLITE["SQLiteStorageBackend<br/>better-sqlite3 + FTS5 (default)"]
HYBRID["HybridStorageBackend<br/>SQLite + RuVector HNSW + MiniLM<br/>opt-in: CONTINUUM_STORAGE_BACKEND=hybrid"]
end
subgraph Adapters["Source Adapters (3 of 5)"]
DOCS["docs (.md/.mdx)"]
GIT["git (1 obs/commit)"]
EXPORT["export (Claude JSONL)"]
MEM["mem — V0.5"]
SONA["sona — V0.5"]
end
CC --> STDIO --> BUILD
CC --> HTTP --> REG --> BUILD
BUILD --> TOOLS & RES & PROMPTS
TOOLS --> CKPT & TODO
CKPT --> PRIV --> FACT
FACT --> SQLITE & HYBRID
DOCS & GIT & EXPORT --> PRIV
MEM -.V0.5.-> PRIV
SONA -.V0.5.-> PRIV
SQLITE & HYBRID --> DISK[("~/.continuum/{project}<br/>or /data on Fly")]
flowchart LR
subgraph Local["Local (OSS default)"]
AIC["AI client"] -->|stdio| MCP["continuum start<br/>SQLite @ ~/.continuum"]
end
subgraph Cloud["Hosted (current)"]
VERCEL["Vercel<br/>apps/console (Next.js 15)<br/>continuum-kohl.vercel.app"]
FLY["Fly.io iad<br/>continuum-engine.fly.dev<br/>Docker · 512MB · /data volume"]
VERCEL -->|SSE + Bearer| FLY
end
DNS["api.continuum.rest<br/>cert issued, DNS pending"] -.-> FLY

§1.3.3 Component breakdown (verified at 3531c6f)

Section titled “§1.3.3 Component breakdown (verified at 3531c6f)”
ComponentPathPurposeKey deps
@continuum/corepackages/coretypes, db, checkpoint engine, todo CRUD, openStorage() factory, SQLite + hybrid backends, privacy filter (observation.ts), STATE.md parser, embedder, byzantine-vote, tenant helpersbetter-sqlite3 (FTS5), ruvector@0.2.25, @xenova/transformers (MiniLM-L6-v2, 384-dim)
@continuum/mcp-serverpackages/mcp-server10 tools, 4 resources, 2 prompts; index.ts (stdio) + server.ts (factory) + http.ts (SSE); auth.ts, briefing.ts, tenant-registry.ts@modelcontextprotocol/sdk, express
@continuum/clipackages/clisingle continuum bin: init / start / serve / status / import-state@continuum/core, @continuum/mcp-server
@continuum/adapter-docspackages/adapters/docsidempotent .md/.mdx ingester; sha256(relativePath) UUID-shape IDs@continuum/core
@continuum/adapter-gitpackages/adapters/gitone Observation/commit; 40-char SHA ID; git log -z \x1f parse@continuum/core
@continuum/adapter-exportpackages/adapters/exportClaude session JSONL → Observation@continuum/core
apps/consoleapps/consoleNext.js 15 AaaS frontend; SSE client renders live registryNext.js 15, MCP SDK SSEClientTransport

The load-bearing seam (D2):

// packages/core/src/storage.ts — every consumer goes through this interface.
export interface StorageBackend {
upsertObservation(obs: Observation): void; // idempotent adapter re-sync
deleteObservation(id: string): void; // incident response (Issue #10)
// checkpoint, todo, FTS5 search operations …
}
// packages/core/src/factory.ts — the single swap point.
// default → SQLiteStorageBackend (better-sqlite3 + FTS5)
// STORAGE_BACKEND=hybrid → HybridStorageBackend (SQLite + RuVector HNSW + MiniLM)
export function openStorage(projectId: string): StorageBackend { /* … */ }

The contract is the MCP tool/resource/prompt schema. The only non-MCP HTTP surface is GET /healthz (auth-exempt load-balancer probe). The 10 tools are: continuum_record_checkpoint, continuum_get_state, continuum_get_digest, continuum_search_docs, continuum_get_todos, continuum_create_todo, continuum_update_todo, continuum_timeline, continuum_get_observations, continuum_delete_observation. Client registration:

// .mcp.json (per-project) — see .mcp.json.example
{ "mcpServers": { "continuum": {
"command": "node",
"args": [".../packages/mcp-server/dist/index.js"],
"env": { "CONTINUUM_PROJECT_ID": "your-project" }
}}}

In scope (shipped & verified): 10 tools, 4 resources, 2 prompts; progressive-disclosure retrieval; checkpoint engine; todo pipeline; 3-of-5 adapters; cross-source FTS5; CLI; STATE.md parser; 11-pattern scrubbing privacy filter; HTTP/SSE + Bearer + JWT tenant routing; V1.2 multi-tenant Path-A filesystem isolation + TenantRegistry; Vercel console.

Out of scope / deferred (locked): Chroma (never shipped; FTS5-only V0); RuVector-as-default (V0.5); local digest gen ruv-FANN/ruvllm (V0.5); Dolt (PARKED 2026-06-12 — Scenario B viable but adds zero benefit over the shipped stack); worker-daemon on :37778 (ASPIRATIONAL, not shipped); Web UI (V1.5); hosted SaaS control plane (V2); ARIA voice (V3); the 11 parked integration proposals (Issues #1–#22, gated). Partner-agreement clause #3 forbids landing integration #N ahead of its gate.

§1.4 Architecture Decision Records (ADRs)

Section titled “§1.4 Architecture Decision Records (ADRs)”

Format: Decision · Rationale · Alternatives rejected · Status. D0–D8 + D-V2.2 are the locked repo decisions (ARCHITECTURE.md §14); ADR-A…F are the cross-cutting decisions G1 surfaced.

IDDecisionRationaleAlternatives rejectedStatus
D0Standalone repo (not a VC-Hospitality subdir)clean OSS license boundary; independent release cadencemono-repo-inside-product (couples release to ARIA)✅ Locked
D1Product name “Continuum”memory-continuity metaphor”Recall”, “Ledger”⚠️ pending (name lock)
D2Phased storage: SQLite-FTS5 → RuVector behind openStorage()ship battle-tested keyword search week 1; swap engines with a one-line factory changeChroma now (heavier, network dep); RuVector now (pre-1.0)✅ Locked
D3npm workspaces (not pnpm)pnpm not installed; migration documented trivialpnpm/turbo (added tooling before value)✅ Locked
D4Phased digest engine (template now, ruv-FANN/ruvllm later)no external-LLM dep in default configcloud-LLM digest (breaks zero-config + cost)✅ Locked
D5Apache-2.0patent grant + OSS-friendly for enterprise adoptersMIT (no patent grant), AGPL (adoption friction)✅ Locked
D6number7even GitHub orgbrand alignmentpersonal account✅ Locked
D7claude-mem consumed as an adapter, not a forksource-agnostic aggregationfork claude-mem (maintenance burden)✅ Locked
D8Checkpoint trigger = both (manual + event)dogfood needs both explicit stamps and auto-capturemanual-only (misses drift)✅ Locked
D-V2.2(open flag) RuVector data plane + Postgres control plane vs revert-to-Postgres for tenancyRuVector holds data; Postgres as auth/tenancy directory is the common SaaS pattern with no D2 revisionfull revert-to-Postgres (D2 lock-revision needed)⚠️ Must lock before V2.2
ADR-AHTTP auth = Bearer token + optional JWT tenant claim (not OAuth2) for V1zero external IdP dependency; matches single-operator + self-host reality; OAuth is a V2 SaaS concernOAuth2/OIDC now (needs an IdP, breaks self-host simplicity)✅ Locked (V1)
ADR-BSQLite (better-sqlite3) over Postgres for V0–V1in-process sub-ms reads; zero-config; local-first; no server to runPostgres (operational weight, breaks zero-config)✅ Locked (revisit at V2 per D-V2.2)
ADR-CFly.io single-VM over Kubernetesone always-on 512 MB VM serves the AaaS proof at ~$2/mo; K8s is unjustified complexity pre-scaleK8s/ECS (cost + ops overhead with no multi-node need yet)✅ Locked (V1)
ADR-DSSE transport over WebSocket for V1MCP SDK ships SSEServerTransport/SSEClientTransport; one-way server-push + POST fits MCP; simpler than bidirectional WS fanoutWebSocket + Redis fanout (V2 scale concern, premature now)✅ Locked (V1; WS is V2.1 todo)
ADR-EMulti-tenancy = Path A (per-tenant filesystem isolation), not Doltfilesystem dirs give mechanical rm -rf isolation with zero added memory; Dolt Scenario A rejected on memory, Scenario B adds no benefitDolt branches (memory cost, no isolation gain); shared DB + row filter (weaker isolation)✅ Locked (V1.2)
ADR-FPrivacy enforcement inside observation.ts:insertObservation, not a separate Aggregatorsingle mandatory choke-point — impossible to write an observation that bypasses scrubbingfilter-at-call-site (each adapter must remember to call it — unsafe)✅ Locked

Scope = the deployed surface: MCP server (stdio + HTTP/SSE), privacy filter, multi-tenant isolation, auth, SQLite at rest. Trust model: local-first; the host and its filesystem are trusted (per SECURITY.md). Out of scope: already-compromised host, physical disk access, the disposable dolt-probe/, the parked integrations.

STRIDEThreat / attack vectorMitigation (shipped)Residual riskAction
SpoofingForged X-Continuum-Project header to access another tenantsanitiseTenantId gate + case-folded canonical normalization closes header-spoofing; JWT tenant-claim routing when enabledIf CONTINUUM_HTTP_TOKEN leaks, an attacker is any tenant they nameRotate token on leak; prefer JWT mode for multi-tenant prod
TamperingMutating/forging checkpoint historyAppend-only + content hash-seal; no update/delete path on checkpointsHost-level DB file edit (trusted-host model)Out of scope by trust model; document at §1.6
TamperingInjecting un-scrubbed secrets into stored observationsPrivacy filter scrubs 11 patterns + deep metadata scrub at the single write choke-pointNovel secret formats the patterns miss (entropy detector off by default)Enable CONTINUUM_PRIVACY_ENTROPY_DETECTOR=1 for sensitive repos; treat as best-effort (SECURITY.md)
Repudiation”I never stored that” / audit disputeAppend-only hash-sealed ledger is itself the tamper-evident audit chainNo external WORM/notaryV2: optional external anchor (parked Issue #4 Mike — counsel-gated)
Info disclosureCross-tenant read/enumeratePath-A per-tenant filesystem dirs; mechanical isolation proofs (verify-w27-isolation.mjs); per-session buildServer(tenantId)A bug in tenant routing = breachKeep verify-w27-isolation.mjs in CI as a gate (P6-T1)
Info disclosureSQLite file readable on diskTLS in transit (Fly force_https); secrets via fly secretsNo app-level at-rest encryption of the SQLite fileAccepted under host-trust model; document loudly (SECURITY.md does)
DoSUnbounded tenant backends exhaust 512 MBTenantRegistry LRU + refcount + idle eviction; CONTINUUM_MAX_OPEN_TENANTS boundBurst beyond LRU cap → eviction churnMonitor /healthz memory; bump VM to 1024 MB before scaling tenants
DoS/sse connection floodingBearer auth required before SSE upgrade (401 unauth)Authenticated client can still open many sessionsV2: per-token rate limit (matches Redis-fanout scale story)
ElevationUnauth caller reaching toolsAll HTTP routes except /healthz require Bearer; tenant routing validates claimToken compromise = full tenant access (no per-tool scopes)V2: scoped tokens / claims-based authz

RPO/RTO (G12 — newly defined here): RPO = 24h (target: daily Fly volume snapshot); RTO = 30 min (redeploy from main + restore latest volume snapshot). The Fly continuum_data volume is the only copy of hosted state at snapshot — MD10 / P5-T5 make a snapshot cadence a launch gate.

⚠️ No formal certification program exists. CONTINUUM provides enabling primitives, not compliance. This matrix maps each regulation’s relevant control to what the codebase provides and what remains the operator’s responsibility.

RegulationRelevant controlCONTINUUM primitive (shipped)Operator responsibility / gap
GDPRArt. 17 right to erasurecontinuum_delete_observation + per-tenant rm -rfOperator must locate + delete subject data; no automated DSAR tooling
GDPRArt. 25 data-protection-by-designPrivacy filter scrubs secrets before persistence; local-first (no third-party processor in default config)DPA with any hosted-tier sub-processors (Fly/Vercel) at V2
GDPRArt. 32 security of processingTLS in transit; tenant isolation; Bearer/JWTAt-rest encryption is not provided (host-trust); operator must encrypt the volume if required
SOC 2CC6 logical accessBearer + JWT + sanitiseTenantId; least-privilege host modelNo SSO/MFA, no access-review process — operator + V2 work
SOC 2CC7 change management / auditAppend-only hash-sealed ledger; Conventional Commits; CI gateNo formal change-advisory or evidence collection
EU AI ActTransparency / record-keeping (Art. 12 logging)Checkpoint ledger + observation provenance (source-derived IDs)CONTINUUM is infra, not a high-risk AI system itself; classification is the deploying system’s duty (e.g. ARIA)
HIPAA§164.312 audit controls / integrityHash-sealed append-only ledgerNo BAA, no PHI handling guarantees — do not store PHI in default config; encryption-at-rest gap is disqualifying for PHI until closed

Compliance verdict: safe to launch as developer tooling under “best-effort, local-first, no certification” framing (matches SECURITY.md). PHI/regulated workloads are out of scope until V2 adds at-rest encryption + a BAA path.

⚠️ List-price estimates (2026-06-12), USD/month. Verify against current Fly / Vercel / npm pricing before quoting externally.

ComponentConfigEst. monthlyScaling driver
Fly.io engine VMshared-cpu-1x, 512 MB, always-on (min_machines_running=1)~$1.94+VM per region/replica; +memory for hybrid backend (1024 MB ≈ ~$3.88)
Fly.io volumecontinuum_data, ~1–3 GB~$0.15/GB → ~$0.15–0.45grows with observation volume
Fly.io egresslow (SSE text)~$0 within free allowancescales with active SSE clients
Vercelapps/console, Hobby/Pro$0 (Hobby) / ~$20 (Pro)bandwidth + build minutes
npm publishpublic scoped packages$0free for public
Custom domainapi.continuum.rest~$0 (DNS only)n/a
Total (current AaaS proof)~$2–3/mo (Hobby) … ~$25/mo (Pro)

Scaling projection (probe-derived, ⚠️ from handover §5.3): the current per-tenant cost supports ~40 additional tenants on a single 512 MB VM before tuning; TenantRegistry bounds memory. Horizontal scale (multi-VM fleet + WS + Redis fanout) is the V2 cost story, not V1.

MetricSLO / targetMeasured (snapshot)How to re-measure (pass/fail)
Read latencysub-millisecondsub-ms (in-process SQLite)micro-bench a get_state call; PASS if median < 1 ms
Query p95< 50 ms (W25 budget)15.4 ms p95 (Dolt TCP probe upper bound)scripts/run-canonical-queries.mjs; PASS if p95 < 50 ms
Steady-state RSS≤ 362 MB (≥150 MB headroom under 512 MB)~177 MB baselinecurl …/healthz → RSS; PASS if ≤ 362 MB
Ingestion throughputhardened W25 (batch 128, 200 ms quiet timer)see scripts/verify-w25-throughput.mjsrun script; PASS on exit 0
Test suite120/120 green120/120npm test; PASS if 0 failures
Token efficiency⚠️ “~10x savings” is design-intent, unbenchmarked (G11)not measuredP6-T4 builds the benchmark; until then, state as hypothesis

Benchmark method (mandatory before quoting any number externally): run the named script on the target VM size, capture raw output to scripts/benchmark-results/<metric>-<date>.txt, and cite the file. Never quote a performance number that is not backed by a committed result file.

§1.9 Voice AI / ARIA V3 Binding (G6 — the integration contract)

Section titled “§1.9 Voice AI / ARIA V3 Binding (G6 — the integration contract)”

CONTINUUM is not a voice AI. It is the memory/state engine. Voice belongs to customer #3, VoiceCosmos “ARIA” (V3), where a tenant-scoped CONTINUUM instance is pointed at one hotel’s data so the Voice OS “knows the property.” The spec’s voice stack (Deepgram/AssemblyAI STT, VoiceIDVault biometrics, Redis WS fanout, PMS adapters) lives in ARIA, not this repo. This section defines the contract between them so a future model extending toward V3 does not invent voice features inside Continuum-core.

flowchart LR
subgraph ARIA["ARIA Voice OS (V3, separate repo)"]
STT["STT (Deepgram/AssemblyAI)"]
BIO["Voice biometrics (VoiceIDVault)"]
WS["WebSocket fanout (Redis)"]
PMS["PMS adapters (Oracle Hospitality, Onyx)"]
end
subgraph CONT["CONTINUUM (this repo, tenant-scoped)"]
TENANT["buildServer(hotelTenantId)"]
MCP2["MCP tools/resources/prompts"]
end
WS -->|"MCP over HTTP/SSE + Bearer/JWT<br/>X-Continuum-Project: hotel-<id>"| TENANT
TENANT --> MCP2
PMS -->|"adapter → Observation (V3)"| CONT
STT & BIO -.context.-> WS

Binding rules (executable):

  1. ARIA consumes CONTINUUM only through the existing MCP contract (§1.3.4) + the multi-tenant HTTP surface — no new Continuum-core API. Test: a V3 PR that adds a voice-specific tool to packages/mcp-server/src/tools/ violates principle #3 and must be rejected.
  2. Each hotel = one tenant (X-Continuum-Project: hotel-<id>), isolated by Path A. Test: verify-w27-isolation.mjs semantics hold for hotel tenants.
  3. STT/TTS provider selection, biometric confidence thresholds, and real-time latency SLOs are ARIA SLOs, documented in the ARIA repo, not here. Do not author voice specs in this document that the code does not have.
  4. PMS data enters CONTINUUM only as scrubbed Observation rows via a future adapter-pms (V3), behind the same privacy choke-point (ADR-F).

§1.10 Testing & Validation (the executable acceptance suite)

Section titled “§1.10 Testing & Validation (the executable acceptance suite)”

Existing automated gates (all must exit 0):

Terminal window
npm test # 120/120 across workspaces (MD4)
node scripts/privacy-smoke.mjs # 13 privacy-filter checks (principle #5)
node scripts/ruvector-smoke.mjs # 9 hybrid-backend checks
node scripts/http-smoke.mjs # 7-check SSE round-trip via real SDK client
node scripts/verify-w27-isolation.mjs # mechanical cross-tenant isolation (principle #6)
node scripts/burst-test-w27-5.mjs # TenantRegistry memory bounds
node scripts/verify-w25-throughput.mjs # ingestion throughput
node scripts/delete-observation-smoke.mjs # incident-response delete (Issue #10)

Load testing plan (V1→V2 readiness): drive N concurrent SSE clients against continuum-engine.fly.dev with Bearer auth, each issuing get_state + search_docs at 1 rps for 5 min; capture p95 and peak RSS from /healthz. PASS if p95 < 50 ms and RSS stays ≤ 362 MB (512 MB) up to the tenant count §1.7 projects (~40). Tool: a small autocannon/k6 script (V2 task; not a V1 gate).

Security audit checklist (pre-public, MD7): gitleaks detect over full history = 0; npm run audit (audit-ci, --audit-level=high) green with the documented per-CVE allowlist; manual review that no .env is committed and no secret value appears in any tracked file (including this one).


§2 — Ultra Build Roadmap (atomic, executable tasks)

Section titled “§2 — Ultra Build Roadmap (atomic, executable tasks)”

Audience: a weaker model executing mechanically. Every task has: ID, Action (copy-paste), Input, Output, Validation (pass/fail), Time. Execute phases in order; tasks within a phase may parallelize unless a dependency is noted. Do not stop the whole roadmap if one task blocks — mark it blocked, record why, continue.

  • Action: cd /Users/emporiumcollection/Development/supabase-projects/CONTINUUM && find packages apps -maxdepth 3 -type f -name '*.ts' | sort > docs/inventory/source-tree.txt
  • Input: repo root @ main
  • Output: docs/inventory/source-tree.txt
  • Validation: file exists and contains packages/core/src/factory.ts and packages/mcp-server/src/tools/index.ts
  • Time: 5 min

P1-T2: Confirm tool/resource/prompt counts

Section titled “P1-T2: Confirm tool/resource/prompt counts”
  • Action: ls packages/mcp-server/src/tools/*.ts | grep -v index | wc -l (expect 10); ls packages/mcp-server/src/resources/*.ts | grep -v index | wc -l (expect 4); ls packages/mcp-server/src/prompts/*.ts | grep -v index | wc -l (expect 2)
  • Input: packages/mcp-server/src
  • Output: counts recorded in docs/inventory/contract-counts.txt
  • Validation: 10 / 4 / 2 respectively
  • Time: 3 min
  • Action: npm ci --ignore-scripts && npm run audit > docs/inventory/audit-2026-06-12.txt 2>&1 || true
  • Input: root package.json, .audit-ci.jsonc
  • Output: docs/inventory/audit-2026-06-12.txt
  • Validation: file contains an audit-ci summary line; exit policy = allowlisted CVEs do not fail
  • Time: 10 min

P1-T4: Confirm npm publish gap (the launch blocker)

Section titled “P1-T4: Confirm npm publish gap (the launch blocker)”
  • Action: for p in core cli mcp-server; do npm view @continuum/$p version 2>&1 | tail -1; done
  • Input: npm registry
  • Output: docs/inventory/npm-status.txt
  • Validation: all three return E404 before launch (confirms MD1 not yet met); after P5 they return versions
  • Time: 3 min

P2-T1: Verify the D2 storage seam is unbypassed

Section titled “P2-T1: Verify the D2 storage seam is unbypassed”
  • Action: grep -rn "new SQLiteStorageBackend\|new HybridStorageBackend" packages --include=*.ts
  • Input: packages/**
  • Output: docs/inventory/seam-check.txt
  • Validation: every hit is inside packages/core/src/factory.ts. Any hit elsewhere = principle #4 violation → open a fix task, mark blocked, continue
  • Time: 5 min

P2-T2: Confirm privacy choke-point (ADR-F)

Section titled “P2-T2: Confirm privacy choke-point (ADR-F)”
  • Action: grep -n "insertObservation" packages/core/src/observation.ts and confirm scrub is called inside it
  • Input: packages/core/src/observation.ts
  • Output: note in docs/inventory/privacy-chokepoint.txt
  • Validation: the scrub function is invoked unconditionally before the DB write
  • Time: 8 min
  • Action: copy the Mermaid blocks from §1.3.1 / §1.3.2 / §1.9 into docs/diagrams/*.mmd; render at mermaid.live to confirm
  • Input: §1 of this document
  • Output: docs/diagrams/system.mmd, topology.mmd, aria-binding.mmd
  • Validation: all three render without syntax error in Mermaid Live Editor
  • Time: 15 min
  • Action: run every command in §1.10 “existing automated gates”
  • Input: built dist/ per workspace (npm run build first)
  • Output: docs/inventory/security-gates-2026-06-12.txt
  • Validation: all listed scripts exit 0 (record any non-zero as blocked with the failing check)
  • Time: 20 min

P3-T2: Full-history secret scan (MD7 prerequisite)

Section titled “P3-T2: Full-history secret scan (MD7 prerequisite)”
  • Action: gitleaks detect --no-banner --report-path docs/inventory/gitleaks.json (install via brew install gitleaks if absent)
  • Input: full git history
  • Output: docs/inventory/gitleaks.json
  • Validation: report shows 0 findings. Any finding blocks flipping the repo public (P5-T3) until rotated + history-scrubbed
  • Time: 15 min

P3-T3: Confirm threat-model mitigations are live

Section titled “P3-T3: Confirm threat-model mitigations are live”
  • Action: for each §1.5 row, run the cited mitigation test (verify-w27-isolation.mjs, privacy-smoke.mjs, an unauth curl https://continuum-engine.fly.dev/sse expecting 401)
  • Input: §1.5 table
  • Output: docs/inventory/threat-verification.txt
  • Validation: isolation + privacy scripts exit 0; /sse unauth returns 401; /healthz returns 200
  • Time: 15 min

Phase 4 — Adapter & Contract Documentation

Section titled “Phase 4 — Adapter & Contract Documentation”

P4-T1: Document the 3 shipped adapters + the 2 deferred

Section titled “P4-T1: Document the 3 shipped adapters + the 2 deferred”
  • Action: for docs, git, export capture: ID strategy, idempotency, what is excluded and why (git diffs excluded; recoverable via git show)
  • Input: packages/adapters/{docs,git,export}/src
  • Output: docs/adapters/README.md
  • Validation: each adapter section states its stable-ID rule and an idempotency test command
  • Time: 30 min
  • Action: enumerate each tool’s input schema from packages/mcp-server/src/tools/*.ts; write a one-line contract per tool
  • Input: tools/*.ts, resources/*.ts, prompts/*.ts
  • Output: docs/MCP_CONTRACT.md
  • Validation: all 10 tools, 4 resources, 2 prompts documented; names match index.ts registrations exactly
  • Time: 40 min

Phase 5 — Launch Construction (the V1 OSS launch — MD1–MD3, MD6, MD7, MD10)

Section titled “Phase 5 — Launch Construction (the V1 OSS launch — MD1–MD3, MD6, MD7, MD10)”
  • Action: in each of packages/core, packages/cli, packages/mcp-server package.json, set "private": false, add "publishConfig": { "access": "public" }, "files": ["dist"], correct "main"/"types"/"exports"/"bin", and "prepublishOnly": "npm run build"; verify with npm pack --dry-run
  • Input: the three package.json files
  • Output: updated manifests; npm pack --dry-run tarball listings in docs/inventory/pack-dryrun.txt
  • Validation: npm pack --dry-run lists only dist/ + package.json + LICENSE + README.md; no src or .test files
  • Time: 45 min
  • Dependency: P1-T4 (confirm names), MD4 green
  • Action: npm login; then per package in dep order (core → mcp-server → cli) npm publish --workspace=@continuum/<name>
  • Input: authenticated npm session (NPM_TOKEN configured)
  • Output: three published versions
  • Validation: P1-T4 command now returns versions, not E404 (MD1 met)
  • Time: 15 min
  • Dependency: P5-T1
  • Action: confirm P3-T2 gitleaks = 0; then flip GitHub repo number7even/CONTINUUM to public via repo Settings → Danger Zone → Change visibility
  • Input: clean gitleaks report
  • Output: public repo
  • Validation: gh repo view number7even/CONTINUUM --json visibility returns PUBLIC (MD2 partial); blocked if gitleaks ≠ 0
  • Time: 10 min
  • Dependency: P3-T2 = 0 findings

P5-T4: Add CODE_OF_CONDUCT.md (G10 — confirmed missing)

Section titled “P5-T4: Add CODE_OF_CONDUCT.md (G10 — confirmed missing)”
  • Action: create CODE_OF_CONDUCT.md at repo root using Contributor Covenant v2.1, contact riaan@number7even.com; commit docs(governance): add Code of Conduct
  • Input: Contributor Covenant v2.1 text
  • Output: CODE_OF_CONDUCT.md at root
  • Validation: test -f CODE_OF_CONDUCT.md exits 0 (MD2 complete; SECURITY.md already present)
  • Time: 10 min

P5-T5: Define RPO + take first Fly volume snapshot (MD10, G12)

Section titled “P5-T5: Define RPO + take first Fly volume snapshot (MD10, G12)”
  • Action: fly volumes list; fly volumes snapshots create <vol-id>; document the 24h RPO + restore (RTO 30 min) procedure in docs/RUNBOOK_BACKUP.md
  • Input: Fly continuum_data volume
  • Output: one snapshot + docs/RUNBOOK_BACKUP.md
  • Validation: fly volumes snapshots list <vol-id> shows ≥1 snapshot; runbook states RPO=24h, RTO=30 min
  • Time: 20 min

P5-T6: Finalize one-line install + fix Issue #9

Section titled “P5-T6: Finalize one-line install + fix Issue #9”
  • Action: make npx @continuum/cli init canonicalize project IDs (lower-case fold) to close the case-sensitivity foot-gun; verify on a clean dir
  • Input: packages/cli/src, Issue #9
  • Output: patched CLI; docs/QUICKSTART.md with the one-liner
  • Validation: mkdir /tmp/ct && cd /tmp/ct && npx @continuum/cli init && npx @continuum/cli start yields a live stdio server; MyProj and myproj resolve to one DB (MD3)
  • Time: 60 min
  • Dependency: P5-T2
  • Action: curl -fsSL https://continuum-engine.fly.dev/healthz and curl -fsSL -o /dev/null -w '%{http_code}' https://continuum-kohl.vercel.app
  • Input: live deployments
  • Output: docs/inventory/endpoint-check-2026-06-12.txt
  • Validation: engine returns 200 + JSON; frontend returns 200 (MD6)
  • Time: 5 min

Phase 6 — Validation, Docs & Gap Closure

Section titled “Phase 6 — Validation, Docs & Gap Closure”
  • Action: npm run build && npm test; push to main; confirm GitHub Actions run = success
  • Input: all workspaces
  • Output: green CI run URL recorded
  • Validation: npm test = 120/120; gh run list --branch main --limit 1 shows success
  • Time: 15 min
  • Action: edit ARCHITECTURE.md §6 to mark the worker-daemon-on-:37778 model ASPIRATIONAL (not shipped) and point readers to the shipped direct stdio/HTTP runtime
  • Input: ARCHITECTURE.md §6, handover §3.1 divergence note
  • Output: corrected ARCHITECTURE.md
  • Validation: §6 contains the words “ASPIRATIONAL — not the shipped runtime” and links to continuum start/continuum serve
  • Time: 20 min
  • Action: scaffold Astro Starlight in docs-site/ (npm create astro@latest -- --template starlight), import README.md, ARCHITECTURE.md, this file; deploy to Vercel as a second project
  • Input: root markdown docs
  • Output: docs-site/ + a live docs URL
  • Validation: the docs URL returns 200 and renders this North Star’s headings
  • Time: 3 h
  • Dependency: none (parallel with P5)

P6-T4: Build the token-efficiency benchmark (G11, MD-quality)

Section titled “P6-T4: Build the token-efficiency benchmark (G11, MD-quality)”
  • Action: write scripts/benchmark-token-savings.mjs comparing a cold-start session WITHOUT CONTINUUM (full re-read) vs WITH (Layer-0 briefing → Layer-1 search → Layer-3 fetch); record token counts
  • Input: progressive-disclosure resources/prompts
  • Output: scripts/benchmark-results/token-savings-<date>.txt
  • Validation: script runs and emits a measured ratio; until this exists, the README must say “design-intent, not yet benchmarked,” not “~10x”
  • Time: 2 h
  • Action: git tag -a v1.0.0 -m "CONTINUUM V1 OSS launch" && git push origin v1.0.0; create a GitHub Release with notes
  • Input: green main after all P5/P6 gates
  • Output: v1.0.0 tag + GitHub Release
  • Validation: git tag lists v1.0.0; gh release view v1.0.0 succeeds
  • Time: 15 min
  • Dependency: all MD gates green

P6-T6: Final consistency audit (per contract)

Section titled “P6-T6: Final consistency audit (per contract)”
  • Action: re-run §3 Validation Checklist top to bottom; sweep grep -rn "TODO\|FIXME\|XXX\|<placeholder>\|<insert" packages apps docs --include=*.ts --include=*.md
  • Input: whole repo
  • Output: docs/inventory/final-audit-2026-06-12.txt
  • Validation: every §3 box checks; the grep returns no <placeholder>/<insert> and no unexplained TODO in shipping code
  • Time: 30 min

Run this to verify the Ultra doc + the launch are complete. Each box is pass/fail and cites its evidence.

Document completeness (spec quality gates):

  • All ADRs present with rationale + alternatives considered (§1.4: D0–D8, D-V2.2, ADR-A–F)
  • Threat model enumerated with mitigation + residual risk (§1.5 STRIDE)
  • Compliance matrix covers GDPR / SOC2 / EU AI Act / HIPAA (§1.6)
  • Cost model present with per-component figures + scaling projection (§1.7)
  • Performance SLOs with benchmark method (§1.8); unbenchmarked claims marked as hypotheses
  • Voice/ARIA binding defined as a V3 contract, no invented Continuum-core voice features (§1.9)
  • All Mermaid diagrams render in Mermaid Live Editor (§1.3.1, §1.3.2, §1.9 / P2-T3)
  • All commands are copy-paste runnable; no <placeholder> / <insert here> / unexplained TODO (P6-T6)
  • Every roadmap task has ID + Action + Input + Output + Validation + Time (§2)
  • Version & change log included (§5)

Launch readiness (Mandatory Deliverables MD1–MD10):

  • MD1 — npm view @continuum/{core,cli,mcp-server} version returns versions (P5-T2)
  • MD2 — repo public + SECURITY.md & CODE_OF_CONDUCT.md present (P5-T3, P5-T4)
  • MD3 — npx @continuum/cli init && start works on a clean machine (P5-T6)
  • MD4 — npm test = 120/120 (P6-T1)
  • MD5 — CI on main = success (P6-T1)
  • MD6 — /healthz 200 + Vercel 200 (P5-T7)
  • MD7 — gitleaks detect = 0 over full history (P3-T2)
  • MD8 — docs site live (P6-T3)
  • MD9 — v1.0.0 tag pushed (P6-T5)
  • MD10 — RPO defined + ≥1 Fly volume snapshot taken (P5-T5)

Invariant guards (North Star principles):

  • Storage seam unbypassed — grep for new *StorageBackend hits only factory.ts (P2-T1)
  • Privacy choke-point intact — scrub runs inside insertObservation (P2-T2)
  • Tenant isolation mechanical — verify-w27-isolation.mjs exits 0 (P3-T1)
  • Append-only ledger — broken-draft rows a63eb576/c6291935 still present (principle #2)
  • Memory law — /healthz RSS ≤ 362 MB on default backend (principle #7)

RiskTriggerFallback (executable)
Secret found in history at P3-T2gitleaks ≠ 0Block P5-T3. Rotate the exposed secret, git filter-repo to scrub, force-push a cleaned history (coordinate; this is the one sanctioned non-append exception), re-scan
npm name @continuum takenE404 → EEXIST/403 on publishPublish unscoped (continuum-core, continuum-cli, continuum-mcp-server) or scope under @number7even/*; update install docs
Fly VM OOM after enabling hybrid/healthz RSS > 480 MBBump fly.toml [[vm]] memory_mb = 1024, fly deploy; keep default backend = sqlite for OSS
Fly volume lost (only copy of hosted state)volume detach / region incidentRestore from P5-T5 snapshot; redeploy from main (RTO 30 min)
Docs site framework churn (P6-T3)Astro/Starlight blockerMark P6-T3 blocked, ship a single rendered docs/INDEX.md on GitHub Pages as the interim docs surface — launch is not blocked on the site framework
Token-efficiency benchmark underperformsP6-T4 ratio ≪ 10xRestate the README claim with the measured number; never ship the unmeasured “~10x” (principle: claim only what you verify)
Premature integration pressurea PR adds integration #N ahead of its gateReject per partner-clause #3; the issue stays parked until its phase

Blocked-section log (per contract): none at generation time. If any §2 task blocks during execution, append a row here with the task ID, the reason, and the substitute deliverable taken.


VersionDateAuthorChange
1.0.02026-06-12Claude (Opus 4.8, 1M ctx)Initial Ultra North Star — elevated PROJECT_HANDOVER.md per Smater-Spec.md. Added §1.4 ADRs (incl. ADR-A–F), §1.5 STRIDE threat model, §1.6 compliance matrix, §1.7 cost model, §1.8 SLOs+method, §1.9 ARIA/V3 binding, §2 atomic roadmap (6 phases / 23 tasks), §3 checklist, §4 fallback plan. Resolved gaps G1–G12. All structural claims re-derived from code/git/fly.toml/CI at HEAD 3531c6f.

Maintenance rule: update this log and the snapshot SHA on every material change. Re-run §3 before claiming completeness. This document supersedes PROJECT_HANDOVER.md as the North Star; the handover is retained as the verified raw-fact snapshot it elevates.

Generated under AGENTS.md / The Nine (P4: never claim more than you can verify). A future model should re-derive, not trust — the checkpoint ledger, the CI run, and the §1.10 scripts are the witnesses.

IP by Riaan Kleynhans — Human in the Loop — Copyright Riaan Kleynhans.