# Configuration storage layers

The following SQL tables have the same observed storage-row shape:

`FileName`, `Creation`, `Modified`, `Attributes`, `DataSize`, `BinaryData`,
`PartNo`.

| Layer | Role | Direct adapter writes |
|---|---|---|
| `Config` | Active base configuration | Forbidden |
| `ConfigSave` | Pending base configuration changes | Controlled `upo_test` only |
| `ConfigCAS` | Active extension content-addressed store | Forbidden |
| `ConfigCASSave` | Pending extension configuration overlay | Controlled `upo_test` only |

`PartNo` must be read and preserved. The currently proven writer handles a
single-part stream only; a multi-part stream is unsupported until a
table-aware round-trip codec exists.

## Addressing rules

Base `Config` objects are commonly addressed by metadata GUID. Extension active
objects are reached through `_ExtensionsInfo` → extension root in `ConfigCAS`
→ root manifest → object part SHA-1 key. Do not infer a semantic role from a
suffix such as `.0`; inspect the payload and route evidence.

For normal content-addressed rows, `ConfigCAS.FileName` was observed to equal
SHA-1 of the stored bytes. Always compute and compare the hash rather than
trusting the name: an activation experiment left a legacy alias whose name was
an old key while its bytes had the new SHA-1.

## Write sequence

1. Resolve public object/form/module against live SQL.
2. Read active bytes and any existing saved-state rows.
3. Prepare only missing saved rows; never overwrite a user’s existing rows.
4. Encode the changed stream losslessly.
5. Update every proved companion index in the same SQL transaction.
6. Read back and validate hashes and semantic exact-match count.
7. Tell the human which Configurator scope to reload.
