Foundation slice of #120 — one server, many namespaces, per-token hard wall. Unblocks the rest of Layer 2.
Model
- Namespace = the `project` discriminator value (reuse Layer 1 identity; no migration).
- Per-token principal: bearer token → `{read: [namespaces], write: single}`. Multiple principals in ONE process.
- Auth on reads too: once principals are configured, every `/api` endpoint requires a valid token; principal derived from it.
- Enforced read-wall in core (single choke point, not an HTTP query filter): search/recall/get_node/graph/edges clamped to the principal's read-set. `?project=` may narrow within, never widen beyond.
- Write-pin: remember/link/add_document/ingest forced to the principal's single write namespace; a foreign `project` is rejected (403).
- Secure global default: a namespace-restricted principal sees global only if its read-set explicitly lists global.
- Edge isolation: edges have no scope column → visible only when BOTH endpoint nodes are inside the wall.
- Backward-compat: no principals configured ⇒ exactly Layer 1 today (open reads, single AUTH_TOKEN gates writes). Existing tests unchanged.
Predicate (no migration)
`AND ( $wall IS NULL OR COALESCE(NULLIF(discriminators->>'project',''),'') = ANY($wall) )` on nodes/chunks; both-endpoints EXISTS on edges.
Acceptance
A principal scoped to A cannot read B's nodes/edges/chunks via search, recall, get_node, or graph — by any query or `?project=`. Layer-1 deployments unchanged.
Deferred (separate issues)
quotas, namespace export/backup, whole-namespace delete/handoff, WebUI read-auth, per-token id-based curation.
Foundation slice of #120 — one server, many namespaces, per-token hard wall. Unblocks the rest of Layer 2.
Model
Predicate (no migration)
`AND ( $wall IS NULL OR COALESCE(NULLIF(discriminators->>'project',''),'') = ANY($wall) )` on nodes/chunks; both-endpoints EXISTS on edges.
Acceptance
A principal scoped to A cannot read B's nodes/edges/chunks via search, recall, get_node, or graph — by any query or `?project=`. Layer-1 deployments unchanged.
Deferred (separate issues)
quotas, namespace export/backup, whole-namespace delete/handoff, WebUI read-auth, per-token id-based curation.