Controlled
Intervention.
The planned change commands – patches apply, symbols rename, and symbols move – share one mutation engine. For supported edits, the Double-Lock harness applies the parser-backed syntactic check and the language-server semantic check before the change is committed to disk. No proposal cycle, no human approval gate – the locks are the safety gate.
Synopsis
Planned targets: patches apply accepts a patch file with --file or standard input. symbols rename and symbols move use selector entry points: direct (--uri + --position, or an inline --query) and a typed stream via --selectors <path|->. For edits supported by the parser and language-server integration, the daemon plans in memory, runs both locks, and writes to disk only on success. Failures leave the filesystem untouched.
weaver <resource> <verb> [--dry-run] [FLAGS]
Commands
| Command | Input | Description |
|---|---|---|
| patches apply Planned | File / STDIN | Apply a Git-style patch via --file or stdin. Supports modify, create, and delete hunks, plus --dry-run. |
| symbols rename Planned | Selectors | Rename by position, inline --query, or piped --selectors -. Capability: symbol.rename. |
| symbols move Planned | Selectors | Move a symbol to another module (formerly extricate). Public verb move; internal capability extricate-symbol. Not an alias for extract-method. See the deep dive. |
| declared, unbuilt | — | Sibling capability identifiers extract-method, replace-body, and extract-predicate are declared in the contract but not implemented. They will not pretend otherwise. |
The "Birdcage" Sandbox
Code execution happens in an ephemeral environment using seccomp-bpf filters to prevent unauthorized syscalls.
Lock-Guarded Actuation
patches apply Planned
Point at a Git-style patch. The engine stages it against expected content versions, formats the staged files, runs both locks, and commits atomically – recording the transaction, digests, and rollback reference.
{"transaction":"txn_01j9...","changed":["src/lib.rs"],"verification":{"syntactic":"ok","semantic":"ok"},"diagnostics":{"introduced":0,"resolved":1}}
symbols rename (by query) Planned
An inline query selects the target; the routed actuator plans, the shared engine verifies through the Double-Lock, and disk changes happen only on success. A multi-match query is refused, with candidates listed – no command guesses whether a multi-match mutation is intended.
--query 'fn process_request($...ARGS)' \
--new-name run_request --json
{"transaction":"txn_01ja...","changed":["src/main.rs","src/handler.rs"],"verification":{"syntactic":"ok","semantic":"ok"},"diagnostics":{"introduced":0,"resolved":0}}
Common Failure Modes
The modified file failed Tree-sitter parsing. Structural error (e.g. unbalanced braces, missing semicolons).
syntactic lock failed: src/main.rs:42:5 syntax error
New diagnostics detected after the edit. The language server found type errors or unresolved references that were not present before.
semantic lock failed: 2 new error(s)
The file changed since the selectors were produced. Checked before planning and again immediately before commit; --force cannot erase this precondition.
stale source: src/lib.rs digest mismatch; re-run the query
A plugin attempted to access a path outside the sandbox allowlist. The child process is killed immediately.
Access denied: /etc/hosts
The Mutation Contract
One engine plans and commits every change, so every actuator inherits the same guarantees. Human and --json renderers read the same result.
Completion before actuation
An actuator reads or spools the complete selector stream and validates its completion record before planning anything. It never mutates while input is still arriving, and a producer failure never fakes a successful completion.
Explicit cardinality
Every actuator documents its policy for zero, one, several, and overlapping selectors. The defaults refuse ambiguity: a multi-match mutation requires the caller to say so.
Idempotent by construction
Idempotency keys, transaction identifiers, and retry matching survive a daemon restart. Resubmitting an equivalent request returns the existing transaction – or the existing refusal.
Honest no-ops
A mutation whose post-format result is byte-identical returns an explicit no-op, and repeated no-ops trip a circuit breaker. Formatting runs on staged files before verification; a formatter failure cannot touch the live workspace.
symbols move
Planned
Move a selected symbol into a different module while preserving behaviour. The detailed execution model documented here is Rust-specific: it covers impl blocks, use tree rewrites, and refusal cases such as non-preservable pub(in ...). Python remains a planned capability route, but its Rope-backed limits are not specified to the same depth yet.
Synopsis
weaver symbols move --uri <file:///...> --position <line:col> --to <module> [--dry-run]
Capability
Public verb move; internal capability extricate-symbol – deliberately not an alias for extract-method. Providers declare the capability in their plugin manifest; the daemon resolves the correct provider for the source file's language and keeps the provider's name out of the primary UX.
Providers
| Language | Plugin | Backend | Notes |
|---|---|---|---|
| Python | rope | Rope refactoring library | Planned capability route only. Current site docs do not define a Rope extrication contract beyond provider intent, so do not infer Rust-style module surgery for Python. |
| Rust | rust-analyzer | RA LSP + overlay transaction engine | Detailed design exists. Handles definition and reference planning, impl moves, use rewrites, and Rust-specific refusal cases. |
Orchestration Sequence
Validate arguments, resolve the selected definition, and collect pre-move references.
Start an in-memory overlay transaction. No filesystem writes until all checks pass.
Build move-set closure for the symbol and associated impl blocks. Apply edits to overlay.
Rewrite external references and use trees. Disambiguate imports via definition-equivalence probes.
Run semantic invariants: no new diagnostics, all reference probes resolve to the moved definition.
The provider returns a unified diff to the daemon on success. The daemon then commits the edit to disk and updates files_written only if both locks pass; on any failure it discards the overlay and returns diagnostics unchanged.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
| --uri | string | Yes | Source file URI containing the selected symbol. |
| --position | string | Yes | Source position in line:col form (LSP coordinates). |
| --to | string | Yes | Destination module path or file URI. |
| --create-missing-modules / --no-create-missing-modules | bool | No | Create missing destination modules. Default true; to disable, pass --no-create-missing-modules. |
| --explain | bool | No | Emit execution plan metadata in diagnostics output. |
Refusal Cases
The plugin refuses execution for non-deterministic or unsound cases. Each refusal returns precise diagnostics and leaves workspace content unchanged.
Items lacking stable editable source ranges cannot be moved safely.
Import repair without a unique semantic match is a hard error.
Non-preservable pub(in ...) constraints that cannot be maintained across modules.
File payload does not cover all files required for deterministic execution.
Trust, but Verify.
Ensure the actions taken produced the desired outcome.