knodin 0.7.6 → 0.8.3
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 +41 -12
- package/benchmarks/competitors/SYNTHESIS.md +66 -0
- package/dist/bin/cli.js +2181 -108
- package/dist/bin/launcher.js +25 -3
- package/dist/src/agent-integration.js +304 -0
- package/dist/src/artifact-refresh.js +82 -0
- package/dist/src/cli-args.js +292 -0
- package/dist/src/cli-model.js +384 -0
- package/dist/src/codeflow-replay.js +81 -0
- package/dist/src/compact-structural.js +96 -0
- package/dist/src/compare.js +39 -0
- package/dist/src/competitive-cold-mcp.js +40 -0
- package/dist/src/competitive-constraints.js +21 -0
- package/dist/src/competitive-manifest.js +411 -0
- package/dist/src/competitive-measurement.js +183 -0
- package/dist/src/competitive-runner.js +487 -0
- package/dist/src/competitive-sandbox.js +108 -0
- package/dist/src/context-export.js +423 -0
- package/dist/src/context.js +102 -0
- package/dist/src/deterministic-random.js +34 -0
- package/dist/src/diagnostics-write-helper.js +473 -0
- package/dist/src/diagnostics.js +1476 -0
- package/dist/src/docs-sections.js +142 -0
- package/dist/src/doctor.js +382 -0
- package/dist/src/engine/ann-hnsw.js +261 -0
- package/dist/src/engine/embeddings.js +193 -0
- package/dist/src/engine/file-walker.js +49 -0
- package/dist/src/engine/git-history.js +289 -0
- package/dist/src/engine/index.js +15094 -0
- package/dist/src/engine/perf.js +115 -0
- package/dist/src/engine/prune.js +112 -0
- package/dist/src/engine/sarif-import.js +341 -0
- package/dist/src/engine/scip-import.js +423 -0
- package/dist/src/engine/source-policy.js +85 -0
- package/dist/src/engine/sqlite.js +71 -0
- package/dist/src/engine/state-paths.js +175 -0
- package/dist/src/engine/symbol-delete.js +58 -0
- package/dist/src/execution-profile.js +208 -0
- package/dist/src/failure-diagnosis.js +655 -0
- package/dist/src/fleet.js +7 -0
- package/dist/src/git-executable.js +31 -0
- package/dist/src/graph-layout.js +173 -0
- package/dist/src/graph-query-health.js +115 -0
- package/dist/src/hook-manager-integration.js +156 -0
- package/dist/src/index-activity.js +126 -0
- package/dist/src/init-progress-worker.js +70 -2
- package/dist/src/init-progress.js +155 -0
- package/dist/src/init.js +1295 -0
- package/dist/src/lifecycle-health.js +282 -0
- package/dist/src/lsp-readonly.js +217 -0
- package/dist/src/mcp-graph-worker.js +69 -0
- package/dist/src/mcp-reliability.js +154 -0
- package/dist/src/mcp-worker-supervisor.js +350 -0
- package/dist/src/mirror.js +290 -0
- package/dist/src/node-runtime.js +157 -0
- package/dist/src/output-compression.js +630 -0
- package/dist/src/output-telemetry.js +368 -0
- package/dist/src/pr-triage.js +638 -0
- package/dist/src/progress-worker-runtime.js +46 -0
- package/dist/src/progressive-evidence.js +477 -0
- package/dist/src/pure-compression-cli.js +102 -0
- package/dist/src/relationship-adapters.js +377 -0
- package/dist/src/release-attestation.js +533 -0
- package/dist/src/release-preflight.js +513 -0
- package/dist/src/repair-lease.js +85 -0
- package/dist/src/repair-progress-worker.js +83 -2
- package/dist/src/repair-progress.js +262 -0
- package/dist/src/repository-init-process.js +177 -0
- package/dist/src/repository-management.js +1261 -0
- package/dist/src/resource-reachability.js +456 -0
- package/dist/src/response-budget.js +200 -0
- package/dist/src/server.js +217 -0
- package/dist/src/structural-fast-path.js +344 -0
- package/dist/src/structural-snapshot.js +37 -0
- package/dist/src/system-config.js +638 -0
- package/dist/src/terminal-help.js +83 -0
- package/dist/src/tools/knodin-tools.js +1645 -0
- package/dist/src/update-ceremony.js +162 -0
- package/dist/src/update-policy.js +944 -0
- package/dist/src/update-trust.js +504 -0
- package/dist/src/version.js +13 -0
- package/dist/src/visualization.js +515 -0
- package/dist/src/wait-for-fresh.js +98 -0
- package/dist/src/worktree-lifecycle.js +234 -0
- package/docs/BEHAVIORAL-CONTRACT.md +114 -0
- package/docs/CLI.md +30 -1
- package/docs/COMPARISON.md +413 -0
- package/docs/COMPETITIVE-LANDSCAPE-2026-08.md +267 -0
- package/docs/CONTAINED-EXECUTION.md +77 -0
- package/docs/DEMO.md +49 -0
- package/docs/DIAGNOSTICS.md +80 -0
- package/docs/GIT-HISTORY-REVIEW.md +39 -0
- package/docs/HANDOFF.md +180 -0
- package/docs/INSTALLATION.md +21 -18
- package/docs/MCP.md +64 -8
- package/docs/PROGRESSIVE-EVIDENCE.md +37 -0
- package/docs/PT-ACCESS-RECOMMENDATION.md +89 -0
- package/docs/RELEASE-0.3-EVIDENCE.md +73 -0
- package/docs/REPOSITORIES-AND-WORKTREES.md +18 -6
- package/docs/SCIP-IMPORT.md +62 -0
- package/docs/SIGNED-UPDATES.md +151 -0
- package/docs/TELEMETRY.md +46 -0
- package/docs/TOKEN-OPTIMIZER-SCORECARD.md +79 -0
- package/docs/assets/knodin-favicon.svg +4 -0
- package/docs/releases/0.3.0.md +46 -0
- package/docs/releases/0.4.0.md +68 -0
- package/docs/releases/0.4.1.md +28 -0
- package/docs/releases/0.4.2.md +27 -0
- package/docs/releases/0.4.3.md +23 -0
- package/docs/releases/0.5.0.md +29 -0
- package/docs/releases/0.5.1.md +17 -0
- package/docs/releases/0.6.0.md +18 -0
- package/docs/releases/0.7.0.md +24 -0
- package/docs/releases/0.7.1.md +21 -0
- package/docs/releases/0.7.2.md +21 -0
- package/docs/releases/0.7.3.md +23 -0
- package/docs/releases/0.7.4.md +17 -0
- package/docs/releases/0.7.5.md +20 -0
- package/docs/releases/0.8.0.md +74 -0
- package/docs/releases/0.8.2.md +34 -0
- package/docs/releases/0.8.3.md +47 -0
- package/package.json +139 -4
- package/roadmap/competitive-roadmap.md +3896 -0
- package/schemas/release-attestation-v1.schema.json +210 -0
- package/schemas/support-bundle-v2.schema.json +212 -0
- package/dist/chunks/chunk-DMQAGX77.js +0 -654
- package/dist/chunks/chunk-F4Z3Z766.js +0 -4
- package/dist/chunks/chunk-SIJAQVSX.js +0 -3
- package/dist/chunks/chunk-X6M4HUUE.js +0 -2
- package/dist/chunks/chunk-YPRMY2LP.js +0 -8
- package/dist/chunks/pure-compression-cli-4TA2TQD5.js +0 -5
- package/dist/chunks/server-7EDF4CBY.js +0 -14
- package/dist/chunks/structural-fast-path-KD5KQSPX.js +0 -4
- package/docs/releases/0.7.6.md +0 -25
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import childProcess from "node:child_process";
|
|
2
|
+
import crypto from "node:crypto";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { compareBytes } from "./compare.js";
|
|
6
|
+
function git(repo, args) {
|
|
7
|
+
return childProcess.execFileSync("git", args, {
|
|
8
|
+
cwd: repo,
|
|
9
|
+
encoding: "utf-8",
|
|
10
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function canonicalPath(target) {
|
|
14
|
+
try {
|
|
15
|
+
return fs.realpathSync(target);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return path.resolve(target);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function commonDirectory(repo) {
|
|
22
|
+
const value = git(repo, ["rev-parse", "--path-format=absolute", "--git-common-dir"]).trim();
|
|
23
|
+
return path.resolve(repo, value);
|
|
24
|
+
}
|
|
25
|
+
function registryPath(repo) {
|
|
26
|
+
return path.join(commonDirectory(repo), "knodin", "worktrees.json");
|
|
27
|
+
}
|
|
28
|
+
function emptyRegistry() {
|
|
29
|
+
return { schemaVersion: 1, graphState: "per-worktree", entries: [] };
|
|
30
|
+
}
|
|
31
|
+
function readRegistry(repo) {
|
|
32
|
+
try {
|
|
33
|
+
const parsed = JSON.parse(fs.readFileSync(registryPath(repo), "utf-8"));
|
|
34
|
+
return parsed.schemaVersion === 1 && Array.isArray(parsed.entries) ? parsed : emptyRegistry();
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return emptyRegistry();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function writeRegistry(repo, registry) {
|
|
41
|
+
const target = registryPath(repo);
|
|
42
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
43
|
+
const temporary = `${target}.${process.pid}.tmp`;
|
|
44
|
+
fs.writeFileSync(temporary, `${JSON.stringify(registry, null, 2)}\n`, { mode: 0o600 });
|
|
45
|
+
fs.renameSync(temporary, target);
|
|
46
|
+
}
|
|
47
|
+
function identityFor(repo, worktreePath, classification) {
|
|
48
|
+
let administrativePath = classification;
|
|
49
|
+
try {
|
|
50
|
+
administrativePath = path.resolve(worktreePath, git(worktreePath, ["rev-parse", "--path-format=absolute", "--git-dir"]).trim());
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// A removed worktree retains its registry identity.
|
|
54
|
+
}
|
|
55
|
+
return crypto
|
|
56
|
+
.createHash("sha256")
|
|
57
|
+
.update(`${commonDirectory(repo)}\0${administrativePath}`)
|
|
58
|
+
.digest("hex")
|
|
59
|
+
.slice(0, 24);
|
|
60
|
+
}
|
|
61
|
+
function listGitWorktrees(repo) {
|
|
62
|
+
const fields = git(repo, ["worktree", "list", "--porcelain", "-z"]).split("\0");
|
|
63
|
+
const records = [];
|
|
64
|
+
for (const field of fields) {
|
|
65
|
+
if (field.startsWith("worktree ")) {
|
|
66
|
+
records.push({
|
|
67
|
+
path: path.resolve(field.slice("worktree ".length)),
|
|
68
|
+
classification: records.length === 0 ? "main" : "linked",
|
|
69
|
+
head: null,
|
|
70
|
+
branch: null,
|
|
71
|
+
locked: false,
|
|
72
|
+
prunable: null,
|
|
73
|
+
});
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const current = records.at(-1);
|
|
77
|
+
if (!current)
|
|
78
|
+
continue;
|
|
79
|
+
if (field.startsWith("HEAD "))
|
|
80
|
+
current.head = field.slice(5);
|
|
81
|
+
else if (field.startsWith("branch "))
|
|
82
|
+
current.branch = field.slice(7).replace(/^refs\/heads\//, "");
|
|
83
|
+
else if (field === "detached")
|
|
84
|
+
current.branch = null;
|
|
85
|
+
else if (field.startsWith("locked"))
|
|
86
|
+
current.locked = true;
|
|
87
|
+
else if (field.startsWith("prunable "))
|
|
88
|
+
current.prunable = field.slice(9);
|
|
89
|
+
}
|
|
90
|
+
return records;
|
|
91
|
+
}
|
|
92
|
+
/** Register one initialized checkout in Git-common metadata without sharing its graph database. */
|
|
93
|
+
export function registerInitializedWorktree(repoPath) {
|
|
94
|
+
const repo = path.resolve(repoPath);
|
|
95
|
+
const current = listGitWorktrees(repo).find((worktree) => canonicalPath(worktree.path) === canonicalPath(repo));
|
|
96
|
+
if (!current)
|
|
97
|
+
throw new Error(`knodin worktrees: ${repo} is not a registered Git worktree`);
|
|
98
|
+
const registry = readRegistry(repo);
|
|
99
|
+
const now = new Date().toISOString();
|
|
100
|
+
const identity = identityFor(repo, current.path, current.classification);
|
|
101
|
+
const existing = registry.entries.find((entry) => entry.identity === identity);
|
|
102
|
+
if (existing) {
|
|
103
|
+
existing.path = current.path;
|
|
104
|
+
existing.lastSeenAt = now;
|
|
105
|
+
delete existing.removedAt;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
registry.entries.push({
|
|
109
|
+
identity,
|
|
110
|
+
path: current.path,
|
|
111
|
+
classification: current.classification,
|
|
112
|
+
registeredAt: now,
|
|
113
|
+
lastSeenAt: now,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
// Byte order: the registry is written to disk in this order.
|
|
117
|
+
registry.entries.sort((left, right) => compareBytes(left.path, right.path));
|
|
118
|
+
writeRegistry(repo, registry);
|
|
119
|
+
}
|
|
120
|
+
export async function inspectWorktrees(repoPath, status) {
|
|
121
|
+
const repo = path.resolve(repoPath);
|
|
122
|
+
const current = listGitWorktrees(repo);
|
|
123
|
+
const registry = readRegistry(repo);
|
|
124
|
+
const livePaths = new Set(current.map((worktree) => worktree.path));
|
|
125
|
+
const worktrees = [];
|
|
126
|
+
for (const worktree of current) {
|
|
127
|
+
const identity = identityFor(repo, worktree.path, worktree.classification);
|
|
128
|
+
const registered = registry.entries.some((entry) => entry.identity === identity);
|
|
129
|
+
const graphInitialized = fs.existsSync(path.join(worktree.path, ".knodin", "db.sqlite"));
|
|
130
|
+
let indexedHead = null;
|
|
131
|
+
if (graphInitialized) {
|
|
132
|
+
try {
|
|
133
|
+
indexedHead = (await status(worktree.path)).lastIndexedHead || null;
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
indexedHead = null;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
worktrees.push({
|
|
140
|
+
...worktree,
|
|
141
|
+
identity,
|
|
142
|
+
registered,
|
|
143
|
+
graphInitialized,
|
|
144
|
+
indexedHead,
|
|
145
|
+
freshness: indexedHead === null || worktree.head === null
|
|
146
|
+
? "unknown"
|
|
147
|
+
: indexedHead === worktree.head
|
|
148
|
+
? "fresh"
|
|
149
|
+
: "stale",
|
|
150
|
+
removedAt: null,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
for (const entry of registry.entries) {
|
|
154
|
+
if (livePaths.has(entry.path))
|
|
155
|
+
continue;
|
|
156
|
+
worktrees.push({
|
|
157
|
+
identity: entry.identity,
|
|
158
|
+
path: entry.path,
|
|
159
|
+
classification: entry.classification,
|
|
160
|
+
head: null,
|
|
161
|
+
branch: null,
|
|
162
|
+
locked: false,
|
|
163
|
+
prunable: "registered worktree is absent from Git's worktree inventory",
|
|
164
|
+
registered: true,
|
|
165
|
+
graphInitialized: fs.existsSync(path.join(entry.path, ".knodin", "db.sqlite")),
|
|
166
|
+
indexedHead: null,
|
|
167
|
+
freshness: "removed",
|
|
168
|
+
removedAt: entry.removedAt ?? null,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
worktrees.sort((left, right) => left.path.localeCompare(right.path));
|
|
172
|
+
return { schemaVersion: 1, graphState: "per-worktree", worktrees };
|
|
173
|
+
}
|
|
174
|
+
/** Reconcile the durable registry with Git metadata; no checkout or graph is deleted. */
|
|
175
|
+
export function reconcileWorktrees(repoPath) {
|
|
176
|
+
const repo = path.resolve(repoPath);
|
|
177
|
+
const current = listGitWorktrees(repo);
|
|
178
|
+
const registry = readRegistry(repo);
|
|
179
|
+
const now = new Date().toISOString();
|
|
180
|
+
const seen = new Set();
|
|
181
|
+
const added = [];
|
|
182
|
+
const restored = [];
|
|
183
|
+
for (const worktree of current) {
|
|
184
|
+
const identity = identityFor(repo, worktree.path, worktree.classification);
|
|
185
|
+
seen.add(identity);
|
|
186
|
+
const existing = registry.entries.find((entry) => entry.identity === identity);
|
|
187
|
+
if (!existing) {
|
|
188
|
+
registry.entries.push({
|
|
189
|
+
identity,
|
|
190
|
+
path: worktree.path,
|
|
191
|
+
classification: worktree.classification,
|
|
192
|
+
registeredAt: now,
|
|
193
|
+
lastSeenAt: now,
|
|
194
|
+
});
|
|
195
|
+
added.push(worktree.path);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
if (existing.removedAt)
|
|
199
|
+
restored.push(worktree.path);
|
|
200
|
+
existing.path = worktree.path;
|
|
201
|
+
existing.lastSeenAt = now;
|
|
202
|
+
delete existing.removedAt;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const removed = [];
|
|
206
|
+
for (const entry of registry.entries) {
|
|
207
|
+
if (!seen.has(entry.identity) && !entry.removedAt) {
|
|
208
|
+
entry.removedAt = now;
|
|
209
|
+
removed.push(entry.path);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// Byte order: the registry is written to disk in this order.
|
|
213
|
+
registry.entries.sort((left, right) => compareBytes(left.path, right.path));
|
|
214
|
+
writeRegistry(repo, registry);
|
|
215
|
+
return { schemaVersion: 1, added, restored, removed };
|
|
216
|
+
}
|
|
217
|
+
/** Remove exactly one linked worktree through Git, then retain removal evidence in the registry. */
|
|
218
|
+
export function removeManagedWorktree(repoPath, targetPath, dryRun) {
|
|
219
|
+
const repo = path.resolve(repoPath);
|
|
220
|
+
const target = path.resolve(targetPath);
|
|
221
|
+
const record = listGitWorktrees(repo).find((worktree) => canonicalPath(worktree.path) === canonicalPath(target));
|
|
222
|
+
if (!record)
|
|
223
|
+
throw new Error(`knodin worktrees remove: ${target} is not a registered Git worktree`);
|
|
224
|
+
if (record.classification === "main")
|
|
225
|
+
throw new Error("knodin worktrees remove: refusing to remove the main worktree");
|
|
226
|
+
if (dryRun)
|
|
227
|
+
return { schemaVersion: 1, target, dryRun: true, removed: false };
|
|
228
|
+
childProcess.execFileSync("git", ["worktree", "remove", target], {
|
|
229
|
+
cwd: repo,
|
|
230
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
231
|
+
});
|
|
232
|
+
reconcileWorktrees(repo);
|
|
233
|
+
return { schemaVersion: 1, target, dryRun: false, removed: true };
|
|
234
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Behavioral contract
|
|
2
|
+
|
|
3
|
+
Knodin's intended product contract is the composition of seven behaviors behind the
|
|
4
|
+
single local gateway: truthful budgets, explicit freshness and availability,
|
|
5
|
+
source evidence and provenance, ambiguity-safe stable identity, recoverable
|
|
6
|
+
handles, bounded diagnosis confidence, and privacy/locality. The authoritative
|
|
7
|
+
operation-to-clause declaration matrix is
|
|
8
|
+
[`contracts/behavior-contract-v1.json`](../contracts/behavior-contract-v1.json),
|
|
9
|
+
and `npm run verify:c95` replays adversarial evidence before release. The gate
|
|
10
|
+
dispatches all 22 operations and every schema-declared query/action
|
|
11
|
+
discriminator against an offline linked-worktree fixture. Positive,
|
|
12
|
+
action-specific response semantics fail closed when a required signal is absent.
|
|
13
|
+
|
|
14
|
+
## Product answers, with checked evidence
|
|
15
|
+
|
|
16
|
+
- **Value:** less manual context assembly and fewer missed dependencies. The
|
|
17
|
+
paired task method and its bounded results are checked in under
|
|
18
|
+
[`benchmarks/evaluations/c93-engineering-outcomes/`](../benchmarks/evaluations/c93-engineering-outcomes/).
|
|
19
|
+
- **ROI:** the intended mechanism is fewer corrective agent round trips without
|
|
20
|
+
hosted-service, account, authentication, or source-egress overhead. C93's
|
|
21
|
+
accepted two-task replay measured no round-trip benefit; both arms needed one
|
|
22
|
+
correction. It therefore authorizes no productivity claim and leaves billed
|
|
23
|
+
cost and unobserved token counts unavailable.
|
|
24
|
+
- **Tomorrow:** run `knodin init`, inspect `knodin status`, then use the existing
|
|
25
|
+
checkout through the CLI or the single `knodin.knodin` MCP gateway. The
|
|
26
|
+
installation and client readiness evidence remains bounded by C91 below.
|
|
27
|
+
- **Secret sauce:** stable identity, source provenance, graph freshness, and
|
|
28
|
+
truthful response budgets remain composed across applicable operations. The
|
|
29
|
+
C95 matrix and representative replay fail closed if an operation declaration,
|
|
30
|
+
mandatory clause, or representative fixture is omitted.
|
|
31
|
+
|
|
32
|
+
## Composition invariants
|
|
33
|
+
|
|
34
|
+
A continuation or retained artifact may expand a bounded response only while
|
|
35
|
+
preserving its stable identity and evidence provenance. Stale, unavailable, or
|
|
36
|
+
ambiguous graph evidence must remain explicit and cannot be promoted to a
|
|
37
|
+
confident failure diagnosis, impact claim, or runtime-causality proof.
|
|
38
|
+
|
|
39
|
+
`ExplainResult.callers[].kind` and `ExplainResult.omissions[]` are governed by
|
|
40
|
+
the existing explain mapping: relationship kinds require source provenance and
|
|
41
|
+
stable resolved endpoints, while omissions require an exact source location and
|
|
42
|
+
must never be promoted into a graph edge. C99 exercises these added fields
|
|
43
|
+
without adding a gateway operation or discriminator, so the C95 applicability
|
|
44
|
+
matrix is unchanged.
|
|
45
|
+
|
|
46
|
+
The C95 fixtures run in a linked non-default worktree. A child harness installs
|
|
47
|
+
guards before importing the production dispatcher and observes global `fetch`,
|
|
48
|
+
HTTP/HTTPS request and get, TCP/TLS connection, callback and promise DNS
|
|
49
|
+
resolution, JavaScript-visible native-addon loading, and production-owned child
|
|
50
|
+
process argv, inherited or explicit environment, synchronous input, and streamed
|
|
51
|
+
stdin boundaries. The release gate derives
|
|
52
|
+
privacy and source-egress results from those observations: network attempts,
|
|
53
|
+
credential forwarding, source bytes at network/subprocess boundaries, and
|
|
54
|
+
native-addon loads must remain zero. Local subprocess execution is counted and
|
|
55
|
+
permitted only when those observed payload checks remain clean.
|
|
56
|
+
|
|
57
|
+
## C101 composition closure
|
|
58
|
+
|
|
59
|
+
C101 composes four independently bounded decisions without adding an MCP tool
|
|
60
|
+
or operation:
|
|
61
|
+
|
|
62
|
+
- C97 retained lazy semantic residency in one local process. It does **not**
|
|
63
|
+
authorize an idle-RSS-reclamation claim.
|
|
64
|
+
- C98 reports literal TS/JS source-to-sink paths as static heuristics with
|
|
65
|
+
coverage, omissions, freshness, budgets, and continuation. Truncation cannot
|
|
66
|
+
become a complete-result claim.
|
|
67
|
+
- C99 persists only uniquely source-resolved Inversify/tsyringe relationships;
|
|
68
|
+
ambiguous, dynamic, factory, alias, conditional, and reflective wiring stays
|
|
69
|
+
omission evidence rather than an edge.
|
|
70
|
+
- C100 proves one Salesforce Flow action to one uniquely resolved Apex
|
|
71
|
+
`@InvocableMethod`. It does not prove Terraform, dbt, arbitrary Salesforce
|
|
72
|
+
metadata, or general cross-substrate traversal.
|
|
73
|
+
|
|
74
|
+
`npm run verify:c101` source-binds those decisions, checks the CLI and one-tool
|
|
75
|
+
MCP query declarations, and rejects eight adversarial mutations of actual
|
|
76
|
+
production responses. Stale resource/path evidence and heuristic-to-exact
|
|
77
|
+
promotion fail; a truncated result cannot be presented as complete; and a DI
|
|
78
|
+
ambiguity, missing source witness, or path omission cannot become a supported
|
|
79
|
+
edge.
|
|
80
|
+
|
|
81
|
+
## Repository stewardship
|
|
82
|
+
|
|
83
|
+
An authoritative pull request starts the full test matrix and Sonar analysis,
|
|
84
|
+
so it is a long, resource-intensive operation. Assistants must not automatically
|
|
85
|
+
open one PR per item. Dependency-compatible, coherently scoped commits should
|
|
86
|
+
normally be stacked into one reasonably sized shared PR; unrelated work must
|
|
87
|
+
not be bundled merely to make the PR larger. The user or approved batch decides
|
|
88
|
+
when that review unit is ready.
|
|
89
|
+
|
|
90
|
+
## Known bounds
|
|
91
|
+
|
|
92
|
+
This replay proves the checked operation/action fixtures, not all repositories,
|
|
93
|
+
languages, frameworks, dynamic runtime behavior, clients, or deployment
|
|
94
|
+
environments. Static relationships and failure correlations are candidates,
|
|
95
|
+
not runtime-causality proof. Budgets can truncate results; indexes can be stale
|
|
96
|
+
or unavailable; names can be ambiguous; generated code, dynamic dispatch,
|
|
97
|
+
framework wiring outside C99's declared Inversify/tsyringe patterns, and
|
|
98
|
+
language coverage can leave relationships unresolved.
|
|
99
|
+
|
|
100
|
+
C91 remains parked pending native client, runtime-manager, Homebrew, and
|
|
101
|
+
Artifactory certification evidence. C94 remains blocked on C91 and therefore
|
|
102
|
+
does not establish a certified five-minute client demonstration. No fixture,
|
|
103
|
+
benchmark, or contract replay supports a universal superiority claim. The
|
|
104
|
+
authoritative roadmap remains the complete source for limitations and status.
|
|
105
|
+
|
|
106
|
+
A new production operation or schema-declared action must add an applicability
|
|
107
|
+
row, positive action semantics, and isolated adversarial mutation before
|
|
108
|
+
release; omission causes `verify:c95` and release preflight to fail. Every mapped
|
|
109
|
+
fixture/clause row is independently redispatched through the real production
|
|
110
|
+
handler, mutated at the guarded pre-serialization boundary, and rejected by the
|
|
111
|
+
same oracle. Network construction is denied before body streaming. JavaScript
|
|
112
|
+
cannot observe opaque operating-system activity performed entirely inside an
|
|
113
|
+
already-loaded native library; these remain explicit bounds rather than claims
|
|
114
|
+
of universal egress detection.
|
package/docs/CLI.md
CHANGED
|
@@ -32,7 +32,17 @@ example repository existence, mutually exclusive configuration modes, and
|
|
|
32
32
|
graph-query target rules), but syntax cannot reach a handler unless the shared
|
|
33
33
|
declarative model accepts it first.
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
`knodin query resource_reachability --limit 100` runs cached, on-demand static
|
|
36
|
+
TS/JS source-to-sink analysis. It covers literal `process.env` and
|
|
37
|
+
`fs.readFileSync` reads reaching `console.log`, `fetch`, or `db.query` through
|
|
38
|
+
bounded assignment, argument, and return handoff. Results include ordered source
|
|
39
|
+
evidence, stable path identities, registry coverage, omissions, freshness, and
|
|
40
|
+
hard truncation/continuation metadata. Depth is fixed at 6 and paths at 100;
|
|
41
|
+
dynamic names, reflection, computed aliases, and unsupported languages are
|
|
42
|
+
reported rather than guessed. This is a static heuristic, not runtime reachability
|
|
43
|
+
or an exploitability verdict.
|
|
44
|
+
|
|
45
|
+
For support evidence, `knodin diagnostics enable|status|preview|archive|inspect|clear|disable`
|
|
36
46
|
manages an explicit local failure journal and redacted gzip JSON bundles.
|
|
37
47
|
Collection does not upload data. See `docs/DIAGNOSTICS.md` for retention,
|
|
38
48
|
redaction, inspection, and known bounds.
|
|
@@ -54,6 +64,25 @@ centrality, churn, co-change, and coupling evidence. Git history has explicit
|
|
|
54
64
|
commit/file/time bounds and truthful unavailable or truncation states; see
|
|
55
65
|
`docs/GIT-HISTORY-REVIEW.md`.
|
|
56
66
|
|
|
67
|
+
`knodin visualize` writes a self-contained local HTML artifact and takes two
|
|
68
|
+
scopes. The default, `--scope call-flow <entry>`, draws a bounded static
|
|
69
|
+
downstream traversal from one entry symbol; `--depth` accepts 1 through 6.
|
|
70
|
+
`--scope repo` needs no entry and draws the repository's dependency graph as
|
|
71
|
+
inline SVG, with `--granularity file` (default) or `symbol`.
|
|
72
|
+
|
|
73
|
+
Repo scope reads every recorded dependency rather than the ranked summary
|
|
74
|
+
`knodin map` returns, so its coverage section measures against the whole graph.
|
|
75
|
+
Node and edge caps and the `--max-bytes` budget (4096 through 2097152; repo
|
|
76
|
+
scope defaults to 524288) can still withhold detail, and the artifact always
|
|
77
|
+
states how much: "showing 200 of 1,847 relationships". Solid edges carry a
|
|
78
|
+
narrow source declaration at full confidence; dashed edges are heuristic or
|
|
79
|
+
inferred and are not proof of a relationship.
|
|
80
|
+
|
|
81
|
+
Coordinates are computed when the artifact is written, from a PRNG seeded by
|
|
82
|
+
the source commit, so the file contains no script and no network reference and
|
|
83
|
+
identical evidence reproduces byte-identical output. That makes the artifact
|
|
84
|
+
safe to open offline and its SHA-256 meaningful.
|
|
85
|
+
|
|
57
86
|
`knodin pack grep` evaluates user patterns with exact-pinned RE2 WebAssembly,
|
|
58
87
|
not Node's backtracking regular-expression engine. Backreferences and lookaround
|
|
59
88
|
are rejected because they cannot retain RE2's linear-time guarantee. Route
|