diff --git a/docs/decisions/index.md b/docs/decisions/index.md index b01ac7f..0bd85ca 100644 --- a/docs/decisions/index.md +++ b/docs/decisions/index.md @@ -322,6 +322,7 @@ the historical conversation: - Repository metadata and `.github` baseline across the estate. (Proposed: [ADR 0011](adrs/ADR-0011-repository-metadata-baseline.md) and the [Repository Metadata and GitHub Baseline](../development/repository-metadata-baseline.md) guide — byte-identical, parameterized, and per-repository tiers; required-check naming atomic with branch protection; action SHA pinning and rust-channel pinning. Extended from the 2026-09-11 configuration-drift audit under `CTX-0155`; not yet accepted and authorizes no consumer-repository change.) - AI consent to generic scope mapping. (Draft: [AI Consent to Generic Scope Mapping RFC](rfcs/RFC-0003-ai-consent-scope-mapping.md) — maps the AI consent vocabulary to the shipped 13-scope generic IPC registry, marks workspace-context and memory-persistence terms as uncovered with candidate resolutions, and defines the ai-docs adoption path; closes CTX-0407 gap G-6 under docs `CTX-0190` while [OQ-066](open-questions.md) remains open; frontmatter `draft` on 2026-09-14.) - Read-only history, search, and selection plugin surface. (Accepted: [History Read Surface RFC](rfcs/RFC-0004-history-read-surface.md) — fixes a NEW read-only capability family (not `terminal.*`) of bounded snapshot queries with explicit per-plugin grants, no live streaming or subscription, secret-minimizing storage with redaction per W-131, transcript/history/KV stores as queryable sources under the same ceilings, and typed denials; the closed `terminal` family stays closed and v1 stays frozen; targets [OQ-056](open-questions.md), which stays open; successor to the W-139 block per DEC-W139-1 with the chain RFC accepted, Core host implementation, SDK, plugin parity, then W-144 deletion; frontmatter `accepted` on 2026-10-04; Issue #430.) +- Filesystem host surface. (Accepted: [Filesystem Host Surface RFC](rfcs/RFC-0005-filesystem-host-surface.md) — reconciles the draft `bitty.fs.open/append/read/list` sketch against the accepted `fs.read:PATTERN`/`fs.write:PATTERN` split as decided verbs read/write/list under a NEW `bitty.fs.*` root (never `bitty.terminal.*`), with scoped grants and no wildcard reusing the 4096/32/8KiB bounds, typed oracle-tight denials, untrusted labeling with preview-equality, read-into-VM-only grant combination, and no watch or tail-follow; v1 stays frozen with no `fs` namespace; targets [OQ-056](open-questions.md), which stays open; rollout is RFC draft, security review, Core host bridge, SDK, then file-manager/editor-preview/Wheel parity; frontmatter `accepted` on 2026-10-05; Issue #439.) Each candidate is represented by an item in the [open-question register](open-questions.md). Acceptance requires an ADR, RFC, diff --git a/docs/decisions/open-questions.md b/docs/decisions/open-questions.md index 569cb1c..f6715ca 100644 --- a/docs/decisions/open-questions.md +++ b/docs/decisions/open-questions.md @@ -54,26 +54,26 @@ other evidence. Update the topic document and the ## Configuration and plugins -| ID | Question | Canonical document | Next artifact | State | -| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| OQ-009 | Which Lua runtime/binding, standard-library subset, module search rules, schema, and diagnostics contract are used? | [Lua and XDG](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/configuration/lua-and-xdg.md) | [Lua runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/lua-runtime-rfc.md) | Accepted: [lua-runtime-rfc.md](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/lua-runtime-rfc.md) (closed OQ-009 on 2026-08-27; OQ-030, OQ-031, OQ-032 remain Open as follow-ups) | -| OQ-010 | Are declarative `ConfigPlan` generation and Rust reconciliation adopted, and how do XDG layers, profiles, merge rules, reload, and project trust work? | [Lua and XDG](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/configuration/lua-and-xdg.md) | Configuration model RFC | Accepted: [configuration-model-rfc](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/specifications/configuration-model-rfc.md) | -| OQ-011 | What is Plugin API v1 across commands, events, UI, services, lifecycle, and compatibility? | [Plugin system](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/extensibility/plugin-system.md); [core boundaries](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/architecture/core-boundaries.md) | [Plugin platform RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/specifications/plugin-platform-rfc.md) | Accepted: [plugin-platform-rfc](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/specifications/plugin-platform-rfc.md); Lua surface resolved 2026-09-11 by [plugin-api-v1-lua-surface-rfc](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/sdk/plugin-api-v1-lua-surface-rfc.md) ([ADR 0009](adrs/ADR-0009-plugin-api-v1-lua-surface.md)) | -| OQ-012 | What manifest, capability identifiers, grant storage, prompts, and revocation workflow implement the normative capability model? | [Plugin system](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/extensibility/plugin-system.md); [security overview](../security/overview.md) | [Plugin platform RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/specifications/plugin-platform-rfc.md) | Accepted: [plugin-platform-rfc](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/specifications/plugin-platform-rfc.md) | -| OQ-013 | Which event phases may observe or intercept, and what batching, timeout, drop, and backpressure rules apply? | [Core boundaries](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/architecture/core-boundaries.md) | [Plugin platform RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/specifications/plugin-platform-rfc.md) | Accepted: [plugin-platform-rfc](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/specifications/plugin-platform-rfc.md) | -| OQ-014 | Which per-plugin VM, restricted-library, lazy-load, reload, callback, queue, instruction, CPU, memory, and task mechanisms satisfy the normative isolation and budget gates? | [Plugin system](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/extensibility/plugin-system.md); [security overview](../security/overview.md) | [Isolation Resource RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/isolation-resource-rfc.md) | Accepted: [isolation-resource-rfc.md](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/isolation-resource-rfc.md) (closed OQ-014 on 2026-08-28; isolation domains, resource ceilings RC-1..RC-10, failure semantics FS-1..FS-9, and adversarial AT-IR-001..015 accepted; three-level queue PerSub 64 / PerPlugin 1024 events/256 KiB / Global 8192 events/2 MiB hard-gated at Host admission, RC-1 10^7/50 ms/8 ms, RC-2 32 MiB via `piccolo` Fuel + wall and `Lua::total_memory()`, measured 2026-08-27 via `crates/bitty-plugin-host/tests/measurement.rs` 21 tests and `crates/bitty-lua/tests/measurement_lua.rs` 15 tests @ `d67a65b`, gates `just check` + `cargo check --target x86_64-pc-windows-gnu` pass; panel-platform follow-up accepted 2026-09-14 via [Panel Runtime RFC](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/specifications/panel-runtime-rfc.md) (docs `CTX-0181`), which keeps `RFC-OQ-1` through `RFC-OQ-9` open; this RFC does not re-close OQ-014, whose isolation and budget mechanisms remain governed here) | -| OQ-030 | Which exact Lua 5.4.x and mlua pins, upgrade cadence, and final standard-library and debug allowlist complete the sandboxed runtime, and what unsafe-surface audit gates the binding choice? | [Lua Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/lua-runtime-rfc.md); [ADR 0004](adrs/ADR-0004-upstream-dependencies.md) | Lua pin and stdlib ADR | Accepted: [ADR 0005](adrs/ADR-0005-lua-pins-and-stdlib.md) (closed OQ-030 on 2026-08-29); successor direction accepted 2026-09-20: [ADR 0012](adrs/ADR-0012-phodopus-runtime.md) moves the plugin-VM path from the Piccolo watch-list candidate to Phodopus, a sandbox-first fork of `piccolo` at `bitty-terminal/phodopus`; the accepted Lua 5.4.x/`mlua` and `piccolo 0.3.3` pins remain accurate and in force until an implementing task migrates `bitty-lua`. | -| OQ-031 | What is the exposure policy for `os.getenv` and environment-adjacent APIs in the Configuration VM given trace-minimization and redaction defaults? | [Lua Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/lua-runtime-rfc.md); [Security overview](../security/overview.md) | os.getenv policy ADR | Accepted: [ADR 0006](adrs/ADR-0006-os-env-policy.md) (closed OQ-031 on 2026-08-29) | -| OQ-032 | How are async/Send boundaries, GC tuning, memory ceilings, Config VM budgets, and reload/module-cache interactions specified and measured for the Lua VMs? | [Lua Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/lua-runtime-rfc.md); [Configuration Model RFC](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/specifications/configuration-model-rfc.md); [Isolation Resource RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/isolation-resource-rfc.md) | Async/Send and GC tuning RFC | Accepted: [ADR 0007](adrs/ADR-0007-async-gc.md) (closed OQ-032 on 2026-08-29) | -| OQ-033 | Where does the runtime plugin host bridge live, how is it embedded over the `piccolo` `bitty-lua` seam, how are host callbacks marshalled and `init.lua` registration captured, and how is the per-plugin VM created, suspended, resumed, reloaded, and disposed with its generation? | [Plugin system](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/extensibility/plugin-system.md); [Plugin API v1 Lua Surface RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/sdk/plugin-api-v1-lua-surface-rfc.md); [Lua Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/lua-runtime-rfc.md) | [Plugin Host Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/plugin-host-runtime-rfc.md), then ADR | Accepted and shipped: [plugin-host-runtime-rfc](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/plugin-host-runtime-rfc.md) and [ADR 0010](adrs/ADR-0010-plugin-host-runtime-acceptance.md) (closed OQ-033 on 2026-09-11; adopts `bitty-runtime` orchestration, the `bitty-lua` seam extensions, synchronous non-blocking marshalling, one VM per `(PluginId, generation)`, and the `RC-1`-reused activation deadline; bitty `CTX-0324` Gap A). First slice shipped in bitty PR #554 merge `e51b5cc` (CTX-0328: bridge, VM lifecycle, and the `bitty-lua` seam in `crates/bitty-lua/src/host.rs`; tests `crates/bitty-runtime/tests/plugin_runtime.rs` incl. `real_activity_plugin_activates`); reload/update triggers remain OQ-072 and hardening remains bitty `CTX-0330` | -| OQ-034 | What is the runtime plugin source resolution and staging layout, including the installed manifest and Lua module tree location, active-version pointer, discovery and integrity checks, and the local-path development flow, so the host can load non-bundled plugins? | [Package management](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/extensibility/package-management.md); [Package Lifecycle RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/packaging/package-lifecycle-rfc.md) | [Plugin Host Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/plugin-host-runtime-rfc.md), then ADR | Accepted and shipped: [plugin-host-runtime-rfc](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/plugin-host-runtime-rfc.md) and [ADR 0010](adrs/ADR-0010-plugin-host-runtime-acceptance.md) (closed OQ-034 on 2026-09-11; adopts the `$XDG_DATA_HOME/bitty/plugins/` store, atomic `current.json`, fail-closed `manifest_hash`/`content_digest` verification, the extended source record, and the read-only local-path flow; the source-layout dependency on the package-management candidate store is resolved; bitty `CTX-0324` Gap B). First slice shipped in bitty PR #558 merge `064b9de` (CTX-0329: `plugin_runtime::resolution`, tests `crates/bitty-runtime/tests/plugin_store.rs` incl. `write_index_is_atomic_and_round_trips`, `content_digest_mismatch_fails_closed`, `native_artifact_is_rejected`, and `safe_mode_does_not_read_store_tree`); `registry`/`git` resolution stays deferred per RFC B.1 | -| OQ-035 | What is the plugin host-service wiring boundary - owning component, sync/async and `Send` contract, and persistence path - for `bitty.terminal.snapshot`, `bitty.notify.show`, `bitty.store.*`, and `bitty.settings.*`? | [Plugin API v1 Lua Surface RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/sdk/plugin-api-v1-lua-surface-rfc.md); [Core boundaries](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/architecture/core-boundaries.md) | [Plugin Host Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/plugin-host-runtime-rfc.md), then ADR | Accepted and shipped: [plugin-host-runtime-rfc](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/plugin-host-runtime-rfc.md) and [ADR 0010](adrs/ADR-0010-plugin-host-runtime-acceptance.md) (closed OQ-035 on 2026-09-11; adopts the host-service ownership/persistence table, the synchronous non-blocking `Send` contract, and the typed fail-closed error contract; bitty `CTX-0324` Gap C). First slice shipped in bitty PR #554 merge `e51b5cc` (CTX-0328: `plugin_runtime::services` with `SettingsSource`, `SnapshotSource`, bounded `NotificationQueue`, and the atomic plugin store); typed-error/`E_TIMEOUT` hardening and lifecycle edge cases remain bitty `CTX-0330` (P1) | -| OQ-053 | Which bundled first-party plugins migrate to independently versioned first-party packages, and what discovery, trust, update, and grant-preservation rules apply to the migration? | [Plugin Roadmap](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/product/plugin-roadmap.md) | Acceptance decision (ADR, RFC revision, or specification update) | Accepted: [Bundled-Plugin Split Decision (OQ-053)](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/product/bundled-plugin-split-decision.md) (closed OQ-053 on 2026-09-14; `palette` and `statusline` split to independent first-party packages; `browser-panel` stays bundled as a Core mechanism; `file-manager`, `git-panel`, `ai-panel`, and `mail-panel` split later behind the panel-provider contract; shell integration and the workspace core, including the workspaceline claim, stay bundled. Catalog revised ten to eight in the [Default Distribution RFC amendment](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/specifications/default-distribution-rfc.md#split-to-independent-first-party-packages-2026-09-14); evidence `palette`#2, `statusline`#2, `bitty-plugins`#6/#9, `bitty`#678 `dd46c7a`, `bitty`#680 head `5591216` (open); deltas tracked as `bitty-plugins` `CTX-0005`). Superseded 2026-09-30 (`bitty` CTX-0886, #1554/#1556/#1557): only `shell-integration` and `workspace` stay bundled | -| OQ-054 | What are the config semantics for `api_key_env` versus `api_key_cmd` credential references, their resolution order, and the project-level override boundary that cannot widen credentials? | [AI Architecture](https://github.com/bitty-terminal/bitty-ai-docs/blob/main/architecture/ai-architecture.md); [Plugin Roadmap](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/product/plugin-roadmap.md) | Acceptance decision (ADR, RFC revision, or specification update) | Accepted (owner ruling 2026-09-23 adopting packet MPC-1..MPC-4): explicit `api_key_env` versus `api_key_cmd` resolution order with the project-cannot-widen boundary; composes with ADR 0006 and MP-10; implementation: bitty#1092 provider-schema work; no implementation claim | -| OQ-055 | Which secret-storage tiers are in scope (host-consumed environment, `$XDG_CONFIG_HOME/bitty/secrets.env` mode `0600`, OS keyring, `pass`/1Password command references), and how do consent, audit, and redaction apply per tier? | [Plugin Roadmap](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/product/plugin-roadmap.md); [ADR 0006](adrs/ADR-0006-os-env-policy.md) | Acceptance decision (ADR, RFC revision, or specification update) | Accepted (owner ruling 2026-09-23 adopting the packet recommendation): secret-storage tiers (host env, `0600` secrets file, OS keyring, command references) with per-tier consent, audit, and redaction on top of ADR 0006; implementation: bitty#1091; no implementation claim | -| OQ-056 | Which plugin capability dimensions beyond the accepted v1 surface get contracts (semantic UI slots, presentation projection, workspace policies, events/automation action classes, cross-plugin service multiplicity, and the focusable-overlay and transient input-capture host API), and in which API version? | [Plugin Roadmap](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/product/plugin-roadmap.md); [UI Extensibility Architecture](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/architecture/ui-extensibility-architecture.md) | Acceptance decision (ADR, RFC revision, or specification update) | Open (deferred to API v2 per owner ruling 2026-09-23 adopting the packet recommendation): v1 surface frozen; semantic UI slots, presentation projection, workspace policies, automation actions, and service multiplicity recorded as v2 scope; bitty#1000 and #1017 proceed against the frozen v1; no implementation claim. Amended 2026-10-02 (`W-01`, Issue #396) to name the focusable-overlay and transient input-capture host API as v2 scope: a capability-gated Core host mechanism a plugin claims to take exclusive keyboard and overlay focus for the duration of a UI interaction, blocked consumers are the palette overlay (`E_UI_UNAVAILABLE` with the v1 non-focusable `overlay` slot), Beacon key capture, and help/search/copy-mode extraction; safety constraints are that capture stays capability-gated, transient, bounded, revocable on cancel, submit, focus switch, plugin unload, plugin crash, and Core-side timeout, never places a plugin callback on the input hot path, and the capture mechanism stays Core-owned and never weakenable; contract authority is `W-01`; no implementation claim. Decided 2026-10-03 for the focusable-overlay and transient input-capture dimension only (`docs/development/overlay-input-capture-contract.md`, `status: accepted`, CTX-0273, Issue #423): capability `ui.overlay.focus`, Lua `bitty.ui.overlay.*` surface, bounds and error codes fixed; all other listed dimensions stay Open v2 scope. Amended 2026-10-04 (W-139 successor, Issue #430) to name the read-only history/search/selection plugin surface as v2 scope: a NEW capability family (not `terminal.*`) of bounded snapshot queries with explicit row ranges and capped counts/sizes, explicit per-plugin grants, no live streaming or subscription, secret-minimizing storage with redaction per W-131, transcript/history/KV stores as queryable sources under the same ceilings, and typed denials; blocked consumers are search, copy-mode, and history plugins, with W-144 deletion waiting on their parity; safety constraints are that the closed `terminal` family stays closed, scrollback content stays untrusted observation data, and the surface stays v2-only with v1 frozen; contract authority is RFC-0004; no implementation claim. Accepted 2026-10-04 for the read-only history/search/selection dimension only ([RFC-0004](rfcs/RFC-0004-history-read-surface.md), `status: accepted`, Issue #430): NEW read-only capability family (not `terminal.*`) of bounded snapshot queries with explicit per-plugin grants, typed denials, and secret-minimizing storage with redaction per W-131; Core host implementation plus search, copy-mode, and history plugin parity remain Open v2 scope; no implementation claim. | -| OQ-068 | What is the `.wheel/` project-definition directory contract (layout, schema, Git-tracked versus runtime-state split, and trust), and how does `.agents/` compatibility resolve against it without becoming a competing source of truth? | [Lua and XDG](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/configuration/lua-and-xdg.md); [Configuration Model RFC](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/specifications/configuration-model-rfc.md) | Acceptance decision (ADR, RFC revision, or specification update) | Accepted (owner ruling 2026-09-23 adopting the packet recommendation): declarative-data-only Git-tracked `.wheel/` (`project.toml`, `agents/`, `workflows/`, `prompts/`, `policies/`, `tools/`, `skills/`) with discovery `.wheel/` then `.agents/`; Wheel rename confirmed; schema drafting is the open part; implementation: bitty#1096; no implementation claim | -| OQ-072 | What triggers plugin reload and update at runtime in v1 — which explicit surfaces (`bitty plugin reload`, IPC control, package-manager wake) and which automatic `local-path` development watcher contract (watch roots, canonicalization, debounce/coalescing, in-flight limits, failure handling) — and what happens to queued generation-N events at disposal? | [Plugin Host Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/plugin-host-runtime-rfc.md); [Plugin system](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/extensibility/plugin-system.md); [Package Lifecycle RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/packaging/package-lifecycle-rfc.md) | Acceptance decision (ADR, RFC revision, or specification update) | Open: candidate direction recorded in the Plugin Host Runtime RFC section "Candidate - reload/update triggers and queue drain (OQ-072)"; accepted reload mechanics stay authoritative (teardown N before N+1, FS-6 restore-or-disable, hash-bound grants and R-016 update diff, `DropOldest` v1 default); trigger surface, watcher contract, and generation-queue drain at disposal remain unspecified; no implementation claim | +| ID | Question | Canonical document | Next artifact | State | +| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| OQ-009 | Which Lua runtime/binding, standard-library subset, module search rules, schema, and diagnostics contract are used? | [Lua and XDG](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/configuration/lua-and-xdg.md) | [Lua runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/lua-runtime-rfc.md) | Accepted: [lua-runtime-rfc.md](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/lua-runtime-rfc.md) (closed OQ-009 on 2026-08-27; OQ-030, OQ-031, OQ-032 remain Open as follow-ups) | +| OQ-010 | Are declarative `ConfigPlan` generation and Rust reconciliation adopted, and how do XDG layers, profiles, merge rules, reload, and project trust work? | [Lua and XDG](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/configuration/lua-and-xdg.md) | Configuration model RFC | Accepted: [configuration-model-rfc](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/specifications/configuration-model-rfc.md) | +| OQ-011 | What is Plugin API v1 across commands, events, UI, services, lifecycle, and compatibility? | [Plugin system](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/extensibility/plugin-system.md); [core boundaries](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/architecture/core-boundaries.md) | [Plugin platform RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/specifications/plugin-platform-rfc.md) | Accepted: [plugin-platform-rfc](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/specifications/plugin-platform-rfc.md); Lua surface resolved 2026-09-11 by [plugin-api-v1-lua-surface-rfc](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/sdk/plugin-api-v1-lua-surface-rfc.md) ([ADR 0009](adrs/ADR-0009-plugin-api-v1-lua-surface.md)) | +| OQ-012 | What manifest, capability identifiers, grant storage, prompts, and revocation workflow implement the normative capability model? | [Plugin system](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/extensibility/plugin-system.md); [security overview](../security/overview.md) | [Plugin platform RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/specifications/plugin-platform-rfc.md) | Accepted: [plugin-platform-rfc](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/specifications/plugin-platform-rfc.md) | +| OQ-013 | Which event phases may observe or intercept, and what batching, timeout, drop, and backpressure rules apply? | [Core boundaries](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/architecture/core-boundaries.md) | [Plugin platform RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/specifications/plugin-platform-rfc.md) | Accepted: [plugin-platform-rfc](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/specifications/plugin-platform-rfc.md) | +| OQ-014 | Which per-plugin VM, restricted-library, lazy-load, reload, callback, queue, instruction, CPU, memory, and task mechanisms satisfy the normative isolation and budget gates? | [Plugin system](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/extensibility/plugin-system.md); [security overview](../security/overview.md) | [Isolation Resource RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/isolation-resource-rfc.md) | Accepted: [isolation-resource-rfc.md](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/isolation-resource-rfc.md) (closed OQ-014 on 2026-08-28; isolation domains, resource ceilings RC-1..RC-10, failure semantics FS-1..FS-9, and adversarial AT-IR-001..015 accepted; three-level queue PerSub 64 / PerPlugin 1024 events/256 KiB / Global 8192 events/2 MiB hard-gated at Host admission, RC-1 10^7/50 ms/8 ms, RC-2 32 MiB via `piccolo` Fuel + wall and `Lua::total_memory()`, measured 2026-08-27 via `crates/bitty-plugin-host/tests/measurement.rs` 21 tests and `crates/bitty-lua/tests/measurement_lua.rs` 15 tests @ `d67a65b`, gates `just check` + `cargo check --target x86_64-pc-windows-gnu` pass; panel-platform follow-up accepted 2026-09-14 via [Panel Runtime RFC](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/specifications/panel-runtime-rfc.md) (docs `CTX-0181`), which keeps `RFC-OQ-1` through `RFC-OQ-9` open; this RFC does not re-close OQ-014, whose isolation and budget mechanisms remain governed here) | +| OQ-030 | Which exact Lua 5.4.x and mlua pins, upgrade cadence, and final standard-library and debug allowlist complete the sandboxed runtime, and what unsafe-surface audit gates the binding choice? | [Lua Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/lua-runtime-rfc.md); [ADR 0004](adrs/ADR-0004-upstream-dependencies.md) | Lua pin and stdlib ADR | Accepted: [ADR 0005](adrs/ADR-0005-lua-pins-and-stdlib.md) (closed OQ-030 on 2026-08-29); successor direction accepted 2026-09-20: [ADR 0012](adrs/ADR-0012-phodopus-runtime.md) moves the plugin-VM path from the Piccolo watch-list candidate to Phodopus, a sandbox-first fork of `piccolo` at `bitty-terminal/phodopus`; the accepted Lua 5.4.x/`mlua` and `piccolo 0.3.3` pins remain accurate and in force until an implementing task migrates `bitty-lua`. | +| OQ-031 | What is the exposure policy for `os.getenv` and environment-adjacent APIs in the Configuration VM given trace-minimization and redaction defaults? | [Lua Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/lua-runtime-rfc.md); [Security overview](../security/overview.md) | os.getenv policy ADR | Accepted: [ADR 0006](adrs/ADR-0006-os-env-policy.md) (closed OQ-031 on 2026-08-29) | +| OQ-032 | How are async/Send boundaries, GC tuning, memory ceilings, Config VM budgets, and reload/module-cache interactions specified and measured for the Lua VMs? | [Lua Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/lua-runtime-rfc.md); [Configuration Model RFC](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/specifications/configuration-model-rfc.md); [Isolation Resource RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/isolation-resource-rfc.md) | Async/Send and GC tuning RFC | Accepted: [ADR 0007](adrs/ADR-0007-async-gc.md) (closed OQ-032 on 2026-08-29) | +| OQ-033 | Where does the runtime plugin host bridge live, how is it embedded over the `piccolo` `bitty-lua` seam, how are host callbacks marshalled and `init.lua` registration captured, and how is the per-plugin VM created, suspended, resumed, reloaded, and disposed with its generation? | [Plugin system](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/extensibility/plugin-system.md); [Plugin API v1 Lua Surface RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/sdk/plugin-api-v1-lua-surface-rfc.md); [Lua Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/lua-runtime-rfc.md) | [Plugin Host Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/plugin-host-runtime-rfc.md), then ADR | Accepted and shipped: [plugin-host-runtime-rfc](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/plugin-host-runtime-rfc.md) and [ADR 0010](adrs/ADR-0010-plugin-host-runtime-acceptance.md) (closed OQ-033 on 2026-09-11; adopts `bitty-runtime` orchestration, the `bitty-lua` seam extensions, synchronous non-blocking marshalling, one VM per `(PluginId, generation)`, and the `RC-1`-reused activation deadline; bitty `CTX-0324` Gap A). First slice shipped in bitty PR #554 merge `e51b5cc` (CTX-0328: bridge, VM lifecycle, and the `bitty-lua` seam in `crates/bitty-lua/src/host.rs`; tests `crates/bitty-runtime/tests/plugin_runtime.rs` incl. `real_activity_plugin_activates`); reload/update triggers remain OQ-072 and hardening remains bitty `CTX-0330` | +| OQ-034 | What is the runtime plugin source resolution and staging layout, including the installed manifest and Lua module tree location, active-version pointer, discovery and integrity checks, and the local-path development flow, so the host can load non-bundled plugins? | [Package management](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/extensibility/package-management.md); [Package Lifecycle RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/packaging/package-lifecycle-rfc.md) | [Plugin Host Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/plugin-host-runtime-rfc.md), then ADR | Accepted and shipped: [plugin-host-runtime-rfc](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/plugin-host-runtime-rfc.md) and [ADR 0010](adrs/ADR-0010-plugin-host-runtime-acceptance.md) (closed OQ-034 on 2026-09-11; adopts the `$XDG_DATA_HOME/bitty/plugins/` store, atomic `current.json`, fail-closed `manifest_hash`/`content_digest` verification, the extended source record, and the read-only local-path flow; the source-layout dependency on the package-management candidate store is resolved; bitty `CTX-0324` Gap B). First slice shipped in bitty PR #558 merge `064b9de` (CTX-0329: `plugin_runtime::resolution`, tests `crates/bitty-runtime/tests/plugin_store.rs` incl. `write_index_is_atomic_and_round_trips`, `content_digest_mismatch_fails_closed`, `native_artifact_is_rejected`, and `safe_mode_does_not_read_store_tree`); `registry`/`git` resolution stays deferred per RFC B.1 | +| OQ-035 | What is the plugin host-service wiring boundary - owning component, sync/async and `Send` contract, and persistence path - for `bitty.terminal.snapshot`, `bitty.notify.show`, `bitty.store.*`, and `bitty.settings.*`? | [Plugin API v1 Lua Surface RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/sdk/plugin-api-v1-lua-surface-rfc.md); [Core boundaries](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/architecture/core-boundaries.md) | [Plugin Host Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/plugin-host-runtime-rfc.md), then ADR | Accepted and shipped: [plugin-host-runtime-rfc](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/plugin-host-runtime-rfc.md) and [ADR 0010](adrs/ADR-0010-plugin-host-runtime-acceptance.md) (closed OQ-035 on 2026-09-11; adopts the host-service ownership/persistence table, the synchronous non-blocking `Send` contract, and the typed fail-closed error contract; bitty `CTX-0324` Gap C). First slice shipped in bitty PR #554 merge `e51b5cc` (CTX-0328: `plugin_runtime::services` with `SettingsSource`, `SnapshotSource`, bounded `NotificationQueue`, and the atomic plugin store); typed-error/`E_TIMEOUT` hardening and lifecycle edge cases remain bitty `CTX-0330` (P1) | +| OQ-053 | Which bundled first-party plugins migrate to independently versioned first-party packages, and what discovery, trust, update, and grant-preservation rules apply to the migration? | [Plugin Roadmap](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/product/plugin-roadmap.md) | Acceptance decision (ADR, RFC revision, or specification update) | Accepted: [Bundled-Plugin Split Decision (OQ-053)](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/product/bundled-plugin-split-decision.md) (closed OQ-053 on 2026-09-14; `palette` and `statusline` split to independent first-party packages; `browser-panel` stays bundled as a Core mechanism; `file-manager`, `git-panel`, `ai-panel`, and `mail-panel` split later behind the panel-provider contract; shell integration and the workspace core, including the workspaceline claim, stay bundled. Catalog revised ten to eight in the [Default Distribution RFC amendment](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/specifications/default-distribution-rfc.md#split-to-independent-first-party-packages-2026-09-14); evidence `palette`#2, `statusline`#2, `bitty-plugins`#6/#9, `bitty`#678 `dd46c7a`, `bitty`#680 head `5591216` (open); deltas tracked as `bitty-plugins` `CTX-0005`). Superseded 2026-09-30 (`bitty` CTX-0886, #1554/#1556/#1557): only `shell-integration` and `workspace` stay bundled | +| OQ-054 | What are the config semantics for `api_key_env` versus `api_key_cmd` credential references, their resolution order, and the project-level override boundary that cannot widen credentials? | [AI Architecture](https://github.com/bitty-terminal/bitty-ai-docs/blob/main/architecture/ai-architecture.md); [Plugin Roadmap](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/product/plugin-roadmap.md) | Acceptance decision (ADR, RFC revision, or specification update) | Accepted (owner ruling 2026-09-23 adopting packet MPC-1..MPC-4): explicit `api_key_env` versus `api_key_cmd` resolution order with the project-cannot-widen boundary; composes with ADR 0006 and MP-10; implementation: bitty#1092 provider-schema work; no implementation claim | +| OQ-055 | Which secret-storage tiers are in scope (host-consumed environment, `$XDG_CONFIG_HOME/bitty/secrets.env` mode `0600`, OS keyring, `pass`/1Password command references), and how do consent, audit, and redaction apply per tier? | [Plugin Roadmap](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/product/plugin-roadmap.md); [ADR 0006](adrs/ADR-0006-os-env-policy.md) | Acceptance decision (ADR, RFC revision, or specification update) | Accepted (owner ruling 2026-09-23 adopting the packet recommendation): secret-storage tiers (host env, `0600` secrets file, OS keyring, command references) with per-tier consent, audit, and redaction on top of ADR 0006; implementation: bitty#1091; no implementation claim | +| OQ-056 | Which plugin capability dimensions beyond the accepted v1 surface get contracts (semantic UI slots, presentation projection, workspace policies, events/automation action classes, cross-plugin service multiplicity, and the focusable-overlay and transient input-capture host API), and in which API version? | [Plugin Roadmap](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/product/plugin-roadmap.md); [UI Extensibility Architecture](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/architecture/ui-extensibility-architecture.md) | Acceptance decision (ADR, RFC revision, or specification update) | Open (deferred to API v2 per owner ruling 2026-09-23 adopting the packet recommendation): v1 surface frozen; semantic UI slots, presentation projection, workspace policies, automation actions, and service multiplicity recorded as v2 scope; bitty#1000 and #1017 proceed against the frozen v1; no implementation claim. Amended 2026-10-02 (`W-01`, Issue #396) to name the focusable-overlay and transient input-capture host API as v2 scope: a capability-gated Core host mechanism a plugin claims to take exclusive keyboard and overlay focus for the duration of a UI interaction, blocked consumers are the palette overlay (`E_UI_UNAVAILABLE` with the v1 non-focusable `overlay` slot), Beacon key capture, and help/search/copy-mode extraction; safety constraints are that capture stays capability-gated, transient, bounded, revocable on cancel, submit, focus switch, plugin unload, plugin crash, and Core-side timeout, never places a plugin callback on the input hot path, and the capture mechanism stays Core-owned and never weakenable; contract authority is `W-01`; no implementation claim. Decided 2026-10-03 for the focusable-overlay and transient input-capture dimension only (`docs/development/overlay-input-capture-contract.md`, `status: accepted`, CTX-0273, Issue #423): capability `ui.overlay.focus`, Lua `bitty.ui.overlay.*` surface, bounds and error codes fixed; all other listed dimensions stay Open v2 scope. Amended 2026-10-04 (W-139 successor, Issue #430) to name the read-only history/search/selection plugin surface as v2 scope: a NEW capability family (not `terminal.*`) of bounded snapshot queries with explicit row ranges and capped counts/sizes, explicit per-plugin grants, no live streaming or subscription, secret-minimizing storage with redaction per W-131, transcript/history/KV stores as queryable sources under the same ceilings, and typed denials; blocked consumers are search, copy-mode, and history plugins, with W-144 deletion waiting on their parity; safety constraints are that the closed `terminal` family stays closed, scrollback content stays untrusted observation data, and the surface stays v2-only with v1 frozen; contract authority is RFC-0004; no implementation claim. Accepted 2026-10-04 for the read-only history/search/selection dimension only ([RFC-0004](rfcs/RFC-0004-history-read-surface.md), `status: accepted`, Issue #430): NEW read-only capability family (not `terminal.*`) of bounded snapshot queries with explicit per-plugin grants, typed denials, and secret-minimizing storage with redaction per W-131; Core host implementation plus search, copy-mode, and history plugin parity remain Open v2 scope; no implementation claim. Amended 2026-10-05 (filesystem host surface, Issue #439) to name the capability-gated plugin filesystem surface as v2 scope: the accepted `fs.read:PATTERN`/`fs.write:PATTERN` identifiers with a Core-owned `bitty.fs.*` Lua bridge under a NEW root (never `bitty.terminal.*`), reconciled verbs read/write/list with no retained handles and no watch or tail-follow, scoped grants with no wildcard reusing the 4096/32/8KiB bounds, typed denials, and untrusted labeling with preview-equality; blocked consumers are file-manager, editor preview, and Wheel (illustrative only); safety constraints are that v1 stays frozen with no `fs` namespace, the read/write split is never bundled, and the surface stays v2-only; contract authority is draft RFC-0005; no implementation claim. Accepted 2026-10-05 for the filesystem dimension only ([RFC-0005](rfcs/RFC-0005-filesystem-host-surface.md), `status: accepted`, Issue #439): capability-gated plugin filesystem surface with reconciled verbs read/write/list under NEW `bitty.fs.*` root, scoped grants reusing 4096/32/8KiB bounds, typed oracle-tight denials, and untrusted labeling with preview-equality; Core host bridge, SDK spellings, and file-manager/editor-preview/Wheel parity remain Open v2 scope; no implementation claim. | +| OQ-068 | What is the `.wheel/` project-definition directory contract (layout, schema, Git-tracked versus runtime-state split, and trust), and how does `.agents/` compatibility resolve against it without becoming a competing source of truth? | [Lua and XDG](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/configuration/lua-and-xdg.md); [Configuration Model RFC](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/specifications/configuration-model-rfc.md) | Acceptance decision (ADR, RFC revision, or specification update) | Accepted (owner ruling 2026-09-23 adopting the packet recommendation): declarative-data-only Git-tracked `.wheel/` (`project.toml`, `agents/`, `workflows/`, `prompts/`, `policies/`, `tools/`, `skills/`) with discovery `.wheel/` then `.agents/`; Wheel rename confirmed; schema drafting is the open part; implementation: bitty#1096; no implementation claim | +| OQ-072 | What triggers plugin reload and update at runtime in v1 — which explicit surfaces (`bitty plugin reload`, IPC control, package-manager wake) and which automatic `local-path` development watcher contract (watch roots, canonicalization, debounce/coalescing, in-flight limits, failure handling) — and what happens to queued generation-N events at disposal? | [Plugin Host Runtime RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/runtime/plugin-host-runtime-rfc.md); [Plugin system](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/extensibility/plugin-system.md); [Package Lifecycle RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/packaging/package-lifecycle-rfc.md) | Acceptance decision (ADR, RFC revision, or specification update) | Open: candidate direction recorded in the Plugin Host Runtime RFC section "Candidate - reload/update triggers and queue drain (OQ-072)"; accepted reload mechanics stay authoritative (teardown N before N+1, FS-6 restore-or-disable, hash-bound grants and R-016 update diff, `DropOldest` v1 default); trigger surface, watcher contract, and generation-queue drain at disposal remain unspecified; no implementation claim | ## Presentation and automation diff --git a/docs/decisions/rfcs/README.md b/docs/decisions/rfcs/README.md index 15a12df..21cd0d8 100644 --- a/docs/decisions/rfcs/README.md +++ b/docs/decisions/rfcs/README.md @@ -17,6 +17,7 @@ sidebar_order: 40 | [Panel Animations and Effects RFC](RFC-0002-panel-animations.md) | Accepted | OQ-040 | | [AI Consent to Generic Scope Mapping RFC](RFC-0003-ai-consent-scope-mapping.md) | Draft | OQ-066 | | [History Read Surface RFC](RFC-0004-history-read-surface.md) | Accepted | OQ-056 | +| [Filesystem Host Surface RFC](RFC-0005-filesystem-host-surface.md) | Accepted | OQ-056 | Candidate mechanisms in the design corpus remain candidates until a scoped RFC is written and reviewed. Acceptance records a reviewed contract, not an diff --git a/docs/decisions/rfcs/RFC-0005-filesystem-host-surface.md b/docs/decisions/rfcs/RFC-0005-filesystem-host-surface.md new file mode 100644 index 0000000..c053be4 --- /dev/null +++ b/docs/decisions/rfcs/RFC-0005-filesystem-host-surface.md @@ -0,0 +1,544 @@ +--- +title: Filesystem Host Surface RFC +description: Accepted contract for a capability-gated plugin filesystem surface with scoped read and write grants explicit path patterns and Core-owned enforcement +category: decisions +audience: contributor +document_type: specification +status: accepted +website_publish: false +sidebar_order: 49 +--- + +# Filesystem Host Surface RFC + +> Status: **accepted** on 2026-10-05 (filesystem acceptance; +> [issue #439](https://github.com/bitty-terminal/bitty-docs/issues/439)). +> This document is the `bitty.fs` successor RFC: it gives the capability-gated +> plugin filesystem host surface a documented home. It is an accepted +> contract: it mints no capability identifier, authorizes no shipped behavior, +> and makes no compatibility promise. [OQ-056](../open-questions.md) +> stays open. Acceptance rests on explicit review plus the independent security +> review recorded under Acceptance evidence. Revised 2026-10-05 +> per the independent security review NEEDS-FIX (findings F-01..F-04); accepted +> 2026-10-05 after re-review APPROVE with the matrix plus `P0-AC-035` update +> merged (PR #442). + +## Problem + +Plugins have no file access to build on. The accepted contracts define ONLY +the capability identifiers `fs.read:PATTERN` and `fs.write:PATTERN` with +explicit path globs (Plugin Platform RFC identifier table; parameters +resolve against real paths with symlinks and devices rejected), and v1 has +NO Lua filesystem entry point: the accepted v1 Lua surface exposes no `fs` +namespace, the `bitty-lua` crate ships no `fs` seam module, and the draft +file-manager design states explicitly that there is no `bitty.fs`, removing +its former root-scoped `fs.read`/`fs.write` requests as phantom authority +until a surface exists. + +Core owns grammar plus authorization but no bridge: `capability.rs` parses +and parameter-requires the `fs.read`/`fs.write` identifiers with no wildcard +head, `manifest.rs` bounds the grant shape (32 patterns per kind, 8 KiB +total pattern text, hostile-pattern rejection), and `fs_authz.rs` bounds the +request path (4096-byte path ceiling, sensitive-path policy, secret-shaped +content detection, typed allow/deny/consent outcomes) — yet no `bitty-lua` +filesystem bridge maps these grants to callable Lua functions. + +The only function sketch in the corpus is draft illustrative direction: the +panel-history candidate names capability-sandboxed `bitty.fs.open/append/ +read/list` mapped by the host under the plugin state directory, with upward +traversal denied. That sketch conflicts with the accepted capability split: +`open` names no read/write mode, `append` duplicates the write grant as a +separate verb, and `list` has no grant home at all. Three consumer kinds +wait on a reconciled contract: + +- **File-manager plugins** that list, navigate, and preview files under a + root-parameterized, fail-closed scope (draft policy-only design; + observation-only today, direct filesystem I/O an explicit non-goal until + the surface lands); +- **Editor preview paths** that need bounded reads of file content for + preview selection without taking on write authority; +- **Wheel project-data consumers**, illustratively only: the `.wheel/` + contract is declarative-data-only with no hard file-operation requirement, + so Wheel names a future mediated-read consumer, never a direct-access one. + +The chain is blocked at the first link: there is no reviewable contract for +what a plugin may read, write, or list, under which grant, with which +verbs, which bounds, and which secrecy treatment. + +## Goals + +- Give the filesystem host surface a documented home in shared governance + (`bitty-docs`), naming the capability family, the grant shape, the + reconciled verb set, the bound shape, and the secrecy treatment. +- Reuse the accepted `fs.read`/`fs.write` capability split as the single + authority: reconcile the draft `open/append/read/list` sketch against it + with a decided verb set and recorded rationale, instead of carrying two + conflicting verb vocabularies. +- Keep the surface under a NEW Lua root, never under `bitty.terminal.*`, + and keep v1 frozen: no v1 member is widened, aliased, or shadowed. +- Reuse the accepted Core bounds (4096-byte path ceiling, 32 patterns per + kind, 8 KiB total pattern text) with no new numeric ceiling invented here; + every value that stays parked names its owner. +- Name the blocked consumers and the unblocking chain explicitly, so the + Core host bridge, the SDK spellings, and consumer parity each have a named + predecessor instead of an implied one. +- Define the acceptance path: what review, evidence, and adoption must exist + before this draft becomes an accepted contract (RFC-0004 pattern: draft, + then security review, then acceptance). + +## Non-goals + +- No capability identifier is minted by this document; adding an identifier + requires acceptance of this RFC plus the Core host integration that + enforces it (identifiers are capability-registry stable). +- No `terminal.*` member is widened, reinterpreted, or given a filesystem + sub-scope here; the v1 surface stays frozen. +- No exact Lua function signatures, argument orders, or return shapes are + fixed here; spellings belong to the SDK work that follows acceptance, and + the Core bridge owns the enforcement behind them. +- No live watch, subscription, tail-follow, retained file handle, or + cross-call cursor semantic is granted; every operation is a bounded, + self-contained request over current state. +- No ambient file access is granted: there is no read of the whole home + directory, no traversal above a grant root, no symlink or device escape, + and no private first-party bypass. +- No open question is closed; [OQ-056](../open-questions.md) stays open. +- No shipped, stable, normative, or compatibility-guaranteed behavior is + claimed for any grant, verb, denial, or bound shape. + +## Normative sources this proposal must not weaken + +This proposal must be read together with, and must not weaken: + +- The [security overview](../../security/overview.md), + the [threat model](../../security/threat-model.md), + the [risk register](../../security/risk-register.md), + and the [P0 acceptance criteria](../../security/p0-acceptance-criteria.md). + The controls that bind this surface include plugin capability checking with + least privilege (`P0-AC-012`), per-plugin VM isolation and failure + containment (`P0-AC-013`), resource budgets with attribution (`P0-AC-014`), + hot-path exclusion (`P0-AC-015`), read-only default with untrusted labeling + (`P0-AC-024`), trace minimization and redaction with user-only files + (`P0-AC-026`), capability-increase update blocking (`P0-AC-030`), trust-level + admission before grant intersection (`P0-AC-035`), the secret-storage tiers + (`P0-AC-036`), and argv-first external invocation with no shell-string + construction (`P0-AC-009`). +- The accepted + [Plugin Platform RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/specifications/plugin-platform-rfc.md): + the `fs.read:PATTERN`/`fs.write:PATTERN` identifier rows, the deny-by-default + rule with no family-wide wildcard, the real-path/symlink/device restriction, + and the read/write separation (reads stay out of the destructive warning + set while `fs.write:PATTERN` is included). +- The accepted + [Plugin API v1 Lua Surface RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/sdk/plugin-api-v1-lua-surface-rfc.md) + and [ADR 0009](../adrs/ADR-0009-plugin-api-v1-lua-surface.md): + v1 is frozen; this surface is v2-only. +- The Core capability grammar and authorization in `bitty` + (`crates/bitty-plugin-host/src/capability.rs`, `manifest.rs`, + `fs_authz.rs`): parameter-required `fs.read`/`fs.write` identifiers, the + 32-patterns-per-kind and 8 KiB-pattern-text grant bounds, hostile-pattern + rejection, the 4096-byte path ceiling, the sensitive-path default-deny set + with an explicit consent path, and the typed allow/deny/consent outcomes. + This RFC reuses these bounds and rules; it redefines none of them. +- The draft + [file-manager design](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/docs/plugins/file-manager/design.md) + (policy-only): observation-only listing, navigation, and preview over a + caller-supplied root with an 8 KiB listing payload precedent, no direct + filesystem I/O, and phantom-authority removal until the surface exists. +- The draft + [panel-history candidate](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/specifications/panel-history-candidate.md): + the illustrative `bitty.fs.open/append/read/list` sketch this RFC + reconciles, and the secret-minimizing storage direction its results must + compose with. +- [ADR 0012](../adrs/ADR-0012-phodopus-runtime.md): the `bitty-lua` Host ABI + (`bitty.ui`, `bitty.panel`, `bitty.fs`, `bitty.command`) sits strictly on + top of the generic runtime as an ordinary consumer; the future `bitty.fs` + bridge is Core-owned host work, never runtime work. +- The [Core boundaries](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/architecture/core-boundaries.md) + capability rule: plugins never receive the filesystem directly; they + request filesystem read and write constrained by explicit path patterns + through host services. +- The [History Read Surface RFC](RFC-0004-history-read-surface.md) + (accepted): the precedent for a NEW capability family with explicit + per-plugin grants, typed oracle-tight denials, Core-attached + untrusted-observation labels, export-preview equality, the read-into-VM-only + grant-combination rule, and no streaming or subscription semantics. This + RFC adopts the same shape for files. +- The accepted + [IPC and Agent RFC](https://github.com/bitty-terminal/bitty-ai-docs/blob/main/specifications/ipc-agent-rfc.md): + returned content is observation data, never instructions. File bytes + returned by any operation in this family carry the same treatment. + +Where a control or threshold appears to need change, it is recorded under +"Unresolved questions" instead. + +## Terminology + +- **Core**: the always-available terminal mechanism that works with zero + plugins and in `bitty --safe`; it owns the capability gate, the + filesystem authorization layer, and resource budgets, and it will own the + future `bitty-lua` filesystem bridge. +- **Scoped grant**: a per-plugin capability grant naming explicit path + patterns with no wildcard default; absence of a grant, or an operation + outside the grant scope, denies fail-closed. +- **Read/write split**: the accepted separation of `fs.read` authority from + `fs.write` authority; a grant in one never implies the other. +- **Bounded request**: a single self-contained filesystem operation carrying + explicit path and size caps, enforced by Core before any bytes move. It + holds no handle or cursor across calls. +- **Typed denial**: a catchable, machine-readable denial naming its reason + from the complete taxonomy without leaking out-of-scope identifiers, + content bytes, or retention-existence signals. +- **Candidate**: a proposal that is not decided; candidate status is not + acceptance and is not implementation. + +## Proposed contract + +The family is the accepted `fs` capability family with a Core-owned Lua +bridge beside `terminal.*`, owned by Core enforcement with SDK spellings. +Its invariant, in one sentence: **a granted plugin may perform bounded, +self-contained reads, writes, and listings strictly inside its explicit path +patterns and receive labeled results or a typed denial; it may never hold a +handle, cross a scope, stream a file, or move bytes beyond the VM without a +separately granted authority.** + +### Capability family + +- The family is the accepted `fs` family: `fs.read:PATTERN` and + `fs.write:PATTERN` remain the only identifiers, with the parameter + required and no family-wide wildcard. This RFC mints no identifier and + changes no grammar. +- Every member is deny-by-default: without an explicit per-plugin grant + recorded by the Core gate, every operation denies fail-closed with a typed + denial. Grants never bundle modes: a read grant never implies a write + grant, and a write grant never implies read-back. +- The Lua namespace lives under a NEW root, never under `bitty.terminal.*`: + the proposed root is `bitty.fs.*`, the Host ABI slot ADR-0012 already + names for the future bridge. No `terminal.*` spelling touches the + filesystem, and no `bitty.fs.*` spelling touches terminal state. +- The family maps to the OQ-085 `filesystem` capability domain. A grant in + this family never implies process, network, clipboard, IPC, terminal + input/output, or any other domain authority. No grant migration in either + direction: a `terminal.*` grant never implies a grant in this family, and + a grant in this family never implies a `terminal.*` grant. +- A plugin update that newly requests this family is a capability increase + and blocks pending the explicit permission-diff approval gate + (`P0-AC-030`). + +### Verb reconciliation + +The draft sketch (`open/append/read/list`) is reconciled against the +accepted read/write split as follows; the decided verb set is +**read, write, list**: + +- **`read`** (read-class): bounded reads of file bytes under the read grant. + Directly authorized by `fs.read:PATTERN`. +- **`write`** (write-class): bounded writes of file bytes under the write + grant, with the disposition (create, overwrite, append-mode) a write-flag + candidate, not a verb. Directly authorized by `fs.write:PATTERN`. +- **`list`** (read-class): bounded directory listings (names plus file-kind + metadata, never file bytes) authorized by the read grant scoped to the + listed prefix. Listing reads the namespace, so it needs read authority; + it must never become a read-grant-free enumeration oracle. + +Rationale for retiring the sketch verbs: + +- **`open` is rejected as a verb.** A handle-returning `open` implies a + retained descriptor held across calls, which conflicts with the bounded, + self-contained request invariant, with per-plugin generation fencing, and + with the no-streaming rule (a held handle is a subscription by another + name). Whatever the sketch meant by `open` is covered by `read` (for + read-handles) or `write` (for write-handles) without retaining state. +- **`append` is rejected as a verb and parked as a write disposition.** + Splitting the write grant into overwrite versus append verbs would divide + one accepted identifier into two unenforced halves. Whether the write + grant subdivides by disposition stays an unresolved question owned by the + Core bridge and SDK work; the default proposed here is a single `write` + verb with append-mode as a flag candidate. +- **`list` is kept and given a grant home.** The sketch named `list` with + no capability backing; this RFC backs it with the read grant over the + listed prefix and bounds it like every other operation. + +Exact function signatures, argument orders, and return shapes stay parked to +the SDK work; this RFC fixes the verb set and the grant mapping only. + +### Grants, scopes, and bounds + +- Every grant carries explicit path patterns. There is no wildcard or `all` + default; an unscoped grant request denies. Patterns resolve against real + paths; symlinks and devices are rejected per the accepted restriction. +- An operation carries its own path and is authorized only when the path + intersects the grant scope; otherwise Core denies with a typed + scope-mismatch denial. Upward traversal above a grant root denies; the + sensitive-path default-deny set (credential locations, `.env` variants, + token stores) denies or routes to the explicit consent path per the + accepted `fs_authz` policy. +- Numeric ceilings reuse the accepted Core bounds: 4096 bytes maximum path, + 32 patterns per kind, 8 KiB total pattern text. The per-line content-scan + bound (4096 + 128 bytes) and the bounded audit and consent tables are + reused where the bridge routes through the same authorization layer. No + new numeric ceiling is invented here; per-call read/write payload caps + and listing entry caps stay parked to the Core bridge and SDK work (the + file-manager draft's 8 KiB listing payload is precedent, not norm). +- Core enforces a per-plugin operation rate and an aggregate byte budget, + attributed per plugin (`P0-AC-014`); polling that would reconstitute a + watch or a tail-follow denies with a typed over-rate or over-budget + denial. Exact rates and quotas stay parked with the other ceilings (no new + ceiling invented here). +- Operations carry no freshness or durability promise beyond what the Core + bridge documents: every call is a point-in-time request over current + state, and durability semantics (atomic replacement, sync) belong to the + Core implementation task, not to this contract. + +### Secrecy treatment + +- Secret-minimizing from the start: reads that encounter secret-shaped + content are treated fail-closed per the accepted content-detection + heuristics, and sensitive paths stay default-deny with an explicit + consent path; consent is keyed by path, never a value, and no file value + enters audit records, traces, or denial shapes. +- Redaction composes with ADR 0006 and the security corpus from the start: + the preview-equality analog holds (what a preview shows is what an export + or a write carries — a redacted preview must never launder into an + unredacted write), and the exact redaction format stays parked with the + accepted storage and history policy owners. +- Every returned record carries a Core-attached, typed untrusted-observation + label that survives redaction, truncation, and attribution: a plugin, agent, or tool + that consumes file bytes must treat them as content under the + prompt-injection rule, and the host forbids executing, interpolating, or + routing labeled content into an instruction channel without a separately + granted authority outside this family (exercises `P0-AC-024`). +- Grant-combination rule: reading or listing under this family authorizes + delivery of results into the plugin VM only. Copying to the clipboard, + spawning processes over file content, publishing to IPC, or egressing + over the network each needs its own separately granted authority; the + family grant never implies them. Process invocation over file content stays + argv-first with validated arguments and no shell-string construction or + interpolation (`P0-AC-009`). Writing file content obtained under a + read grant to a separately granted write scope is permitted only when + both grants are present; the read grant alone never authorizes the write. + +### Typed denials + +Denials are typed and catchable, and they fail closed. The complete +required taxonomy is: missing grant; revoked or expired grant; scope +mismatch (including upward traversal and cross-root operations outside the +grant scope); hostile pattern; sensitive-path denial or consent-required; +secret-shaped content refusal; over-bound path, payload, or listing request; +over-rate or over-budget request; safe-mode denial; and unknown trust level +or domain. Denials are oracle-tight: their shape must not vary with +out-of-scope facts, so no denial carries content bytes, foreign +identifiers, or any signal distinguishing absent files from denied files; +where `P0-AC-035` applies, the denial names the level and the family only. +Listings suppress denied entries silently (silent skip) as the default; any +alternative shape stays an unresolved question for the security review only +if it preserves the no absent-vs-denied signal rule above, with disposition +required before acceptance (suppression leaks less; marking is more +debuggable but must not leak existence). Exact error identifiers and wire shapes +belong to the SDK work; this RFC fixes the taxonomy and the no-leak rule. + +### No streaming or watch analog + +- Every operation is a bounded, self-contained request: no watch, no + subscription, no tail-follow, no retained handle, no cursor held across + calls. A caller that wants newer state issues a new bounded request under + its grant. +- No freshness guarantee and no change notification exist in this family; + polling that reconstitutes a live view is bounded by the per-plugin rate + and aggregate budget above. + +## Alternatives considered + +- **Adopt the sketch verbs verbatim (`open/append/read/list`).** + Rejected: `open` implies retained cross-call handles against the bounded + invariant and generation fencing; `append` splits the accepted write + identifier into unenforced halves; `list` would float without a grant + home. The reconciliation above keeps the sketch's coverage with none of + its conflicts. +- **Widen `terminal.*` with filesystem members.** + Rejected: terminal state and filesystem authority are distinct OQ-085 + domains, and the terminal family is accepted as a closed set. A widened + member would inherit `terminal.*` grant expectations never reviewed for + persistent, secret-bearing file content. +- **Grant directory-scoped ambient access (whole home or project tree by + default).** Rejected: it replaces explicit patterns with an implicit root, + defeats least privilege, and contradicts the deny-by-default posture the + file-manager draft already applies to itself. +- **Route file access through per-plugin KV or the settings store as a + general sink.** Rejected: it bypasses the path-pattern capability model, + the scope rules, and the secrecy treatment, the same shim the storage and + history policies forbid. +- **Leave reads and writes to direct host-filesystem access by trusted + first-party plugins.** Rejected: there is no private first-party bypass; + the official file manager uses the same public, capability-gated bridge + as any third-party plugin. +- **Give Wheel direct file operations for project data.** Rejected as a + requirement: the `.wheel/` contract is declarative-data-only with no hard + file-operation requirement, so Wheel stays an illustrative mediated-read + consumer. Direct Wheel file operations would need their own RFC if the + contract ever requires them. + +## Security and compatibility impact + +- Threat-model touchpoints: untrusted file bytes crossing into + plugin-readable state (prompt-injection labeling required above); + persisted-secret exposure through reads and listings (default-deny + sensitive paths, secret-shaped refusal, preview-equality); + scope escape across roots, homes, symlinks, or devices (explicit patterns + plus hostile-pattern rejection plus typed denials); handle retention used + as subscription (no `open` verb, no cross-call state); polling + reconstituted as watch (per-plugin rate plus aggregate budget); + grant-confusion between read and write (no bundled grants, no implied + read-back) and beyond the VM (separate authorities for + copy/spawn/publish/egress); trust-level admission for the `fs` family + (level x family cells under `P0-AC-035`); and denial oracles (oracle-tight + no-leak rule, listing silent-suppression default with no-signal constraint, + disposition before acceptance). +- P0 gates exercised: `P0-AC-012` (every operation capability-checked), + `P0-AC-013` (operation faults contained to the calling plugin VM), + `P0-AC-014` (paths, payloads, listings, rates, and aggregate budgets with + per-plugin attribution), `P0-AC-015` (no plugin callback on the input, + parse, or render hot path; operations run against the host filesystem + boundary, never inline), `P0-AC-024` (Core-attached untrusted labeling on + every result; read into the VM only with no automatic combination), + `P0-AC-026` (minimization, redaction, user-only files, preview-equality), + `P0-AC-030` (new-family requests block updates pending diff approval), + `P0-AC-035` (trust-level admission for the `fs` family under the + `filesystem` domain before grant intersection), `P0-AC-036` + (secret-storage tiers respected), and `P0-AC-009` (argv-first external + invocation over file content, no shell-string construction). +- Compatibility: v2-only. The v1 Lua surface is frozen; no v1 member is + altered, aliased, or shadowed by this family, and no `bitty.fs.*` spelling + exists in v1 to collide with. Any future identifier in this family is + capability-registry stable from its acceptance, so the acceptance review + must treat identifier choice as a compatibility decision, not as a + spelling detail. + +## Rollout and adoption + +1. Review this draft in `bitty-docs` (this task's PR; no merge claims beyond + draft status; no `Closes` until accepted). +2. Independent security review of the draft before acceptance: the reviewer + confirms the family shape preserves the accepted `fs` identifier split, + the closed `terminal` family, the v1 freeze, the new-root rule, every P0 + gate above, the verb reconciliation, and the prompt-injection labeling + rule, and dispositions the unresolved questions. +3. On acceptance, the Core host bridge lands the enforcement (grant gate, + bound enforcement, redaction and labeling, typed denials) under its own + task with host parity tests. +4. SDK work mints the accepted `bitty.fs.*` spellings with the mock host and + conformance suite against the accepted contract. +5. File-manager, editor-preview, and Wheel consumers build to parity on the + SDK surface. +6. Only after host parity evidence exists does any follow-up flip this RFC + toward acceptance-amendment or a successor revision; acceptance itself + still authorizes no implementation beyond the reviewed contract. + +## Unresolved questions + +- What are the exact Lua function signatures, argument orders, and return + shapes for `read`, `write`, and `list` (parked to the SDK work under the + capability model)? +- What are the exact default per-call payload caps, listing entry caps, + operation rates, and aggregate byte budgets, and how do they compose with + the accepted 4096/32/8KiB ceilings (parked to the Core bridge and SDK + work; no new ceiling invented here)? +- Does the write grant subdivide by disposition (create versus overwrite + versus append-mode flag), or stay a single disposition (parked to the Core + bridge and SDK work; default proposed is a single verb with a flag + candidate)? +- Do listings keep the silent-suppression default or adopt an alternative + denied-entry shape (parked to the security review; whichever shape is + chosen must preserve the no absent-vs-denied signal rule, with disposition + required before acceptance; suppression leaks less, marking is more + debuggable but must not leak existence)? Disposition (accepted + 2026-10-05): silent-suppression default APPROVED (PX-0933); any + alternative shape stays parked to the security review only if it preserves + the no absent-vs-denied signal rule. +- What is the exact redaction format and label encoding in read and listing + results, and how are preview-equality and label preservation tested + (parked with the accepted storage and history policy owners)? +- Which threat-model matrix cells (every level x `fs`-family admission cell) + and which `P0-AC-035` update cover this family? Disposition (accepted + 2026-10-05): satisfied by PR #442 (merged as commit + `856f34d51f1fa45ef14b2caf7009f0c8b2d83e65`) — the filesystem family + admission subsection under the `filesystem` domain with every L0-L4 x + family admission cell plus the `P0-AC-035`/`P0-AC-030`/`P0-AC-024`/`P0-AC-013` + filesystem scope notes; exact identifiers stay parked to the Core bridge + and SDK work. +- Does the `.wheel/` contract ever require direct file operations, or does + mediated host read stay sufficient (owned by the Wheel contract work; this + RFC assumes the latter and grants nothing to Wheel)? + +## Acceptance evidence + +This RFC flips from draft to accepted when all of the following are linked +here: independent reviewer APPROVE on the family shape, the verb +reconciliation, the grant/scope/bound rules, the rate and budget rules, and +the denial taxonomy; independent security-reviewer sign-off covering the +threat-model touchpoints, the P0 gates (`P0-AC-035`, `P0-AC-030`, +`P0-AC-024`, and `P0-AC-013` named in scope), the closed-terminal-family and +new-root guarantees, the grant-combination rule, and the prompt-injection +labeling rule; threat-model matrix plus `P0-AC-035` update covering the +`fs` family under the `filesystem` domain, with every level x family +admission cell evidenced; docs-curator APPROVE on taxonomy, links, and +register synchronization; and a disposition (accepted shape or parked owner) +for each unresolved question. Acceptance still authorizes no +implementation: it records the reviewed contract, not shipped behavior. +Host parity tests belong to the Core implementation task that follows +acceptance, and must not be claimed as evidence inside this RFC. + +Accepted 2026-10-05 (filesystem acceptance, +[issue #439](https://github.com/bitty-terminal/bitty-docs/issues/439)): +independent security review APPROVE after the NEEDS-FIX revision (findings +F-01..F-04 resolved in `0b0bab1`; provenance CarryCtx note PX-0933 on +CTX-0280); independent acceptance review NOT-YET with curator gap now +satisfied (provenance CarryCtx note PX-0936 on CTX-0280, conditional on +curator); docs-curator APPROVE filling the PX-0936 gap (provenance CarryCtx +note PX-0937 on CTX-0280); threat-model matrix plus `P0-AC-035` update +covering the `fs` family under the `filesystem` domain with every L0-L4 x +family admission cell evidenced, merged as +[PR #442](https://github.com/bitty-terminal/bitty-docs/pull/442) (commit +`856f34d51f1fa45ef14b2caf7009f0c8b2d83e65`). Per-UQ dispositions: Lua +signatures parked to SDK work; payload/rate/budget caps parked to Core bridge +and SDK work; write-disposition flag parked to Core bridge and SDK work; +listing silent-suppression default APPROVED (see disposition above); +redaction/label encoding parked with storage and history policy owners; +matrix cells satisfied by the #442 merge (see disposition above); Wheel +mediated-read assumption parked to Wheel contract work. + +## References + +- [Plugin Platform RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/specifications/plugin-platform-rfc.md) + (accepted): the `fs.read:PATTERN`/`fs.write:PATTERN` identifier rows, the + deny-by-default rule, and the real-path/symlink/device restriction this + family inherits. +- [Plugin API v1 Lua Surface RFC](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/sdk/plugin-api-v1-lua-surface-rfc.md) + (accepted): the frozen v1 surface with no `fs` namespace this RFC stays + outside of. +- [File-manager design](https://github.com/bitty-terminal/bitty-plugins-docs/blob/main/docs/plugins/file-manager/design.md) + (draft, policy-only): the observation-only listing, navigation, and preview + policy, the caller-supplied-root scope, and the 8 KiB listing-payload + precedent this RFC unblocks. +- [Panel history candidate](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/specifications/panel-history-candidate.md) + (draft candidate): the illustrative `bitty.fs.open/append/read/list` + sketch reconciled here. +- [Core boundaries](https://github.com/bitty-terminal/bitty-terminal-docs/blob/main/architecture/core-boundaries.md) + (accepted): plugins never receive the filesystem directly; filesystem read + and write constrained by explicit path patterns through host services. +- [ADR 0012](../adrs/ADR-0012-phodopus-runtime.md) (accepted): the `bitty.fs` + Host ABI slot and the Core-owns-the-bridge boundary this RFC builds on. +- [History Read Surface RFC](RFC-0004-history-read-surface.md) + (accepted): the draft-to-acceptance pattern (draft, security review, + acceptance), the NEW-family shape, typed oracle-tight denials, + untrusted-observation labels, preview-equality, and the read-into-VM-only + rule this RFC adopts for files. +- [Threat model](../../security/threat-model.md) trust levels and + capability-domain admission (OQ-085) and [P0 acceptance + criteria](../../security/p0-acceptance-criteria.md) (`P0-AC-035`, + `P0-AC-030`, `P0-AC-024`, `P0-AC-013`): the admission matrix and gates + this family must update and exercise before acceptance. +- [OQ-056](../open-questions.md) (stays open): the v2-scope register this + draft targets; amended (Issue #439) to name this surface. +- [Issue #439](https://github.com/bitty-terminal/bitty-docs/issues/439) + (this RFC's task issue).