From 9a95e484944e59eb616db20e6592aa2189e42f6c Mon Sep 17 00:00:00 2001 From: Xuepoo Foter <144407384+Xuepoo@users.noreply.github.com> Date: Mon, 5 Oct 2026 23:47:19 +0800 Subject: [PATCH 1/3] [CTX-0279] docs(decisions): draft RFC-0005 filesystem host-surface (Issue #439) --- docs/decisions/index.md | 1 + docs/decisions/open-questions.md | 40 +- docs/decisions/rfcs/README.md | 1 + .../rfcs/RFC-0005-filesystem-host-surface.md | 505 ++++++++++++++++++ 4 files changed, 527 insertions(+), 20 deletions(-) create mode 100644 docs/decisions/rfcs/RFC-0005-filesystem-host-surface.md diff --git a/docs/decisions/index.md b/docs/decisions/index.md index b01ac7f..b55c8a5 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. (Draft: [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 `draft` 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..fdbf474 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. | +| 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..18a7b7e 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) | Draft | 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..476015d --- /dev/null +++ b/docs/decisions/rfcs/RFC-0005-filesystem-host-surface.md @@ -0,0 +1,505 @@ +--- +title: Filesystem Host Surface RFC +description: Draft 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: draft +website_publish: false +sidebar_order: 49 +--- + +# Filesystem Host Surface RFC + +> Status: **draft** (targets [OQ-056](../open-questions.md), which stays open; +> [issue #439](https://github.com/bitty-terminal/bitty-docs/issues/439)). +> This document is a proposal for the plugin filesystem host surface (the +> `bitty.fs` successor). It is not an accepted contract: it mints no +> capability identifier, authorizes no shipped behavior, and makes no +> compatibility promise. It must not merge beyond draft status until an +> independent security review plus acceptance are recorded under Acceptance +> evidence. + +## 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, or any other + domain authority. +- 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 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. 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. +Whether listings suppress denied entries silently or mark them as denied +stays an unresolved question for the security review (suppression leaks +less; marking is more debuggable). 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-suppression question parked to review). +- 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 suppress denied entries silently or mark them as denied + (parked to the security review; suppression leaks less, marking is more + debuggable)? +- 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 (owned by the security + review and the matrix update that must precede acceptance)? +- 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. + +## 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). From 0b0bab1ad18d1e4ad6f06648419c257bfa0a3bdd Mon Sep 17 00:00:00 2001 From: Xuepoo Foter <144407384+Xuepoo@users.noreply.github.com> Date: Tue, 6 Oct 2026 02:50:22 +0800 Subject: [PATCH 2/3] [CTX-0279] [CTX-0280] docs(rfc-0005): apply security-review F-01..F-04 wording fixes --- .../rfcs/RFC-0005-filesystem-host-surface.md | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/docs/decisions/rfcs/RFC-0005-filesystem-host-surface.md b/docs/decisions/rfcs/RFC-0005-filesystem-host-surface.md index 476015d..f49bc77 100644 --- a/docs/decisions/rfcs/RFC-0005-filesystem-host-surface.md +++ b/docs/decisions/rfcs/RFC-0005-filesystem-host-surface.md @@ -214,8 +214,10 @@ separately granted authority.** 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, or any other - domain authority. + 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`). @@ -298,7 +300,7 @@ the SDK work; this RFC fixes the verb set and the grant mapping only. 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 truncation and attribution: a plugin, agent, or tool + 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 @@ -307,7 +309,9 @@ the SDK work; this RFC fixes the verb set and the grant mapping only. 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. Writing file content obtained under a + 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. @@ -323,9 +327,11 @@ 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. -Whether listings suppress denied entries silently or mark them as denied -stays an unresolved question for the security review (suppression leaks -less; marking is more debuggable). Exact error identifiers and wire shapes +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 @@ -383,7 +389,8 @@ belong to the SDK work; this RFC fixes the taxonomy and the no-leak rule. 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-suppression question parked to review). + 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 @@ -437,9 +444,11 @@ belong to the SDK work; this RFC fixes the taxonomy and the no-leak rule. 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 suppress denied entries silently or mark them as denied - (parked to the security review; suppression leaks less, marking is more - debuggable)? +- 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)? - 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)? From 5dc321a1f2a8c07e0e410ff50eced462a08abbbd Mon Sep 17 00:00:00 2001 From: Xuepoo Foter <144407384+Xuepoo@users.noreply.github.com> Date: Tue, 6 Oct 2026 03:38:33 +0800 Subject: [PATCH 3/3] [CTX-0281] [CTX-0280] docs(decisions): flip RFC-0005 draft to accepted (filesystem acceptance) --- docs/decisions/index.md | 2 +- docs/decisions/open-questions.md | 40 +++++++------- docs/decisions/rfcs/README.md | 2 +- .../rfcs/RFC-0005-filesystem-host-surface.md | 54 ++++++++++++++----- 4 files changed, 64 insertions(+), 34 deletions(-) diff --git a/docs/decisions/index.md b/docs/decisions/index.md index b55c8a5..0bd85ca 100644 --- a/docs/decisions/index.md +++ b/docs/decisions/index.md @@ -322,7 +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. (Draft: [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 `draft` on 2026-10-05; Issue #439.) +- 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 fdbf474..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. 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. | -| 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 18a7b7e..21cd0d8 100644 --- a/docs/decisions/rfcs/README.md +++ b/docs/decisions/rfcs/README.md @@ -17,7 +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) | Draft | 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 index f49bc77..c053be4 100644 --- a/docs/decisions/rfcs/RFC-0005-filesystem-host-surface.md +++ b/docs/decisions/rfcs/RFC-0005-filesystem-host-surface.md @@ -1,24 +1,27 @@ --- title: Filesystem Host Surface RFC -description: Draft contract for a capability-gated plugin filesystem surface with scoped read and write grants explicit path patterns and Core-owned enforcement +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: draft +status: accepted website_publish: false sidebar_order: 49 --- # Filesystem Host Surface RFC -> Status: **draft** (targets [OQ-056](../open-questions.md), which stays open; +> Status: **accepted** on 2026-10-05 (filesystem acceptance; > [issue #439](https://github.com/bitty-terminal/bitty-docs/issues/439)). -> This document is a proposal for the plugin filesystem host surface (the -> `bitty.fs` successor). It is not an accepted contract: it mints no -> capability identifier, authorizes no shipped behavior, and makes no -> compatibility promise. It must not merge beyond draft status until an -> independent security review plus acceptance are recorded under Acceptance -> evidence. +> 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 @@ -448,13 +451,21 @@ belong to the SDK work; this RFC fixes the taxonomy and the no-leak rule. 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)? + 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 (owned by the security - review and the matrix update that must precede acceptance)? + 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)? @@ -477,6 +488,25 @@ 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)