Files
llm/docs/1c-sql-protocol/extensions/saved-state-overlay.md
T
2026-08-14 09:40:51 +03:00

129 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Extension saved-state overlay (`ConfigCASSave`)
> **Deployment and integration-test target:** `adapter-1c-mcp` runs on
> `docker.cin.su`. Use that host for deployment and live adapter checks;
> `test-docker` is staging only and requires an explicit request.
## Canonical object-module overlay: activation evidence
For extension GUID `E` and object GUID `O`, the overlay uses:
```text
E__configinfo
E__O
E__O.S
```
This route is now human-confirmed in two independently selected extension
object-module cases on `upo_test`:
| Extension | Object | Public test | Human confirmation |
|---|---|---|---|
| `test2` | Common form/module fixture | prior `change-10` experiment | Configurator applied overlay into `ConfigCAS` |
| `фс_Отчеты` | `Report._ПоступлениеТовара` object module | `//Пример - 3``//Тест - 3` | Configurator displayed `//Тест - 3` in the extension editor |
The descriptor and module are separate objects. A pending extension may contain
only rows changed manually by the user; the root `__configinfo` map can still
refer to unchanged active parts. An adapter must preserve those rows and all
their map entries.
For the separately observed hash-keyed overlay, the equivalent boundary is the
live extension `root_cas_key`: an automatic first-write copy must include that
root manifest together with the selected object parts. A leaf module key alone
is not a complete working-copy selection boundary.
## Hash-keyed first-write status
In `upo_test` / `фс_Отчеты`, copying the complete evidenced hash-key group
from `ConfigCAS` to `ConfigCASSave` under unchanged hash names produced a
byte-for-byte SQL readback, but Configurator continued to read the active
`ConfigCAS` module. Therefore a same-name hash copy is **not** a working-copy
protocol.
The active extension root has since been decoded as the equivalent logical
file map: it contains `"<object-guid>[.suffix]",Base64(SHA-1(payload))`
pairs, including the target descriptor and the selected BSL module. For the evidenced
object-module family the initial overlay maps exactly three active files to:
```text
root manifest -> E__configinfo
object descriptor -> E__O
object `.S` module -> E__O.S, where `.S` is the suffix of the exact resolved
BSL stream (for example `.0` or `.2`)
```
The adapter must reject any incomplete route and must never fall back to
unchanged hash names. The map and all service atoms are copied verbatim on the
first overlay; subsequent writes update only the proven file-SHA reference.
### Exact prepare/write algorithm
1. Resolve the extension, public object `O`, active descriptor and active `.S`
BSL stream from the extension manifest.
2. Decode the selected active root. Require exactly one map entry for `O` and
exactly one for the selected `O.S`; require their SHA-1 values to equal the selected
active descriptor/module payloads.
3. If the overlay is absent, atomically copy only those three sources as
`E__configinfo`, `E__O`, and `E__O.S`. Do not copy the whole extension.
4. If it exists, preserve pending rows and maps; never overwrite another
change. Prepare may add only missing object parts.
5. Replace BSL only after the exact old fragment, source SHA-1, extension,
public object and module stream agree. For an object module, update the one
`O.S` SHA-1 value in `E__configinfo` in the same transaction and preserve
service atoms byte-for-byte.
6. Re-read the BSL and both changed rows. `apply_and_rollback` must restore
the module and remove adapter-created first-overlay rows.
`code.write` callers provide only public selectors and the replacement. The
adapter owns storage mapping, preparation, paired update and rollback.
## Rejected approaches (retain as regression hazards)
- Copying `ConfigCAS` hash rows to `ConfigCASSave` under the same names. It
produced correct SQL readback but Configurator ignored it for `фс_Отчеты`.
- Writing only the BSL module payload. The map continues to point to the old
SHA-1 and Configurator reports a collection/hash-version error.
- Generating `__configinfo`, its service atoms, or logical file mappings from
names alone. The adapter must first decode the actual selected root map.
- Replacing the entire compressed module container. Only the declared BSL
prefix codec is allowed; opaque stream tail bytes must remain unchanged.
- Resolving an already selected object-module path through generic metadata
path traversal. Its module suffix is a BSL container, so this can fail before the
saved-state writer sees the exact module route.
## Proven incremental write protocol
For a form module change:
1. Read the current `E__configinfo` from `ConfigCASSave` if it exists;
otherwise derive a complete initial overlay from active `ConfigCAS`.
2. Resolve the form descriptor and module hashes from that map.
3. Patch the module with a unique BSL anchor and lossless payload codec.
4. Replace exactly the Base64(SHA-1(raw module bytes)) value paired with
logical name `O.0` in `E__configinfo`.
5. Preserve every unrelated map entry and service atom byte-for-byte.
6. In one transaction insert missing `E__O`/`E__O.0` rows and update
`E__configinfo`, with compare-and-set SHA-1 preconditions.
The adapter core exposes a pure `build_extension_saved_state_pair_plan` helper
for steps 35. It refuses a plan when the ConfigInfo map does not reference the
current saved stream, so a later transaction cannot silently overwrite a
divergent human overlay.
For an already existing single-part pending stream, the paired writer locks the
module and `__configinfo`, verifies both preconditions, writes both payloads
and their `DataSize` values in one transaction, keeps independent rollback
evidence, and verifies both rows afterwards. `__configinfo` itself is never a
primary editable stream. Missing overlay rows still use the separate prepare
route before this writer may update them.
This protocol was activation-proven in the `test2` experiment. It is not yet
a universal proof for every 1C platform version or every extension object
class; new classes require their own evidence record.
## Important overlay behaviour
An external SQL overlay write does not set the Configurators in-memory dirty
flag. Its visibility therefore depends on the current session. See
[Configurator refresh behaviour](../operations/configurator-cache.md).