Spaces:
Sleeping
Sleeping
| -- 007_knowledge (sqlite) β Phase 6 first-customer UX (docs/HARDENING.md): | |
| -- company-knowledge ingestion (vault docs) + generated L5 exam drafts. | |
| -- | |
| -- Data class T2 "crown jewels" (docs/TENANCY.md): uploaded company documents | |
| -- and the exam items derived from them. Protection = T1 (org-scoped queries | |
| -- via atp/tenant_db.py) PLUS Fernet encryption at rest via | |
| -- atp/crypto.py encrypt_for_org (per-org HKDF subkeys): | |
| -- * vault_docs.content_enc / summary_enc β 'enc1:β¦' ciphertext, never | |
| -- plaintext (leak surface #7: T2 columns are ciphertext in dumps by | |
| -- construction). | |
| -- * l5_drafts.items_json_enc β exam items derived from the | |
| -- docs, encrypted for the same reason; the blueprint (section names + | |
| -- weights only) stays plaintext for review listings. | |
| -- Tenant files NEVER land under /videos or /media (leak surface #4) β there | |
| -- is no file path at all: content lives only in these encrypted columns. | |
| -- | |
| -- Conventions (002/004/005/006): | |
| -- * ts columns are ISO-8601 UTC strings ("%Y-%m-%dT%H:%M:%SZ"). | |
| -- * org_id defaults to 'org-demo', the bootstrap org (005 bridge), so dev | |
| -- mode (BU_AUTH_DISABLED=1) keeps working unchanged. | |
| -- * SQLite has NO row-level security: dev/demo isolation relies on layers | |
| -- 1-2 of docs/TENANCY.md (route deps + org-scoped SQL). The Postgres | |
| -- twin (007_knowledge.pg.sql) adds RLS. | |
| -- | |
| -- Mutability model: NOT append-only, by design. Drafts are working documents | |
| -- (draft -> approved | rejected state transitions; docs move uploaded -> | |
| -- drafted -> signed). The tamper-evident record of who signed what lives in | |
| -- the atp_evidence hash chain instead: approve/reject writes a signed | |
| -- 'sme_signoff' evidence row via atp/signing.py append_chain. | |
| -- | |
| -- Statement separator convention: a line containing only `--;;` splits this | |
| -- file into statements (see atp/db.py). | |
| CREATE TABLE IF NOT EXISTS vault_docs ( | |
| id TEXT PRIMARY KEY, | |
| org_id TEXT NOT NULL DEFAULT 'org-demo', | |
| title TEXT NOT NULL, | |
| filename TEXT, | |
| mime TEXT, | |
| content_enc TEXT NOT NULL, -- Fernet 'enc1:β¦' via crypto.encrypt_for_org | |
| summary_enc TEXT, -- heuristic summary, encrypted too (T2) | |
| uploaded_by TEXT, | |
| created_at TEXT NOT NULL, | |
| status TEXT NOT NULL DEFAULT 'uploaded' | |
| CHECK (status IN ('uploaded', 'drafted', 'signed')) | |
| ); | |
| --;; | |
| -- (org_id, <pk>) per docs/TENANCY.md invariants. | |
| CREATE INDEX IF NOT EXISTS idx_vault_docs_org ON vault_docs(org_id, id); | |
| --;; | |
| CREATE TABLE IF NOT EXISTS l5_drafts ( | |
| id TEXT PRIMARY KEY, | |
| org_id TEXT NOT NULL DEFAULT 'org-demo', | |
| cert_label TEXT NOT NULL, | |
| blueprint_json TEXT NOT NULL, -- sections/weights only β reviewable, plaintext | |
| items_json_enc TEXT NOT NULL, -- T2: items derived from docs are encrypted | |
| doc_ids_json TEXT NOT NULL, -- JSON array of vault_docs.id this draft covers | |
| status TEXT NOT NULL DEFAULT 'draft' | |
| CHECK (status IN ('draft', 'approved', 'rejected')), | |
| created_by TEXT, | |
| created_at TEXT NOT NULL, | |
| reviewed_by TEXT, | |
| reviewed_at TEXT, | |
| review_note TEXT | |
| ); | |
| --;; | |
| CREATE INDEX IF NOT EXISTS idx_l5_drafts_org ON l5_drafts(org_id, id); | |