# TODO

This file tracks hardening work for making Daat Locus a reliable long-running local agent runtime.

- [x] Add daemon authentication for local control endpoints
  - [x] Protect `/commands/run`, `/daemon/shutdown`, dashboard snapshot, and dashboard stream.
  - [x] Store a per-install random daemon token in the protected runtime directory.
  - [x] Make the CLI client send the token on every protected request.
  - [x] Keep `/health` minimal and unauthenticated for readiness probing.

- [x] Add daemon ready-state gating before accepting runtime commands
  - [x] Add explicit daemon states: `initializing`, `ready`, `stopping`, and `failed`.
  - [x] Expose daemon state through `/status`.
  - [x] Reject runtime commands until daemon initialization reaches `ready`.
  - [x] Make `attach` render startup progress without implying the runtime is ready.

- [x] Replace Hindsight retain flush no-op with real handoff ack tracking
  - [x] Track pending and inflight handoff jobs inside `HindsightRetainHandle`.
  - [x] Treat backend success as Hindsight accepting the async retain request.
  - [x] Make `flush()` wait for local handoff submission acks.

- [x] Remove Hindsight handoff items only after backend accepts submission
  - [x] Preserve pending and inflight handoff items across process exits.
  - [x] Drain submitted handoffs or preserve unfinished work during daemon shutdown.
  - [x] Avoid deleting local queue items until retain handoff is accepted.

- [x] Add hard memory bounds for terminal process output buffers
  - [x] Replace unbounded terminal `Vec<u8>` output storage with a bounded ring buffer.
  - [x] Track dropped byte counts when output exceeds the hard limit.
  - [x] Surface truncation/drop metadata in terminal tool results and dashboard cells.
  - [x] Add tests for high-output commands that exceed the buffer limit.

- [x] Add request timeout and worker recovery for Lua workspace apps
  - [x] Cover app hooks, tools, render, and notice polling.
  - [x] Run Lua `config(ctx)` before cold start so apps can adjust request and cold-start timeouts.
  - [x] Run worker cold start through explicit initialization with a separate timeout.
  - [x] Treat Lua `init(ctx, state)` as a worker cold-start hook, not a one-time state factory.
  - [x] Enforce app request timeouts by terminating and restarting worker processes.
  - [x] Convert timeout and resource failures into stable app errors instead of blocking runtime.

- [x] Tighten the default runtime self-protection policy
  - [x] Keep the default policy lightweight: the user owns the machine, so do not build a broad filesystem jail.
  - [x] Prevent tools from reading or writing Daat Locus private config/runtime state.
  - [x] Prevent tools from writing Daat Locus's own source tree when the source root is known.
  - [x] Prevent terminal tools from inheriting provider secret environment variables.
  - [x] Add tests for protected runtime paths, source writes, and secret env stripping.

- [x] Consider optional strong sandbox backends for Linux and Windows
  - [x] Keep strong sandboxing out of the default path; the default policy remains a lightweight self-protection guard.
  - [x] Scope the strong sandbox to filesystem permissions only; network/web restrictions are out of scope.
  - [x] Select Codex-style Linux bubblewrap as the primary filesystem backend direction.
  - [x] Keep Linux Landlock as a legacy or fallback reference, not the primary backend.
  - [x] Select Codex-style Windows restricted-token, capability SID, ACL, and Job Object design as the Windows direction.
  - [x] Document platform support and failure-mode expectations before implementation.
  - [x] Add a platform-neutral strong sandbox spawn layer for Terminal and workspace app worker processes.
  - [x] Route Terminal and workspace app worker process creation through sandbox-owned launch wrappers.
  - [x] Implement the optional Linux bubblewrap filesystem backend.
  - [x] Implement the optional Windows workspace app worker backend with restricted tokens and temporary ACL guards.
  - [x] Extend the optional Windows backend to Terminal pipes and process-tree cleanup.
  - [x] Add conformance tests for protected runtime paths when a backend is enabled.

- [x] Resolve symlinks and canonical paths for sandbox enforcement
  - [x] Canonicalize paths before read/write checks where possible.
  - [x] Add tests for symlink escape attempts.
  - [x] Keep behavior deterministic when target paths do not exist yet.

- [x] Introduce a unified persistence store for runtime state files
  - [x] Centralize runtime config, state, and memory file path access.
  - [x] Use temp-file, fsync, and rename semantics for replace-style writes.
  - [x] Add corruption quarantine for unreadable persisted state files.
  - [x] Add durable append helpers for append-only runtime records.
  - [x] Add tests for atomic writes, private permissions, corrupt files, and durable append.

- [x] Apply unified persistence to state stores
  - [x] Cover memory, events, pending work, plan, config, and ACL state.
  - [x] Cover daemon auth files, Telegram transport state, workspace app state, workflow specs, workflow run records, and reasoning compile/frontier artifacts.
  - [x] Cover append-only runtime trace and compaction journals.
  - [x] Avoid direct `tokio::fs::write` or `std::fs::write` for durable state.

- [x] Support env-based secret references for all provider credentials
  - [x] Accept `env:NAME` or `$NAME` references consistently.
  - [x] Resolve OpenAI and OpenAI-compatible API keys through the same resolver as Copilot.

- [x] Support OpenAI Codex OAuth login
  - [x] Add a first-class OpenAI Codex OAuth provider type.
  - [x] Reuse the Codex browser callback OAuth flow and client id.
  - [x] Keep device-code OAuth as a fallback for headless or explicitly enabled flows.
  - [x] Persist rotating OAuth credentials in a private auth JSON file.
  - [x] Refresh expired access tokens and attach ChatGPT account routing headers.
  - [x] Use the ChatGPT Codex Responses backend instead of the public OpenAI API path.
  - [x] Wire setup, model discovery, runtime LLM creation, and docs.

- [x] Write config files with private permissions
  - [x] Set `0600` on Unix-like systems.
  - [x] Preserve safe behavior when rewriting existing config files.

- [x] Avoid leaking provider secrets in UI and logs
  - [x] Mask provider secrets in config summaries.
  - [x] Avoid printing raw credentials in errors and debug output.
  - [x] Avoid persisting unmasked secrets outside config.

- [x] Pin and verify managed uv downloads
  - [x] Pin auto-downloaded uv versions instead of using GitHub `latest`.
  - [x] Verify downloads with checksums before execution.

- [x] Verify browser runtime downloads without pinning latest stable
  - [x] Keep using Chrome for Testing latest stable to receive browser security updates.
  - [x] Verify browser runtime content length and GCS MD5 hash before extraction.
  - [x] Record installed browser runtime version, revision, URL, and archive hash metadata.

- [x] Persist mutable runtime state at mutation boundaries
  - [x] Persist plan immediately after `update_plan` and dashboard clear.
  - [x] Persist runtime conversation and Hindsight queue immediately after committing a runtime turn.
  - [x] Persist runtime conversation compaction results when they are applied.
  - [x] Keep shutdown persistence as a best-effort fallback, not the primary durability boundary.

- [x] Preserve pending Hindsight handoff items across process exits
  - [x] Reset only inflight state that is safe to retry.
  - [x] Keep pending but unsubmitted items visible in the local queue.

- [x] Add explicit app notice resolution
  - [x] Add a `notice_resolved` tool that can resolve only app notices claimed by the current turn.
  - [x] Render `notice_resolved` with the same resolved completion UI used by `finish_and_send`, without implying an outbound reply was sent.
  - [x] Track active and resolved app notice state by `(app, reason)` instead of app id alone.
  - [x] Do not requeue a claimed app notice after the model explicitly resolves that exact notice.
  - [x] Re-enqueue app notice work only when the app reports a different reason or after the notice clears and later reappears.
  - [x] Keep bounded retry or suppression only as a fallback for repeatedly unresolved claimed notices.

- [x] Add tests for pending work recovery paths
  - [x] Cover event claim, requeue, overflow fuse, and terminal resolution paths.
  - [x] Audit turn-boundary behavior after focus/app/tool changes.
  - [x] Ensure unresolved claimed inputs are requeued or failed with explicit reason.

- [x] Document model catalog source and update process
  - [x] Record source, generation process, and update date.
  - [x] Add a refresh script or documented manual process.
  - [x] Keep generated/catalog data clearly separated from handwritten provider logic.

- [x] Add model catalog fallback tests
  - [x] Cover unknown model IDs.
  - [x] Cover stale or similar model names.
  - [x] Confirm conservative defaults are used safely.

- [x] Add CI quality gates
  - [x] Run `cargo fmt --check`.
  - [x] Run `cargo clippy --all-targets`.
  - [x] Run `cargo test`.
  - [x] Add dependency/license checks.

- [x] Add release checklist
  - [x] Cover daemon auth.
  - [x] Cover state migration.
  - [x] Cover supply chain pins.
  - [x] Cover backwards compatibility for config and workspace app behavior.

- [x] Track license and attribution obligations
  - [x] Add a dependency license audit note for transitive dependencies.
  - [x] Track dependencies with weak-copyleft or attribution-sensitive licenses.
  - [x] Document when a project-level `NOTICE` file becomes necessary.

- [x] TUI：引入 cell 级视口裁剪替代全量 Vec<Line> 渲染
  - [x] 实现 Renderable trait 和 ColumnRenderable 组合器（参考 codex renderable.rs）。
  - [x] 每个 ActivityCell 实现 desired_height / render，视口外 cell 跳过绘制。
  - [x] 用 FlexRenderable 将活动列表、命令输入框、弹窗组合为布局树。
  - [x] 保留 CachedActivityLines 作为 cell 内 markdown 行缓存。
  - [x] ViewportCulledColumn 实现视口裁剪，render_skip 支持 Paragraph::scroll 跳行。

- [x] TUI：修复命令输入框光标位置
  - [x] 在 terminal.draw 闭包中调用 frame.set_cursor_position()（已在 render_command_bar 实现）。
  - [x] 命令输入框光标位置由 render_command_bar 直接计算（无需布局树递归）。
  - [x] 通过 crossterm::execute! 调用 SetCursorStyle::SteadyBar 恢复可见光标，退出时重置为 DefaultUserShape。
  - [x] 确认 crossterm 层面无 EnableMouseCapture 残留（已在 69d57f1 移除）。

- [x] TUI：重构事件循环为 async stream 模式
  - [x] 引入 TuiEvent 枚举（Key / Paste / Resize / Draw）替代裸 crossterm Event。
  - [x] 用 tokio::select! 同时监听 tui_events、app_events、app_server_events。
  - [x] 引入 FrameRequester + FrameScheduler 机制让组件按需请求重绘。
  - [x] 加入 FrameRateLimiter (120fps cap) 防止过度绘制。
  - [x] 移除手动的 needs_render / poll_timeout / next_animation_deadline 轮询逻辑。

- [x] TUI：实现 history_cell 级 markdown 增量渲染
  - [x] 参考 codex history_cell.rs 的 display_lines(width) 模式。
  - [x] 将 render_markdown 输入改为按 cell 调用，而非拼接全部 body_lines。
  - [x] 为 Assistant 消息 cell 添加 Rich / Raw 双模式支持。
  - [x] 加入 ReducedMotionIndicator 控制动画行为。

- [x] Filter import-only LSP review events from Coding propagation output
  - [x] Detect references whose only usage is an import/use statement and exclude them from review events.
  - [x] Keep semantic references such as call sites, parser entry points, and tests visible for propagation review.
  - [x] Add coverage for Rust `use` imports so TreeSitterAnalyzer imports do not dominate review output.
