|
1 | | -# OuterBrain Outer Brain Persistence Persistence |
| 1 | +# OuterBrain Persistence |
2 | 2 |
|
3 | | -## Scope |
| 3 | +## Production contract |
4 | 4 |
|
5 | | -OuterBrain Outer Brain Persistence owns raw Ecto/Postgres durability layer for semantic-session, journal, recovery, and publication truth. This document is package-local and is the persistence contract for `core/outer_brain_persistence` in `outer_brain`. |
| 5 | +`core/outer_brain_persistence` owns PostgreSQL truth for semantic-session |
| 6 | +leases, journal entries, recovery tasks, reply publications, artifact |
| 7 | +descriptors, and semantic-context provenance. The sole production profile is |
| 8 | +`:durable_redacted`; missing, disabled, memory, and unknown profiles fail before |
| 9 | +a repository child is selected. |
6 | 10 |
|
7 | | -## Available Tiers |
8 | | - |
9 | | -- `:mickey_mouse`: memory or ref-only default. No restart durability claim. |
10 | | -- `:memory_debug`: memory or ref-only with redacted debug evidence only. |
11 | | -- `:local_restart_safe`: supported only when this package or a named adapter package owns a local durable store and preflight proof. |
12 | | -- `:integration_postgres`: supported only when a named Postgres or AshPostgres adapter and migration proof are configured. |
13 | | -- `:ops_durable`: supported only for Temporal-owning runtime packages after explicit substrate proof. |
14 | | -- `:full_debug_tracked`: supported only when durable storage and redacted debug capture are both explicitly preflighted. |
15 | | - |
16 | | -## Default Tier |
17 | | - |
18 | | -The default tier is `:mickey_mouse`. It is memory-only or ref-only and is lost on restart unless this package explicitly states that a local durable adapter has been selected by the caller. |
19 | | - |
20 | | -## Capture Levels |
21 | | - |
22 | | -Supported capture levels are `:off`, `:metadata`, `:refs_only`, `:redacted_debug`, and `:full_debug` when the package explicitly supports full debug. Raw credentials, auth headers, token files, credential bodies, raw prompt bodies, raw provider payload bodies, native auth file content, private keys, session cookies, refresh tokens, access tokens, database URLs with credentials, and object-store signed URLs are always forbidden. |
23 | | - |
24 | | -## Supported Adapters |
25 | | - |
26 | | -Explicit Ecto/Postgres durable adapter. Not required for default semantic runtime execution. |
27 | | - |
28 | | -## Unsupported Adapters |
29 | | - |
30 | | -Unsupported adapter selections fail before mutation. Silent fallback from durable selection to memory is invalid. Product code must not import lower store modules directly to compensate for a missing adapter. |
31 | | - |
32 | | -## Configuration Precedence |
33 | | - |
34 | | -Configuration is explicit caller data first, package option second, release profile third, and built-in default last. Governed flows do not read process environment, local credential files, provider defaults, singleton clients, or application configuration as authority unless this package names a standalone boot boundary. |
35 | | - |
36 | | -## OTP Ownership And Repo Configuration |
37 | | - |
38 | | -`OuterBrain.Persistence.Application` is inert by default and does not read app env to start or configure Postgres. Hosts that need durable storage own the supervision decision by starting `OuterBrain.Persistence.Repo` with explicit config in their own supervision tree. Tests may start the repo directly with container-derived config. |
39 | | - |
40 | | -This keeps durability opt-in visible at the caller boundary: no code path can silently enable Postgres persistence through global app configuration, and `OuterBrain.Persistence.Repo` receives the config that its caller supplied. |
41 | | - |
42 | | -## Test Container Readiness |
43 | | - |
44 | | -Dockerized Postgres test support uses a bounded readiness awaiter with explicit |
45 | | -timeout and interval options. A readiness failure raises with the last probe's |
46 | | -exit status and output, then removes the temporary container before returning |
47 | | -control to the test process. |
48 | | - |
49 | | -## Example Config |
| 11 | +Production hosts add this child to their supervision tree: |
50 | 12 |
|
51 | 13 | ```elixir |
52 | | -# Default deterministic profile. |
53 | | -[persistence_profile: :mickey_mouse] |
54 | | - |
55 | | -# Redacted in-memory debug profile. |
56 | | -[persistence_profile: :memory_debug, capture_level: :redacted_debug] |
57 | | - |
58 | | -# Durable opt-in example. The caller must also pass adapter capability and preflight proof. |
59 | | -[persistence_profile: :integration_postgres] |
| 14 | +{OuterBrain.Persistence.DurableSupervisor, |
| 15 | + profile: :durable_redacted, |
| 16 | + repo_options: [url: database_url]} |
60 | 17 | ``` |
61 | 18 |
|
62 | | -## Test Commands |
| 19 | +Hosts that start all repositories in an earlier supervision layer use |
| 20 | +`repo_mode: :external`. That mode omits the Repo child and requires the |
| 21 | +canonical Repo to be running before Bootstrap starts. A host can validate the |
| 22 | +same database before starting its Repo layer by using a bounded temporary Repo: |
63 | 23 |
|
64 | | -```bash |
65 | | -cd core/outer_brain_persistence && mix test; root mix ci |
| 24 | +```elixir |
| 25 | +OuterBrain.Persistence.Store.preflight( |
| 26 | + profile: :durable_redacted, |
| 27 | + repo_mode: :temporary, |
| 28 | + repo_options: [url: database_url] |
| 29 | +) |
66 | 30 | ``` |
67 | 31 |
|
68 | | -## Lost-On-Restart Claims |
69 | | - |
70 | | -`:mickey_mouse` and `:memory_debug` data is lost on BEAM or process restart unless the package explicitly says a local durable adapter was selected. Memory profiles may prove semantics, validation, and receipt shape; they do not prove restart durability. |
71 | | - |
72 | | -## Valid Durability Claims |
| 32 | +The supervisor starts `OuterBrain.Persistence.Repo` and then performs a live |
| 33 | +preflight. Boot fails if the Repo is unavailable, a required table is absent, |
| 34 | +or a package migration is pending. Preflight errors expose only safe error |
| 35 | +classes, never connection strings or driver exception messages. A running host |
| 36 | +may perform the same health check with: |
73 | 37 |
|
74 | | -Valid durability claims require explicit profile selection, adapter capability, migration or substrate preflight, redacted evidence, focused tests, repo QC, and a pushed commit. :integration_postgres after migration and repository preflight. |
75 | | - |
76 | | -## Invalid Durability Claims |
77 | | - |
78 | | -Invalid claims include ambient provider credentials, default database reachability, default Temporal reachability, object-store availability without opt-in, network reachability, raw debug capture, raw prompt capture, raw provider payload capture, and product direct lower-store imports. |
79 | | - |
80 | | -## Debug Sidecar Behavior |
| 38 | +```elixir |
| 39 | +OuterBrain.Persistence.Store.preflight( |
| 40 | + profile: :durable_redacted, |
| 41 | + repo: OuterBrain.Persistence.Repo |
| 42 | +) |
| 43 | +``` |
81 | 44 |
|
82 | | -Debug sidecars are disabled by default. When enabled, they are read-only or append-only redacted evidence surfaces. Debug failure must be non-mutating and must not alter authority, lease, run, workflow, store, projection, or product state. |
| 45 | +## Semantic context and artifact boundaries |
83 | 46 |
|
84 | | -## Redaction Guarantees |
| 47 | +`Store.record_semantic_context/3` atomically records an immutable, |
| 48 | +secret-free `GroundPlane.Contracts.ArtifactDescriptor` and the matching |
| 49 | +`OuterBrain.Contracts.SemanticContextProvenance`. Exact replays are idempotent; |
| 50 | +reuse of an artifact, semantic, or idempotency reference with different facts |
| 51 | +fails closed. Tenant scope is required on every write and read. |
85 | 52 |
|
86 | | -Evidence stores opaque refs, stable redacted ids, hashes, bounded metadata, claim-check refs, capture tags, receipt refs, store refs without credentials, and partition refs without secrets. Raw secret and raw payload fields are rejected before persistence or export. |
| 53 | +The semantic index contains only opaque semantic, provider, model, artifact, |
| 54 | +and provenance refs. Raw prompts, provider bodies, signed object-store URLs, |
| 55 | +credentials, and credential-shaped metadata are forbidden. Object locations |
| 56 | +remain opaque owner-authorized refs. |
87 | 57 |
|
88 | | -## Migration And Preflight Behavior |
| 58 | +## Test boundary |
89 | 59 |
|
90 | | -Package migrations own semantic_session_leases, semantic_journal_entries, recovery_tasks, and reply_publications. |
| 60 | +Tests may start the canonical Repo directly against the isolated Docker |
| 61 | +PostgreSQL fixture. That is a deterministic proof path, not a production |
| 62 | +selector. There is no production memory, no-op, disabled, or fixture Repo. |
91 | 63 |
|
92 | | -## Phase 12 Migration And Preflight Closeout |
| 64 | +Focused QC: |
93 | 65 |
|
94 | | -- Tier: `:integration_postgres`. |
95 | | -- Schema owner: `OuterBrain.Persistence.Repo`. |
96 | | -- Migration owner: `core/outer_brain_persistence/priv/repo/migrations`. |
97 | | -- Migration command: run `Ecto.Migrator.run(OuterBrain.Persistence.Repo, OuterBrain.Persistence.PostgresContainer.migrations_path(), :up, all: true)` against the configured repo, or the equivalent release-owned migration command for `OuterBrain.Persistence.Repo`. |
98 | | -- Migration preflight command: `OuterBrain.Persistence.Store.preflight(profile: :integration_postgres, migration_proof: :present)`. |
99 | | -- Failure behavior: missing migration proof returns `{:error, {:missing_migration_proof, :outer_brain_persistence}}` before semantic-session, journal, recovery, or publication mutation. |
100 | | -- Rollback behavior: rollback is an operator-owned database migration action against the same repo and migration path; restart durability claims remain open until post-rollback focused tests are recorded. |
101 | | -- Tagged test command: `cd core/outer_brain_persistence && mix test test/outer_brain/persistence/store_test.exs`. |
102 | | -- Release claim boundary: durable OuterBrain truth is valid only after migration proof, focused package tests, root QC, static scans, and pushed commit evidence are recorded. |
| 66 | +```bash |
| 67 | +cd core/outer_brain_persistence |
| 68 | +mix compile --warnings-as-errors |
| 69 | +mix test test/outer_brain/persistence/store_boundary_test.exs \ |
| 70 | + test/outer_brain/persistence/store_test.exs \ |
| 71 | + test/outer_brain/persistence/semantic_failure_store_test.exs |
| 72 | +``` |
0 commit comments