@ecoma-io/archkeep 0.25.0 → 0.26.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/cli.mjs +166 -506
- package/commands.mjs +7 -1
- package/package.json +1 -1
- package/src/architecture-intent/judge.mjs +1 -1
- package/src/architecture-intent/model.mjs +34 -0
- package/src/canonical.mjs +2 -1
- package/src/commands/adr-for-workspace.mjs +63 -0
- package/src/commands/analyze-capability.mjs +13 -0
- package/src/commands/change-intent.mjs +11 -0
- package/src/commands/change.mjs +247 -34
- package/src/commands/check-capability.mjs +13 -0
- package/src/commands/check.mjs +13 -3
- package/src/commands/compare-capability.mjs +20 -0
- package/src/commands/completeness.mjs +12 -0
- package/src/commands/context-command.mjs +31 -0
- package/src/commands/coverage-verdict.mjs +15 -2
- package/src/commands/debt.mjs +30 -0
- package/src/commands/decisions.mjs +59 -10
- package/src/commands/delta.mjs +263 -49
- package/src/commands/diff.mjs +45 -0
- package/src/commands/discover.mjs +37 -0
- package/src/commands/drift.mjs +45 -0
- package/src/commands/evolution.mjs +22 -2
- package/src/commands/explain-capability.mjs +11 -0
- package/src/commands/explain.mjs +24 -0
- package/src/commands/fitness.mjs +119 -10
- package/src/commands/govern-capability.mjs +16 -0
- package/src/commands/graph.mjs +39 -0
- package/src/commands/health.mjs +34 -0
- package/src/commands/history.mjs +85 -2
- package/src/commands/impact.mjs +23 -0
- package/src/commands/inspect-capability.mjs +16 -0
- package/src/commands/plan-context-command.mjs +35 -0
- package/src/commands/policy.mjs +42 -4
- package/src/commands/provenance-command.mjs +15 -24
- package/src/commands/report.mjs +38 -0
- package/src/commands/rules-capability.mjs +16 -0
- package/src/commands/rules.mjs +3 -1
- package/src/commands/scenario.mjs +23 -0
- package/src/commands/trajectory.mjs +35 -0
- package/src/commands/waivers.mjs +30 -0
- package/src/corpus/goldens/.gitkeep +0 -0
- package/src/corpus/goldens/adr.json +62 -0
- package/src/corpus/goldens/adr.text +6 -0
- package/src/corpus/goldens/change.json +98 -0
- package/src/corpus/goldens/change.text +6 -0
- package/src/corpus/goldens/check.json +90 -0
- package/src/corpus/goldens/check.sarif +479 -0
- package/src/corpus/goldens/check.text +9 -0
- package/src/corpus/goldens/context.json +47 -0
- package/src/corpus/goldens/context.text +6 -0
- package/src/corpus/goldens/debt.json +59 -0
- package/src/corpus/goldens/debt.text +7 -0
- package/src/corpus/goldens/decisions.json +74 -0
- package/src/corpus/goldens/decisions.text +7 -0
- package/src/corpus/goldens/delta.json +94 -0
- package/src/corpus/goldens/delta.sarif +472 -0
- package/src/corpus/goldens/delta.text +5 -0
- package/src/corpus/goldens/diff.json +58 -0
- package/src/corpus/goldens/diff.text +4 -0
- package/src/corpus/goldens/discover.json +77 -0
- package/src/corpus/goldens/discover.text +10 -0
- package/src/corpus/goldens/drift.json +43 -0
- package/src/corpus/goldens/drift.text +3 -0
- package/src/corpus/goldens/evolution.json +328 -0
- package/src/corpus/goldens/evolution.text +32 -0
- package/src/corpus/goldens/explain.json +60 -0
- package/src/corpus/goldens/explain.text +7 -0
- package/src/corpus/goldens/fitness.json +45 -0
- package/src/corpus/goldens/fitness.text +3 -0
- package/src/corpus/goldens/graph.json +78 -0
- package/src/corpus/goldens/graph.text +10 -0
- package/src/corpus/goldens/health.json +72 -0
- package/src/corpus/goldens/health.text +10 -0
- package/src/corpus/goldens/help.text +104 -0
- package/src/corpus/goldens/history.json +43 -0
- package/src/corpus/goldens/history.text +4 -0
- package/src/corpus/goldens/impact.json +327 -0
- package/src/corpus/goldens/impact.text +10 -0
- package/src/corpus/goldens/provenance.json +453 -0
- package/src/corpus/goldens/provenance.text +14 -0
- package/src/corpus/goldens/reconcile.json +168 -0
- package/src/corpus/goldens/reconcile.text +3 -0
- package/src/corpus/goldens/report.json +168 -0
- package/src/corpus/goldens/report.text +42 -0
- package/src/corpus/goldens/rules verify.json +0 -0
- package/src/corpus/goldens/rules verify.text +0 -0
- package/src/corpus/goldens/scenario.json +441 -0
- package/src/corpus/goldens/scenario.text +28 -0
- package/src/corpus/goldens/trajectory.json +83 -0
- package/src/corpus/goldens/trajectory.text +10 -0
- package/src/corpus/goldens/usage-error.text +105 -0
- package/src/corpus/goldens/waivers.json +40 -0
- package/src/corpus/goldens/waivers.text +1 -0
- package/src/corpus/goldens-lsp/initialize.result.json +15 -0
- package/src/corpus/goldens-lsp/publish-cleared-empty.json +4 -0
- package/src/corpus/goldens-lsp/publish-fixed-empty.json +5 -0
- package/src/corpus/goldens-lsp/publish-unparseable.json +54 -0
- package/src/corpus/goldens-lsp/publish-violation.json +22 -0
- package/src/corpus/goldens-lsp/register-watched-files.json +72 -0
- package/src/go-work.mjs +8 -23
- package/src/governance/evolution-event.mjs +15 -0
- package/src/governance/evolution-store.mjs +59 -31
- package/src/governance/provenance-record.mjs +0 -152
- package/src/governance/verdict.mjs +26 -3
- package/src/intent/intent-manifest.json +14 -14
- package/src/lsp/server.mjs +5 -8
- package/src/lsp/workspace-index.mjs +55 -220
- package/src/options.mjs +10 -0
- package/src/providers/native/discover.mjs +13 -12
- package/src/providers/native/model.mjs +8 -3
- package/src/providers/nx-static.mjs +231 -0
- package/src/report/json.mjs +3 -2
- package/src/report/sarif.mjs +8 -3
- package/src/rules/edge-constraints.mjs +9 -0
- package/src/rules/index.mjs +26 -10
- package/src/rules/messages.mjs +64 -14
- package/src/rules/specifiers.mjs +21 -20
- package/src/tsconfig-paths.mjs +8 -14
- package/src/verdict.mjs +127 -16
|
@@ -37,17 +37,8 @@
|
|
|
37
37
|
* or a polluted prototype cannot smuggle keys into a validated origin. This
|
|
38
38
|
* module builds nothing from untrusted keys; it validates and, at write time,
|
|
39
39
|
* builds a fresh object with only the three permitted keys.
|
|
40
|
-
* ## The decision-lifecycle record
|
|
41
|
-
*
|
|
42
|
-
* The same discipline extends from a row to a DECISION (an ADR id — the
|
|
43
|
-
* stable handle later waves reference). `recordDecisionLifecycle` records one
|
|
44
|
-
* lifecycle event — a status transition, a supersession, or a bindings
|
|
45
|
-
* change — attributed by the same `origin` shape and the same clock door:
|
|
46
|
-
* `by`/`tool` are required, and `on` comes from `recordOrigin` and nowhere
|
|
47
|
-
* else. A record that records nothing (a no-op transition) is refused loudly.
|
|
48
40
|
*/
|
|
49
41
|
|
|
50
|
-
import { ADR_STATUSES } from "./adr-registry.mjs";
|
|
51
42
|
import { clockViolations } from "./clock.mjs";
|
|
52
43
|
import { describe, isPlainObject } from "../values.mjs";
|
|
53
44
|
|
|
@@ -175,146 +166,3 @@ export function recordOrigin({ by, tool, clock }) {
|
|
|
175
166
|
// record, so two calls with the same clock are byte-identical.
|
|
176
167
|
return { by, tool, on: clock.now() };
|
|
177
168
|
}
|
|
178
|
-
/**
|
|
179
|
-
* The decision-lifecycle events one record can hold, each a single fact about
|
|
180
|
-
* ONE decision (an ADR id — `docs/adr/NNN-slug.md` — the stable handle the
|
|
181
|
-
* registry's `byId` map keys on). A decision's creation and every status
|
|
182
|
-
* change, supersession, and bindings change is recorded as one of these.
|
|
183
|
-
*/
|
|
184
|
-
export const DECISION_LIFECYCLE_KINDS = Object.freeze([
|
|
185
|
-
// used by its own test
|
|
186
|
-
"status-transition",
|
|
187
|
-
"supersession",
|
|
188
|
-
"bindings-change",
|
|
189
|
-
]);
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* @typedef {object} DecisionLifecycleRecord
|
|
193
|
-
* @property {"status-transition"|"supersession"|"bindings-change"} kind
|
|
194
|
-
* One recorded lifecycle event on one decision.
|
|
195
|
-
* @property {string} decisionId The ADR id the event happened to — the stable
|
|
196
|
-
* handle the ADR registry keys on (`docs/adr/NNN-slug.md`).
|
|
197
|
-
* @property {string|null} [from] status-transition: the status the decision
|
|
198
|
-
* left, or null when the event is the decision's creation (its proposed
|
|
199
|
-
* entry).
|
|
200
|
-
* @property {string} [to] status-transition: the status the decision entered.
|
|
201
|
-
* @property {string[]} [superseded] supersession: the ADR id(s) this decision
|
|
202
|
-
* replaced — `decisionId` is the RECORDING record, the successor.
|
|
203
|
-
* @property {string[]} [added] bindings-change: constraint ids made
|
|
204
|
-
* enforceable.
|
|
205
|
-
* @property {string[]} [removed] bindings-change: constraint ids unbound.
|
|
206
|
-
* @property {OriginRecord} origin WHO recorded the event and with what tool —
|
|
207
|
-
* `on` produced by `recordOrigin`, the only door.
|
|
208
|
-
*/
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Records one decision-lifecycle event, attributed by the same `origin`
|
|
212
|
-
* discipline as a row: `by` and `tool` are required, and `on` comes from the
|
|
213
|
-
* injected clock through `recordOrigin` — the only producer of an `on`, and
|
|
214
|
-
* the refusal to run without one is its own, inherited here.
|
|
215
|
-
*
|
|
216
|
-
* The record carries ONLY the kind's own keys and the origin, built fresh, so
|
|
217
|
-
* nothing from untrusted input rides along. A no-op event — a status
|
|
218
|
-
* transition that changes nothing, a supersession naming no target, a
|
|
219
|
-
* bindings change that adds and removes nothing — is refused loudly: a record
|
|
220
|
-
* that records nothing would read as a transition that happened, the silent
|
|
221
|
-
* direction this module exists to exclude.
|
|
222
|
-
*
|
|
223
|
-
* Statuses are validated against `ADR_STATUSES` (`./adr-registry.mjs`), the
|
|
224
|
-
* single status vocabulary — a record can never attest a status the registry
|
|
225
|
-
* could not hold.
|
|
226
|
-
*
|
|
227
|
-
* @param {{kind: "status-transition"|"supersession"|"bindings-change",
|
|
228
|
-
* decisionId: string,
|
|
229
|
-
* from?: string|null, to?: string,
|
|
230
|
-
* superseded?: string[],
|
|
231
|
-
* added?: string[], removed?: string[],
|
|
232
|
-
* origin: {by: string, tool: string},
|
|
233
|
-
* clock: import("./clock.mjs").Clock}} event
|
|
234
|
-
* @returns {DecisionLifecycleRecord}
|
|
235
|
-
* @throws {Error} on an unknown kind, a missing decisionId, a status outside
|
|
236
|
-
* the registry's `ADR_STATUSES`, a no-op event, or an invalid origin/clock.
|
|
237
|
-
*/
|
|
238
|
-
export function recordDecisionLifecycle({
|
|
239
|
-
// used by its own test
|
|
240
|
-
kind,
|
|
241
|
-
decisionId,
|
|
242
|
-
from = null,
|
|
243
|
-
to,
|
|
244
|
-
superseded,
|
|
245
|
-
added,
|
|
246
|
-
removed,
|
|
247
|
-
origin,
|
|
248
|
-
clock,
|
|
249
|
-
}) {
|
|
250
|
-
const violations = [];
|
|
251
|
-
if (!DECISION_LIFECYCLE_KINDS.includes(kind)) {
|
|
252
|
-
violations.push(
|
|
253
|
-
`kind: must be one of ${DECISION_LIFECYCLE_KINDS.join(", ")}, got ${describe(kind)}`,
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
if (typeof decisionId !== "string" || decisionId.trim() === "") {
|
|
257
|
-
violations.push(
|
|
258
|
-
`decisionId: must be a non-empty string naming the ADR, got ${describe(decisionId)}`,
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
if (kind === "status-transition") {
|
|
262
|
-
if (from !== null && !ADR_STATUSES.includes(from)) {
|
|
263
|
-
violations.push(
|
|
264
|
-
`from: must be null or one of ${ADR_STATUSES.join(", ")}, got ${describe(from)}`,
|
|
265
|
-
);
|
|
266
|
-
}
|
|
267
|
-
if (!ADR_STATUSES.includes(to)) {
|
|
268
|
-
violations.push(`to: must be one of ${ADR_STATUSES.join(", ")}, got ${describe(to)}`);
|
|
269
|
-
}
|
|
270
|
-
if (from !== null && from === to) {
|
|
271
|
-
violations.push(
|
|
272
|
-
`to: equals from (${JSON.stringify(from)}) — a status transition that changes nothing is not a recordable event`,
|
|
273
|
-
);
|
|
274
|
-
}
|
|
275
|
-
} else if (kind === "supersession") {
|
|
276
|
-
if (
|
|
277
|
-
!Array.isArray(superseded) ||
|
|
278
|
-
superseded.length === 0 ||
|
|
279
|
-
superseded.some((ref) => typeof ref !== "string" || ref.trim() === "")
|
|
280
|
-
) {
|
|
281
|
-
violations.push("superseded: must be a non-empty array of ADR ids this decision replaced");
|
|
282
|
-
}
|
|
283
|
-
} else if (kind === "bindings-change") {
|
|
284
|
-
for (const [name, value] of [
|
|
285
|
-
["added", added],
|
|
286
|
-
["removed", removed],
|
|
287
|
-
]) {
|
|
288
|
-
if (value !== undefined && !Array.isArray(value)) {
|
|
289
|
-
violations.push(`${name}: must be an array of constraint ids, got ${describe(value)}`);
|
|
290
|
-
} else if (
|
|
291
|
-
Array.isArray(value) &&
|
|
292
|
-
value.some((id) => typeof id !== "string" || id.trim() === "")
|
|
293
|
-
) {
|
|
294
|
-
violations.push(`${name}: every entry must be a non-empty constraint id`);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
const addedList = Array.isArray(added) ? added : [];
|
|
298
|
-
const removedList = Array.isArray(removed) ? removed : [];
|
|
299
|
-
if (addedList.length === 0 && removedList.length === 0) {
|
|
300
|
-
violations.push(
|
|
301
|
-
"added/removed: a bindings change that adds nothing and removes nothing is not a recordable event",
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
if (violations.length > 0) {
|
|
306
|
-
throw new Error(`decisionLifecycle: ${violations.join("; ")}`);
|
|
307
|
-
}
|
|
308
|
-
const eventFields =
|
|
309
|
-
kind === "status-transition"
|
|
310
|
-
? { from, to }
|
|
311
|
-
: kind === "supersession"
|
|
312
|
-
? { superseded }
|
|
313
|
-
: { added: added ?? [], removed: removed ?? [] };
|
|
314
|
-
return {
|
|
315
|
-
kind,
|
|
316
|
-
decisionId,
|
|
317
|
-
...eventFields,
|
|
318
|
-
origin: recordOrigin({ by: origin?.by, tool: origin?.tool, clock }),
|
|
319
|
-
};
|
|
320
|
-
}
|
|
@@ -13,9 +13,17 @@
|
|
|
13
13
|
* `"findings"` → `"fail"`
|
|
14
14
|
* `"no-verdict"` → `"unknown"`
|
|
15
15
|
*
|
|
16
|
-
* and `"not_applicable"` has no source status in this release —
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* and `"not_applicable"` has no source status in this release — no envelope
|
|
17
|
+
* status maps to it, so it never rides an envelope. Engine behavior does emit
|
|
18
|
+
* it today, on the paths that cannot judge: the fitness registry answers it
|
|
19
|
+
* for a declared function whose `match` selects no observed project, and
|
|
20
|
+
* again for `coverage-minimum` on a path-scoped run, which no scoped run can
|
|
21
|
+
* judge; decision fitness derives it for a decision without authority; the
|
|
22
|
+
* boundary metrics answer it when there is no boundary config to judge
|
|
23
|
+
* against (`./metrics.mjs`). A
|
|
24
|
+
* custom rule may return it as its own verdict — the host requires a
|
|
25
|
+
* `notApplicableReason` (`../custom-rules/host.mjs`) — but no engine path
|
|
26
|
+
* answers it on a rule's behalf.
|
|
19
27
|
*
|
|
20
28
|
* ## The invariants, I1–I5
|
|
21
29
|
*
|
|
@@ -41,6 +49,21 @@
|
|
|
41
49
|
* (`../verdict.mjs`) depend on the presentation layer. `../report/evidence.mjs`
|
|
42
50
|
* re-exports `buildDecision` so the render-side callers keep their import
|
|
43
51
|
* path — a path, never a second implementation.
|
|
52
|
+
*
|
|
53
|
+
* Layer: the verdict vocabulary and decision owner — `VERDICTS`, `isVerdict`,
|
|
54
|
+
* `verdictForStatus`, `fitnessVerdict`, and `buildDecision`. Its counterpart,
|
|
55
|
+
* `../verdict.mjs`, is the check lane built on top of `buildDecision` — the
|
|
56
|
+
* process's exit codes, the coverage clauses, and `verdictFor`, the per-lint
|
|
57
|
+
* verdict the `check` command words its envelope and its exit from. The two
|
|
58
|
+
* near-collision pairs cross that boundary, and the name decides which file
|
|
59
|
+
* a reader wants: `verdictForStatus` here looks one status up in a frozen
|
|
60
|
+
* map, while `../verdict.mjs`'s `verdictFor` folds a run's counts into
|
|
61
|
+
* status + exitCode; `VERDICT_FOR_STATUS` here is an independently frozen
|
|
62
|
+
* map, while `../verdict.mjs`'s `EXIT_FOR_STATUS` is derived from its own
|
|
63
|
+
* `EXIT`. Verdict vocabulary and decision construction live here; exit-code,
|
|
64
|
+
* coverage and check-lane concerns live there — and the layering stays
|
|
65
|
+
* one-directional (the check lane imports this module, never the reverse),
|
|
66
|
+
* so this module must not grow exit-code or coverage concerns.
|
|
44
67
|
*/
|
|
45
68
|
|
|
46
69
|
import { describe, isNonEmptyString } from "../values.mjs";
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"type": "source-evidence",
|
|
53
53
|
"path": "cli.mjs",
|
|
54
54
|
"assertion": "Exit codes 0/1/3 distinguish clean/findings/cannot-look",
|
|
55
|
-
"sha256": "
|
|
55
|
+
"sha256": "2b6590f4039464d3569727d0a73db61dd86c18648a519ee034ebcc2d845ecfc7"
|
|
56
56
|
}
|
|
57
57
|
],
|
|
58
58
|
"status": "proven"
|
|
@@ -66,13 +66,13 @@
|
|
|
66
66
|
"type": "behavioral-test",
|
|
67
67
|
"path": "src/intent/intent.test.mjs",
|
|
68
68
|
"assertion": "analysis output conforms to the frozen contract schema (no extra verdict/policy fields); analysis output is invariant under project tag changes (three workspaces differing only in project tag fields compared byte-for-byte)",
|
|
69
|
-
"sha256": "
|
|
69
|
+
"sha256": "749414363ef9991ae3697fc00ab5969751666867792d4bb4dbe528ec47ccd740"
|
|
70
70
|
},
|
|
71
71
|
{
|
|
72
72
|
"type": "architecture-test",
|
|
73
73
|
"path": "src/intent/intent.test.mjs",
|
|
74
74
|
"assertion": "the gate walks every production analysis module and fails when judging vocabulary (judge/forbid/permit/allow/ban) appears in code",
|
|
75
|
-
"sha256": "
|
|
75
|
+
"sha256": "749414363ef9991ae3697fc00ab5969751666867792d4bb4dbe528ec47ccd740"
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
78
|
"type": "source-evidence",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"type": "source-evidence",
|
|
85
85
|
"path": "AGENTS.md",
|
|
86
86
|
"assertion": "src/graph/ is a lossy view of analysis, on purpose; src/analysis/ never judges",
|
|
87
|
-
"sha256": "
|
|
87
|
+
"sha256": "552b54c1956370f024ffeecec95c0e0941a0c66d4a14094045b444a25a27f913"
|
|
88
88
|
}
|
|
89
89
|
],
|
|
90
90
|
"status": "proven"
|
|
@@ -104,19 +104,19 @@
|
|
|
104
104
|
"type": "source-evidence",
|
|
105
105
|
"path": "src/commands/graph.mjs",
|
|
106
106
|
"assertion": "Plain string comparison, never localeCompare; INTERNAL_DATA_FIELDS stripped",
|
|
107
|
-
"sha256": "
|
|
107
|
+
"sha256": "4f493421e11b012ce7b9c1b111155c8ebdbca6ab4ad3fa37221fbe1a465bef46"
|
|
108
108
|
},
|
|
109
109
|
{
|
|
110
110
|
"type": "source-evidence",
|
|
111
111
|
"path": "src/report/json.mjs",
|
|
112
112
|
"assertion": "SCHEMA_VERSION = 2 — the envelope's schemaVersion constant",
|
|
113
|
-
"sha256": "
|
|
113
|
+
"sha256": "ac6db6e74b4ef7e54db12cc14ef57a7c5080ad081d7bf1273beb5ba543dcac24"
|
|
114
114
|
},
|
|
115
115
|
{
|
|
116
116
|
"type": "source-evidence",
|
|
117
117
|
"path": "src/commands/graph.mjs",
|
|
118
118
|
"assertion": "computePolicyFingerprint produces SHA-256 of canonicalized policy",
|
|
119
|
-
"sha256": "
|
|
119
|
+
"sha256": "4f493421e11b012ce7b9c1b111155c8ebdbca6ab4ad3fa37221fbe1a465bef46"
|
|
120
120
|
}
|
|
121
121
|
],
|
|
122
122
|
"status": "proven"
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
"type": "source-evidence",
|
|
137
137
|
"path": "src/commands/diff.mjs",
|
|
138
138
|
"assertion": "parseBaseline validates schemaVersion; refuses unknown versions",
|
|
139
|
-
"sha256": "
|
|
139
|
+
"sha256": "4d44eea475cd4b06122a405718203d2e0018a163c1d42b17324400e7e4de5eea"
|
|
140
140
|
}
|
|
141
141
|
],
|
|
142
142
|
"status": "proven"
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
"type": "source-evidence",
|
|
157
157
|
"path": "src/commands/diff.mjs",
|
|
158
158
|
"assertion": "computeDiff returns structural diff; policyMismatch detected via fingerprint; computeRuleImpact for depConstraints-only context",
|
|
159
|
-
"sha256": "
|
|
159
|
+
"sha256": "4d44eea475cd4b06122a405718203d2e0018a163c1d42b17324400e7e4de5eea"
|
|
160
160
|
}
|
|
161
161
|
],
|
|
162
162
|
"status": "proven"
|
|
@@ -236,7 +236,7 @@
|
|
|
236
236
|
"type": "behavioral-test",
|
|
237
237
|
"path": "src/intent/intent.test.mjs",
|
|
238
238
|
"assertion": "depConstraints verdicts from judgeEdge agree with evaluate in both directions (violating edge found by both, legal edge reported by neither); explain includes the same violations as evaluate at a given site",
|
|
239
|
-
"sha256": "
|
|
239
|
+
"sha256": "749414363ef9991ae3697fc00ab5969751666867792d4bb4dbe528ec47ccd740"
|
|
240
240
|
},
|
|
241
241
|
{
|
|
242
242
|
"type": "behavioral-test",
|
|
@@ -254,19 +254,19 @@
|
|
|
254
254
|
"type": "source-evidence",
|
|
255
255
|
"path": "src/commands/context-command.mjs",
|
|
256
256
|
"assertion": "coverage.notes warns that per-edge violations cover only depConstraints (3 of 15 violation types)",
|
|
257
|
-
"sha256": "
|
|
257
|
+
"sha256": "2d8a17dce1a5f4075ee02a7a8c1bdff94e70afe5cd609f63fe3cf6324f78aaf3"
|
|
258
258
|
},
|
|
259
259
|
{
|
|
260
260
|
"type": "source-evidence",
|
|
261
261
|
"path": "src/commands/impact.mjs",
|
|
262
262
|
"assertion": "coverage.notes warns that per-edge violations cover only depConstraints (3 of 15 violation types)",
|
|
263
|
-
"sha256": "
|
|
263
|
+
"sha256": "440f20017cceae4b13c6bc5c653c7a8b99511e0c062dcc7abfb18859f3f0520c"
|
|
264
264
|
},
|
|
265
265
|
{
|
|
266
266
|
"type": "source-evidence",
|
|
267
267
|
"path": "src/commands/diff.mjs",
|
|
268
268
|
"assertion": "coverage.notes warns when ruleImpact is computed (depConstraints only, 3 of 15)",
|
|
269
|
-
"sha256": "
|
|
269
|
+
"sha256": "4d44eea475cd4b06122a405718203d2e0018a163c1d42b17324400e7e4de5eea"
|
|
270
270
|
},
|
|
271
271
|
{
|
|
272
272
|
"type": "documentation",
|
|
@@ -292,7 +292,7 @@
|
|
|
292
292
|
"type": "source-evidence",
|
|
293
293
|
"path": "src/commands/graph.mjs",
|
|
294
294
|
"assertion": "Plain string comparison throughout; never localeCompare",
|
|
295
|
-
"sha256": "
|
|
295
|
+
"sha256": "4f493421e11b012ce7b9c1b111155c8ebdbca6ab4ad3fa37221fbe1a465bef46"
|
|
296
296
|
}
|
|
297
297
|
],
|
|
298
298
|
"status": "proven"
|
package/src/lsp/server.mjs
CHANGED
|
@@ -60,12 +60,8 @@ import {
|
|
|
60
60
|
TEXT_DOCUMENT_SYNC_KIND,
|
|
61
61
|
uriToPath,
|
|
62
62
|
} from "./protocol.mjs";
|
|
63
|
-
import {
|
|
64
|
-
|
|
65
|
-
listWorkspaceFiles,
|
|
66
|
-
PROJECT_CONFIG_FILE,
|
|
67
|
-
readWorkspaceFile,
|
|
68
|
-
} from "./workspace-index.mjs";
|
|
63
|
+
import { PROJECT_CONFIG_FILE } from "../providers/native/discover.mjs";
|
|
64
|
+
import { buildWorkspaceIndex, listWorkspaceFiles, readWorkspaceFile } from "./workspace-index.mjs";
|
|
69
65
|
|
|
70
66
|
/**
|
|
71
67
|
* A project's own `package.json`, and the two spellings of its Module
|
|
@@ -232,8 +228,9 @@ const POLYGLOT_GRAPH_MANIFESTS = Object.freeze([
|
|
|
232
228
|
* the annotations cached against the old one. The stale waiver then publishes
|
|
233
229
|
* `[]` for a real violation for the rest of the session, which is the silent
|
|
234
230
|
* direction exactly (`../../../../AGENTS.md`). `package.json` earns the entry a
|
|
235
|
-
* second way as well: it is where
|
|
236
|
-
* takes a project's NAME
|
|
231
|
+
* second way as well: it is where the static acquisition
|
|
232
|
+
* (`../providers/nx-static.mjs`'s `discoverProjects`) takes a project's NAME
|
|
233
|
+
* when its `project.json` states none, so an edit to it
|
|
237
234
|
* can move a project in the graph and not only waive something in it.
|
|
238
235
|
*
|
|
239
236
|
* The polyglot graph manifests are here for that same argument one level out,
|