weavatrix 0.2.11 → 0.2.13
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 +119 -0
- package/docs/releases/v0.2.13.md +48 -0
- package/package.json +2 -2
- package/skill/SKILL.md +78 -23
- package/src/analysis/allowed-test-runner.js +20 -9
- package/src/mcp/catalog.mjs +2 -0
- package/src/mcp/tools-graph.mjs +1 -0
- package/src/mcp/tools-verified-change.mjs +12 -4
- package/src/mcp-server.mjs +17 -3
- package/docs/releases/v0.2.11.md +0 -23
package/README.md
CHANGED
|
@@ -49,6 +49,100 @@ Weavatrix answers questions a text index cannot:
|
|
|
49
49
|
impact, bounded call-argument flow, Git graph drift, architecture/duplicate/API ratchets, and
|
|
50
50
|
affected-test evidence.
|
|
51
51
|
|
|
52
|
+
## Worked examples
|
|
53
|
+
|
|
54
|
+
These are representative sequences from local dogfooding, not fabricated chat transcripts. Counts
|
|
55
|
+
describe the observed repository snapshots and will move with the code.
|
|
56
|
+
|
|
57
|
+
### Understand an unfamiliar backend without reading it linearly
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
Question: Where does an attack-mitigation request go?
|
|
61
|
+
|
|
62
|
+
module_map
|
|
63
|
+
-> production territories and strongest module dependencies
|
|
64
|
+
list_endpoints
|
|
65
|
+
-> 462 routes observed in a 1,076-file backend snapshot
|
|
66
|
+
trace_endpoint
|
|
67
|
+
-> composed router mount -> controller -> service -> task/messaging
|
|
68
|
+
-> bounded call-site excerpts around decisive edges
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Use `module_map` for the initial application shape, then switch to the exact endpoint or symbol. Do
|
|
72
|
+
not lead with a broad natural-language `query_graph` when the route or identifier is already known.
|
|
73
|
+
|
|
74
|
+
### Check whether a backend handler is used by another repository
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
Question: Can this handler be removed?
|
|
78
|
+
|
|
79
|
+
list_known_repos -> trace_api_contract
|
|
80
|
+
backend endpoints observed: 163
|
|
81
|
+
client callsites joined: 267 across two registered clients
|
|
82
|
+
handler liveness: NOT_DEAD_EXTERNAL_USE
|
|
83
|
+
unresolved dynamic URLs: POSSIBLE_EXTERNAL_USE / UNKNOWN
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
This joins separately cached local graphs; it does not upload source. Medium/high-confidence
|
|
87
|
+
external use can keep a handler out of the dead-code queue, while dynamic or ambiguous calls remain
|
|
88
|
+
explicitly incomplete evidence.
|
|
89
|
+
|
|
90
|
+
### Change one method with an evidence trail
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
inspect_symbol -> context_bundle -> get_dependents -> coverage_map
|
|
94
|
+
-> edit the bounded workset
|
|
95
|
+
-> verified_change phase=verify base_ref=<merge-base>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
On an observed BranchPilot diff, `change_impact` separated removed methods/signatures from additive
|
|
99
|
+
exports and ranked a 98-node radius without collapsing runtime and type-only coupling. If measured
|
|
100
|
+
coverage, the architecture contract, or requested tests are missing, the final state is `UNKNOWN`,
|
|
101
|
+
not a cosmetic pass.
|
|
102
|
+
|
|
103
|
+
### Review Health and clone debt without auto-deleting code
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
run_audit category=dependencies debt=all
|
|
107
|
+
-> missing direct dependency (observed: mongodb)
|
|
108
|
+
-> lockfile drift and unresolved imports
|
|
109
|
+
run_audit debt=all
|
|
110
|
+
-> runtime cycles separated from compile/type-only coupling
|
|
111
|
+
find_duplicates
|
|
112
|
+
-> clone families and same-name divergence
|
|
113
|
+
-> homogeneous router boilerplate suppressed by default
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Every dead-code, orphan, dependency and duplicate item remains review evidence. Confirm framework
|
|
117
|
+
conventions and source use before editing; Weavatrix does not auto-delete or merge findings.
|
|
118
|
+
|
|
119
|
+
## Benchmarks
|
|
120
|
+
|
|
121
|
+
Two different gates ship in the repository:
|
|
122
|
+
|
|
123
|
+
- `npm run benchmark` is a reproducible golden suite for TypeScript, JavaScript, Python, Go, Java
|
|
124
|
+
and Rust, plus cross-repository HTTP matching, framework conventions and the MCP graph lifecycle.
|
|
125
|
+
- `npm run benchmark:real` compares revision-pinned local application snapshots with the checked-in
|
|
126
|
+
0.2.1 relation baseline. It fails on unexplained signal loss; `MISSING`, `STALE` and `UNBASELINED`
|
|
127
|
+
remain incomplete, not green.
|
|
128
|
+
|
|
129
|
+
Latest local release run (Windows x64, Node 24.15.0, July 18, 2026):
|
|
130
|
+
|
|
131
|
+
| Gate | Result | Selected evidence |
|
|
132
|
+
|---|---:|---|
|
|
133
|
+
| Six language fixtures | 6/6 PASS | exact symbols/edges and complete edge provenance |
|
|
134
|
+
| Cross-repo fixture | PASS, 431.79 ms cold | endpoint match, typed wrapper, external use, affected screen |
|
|
135
|
+
| Lifecycle | PASS | `full -> incremental -> none -> reconnect/none`; 1,376-byte text response |
|
|
136
|
+
| Total fixture cold build | 1.31 s | all six language graphs; 6.4 KB bounded report |
|
|
137
|
+
| Real-repository baseline | 6/6 PASS | TS, JS, Python, Go, Java and Rust snapshots |
|
|
138
|
+
|
|
139
|
+
Real snapshots ranged from 473 nodes / 1,165 edges in 0.22 s (Go) to 8,192 nodes / 21,814 edges
|
|
140
|
+
in 9.44 s (TypeScript). The Java snapshot built 7,143 nodes / 23,708 edges in 2.61 s, including
|
|
141
|
+
receiver-aware cross-file calls. These are regression measurements on one machine, not competitor
|
|
142
|
+
benchmarks or universal latency claims. See [benchmark/cases.mjs](benchmark/cases.mjs),
|
|
143
|
+
[benchmark/real-repositories.json](benchmark/real-repositories.json), and run the commands above to
|
|
144
|
+
reproduce them on your own repositories.
|
|
145
|
+
|
|
52
146
|
## Quick start
|
|
53
147
|
|
|
54
148
|
Requires Node ≥ 18. One command:
|
|
@@ -100,6 +194,13 @@ Advanced registrations may still pass an exact comma-separated capability set:
|
|
|
100
194
|
a compatibility alias for `advisories,hosted`; new registrations should use the named profiles or
|
|
101
195
|
the narrower capability names.
|
|
102
196
|
|
|
197
|
+
After an upgrade, reconnect the MCP server or start a new agent task before checking its tool list:
|
|
198
|
+
many clients snapshot `tools/list` and input schemas for the lifetime of one connection. The expected
|
|
199
|
+
counts are 31 for `pinned`, 34 for `offline`, 35 for `osv`, and all 38 for `hosted` / `full`. A custom
|
|
200
|
+
capability list must include `crossrepo` to expose `trace_api_contract`; `online` alone adds only the
|
|
201
|
+
legacy advisory/Hosted groups. `graph_stats` reports the running package version, enabled capabilities
|
|
202
|
+
and registered-tool count so a cached process can be distinguished from the installed package.
|
|
203
|
+
|
|
103
204
|
Or clone it:
|
|
104
205
|
|
|
105
206
|
```sh
|
|
@@ -248,6 +349,24 @@ reconnect. Every MCP response also carries local, transient `_meta["weavatrix/me
|
|
|
248
349
|
time, output bytes/token estimate, graph freshness/revision/update and graph-cache status. These
|
|
249
350
|
metrics are not persisted or transmitted by Weavatrix.
|
|
250
351
|
|
|
352
|
+
### 0.2.13 runtime-integrity and cross-language verification patch
|
|
353
|
+
|
|
354
|
+
- `verified_change` no longer requires `package.json` when no package tests can run. Python, Go,
|
|
355
|
+
Java, Rust and other non-Node repositories now receive `NOT_REQUESTED` or `DISABLED` test evidence
|
|
356
|
+
instead of a false `BLOCKED`; actual package-script execution keeps the same double opt-in and
|
|
357
|
+
allowlist.
|
|
358
|
+
- Release verification starts the packed npm artifact and portable MCPB stage over stdio. It asserts
|
|
359
|
+
the exact profile counts and required 38-tool `full` surface, including `trace_endpoint`,
|
|
360
|
+
`trace_api_contract` and `preview_sync`, so source/package drift cannot publish silently.
|
|
361
|
+
- Runtime diagnostics expose the package version, selected capability groups and registered tool
|
|
362
|
+
count. The documentation now distinguishes an old client connection from an intentional profile
|
|
363
|
+
omission and explains that custom capabilities need `crossrepo` for contract tracing.
|
|
364
|
+
- The bundled skill documents practical CLI/worker/event flows, local target-architecture adoption,
|
|
365
|
+
repository classification, undirected path semantics and the correct release and proof-carrying
|
|
366
|
+
change recipes without reducing Weavatrix to text search.
|
|
367
|
+
|
|
368
|
+
Full patch notes: [docs/releases/v0.2.13.md](docs/releases/v0.2.13.md).
|
|
369
|
+
|
|
251
370
|
### 0.2.9 correctness, signal, and consent patch
|
|
252
371
|
|
|
253
372
|
- Express endpoint inventory composes nested imported `router.use(...)` mounts, so a local route such
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Weavatrix 0.2.13
|
|
2
|
+
|
|
3
|
+
## Runtime-integrity and cross-language verification patch
|
|
4
|
+
|
|
5
|
+
0.2.13 closes two failures found by dogfooding the live MCP on real JavaScript and Python
|
|
6
|
+
applications. A live client could keep an older tool/schema snapshot after the checkout had advanced,
|
|
7
|
+
and `verified_change` treated the absence of a Node manifest as a blocker even when no package test
|
|
8
|
+
was requested. Neither failure is converted into a cosmetic pass: incomplete architecture, coverage,
|
|
9
|
+
API or test evidence still produces `UNKNOWN` where appropriate.
|
|
10
|
+
|
|
11
|
+
### Cross-language `verified_change`
|
|
12
|
+
|
|
13
|
+
- An empty test request returns `NOT_REQUESTED` before looking for `package.json`.
|
|
14
|
+
- Requested package tests with `run_tests:false` return `DISABLED` without pretending that they ran
|
|
15
|
+
or blocking a Python/Go/Java/Rust repository for lacking an npm manifest.
|
|
16
|
+
- Actual execution still requires both `run_tests:true` and `WEAVATRIX_ALLOW_TEST_RUNS=1`, accepts
|
|
17
|
+
only existing test/check/verify package scripts and rejects shell-sensitive arguments.
|
|
18
|
+
- Regression coverage exercises both plan and verify phases against a Python-only repository.
|
|
19
|
+
|
|
20
|
+
### Packed-runtime and live-tool integrity
|
|
21
|
+
|
|
22
|
+
- Release verification runs the packed npm artifact and portable MCPB stage as real stdio servers.
|
|
23
|
+
- The smoke gate asserts 34 tools for the offline profile and all 38 for `hosted` / `full`, including
|
|
24
|
+
`trace_endpoint`, `trace_api_contract` and the local-only `preview_sync` approval step.
|
|
25
|
+
- `graph_stats` and initialization diagnostics identify the running package version, enabled
|
|
26
|
+
capabilities and registered tool count. This separates an old client connection from a deliberately
|
|
27
|
+
restricted profile.
|
|
28
|
+
- Existing security boundaries are unchanged: `offline` remains the no-HTTP default; `online` stays
|
|
29
|
+
a compatibility alias for `advisories,hosted`; `crossrepo` is not silently added to a custom list;
|
|
30
|
+
and no network tool is made available by default.
|
|
31
|
+
|
|
32
|
+
MCP clients commonly snapshot `tools/list` for one connection. After upgrading, reconnect or start a
|
|
33
|
+
new task. Expected counts are 31 (`pinned`), 34 (`offline`), 35 (`osv`) and 38 (`hosted` / `full`).
|
|
34
|
+
|
|
35
|
+
### Skill and architecture workflow
|
|
36
|
+
|
|
37
|
+
The bundled skill now covers non-HTTP entrypoints (CLI, worker, queue, cron and events), explains how
|
|
38
|
+
to review and save a local starter contract, establish an explicit ratchet baseline, apply a reviewed
|
|
39
|
+
exception, and classify generated/test/resource trees through `.weavatrix.json`. It also labels
|
|
40
|
+
`shortest_path` as undirected connectivity rather than directional call proof, uses the correct
|
|
41
|
+
`change_impact base` parameter, and avoids redundant symbol-context calls.
|
|
42
|
+
|
|
43
|
+
## Compatibility
|
|
44
|
+
|
|
45
|
+
- The 38 tool names, input schemas and `weavatrix.tool.v1` result envelope remain compatible.
|
|
46
|
+
- Hosted sync payload v2/v3, confirmation-token consent and architecture-contract transport are
|
|
47
|
+
unchanged; no hosted application change is required.
|
|
48
|
+
- The public MIT license and local-first network boundary are unchanged.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "weavatrix",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Local repository intelligence MCP for AI coding agents: reusable architecture graph for fast application understanding, Health, dead code, clones, history, blast radius and architecture safeguards.",
|
|
6
6
|
"author": "Sergii Ziborov <sergii.ziborov@gmail.com>",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"skill",
|
|
27
27
|
"scripts/run-agent-task-benchmark.mjs",
|
|
28
28
|
"docs/agent-task-benchmark.md",
|
|
29
|
-
"docs/releases/v0.2.
|
|
29
|
+
"docs/releases/v0.2.13.md",
|
|
30
30
|
"README.md",
|
|
31
31
|
"SECURITY.md",
|
|
32
32
|
"LICENSE"
|
package/skill/SKILL.md
CHANGED
|
@@ -16,15 +16,20 @@ Tools are named `mcp__weavatrix__…`. If none are available, ask the user to re
|
|
|
16
16
|
(`claude mcp add -s user weavatrix -- npx -y weavatrix <repoRoot>`; Codex:
|
|
17
17
|
`codex mcp add weavatrix -- npx -y weavatrix <repoRoot>`), then retry.
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
First compare the selected profile with the `graph_stats` runtime line. Expected catalogs are 31
|
|
20
|
+
tools for `pinned`, 34 for `offline`, 35 for `osv`, and 38 for `hosted` / `full`. If the running
|
|
21
|
+
version/count differs from the installed package, or local tools such as `trace_endpoint` are missing,
|
|
22
|
+
reconnect/start a new agent task because clients commonly cache `tools/list` for one connection. A
|
|
23
|
+
custom capability list needs `crossrepo` for `trace_api_contract`; legacy `online` adds only
|
|
24
|
+
`advisories,hosted`. Missing HTTP tools are intentional only when the selected profile excludes them.
|
|
21
25
|
|
|
22
26
|
Profiles use the same npm package and binary:
|
|
23
27
|
|
|
24
28
|
- `offline` (default): all local analysis and explicit `open_repo`; no HTTP tools.
|
|
25
29
|
- `pinned`: local analysis with no `open_repo`, no global/cross-repository graph access, and no HTTP tools.
|
|
26
30
|
- `osv`: `offline` plus explicit `refresh_advisories`.
|
|
27
|
-
- `hosted` / `full`: `osv` plus local-only `preview_sync
|
|
31
|
+
- `hosted` / `full`: `osv` plus local-only `preview_sync` and the explicitly invoked network tools
|
|
32
|
+
`pull_architecture_contract` and confirmed `sync_graph`.
|
|
28
33
|
|
|
29
34
|
The legacy `online` capability remains a compatibility alias for `advisories,hosted`; prefer the
|
|
30
35
|
named profiles for new registrations.
|
|
@@ -45,7 +50,9 @@ projection; expand only when the answer requires it.
|
|
|
45
50
|
- **Find high-coupling hubs**: `god_nodes`; repeated call sites do not inflate unique connectivity.
|
|
46
51
|
- **Inspect one graph entity**: `get_node`; pass an exact node ID when labels are ambiguous.
|
|
47
52
|
- **Inspect direct one-hop relations**: `get_neighbors`; do not confuse it with transitive impact.
|
|
48
|
-
- **
|
|
53
|
+
- **Find a connectivity path between two concepts**: `shortest_path`. It traverses the graph as
|
|
54
|
+
undirected reachability, so it is not proof of call/dependency direction; confirm direction with
|
|
55
|
+
`get_neighbors` and `read_source`.
|
|
49
56
|
- **Explore an unknown entry point or architectural question**: `query_graph`; pin `seed_files` when
|
|
50
57
|
known, and keep its broad result as orientation evidence.
|
|
51
58
|
- **Inspect one exact symbol deeply**: `context_bundle` for the bounded edit workset;
|
|
@@ -59,16 +66,23 @@ projection; expand only when the answer requires it.
|
|
|
59
66
|
- **Trace one endpoint through the application**: `trace_endpoint` for route -> handler -> bounded
|
|
60
67
|
downstream call flow with edge-centered excerpts.
|
|
61
68
|
- **Trace an API contract across repositories**: `list_known_repos` -> `trace_api_contract` with an
|
|
62
|
-
explicit backend/client set;
|
|
69
|
+
explicit backend/client set; prefer this over separate per-repository endpoint/search passes when
|
|
70
|
+
a backend change may affect registered clients, and inspect each graph reconciliation state before
|
|
71
|
+
using the verdict.
|
|
63
72
|
- **Measure one symbol's transitive blast radius**: `get_dependents`.
|
|
64
|
-
- **Review the current branch, diff, or external patch**: `change_impact
|
|
73
|
+
- **Review the current branch, diff, or external patch**: `change_impact`; its explicit baseline
|
|
74
|
+
parameter is `base`, not the `base_ref` used by audit/diff/verification tools. It distinguishes
|
|
75
|
+
additive exports from signature/body/removal risk and separates runtime/type-only radius plus
|
|
76
|
+
available measured coverage or explicitly static reachability.
|
|
65
77
|
- **Compare structural graph revisions**: `graph_diff base_ref=<merge-base>` for module edges, cycles,
|
|
66
78
|
orphans and lost callers; without `base_ref`, compare the last rebuild snapshots.
|
|
67
79
|
- **Use behavioral history**: `git_history` for churn x connectivity, hidden co-change and expected
|
|
68
80
|
test/source coupling from bounded local Git numstat evidence.
|
|
69
|
-
- **Plan and verify a serious change or pre-commit gate**:
|
|
70
|
-
`verified_change phase=
|
|
71
|
-
|
|
81
|
+
- **Plan and verify a serious change or pre-commit gate**:
|
|
82
|
+
`verified_change task=<same-task> phase=plan base_ref=<merge-base>` -> edit ->
|
|
83
|
+
`verified_change task=<same-task> phase=verify base_ref=<same-ref>`. It composes exact context, impact, graph,
|
|
84
|
+
architecture, duplicate, optional API and test proof into one PASS/BLOCKED/UNKNOWN envelope. It is
|
|
85
|
+
a proof layer around an agent's edit, not a source editor or hidden auto-fix.
|
|
72
86
|
|
|
73
87
|
### Health, debt and testing scenarios
|
|
74
88
|
|
|
@@ -96,7 +110,8 @@ projection; expand only when the answer requires it.
|
|
|
96
110
|
- **Select rules before editing**: `prepare_change`; **enforce the ratchet after editing**:
|
|
97
111
|
`verify_architecture`.
|
|
98
112
|
- **Understand or request an exception**: `explain_architecture_violation` ->
|
|
99
|
-
`propose_architecture_exception`; proposals never mutate policy automatically.
|
|
113
|
+
`propose_architecture_exception`; proposals never mutate policy automatically. After human approval,
|
|
114
|
+
the owner must add the returned proposal to the local contract's `exceptions` or approve it in Hosted.
|
|
100
115
|
- **Pull an owner-approved Hosted target**: `pull_architecture_contract` only in an explicitly enabled
|
|
101
116
|
Hosted profile.
|
|
102
117
|
- **Review exactly what Hosted sync would send**: `preview_sync`; only an approved
|
|
@@ -110,6 +125,9 @@ TypeScript/JavaScript overlay. Java receiver-type call edges are parser-resolved
|
|
|
110
125
|
|
|
111
126
|
## Ground rules
|
|
112
127
|
|
|
128
|
+
- **No hidden source mutation**: Weavatrix builds derived graph/cache artifacts and can run explicitly
|
|
129
|
+
authorized tests, but it does not edit repository source, auto-delete debt, merge clones, or rewrite
|
|
130
|
+
architecture policy. The coding agent remains responsible for the change and its tests.
|
|
113
131
|
- **Evidence, not verdicts**: treat audit, hub, orphan and duplicate output as hypotheses. Confirm a
|
|
114
132
|
finding in source and check framework/runtime conventions before deleting, merging or redesigning
|
|
115
133
|
code. A same-name/different-body pair is a divergence candidate, not proof of duplication.
|
|
@@ -187,16 +205,19 @@ TypeScript/JavaScript overlay. Java receiver-type call edges are parser-resolved
|
|
|
187
205
|
|
|
188
206
|
## Recipes
|
|
189
207
|
|
|
190
|
-
- **Proof-carrying refactor**: `verified_change task
|
|
191
|
-
`verified_change task
|
|
208
|
+
- **Proof-carrying refactor**: `verified_change task=<same-task> phase=plan base_ref=<merge-base>` -> edit ->
|
|
209
|
+
`verified_change task=<same-task> phase=verify base_ref=<same-ref> tests=[{"script":"test","args":[...]}]`.
|
|
210
|
+
Repeat `task` on both calls; it is required and is not retained between invocations.
|
|
192
211
|
Add `run_tests:true` only when test execution was authorized. `BLOCKED` means an evidenced ratchet
|
|
193
212
|
or test failure; `UNKNOWN` means at least one required proof is incomplete.
|
|
194
213
|
|
|
195
214
|
- **Orient in the configured repo**: `module_map` → `list_communities` → `god_nodes`. Hub ranking
|
|
196
215
|
is production-only by default; use `include_classified:true` only when tests/generated/build
|
|
197
216
|
surfaces are deliberately part of the question.
|
|
198
|
-
- **Refactor safety for one symbol**: `
|
|
199
|
-
|
|
217
|
+
- **Refactor safety for one symbol**: `context_bundle` → optional `inspect_symbol` when raw LSP
|
|
218
|
+
occurrences, ambiguity details or the larger source window are needed → `get_dependents` →
|
|
219
|
+
`coverage_map` (low coverage × many dependents ⇒ write tests first) → edit →
|
|
220
|
+
`verified_change task=<task> phase=verify base_ref=<merge-base>`.
|
|
200
221
|
- **Performance review**: `hot_path_review` → inspect its local evidence with `read_source` → use
|
|
201
222
|
`get_dependents` for change risk → confirm with the repository's profiler/benchmark before editing.
|
|
202
223
|
- **Pre-PR review of your current changes**: `change_impact` (auto merge-base; includes uncommitted
|
|
@@ -229,6 +250,10 @@ TypeScript/JavaScript overlay. Java receiver-type call edges are parser-resolved
|
|
|
229
250
|
- **API inventory**: `list_endpoints` (including mount provenance, Next.js App Router, Rust axum and
|
|
230
251
|
actix-web). When one exact route is known, use `trace_endpoint` for its composed mount chain,
|
|
231
252
|
handler and bounded production call graph instead of broad natural-language traversal.
|
|
253
|
+
- **CLI, worker, queue, cron or event flow**: locate the manifest/registration literal with
|
|
254
|
+
`search_code`, then pin the discovered entry file with `query_graph seed_files=[...]`; use
|
|
255
|
+
`context_bundle` on its exact handler plus `get_neighbors` / `get_dependents`, and confirm the
|
|
256
|
+
registration and call sites with `read_source`. Do not force a non-HTTP flow through endpoint tools.
|
|
232
257
|
- **Cross-repository API impact**: ensure both repositories are in `list_known_repos`, then call
|
|
233
258
|
`trace_api_contract backend=<uuid-or-label> clients=[<uuid-or-label>]`; narrow with `method`, `path`,
|
|
234
259
|
or backend `changed_files`. `path` may be a segment-aligned fragment (`/query` can select
|
|
@@ -239,8 +264,9 @@ TypeScript/JavaScript overlay. Java receiver-type call edges are parser-resolved
|
|
|
239
264
|
confidence; only an unambiguously resolved handler node can suppress a dead-method candidate.
|
|
240
265
|
`POSSIBLE_EXTERNAL_USE`, `UNKNOWN`, and remaining unresolved/dynamic URLs are incomplete evidence,
|
|
241
266
|
never proof that a method is dead.
|
|
242
|
-
- **Release regression gate**: for a Weavatrix source checkout, use `npm test` for the
|
|
243
|
-
|
|
267
|
+
- **Release regression gate**: for a Weavatrix source checkout, use `npm test` for the full
|
|
268
|
+
unit/integration suite, `npm run benchmark:quick` for the quick six-language golden corpus, and
|
|
269
|
+
`npm run benchmark` before release for the golden corpus plus the real MCP
|
|
244
270
|
`full -> incremental -> none -> reconnect/none` lifecycle, bounded output and active-target checks.
|
|
245
271
|
Use `npm run benchmark:real` for available manifest repositories and
|
|
246
272
|
`npm run benchmark:real:release` only when all six source checkouts are present; `MISSING`,
|
|
@@ -250,16 +276,25 @@ TypeScript/JavaScript overlay. Java receiver-type call edges are parser-resolved
|
|
|
250
276
|
- **Target architecture before editing**: `get_architecture_contract` → `prepare_change` with the
|
|
251
277
|
intended files → edit and rebuild → `verify_architecture`. A missing contract returns a starter
|
|
252
278
|
proposal from `get_architecture_contract output_format:"json"`, not an automatically approved
|
|
253
|
-
architecture.
|
|
254
|
-
|
|
255
|
-
|
|
279
|
+
architecture. For offline adoption, have the owner review/edit `starterContract`, save it as
|
|
280
|
+
`.weavatrix/architecture.json`, and rerun the lookup. To establish a ratchet over accepted current
|
|
281
|
+
debt, run `verify_architecture output_format:"json"`; only after explicit owner approval, copy the
|
|
282
|
+
accepted `verification.new[*].fingerprint` values into `ratchet.baseline.fingerprints`, save, and
|
|
283
|
+
verify again so accepted debt is `existing` while later debt is `new`. The v1 verifier classifies
|
|
284
|
+
ratchet debt by fingerprints; `ratchet.baseline.metrics` is metadata, not a replacement. An approved local exception
|
|
285
|
+
is applied by adding the exact returned `proposal` to `exceptions`; rerun verification afterward.
|
|
286
|
+
Without a contract, `prepare_change` still returns provisional no-regression budgets, but they are
|
|
287
|
+
guidance rather than enforceable policy. Pull an owner-approved hosted contract only when the user
|
|
288
|
+
selected `hosted` and explicitly asks for it. No Weavatrix tool silently writes either policy.
|
|
256
289
|
- **Behavioral architecture**: `git_history` ranks churn × connectivity hotspots and hidden
|
|
257
290
|
co-change coupling from bounded local numstat history. Always set `top_n`; it is enforced across
|
|
258
291
|
every returned structured collection and JSON reports per-collection truncation. Use it as review
|
|
259
292
|
evidence, not proof that two files must be merged.
|
|
260
293
|
- **Machine output**: keep the default `output_format:"text"` for concise agent conversations; opt
|
|
261
294
|
into `output_format:"json"` only when a workflow consumes the full `weavatrix.tool.v1` envelope.
|
|
262
|
-
- **Find code**: `search_code` (regex + glob) →
|
|
295
|
+
- **Find code**: `search_code` (regex + glob) →
|
|
296
|
+
`read_source path=<match-path> start_line=<match-line>`; add `get_node` / `get_neighbors` only after
|
|
297
|
+
identifying an exact graph symbol.
|
|
263
298
|
- **Another repo**: `list_known_repos` → `open_repo <path>`
|
|
264
299
|
(builds or upgrades the graph when needed; `build:false` probes without building).
|
|
265
300
|
|
|
@@ -267,9 +302,29 @@ TypeScript/JavaScript overlay. Java receiver-type call edges are parser-resolved
|
|
|
267
302
|
|
|
268
303
|
Weavatrix understands nearest workspace manifests, nested `tsconfig`/`jsconfig` aliases,
|
|
269
304
|
framework-owned runtime peers such as Next.js + `react-dom`, generated NAPI-RS platform loaders,
|
|
270
|
-
and Next.js App Router route exports.
|
|
271
|
-
|
|
272
|
-
|
|
305
|
+
and Next.js App Router route exports. Use repository-root `.weavatrix.json` to correct ambiguous
|
|
306
|
+
production classification without deleting graph evidence:
|
|
307
|
+
|
|
308
|
+
```json
|
|
309
|
+
{
|
|
310
|
+
"classify": {
|
|
311
|
+
"generated": ["src/generated/**"],
|
|
312
|
+
"test": ["qa/**"],
|
|
313
|
+
"product": ["benchmarks/core/**"]
|
|
314
|
+
},
|
|
315
|
+
"exclude": ["resources/snapshots/**"]
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Use `generated` / `test` (or `e2e`, `mock`, `story`, `docs`, `benchmark`, `temp`) for non-production
|
|
320
|
+
code, top-level `exclude` for resource/catalog roots that should stay visible in the graph but not
|
|
321
|
+
drive production-first Health/query ranking, and `product` only to opt a verified benchmark/temp path
|
|
322
|
+
back into production review. `product` does not override an explicit generated/test classification or
|
|
323
|
+
`exclude`. Use `.weavatrixignore` instead only when a path must be removed consistently from graph,
|
|
324
|
+
audit and duplicate scans.
|
|
325
|
+
|
|
326
|
+
For project-specific entry points, reusable template catalogs, or Python dependencies supplied by an
|
|
327
|
+
external runtime, add `.weavatrix-deps.json` at the repository root:
|
|
273
328
|
|
|
274
329
|
```json
|
|
275
330
|
{
|
|
@@ -19,29 +19,40 @@ function packageManager(repoRoot) {
|
|
|
19
19
|
return 'npm'
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
const manifest = manifestAt(repoRoot)
|
|
24
|
-
if (!manifest) return {ok: false, reason: 'package.json is missing or unreadable', tests: []}
|
|
22
|
+
function normalizeTestRequests(requests = []) {
|
|
25
23
|
const tests = []
|
|
26
|
-
for (const request of requests.slice(0, 5)) {
|
|
24
|
+
for (const request of (Array.isArray(requests) ? requests : []).slice(0, 5)) {
|
|
27
25
|
const script = String(request?.script || '')
|
|
28
26
|
const args = Array.isArray(request?.args) ? request.args.slice(0, 40).map(String) : []
|
|
29
27
|
if (!SAFE_SCRIPT.test(script)) return {ok: false, reason: `script ${script || '(missing)'} is outside the test/check/verify allowlist`, tests}
|
|
30
|
-
if (!Object.hasOwn(manifest.scripts || {}, script)) return {ok: false, reason: `package.json has no script named ${script}`, tests}
|
|
31
28
|
if (args.some((arg) => arg.length > 300 || UNSAFE_SHELL_ARG.test(arg))) return {ok: false, reason: `script ${script} has an invalid or shell-sensitive argument`, tests}
|
|
32
29
|
tests.push({script, args})
|
|
33
30
|
}
|
|
31
|
+
return {ok: true, tests}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function validateTestRequests(repoRoot, requests = []) {
|
|
35
|
+
const normalized = normalizeTestRequests(requests)
|
|
36
|
+
if (!normalized.ok || !normalized.tests.length) return normalized
|
|
37
|
+
const manifest = manifestAt(repoRoot)
|
|
38
|
+
if (!manifest) return {ok: false, reason: 'package.json is missing or unreadable', tests: []}
|
|
39
|
+
for (const test of normalized.tests) {
|
|
40
|
+
if (!Object.hasOwn(manifest.scripts || {}, test.script)) return {ok: false, reason: `package.json has no script named ${test.script}`, tests: []}
|
|
41
|
+
}
|
|
42
|
+
const tests = normalized.tests
|
|
34
43
|
return {ok: true, tests, packageManager: packageManager(repoRoot)}
|
|
35
44
|
}
|
|
36
45
|
|
|
37
46
|
export async function runAllowedTests(repoRoot, requests = [], {enabled = false, timeoutMs = 60_000} = {}) {
|
|
38
|
-
const
|
|
39
|
-
if (!
|
|
40
|
-
if (!
|
|
47
|
+
const normalized = normalizeTestRequests(requests)
|
|
48
|
+
if (!normalized.ok) return {state: 'BLOCKED', reason: normalized.reason, results: []}
|
|
49
|
+
if (!normalized.tests.length) return {state: 'NOT_REQUESTED', reason: 'no package scripts were requested', plan: [], results: []}
|
|
41
50
|
if (!enabled || process.env.WEAVATRIX_ALLOW_TEST_RUNS !== '1') return {
|
|
42
51
|
state: 'DISABLED', reason: 'set WEAVATRIX_ALLOW_TEST_RUNS=1 and pass run_tests:true to execute allowlisted package scripts',
|
|
43
|
-
plan:
|
|
52
|
+
plan: normalized.tests, results: [],
|
|
44
53
|
}
|
|
54
|
+
const checked = validateTestRequests(repoRoot, normalized.tests)
|
|
55
|
+
if (!checked.ok) return {state: 'BLOCKED', reason: checked.reason, results: []}
|
|
45
56
|
const results = []
|
|
46
57
|
const timeout = Math.max(1000, Math.min(300_000, Number(timeoutMs) || 60_000))
|
|
47
58
|
for (const test of checked.tests) {
|
package/src/mcp/catalog.mjs
CHANGED
|
@@ -169,6 +169,7 @@ export async function loadHotApi(version, capsArg) {
|
|
|
169
169
|
import(new URL(`./tools-verified-change.mjs${v}`, import.meta.url).href),
|
|
170
170
|
])
|
|
171
171
|
const raw = capsArg == null ? 'offline' : String(capsArg).trim()
|
|
172
|
+
const profile = Object.hasOwn(PROFILE_CAPS, raw) ? raw : 'custom'
|
|
172
173
|
const selected = PROFILE_CAPS[raw] || raw.split(',').map((s) => s.trim()).filter(Boolean)
|
|
173
174
|
.flatMap((cap) => cap === 'online' ? ['advisories', 'hosted'] : [cap])
|
|
174
175
|
const caps = new Set(selected)
|
|
@@ -178,6 +179,7 @@ export async function loadHotApi(version, capsArg) {
|
|
|
178
179
|
tools,
|
|
179
180
|
byName: new Map(tools.map((t) => [t.name, t])),
|
|
180
181
|
caps,
|
|
182
|
+
profile,
|
|
181
183
|
stalenessLine,
|
|
182
184
|
resetStalenessCache,
|
|
183
185
|
}
|
package/src/mcp/tools-graph.mjs
CHANGED
|
@@ -40,6 +40,7 @@ export function tGraphStats(g, ctx) {
|
|
|
40
40
|
const precision = g.precision || {state: 'UNAVAILABLE', verifiedEdges: 0, candidates: 0, queried: 0, reason: 'no revision-matched precision overlay'}
|
|
41
41
|
return [
|
|
42
42
|
`Graph summary`,
|
|
43
|
+
ctx?.runtime ? `- Weavatrix runtime: v${ctx.runtime.version}; profile ${ctx.runtime.profile}; ${ctx.runtime.toolCount} registered tools; capabilities: ${ctx.runtime.capabilities.join(',') || '(none)'}` : null,
|
|
43
44
|
ctx?.repoRoot ? `- Repo: ${ctx.repoRoot}` : null,
|
|
44
45
|
ctx?.graphPath ? `- Graph: ${ctx.graphPath}` : null,
|
|
45
46
|
`- Build mode: ${g.graphBuildMode || 'full'}`,
|
|
@@ -126,10 +126,18 @@ export async function tVerifiedChange(g, args = {}, ctx = {}, tools = {}, permis
|
|
|
126
126
|
})
|
|
127
127
|
: {model: 'bounded call-argument-to-parameter evidence (not CFG or taint analysis)', status: 'UNAVAILABLE', reason: 'source capability is not enabled', edges: [], unsupportedEdges: 0, capped: false}
|
|
128
128
|
const suggestedTests = targetTests(impact)
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
const requestedTests = Array.isArray(args.tests) ? args.tests : []
|
|
130
|
+
let testProof
|
|
131
|
+
if (!requestedTests.length) {
|
|
132
|
+
testProof = {state: 'NOT_REQUESTED', reason: 'no package scripts were requested', plan: [], results: []}
|
|
133
|
+
} else if (args.run_tests !== true) {
|
|
134
|
+
testProof = await runAllowedTests(ctx.repoRoot, requestedTests, {enabled: false, timeoutMs: args.test_timeout_ms})
|
|
135
|
+
} else if (phase === 'verify') {
|
|
136
|
+
testProof = await runAllowedTests(ctx.repoRoot, requestedTests, {enabled: true, timeoutMs: args.test_timeout_ms})
|
|
137
|
+
} else {
|
|
138
|
+
const checkedTests = validateTestRequests(ctx.repoRoot, requestedTests)
|
|
139
|
+
testProof = {state: checkedTests.ok ? 'PLANNED' : 'BLOCKED', reason: checkedTests.reason, plan: checkedTests.tests || [], results: []}
|
|
140
|
+
}
|
|
133
141
|
const testCoverageState = testCoverage(testProof, args.tests || [], suggestedTests)
|
|
134
142
|
|
|
135
143
|
const architectureValue = phase === 'verify'
|
package/src/mcp-server.mjs
CHANGED
|
@@ -85,11 +85,21 @@ function hotVersion(hotFiles) {
|
|
|
85
85
|
async function main() {
|
|
86
86
|
let catalog = await loadCatalog()
|
|
87
87
|
let api = await catalog.loadHotApi(0, CAPS_ARG)
|
|
88
|
+
const runtimeInfo = () => ({
|
|
89
|
+
version: PKG_VERSION,
|
|
90
|
+
profile: api.profile || 'custom',
|
|
91
|
+
capabilities: [...api.caps],
|
|
92
|
+
toolCount: api.tools.length,
|
|
93
|
+
})
|
|
94
|
+
const runtimeInstructions = () => {
|
|
95
|
+
const runtime = runtimeInfo()
|
|
96
|
+
return `Weavatrix ${runtime.version}; profile=${runtime.profile}; tools=${runtime.toolCount}; capabilities=${runtime.capabilities.join(',') || '(none)'}. If this differs from the client-visible tool list, reconnect the MCP client to discard its cached schema.`
|
|
97
|
+
}
|
|
88
98
|
let graph = null
|
|
89
99
|
let graphError = null
|
|
90
100
|
// ctx owns the CURRENT target: rebuild_graph reloads it, open_repo retargets graphPath/repoRoot
|
|
91
101
|
// at runtime. loadInto always reads ctx.graphPath so both paths share one loader.
|
|
92
|
-
const ctx = {graphPath: GRAPH_PATH, repoRoot: REPO_ROOT, reload: null}
|
|
102
|
+
const ctx = {graphPath: GRAPH_PATH, repoRoot: REPO_ROOT, reload: null, runtime: runtimeInfo()}
|
|
93
103
|
const loadInto = () => { graph = loadGraph(ctx.graphPath, {repoRoot: ctx.repoRoot}); graphError = null; return graph }
|
|
94
104
|
ctx.reload = () => { api.resetStalenessCache(); try { return loadInto() } catch (e) { graphError = e.message; return null } }
|
|
95
105
|
try {
|
|
@@ -229,6 +239,7 @@ async function main() {
|
|
|
229
239
|
const nextApi = await nextCatalog.loadHotApi(v, CAPS_ARG)
|
|
230
240
|
catalog = nextCatalog
|
|
231
241
|
api = nextApi
|
|
242
|
+
ctx.runtime = runtimeInfo()
|
|
232
243
|
loadedVersion = v
|
|
233
244
|
log(`hot-reloaded tool implementations from changed source (${api.tools.length} tools)`)
|
|
234
245
|
send({jsonrpc: '2.0', method: 'notifications/tools/list_changed'})
|
|
@@ -247,14 +258,17 @@ async function main() {
|
|
|
247
258
|
}
|
|
248
259
|
if (method === 'initialize') {
|
|
249
260
|
if (params?.protocolVersion) protocolVersion = String(params.protocolVersion)
|
|
250
|
-
return reply(id, {protocolVersion, capabilities: {tools: {listChanged: true}}, serverInfo: SERVER_INFO})
|
|
261
|
+
return reply(id, {protocolVersion, capabilities: {tools: {listChanged: true}}, serverInfo: SERVER_INFO, instructions: runtimeInstructions()})
|
|
251
262
|
}
|
|
252
263
|
if (method === 'notifications/initialized' || method === 'initialized') return
|
|
253
264
|
if (method === 'ping') return reply(id, {})
|
|
254
265
|
if (method === 'tools/list') {
|
|
255
266
|
await maybeHotReload()
|
|
256
267
|
if (shuttingDown) return
|
|
257
|
-
return reply(id, {
|
|
268
|
+
return reply(id, {
|
|
269
|
+
tools: api.tools.map(({name, description, inputSchema, outputSchema}) => ({name, description, inputSchema, outputSchema})),
|
|
270
|
+
_meta: {'weavatrix/runtime': runtimeInfo()},
|
|
271
|
+
})
|
|
258
272
|
}
|
|
259
273
|
if (method === 'tools/call') {
|
|
260
274
|
await maybeHotReload()
|
package/docs/releases/v0.2.11.md
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# Weavatrix 0.2.11
|
|
2
|
-
|
|
3
|
-
## MCP Registry publication hotfix
|
|
4
|
-
|
|
5
|
-
0.2.11 is the immutable follow-up to 0.2.10. The 0.2.10 npm package published successfully, but
|
|
6
|
-
the official MCP Registry rejected its expanded server description because that field exceeded the
|
|
7
|
-
Registry's 100-character limit. This patch shortens only the Registry summary while preserving the
|
|
8
|
-
broad product positioning across the package, MCPB, skill, README and public site. The release
|
|
9
|
-
verifier now enforces the same 1-100 character boundary before a tag can publish.
|
|
10
|
-
|
|
11
|
-
The runtime is otherwise the verified 0.2.10 release: 38 graph-backed methods for fast application
|
|
12
|
-
understanding, Health, dependencies, dead-code and duplicate review, history, endpoint and impact
|
|
13
|
-
tracing, proof-carrying changes, target-architecture ratchets and explicit Hosted governance. Its
|
|
14
|
-
Java receiver-aware call resolver and product-code-only architecture starter are unchanged.
|
|
15
|
-
|
|
16
|
-
## Compatibility and verification
|
|
17
|
-
|
|
18
|
-
- Tool names, input schemas, result envelopes and Hosted sync payload v2/v3 remain unchanged.
|
|
19
|
-
- Full Node suite: 506 tests, 503 passed, 3 platform skips, 0 failed.
|
|
20
|
-
- Six-language, cross-repository, framework and MCP lifecycle benchmark: `PASS`.
|
|
21
|
-
- Six available real-repository baselines: 6/6 `PASS`.
|
|
22
|
-
- Repo Lens portable analyzer parity: 21/21 methods present in the default offline profile.
|
|
23
|
-
- Release metadata, MCP Registry description length and MCPB manifest validation: `PASS`.
|