From d625688a09881de2484a1b2a1d5fcb8e8fd24f5f Mon Sep 17 00:00:00 2001 From: Xuepoo Foter <144407384+Xuepoo@users.noreply.github.com> Date: Mon, 5 Oct 2026 15:26:39 +0800 Subject: [PATCH 1/3] [CTX-0251] docs(erratum): reconcile W-131 KV ceilings with implemented values --- .../storage-and-history-boundary.md | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/docs/development/storage-and-history-boundary.md b/docs/development/storage-and-history-boundary.md index 569ed10..e959143 100644 --- a/docs/development/storage-and-history-boundary.md +++ b/docs/development/storage-and-history-boundary.md @@ -41,6 +41,32 @@ ownership statement here is a contract direction for a later implementation; the (bitty-plugins-docs), `W-139` (bitty-plugin-sdk), and `W-146` (bitty / `CTX-0939`). +## Erratum (2026-10-05) + +This erratum amends the per-plugin KV ceiling contract to the implemented +values. Accepted status is kept; this is a correction, not a normative +weakening. + +- Corrected ceilings: 64 KiB total per plugin + (`STORE_MAX_TOTAL_BYTES = 64 * 1024`), 8 KiB per value (unchanged, + `STORE_MAX_VALUE_BYTES = 8 * 1024`), JSON depth 16 + (`JSON_MAX_DEPTH = 16`), 256 entries per plugin + (`STORE_MAX_ENTRIES = 256`); atomic commit with no partial write is + unchanged. +- Provenance: `bitty-storage` `src/ceiling.rs` ceiling constants, + byte-for-byte with the Core + `crates/bitty-runtime/src/plugin_runtime/store.rs` bounds, confirmed by + the `bitty-storage` CTX-0003/0004 parity evidence. +- Superseded prose: the budget table below previously stated 256 KiB total + per plugin, depth 8, and 1024 nodes. Read the corrected ceilings above + wherever that prose appears. +- Why this is not a weakening: the implemented size and entry bounds are + strictly tighter than the superseded prose. Depth 16 versus 8 is the one + documented exception: it carries Core's pre-existing JSON depth, already + enforced by Core. +- No silent changes: any future bound change is a new security-reviewed + decision, not an edit to this erratum. + ## Purpose and scope This specification is the accepted reconciliation of the history and storage scope. It fixes one ownership and @@ -159,12 +185,12 @@ sensitivities, and budgets. They must not be merged into one universal database or one shared store, and none may become the default sink for raw terminal output. -| Storage object | Owner (contract and policy) | Store mechanics | Lifecycle | Retention and deletion | Persists by default | Budget or bound | -| -------------------- | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | -| Segmented transcript | History plugin (`history`, candidate) under plugin-facing policy fixed by `W-137`; Core owns the event source | Proposed extracted `bitty-storage` mechanics under the accepted reconciliation | Created only while opt-in capture is enabled for a panel; segments seal and roll; active capture ends at purging or uninstalling the plugin or at panel close per policy, and retained history is not deleted merely by closing a panel | Retention by age and size with sealed-segment deletion; explicit purge is authoritative and must remove bytes; no resurrect from a derived index | No; raw stdout and PTY bytes are not persisted without explicit opt-in | Per-panel and per-store byte and age caps; bounded sealed-segment size; compression; no unbounded growth | -| Command history | History plugin under policy fixed by `W-137`; Core owns the event source, and `OSC 133` is advisory only | Proposed extracted `bitty-storage` mechanics for the bytes and rebuildable index | Appended per command boundary while capture is enabled; small and long-lived; external links may dangle after provider removal | Explicit purge or uninstall; age and count bounds; dangling external references surface as typed unavailability, never as silent gaps | No; capture is opt-in, and recording input is a separate opt-in | Command-count, age, and byte bounds; commands-only is the least sensitive tier; optional output tier stays bounded and separate | -| Session snapshots | Core, under the Restore/Persistence separation in ADR 0013 and the Panel Runtime save/restore rules | Core save/restore path; storage mechanics may move only if restore re-derivation stays Core | Written by Core on normal interactive exit; read on restore; volatile structure is re-derived on load and fails closed to a clean start | Replaced by the next exit save; deletion removes the session file; safe mode never reads it; restore never writes | Yes for bounded scrollback and cwd on normal interactive exit (open point below); never under safe or headless mode | Versioned whole-file bound; bounded per-pane scrollback and captured metadata; atomic temp-plus-rename | -| Per-plugin KV | `bitty-plugin-host` Lua host service (Core); SDK surface fixed by `W-139`, plugin-facing policy by `W-137` | Core host service today; mechanics may move to `bitty-storage` while the contract stays with the SDK | Plugin-scoped and generation-independent: values committed before a generation is disposed remain readable by the next generation | Deleted only by uninstall, an explicit `nil` write, or an explicit user purge; no expiry and no eviction by construction | Only plugin-authored writes; not a default sink for terminal output or secrets | Published plugin-store ceilings: 256 KiB total per plugin, 8 KiB per value, depth 8, 1024 nodes; atomic commit with no partial write | +| Storage object | Owner (contract and policy) | Store mechanics | Lifecycle | Retention and deletion | Persists by default | Budget or bound | +| -------------------- | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| Segmented transcript | History plugin (`history`, candidate) under plugin-facing policy fixed by `W-137`; Core owns the event source | Proposed extracted `bitty-storage` mechanics under the accepted reconciliation | Created only while opt-in capture is enabled for a panel; segments seal and roll; active capture ends at purging or uninstalling the plugin or at panel close per policy, and retained history is not deleted merely by closing a panel | Retention by age and size with sealed-segment deletion; explicit purge is authoritative and must remove bytes; no resurrect from a derived index | No; raw stdout and PTY bytes are not persisted without explicit opt-in | Per-panel and per-store byte and age caps; bounded sealed-segment size; compression; no unbounded growth | +| Command history | History plugin under policy fixed by `W-137`; Core owns the event source, and `OSC 133` is advisory only | Proposed extracted `bitty-storage` mechanics for the bytes and rebuildable index | Appended per command boundary while capture is enabled; small and long-lived; external links may dangle after provider removal | Explicit purge or uninstall; age and count bounds; dangling external references surface as typed unavailability, never as silent gaps | No; capture is opt-in, and recording input is a separate opt-in | Command-count, age, and byte bounds; commands-only is the least sensitive tier; optional output tier stays bounded and separate | +| Session snapshots | Core, under the Restore/Persistence separation in ADR 0013 and the Panel Runtime save/restore rules | Core save/restore path; storage mechanics may move only if restore re-derivation stays Core | Written by Core on normal interactive exit; read on restore; volatile structure is re-derived on load and fails closed to a clean start | Replaced by the next exit save; deletion removes the session file; safe mode never reads it; restore never writes | Yes for bounded scrollback and cwd on normal interactive exit (open point below); never under safe or headless mode | Versioned whole-file bound; bounded per-pane scrollback and captured metadata; atomic temp-plus-rename | +| Per-plugin KV | `bitty-plugin-host` Lua host service (Core); SDK surface fixed by `W-139`, plugin-facing policy by `W-137` | Core host service today; mechanics may move to `bitty-storage` while the contract stays with the SDK | Plugin-scoped and generation-independent: values committed before a generation is disposed remain readable by the next generation | Deleted only by uninstall, an explicit `nil` write, or an explicit user purge; no expiry and no eviction by construction | Only plugin-authored writes; not a default sink for terminal output or secrets | Published plugin-store ceilings: 64 KiB total per plugin, 8 KiB per value, depth 16, 256 entries; atomic commit with no partial write | ### Segmented transcript From 7f38336229ef178ca9d886a0dfe69a16a8b2e60e Mon Sep 17 00:00:00 2001 From: Xuepoo Foter <144407384+Xuepoo@users.noreply.github.com> Date: Mon, 5 Oct 2026 15:44:35 +0800 Subject: [PATCH 2/3] [CTX-0251] docs(erratum): note dual-layer enforcement until bitty-lua alignment (CTX-0970) --- docs/development/storage-and-history-boundary.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/development/storage-and-history-boundary.md b/docs/development/storage-and-history-boundary.md index e959143..3fe0296 100644 --- a/docs/development/storage-and-history-boundary.md +++ b/docs/development/storage-and-history-boundary.md @@ -64,6 +64,11 @@ weakening. strictly tighter than the superseded prose. Depth 16 versus 8 is the one documented exception: it carries Core's pre-existing JSON depth, already enforced by Core. +- Dual-layer scope note: the Lua marshalling layer (`bitty-lua` store) still + enforces the older 256 KiB / depth 8 / 1024-node ceilings; effective + enforcement is the tighter of the two layers per dimension until its + alignment lands (bitty CTX-0970). In particular depth 8 governs live + traffic today, not the depth 16 stated above. - No silent changes: any future bound change is a new security-reviewed decision, not an edit to this erratum. From 0c750b9c8261992d0259e23936bf0697027ce0d1 Mon Sep 17 00:00:00 2001 From: Xuepoo Foter <144407384+Xuepoo@users.noreply.github.com> Date: Mon, 5 Oct 2026 16:15:03 +0800 Subject: [PATCH 3/3] [CTX-0251] docs(erratum): resolve dual-layer note past-tense after CTX-0970 merge --- docs/development/storage-and-history-boundary.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/development/storage-and-history-boundary.md b/docs/development/storage-and-history-boundary.md index 3fe0296..ba6710b 100644 --- a/docs/development/storage-and-history-boundary.md +++ b/docs/development/storage-and-history-boundary.md @@ -64,11 +64,12 @@ weakening. strictly tighter than the superseded prose. Depth 16 versus 8 is the one documented exception: it carries Core's pre-existing JSON depth, already enforced by Core. -- Dual-layer scope note: the Lua marshalling layer (`bitty-lua` store) still - enforces the older 256 KiB / depth 8 / 1024-node ceilings; effective - enforcement is the tighter of the two layers per dimension until its - alignment lands (bitty CTX-0970). In particular depth 8 governs live - traffic today, not the depth 16 stated above. +- Dual-layer scope note (resolved 2026-10-05): the Lua marshalling layer + previously enforced the older 256 KiB / depth 8 / 1024-node ceilings; its + alignment to the ceilings above landed in bitty CTX-0970 (PR #1713, + `a3dbf9d`). Both layers now enforce 64 KiB total, 8 KiB per value, and + depth 16; the count bound is 256 in each layer's native unit (entries in + `bitty-runtime`, nodes in `bitty-lua`). - No silent changes: any future bound change is a new security-reviewed decision, not an edit to this erratum.