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
7 changes: 7 additions & 0 deletions .tower/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ adapter_type = "fixture"
default_timeout_secs = 5
idle_ttl_secs = 300

[debug.record]
backend = "rr"
trace_dir = ".tower/traces"
ttl_secs = 86400
max_traces = 25
record_timeout_secs = 30

[extensions]
# Plugin file stems to skip loading, e.g. ["ast"].
# A disabled extension gets no sandbox, no fuel, no tools, no watcher hooks.
Expand Down
24 changes: 24 additions & 0 deletions .zpm/kb/architecture/journal.wal
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,27 @@
{"ts":1782295010,"op":"assert","clause":"arch_convention('conv_debug_inspection_requires_stop', 'extensions/debug', 'stack, variables, and evaluate require a stopped session and return not-stopped while the debuggee is running', 'feature_f004_interactive_debug_session_sidecar')"}
{"ts":1782295010,"op":"retractall","clause":"arch_convention('conv_sidecar_hostcall_queue', _, _, _)"}
{"ts":1782295010,"op":"assert","clause":"arch_convention('conv_sidecar_hostcall_queue', 'extension sidecars', 'sidecars that await HostCall responses must queue inbound host requests and replay them instead of discarding non-matching frames', 'feature_f004_interactive_debug_session_sidecar')"}
{"ts":1782309987,"op":"retractall","clause":"arch_component(_,_,_,'feature_f005_debug_eval_at_stateless_evidence_prob')"}
{"ts":1782309987,"op":"retractall","clause":"arch_port(_,_,'feature_f005_debug_eval_at_stateless_evidence_prob')"}
{"ts":1782309987,"op":"retractall","clause":"arch_decision(_,_,_,_,'feature_f005_debug_eval_at_stateless_evidence_prob')"}
{"ts":1782309988,"op":"retractall","clause":"arch_convention(_,_,_,'feature_f005_debug_eval_at_stateless_evidence_prob')"}
{"ts":1782309988,"op":"retractall","clause":"arch_adr(_,_,'feature_f005_debug_eval_at_stateless_evidence_prob')"}
{"ts":1782309988,"op":"retractall","clause":"arch_feature('feature_f005_debug_eval_at_stateless_evidence_prob',_,_)"}
{"ts":1782309988,"op":"retractall","clause":"arch_decision('dec_eval_at_sidecar_tool', _, _, _, _, _)"}
{"ts":1782309988,"op":"assert","clause":"arch_decision('dec_eval_at_sidecar_tool', 'debug probe placement', 'implement eval_at as a debug sidecar extension tool exposed through tower_debug_eval_at, not as a native core_engine MCP tool', 'keeps DAP process lifecycle and debug config gating inside the existing fault-isolated debug extension while preserving the host/domain boundary', 'feature_f005_debug_eval_at_stateless_evidence_probe')"}
{"ts":1782309988,"op":"retractall","clause":"arch_decision('dec_eval_at_stateless', _, _, _, _)"}
{"ts":1782309988,"op":"assert","clause":"arch_decision('dec_eval_at_stateless', 'debug probe lifecycle', 'make eval_at a one-shot stateless probe that never exposes session_id in request or response', 'the probe exists to capture runtime evidence without making callers manage interactive session state; the internal session id is only for cleanup', 'feature_f005_debug_eval_at_stateless_evidence_probe')"}
{"ts":1782309989,"op":"retractall","clause":"arch_decision('dec_eval_at_reuse_session_manager', _, _, _, _, _, _, _, _, _)"}
{"ts":1782309989,"op":"assert","clause":"arch_decision('dec_eval_at_reuse_session_manager', 'DAP orchestration', 'build eval_at as an orchestration recipe over SessionManager and DebugAdapterSession instead of a parallel DAP client or new probe runtime', 'reuses existing launch, breakpoint, resume, inspection, timeout, and cleanup semantics while keeping the new behavior fakeable in tests', 'feature_f005_debug_eval_at_stateless_evidence_probe')"}
{"ts":1782309989,"op":"retractall","clause":"arch_decision('dec_eval_at_exited_payload', _, _, _, _, _, _)"}
{"ts":1782309989,"op":"assert","clause":"arch_decision('dec_eval_at_exited_payload', 'no-hit process exit', 'represent normal no-hit process exit as hit:false with finished:exited and optional exit_code', 'a program that exits before the breakpoint is reached is probe evidence, not a transport failure, and callers need the adapter-provided exit code when available', 'feature_f005_debug_eval_at_stateless_evidence_probe')"}
{"ts":1782309989,"op":"retractall","clause":"arch_decision('dec_eval_at_local_expression_errors', _, _, _, _, _, _, _)"}
{"ts":1782309989,"op":"assert","clause":"arch_decision('dec_eval_at_local_expression_errors', 'expression evaluation failures', 'record each failed expression as an error value in that expression result instead of failing the whole probe', 'one bad expression should not discard stack, locals, output, or other expression evidence captured from the same stop', 'feature_f005_debug_eval_at_stateless_evidence_probe')"}
{"ts":1782309989,"op":"retractall","clause":"arch_convention('conv_eval_at_bounded_capture', _, _, _, _, _, _)"}
{"ts":1782309989,"op":"assert","clause":"arch_convention('conv_eval_at_bounded_capture', 'extensions/debug/eval_at', 'eager variable capture must obey max_depth, max_children, and max_hits, and mark truncated variable nodes', 'feature_f005_debug_eval_at_stateless_evidence_probe')"}
{"ts":1782309989,"op":"retractall","clause":"arch_convention('conv_eval_at_cleanup', _, _, _, _, _, _, _)"}
{"ts":1782309989,"op":"assert","clause":"arch_convention('conv_eval_at_cleanup', 'extensions/debug/eval_at', 'eval_at must terminate and reap the internal debug session on hit, no-hit exit, timeout, adapter exit, and runtime error paths', 'feature_f005_debug_eval_at_stateless_evidence_probe')"}
{"ts":1782309990,"op":"retractall","clause":"arch_convention('conv_eval_at_probe_outcomes', _, _, _, _, _, _)"}
{"ts":1782309990,"op":"assert","clause":"arch_convention('conv_eval_at_probe_outcomes', 'extensions/debug/tools', 'expected probe outcomes such as timeout, unsupported breakpoint conditions, expression errors, and no-hit exits should serialize as successful JSON payloads rather than protocol errors', 'feature_f005_debug_eval_at_stateless_evidence_probe')"}
{"ts":1782309990,"op":"retractall","clause":"arch_convention('conv_debug_no_workspace_mutation', _, _, _)"}
{"ts":1782309990,"op":"assert","clause":"arch_convention('conv_debug_no_workspace_mutation', 'extensions/debug', 'debug extension protocol additions must continue to request no workspace mutation capabilities', 'feature_f005_debug_eval_at_stateless_evidence_probe')"}
5 changes: 5 additions & 0 deletions .zpm/kb/feedback/journal.wal
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,8 @@
{"ts":1782302951,"op":"assert","clause":"rule(debug_dap_timeout_tests_use_timeout_error, test, 'Scripted DAP transport tests must model wait deadlines with DapError::Timeout; an exhausted/Ok(None) receive stream represents adapter EOF and should exercise AdapterExited behavior.', medium, 'F005 review remediation 2026-06-24')"}
{"ts":1782305755,"op":"assert","clause":"rule(debug_eval_at_reject_unknown_fields, pitfall, 'Debug eval-at request DTOs must deny unknown fields whenever the advertised schema uses additionalProperties:false, so typos fail as InvalidParams instead of silently defaulting.', high, 'F005 review remediation 2026-06-24')"}
{"ts":1782309178,"op":"assert","clause":"rule(debug_eval_at_breakpoints_before_configuration_done, pitfall, 'For stateless debug eval-at probes, install requested breakpoints before DAP configurationDone; sending configurationDone first can let real adapters run past the probe location before breakpoints exist.', high, 'F005 remediation 2026-06-24')"}
{"ts":1782316077,"op":"assert","clause":"rule(debug_trace_delete_direct_child, pitfall, 'Debug trace deletion and pruning must verify a trace path canonicalizes to the direct child directory named by TraceId under TracePolicy.trace_root before remove_dir_all; starts_with(root) is insufficient because it accepts the root itself.', high, 'F006 T011 review remediation 2026-06-24')"}
{"ts":1782317926,"op":"assert","clause":"rule(f006_rr_output_order_global_budget, test, 'When testing rr bounded output capture, cover cross-stream stderr/stdout interleaving separately from global byte-budget truncation because a true shared cap may consume the entire budget before a later stream writes.', medium, 'F006 remediation 2026-06-24')"}
{"ts":1782323287,"op":"assert","clause":"rule(f006_t016_cleanup_token_e2e_exact_event_count, test, 'For reverse debug cleanup e2e coverage, assert each required cleanup token has exactly one captured {\"event\":\"cleanup\",\"token\":...} event through the public tool result, not only process absence.', high, 'F006 T016 QA remediation 2026-06-24')"}
{"ts":1782323287,"op":"assert","clause":"trigger(f006_t016_cleanup_token_e2e_exact_event_count, 'crates/core_engine/tests/extension_debug_e2e.rs', file)"}
{"ts":1782325349,"op":"assert","clause":"rule(f006_reverse_debug_cleanup_tokens_per_process, test, 'Use distinct cleanup tokens for distinct reverse-debug replay-backed operations when asserting exact cleanup event counts.', medium, 'F006 functional test implementation 2026-06-24')"}
32 changes: 28 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,13 @@ Positions are **0-based** `line` + **UTF-16** `character` offset.
| `tower_lsp_hover` | Hover info for the symbol at a position. |
| `tower_lsp_diagnostics` | Errors/warnings for a file. |

### Debug — interactive sessions (`debug` extension, spec 33)
### Debug — interactive sessions and reverse debugging (`debug` extension, spec 33)

Opt-in; tools appear only when `[debug.<language>]` is configured and the `debug` extension is
enabled. A discovered `debug` extension takes priority; otherwise the bundled sidecar is used when
`debug_extension` is available next to `tower`.
`debug_extension` is available next to `tower`. rr-backed record/replay tools appear only when
`[debug.record] backend = "rr"` is configured; unsupported rr hosts return structured tool payloads
rather than transport errors.

| Tool | Purpose |
|------|---------|
Expand All @@ -128,6 +130,16 @@ enabled. A discovered `debug` extension takes priority; otherwise the bundled si
| `tower_debug_stack` | Read stack frames for a thread. |
| `tower_debug_variables` | Read variables for a DAP variables reference. |
| `tower_debug_evaluate` | Evaluate an expression in a stack frame. |
| `tower_debug_eval_at` | Run a stateless one-shot breakpoint probe and capture bounded stack/variable evidence. |
| `tower_debug_record` | Record one native execution through rr and register a trace. |
| `tower_debug_replay` | Open a replay-backed debug session for a recorded trace. |
| `tower_debug_reverse_continue` | Continue a replay session backward until a stop, trace start, or timeout. |
| `tower_debug_step_back` | Step a replay session backward by line, instruction, or over granularity. |
| `tower_debug_watchpoint` | Set a replay-session data watchpoint by expression or address. |
| `tower_debug_traces` | List recorded debug traces known to the sidecar trace store. |
| `tower_debug_delete_trace` | Delete a recorded trace by id, contained to the configured trace root. |
| `tower_debug_find_origin` | Open replay, seek, set a write watchpoint, reverse-continue, capture origin evidence, and clean up. |
| `tower_debug_record_and_find_origin` | Record a trace and immediately run the origin-finding recipe against it. |
| `tower_debug_terminate` | Terminate a debug session and clean up the adapter process. |
| `tower_debug_disconnect` | Disconnect from a debug session. |
| `tower_debug_sessions` | List active debug sessions and their last known state. |
Expand Down Expand Up @@ -314,11 +326,13 @@ Positions are **0-based** `line` + **UTF-16** `character` offset.
| `tower_lsp_hover` | Hover info for the symbol at a position. |
| `tower_lsp_diagnostics` | Errors/warnings for a file. |

### Debug — interactive sessions (`debug` extension)
### Debug — interactive sessions and reverse debugging (`debug` extension)

Opt-in; tools appear only when `[debug.<language>]` is configured and the `debug` extension is
enabled. A discovered `debug` extension takes priority; otherwise the bundled sidecar is used when
`debug_extension` is available next to `tower`.
`debug_extension` is available next to `tower`. rr-backed record/replay tools appear only when
`[debug.record] backend = "rr"` is configured; unsupported rr hosts return structured tool payloads
rather than transport errors.

| Tool | Purpose |
|------|---------|
Expand All @@ -331,6 +345,16 @@ enabled. A discovered `debug` extension takes priority; otherwise the bundled si
| `tower_debug_stack` | Read stack frames for a thread. |
| `tower_debug_variables` | Read variables for a DAP variables reference. |
| `tower_debug_evaluate` | Evaluate an expression in a stack frame. |
| `tower_debug_eval_at` | Run a stateless one-shot breakpoint probe and capture bounded stack/variable evidence. |
| `tower_debug_record` | Record one native execution through rr and register a trace. |
| `tower_debug_replay` | Open a replay-backed debug session for a recorded trace. |
| `tower_debug_reverse_continue` | Continue a replay session backward until a stop, trace start, or timeout. |
| `tower_debug_step_back` | Step a replay session backward by line, instruction, or over granularity. |
| `tower_debug_watchpoint` | Set a replay-session data watchpoint by expression or address. |
| `tower_debug_traces` | List recorded debug traces known to the sidecar trace store. |
| `tower_debug_delete_trace` | Delete a recorded trace by id, contained to the configured trace root. |
| `tower_debug_find_origin` | Open replay, seek, set a write watchpoint, reverse-continue, capture origin evidence, and clean up. |
| `tower_debug_record_and_find_origin` | Record a trace and immediately run the origin-finding recipe against it. |
| `tower_debug_terminate` | Terminate a debug session and clean up the adapter process. |
| `tower_debug_disconnect` | Disconnect from a debug session. |
| `tower_debug_sessions` | List active debug sessions and their last known state. |
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ INSTALL_DIR ?= $(HOME)/.local/bin
# For the global XDG scope, pass
# EXT_DEST=$(HOME)/.local/share/tower/extensions
# EXT_PROFILE — release (default, deployable) or debug (fast, reuses dev build).
EXTENSIONS ?= ast lsp fmt lint debug
EXTENSIONS ?= ast debug fmt lint lsp
EXT_DEST ?= .tower/extensions
EXT_PROFILE ?= release

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ See [`project-brief.md`](project-brief.md) for the full vision.
| **AST analysis** | `ast` extension — Tree-sitter outline and symbol search for Rust, Go, PHP |
| **Code intelligence** | `lsp` extension — diagnostics, definition, references, hover via a language-server bridge |
| **Standalone linting and fixes** | `lint` extension — on-demand diagnostics and structured fixes from configured external linters, using the same diagnostic shape as LSP |
| **Debugging** | `debug` extension — opt-in Debug Adapter Protocol sessions plus one-shot `tower_debug_eval_at` probes for breakpoint evidence capture |
| **Debugging** | `debug` extension — opt-in Debug Adapter Protocol sessions, one-shot `tower_debug_eval_at` probes, and rr-backed record/replay reverse debugging |
| **Single static binary** | No WASM, WASI SDK, JVM, Node, or container required at runtime |

---
Expand Down Expand Up @@ -180,8 +180,8 @@ tests can locate sidecars under `target/debug/`. There is no WASM build step and
|---|---|
| [`docs/getting-started.md`](docs/getting-started.md) | Prerequisites, build, quality gate, first MCP session |
| [`docs/architecture.md`](docs/architecture.md) | Hexagonal boundary, crate layout, ports, data flow, design decisions |
| [`docs/mcp-tools.md`](docs/mcp-tools.md) | Full MCP tool reference — wire protocol, the native tools, extension tools including lint fix, interactive debug sessions, and `tower_debug_eval_at`, error codes |
| [`docs/user-guide/debug-sessions.md`](docs/user-guide/debug-sessions.md) | How to configure and drive interactive Debug Adapter Protocol sessions and one-shot `tower_debug_eval_at` probes |
| [`docs/mcp-tools.md`](docs/mcp-tools.md) | Full MCP tool reference — wire protocol, the native tools, extension tools including lint fix, interactive debug sessions, rr record/replay reverse debugging, and error codes |
| [`docs/user-guide/debug-sessions.md`](docs/user-guide/debug-sessions.md) | How to configure and drive interactive Debug Adapter Protocol sessions, one-shot `tower_debug_eval_at` probes, and rr-backed reverse-debug workflows |
| [`docs/user-guide/lint-fixes.md`](docs/user-guide/lint-fixes.md) | How to preview and apply structured linter fixes safely with `tower_lint_fix` |
| [`docs/extensions.md`](docs/extensions.md) | Extension authoring guide — native sidecars, the JSON-RPC protocol, capabilities, manifest, fault model |
| [`docs/development.md`](docs/development.md) | Contributing, TDD workflow, CI pipeline, test conventions |
Expand Down
Loading
Loading