ucn 5.2.2 → 5.3.0
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/.claude/skills/ucn/SKILL.md +49 -3
- package/.claude/skills/ucn/references/commands.md +3 -1
- package/README.md +158 -533
- package/cli/index.js +71 -10
- package/core/cache.js +22 -13
- package/core/callers.js +51 -52
- package/core/execute.js +24 -6
- package/core/graph.js +167 -35
- package/core/index-ir.js +12 -9
- package/core/output/graph.js +60 -11
- package/core/output/lines.js +259 -0
- package/core/output/public.js +15 -0
- package/core/output/reporting.js +9 -2
- package/core/output-budget.js +7 -4
- package/core/project.js +15 -2
- package/core/registry.js +7 -6
- package/core/reporting.js +159 -14
- package/languages/javascript.js +213 -6
- package/languages/python.js +115 -12
- package/mcp/server.js +3 -1
- package/package.json +2 -2
- package/assets/demo.svg +0 -31
package/README.md
CHANGED
|
@@ -10,11 +10,12 @@ If you work with AI Agents, add UCN as a [Skill or MCP tool](#ai-setup). One too
|
|
|
10
10
|
gives the agent compact, source-linked answers to caller, impact, and test
|
|
11
11
|
questions, with uncertainty labeled instead of guessed.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
source, and spot dead code - from your terminal or your AI agent.
|
|
13
|
+
<img src="assets/readme/ucn-connected-scope.gif" width="736" alt="Conceptual overview of UCN's relationship views, multi-hop exploration, visible uncertainty, index reuse, and refresh after edits. Nodes and timing are illustrative, not a captured query or benchmark.">
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
Conceptual overview · [Still image](assets/readme/ucn-connected-scope.png)
|
|
16
|
+
|
|
17
|
+
Use the CLI directly, install the [agent skill](#agent-skill-no-server-needed),
|
|
18
|
+
or connect through [MCP](#mcp). One engine supplies all three:
|
|
18
19
|
|
|
19
20
|
```text
|
|
20
21
|
Terminal AI Agents Agent Skills
|
|
@@ -29,440 +30,140 @@ and HTML inline scripts. All commands, one engine, three ways to use it:
|
|
|
29
30
|
└─────────────┘
|
|
30
31
|
```
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
It's deliberately lightweight:
|
|
39
|
-
|
|
40
|
-
- **No required background process** - the CLI parses on demand, answers, and
|
|
41
|
-
exits. MCP stays warm only when you choose to run it.
|
|
42
|
-
- **No HTTP or network stack** - MCP uses a local, dependency-free stdio
|
|
43
|
-
transport; UCN never opens a port.
|
|
44
|
-
- **No language servers, no compilation** - tree-sitter does the analysis
|
|
45
|
-
without building the project.
|
|
46
|
-
- **No config** - point it at a directory and ask.
|
|
47
|
-
|
|
48
|
-
And it's built for auditable trust. grep hands you raw matches to sift
|
|
49
|
-
yourself; UCN separates proven edges from possible ones, explains every
|
|
50
|
-
exclusion, and reconciles every occurrence of the name it searched. It never
|
|
51
|
-
turns a zero into a deletion claim. CI re-derives its answers from real
|
|
52
|
-
compilers and language servers (ts-morph, Pyright, gopls, rust-analyzer,
|
|
53
|
-
JDT LS, Roslyn, clangd) on pinned production repositories. See
|
|
54
|
-
[Answers you can trust](#answers-you-can-trust).
|
|
55
|
-
|
|
56
|
-
<img src="https://raw.githubusercontent.com/mleoca/ucn/main/assets/demo.svg" alt="ucn show on ripgrep: signature, 123 confirmed callers with evidence types, and the ACCOUNT line reconciling all 136 occurrences of the name" width="100%">
|
|
33
|
+
UCN uses tree-sitter abstract syntax trees (ASTs) for static code analysis,
|
|
34
|
+
without compiling the project or starting
|
|
35
|
+
a language server. The CLI runs on demand and reuses an incremental index;
|
|
36
|
+
MCP keeps a process available for repeated queries. No project configuration
|
|
37
|
+
is required, and the cache lives outside the repository.
|
|
57
38
|
|
|
58
|
-
|
|
39
|
+
Supports JavaScript, TypeScript, JSX/TSX, Python, Go, Rust, Java, C, C++, C#,
|
|
40
|
+
and HTML inline scripts.
|
|
59
41
|
|
|
60
|
-
##
|
|
42
|
+
## Install
|
|
61
43
|
|
|
62
44
|
```bash
|
|
63
45
|
npm install -g ucn # Node.js 20+
|
|
64
|
-
|
|
65
|
-
cd your-project
|
|
66
|
-
ucn repo # what is this codebase?
|
|
67
|
-
ucn find handleRequest # exact definitions, stable handles
|
|
68
|
-
ucn show src/server.ts:42:handleRequest # the full picture
|
|
69
|
-
ucn trace src/server.ts:42:handleRequest --direction=callers
|
|
70
|
-
ucn impact src/server.ts:42:handleRequest # every call site, with evidence
|
|
71
|
-
ucn tests src/server.ts:42:handleRequest --depth=3 # which tests to run
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
The first command builds an incremental index; the rest reuse it. The cache
|
|
75
|
-
lives outside your project directory, so there's nothing to gitignore.
|
|
76
|
-
|
|
77
|
-
## Understand code you didn't write
|
|
78
|
-
|
|
79
|
-
What does this function do, who calls it, and how sure is the answer?
|
|
80
|
-
`ucn show` gathers everything useful about one symbol: signature, source,
|
|
81
|
-
callers, callees, tests, types, dependencies, examples. Project it down to
|
|
82
|
-
just the sections you need:
|
|
83
|
-
|
|
84
|
-
```text
|
|
85
|
-
$ ucn show detectLanguage --sections=summary,callers,callees --compact
|
|
86
|
-
|
|
87
|
-
SUMMARY
|
|
88
|
-
───────
|
|
89
|
-
detectLanguage(filePath: string, projectRoot = null): string|null
|
|
90
|
-
languages/index.js:420-428 (9 lines)
|
|
91
|
-
handle: languages/index.js:420:detectLanguage
|
|
92
|
-
"Detect language from file path"
|
|
93
|
-
async: no | side_effects: [none] | complexity: branches=1, depth=1
|
|
94
|
-
|
|
95
|
-
RELATIONSHIPS
|
|
96
|
-
─────────────
|
|
97
|
-
CALLERS — CONFIRMED (51, 30 prod + 21 test):
|
|
98
|
-
evidence: scope-match (all)
|
|
99
|
-
[1] cli/index.js:604 [runFileCommand]: const language = detectLanguage(filePath);
|
|
100
|
-
[7] core/build-worker.js:39 [processFile]: const language = detectLanguage(filePath, rootDir);
|
|
101
|
-
[17] core/project.js:472 [build]: const language = detectLanguage(filePath, this.root);
|
|
102
|
-
[34] test/parser-unit.test.js:19: assert.strictEqual(detectLanguage('file.js'), 'javascript');
|
|
103
|
-
... 47 more callers
|
|
104
|
-
|
|
105
|
-
CALLEES (1):
|
|
106
|
-
evidence: exact-binding (all)
|
|
107
|
-
[52] detectHeaderLanguage {fs} - core/compilation-database.js:217
|
|
108
|
-
CALLEES — UNVERIFIED (1) — call syntax, receiver/binding unresolved:
|
|
109
|
-
toLowerCase ×1 — possible-dispatch L422
|
|
110
|
-
|
|
111
|
-
ACCOUNT: "detectLanguage" occurs on 79 lines in 20 files: 51 confirmed, 0 unverified,
|
|
112
|
-
28 non-call (18 import, 1 definition, 3 reference, 6 other-text), 0 other-target, 0 unaccounted
|
|
113
|
-
CONTRACT: literal-name text partition complete; semantic completeness is not claimed
|
|
114
|
-
(aliases, indirect calls, generated code, and runtime dispatch may exist).
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
`find` returns stable handles in `file:line:name` form. Pass a handle to any
|
|
118
|
-
command to pin the answer to one definition, even when several files or classes
|
|
119
|
-
reuse the same name.
|
|
120
|
-
|
|
121
|
-
## Follow the execution path
|
|
122
|
-
|
|
123
|
-
What happens when `build()` runs?
|
|
124
|
-
|
|
125
|
-
```text
|
|
126
|
-
$ ucn trace build --depth=2
|
|
127
|
-
|
|
128
|
-
build
|
|
129
|
-
├── compareNames (core/discovery.js:293) [regular] 3x
|
|
130
|
-
├── recordDiscoveryIssue (core/project.js:346) 2x
|
|
131
|
-
│ └── [unverified] push — method-ambiguous L351
|
|
132
|
-
├── detectProjectPattern (core/discovery.js:760) [utility] 1x
|
|
133
|
-
├── parseGitignore (core/discovery.js:253) [utility] 1x
|
|
134
|
-
│ ├── gitignoreFiles (core/discovery.js:234) [utility] 1x
|
|
135
|
-
│ ├── compareNames (core/discovery.js:293) [utility] 1x (see above)
|
|
136
|
-
│ └── parseGitignoreFile (core/discovery.js:152) [utility] 1x
|
|
137
|
-
├── gitTrackedPaths (core/discovery.js:266) [utility] 1x
|
|
138
|
-
│ ├── hasGitMetadata (core/discovery.js:224) [utility] 1x
|
|
139
|
-
│ └── [unverified] dirname — method-ambiguous L281,L284
|
|
140
|
-
└── ... more callees
|
|
141
|
-
|
|
142
|
-
CALLEE ACCOUNT: 11 nodes expanded · 210 call sites = 31 confirmed + 33 unverified
|
|
143
|
-
(25 method-ambiguous, 1 possible-dispatch, 7 uncertain-receiver) + 86 external/builtin + 60 excluded
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
`trace` walks callees, callers, or callers all the way up to runtime entry
|
|
147
|
-
points (`--direction=callers --to=entrypoints`). Proven edges form the tree;
|
|
148
|
-
calls UCN can't prove a receiver for show up as `[unverified]` leaves with a
|
|
149
|
-
reason. The account line reconciles every call site in the expanded tree, so
|
|
150
|
-
unresolved dispatch stays visible and counted instead of quietly vanishing.
|
|
151
|
-
|
|
152
|
-
## Answers you can trust
|
|
153
|
-
|
|
154
|
-
UCN doesn't turn every matching name into a semantic claim. Watch it work
|
|
155
|
-
through a name with two definitions and a pile of ambiguous method calls:
|
|
156
|
-
|
|
157
|
-
```text
|
|
158
|
-
$ ucn impact saveCache
|
|
159
|
-
|
|
160
|
-
Impact analysis for saveCache
|
|
161
|
-
core/cache.js:610
|
|
162
|
-
Note: Found 2 definitions for "saveCache". Using core/cache.js:610. Also in: core/project.js:2380. Use file= to disambiguate.
|
|
163
|
-
CALL SITES: 5 confirmed + 15 unverified
|
|
164
|
-
Files affected: 3
|
|
165
|
-
BY FILE:
|
|
166
|
-
core/project.js:2380 [saveCache]: saveCache(cachePath) { return indexCache.saveCache(this, cachePath); }
|
|
167
|
-
test/prerelease-audit.test.js:1493: saveCache(built, cacheFile);
|
|
168
|
-
... (3 more)
|
|
169
|
-
UNVERIFIED CALL SITES (15) — call syntax, no binding/receiver evidence:
|
|
170
|
-
mcp/server.js:517: try { index.saveCache(); } catch (_) { /* best-effort */ } (possible-dispatch via local receiver)
|
|
171
|
-
test/cache.test.js:124: index.saveCache(); (possible-dispatch via local receiver)
|
|
172
|
-
(+13 more)
|
|
173
|
-
ACCOUNT: "saveCache" occurs on 68 lines in 11 files: 5 confirmed, 15 unverified,
|
|
174
|
-
12 non-call (3 import, 1 definition, 1 reference, 7 other-text), 36 other-target, 0 unaccounted
|
|
175
|
-
CONTRACT: literal-name text partition complete; semantic completeness is not claimed
|
|
176
|
-
(aliases, indirect calls, generated code, and runtime dispatch may exist).
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
UCN sorted all 68 places the name appears:
|
|
180
|
-
|
|
181
|
-
- **5 confirmed** - call sites it can *prove* resolve to this `saveCache`,
|
|
182
|
-
via a binding, import, receiver type, qualified path, or same-class evidence.
|
|
183
|
-
- **15 unverified** - real call syntax it refuses to claim. `index.saveCache()`
|
|
184
|
-
sits on an untyped receiver, so the site stays visible with its reason
|
|
185
|
-
(`possible-dispatch via local receiver`) instead of being guessed or dropped.
|
|
186
|
-
- **36 other-target** - occurrences that belong to the *other* `saveCache`,
|
|
187
|
-
kept out of the answer instead of quietly inflating it.
|
|
188
|
-
- **12 non-call** - imports, the definition, comments, strings.
|
|
189
|
-
- **0 unaccounted** - every observed line landed in exactly one bucket.
|
|
190
|
-
|
|
191
|
-
That's the payoff: an answer you (or your agent) can audit, instead of an
|
|
192
|
-
opaque match count. A confirmed edge is evidence about the pinned target. An
|
|
193
|
-
unverified edge is a review item with a stated reason. And a clean zero is an
|
|
194
|
-
*observed-text* zero, not a safe-to-delete claim: aliases, generated code,
|
|
195
|
-
reflection, runtime registration, and external consumers can live beyond the
|
|
196
|
-
indexed evidence, and `ucn repo --sections=health --deep` reports exactly those
|
|
197
|
-
blind spots. Even when output is truncated to fit an agent's budget, the
|
|
198
|
-
ACCOUNT, CONTRACT, and WARNING lines survive the cut.
|
|
199
|
-
|
|
200
|
-
### Measured against ground truth
|
|
201
|
-
|
|
202
|
-
Don't take the tiers on faith. Release gates re-derive UCN's answers from real
|
|
203
|
-
compilers and language servers on a ten-repository board of pinned production
|
|
204
|
-
codebases, and publishing is blocked unless they pass. The latest full
|
|
205
|
-
release-board run (2026-08-24):
|
|
206
|
-
|
|
207
|
-
| Repository | Pinned commit | Oracle | Caller precision | Caller recall | Callee prec / recall | Command checks |
|
|
208
|
-
|---|---|---|---:|---:|---:|---:|
|
|
209
|
-
| [preact-signals](https://github.com/preactjs/signals) | [`e0ce9fdf`](https://github.com/preactjs/signals/commit/e0ce9fdf92df7f0ece2c89d44554c39f36dc6882) | ts-morph | 100% | 100% | 100% / 100% | 100% |
|
|
210
|
-
| [httpx](https://github.com/encode/httpx) | [`b5addb64`](https://github.com/encode/httpx/commit/b5addb64f0161ff6bfe94c124ef76f6a1fba5254) | Pyright | 100% | 100% | 100% / 100% | 100% |
|
|
211
|
-
| [cobra](https://github.com/spf13/cobra) | [`ad460ea8`](https://github.com/spf13/cobra/commit/ad460ea8f249db69c943a365fb84f3a59042d54e) | gopls | 100% | 100% | 100% / 100% | 100% |
|
|
212
|
-
| [viper](https://github.com/spf13/viper) | [`528f7416`](https://github.com/spf13/viper/commit/528f7416c4b56a4948673984b190bf8713f0c3c4) | gopls | 100% | 100% | 100% / 100% | 100% |
|
|
213
|
-
| [ripgrep](https://github.com/BurntSushi/ripgrep) | [`82313cf9`](https://github.com/BurntSushi/ripgrep/commit/82313cf95849bfe425109ad9506a52154879b1b1) | rust-analyzer | 100% | 100% | 100% / 100% | 100% |
|
|
214
|
-
| [clap](https://github.com/clap-rs/clap) | [`d3e59a9a`](https://github.com/clap-rs/clap/commit/d3e59a9ab214910b9dad02921b7ef42c6400de9b) | rust-analyzer | 100% | 100% | 100% / 100% | 100% |
|
|
215
|
-
| [javapoet](https://github.com/square/javapoet) | [`b9017a95`](https://github.com/square/javapoet/commit/b9017a9503b76e11b4ad4c1a9f050e2d29112cb0) | JDT LS | 100% | 100% | 100% / 100% | 100% |
|
|
216
|
-
| [newtonsoft-json](https://github.com/JamesNK/Newtonsoft.Json) | [`4f73e743`](https://github.com/JamesNK/Newtonsoft.Json/commit/4f73e74372445108d2c1bda37b36e6f5e43402e0) | Roslyn | 100% | 100% | 100% / 100% | 100% |
|
|
217
|
-
| [cjson](https://github.com/DaveGamble/cJSON) | [`c859b25d`](https://github.com/DaveGamble/cJSON/commit/c859b25da02955fef659d658b8f324b5cde87be3) | clangd | 100% | 100% | 100% / 100% | 100% |
|
|
218
|
-
| [fmt](https://github.com/fmtlib/fmt) | [`e424e3f2`](https://github.com/fmtlib/fmt/commit/e424e3f2e607da02742f73db84873b8084fc714c) | clangd | 100% | 100% | 100% / 100% | 100% |
|
|
219
|
-
|
|
220
|
-
On the same run: **zero** in-scope oracle call edges missing from the answer
|
|
221
|
-
(the release gate) on every repository, **zero** false-dead `deadcode` claims
|
|
222
|
-
in the oracle-visible sample, **8,000 / 8,000** cross-command consistency
|
|
223
|
-
comparisons in agreement, **10 / 10** repositories inside the performance
|
|
224
|
-
budget (slowest normalized median cold build 17.4K lines/second by wall time,
|
|
225
|
-
worst query p95 83.0 ms, highest peak RSS 908.5 MB), and 3,609 automated tests with no
|
|
226
|
-
failures or skips. The same gates run in CI (the scheduled
|
|
227
|
-
[Eval workflow](https://github.com/mleoca/ucn/actions/workflows/eval.yml) and
|
|
228
|
-
every release tag), and `npm run trust:gate` reproduces the release board
|
|
229
|
-
locally. Pinned sources: [`eval/lib/repos.js`](eval/lib/repos.js).
|
|
230
|
-
|
|
231
|
-
Semantic runs draw a deterministic, reference-stratified sample of up to 50
|
|
232
|
-
compiler/LSP symbols per repository, then check caller identity, callee
|
|
233
|
-
identity, account conservation, review burden, and the public commands `find`,
|
|
234
|
-
`show`, `source`, `trace`, `impact`, `usages`, and `tests` against that same
|
|
235
|
-
external population. Unverified precision is reported separately and is
|
|
236
|
-
intentionally much lower on dispatch-heavy code: those entries are review
|
|
237
|
-
candidates, never confirmed claims.
|
|
238
|
-
|
|
239
|
-
Beyond the publish gate, a scheduled board re-checks 24 pinned repositories
|
|
240
|
-
across every supported oracle language (zod, express, hono, zustand, fastify,
|
|
241
|
-
rich, click, attrs, grpc-go, chi, cursive, itertools, gson, jsoup, and
|
|
242
|
-
friends), plus a rotating fresh-repo arm of codebases the engine was never
|
|
243
|
-
tuned on. Repositories that
|
|
244
|
-
expose a gap stay on the board; they don't get removed to keep a table pretty.
|
|
245
|
-
These are measured results on pinned code, not a claim of universal program
|
|
246
|
-
understanding or identical performance on every machine.
|
|
247
|
-
|
|
248
|
-
## Change code without breaking things
|
|
249
|
-
|
|
250
|
-
Will this change break a call site you've never seen? Check before you edit:
|
|
251
|
-
|
|
252
|
-
```text
|
|
253
|
-
$ ucn check expandGlob
|
|
254
|
-
|
|
255
|
-
Verification: expandGlob
|
|
256
|
-
════════════════════════════════════════════════════════════
|
|
257
|
-
core/discovery.js:314
|
|
258
|
-
expandGlob (pattern: string, options: number = {}) : string[]
|
|
259
|
-
|
|
260
|
-
Expected arguments: 1-2
|
|
261
|
-
|
|
262
|
-
STATUS: ✓ All calls valid
|
|
263
|
-
Total calls: 7
|
|
264
|
-
Valid: 7
|
|
265
|
-
Mismatches: 0
|
|
266
|
-
Uncertain: 0
|
|
267
|
-
Patterns: 4 in try, 4 in callback
|
|
268
|
-
|
|
269
|
-
ACCOUNT: "expandGlob" occurs on 14 lines in 6 files: 7 confirmed, 0 unverified,
|
|
270
|
-
7 non-call (4 import, 1 definition, 2 reference, 0 other-text), 0 other-target, 0 unaccounted
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
The `Patterns:` line classifies call-site structure (`inLoop`, `inTry`,
|
|
274
|
-
`inCallback`, `awaited`) so risky sites stand out. Then preview the refactor.
|
|
275
|
-
UCN shows exactly what would need to change and where:
|
|
276
|
-
|
|
277
|
-
```text
|
|
278
|
-
$ ucn plan expandGlob --rename-to=expandGlobPattern
|
|
279
|
-
|
|
280
|
-
Refactoring plan: rename
|
|
281
|
-
════════════════════════════════════════════════════════════
|
|
282
|
-
core/discovery.js:314
|
|
283
|
-
|
|
284
|
-
SIGNATURE CHANGE:
|
|
285
|
-
Before: expandGlob (pattern: string, options: number = {}) : string[]
|
|
286
|
-
After: expandGlobPattern (pattern: string, options: number = {}) : string[]
|
|
287
|
-
|
|
288
|
-
CHANGES NEEDED: 12
|
|
289
|
-
Files affected: 5
|
|
290
|
-
Definition 1, calls 7, references 0, text dependencies 0, imports 4, exports 0; manual review items 0
|
|
291
|
-
|
|
292
|
-
BY FILE:
|
|
293
|
-
|
|
294
|
-
cli/index.js (2 changes)
|
|
295
|
-
:771 [call]
|
|
296
|
-
const files = expandGlob(pattern);
|
|
297
|
-
→ Rename to: const files = expandGlobPattern(pattern);
|
|
298
|
-
:15 [import]
|
|
299
|
-
const { expandGlob, findProjectRoot } = require('../core/discovery');
|
|
300
|
-
→ Update import: const { expandGlobPattern, findProjectRoot } = require('../core/discovery');
|
|
301
|
-
|
|
302
|
-
... (more changes in core/discovery.js, core/cache.js, core/project.js, test/integration.test.js)
|
|
303
46
|
```
|
|
304
47
|
|
|
305
|
-
|
|
306
|
-
prove: overload/signature groups, base and override declarations, Rust trait
|
|
307
|
-
slots, Go interface slots and their satisfiers, exact call and value-reference
|
|
308
|
-
tokens, imports/exports, Python `__all__` strings, and module-attribute
|
|
309
|
-
references. Accessor renames also follow receiver-proven property reads and
|
|
310
|
-
writes. It edits exact token or expression spans, so another same-named call
|
|
311
|
-
on the same line is not swept up accidentally.
|
|
312
|
-
|
|
313
|
-
Open external interfaces, incomplete ownership, unresolved dispatch, or an
|
|
314
|
-
inexact token are marked `needsReview` instead of receiving a synthesized
|
|
315
|
-
edit. Comments and strings in indexed source appear as separate review items
|
|
316
|
-
and are never rewritten automatically; documentation, configuration,
|
|
317
|
-
generated files, and unsupported languages get an explicit exact-text search
|
|
318
|
-
handoff. `plan` previews changes; it does not modify files or replace the
|
|
319
|
-
compiler and test suite. Before committing, point the same machinery at your
|
|
320
|
-
Git diff:
|
|
48
|
+
## In the shell
|
|
321
49
|
|
|
322
|
-
|
|
323
|
-
ucn impact --staged # what did I change, and who depends on it?
|
|
324
|
-
ucn check --staged # signature drift, orphaned functions, tests to run
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
## Pick the right tests
|
|
328
|
-
|
|
329
|
-
Which tests actually exercise this function, directly or three hops away?
|
|
330
|
-
|
|
331
|
-
```text
|
|
332
|
-
$ ucn tests expandGlob --depth=3
|
|
333
|
-
|
|
334
|
-
affected-tests: expandGlob
|
|
335
|
-
════════════════════════════════════════════════════════════
|
|
336
|
-
core/discovery.js:314
|
|
337
|
-
1 function changed → 12 functions affected (depth 3)
|
|
338
|
-
|
|
339
|
-
Test files to run (30):
|
|
340
|
-
|
|
341
|
-
test/integration.test.js (links: expandGlob, build, idx, setupProject)
|
|
342
|
-
L169: const files = expandGlob('**/*.go', { root: tmpDir }); [call]
|
|
343
|
-
test/prerelease-audit.test.js (links: isCacheStale, runInteractive, build, idx)
|
|
344
|
-
L39: const index = idx(dir); [call]
|
|
345
|
-
...
|
|
346
|
-
|
|
347
|
-
Summary: 12 affected → 30 statically linked test files, 5/12 functions linked (42%) · 1 possibly affected (unverified chains)
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
`tests` reports static call/reference linkage, not runtime coverage. Functions
|
|
351
|
-
reached only through unverified edges are listed separately as *possibly
|
|
352
|
-
affected*, and empty results warn about subprocess tests, reflection, and
|
|
353
|
-
external harnesses that may still exercise the target.
|
|
354
|
-
|
|
355
|
-
## Get the lay of the land
|
|
356
|
-
|
|
357
|
-
One command answers "what is this codebase?" Here it is on ripgrep:
|
|
358
|
-
|
|
359
|
-
```text
|
|
360
|
-
$ ucn repo
|
|
361
|
-
|
|
362
|
-
PROJECT ORIENTATION — ripgrep
|
|
363
|
-
════════════════════════════════════════════════════════════
|
|
364
|
-
100 files · 4755 symbols · language mix by symbols: rust 100%
|
|
365
|
-
|
|
366
|
-
TOP DIRS (by symbols):
|
|
367
|
-
crates/core/flags 1510 symbols · 6 file(s)
|
|
368
|
-
crates/printer/src 677 symbols · 11 file(s)
|
|
369
|
-
crates/ignore/src 607 symbols · 8 file(s)
|
|
370
|
-
crates/globset/src 331 symbols · 5 file(s)
|
|
371
|
-
|
|
372
|
-
HOT (most-called production functions, top 8 of 2238 raw candidates):
|
|
373
|
-
parse_low_raw — 545 call(s) · crates/core/flags/parse.rs:139
|
|
374
|
-
SearcherBuilder.build — 123 call(s) · crates/searcher/src/searcher/mod.rs:315
|
|
375
|
-
Searcher.search_reader — 123 call(s) · crates/searcher/src/searcher/mod.rs:727
|
|
376
|
-
RegexMatcher.new — 100 call(s) · crates/regex/src/matcher.rs:385
|
|
377
|
-
...
|
|
378
|
-
|
|
379
|
-
ENTRY POINTS: 426 — test 421, runtime 5
|
|
380
|
-
TRUST: PARTIAL — 48 glob import(s), 5 unsupported source file(s) (ucn repo --sections=health --deep for detail)
|
|
381
|
-
SKIPPED SOURCE: 5 file(s) (Shell 4, Ruby 1) — use grep/ripgrep plus a language-native analyzer.
|
|
382
|
-
|
|
383
|
-
Next: ucn show parse_low_raw · ucn repo --sections=files --detailed · ucn repo --sections=health --deep
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
Size, layout, hot spots, entry points, and an honest trust line. Note the
|
|
387
|
-
`SKIPPED SOURCE` handoff: when a repo mixes in languages UCN can't parse, it
|
|
388
|
-
says so and points you at the right tool, instead of presenting a clean-looking
|
|
389
|
-
answer over a partial index.
|
|
390
|
-
|
|
391
|
-
## Find dead code you can act on
|
|
392
|
-
|
|
393
|
-
```text
|
|
394
|
-
$ ucn deadcode --exclude=test # run on ripgrep
|
|
395
|
-
|
|
396
|
-
Dead code: 3 unused symbol(s)
|
|
397
|
-
|
|
398
|
-
crates/globset/src/serde_impl.rs
|
|
399
|
-
[ 38- 42] Glob.deserialize (method)
|
|
400
|
-
[ 70- 74] GlobSet.deserialize (method)
|
|
401
|
-
crates/matcher/src/lib.rs
|
|
402
|
-
[ 397- 399] Captures.as_match (method)
|
|
403
|
-
|
|
404
|
-
33 decorated/annotated symbol(s) hidden (framework-registered). Use --include-decorated to include them.
|
|
405
|
-
|
|
406
|
-
903 exported symbol(s) excluded from the audit (public API may have external callers). Use --include-exported to audit them.
|
|
407
|
-
|
|
408
|
-
WARNING: source coverage is incomplete (5 unsupported-language); 17 candidate name(s) found in skipped source were suppressed.
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
Three claims, and every one is re-checked against rust-analyzer in CI: a
|
|
412
|
-
default-audit claim with an oracle-visible reference fails the build. Notice
|
|
413
|
-
what it *didn't* claim: exported API that external code may call,
|
|
414
|
-
framework-registered symbols, and anything whose name appears in files UCN
|
|
415
|
-
couldn't parse. A literal reflection target such as `getattr(obj, "run")`
|
|
416
|
-
also withholds matching member names from deletion candidates; recognized
|
|
417
|
-
dynamic reflection is counted and warned because it cannot be attributed.
|
|
418
|
-
`deadcode` is deliberately a candidate generator. Before
|
|
419
|
-
deleting, corroborate with `usages`, `impact`, `api`, and your compiler and
|
|
420
|
-
tests.
|
|
421
|
-
|
|
422
|
-
For missing-await bugs, `ucn audit-async` lists async calls inside async
|
|
423
|
-
functions that lack `await` (JS/TS/Python).
|
|
424
|
-
|
|
425
|
-
## Map dependencies and API surfaces
|
|
50
|
+
From a project directory:
|
|
426
51
|
|
|
427
52
|
```bash
|
|
428
|
-
ucn
|
|
429
|
-
ucn
|
|
430
|
-
ucn
|
|
431
|
-
ucn
|
|
432
|
-
ucn
|
|
433
|
-
ucn endpoints --bridge --unmatched # server routes with no client, and vice versa
|
|
53
|
+
ucn repo
|
|
54
|
+
ucn show handleRequest --lines
|
|
55
|
+
ucn source handleRequest --raw
|
|
56
|
+
ucn impact --staged --lines
|
|
57
|
+
ucn check --staged
|
|
434
58
|
```
|
|
435
59
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
`
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
##
|
|
60
|
+
`repo` maps the project. `show --lines` locates callers, `source --raw`
|
|
61
|
+
retrieves the implementation, and `impact` and `check` inspect a staged change.
|
|
62
|
+
When a name is ambiguous, `find` returns a `file:line:name` handle that
|
|
63
|
+
subsequent commands accept.
|
|
64
|
+
|
|
65
|
+
`--lines` returns `path:line:text` records; `--raw` returns source code.
|
|
66
|
+
Both fit an agent's existing scripts without parsing a human-readable report.
|
|
67
|
+
|
|
68
|
+
Text search remains useful for comments, configuration, strings, and code
|
|
69
|
+
outside the supported languages. `usages` provides the literal-name inventory
|
|
70
|
+
when the task needs every occurrence, including those that are not calls.
|
|
71
|
+
|
|
72
|
+
## Code navigation and change analysis
|
|
73
|
+
|
|
74
|
+
`show` gathers a symbol's signature, source, callers, callees, and related
|
|
75
|
+
context. Select the sections you need or set an output budget to keep the
|
|
76
|
+
answer focused. `trace` follows the call graph across files, down into callees
|
|
77
|
+
or up through callers toward entry points. Unverified relationships remain
|
|
78
|
+
visible, and the tree's accounting reports where exploration stopped.
|
|
79
|
+
|
|
80
|
+
`impact` connects a symbol or Git diff to its callers. `tests` follows indexed
|
|
81
|
+
call and reference paths to identify statically linked tests, including links
|
|
82
|
+
several hops away. `plan` previews a rename or signature change with source
|
|
83
|
+
locations and review items; it does not edit files. Together these commands
|
|
84
|
+
support code exploration, refactoring, and change review from a terminal or
|
|
85
|
+
an AI agent.
|
|
86
|
+
|
|
87
|
+
## What an answer establishes
|
|
88
|
+
|
|
89
|
+
For caller answers, UCN checks bindings, imports, receiver types, and ownership
|
|
90
|
+
to distinguish calls to the selected definition from other uses of its name.
|
|
91
|
+
Calls without enough evidence stay visible as unverified, with a reason.
|
|
92
|
+
A matching method name alone does not establish which implementation runs;
|
|
93
|
+
receiver and ownership evidence determine how the candidate is classified.
|
|
94
|
+
|
|
95
|
+
In ripgrep at [`82313cf9`](https://github.com/BurntSushi/ripgrep/commit/82313cf95849bfe425109ad9506a52154879b1b1),
|
|
96
|
+
the selected `file_name` helper has four confirmed call sites and one unverified
|
|
97
|
+
candidate. This animation accounts for all 29 matching lines, alongside import
|
|
98
|
+
relationships and same-name definitions drawn from UCN's output.
|
|
99
|
+
|
|
100
|
+
<a href="assets/readme/ucn-evidence-graph.gif"><img src="assets/readme/ucn-evidence-graph.gif" width="736" alt="Captured ripgrep findings for file_name: 29 matching lines in six files, partitioned into 4 confirmed calls, 1 unverified candidate, 17 non-call lines, 7 other-target lines, and 0 unaccounted. The graph shows selected import relationships and the distinct definitions; motion is illustrative."></a>
|
|
101
|
+
|
|
102
|
+
Captured findings · [Still image](assets/readme/ucn-evidence-graph.png) · [Data](assets/readme/ucn-evidence-graph.json)
|
|
103
|
+
|
|
104
|
+
The ACCOUNT line reconciles the observed name occurrences: confirmed calls,
|
|
105
|
+
unverified candidates, non-call occurrences, and matches attributed to another
|
|
106
|
+
target. CONTRACT describes the scope of that accounting. Warnings identify
|
|
107
|
+
source the index could not cover. These details survive text truncation for
|
|
108
|
+
an agent's output budget.
|
|
109
|
+
|
|
110
|
+
An empty result therefore means something specific about the inspected code.
|
|
111
|
+
It cannot establish that reflection, generated code, runtime registration, or
|
|
112
|
+
external consumers never reach a symbol. `deadcode` supplies candidates to
|
|
113
|
+
investigate; deletion still needs corroboration. A refactor preview still
|
|
114
|
+
needs the compiler and tests.
|
|
115
|
+
|
|
116
|
+
## Accuracy and validation
|
|
117
|
+
|
|
118
|
+
Release gates compare UCN's answers with independent compilers and language
|
|
119
|
+
servers on a ten-repository board of pinned production codebases. The local
|
|
120
|
+
September 6, 2026 evaluation recorded these sampled caller results:
|
|
121
|
+
|
|
122
|
+
| Repository | Pinned commit | Oracle | Symbols sampled | Confirmed precision | In-scope recall |
|
|
123
|
+
|---|---|---|---:|---:|---:|
|
|
124
|
+
| preact-signals | `e0ce9fdf` | ts-morph | 27 | 100% | 100% |
|
|
125
|
+
| httpx | `b5addb64` | Pyright | 50 | 100% | 100% |
|
|
126
|
+
| cobra | `ad460ea8` | gopls | 50 | 100% | 100% |
|
|
127
|
+
| viper | `528f7416` | gopls | 50 | 100% | 100% |
|
|
128
|
+
| ripgrep | `82313cf9` | rust-analyzer | 41 | 100% | 100% |
|
|
129
|
+
| clap | `d3e59a9a` | rust-analyzer | 50 | 100% | 100% |
|
|
130
|
+
| javapoet | `b9017a95` | JDT LS | 50 | 100% | 100% |
|
|
131
|
+
| newtonsoft-json | `4f73e743` | Roslyn | 50 | 100% | 100% |
|
|
132
|
+
| cjson | `c859b25d` | clangd | 50 | 100% | 100% |
|
|
133
|
+
| fmt | `e424e3f2` | clangd | 50 | 100% | 100% |
|
|
134
|
+
|
|
135
|
+
That evaluation reported zero missing in-scope oracle edges in both caller
|
|
136
|
+
and callee answers, and 8,000 cross-command comparisons with zero disagreements.
|
|
137
|
+
The default dead-code audit found zero false-dead results among 13 scored
|
|
138
|
+
claims; 13 additional claims could not be pinned by the oracle and were unscored.
|
|
139
|
+
All ten repositories passed the performance budgets, with steady-state query
|
|
140
|
+
p95 from 4.5 to 76.2 ms. Those timings exclude process startup and indexing;
|
|
141
|
+
cold builds and cache loading are measured separately.
|
|
142
|
+
|
|
143
|
+
The samples are deterministic and stratified by reference activity. Confirmed
|
|
144
|
+
precision applies to scored claims; recall counts in-scope oracle edges found
|
|
145
|
+
in either the confirmed or unverified band. Unverified candidates, oracle
|
|
146
|
+
abstentions, and unscored findings remain separate. These measurements do not
|
|
147
|
+
establish complete runtime knowledge or identical performance on every machine.
|
|
148
|
+
|
|
149
|
+
The scheduled board covers 24 pinned repositories: the ten above plus zod,
|
|
150
|
+
express, hono, zustand, fastify, rich, click, attrs, grpc-go, chi, cursive,
|
|
151
|
+
itertools, gson, and jsoup. A rotating fresh-repository arm checks codebases
|
|
152
|
+
outside that pinned board.
|
|
153
|
+
|
|
154
|
+
The [repository manifest](eval/lib/repos.js) records the full commits.
|
|
155
|
+
The [Publish workflow](https://github.com/mleoca/ucn/actions/workflows/publish.yml)
|
|
156
|
+
gates releases, and the [Eval workflow](https://github.com/mleoca/ucn/actions/workflows/eval.yml)
|
|
157
|
+
runs the checks on schedule and on demand. Their run pages provide CI results
|
|
158
|
+
and evaluation artifacts. Reproduce the checks locally with the oracle
|
|
159
|
+
dependencies installed:
|
|
449
160
|
|
|
450
161
|
```bash
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
ucn search '$scope.$apply' # literal by default
|
|
454
|
-
ucn search 'TODO|FIXME' --regex # regex is explicit
|
|
455
|
-
ucn search --type=call --receiver=client # structural search
|
|
456
|
-
ucn usages expandGlob --include-tests # every occurrence, classified
|
|
162
|
+
npm run verify
|
|
163
|
+
npm run trust:gate
|
|
457
164
|
```
|
|
458
165
|
|
|
459
|
-
|
|
460
|
-
definitions, imports, references, comments, strings), for when you want
|
|
461
|
-
everything the text contains, not just what the engine can prove. Regex search runs on an
|
|
462
|
-
RE2-compatible linear-time engine; hostile nested repetition is rejected up
|
|
463
|
-
front instead of hanging your terminal.
|
|
464
|
-
|
|
465
|
-
## The 18 commands
|
|
166
|
+
## Commands
|
|
466
167
|
|
|
467
168
|
| Task | Command |
|
|
468
169
|
|---|---|
|
|
@@ -485,100 +186,32 @@ front instead of hanging your terminal.
|
|
|
485
186
|
| Likely missing awaits | `audit-async` |
|
|
486
187
|
| Stack-trace frame resolution | `stacktrace <text>` |
|
|
487
188
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
189
|
+
`deps --cycles` groups circular dependencies and distinguishes eager imports
|
|
190
|
+
from deferred or type-only edges. Enumeration limits are disclosed. `repo`
|
|
191
|
+
reports source coverage as well as project structure; its quick HOT ranking
|
|
192
|
+
has a disclosed refinement budget, and `repo --sections=stats --hot` requests
|
|
193
|
+
the exact ranking.
|
|
493
194
|
|
|
494
|
-
|
|
195
|
+
`endpoints --bridge` matches server routes and client requests recognized by
|
|
196
|
+
its framework extractors. `plan` handles code relationships
|
|
197
|
+
such as imports, overrides, and interface or trait methods when ownership is
|
|
198
|
+
resolved; ambiguous relationships remain review items.
|
|
495
199
|
|
|
496
|
-
|
|
497
|
-
commands
|
|
498
|
-
same answers everywhere, different delivery.
|
|
200
|
+
Run `ucn --help` for flags, or use the
|
|
201
|
+
[command reference](.claude/skills/ucn/references/commands.md).
|
|
499
202
|
|
|
500
|
-
|
|
501
|
-
- MCP exposes exactly one tool named `ucn`. Its `command` enum lists the 18
|
|
502
|
-
tasks, snake_cased where needed (`audit_async`, `project_dir`, `class_name`).
|
|
503
|
-
A persistent MCP process keeps the index warm across calls.
|
|
504
|
-
- Targeted text answers default to a 10K-character budget, broad ones to 3K,
|
|
505
|
-
ceiling 100K (`--max-chars` / `max_chars`). Truncation preserves ACCOUNT,
|
|
506
|
-
CONTRACT, and WARNING lines; JSON is never text-truncated.
|
|
203
|
+
## Shell output
|
|
507
204
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
```
|
|
205
|
+
Records and code go to stdout; accounting and notes go to stderr. Unverified
|
|
206
|
+
records carry a tab-separated reason. An empty listing exits 1, an error
|
|
207
|
+
exits 2, and a successful listing exits 0. `--lines` supports `find`, `show`,
|
|
208
|
+
`usages`, `search`, and `impact`; `show --lines` lists callers by default.
|
|
209
|
+
Use `--json` when the script needs structured fields or a tree result.
|
|
514
210
|
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
The incremental index lives under your user cache root, not in the repo:
|
|
521
|
-
`UCN_CACHE_DIR` if set, else `$XDG_CACHE_HOME/ucn`, `~/Library/Caches/ucn`
|
|
522
|
-
(macOS), `%LOCALAPPDATA%/ucn/cache` (Windows), or `~/.cache/ucn`. Canonical
|
|
523
|
-
path hashes keep same-named checkouts separate. `--no-cache` bypasses,
|
|
524
|
-
`--clear-cache` clears the current project, `--clear-cache --all` clears every
|
|
525
|
-
bounded UCN cache. Old in-project `.ucn-cache` directories are migrated out
|
|
526
|
-
automatically on first use.
|
|
527
|
-
|
|
528
|
-
## Language coverage
|
|
529
|
-
|
|
530
|
-
All parsers feed the same versioned language IR and index path, and sequential
|
|
531
|
-
and worker builds are tested to produce identical symbols, calls, imports, and
|
|
532
|
-
evidence.
|
|
533
|
-
|
|
534
|
-
- **JavaScript / TypeScript / JSX / TSX** - functions, classes,
|
|
535
|
-
imports/exports, typed receivers, aliases, callbacks, async flow, framework
|
|
536
|
-
roots.
|
|
537
|
-
- **Python** - functions, classes, annotations, decorators, imports,
|
|
538
|
-
comprehensions, context-manager bindings, async flow, framework roots.
|
|
539
|
-
- **Go, Rust, Java** - nominal receivers, methods,
|
|
540
|
-
inheritance/traits/interfaces, package and path ownership, overload/arity
|
|
541
|
-
discipline, framework roots.
|
|
542
|
-
- **C** - functions, structs, macros, includes, calls, entry points, API
|
|
543
|
-
analysis.
|
|
544
|
-
- **C++** - C coverage plus classes, methods, constructors, inheritance,
|
|
545
|
-
namespaces, overloads, templates, typed field receivers, static array-shape
|
|
546
|
-
selection, and macro requalification. Conditional macro disagreement stays
|
|
547
|
-
visible as unverified.
|
|
548
|
-
- **C#** - namespaces, classes/interfaces/records, fields/properties,
|
|
549
|
-
attributes, declared property/field receiver types, overload and hiding
|
|
550
|
-
discipline, async flow, top-level programs, .NET stack frames, and
|
|
551
|
-
ASP.NET/HttpClient endpoints.
|
|
552
|
-
- **HTML** - inline JavaScript and `on*` event handlers.
|
|
553
|
-
|
|
554
|
-
For C and C++, a `compile_commands.json` improves header-language,
|
|
555
|
-
include-path, and ownership context when available. UCN keeps AST-proven
|
|
556
|
-
definitions from recoverable preprocessor branches without claiming which
|
|
557
|
-
branch a particular build activates.
|
|
558
|
-
|
|
559
|
-
## Testing and reliability
|
|
560
|
-
|
|
561
|
-
- **Regression discipline** - every fixed defect gets a focused test.
|
|
562
|
-
- **Surface coverage** - all 18 commands run through CLI text, CLI JSON, and
|
|
563
|
-
MCP; parity between them is guarded by architecture tests.
|
|
564
|
-
- **External ground truth** - real compilers and language servers adjudicate
|
|
565
|
-
caller, callee, command, and dead-code claims on pinned repositories
|
|
566
|
-
([see the board](#measured-against-ground-truth)).
|
|
567
|
-
- **Release-blocking budgets** - publishing requires 100% in-scope semantic
|
|
568
|
-
recall, ≥98% confirmed precision, a conserved account for every sample, zero
|
|
569
|
-
cross-command disagreements, zero default-arm false-dead claims, and the
|
|
570
|
-
performance gate (≥10K lines/second cold build by wall time and ≥3K by CPU
|
|
571
|
-
time, query p50 ≤75 ms, p95 ≤250 ms, bounded peak RSS), all on the actual
|
|
572
|
-
release board.
|
|
573
|
-
|
|
574
|
-
```bash
|
|
575
|
-
npm run verify # lint + full test suite
|
|
576
|
-
npm run trust:gate # the release board: semantic, dead-code, consistency, performance
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
Gate runs write their reports under `eval/reports/` as local run artifacts;
|
|
580
|
-
the pinned manifest is [`eval/lib/repos.js`](eval/lib/repos.js). Before a tag,
|
|
581
|
-
the Eval workflow's pre-tag dry run must pass on the actual CI runner.
|
|
211
|
+
Listings have no default row cap. Explicit limits disclose what they omit,
|
|
212
|
+
and a shell-mode character budget fails before writing partial output.
|
|
213
|
+
`source --raw` extracts complete functions and classes unless an explicit
|
|
214
|
+
line limit is requested; any resulting truncation is reported on stderr.
|
|
582
215
|
|
|
583
216
|
## AI setup
|
|
584
217
|
|
|
@@ -657,28 +290,20 @@ The skill teaches an agent how to orient, pin symbols, choose the smallest
|
|
|
657
290
|
useful command, interpret the evidence tiers, and recover from incomplete
|
|
658
291
|
answers. It's guidance over the same engine, not a second implementation.
|
|
659
292
|
|
|
660
|
-
##
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
semantics stay outside the index.
|
|
675
|
-
- HTML has regression coverage but no compiler/LSP real-repository oracle.
|
|
676
|
-
- Large repos take a few seconds on the first query, then use the cache.
|
|
677
|
-
|
|
678
|
-
If a decision needs compiler completeness or runtime truth, use the compiler,
|
|
679
|
-
the type checker, the test runner, or a profiler. Those are different tools
|
|
680
|
-
for different jobs. UCN's job is getting you to the right code fast, with
|
|
681
|
-
answers you can audit.
|
|
293
|
+
## Scope
|
|
294
|
+
|
|
295
|
+
UCN analyzes indexed source in one project. It does not execute the program
|
|
296
|
+
or index installed dependencies such as `node_modules` and `site-packages`.
|
|
297
|
+
`repo --sections=health --deep` reports source coverage and known analysis
|
|
298
|
+
limits.
|
|
299
|
+
|
|
300
|
+
C and C++ can use `compile_commands.json` for include paths and header context,
|
|
301
|
+
but UCN does not run the preprocessor or reproduce a compiler's build-specific
|
|
302
|
+
view. C# source generators and external assemblies are also outside the
|
|
303
|
+
index. HTML has regression coverage but no compiler/LSP repository oracle.
|
|
304
|
+
|
|
305
|
+
The CLI, MCP, and skill share the same resolution rules and evidence. Changing
|
|
306
|
+
the transport does not change what the engine knows about the code.
|
|
682
307
|
|
|
683
308
|
---
|
|
684
309
|
|