Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@
- Upgraded the terminal stack to exact Ratatui 0.30.2, ratatui-core 0.1.2,
tui-markdown 0.3.8, Crossterm 0.29.0, and unicode-width 0.2.2 versions.
Dext carries a narrow exact-source ratatui-core compatibility patch for its
inline viewport; the real-PTY suite now gates streaming input, populated
resize bursts, whole-screen clears, cursor-query counts, replay bounds, and a
bounded completion wait that tolerates slower macOS CI hosts.
inline viewport; the real-PTY suite now starts each child with a controlling
terminal and gates streaming input, populated resize bursts, whole-screen
clears, cursor-query counts, replay bounds, and a bounded completion wait
that tolerates slower macOS CI hosts.
- macOS Seatbelt profiles now allow both canonical `/private/...` scratch paths
and their standard `/var` or `/tmp` aliases, keeping temp APIs confined and
usable.
Expand All @@ -62,6 +63,18 @@
project, user, or `DEXT_SHELVES_DIR` roots; direct pack roots and
`DEXT_PACKS_DIR` are no longer discovery inputs.

- Replaced `/plan` with conversational planning turn policies. The objective
tracker now classifies planning/analysis-only prompts (including explicit
“don’t change anything” phrasing) and bare plan approvals (“go”, “proceed
with the plan”); Dext injects a matching advisory-only or
implementation-authorized turn policy into the volatile runtime status —
never the cached stable prompt — so weaker models get deterministic per-turn
structure without hard tool gating. Explicit mutation intent always
overrides advisory phrasing, question-phrased prompts are never read as
approvals, and mid-turn queued user updates re-evaluate the policy;
approval prompts and `/sandbox-profile read-only` remain the enforcement
layers.

### Removed

- Removed the completed repository-local `.auto` prompt-efficiency experiment scaffold and now ignore the entire root `.auto/` workspace. Dext runtime/build/CI and the user-owned autoresearch pack do not depend on those project experiment files.
Expand Down Expand Up @@ -89,8 +102,13 @@
- Removed the subagent feature completely: `/subagent` slash command,
`subagent-runtime` CLI subcommand, detached/inline runners, steering,
quality gates, TUI state, session artifacts dir, and all associated
tests/fixtures. `/plan` preserved via a direct read-only planner.
Net -1544 lines.
tests/fixtures. Net -1544 lines.
- Removed the unused `/plan` slash command and its hidden read-only planner turn,
temporary agent-state swapping, duplicated CLI/TUI dispatch, completion entry,
welcome tip, and planner-only regression test. Planning is now an ordinary
conversation: ask Dext to inspect and propose a plan without editing, revise
it in context, then tell it to proceed. A former `/plan ...` input is no
longer intercepted and is delivered as a normal prompt.
- Removed all repository-owned and embedded pack payloads. Dext ships the pack
lifecycle and shelf integration, but no pack content; users own and
distribute shelf repositories separately.
Expand Down
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 17 additions & 4 deletions DEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,23 @@ When changing Dext itself:

## Context files
- `DEXT.md` is tracked project guidance and is auto-injected from the sandbox
root and its ancestors. Keep it terse and machine-facing.
- `recall.md` is an optional ignored prompt cache. It is auto-injected when
present, but Dext does not create or update it automatically.
- Do not create or update `recall.md` unless the user asks.
root and its ancestors. Keep it terse and machine-facing. DEXT.md is
human-authored policy; agents never edit it.
- `recall.md` is agent working memory, ignored by Git and auto-injected when
present.

## Recall policy
- Create/update `recall.md` without asking, at task boundaries (task done,
correction received, gotcha resolved) — not mid-exploration.
- Hard cap ~4KB. To add when full, prune the least-valuable entry in the same
edit.
- One line per entry: date, tag `[fact]`|`[pref]`|`[proc]`|`[fix]`, session id.
- Declarative observations only — record what is true, never what to do.
Imperatives and instructions to future sessions are forbidden; DEXT.md alone
carries policy.
- Never write secrets, credentials, or personal data.
- New entries end with `?`. Strip the `?` only when a later session relies on
the entry and it holds. Delete entries the repo contradicts.

## Packs and shelves
- Packs may optionally declare a reviewed `runtime.json` one-shot helper to expose dynamic tools, bounded state, continuation/steering effects, and markdown views; executable activation and write-risk calls retain approval, sandbox, credential-scrubbing, and checkpoint controls.
Expand Down
6 changes: 3 additions & 3 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Dext is a Rust terminal agent packaged as one binary. Most behavior is still int
- Built-in GLM, ChatGPT/Codex, OpenAI, Anthropic, Kimi Code, DeepSeek, and local OpenAI-compatible profiles.
- Live llama.cpp runtime context probing for the local provider; unavailable local servers fall back cleanly without aborting startup.
- API-key, ChatGPT OAuth, and Anthropic Claude Pro/Max OAuth login flows; runtime auth retains whether a resolved secret is an API key or OAuth token. OAuth callback binding is loopback-only, accepted connections use blocking I/O under one two-second complete-header deadline, result pages wait for exchange/storage completion, exchange/refresh transport is bounded and redirect-free, and active OAuth credentials are rechecked at user-turn boundaries.
- Request builders for Anthropic, OpenAI-compatible, and ChatGPT/Codex response APIs.
- Request builders for Anthropic, OpenAI-compatible, and ChatGPT/Codex response APIs. Public adaptive Anthropic models (Sonnet 4.6, Sonnet 5, Opus 4.6/4.7/4.8, Opus 5, and Fable 5) omit `thinking.display`; transformed OAuth and API-key request fixtures verify the same adaptive shape.
- Model alias normalization and provider/model switching helpers.

- `src/claude_subscription.rs`
Expand Down Expand Up @@ -132,7 +132,7 @@ Dext is a Rust terminal agent packaged as one binary. Most behavior is still int

- `vendor/ratatui-core/`
- Exact upstream `ratatui-core 0.1.2` source selected through `[patch.crates-io]`.
- Narrow inline-terminal fixes that avoid synchronous cursor-query stalls and whole-display clears during resize.
- Narrow inline-terminal fixes that avoid synchronous cursor-query stalls and extra whole-display clears before Dext's owned resize replay, plus an origin-reset primitive that clears the visible display before stale-width scrollback is purged so complete transcript reconstruction replays the intro exactly once.
- Hunk rationale and refresh instructions in `vendor/ratatui-core/DEXT_PATCH.md`.

## Tool model
Expand Down Expand Up @@ -279,6 +279,6 @@ cargo test --release --locked
cargo test --release --locked --test tui_smoke -- --nocapture
```

The TUI smoke suite launches the real compiled binary inside a pseudo-terminal. In addition to launch/help/exit coverage, it checks narrow and wide layouts, multiline input, live-stream input, resize survival, bounded cursor queries, zero whole-screen resize clears, and completed output after resize. Renderer changes also follow the live-terminal checks in [`TUI.md`](TUI.md).
The TUI smoke suite launches the real compiled binary inside a pseudo-terminal. In addition to launch/help/exit coverage, it checks narrow and wide layouts, multiline input, live-stream input, resize survival, bounded cursor queries, a visible-display clear before each paired scrollback purge, exactly one Dext intro per replay segment, terminal-height-bounded complete replay, and completed output after resize. Renderer changes also follow the live-terminal checks in [`TUI.md`](TUI.md).

On Windows CI and release builders, the scheduler-sensitive `fast_bash_command_returns_without_100ms_poll_tail` regression runs alone after the remaining release tests. Its original `<90 ms` assertion remains unchanged; isolation prevents unrelated suite load from obscuring the process-wait regression it measures. The external-runner stdin-backpressure regression still requires bounded completion under the shared deadline, but accepts either the stdin-write or root-process timeout phase on Windows because pipe buffering can make the full write complete at the deadline boundary; Unix continues to require the stdin-write phase. The tool-call mock provider consumes its bounded `Content-Length` request body before responding so Windows does not reset the connection with unread request data.
2 changes: 1 addition & 1 deletion docs/RISK_REGISTER.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Priorities: **P1** needs planned mitigation before a stronger security/reliabili
| R-010 | Privacy · local recovery · P3 | Low with normal Git push; medium with mirror/backup sharing | Medium | High | Checkpoint refs and owner-private sidecars/blobs may retain sensitive file content and symlink targets. Write-risk arbitrary-command checkpoints can preserve existing untracked entries within bounded limits. Mirroring `refs/dext/*`, copying full repository metadata, or sharing state backups can disclose it. Evidence: checkpoint storage in `src/git_checkpoints.rs` and warnings in `SECURITY.md`. | On Unix, checkpoint storage containers are current-user-owned, `.dext` is not group/world-writable, and managed checkpoint/sidecar/blob directories are owner-private; unsafe restore containers fail closed, prune retains unsafe blob entries and sidecar directory trees with bounded warnings, and orphan top-level sidecar symlinks are unlinked without traversal. Blobs are content-addressed and verified before/while restoring; current manifests record exact direct-sidecar membership, while ambiguous missing artifacts in older manifests fail before mutation; every manifest path is validated by one repo-relative rule that a row cannot opt out of; recognized retired rows require intact headers, complete retired field grammar, and live-ref OID matches; retention publishes the compacted manifest before deleting expired/retired refs or artifacts so cleanup failure leaves orphan state rather than a manifest naming deleted recovery points, while corruption or tampering fails closed; runtime manifest reads are capped at 16 MiB; cache reuse requires stable source/blob metadata fingerprints; `.dext/` is locally excluded; arbitrary-command inventory/capture is capped at 500 paths, 8 MiB/file, and 32 MiB/checkpoint; non-UTF-8/unsupported/capped entries require partial-recovery approval; failed creation cleans new blobs; automatic retention is 20 checkpoints/seven days and prunes valid unreferenced blobs; normal Git pushes do not include hidden refs; docs warn against mirror-pushing Dext refs. | Add an explicit sensitive-checkpoint inventory/prune workflow and optional checkpoint disable/exclude patterns · recovery/privacy owner · review when capture scope, retention, backup, or ref publication behavior changes. |
| R-011 | Maintainability · architecture · P2 | High for routine core changes | Medium | High | `src/main.rs`, `src/tui.rs`, and the in-crate test surface remain large; unrelated runtime concerns still share broad compile/review boundaries. Evidence: module line counts and the responsibility map in `docs/ARCHITECTURE.md`. | Provider streaming, tool rounds/journal, checkpoints, mutation previews, sandbox, policy, pack runtime, packs, shelves, seats, sessions, and orchestration already have focused modules; the unused work-map/focus/track vertical slice and its TUI/event/test surface were removed rather than extracted; tool metadata has one registry for required fields and execution flags; release tests cover cross-module behavior. | Extract one stable seam at a time (HTTP tool, diagnostics, doctor, export, eval) with behavior-preserving tests; do not combine extraction with feature work · architecture owner · review when adding another substantial `main.rs` subsystem or when merge/compile cost blocks delivery. |
| R-012 | Security · state · same-user concurrency · P2 | Low in normal private state; medium with a hostile same-user process | High | Medium | Seat reads/writes validate path components, ancestors, ownership, modes, links, and opened-file identity, but path-based ancestor validation and later open/rename are not one descriptor-relative transaction. A hostile same-user process can replace an ancestor after validation and redirect or disrupt Seat metadata/pointer operations. Evidence: `src/seats.rs` ancestor validation and atomic path replacement. | Portable ids; owner-safe Unix state ancestors; owner-private managed directories; no-follow single-link record reads; inode revalidation; bounded schema/content; cross-process operation lock; atomic secret-file replacement; transactional reset rollback attempt; documented same-user boundary. | Use descriptor-relative no-follow traversal and handle-relative atomic replacement for the complete Seat path, or place Seat operations inside an OS-isolated trusted state service · state/security owner · review on Seat path changes or any state-redirection incident. |
| R-013 | Reliability · provider compatibility · P1 | High when Anthropic changes its private Claude Code contract | High for affected subscription users | High | Claude Pro/Max routing depends on an unofficial, version-specific OAuth and request shape that Anthropic can change without API compatibility guarantees; provider terms may also restrict third-party subscription clients. Evidence: pinned Claude Code 2.1.224 constants and billing/checksum/header construction in `src/claude_subscription.rs`. | Compatibility applies only to typed OAuth credentials on the marked built-in Anthropic profile at the exact official base URL; API keys, custom endpoints, GLM, and Kimi bypass it; malformed body shapes fail closed; OAuth callback binding is loopback-only, accepted connections use blocking I/O, and complete request headers/state are validated under one two-second total deadline; exchange/refresh uses bounded redirect-free transport, rechecks active OAuth expiry per user turn, and preserves refresh rotation; fake-transport/vector tests cover fingerprints, checksum, headers, identity validation, callback outcomes, refresh persistence, and provider isolation; docs disclose unofficial status and terms responsibility. | Revalidate OAuth endpoints/scopes and public wire vectors against each supported Claude Code contract before changing the pin; disable or update the route on provider rejection rather than adding permissive fallback shaping · provider/security owner · every Claude compatibility change or authentication incident. |
| R-013 | Reliability · provider compatibility · P1 | High when Anthropic changes its private Claude Code contract | High for affected subscription users | High | Claude Pro/Max routing depends on an unofficial, version-specific OAuth and request shape that Anthropic can change without API compatibility guarantees; provider terms may also restrict third-party subscription clients. Evidence: pinned Claude Code 2.1.224 constants and billing/checksum/header construction in `src/claude_subscription.rs`. | Compatibility applies only to typed OAuth credentials on the marked built-in Anthropic profile at the exact official base URL; API keys, custom endpoints, GLM, and Kimi bypass it; malformed body shapes fail closed; OAuth callback binding is loopback-only, accepted connections use blocking I/O, and complete request headers/state are validated under one two-second total deadline; exchange/refresh uses bounded redirect-free transport, rechecks active OAuth expiry per user turn, and preserves refresh rotation; fake-transport/vector tests cover fingerprints, checksum, headers, identity validation, callback outcomes, refresh persistence, provider isolation, OAuth-transformed adaptive request fields, API-key parity, and visible thinking-delta/signature round trips; docs disclose unofficial status and terms responsibility. | Revalidate OAuth endpoints/scopes and public wire vectors against each supported Claude Code contract before changing the pin; disable or update the route on provider rejection rather than adding permissive fallback shaping · provider/security owner · every Claude compatibility change or authentication incident. |

## Review protocol

Expand Down
Loading