alma 0.1.1

A Bevy-native modal text editor with Vim-style navigation.
Documentation
# Alma Active Roadmap

Completed roadmap history lives in `archive/todos.md`. Keep this file focused
on active work, open design gaps, and the next slice of implementation.

## Plugin Runtime

- [x] Build the first visible proposal lane.
  - Scope: a plugin observes a buffer snapshot, proposes a
    `buffer.propose_edit` change against a base revision, and Alma shows the
    proposal before mutation.
  - Current state: a real component fixture observes a host-issued buffer
    snapshot, proposes a revision-guarded edit, reaches `PluginIntentQueue`,
    enters a typed proposal lane, and mutates only through the buffer owner.
    The default proposal policy still auto-applies for compatibility. Manual
    review mode stores pending proposals until an explicit apply or reject
    request. Proposal lane saturation emits a redacted operational diagnostic. A
    first chrome summary renders pending proposals with proposer identity,
    capability, target shape, base revision, redacted edit shape, and a
    redacted one-hunk diff preview. Chrome apply/reject controls emit the
    existing typed proposal request messages. A bounded in-session receipt log
    now records proposal id, proposer, capability, target, base revision,
    redacted edit shape, and apply, reject, owner-accept, or owner-reject
    outcome. Chrome now renders pending status and latest receipt outcome status
    without exposing proposed text or raw ECS ids.
  - UI: proposal status renders in the proposal lane.
  - Owner path: apply routes through the buffer owner, stale proposals are
    rejected at the owner boundary, and rejection never mutates text.
  - Receipt: receipt status renders in chrome from the bounded receipt log.

- [x] Add runtime abuse tests around resource limits and message bounds.
  - Existing key types: `PluginRuntimeLimits`, `PluginRuntimeSpec`,
    `PluginHostImportSession`, `PluginHandleStore`, `WitCapability`.
  - Current state: real Wasm component fixtures cover Wasmtime fuel exhaustion,
    wall-clock timeout, malformed generated handle payloads, invalid UTF-8 guest
    strings, oversized host-call payloads, and stale handles after discardable
    effects have been queued. Generated `workspace.artifact_write` fixture
    coverage proves invalid workspace paths discard queued workspace I/O before
    filesystem policy execution.
  - Remaining fixture: none for exposed host imports.
  - Acceptance: every failed guest update discards pending effects and pending
    workspace I/O before ECS publication or filesystem policy execution.

- [ ] Add guest-driven scheduling integration tests around `PluginIntent`.
  - Existing key types: `EditorSet::PluginIntent`, `PluginInstanceState`,
    `PluginHostImportSession`, `PluginIntentQueue`,
    `RevisionGuardedBufferEditRequested`, `StatusMessageRequested`.
  - Current state: ECS integration tests cover accepted publication into owner
    systems, missing targets, stale revisions, FIFO queue drain, queue
    saturation, runtime-denied capability before publication, stale handle
    rejection before effect creation, generated `status.publish` and
    `buffer.propose_edit` host import adapters queuing only through the active
    update session, and a real Wasm component fixture publishing status through
    runtime update. A real `buffer.propose_edit` component fixture now publishes
    through `PluginIntentQueue`, reaches the buffer owner, and preserves
    deterministic FIFO ordering across runtime-produced batches from multiple
    plugins. Wasmtime update setup now consumes one active-update proof that
    captures host import authority and update handles after lifecycle gating, so
    missing handles fail before guest execution or session creation.
  - Remaining fixtures: none before `buffer.observe`; scheduling/subscription
    fixtures resume once observation events exist.
  - Acceptance: rejected guest work produces no authoritative mutation, and
    accepted work still reaches only existing owner systems.

- [x] Make `PluginIntentQueue` capacity configurable from validated runtime
  configuration.
  - Current state: `PluginRuntimeLimits` validates `max_intent_batches`, and
    the ECS queue derives its cap from validated enabled-plugin runtime proofs.
  - Acceptance: invalid zero queue limits fail during config validation, and
    the ECS resource is initialized from a validated proof type.

- [x] Add a first Wasmtime adapter boundary behind `plugin-runtime`.
  - Existing key types: `PluginRuntimeSpec`, `PluginInstanceState`,
    `PluginHostContext`, `PluginHostImportSession`, generated bindings in
    `plugin::bindings`.
  - Current state: component validation, lifecycle calls, resource limits,
    timeout handling, discard evidence, generated `status.publish`,
    `buffer.observe`, `buffer.propose_edit`, and `workspace.artifact_write`
    host import adapters, and real component fixtures for accepted and denied
    status publication, buffer observation, buffer edit proposals, and
    workspace artifact writes exist.
  - Remaining scope: none for the first adapter boundary. Next runtime work is
    abuse-test coverage and then the first useful observe-plus-propose plugin.
  - Acceptance: generated WIT types remain private, all guest strings and
    handles are decoded with `TryFrom`-style failures, and traps/timeouts or
    import rejections discard pending work.

- [x] Split plugin docs once the runtime adapter lands.
  - Current state: `docs/plugins/runtime.md`, `docs/plugins/security.md`, and
    `docs/plugins/testing.md` now hold the detailed plugin runtime records.
  - Target files: `docs/plugins/runtime.md`, `docs/plugins/security.md`, and
    `docs/plugins/testing.md`.
  - Acceptance: the top-level architecture stays short, while plugin security
    invariants, runtime dataflow, and test obligations remain auditable.

- [x] Audit checked-in plugin goldens.
  - Current state: `tests/goldens/plugin` contains the checked-in config,
    manifest, and schema fixtures. `tests/plugin_schema.rs` runs as a normal
    Cargo integration test and now enforces required coverage labels, rejects
    orphan JSON fixtures, validates accepted and rejected fixtures through the
    checked-in schemas and typed Rust loaders, checks both schemas against
    `CURRENT_WIT_WORLD`, checks capability vocabulary drift, and checks config
    runtime-limit maxima against Rust host caps.
  - Next extension: add runtime replay goldens only after choosing a stable
    redacted trace format for update inputs, emitted effects, workspace I/O,
    operational events, and proposal receipts.

## Vim And Editor Core

- [ ] Decide whether stored cursor coordinates should become typed.
  - Current state: cursor move requests distinguish normal cursor cells from
    insert caret boundaries, while `CursorPosition` stores a shared byte index.
  - Gap: public request types are safer than stored view state, but future
    features such as replace mode, mouse placement, and plugin-originated
    cursor effects may benefit from a typed stored coordinate.

- [ ] Finish richer insert-mode command coverage.
  - Candidate commands: Delete, Ctrl-W, Ctrl-U, Tab, indentation, completion,
    replace mode, and arrow-key movement.
  - Acceptance: raw text mutation remains in the insert adapter, payloads stay
    bounded, and owner systems preserve UTF-8 boundary checks.

- [ ] Define undo transaction grouping for insert sessions and plugin proposals.
  - Current state: undo exists, but proposal and insert transaction boundaries
    need explicit policy before broad repeat or macro support.
  - Acceptance: one logical user or plugin action maps to one replayable undo
    record unless a typed policy says otherwise.

## Cross-Cutting Security

- [x] Define the repo-wide operation error taxonomy before adding plugin error envelopes.
  - Current state: `error.rs` files already favor typed enums and `thiserror`
    over boxed public errors. Filesystem and config errors may include escaped
    user-facing paths, while ECS and plugin owner boundaries adapt lower errors
    into redacted shapes. `ecs::events::operation` now owns shared
    owner-boundary failure classes and redacted lower-source shapes, with
    command diagnostics re-exporting command-local aliases.
  - Target style: keep boundary-specific error enums, add small operation
    envelopes only where they preserve failure phase information, and avoid a
    single catch-all app error.
  - Plugin candidate: model load, update, or workspace execution with small
    operation envelopes only where a caller would otherwise lose policy,
    decode, authorization, lifecycle, runtime, timeout, or queue-saturation
    phase information.
  - Acceptance: callers can match exact causes, `source()` preserves useful
    lower errors where safe, plugin/runtime `Debug` and `Display` stay
    shape-only, and no public boundary uses `Box<dyn Error>` as its primary
    type.

- [ ] Add redacted diagnostics for future runtime execution failures.
  - Scope: trap, timeout, malformed guest handle, malformed guest string,
    denied capability, stale handle, and over-limit queue rejection.
  - Current state: timeouts and capability denials emit redacted operational
    events. Wasmtime host-import failures now retain the generated import name
    through a closed diagnostic vocabulary and map non-authorization failures
    to closed rejection shapes for malformed guest data, stale or invalid
    handles, resource lookup failures, missing observed revisions, and bounded
    queue rejection. Guest traps now emit redacted operational events with a
    closed lifecycle-export vocabulary. Lower-level Wasmtime failure detail now
    uses a closed failure-class vocabulary instead of classifier strings.
  - Acceptance: user-facing diagnostics disclose stable identity and closed
    reason shape only, not raw guest payloads, host paths, buffer text, or OS
    strings.

- [ ] Keep supply-chain policy current as runtime execution becomes real.
  - Current tracked risk: `block 0.1.6` appears through the Bevy/wgpu/Metal
    stack in future-incompatibility reports.
  - Acceptance: runtime dependency changes update `docs/supply-chain.md` before
    new plugin execution paths are enabled by default.

## Acceptance Bar

- Pure behavior has unit or property tests before ECS wiring.
- New ECS systems are placed in existing `EditorSet`s with explicit ordering.
- No plugin path bypasses `fs_utils` or existing owner mutation boundaries.
- Runtime limits, queue limits, and payload limits are validated before use.
- Diagnostics stay redacted and shape-based at untrusted boundaries.
- Comments in touched files stay laconic and assume a senior Rust reader.