weavatrix 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -14
- package/SECURITY.md +14 -0
- package/docs/agent-task-benchmark.md +58 -0
- package/docs/releases/v0.2.7.md +93 -0
- package/package.json +6 -1
- package/scripts/run-agent-task-benchmark.mjs +119 -0
- package/skill/SKILL.md +31 -10
- package/src/analysis/allowed-test-runner.js +59 -0
- package/src/analysis/data-flow-evidence.js +114 -0
- package/src/analysis/dead-code-review.js +51 -0
- package/src/analysis/dep-check.js +42 -3
- package/src/analysis/duplicate-groups.js +84 -0
- package/src/analysis/graph-analysis.aggregate.js +3 -1
- package/src/analysis/graph-analysis.refs.js +19 -11
- package/src/analysis/hot-path-review.js +20 -2
- package/src/analysis/internal-audit.run.js +6 -1
- package/src/analysis/task-retrieval.js +116 -0
- package/src/bounds.js +4 -0
- package/src/graph/builder/lang-js.js +52 -17
- package/src/graph/freshness-probe.js +4 -2
- package/src/graph/incremental-refresh.js +4 -2
- package/src/graph/internal-builder.barrels.js +39 -2
- package/src/graph/internal-builder.build.js +58 -12
- package/src/mcp/catalog.mjs +28 -6
- package/src/mcp/graph-context.mjs +5 -1
- package/src/mcp/graph-diff.mjs +1 -1
- package/src/mcp/sync-payload.mjs +1 -1
- package/src/mcp/tools-actions.mjs +3 -1
- package/src/mcp/tools-context.mjs +164 -0
- package/src/mcp/tools-graph.mjs +48 -3
- package/src/mcp/tools-health.mjs +15 -28
- package/src/mcp/tools-impact-change.mjs +1 -0
- package/src/mcp/tools-source.mjs +7 -6
- package/src/mcp/tools-verified-change.mjs +169 -0
- package/src/precision/lsp-client.js +1 -1
- package/src/precision/lsp-overlay.js +1 -5
- package/src/precision/symbol-query.js +1 -5
- package/src/security/malware-heuristics.exclusions.js +3 -3
- package/src/security/malware-heuristics.roots.js +4 -1
- package/src/security/malware-heuristics.scan.js +4 -2
- package/src/security/malware-scoring.js +22 -5
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
Grep sees text. Weavatrix sees structure. It builds a dependency graph of any local repository —
|
|
6
6
|
files, symbols, and the imports/calls/inheritance connecting them — and serves it to Claude Code,
|
|
7
7
|
Codex, or any MCP client: change impact, transitive dependents, health audit, clone detection,
|
|
8
|
-
coverage mapping. **
|
|
8
|
+
coverage mapping. **36 tools available; 33 enabled by the default offline profile. Local-first: with
|
|
9
9
|
the defaults, no repository data leaves your machine.**
|
|
10
10
|
|
|
11
11
|
- Website: [weavatrix.com](https://weavatrix.com)
|
|
@@ -22,12 +22,18 @@ answers grep can't produce:
|
|
|
22
22
|
depends on them — with test coverage attached, so the **untested part of the blast radius** stands
|
|
23
23
|
out before you ship.
|
|
24
24
|
- *"Who calls this function?"* → `inspect_symbol` returns exact bounded TS/JS occurrences plus
|
|
25
|
-
source context; `
|
|
25
|
+
source context; `context_bundle` adds grouped graph relations, exact re-export sites, and a
|
|
26
|
+
smaller source workset. `get_dependents` walks the symbol-level reverse graph transitively. Opt into
|
|
26
27
|
`include_container_importers:true` only when a broader module-import radius is intended.
|
|
27
28
|
- *"Did my refactor actually decouple anything?"* → `graph_diff base_ref=HEAD~1` builds an immutable
|
|
28
29
|
baseline graph without checking it out, then reports the structural delta: new module
|
|
29
30
|
dependencies, broken or introduced import cycles, and symbols that lost their last caller.
|
|
30
31
|
|
|
32
|
+
- *"Is this change actually safe?"* -> `verified_change` accepts the task plus current diff/files and
|
|
33
|
+
returns one proof-carrying `PASS`, `BLOCKED`, or `UNKNOWN`: compact edit contexts, exact-symbol
|
|
34
|
+
impact, bounded call-argument flow, Git graph drift, architecture/duplicate/API ratchets, and
|
|
35
|
+
affected-test evidence.
|
|
36
|
+
|
|
31
37
|
## Quick start
|
|
32
38
|
|
|
33
39
|
Requires Node ≥ 18. One command:
|
|
@@ -107,10 +113,11 @@ An agent skill with recipes ships in [skill/SKILL.md](skill/SKILL.md) — instal
|
|
|
107
113
|
|
|
108
114
|
**graph** — `graph_stats`, `get_node`, `get_neighbors`, `query_graph`, `god_nodes`,
|
|
109
115
|
`shortest_path`, `get_community`, `list_communities`, `module_map`, `get_dependents`,
|
|
110
|
-
`change_impact`, `git_history`, `graph_diff`, `get_architecture_contract`,
|
|
116
|
+
`change_impact`, `verified_change`, `git_history`, `graph_diff`, `get_architecture_contract`,
|
|
111
117
|
`prepare_change`. Runtime dependencies, TypeScript type-only coupling and language
|
|
112
118
|
compile-only edges (Rust module/use, Java imports) are reported separately where that distinction
|
|
113
|
-
changes the result.
|
|
119
|
+
changes the result. TypeScript type-space and value-space declarations keep distinct identities;
|
|
120
|
+
classes and enums that inhabit both spaces are labelled `both`.
|
|
114
121
|
|
|
115
122
|
Every current edge carries versioned provenance. The parser emits `EXTRACTED`, `RESOLVED`, and
|
|
116
123
|
`INFERRED`; the built-in bounded TypeScript/JavaScript precision overlay upgrades only references
|
|
@@ -118,7 +125,7 @@ confirmed by its bundled `typescript-language-server` + TypeScript runtime to `E
|
|
|
118
125
|
`CONFLICT` means evidence disagrees. `graph_stats` reports the provenance breakdown and the semantic
|
|
119
126
|
provider's `COMPLETE`, `PARTIAL`, `UNAVAILABLE`, or `OFF` state; `OFF` means precision was explicitly
|
|
120
127
|
disabled and only static evidence is active. Java and Rust language-server providers are not bundled
|
|
121
|
-
in 0.2.
|
|
128
|
+
in 0.2.7: their edges never become `EXACT_LSP`, even when a mixed repository reports a complete
|
|
122
129
|
TypeScript/JavaScript overlay.
|
|
123
130
|
|
|
124
131
|
The bounded JS/TS provider is enabled by default for new graphs. Set `WEAVATRIX_PRECISION=off`
|
|
@@ -127,13 +134,15 @@ before starting the MCP server for parser-only operation from the first build, o
|
|
|
127
134
|
choice as **TypeScript/JavaScript semantic precision**.
|
|
128
135
|
|
|
129
136
|
**search / source** — `search_code` (ripgrep-backed, pure-Node fallback), `read_source` (a
|
|
130
|
-
symbol's actual code in one hop), `
|
|
131
|
-
|
|
137
|
+
symbol's actual code in one hop), `context_bundle` (definition plus grouped inbound/outbound
|
|
138
|
+
containers, exact re-export sites and a few bounded source excerpts), `inspect_symbol` (one exact
|
|
139
|
+
bounded TS/JS reference query, logical containers, impact and source excerpts), `list_endpoints` (HTTP route inventory:
|
|
132
140
|
Express/Fastify/Nest/Flask/FastAPI/Go mux/Rust axum and actix-web …)
|
|
133
141
|
|
|
134
142
|
**health** — `find_dead_code` (bounded review queue for statically unreferenced and test-only files,
|
|
135
|
-
functions, methods, and symbols, with
|
|
136
|
-
|
|
143
|
+
functions, methods, and symbols, with evidence tiers, completed/remaining verification and explicit
|
|
144
|
+
public/framework/dynamic caveats),
|
|
145
|
+
`run_audit` (unused files/exports/dependencies with per-finding manifest/indexed-source/script/config verification,
|
|
137
146
|
missing npm/Go/Python deps, runtime
|
|
138
147
|
cycles, type-only/compile-only coupling, orphans, boundary rules, offline OSV vulnerabilities + typosquat +
|
|
139
148
|
lockfile drift; accepts an immutable `base_ref`, `changed_files`, and `debt: new|existing|all` for
|
|
@@ -146,7 +155,9 @@ with separate graph/test risk), `verify_architecture`,
|
|
|
146
155
|
`hot_path_review` ranks production symbols using parser-derived local time, memory, cyclomatic and
|
|
147
156
|
call-site facts plus exact inside-loop allocation, copy, scan, sort and recursion evidence. Graph
|
|
148
157
|
fan-in/fan-out and measured coverage (or explicitly labelled static test reachability) remain
|
|
149
|
-
separate from local syntax cost.
|
|
158
|
+
separate from local syntax cost. Its focused default uses `min_score:85` plus a narrow strong-local
|
|
159
|
+
fallback; pass `min_score:0` only when the full diagnostic queue is wanted. The ranking is not
|
|
160
|
+
profiler data or interprocedural Big-O.
|
|
150
161
|
|
|
151
162
|
**build** — `rebuild_graph` (reports the structural delta, keeps the prior state as
|
|
152
163
|
`graph.prev.json`)
|
|
@@ -157,7 +168,8 @@ use `kinds:["method"]` or a `path` prefix to narrow it. `min_confidence:"low"` e
|
|
|
157
168
|
public APIs and framework/dynamic/reflection-sensitive candidates with their warnings. For repository
|
|
158
169
|
maintenance or branch debt, pair it with `run_audit category=unused debt=all` (or add an immutable
|
|
159
170
|
`base_ref` with `debt=new`) to cover unused files, exports and dependencies. Neither tool authorizes
|
|
160
|
-
deletion:
|
|
171
|
+
deletion: `STRONG_STATIC_EVIDENCE` means an exact zero-reference result, not permission to remove;
|
|
172
|
+
follow each candidate's `remainingChecks`, then inspect source/dependents/configuration and run tests.
|
|
161
173
|
|
|
162
174
|
`graph_diff` accepts `base_ref` (`HEAD~1`, `main`, `origin/main`, or another local Git ref) for a
|
|
163
175
|
fresh baseline comparison. Without it, the tool compares against `graph.prev.json` saved by the last
|
|
@@ -169,6 +181,14 @@ manifest, alias, ignore/config, non-JS/TS, or unsafe merge cases deliberately fa
|
|
|
169
181
|
rebuild. The result says whether freshness was `none`, `incremental`, or `full`. Graph artifacts stay
|
|
170
182
|
in the per-user cache and never need to be committed to Git.
|
|
171
183
|
|
|
184
|
+
`verified_change` is read-only by default. It may run only explicitly requested `package.json`
|
|
185
|
+
scripts whose names are allowlisted as test/check/verify scripts, and only when both
|
|
186
|
+
`run_tests:true` and `WEAVATRIX_ALLOW_TEST_RUNS=1` are present. It never accepts an arbitrary shell
|
|
187
|
+
command. Cross-repository API proof is used only when the active profile includes `crossrepo`;
|
|
188
|
+
without a configured architecture contract or complete evidence, the result is `UNKNOWN`, not a
|
|
189
|
+
cosmetic pass. Its data-flow section maps bounded JS/TS call arguments to callee parameters; it is
|
|
190
|
+
not CFG, value-propagation, or taint analysis.
|
|
191
|
+
|
|
172
192
|
**retarget** *(included in `offline`; absent from `pinned`; every switch is an explicit local call)* —
|
|
173
193
|
`open_repo`, `list_known_repos`; changes the active repository boundary
|
|
174
194
|
|
|
@@ -179,8 +199,11 @@ in the per-user cache and never need to be committed to Git.
|
|
|
179
199
|
entry points. Resolved explicit seeds are exclusive by default; set `augment_seeds:true` only when
|
|
180
200
|
question-derived seeds are also wanted. Broad bootstrap/tool-execution/routing questions now rank
|
|
181
201
|
conventional executables and graph-declared production entry points ahead of site, documentation, benchmark
|
|
182
|
-
and fixture matches.
|
|
183
|
-
|
|
202
|
+
and fixture matches. Production-first classification also applies during traversal, so unrelated
|
|
203
|
+
tests/generated/docs/benchmarks do not leak back from a production seed; name a class in the
|
|
204
|
+
question or set `include_classified:true` to include it. Unreferenced unmatched constant/field leaves
|
|
205
|
+
are hidden unless `include_low_signal:true`. Broad ranking remains orientation evidence; use
|
|
206
|
+
`seed_files` when the intended entry point is already known.
|
|
184
207
|
|
|
185
208
|
**advisories** *(network, explicit opt-in)* — `refresh_advisories`
|
|
186
209
|
|
|
@@ -193,6 +216,46 @@ disclosed instead of silently guessed; and the server **hot-reloads its watched
|
|
|
193
216
|
modules and catalog** when those files change — other MCP helpers and analysis engines require a
|
|
194
217
|
reconnect.
|
|
195
218
|
|
|
219
|
+
### 0.2.7 verified-change workflow
|
|
220
|
+
|
|
221
|
+
- New `verified_change` composes task retrieval, exact symbol context, change impact, immutable Git
|
|
222
|
+
graph comparison, architecture/duplicate/API ratchets, and targeted-test evidence behind one
|
|
223
|
+
`PASS` / `BLOCKED` / `UNKNOWN` contract.
|
|
224
|
+
- Intent-expanded graph retrieval is combined with exact changed-symbol seeds. A bounded JS/TS
|
|
225
|
+
interprocedural layer records call arguments and their callee parameters without claiming CFG or
|
|
226
|
+
taint completeness.
|
|
227
|
+
- Test execution is a double opt-in and limited to existing test/check/verify package scripts;
|
|
228
|
+
default operation remains read-only.
|
|
229
|
+
- Malware scanning now sweeps installed npm package roots instead of package-manager caches or
|
|
230
|
+
hosted release snapshots. Static heuristic findings are capped at `high`, expose unverified
|
|
231
|
+
execution/origin/lockfile/exposure state, and no longer prescribe secret rotation unless execution
|
|
232
|
+
or credential exposure has actually been confirmed.
|
|
233
|
+
- `query_graph` and `verified_change` task retrieval now enforce production-first classification
|
|
234
|
+
through traversal/selection while retaining exact changed or pinned non-product symbols; query
|
|
235
|
+
output also suppresses unmatched constant/field leaves. `hot_path_review` defaults to a focused
|
|
236
|
+
85-point queue, while `min_score:0` remains the explicit full-diagnostic mode.
|
|
237
|
+
- Dead-code candidates now carry evidence tiers and remaining checks; dependency findings carry
|
|
238
|
+
per-finding manifest plus indexed-source/script/config verification without authorizing removal.
|
|
239
|
+
- `npm run benchmark:agent` reports routing success, false positives, token estimate and latency.
|
|
240
|
+
Codebase Memory and Serena results stay explicitly `MISSING` until independently collected data is
|
|
241
|
+
supplied under the [blind agent-change protocol](docs/agent-task-benchmark.md);
|
|
242
|
+
`benchmark:agent:release` fails closed without same-task change success, FP, token, and time results.
|
|
243
|
+
|
|
244
|
+
Full patch notes: [docs/releases/v0.2.7.md](docs/releases/v0.2.7.md).
|
|
245
|
+
|
|
246
|
+
### 0.2.6 compact-context and TypeScript identity patch
|
|
247
|
+
|
|
248
|
+
- New `context_bundle` turns a symbol into a bounded workset: definition, grouped inbound/outbound
|
|
249
|
+
containers, reference evidence, exact re-export locations and a small number of source excerpts.
|
|
250
|
+
- Re-export records retain their concrete file, line, alias, specifier, type-only flag and resolved
|
|
251
|
+
origin. Barrel propagation through `export *` stays exact and private declarations are not exposed.
|
|
252
|
+
- TypeScript interfaces and type aliases are first-class type-space nodes. Same-named runtime values
|
|
253
|
+
keep separate identities, while classes and enums are explicitly marked as inhabiting both spaces.
|
|
254
|
+
- Graph schema v5 and freshness gates rebuild older caches before these precision-sensitive results
|
|
255
|
+
are used. The changes remain local-only and add no runtime dependency.
|
|
256
|
+
|
|
257
|
+
Full patch notes: [docs/releases/v0.2.6.md](docs/releases/v0.2.6.md).
|
|
258
|
+
|
|
196
259
|
### 0.2.5 exact-symbol and graph-fidelity patch
|
|
197
260
|
|
|
198
261
|
- New `inspect_symbol` spends a bounded LSP query on one requested TS/JS declaration, groups exact
|
|
@@ -450,7 +513,7 @@ vulnerability findings. This is where each capability comes from and how it is c
|
|
|
450
513
|
| Capability alert | Why it exists | Activation and boundary |
|
|
451
514
|
|---|---|---|
|
|
452
515
|
| Network access | `refresh_advisories` sends pinned package names and versions to OSV; `pull_architecture_contract` sends an opaque repository UUID and receives an owner-approved contract; `sync_graph` sends a normalized repository label plus an allowlisted graph/evidence payload. Evidence is derived locally from source and manifests, but source bodies, snippets, absolute paths, environment values, credentials and Git remotes are excluded | `offline` and `pinned` expose no network tools. `osv` exposes only advisory refresh. `hosted`/`full` expose all three; every request still requires an explicit tool call, and hosted calls require `WEAVATRIX_SYNC_URL` |
|
|
453
|
-
| Shell access | Local `git` powers staleness/change impact; `rg` accelerates search; the bundled TLS/tsserver process supplies bounded JS/TS semantic evidence; timed-out Windows child trees may be terminated
|
|
516
|
+
| Shell access | Local `git` powers staleness/change impact; `rg` accelerates search; the bundled TLS/tsserver process supplies bounded JS/TS semantic evidence; timed-out Windows child trees may be terminated; `verified_change` can optionally run an existing package test/check/verify script | The semantic provider never invokes repository code. Test execution separately requires `run_tests:true` plus `WEAVATRIX_ALLOW_TEST_RUNS=1`, rejects arbitrary commands and shell-sensitive arguments, and should be enabled only for trusted repository scripts |
|
|
454
517
|
| Debug / dynamic loading | Cache-busted `import()` hot-reloads watched MCP tool entry modules; `createRequire` loads package metadata and parser dependencies | Loads files from the installed package; no `eval` |
|
|
455
518
|
| Environment access | Reads `WEAVATRIX_*` configuration; ordinary local helpers inherit a credential-stripped environment, while TLS/tsserver receives only allowlisted OS/temp/locale values and a constrained executable path | `WEAVATRIX_SYNC_TOKEN` is removed from every child-process and worker environment. TLS/tsserver also receives no registry/proxy/cloud credentials or `NODE_OPTIONS` |
|
|
456
519
|
| Filesystem access | Reads the active repository, graph, lockfiles and coverage reports; writes derived graphs and advisory/architecture caches | Realpath containment blocks traversal and symlink/junction escapes. The `pinned` profile removes `open_repo`; the default `offline` profile permits only explicit local switching. The optional malware dependency scan may inspect installed dependency caches such as GOPATH |
|
package/SECURITY.md
CHANGED
|
@@ -28,6 +28,11 @@ dependency caches such as GOPATH. `offline` permits repository switching only th
|
|
|
28
28
|
local `open_repo` call; select `pinned` to remove that tool, the global repository listing, and
|
|
29
29
|
cross-repository API tracing, holding a hard startup-repository boundary.
|
|
30
30
|
|
|
31
|
+
Installed-package malware pattern matching is static heuristic evidence. It cannot confirm execution,
|
|
32
|
+
package compromise, or credential exposure and therefore cannot emit `critical`; heuristic severity
|
|
33
|
+
is capped at `high` with explicit `NOT_VERIFIED` runtime/origin/lockfile/exposure fields. Independently
|
|
34
|
+
confirmed malicious-package advisories remain separate vulnerability evidence and may be critical.
|
|
35
|
+
|
|
31
36
|
The JS/TS precision overlay is enabled by default for new graphs and runs the package-pinned `typescript-language-server` and
|
|
32
37
|
TypeScript runtime as local child processes. It never resolves a repository executable, invokes
|
|
33
38
|
`npx`, runs package scripts, or installs dependencies. Automatic type acquisition is disabled, and
|
|
@@ -46,6 +51,15 @@ bounded graph-work drain, and closes or tree-terminates TLS/tsserver before exit
|
|
|
46
51
|
Set `WEAVATRIX_PRECISION=off` before server startup (or select `off` in the MCPB semantic-precision
|
|
47
52
|
setting) to keep new graphs parser-only from their first build.
|
|
48
53
|
|
|
54
|
+
`verified_change` is read-only by default. Its optional targeted-test step can execute only an
|
|
55
|
+
existing `package.json` script whose name matches the bounded test/check/verify allowlist. The call
|
|
56
|
+
must set `run_tests:true` and the server operator must separately set
|
|
57
|
+
`WEAVATRIX_ALLOW_TEST_RUNS=1`; otherwise no repository script runs. The tool accepts no command or
|
|
58
|
+
shell string, caps scripts/arguments/time, rejects shell-sensitive argument characters, and launches
|
|
59
|
+
the selected package-manager script with the credential-stripped child environment. Repository test
|
|
60
|
+
scripts are repository-controlled code and may have arbitrary side effects, so enable this flag only
|
|
61
|
+
for repositories and scripts you trust.
|
|
62
|
+
|
|
49
63
|
Network capabilities are split by purpose. `osv` adds only `refresh_advisories`, which sends pinned
|
|
50
64
|
package names and versions to OSV.dev when called. `hosted` / `full` also expose `sync_graph` and
|
|
51
65
|
`pull_architecture_contract`; both require a user-configured endpoint, and contract pull requires
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Independent agent-change benchmark
|
|
2
|
+
|
|
3
|
+
The 0.2.7 release includes two deliberately separate measurements.
|
|
4
|
+
|
|
5
|
+
`npm run benchmark:agent` is a deterministic local routing microbenchmark. It measures whether the
|
|
6
|
+
task retriever selects the expected symbol, plus false-positive selections, estimated output tokens,
|
|
7
|
+
and local latency. It is a regression test, not evidence that an autonomous code change succeeded.
|
|
8
|
+
|
|
9
|
+
The release comparison is an independently executed, blind agent-change benchmark. The evaluator
|
|
10
|
+
must run the same pinned tasks and repository commits three times: with Weavatrix, with Codebase
|
|
11
|
+
Memory, and with Serena. The product author must not adjudicate or repair a run while it is active.
|
|
12
|
+
|
|
13
|
+
## Required task protocol
|
|
14
|
+
|
|
15
|
+
Each task must provide a repository commit, natural-language request, allowed commands, timeout, and
|
|
16
|
+
machine-verifiable acceptance tests. Keep task prompts and acceptance tests identical across systems;
|
|
17
|
+
randomize system order. Record the entire agent input/output token count and wall-clock duration.
|
|
18
|
+
|
|
19
|
+
A run is successful only when the requested behavior is implemented, all acceptance tests pass, and
|
|
20
|
+
the final diff stays inside the task scope. A false positive is an evidenced warning, impacted symbol,
|
|
21
|
+
or required edit that an evaluator confirms is unrelated to the task. Record a count, including zero;
|
|
22
|
+
do not silently discard noisy output.
|
|
23
|
+
|
|
24
|
+
Use a mix of at least:
|
|
25
|
+
|
|
26
|
+
- behavior changes with indirect callers;
|
|
27
|
+
- API route/client changes;
|
|
28
|
+
- refactors with a duplicate or architecture regression trap;
|
|
29
|
+
- changes whose nearest relevant test is not in the edited file;
|
|
30
|
+
- one negative task where the correct action is to refuse or return unknown.
|
|
31
|
+
|
|
32
|
+
## Result contract
|
|
33
|
+
|
|
34
|
+
Save the blind evaluator output as JSON:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"schemaVersion": "weavatrix.agent-change-results.v1",
|
|
39
|
+
"evaluator": "independent organization or person",
|
|
40
|
+
"systems": {
|
|
41
|
+
"weavatrix": {"runs": [{"taskId": "change-auth", "success": true, "falsePositives": 0, "tokens": 1234, "durationMs": 4567}]},
|
|
42
|
+
"codebase-memory": {"runs": [{"taskId": "change-auth", "success": true, "falsePositives": 1, "tokens": 1400, "durationMs": 5000}]},
|
|
43
|
+
"serena": {"runs": [{"taskId": "change-auth", "success": false, "falsePositives": 2, "tokens": 1600, "durationMs": 7000}]}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Every system must contain the same unique task IDs. Every run must report success, false positives,
|
|
49
|
+
tokens, and duration. Then run:
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
npm run benchmark:agent -- --independent-results path/to/results.json
|
|
53
|
+
npm run benchmark:agent:release -- --independent-results path/to/results.json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The first command reports change-success rate, false positives per task, median tokens, and median
|
|
57
|
+
duration for all three systems. The release command fails unless the independent comparison is
|
|
58
|
+
complete and valid. Missing or malformed competitor data is `INCOMPLETE`, never a green comparison.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Weavatrix 0.2.7
|
|
2
|
+
|
|
3
|
+
## Proof-carrying changes
|
|
4
|
+
|
|
5
|
+
`verified_change` is a new high-level MCP workflow for planning and verifying a code change. It
|
|
6
|
+
accepts a natural-language task, an optional unified diff or changed-file hints, and an immutable Git
|
|
7
|
+
baseline. Its stable result is one of:
|
|
8
|
+
|
|
9
|
+
- `PASS`: every applicable enabled proof completed and no ratchet failed;
|
|
10
|
+
- `BLOCKED`: a test failed, a new duplicate intersects changed code, a runtime cycle appeared, an
|
|
11
|
+
architecture ratchet failed, or bounded API evidence found an HTTP method mismatch;
|
|
12
|
+
- `UNKNOWN`: required evidence is missing, partial, disabled, or not configured.
|
|
13
|
+
|
|
14
|
+
The structured result contains intent-expanded task retrieval combined with exact changed-symbol
|
|
15
|
+
seeds, up to five compact LSP/graph edit contexts, symbol-aware blast radius, affected-test paths,
|
|
16
|
+
bounded JS/TS call-argument-to-parameter evidence, Git graph drift, architecture verification, a
|
|
17
|
+
new-duplicate baseline comparison, and optional cross-repository HTTP contract evidence.
|
|
18
|
+
|
|
19
|
+
The workflow respects the existing capability boundary. Exact source/LSP context requires `source`,
|
|
20
|
+
duplicate comparison and architecture verification require `health`, and API tracing requires
|
|
21
|
+
`crossrepo`. A narrow custom profile is never silently bypassed.
|
|
22
|
+
|
|
23
|
+
## Safe targeted tests
|
|
24
|
+
|
|
25
|
+
The workflow does not accept shell commands. It can execute at most five existing `package.json`
|
|
26
|
+
scripts whose names match the test/check/verify allowlist. Execution requires both
|
|
27
|
+
`run_tests:true` on the tool call and `WEAVATRIX_ALLOW_TEST_RUNS=1` in the server environment. The
|
|
28
|
+
default remains read-only and returns the test plan or `UNKNOWN` when runtime evidence was requested
|
|
29
|
+
but not authorized.
|
|
30
|
+
|
|
31
|
+
## Malware scanner correction
|
|
32
|
+
|
|
33
|
+
The npm content sweep now starts at actual installed package roots instead of the entire
|
|
34
|
+
`node_modules` container. Hidden package-manager caches and hosted release snapshots are therefore
|
|
35
|
+
not attributed as dependencies and cannot make Weavatrix flag its own malware-signature source.
|
|
36
|
+
|
|
37
|
+
Heuristic remediation no longer says to treat a package as compromised or rotate all reachable
|
|
38
|
+
secrets. It asks the operator to quarantine and inspect the package, verify origin and lockfile
|
|
39
|
+
integrity, and rotate secrets only after execution or credential exposure is confirmed.
|
|
40
|
+
|
|
41
|
+
Static heuristic findings now have a hard `high` severity ceiling. They expose
|
|
42
|
+
`confirmedExecution:false` plus explicit runtime/origin/lockfile/exposure verification states;
|
|
43
|
+
`critical` is reserved for independently confirmed malicious advisories or runtime evidence.
|
|
44
|
+
|
|
45
|
+
Package-lock install-script drift now compares only `preinstall`, `install`, and `postinstall`.
|
|
46
|
+
Development/publication hooks such as `prepare` no longer create false high-severity drift findings.
|
|
47
|
+
|
|
48
|
+
## Signal-quality corrections
|
|
49
|
+
|
|
50
|
+
- `query_graph` applies production-first path classification to the traversal, not only seed
|
|
51
|
+
selection. Tests, generated code, fixtures, docs, benchmarks and excluded paths require an
|
|
52
|
+
explicit question class or `include_classified:true`. Exact non-product seed files remain usable.
|
|
53
|
+
- `verified_change` task retrieval uses the same production-first policy while always retaining
|
|
54
|
+
exact changed symbols. The bundled routing microbenchmark moved from one test-symbol false
|
|
55
|
+
positive (`0.25`) to zero (`0`) without losing any of its three expected production targets.
|
|
56
|
+
- Unreferenced constant/field leaves that do not match the query are hidden by default; use
|
|
57
|
+
`include_low_signal:true` for diagnostic expansion.
|
|
58
|
+
- `hot_path_review` now defaults to a focused score gate of 85 plus a narrow strong-local fallback.
|
|
59
|
+
On the 0.2.7 source tree this reduced the default queue from 717 diagnostic candidates to 116 of
|
|
60
|
+
1,043 analyzed symbols; `min_score:0` restores the full diagnostic set.
|
|
61
|
+
- `find_dead_code` adds `STRONG_STATIC_EVIDENCE`, `BOUNDED_STATIC_EVIDENCE`, and
|
|
62
|
+
`HIGH_UNCERTAINTY` tiers, structured completed/remaining checks, and `autoDelete:false` on every
|
|
63
|
+
candidate. Strong static evidence means exact zero LSP references, not permission to delete.
|
|
64
|
+
- npm unused/missing/duplicate dependency findings now carry manifest section, indexed-source,
|
|
65
|
+
script/config, package-scope and unresolved dynamic/plugin verification state. Unused dependencies
|
|
66
|
+
remain `REVIEW_REQUIRED`; missing dependencies retain the exact importing-file evidence.
|
|
67
|
+
|
|
68
|
+
## Benchmark contract
|
|
69
|
+
|
|
70
|
+
`npm run benchmark:agent` runs a deterministic task-to-symbol routing microbenchmark and reports task
|
|
71
|
+
success, false-positive rate, estimated output tokens, and duration. This is intentionally labelled
|
|
72
|
+
as a routing microbenchmark, not an autonomous end-to-end change benchmark.
|
|
73
|
+
|
|
74
|
+
Independent Codebase Memory and Serena results may be supplied with
|
|
75
|
+
`--independent-results <json>` using the blind evaluator contract in
|
|
76
|
+
[`docs/agent-task-benchmark.md`](../agent-task-benchmark.md). Without same-task results for all three
|
|
77
|
+
systems, comparison status is `INCOMPLETE`; `npm run benchmark:agent:release` fails closed. The
|
|
78
|
+
repository does not manufacture competitor scores.
|
|
79
|
+
|
|
80
|
+
## Scope and limitations
|
|
81
|
+
|
|
82
|
+
- The interprocedural evidence maps call arguments to declared callee parameters for bounded JS/TS
|
|
83
|
+
graph call edges. It is not a CFG, value-propagation engine, or taint analysis.
|
|
84
|
+
- An absent architecture contract produces `UNKNOWN`; provisional budgets are guidance, not policy.
|
|
85
|
+
- A static path to a test is not proof that the test executed. A `PASS` that depends on runtime
|
|
86
|
+
behavior requires explicitly authorized test execution.
|
|
87
|
+
- API proof is optional and registry-scoped. No client match is `UNKNOWN`, never proof of no external
|
|
88
|
+
consumers.
|
|
89
|
+
|
|
90
|
+
## Tool catalog
|
|
91
|
+
|
|
92
|
+
0.2.7 exposes 36 MCP tools. The default offline profile exposes 33; pinned exposes 30. Network tools
|
|
93
|
+
remain absent from the offline and pinned profiles.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "weavatrix",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Weavatrix — code graph & blast-radius MCP server for AI coding agents: change impact, transitive dependents, health audit, duplicate detection, and coverage mapping over any local repository.",
|
|
6
6
|
"author": "Sergii Ziborov <sergii.ziborov@gmail.com>",
|
|
@@ -24,6 +24,9 @@
|
|
|
24
24
|
"bin",
|
|
25
25
|
"src",
|
|
26
26
|
"skill",
|
|
27
|
+
"scripts/run-agent-task-benchmark.mjs",
|
|
28
|
+
"docs/agent-task-benchmark.md",
|
|
29
|
+
"docs/releases/v0.2.7.md",
|
|
27
30
|
"README.md",
|
|
28
31
|
"SECURITY.md",
|
|
29
32
|
"LICENSE"
|
|
@@ -34,6 +37,8 @@
|
|
|
34
37
|
"benchmark:quick": "node scripts/run-benchmark.mjs --quick",
|
|
35
38
|
"benchmark:real": "node scripts/run-real-benchmark.mjs",
|
|
36
39
|
"benchmark:real:release": "node scripts/run-real-benchmark.mjs --require-all",
|
|
40
|
+
"benchmark:agent": "node scripts/run-agent-task-benchmark.mjs",
|
|
41
|
+
"benchmark:agent:release": "node scripts/run-agent-task-benchmark.mjs --require-independent",
|
|
37
42
|
"build:mcpb": "node scripts/build-mcpb.mjs",
|
|
38
43
|
"verify:release": "node scripts/verify-release.mjs"
|
|
39
44
|
},
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import {readFileSync} from 'node:fs'
|
|
2
|
+
import {pathToFileURL} from 'node:url'
|
|
3
|
+
import {performance} from 'node:perf_hooks'
|
|
4
|
+
import {retrieveTaskContext} from '../src/analysis/task-retrieval.js'
|
|
5
|
+
|
|
6
|
+
function graphFixture() {
|
|
7
|
+
const nodes = [
|
|
8
|
+
{id: 'src/auth/session.js#validateSession@10', label: 'validateSession()', source_file: 'src/auth/session.js', symbol_kind: 'function'},
|
|
9
|
+
{id: 'src/http/router.js#registerRoutes@20', label: 'registerRoutes()', source_file: 'src/http/router.js', symbol_kind: 'function'},
|
|
10
|
+
{id: 'src/cache/store.js#readCache@5', label: 'readCache()', source_file: 'src/cache/store.js', symbol_kind: 'function'},
|
|
11
|
+
{id: 'src/auth/session.test.js#sessionTest@3', label: 'sessionTest()', source_file: 'src/auth/session.test.js', symbol_kind: 'function'},
|
|
12
|
+
]
|
|
13
|
+
return {nodes, byId: new Map(nodes.map((node) => [node.id, node])), out: new Map(), inn: new Map()}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const CASES = [
|
|
17
|
+
{task: 'validate authentication session', expected: 'src/auth/session.js#validateSession@10'},
|
|
18
|
+
{task: 'register HTTP API routes', expected: 'src/http/router.js#registerRoutes@20'},
|
|
19
|
+
{task: 'read values from cache store', expected: 'src/cache/store.js#readCache@5'},
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
function competitorTemplate(name) {
|
|
23
|
+
return {name, status: 'MISSING', reason: 'supply same-task blind evaluator output with --independent-results <json>'}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function readCompetitors(path) {
|
|
27
|
+
if (!path) return {}
|
|
28
|
+
const parsed = JSON.parse(readFileSync(path, 'utf8'))
|
|
29
|
+
return parsed?.competitors && typeof parsed.competitors === 'object' ? parsed.competitors : {}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const SYSTEMS = ['weavatrix', 'codebase-memory', 'serena']
|
|
33
|
+
const median = (values) => {
|
|
34
|
+
const sorted = values.slice().sort((left, right) => left - right)
|
|
35
|
+
const middle = Math.floor(sorted.length / 2)
|
|
36
|
+
return sorted.length % 2 ? sorted[middle] : (sorted[middle - 1] + sorted[middle]) / 2
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function independentComparison(path) {
|
|
40
|
+
if (!path) return {status: 'MISSING', reason: 'supply blind evaluator output with --independent-results <json>'}
|
|
41
|
+
try {
|
|
42
|
+
const input = JSON.parse(readFileSync(path, 'utf8'))
|
|
43
|
+
if (input?.schemaVersion !== 'weavatrix.agent-change-results.v1') throw new Error('unsupported schemaVersion')
|
|
44
|
+
const taskSets = []
|
|
45
|
+
const metrics = {}
|
|
46
|
+
for (const name of SYSTEMS) {
|
|
47
|
+
const runs = input.systems?.[name]?.runs
|
|
48
|
+
if (!Array.isArray(runs) || !runs.length) throw new Error(`${name} has no runs`)
|
|
49
|
+
const ids = runs.map((run) => String(run.taskId || '')).sort()
|
|
50
|
+
if (ids.some((id) => !id) || new Set(ids).size !== ids.length) throw new Error(`${name} task IDs are missing or duplicated`)
|
|
51
|
+
for (const run of runs) {
|
|
52
|
+
if (typeof run.success !== 'boolean' || !Number.isFinite(run.falsePositives) || !Number.isFinite(run.tokens) || !Number.isFinite(run.durationMs)) {
|
|
53
|
+
throw new Error(`${name}/${run.taskId || '?'} has incomplete metrics`)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
taskSets.push(ids.join('\0'))
|
|
57
|
+
metrics[name] = {
|
|
58
|
+
tasks: runs.length, changeSuccessRate: runs.filter((run) => run.success).length / runs.length,
|
|
59
|
+
falsePositiveRate: runs.reduce((sum, run) => sum + Math.max(0, run.falsePositives), 0) / runs.length,
|
|
60
|
+
medianTokens: median(runs.map((run) => run.tokens)), medianDurationMs: median(runs.map((run) => run.durationMs)),
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (new Set(taskSets).size !== 1) throw new Error('systems were not evaluated on the same task IDs')
|
|
64
|
+
return {status: 'COMPLETE', evaluator: String(input.evaluator || 'unspecified'), metrics}
|
|
65
|
+
} catch (error) {
|
|
66
|
+
return {status: 'INVALID', reason: error instanceof Error ? error.message : String(error)}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function runAgentTaskBenchmark({competitorResults, independentResults} = {}) {
|
|
71
|
+
const graph = graphFixture()
|
|
72
|
+
const started = performance.now()
|
|
73
|
+
const cases = CASES.map((item) => {
|
|
74
|
+
const semanticSeeds = graph.nodes.filter((node) => item.task.toLowerCase().split(/\W+/).some((word) => word.length > 3 && String(node.id).toLowerCase().includes(word)))
|
|
75
|
+
const result = retrieveTaskContext(graph, {task: item.task, semanticSeeds, maxSymbols: 2})
|
|
76
|
+
const selected = result.selected.map((entry) => entry.id)
|
|
77
|
+
return {task: item.task, expected: item.expected, selected, success: selected[0] === item.expected, falsePositives: selected.filter((id) => id !== item.expected).length}
|
|
78
|
+
})
|
|
79
|
+
const durationMs = performance.now() - started
|
|
80
|
+
const output = JSON.stringify(cases)
|
|
81
|
+
const imported = readCompetitors(competitorResults)
|
|
82
|
+
const independent = independentComparison(independentResults)
|
|
83
|
+
const competitors = independent.status === 'COMPLETE' ? {
|
|
84
|
+
'codebase-memory': {name: 'codebase-memory', status: 'COMPLETE', metrics: independent.metrics['codebase-memory']},
|
|
85
|
+
serena: {name: 'serena', status: 'COMPLETE', metrics: independent.metrics.serena},
|
|
86
|
+
} : {
|
|
87
|
+
'codebase-memory': imported['codebase-memory'] || competitorTemplate('codebase-memory'),
|
|
88
|
+
serena: imported.serena || competitorTemplate('serena'),
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
schemaVersion: 'weavatrix.agent-task-benchmark.v1',
|
|
92
|
+
scope: 'deterministic task-to-symbol routing microbenchmark; not an end-to-end autonomous change benchmark',
|
|
93
|
+
weavatrix: {
|
|
94
|
+
status: cases.every((item) => item.success) ? 'PASS' : 'FAIL', cases,
|
|
95
|
+
metrics: {
|
|
96
|
+
taskSuccessRate: cases.filter((item) => item.success).length / cases.length,
|
|
97
|
+
falsePositiveRate: cases.reduce((sum, item) => sum + item.falsePositives, 0) / Math.max(1, cases.reduce((sum, item) => sum + item.selected.length, 0)),
|
|
98
|
+
estimatedOutputTokens: Math.ceil(Buffer.byteLength(output) / 4), durationMs: Number(durationMs.toFixed(3)),
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
competitors, independentComparison: independent,
|
|
102
|
+
comparisonStatus: independent.status === 'COMPLETE' ? 'COMPLETE' : 'INCOMPLETE',
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function argument(name) {
|
|
107
|
+
const index = process.argv.indexOf(name)
|
|
108
|
+
return index >= 0 ? process.argv[index + 1] : null
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
112
|
+
const report = runAgentTaskBenchmark({
|
|
113
|
+
competitorResults: argument('--competitor-results'),
|
|
114
|
+
independentResults: argument('--independent-results'),
|
|
115
|
+
})
|
|
116
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`)
|
|
117
|
+
if ((process.argv.includes('--require-independent') || process.argv.includes('--require-competitors')) && report.comparisonStatus !== 'COMPLETE') process.exitCode = 1
|
|
118
|
+
if (report.weavatrix.status !== 'PASS') process.exitCode = 1
|
|
119
|
+
}
|
package/skill/SKILL.md
CHANGED
|
@@ -38,15 +38,20 @@ Start from the task, not from the complete tool list:
|
|
|
38
38
|
- **Review a branch/diff**: `change_impact` for changed-file blast radius; add
|
|
39
39
|
`graph_diff base_ref=<merge-base>` for structural drift, then drill into exact candidates with
|
|
40
40
|
`get_dependents` and `read_source`.
|
|
41
|
+
- **Plan or verify a serious change**: call `verified_change phase=plan` with the natural-language
|
|
42
|
+
task and current diff/files. After editing, call it again with `phase=verify` and an immutable
|
|
43
|
+
`base_ref`. Treat `UNKNOWN` as missing proof, not success; inspect its blockers and unknowns instead
|
|
44
|
+
of manually orchestrating the lower-level graph, context, impact, ratchet, and test tools.
|
|
41
45
|
- **Trace an API across repositories**: `list_known_repos` -> `trace_api_contract` with an explicit
|
|
42
46
|
backend and client list; inspect each `graphReconciliation.buildMode` before using the verdict.
|
|
43
|
-
- **Inspect exact symbol references**: start with `graph_stats`, then call `
|
|
44
|
-
exact node ID (or an unambiguous label)
|
|
45
|
-
|
|
47
|
+
- **Inspect exact symbol references**: start with `graph_stats`, then call `context_bundle` with an
|
|
48
|
+
exact node ID (or an unambiguous label) for a compact definition, grouped relations, exact
|
|
49
|
+
re-export sites and source workset. Use `inspect_symbol` when the raw bounded point query is needed;
|
|
50
|
+
it spends evidence beyond the broad overlay cap. Use `get_dependents` for transitive
|
|
46
51
|
graph impact and `find_dead_code` for bounded zero-reference
|
|
47
52
|
candidates. Treat `PARTIAL`, `UNAVAILABLE`, `OFF`, or zero exact edges as incomplete evidence, not
|
|
48
53
|
a compiler-exact result; `OFF` means the caller explicitly selected static-only mode. Java and Rust
|
|
49
|
-
providers are not bundled in 0.2.
|
|
54
|
+
providers are not bundled in 0.2.7, so their edges never become `EXACT_LSP` even when a mixed
|
|
50
55
|
repository has a complete TypeScript/JavaScript overlay.
|
|
51
56
|
- **Explore an architectural question**: use broad `query_graph` when entry points are unknown; its
|
|
52
57
|
bootstrap/tool-execution ranking prefers production executables over docs, sites and fixtures.
|
|
@@ -86,16 +91,20 @@ Start from the task, not from the complete tool list:
|
|
|
86
91
|
`.weavatrix.json` `classify.product`, for example `{"classify":{"product":["benchmarks/core/**"]}}`.
|
|
87
92
|
- **Architectural queries**: broad bootstrap/tool-execution/routing questions rank conventional
|
|
88
93
|
production and graph-declared entry points ahead of classified docs, sites, benchmarks and
|
|
89
|
-
fixtures.
|
|
90
|
-
|
|
94
|
+
fixtures. Production-first classification also applies during traversal. A class term in the
|
|
95
|
+
question enables only that class; `include_classified=true` enables all classified paths. Exact
|
|
96
|
+
non-product `seed_files` remain pinned. Unmatched unreferenced constant/field leaves are suppressed
|
|
97
|
+
unless `include_low_signal=true`. Inspect the returned seeds/policy before trusting the traversal.
|
|
91
98
|
- **Coverage**: `coverage_map` reads an existing report. `unavailable` means no supported report was
|
|
92
99
|
found, not 0% coverage; do not rank testing risk from that state.
|
|
93
100
|
- **Local hot paths**: `hot_path_review` ranks parser-derived local syntax cost and reports graph
|
|
94
101
|
fan-in/fan-out plus test evidence separately. `actualCoverage: NOT_AVAILABLE` is not zero coverage,
|
|
95
|
-
and the score is not profiler data or an interprocedural Big-O proof.
|
|
96
|
-
|
|
102
|
+
and the score is not profiler data or an interprocedural Big-O proof. The default queue uses
|
|
103
|
+
`min_score=85` plus a narrow strong-local fallback; use `min_score=0` only for full diagnostics.
|
|
104
|
+
Inspect its line evidence and measure runtime before scheduling a performance rewrite.
|
|
97
105
|
- **Audit completeness**: read `dependencyReport.status` plus its unused/missing counts, then
|
|
98
|
-
|
|
106
|
+
each npm finding's `verification` (manifest, indexed source, scripts/config, unresolved dynamic
|
|
107
|
+
usage), then `checks.osv.status` and `checks.malware.status`. A dependency result from a partial graph is not a
|
|
99
108
|
repository-wide clean zero. For OSV, `OK` is
|
|
100
109
|
complete for the recorded dependency fingerprint; `PARTIAL` is incomplete or stale,
|
|
101
110
|
`NOT_CHECKED` has no repository-specific result, and `ERROR` means the local check failed. Treat
|
|
@@ -120,8 +129,18 @@ Start from the task, not from the complete tool list:
|
|
|
120
129
|
`offline`, absent from `pinned`, and available in a custom registration only when `retarget` is
|
|
121
130
|
named. Concurrent non-mutating calls retain the graph/root snapshot with which they started.
|
|
122
131
|
|
|
132
|
+
- **Test execution is separately authorized**: `verified_change` only executes named
|
|
133
|
+
`package.json` test/check/verify scripts when the call has `run_tests:true` and the server was
|
|
134
|
+
started with `WEAVATRIX_ALLOW_TEST_RUNS=1`. It never accepts arbitrary shell commands. Without
|
|
135
|
+
both gates it returns a plan or `UNKNOWN` evidence state.
|
|
136
|
+
|
|
123
137
|
## Recipes
|
|
124
138
|
|
|
139
|
+
- **Proof-carrying refactor**: `verified_change task="..." phase=plan base_ref=<merge-base>` -> edit ->
|
|
140
|
+
`verified_change task="..." phase=verify base_ref=<same-ref> tests=[{"script":"test","args":[...]}]`.
|
|
141
|
+
Add `run_tests:true` only when test execution was authorized. `BLOCKED` means an evidenced ratchet
|
|
142
|
+
or test failure; `UNKNOWN` means at least one required proof is incomplete.
|
|
143
|
+
|
|
125
144
|
- **Orient in the configured repo**: `module_map` → `list_communities` → `god_nodes`. Hub ranking
|
|
126
145
|
is production-only by default; use `include_classified:true` only when tests/generated/build
|
|
127
146
|
surfaces are deliberately part of the question.
|
|
@@ -151,7 +170,9 @@ Start from the task, not from the complete tool list:
|
|
|
151
170
|
`run_audit category=unused debt=all` (or `base_ref=<merge-base> debt=new`) for unused exports and
|
|
152
171
|
dependencies. Before deletion, run `read_source`, `get_dependents`, exact `search_code`, inspect
|
|
153
172
|
framework discovery/annotations, package scripts, CLI/Docker/manifests, generated consumers and
|
|
154
|
-
test-only use, then run the repository tests. `
|
|
173
|
+
test-only use, then run the repository tests. Use `evidenceTier` and `remainingChecks` to order the
|
|
174
|
+
review; even `STRONG_STATIC_EVIDENCE` is exact zero-reference evidence, not deletion permission.
|
|
175
|
+
`REVIEW_REQUIRED` and `autoDelete:false` are hard
|
|
155
176
|
safety semantics, not boilerplate. Use `.weavatrix-deps.json` entrypoints/nonRuntimeRoots only for
|
|
156
177
|
verified conventions.
|
|
157
178
|
- **API inventory**: `list_endpoints` (including Next.js App Router, Rust axum and actix-web).
|