@ecoma-io/archkeep 0.13.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/LICENSE +202 -0
- package/README.md +262 -0
- package/cli.mjs +2792 -0
- package/index.mjs +85 -0
- package/lsp.mjs +81 -0
- package/nx.mjs +24 -0
- package/package.json +81 -0
- package/presets/clean-architecture.json +78 -0
- package/presets/ddd-bounded-contexts.json +88 -0
- package/presets/hexagonal.json +68 -0
- package/presets/layered.json +92 -0
- package/presets/modular-monolith.json +85 -0
- package/presets/vertical-slice.json +68 -0
- package/src/analysis/analyze.mjs +218 -0
- package/src/analysis/contract.md +259 -0
- package/src/analysis/go.mjs +414 -0
- package/src/analysis/manifest-util.mjs +68 -0
- package/src/analysis/python.mjs +1266 -0
- package/src/analysis/registry.mjs +74 -0
- package/src/analysis/rust.mjs +674 -0
- package/src/analysis/source-util.mjs +230 -0
- package/src/analysis/typescript.mjs +1034 -0
- package/src/analysis/vue.mjs +156 -0
- package/src/architecture-intent/intent-fingerprint.mjs +29 -0
- package/src/architecture-intent/judge.mjs +539 -0
- package/src/architecture-intent/model.mjs +703 -0
- package/src/architecture-intent/selectors.mjs +170 -0
- package/src/canonical.mjs +48 -0
- package/src/commands/README.md +266 -0
- package/src/commands/adr.mjs +248 -0
- package/src/commands/check.mjs +989 -0
- package/src/commands/context-command.mjs +212 -0
- package/src/commands/context.mjs +790 -0
- package/src/commands/custom-rules.mjs +428 -0
- package/src/commands/debt.mjs +218 -0
- package/src/commands/diff.mjs +523 -0
- package/src/commands/discover.mjs +159 -0
- package/src/commands/drift.mjs +473 -0
- package/src/commands/edge-constraints.mjs +355 -0
- package/src/commands/explain.mjs +359 -0
- package/src/commands/fitness.mjs +226 -0
- package/src/commands/graph.mjs +297 -0
- package/src/commands/health.mjs +213 -0
- package/src/commands/history.mjs +614 -0
- package/src/commands/impact.mjs +226 -0
- package/src/commands/plan-context-command.mjs +496 -0
- package/src/commands/policy.mjs +138 -0
- package/src/commands/provenance-command.mjs +352 -0
- package/src/commands/provenance.mjs +159 -0
- package/src/commands/reconcile.mjs +219 -0
- package/src/commands/report.mjs +553 -0
- package/src/commands/snapshot-meta.mjs +107 -0
- package/src/commands/waivers.mjs +240 -0
- package/src/config.mjs +1308 -0
- package/src/containment.mjs +234 -0
- package/src/custom-rules/evidence.mjs +340 -0
- package/src/custom-rules/host.mjs +1023 -0
- package/src/custom-rules/values.mjs +43 -0
- package/src/entry-point.mjs +55 -0
- package/src/errors.mjs +36 -0
- package/src/eslint-config.mjs +542 -0
- package/src/go-work.mjs +394 -0
- package/src/governance/adr-registry.mjs +539 -0
- package/src/governance/clock.mjs +69 -0
- package/src/governance/debt-ledger.mjs +274 -0
- package/src/governance/discovery-proposal.mjs +423 -0
- package/src/governance/fitness-registry.mjs +504 -0
- package/src/governance/fitness-rules.mjs +668 -0
- package/src/governance/metrics.mjs +392 -0
- package/src/governance/preset-fingerprints.json +16 -0
- package/src/governance/profile-registry.mjs +366 -0
- package/src/governance/provenance-record.mjs +177 -0
- package/src/governance/reconcile-candidates.mjs +301 -0
- package/src/governance/reconcile-score.mjs +503 -0
- package/src/governance/row-schema.mjs +208 -0
- package/src/governance/verdict.mjs +127 -0
- package/src/governance/waiver.mjs +105 -0
- package/src/graph/create-dependencies.mjs +96 -0
- package/src/intent/intent-manifest.json +347 -0
- package/src/intent/mask-non-code.mjs +640 -0
- package/src/lsp/boundary-config.mjs +225 -0
- package/src/lsp/diagnose.mjs +202 -0
- package/src/lsp/diagnostics.mjs +241 -0
- package/src/lsp/protocol.mjs +215 -0
- package/src/lsp/server.mjs +922 -0
- package/src/lsp/workspace-index.mjs +891 -0
- package/src/nx-json.mjs +95 -0
- package/src/options.mjs +611 -0
- package/src/process.mjs +91 -0
- package/src/providers/moon.mjs +733 -0
- package/src/providers/native/README.md +204 -0
- package/src/providers/native/coverage.mjs +74 -0
- package/src/providers/native/differential.fixtures.mjs +1277 -0
- package/src/providers/native/discover.mjs +431 -0
- package/src/providers/native/graph.mjs +234 -0
- package/src/providers/native/index.mjs +152 -0
- package/src/providers/native/model.mjs +755 -0
- package/src/providers/nx.mjs +178 -0
- package/src/report/README.md +89 -0
- package/src/report/adr-text.mjs +129 -0
- package/src/report/context-text.mjs +109 -0
- package/src/report/debt-text.mjs +105 -0
- package/src/report/diff-text.mjs +219 -0
- package/src/report/discover-text.mjs +186 -0
- package/src/report/drift-text.mjs +194 -0
- package/src/report/envelope-shape.mjs +161 -0
- package/src/report/evidence.mjs +157 -0
- package/src/report/explain-text.mjs +159 -0
- package/src/report/graph-text.mjs +116 -0
- package/src/report/health-text.mjs +123 -0
- package/src/report/history-text.mjs +204 -0
- package/src/report/impact-text.mjs +128 -0
- package/src/report/json.mjs +173 -0
- package/src/report/plan-context-text.mjs +159 -0
- package/src/report/provenance-text.mjs +78 -0
- package/src/report/reconcile-text.mjs +159 -0
- package/src/report/report-text.mjs +264 -0
- package/src/report/sarif.mjs +953 -0
- package/src/report/text.mjs +823 -0
- package/src/report/waivers-text.mjs +100 -0
- package/src/rules/README.md +123 -0
- package/src/rules/index.mjs +962 -0
- package/src/rules/match.mjs +1708 -0
- package/src/rules/messages.mjs +73 -0
- package/src/rules/reachability.mjs +224 -0
- package/src/rules/specifiers.mjs +300 -0
- package/src/rules/tags.mjs +238 -0
- package/src/rules/topology.mjs +333 -0
- package/src/tsconfig-paths.mjs +237 -0
- package/src/verdict.mjs +145 -0
- package/src/workspace.mjs +580 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 2,
|
|
3
|
+
"generatedAt": "v1.0.0-hardening",
|
|
4
|
+
"description": "Machine-readable manifest declaring every v1.0 intent and the evidence that supports it. A contract is 'proven' only when at least one evidence entry is an executable proof (behavioral-test, e2e-test, or architecture-test). Source-evidence and documentation support the claim but cannot prove it alone.",
|
|
5
|
+
"evidenceTaxonomy": {
|
|
6
|
+
"behavioral-test": "A unit or integration test that imports and calls the code, asserting on runtime behavior (not source text). Proves the intent is regression-protected.",
|
|
7
|
+
"e2e-test": "A CLI subprocess test that exercises the real binary against a consumer workspace. Proves the intent holds end-to-end.",
|
|
8
|
+
"architecture-test": "A test that walks the codebase structure (imports, specifiers, declarations) to verify an architectural constraint. Proves the intent is mechanically enforced.",
|
|
9
|
+
"static-analysis": "An automated static analysis tool (ESLint, Semgrep, etc.) enforces the property. Proves the intent is mechanically checked, but the check scope is limited to what the tool's rules cover.",
|
|
10
|
+
"source-evidence": "The implementation source contains the property the intent declares. Supports the claim but does not prove it is regression-protected — the property could disappear in a refactor.",
|
|
11
|
+
"documentation": "A document describes the property the intent declares. Supports understanding but proves neither implementation nor protection."
|
|
12
|
+
},
|
|
13
|
+
"contracts": [
|
|
14
|
+
{
|
|
15
|
+
"id": "A",
|
|
16
|
+
"name": "Provider independence",
|
|
17
|
+
"intent": "Core (rules, analysis, report) must not import provider-specific code (nx, moon, native).",
|
|
18
|
+
"evidence": [
|
|
19
|
+
{
|
|
20
|
+
"type": "architecture-test",
|
|
21
|
+
"path": "src/conformance/boundary.test.mjs",
|
|
22
|
+
"assertion": "SHIPPED_PACKAGES allow-list prevents unapproved dependencies; specifiersIn() walk catches all imports including createRequire; no provider import found in core layers"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"type": "source-evidence",
|
|
26
|
+
"path": "src/commands/context.mjs",
|
|
27
|
+
"assertion": "Only commands/context.mjs imports providers — the designated orchestration layer"
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"status": "proven"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": "B",
|
|
34
|
+
"name": "Empty result is never silently successful",
|
|
35
|
+
"intent": "An empty diagnostic list must mean 'no violation', and nothing else. Every path that cannot reach a verdict must say so.",
|
|
36
|
+
"evidence": [
|
|
37
|
+
{
|
|
38
|
+
"type": "behavioral-test",
|
|
39
|
+
"path": "src/report/json.test.mjs",
|
|
40
|
+
"assertion": "JSON envelope throws on status=ok + incomplete coverage, status/exitCode disagreement, coverage.complete/notAnalyzed disagreement"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"type": "source-evidence",
|
|
44
|
+
"path": "src/lsp/diagnose.mjs",
|
|
45
|
+
"assertion": "analyzed:false on every non-verdict path; empty diagnostic list only from two named places"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"type": "source-evidence",
|
|
49
|
+
"path": "cli.mjs",
|
|
50
|
+
"assertion": "Exit codes 0/1/3 distinguish clean/findings/cannot-look"
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
"status": "proven"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": "C",
|
|
57
|
+
"name": "Workspace resolution ≠ source analysis",
|
|
58
|
+
"intent": "Graph edges (from provider) and source analysis (from analyzers) answer different questions. Neither replaces the other. The analysis layer never judges, filters, or omits imports based on policy.",
|
|
59
|
+
"evidence": [
|
|
60
|
+
{
|
|
61
|
+
"type": "behavioral-test",
|
|
62
|
+
"path": "src/intent/intent.test.mjs",
|
|
63
|
+
"assertion": "analysis output conforms to the frozen contract schema (no extra verdict/policy fields); analysis output is invariant under project tag changes; analysis source contains no judging vocabulary"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"type": "source-evidence",
|
|
67
|
+
"path": "src/analysis/contract.md",
|
|
68
|
+
"assertion": "Analysis record is a superset of a graph edge — 5 of 15 violations decided on raw specifier"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"type": "source-evidence",
|
|
72
|
+
"path": "AGENTS.md",
|
|
73
|
+
"assertion": "src/graph/ is a lossy view of analysis, on purpose; src/analysis/ never judges"
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"status": "proven"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"id": "D",
|
|
80
|
+
"name": "Architecture snapshot identity",
|
|
81
|
+
"intent": "Two runs over an unchanged tree (and unchanged archkeep version) produce byte-identical JSON. Internal fields are stripped. Schema is versioned.",
|
|
82
|
+
"evidence": [
|
|
83
|
+
{
|
|
84
|
+
"type": "e2e-test",
|
|
85
|
+
"path": "e2e/determinism.e2e.mjs",
|
|
86
|
+
"assertion": "Graph, check, impact run twice — byte-identical JSON output"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"type": "source-evidence",
|
|
90
|
+
"path": "src/commands/graph.mjs",
|
|
91
|
+
"assertion": "Plain string comparison, never localeCompare; INTERNAL_DATA_FIELDS stripped; SCHEMA_VERSION = 2"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"type": "source-evidence",
|
|
95
|
+
"path": "src/commands/graph.mjs",
|
|
96
|
+
"assertion": "computePolicyFingerprint produces SHA-256 of canonicalized policy"
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
"status": "proven"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"id": "E",
|
|
103
|
+
"name": "Snapshot compatibility",
|
|
104
|
+
"intent": "diff refuses a baseline with unknown schemaVersion. A consumer that reads a schemaVersion it does not recognise should refuse to parse.",
|
|
105
|
+
"evidence": [
|
|
106
|
+
{
|
|
107
|
+
"type": "e2e-test",
|
|
108
|
+
"path": "e2e/diff.e2e.mjs",
|
|
109
|
+
"assertion": "Invalid baseline schemaVersion exits 3; incompatible version exits 3"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"type": "source-evidence",
|
|
113
|
+
"path": "src/commands/diff.mjs",
|
|
114
|
+
"assertion": "parseBaseline validates schemaVersion; refuses unknown versions"
|
|
115
|
+
}
|
|
116
|
+
],
|
|
117
|
+
"status": "proven"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": "F",
|
|
121
|
+
"name": "Diff semantics — structural ≠ policy-mismatch ≠ rule-impact",
|
|
122
|
+
"intent": "Graph change ≠ policy mismatch ≠ rule impact. Diff separates structural changes, policy-mismatch warnings, and rule-impact analysis (depConstraints only). Refuses incomplete baseline/head.",
|
|
123
|
+
"evidence": [
|
|
124
|
+
{
|
|
125
|
+
"type": "e2e-test",
|
|
126
|
+
"path": "e2e/diff.e2e.mjs",
|
|
127
|
+
"assertion": "Self-baseline exits 0; added/removed edges reported; policy mismatch warned; rule-impact with config"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"type": "source-evidence",
|
|
131
|
+
"path": "src/commands/diff.mjs",
|
|
132
|
+
"assertion": "computeDiff returns structural diff; policyMismatch detected via fingerprint; computeRuleImpact for depConstraints-only context"
|
|
133
|
+
}
|
|
134
|
+
],
|
|
135
|
+
"status": "proven"
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"id": "G",
|
|
139
|
+
"name": "Impact determinism",
|
|
140
|
+
"intent": "Given the same graph and project name, impact always returns the same set. BFS, sorted, no localeCompare.",
|
|
141
|
+
"evidence": [
|
|
142
|
+
{
|
|
143
|
+
"type": "e2e-test",
|
|
144
|
+
"path": "e2e/determinism.e2e.mjs",
|
|
145
|
+
"assertion": "Impact --format json produces identical output on two runs"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"type": "behavioral-test",
|
|
149
|
+
"path": "src/commands/impact.test.mjs",
|
|
150
|
+
"assertion": "Sorts results using plain string comparison (never localeCompare)"
|
|
151
|
+
}
|
|
152
|
+
],
|
|
153
|
+
"status": "proven"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"id": "H",
|
|
157
|
+
"name": "Context — effective architecture contract",
|
|
158
|
+
"intent": "context shows the constraint table as it applies to a project's tags, not raw metadata. Per-edge verdicts cover depConstraints only (3 of 15 violation types) — this narrowing is disclosed.",
|
|
159
|
+
"evidence": [
|
|
160
|
+
{
|
|
161
|
+
"type": "behavioral-test",
|
|
162
|
+
"path": "src/commands/context-command.test.mjs",
|
|
163
|
+
"assertion": "Returns tags, matched constraints, per-edge violations; coverage.notes warns about depConstraints-only scope"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"type": "e2e-test",
|
|
167
|
+
"path": "e2e/context.e2e.mjs",
|
|
168
|
+
"assertion": "Native consumer: tags, constraints, coverage.notes verified; Moon consumer: context E2E"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"type": "documentation",
|
|
172
|
+
"path": "../../docs/concepts/agentic-development.md",
|
|
173
|
+
"assertion": "Section 'What context and impact do not check' warns agents about the semantic gap"
|
|
174
|
+
}
|
|
175
|
+
],
|
|
176
|
+
"status": "proven"
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"id": "I",
|
|
180
|
+
"name": "Explain — rule, reason, evidence",
|
|
181
|
+
"intent": "explain runs full evaluate() and returns ALL violations at the site (not just first). Unresolvable sites are explicit, not silent drops.",
|
|
182
|
+
"evidence": [
|
|
183
|
+
{
|
|
184
|
+
"type": "behavioral-test",
|
|
185
|
+
"path": "src/commands/explain.test.mjs",
|
|
186
|
+
"assertion": "Returns all violations at a site; unresolvable site returns unresolvable:true with reason"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"type": "e2e-test",
|
|
190
|
+
"path": "e2e/explain.e2e.mjs",
|
|
191
|
+
"assertion": "Native and Moon consumers: specifier, sourceProject, targetProject, violations verified"
|
|
192
|
+
}
|
|
193
|
+
],
|
|
194
|
+
"status": "proven"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"id": "J",
|
|
198
|
+
"name": "Check is enforcement authority",
|
|
199
|
+
"intent": "context/impact/diff/explain must not create different verdicts than check would. The depConstraints-only narrowing in context/impact/diff is disclosed. Where these commands evaluate, their verdicts must agree with check.",
|
|
200
|
+
"evidence": [
|
|
201
|
+
{
|
|
202
|
+
"type": "behavioral-test",
|
|
203
|
+
"path": "src/intent/intent.test.mjs",
|
|
204
|
+
"assertion": "depConstraints verdicts from judgeEdge agree with evaluate; explain includes the same violations as evaluate at a given site; diff warns in coverage.notes when ruleImpact is computed"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"type": "behavioral-test",
|
|
208
|
+
"path": "src/commands/context-command.test.mjs",
|
|
209
|
+
"assertion": "Test verifies coverage.notes contains depConstraints warning"
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
"type": "e2e-test",
|
|
213
|
+
"path": "e2e/context.e2e.mjs",
|
|
214
|
+
"assertion": "E2E verifies coverage.notes in JSON envelope"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"type": "source-evidence",
|
|
218
|
+
"path": "src/commands/context-command.mjs",
|
|
219
|
+
"assertion": "coverage.notes warns that per-edge violations cover only depConstraints (3 of 15 violation types)"
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"type": "source-evidence",
|
|
223
|
+
"path": "src/commands/impact.mjs",
|
|
224
|
+
"assertion": "coverage.notes warns that per-edge violations cover only depConstraints (3 of 15 violation types)"
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"type": "source-evidence",
|
|
228
|
+
"path": "src/commands/diff.mjs",
|
|
229
|
+
"assertion": "coverage.notes warns when ruleImpact is computed (depConstraints only, 3 of 15)"
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"type": "documentation",
|
|
233
|
+
"path": "../../docs/concepts/agentic-development.md",
|
|
234
|
+
"assertion": "Section warns agents: violations:[] means allowed by constraint table, not free of all boundary violations"
|
|
235
|
+
}
|
|
236
|
+
],
|
|
237
|
+
"status": "proven"
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"id": "K",
|
|
241
|
+
"name": "Determinism",
|
|
242
|
+
"intent": "No localeCompare, Date.now, Math.random in production code. Sorts use plain string comparison. Two runs over same tree (and same archkeep version) produce identical output.",
|
|
243
|
+
"evidence": [
|
|
244
|
+
{
|
|
245
|
+
"type": "e2e-test",
|
|
246
|
+
"path": "e2e/determinism.e2e.mjs",
|
|
247
|
+
"assertion": "Graph, check, impact: two runs produce byte-identical JSON"
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"type": "source-evidence",
|
|
251
|
+
"path": "src/commands/graph.mjs",
|
|
252
|
+
"assertion": "Plain string comparison throughout; never localeCompare"
|
|
253
|
+
}
|
|
254
|
+
],
|
|
255
|
+
"status": "proven"
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
"id": "L",
|
|
259
|
+
"name": "Provider parity",
|
|
260
|
+
"intent": "Same semantics on Nx/Moon/Native: same violation types, same options, same constraint table, same message ids. Partial workspaceLayout rejected.",
|
|
261
|
+
"evidence": [
|
|
262
|
+
{
|
|
263
|
+
"type": "e2e-test",
|
|
264
|
+
"path": "e2e/parity.e2e.mjs",
|
|
265
|
+
"assertion": "Nx vs Native: project names, edge source/target/type, violation rule IDs, envelope structure"
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"type": "e2e-test",
|
|
269
|
+
"path": "e2e/moon.e2e.mjs",
|
|
270
|
+
"assertion": "Moon: check, graph, diff, impact, explain, context verified against Moon provider (conditional on moon CLI availability)"
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"type": "source-evidence",
|
|
274
|
+
"path": "src/providers/moon.mjs",
|
|
275
|
+
"assertion": "inferWorkspaceLayout returns null for partial layouts — same all-or-nothing contract as Nx and Native"
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
"type": "behavioral-test",
|
|
279
|
+
"path": "src/providers/moon.test.mjs",
|
|
280
|
+
"assertion": "Partial layout (apps-only, libs-only) returns undefined workspaceLayout"
|
|
281
|
+
}
|
|
282
|
+
],
|
|
283
|
+
"status": "proven"
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
"id": "M",
|
|
287
|
+
"name": "Drift — observed vs declared intent",
|
|
288
|
+
"intent": "drift compares the observed project graph against the canonical architecture-intent.json through the single judgeIntent. It is descriptive (never exits 1); check folds it in by presence and exits 1 on drift findings. Every path that cannot reach a drift verdict (malformed/absent intent, incomplete coverage, incomplete graph) says so loudly instead of returning empty.",
|
|
289
|
+
"evidence": [
|
|
290
|
+
{
|
|
291
|
+
"type": "behavioral-test",
|
|
292
|
+
"path": "src/commands/drift.test.mjs",
|
|
293
|
+
"assertion": "driftCommand returns status ok with observed facts and findings; refuses incomplete coverage, absent intent, and unregistered-plugin incomplete graph; buildObserved counts implicit edges separately"
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
"type": "behavioral-test",
|
|
297
|
+
"path": "src/report/drift-text.test.mjs",
|
|
298
|
+
"assertion": "formatDriftReport states comparison facts even when clean (no-drift is a claim about coverage); groups findings by rule in taxonomy order; byte-identical determinism"
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
"type": "e2e-test",
|
|
302
|
+
"path": "e2e/drift.e2e.mjs",
|
|
303
|
+
"assertion": "Through the installed CLI: drift exits 0 on a matching tree and names fingerprint/rows; reports dependencyForbidden and projectMissing; JSON envelope carries findings; malformed intent exits 3 for both drift and check"
|
|
304
|
+
}
|
|
305
|
+
],
|
|
306
|
+
"status": "proven"
|
|
307
|
+
}
|
|
308
|
+
],
|
|
309
|
+
"bugsFixed": [
|
|
310
|
+
{
|
|
311
|
+
"id": "moon-partial-workspace-layout",
|
|
312
|
+
"description": "Moon provider returned partial workspaceLayout (e.g., {appsDir:'apps'} with no libsDir), which silently disabled isAbsoluteImportIntoAnotherProject for the missing axis via 'undefined/' string comparison. Fixed: inferWorkspaceLayout returns null for partial layouts, forcing the DEFAULT_WORKSPACE_LAYOUT fallback.",
|
|
313
|
+
"evidence": {
|
|
314
|
+
"source": "src/providers/moon.mjs",
|
|
315
|
+
"test": "src/providers/moon.test.mjs",
|
|
316
|
+
"contract": "L"
|
|
317
|
+
}
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
"id": "context-impact-semantic-gap-undisclosed",
|
|
321
|
+
"description": "context and impact commands used judgeEdge (depConstraints-only) without disclosing to agents that 11 of 15 violation types were not checked. An agent seeing violations:[] could believe an edge was clean when check would still flag it. Fixed: coverage.notes warns about the narrowing; agentic-development.md documents the gap.",
|
|
322
|
+
"evidence": {
|
|
323
|
+
"source": ["src/commands/context-command.mjs", "src/commands/impact.mjs"],
|
|
324
|
+
"docs": "../../docs/concepts/agentic-development.md",
|
|
325
|
+
"test": [
|
|
326
|
+
"src/commands/context-command.test.mjs",
|
|
327
|
+
"src/commands/impact.test.mjs",
|
|
328
|
+
"e2e/context.e2e.mjs",
|
|
329
|
+
"e2e/impact.e2e.mjs"
|
|
330
|
+
],
|
|
331
|
+
"contract": "J"
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
"id": "policy-fingerprint-non-canonical",
|
|
336
|
+
"description": "computePolicyFingerprint used raw JSON.stringify without sorting object keys, so two semantically identical policy objects constructed in different key order could produce different fingerprints. diff would then report a spurious policy change. Fixed: canonicalize JSON by sorting keys at every depth before hashing.",
|
|
337
|
+
"evidence": {
|
|
338
|
+
"source": "src/commands/graph.mjs",
|
|
339
|
+
"test": "src/commands/graph.test.mjs",
|
|
340
|
+
"intentTest": "src/intent/intent.test.mjs",
|
|
341
|
+
"contract": "D"
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
],
|
|
345
|
+
"todoAffectingV1": 0,
|
|
346
|
+
"unprovenIntents": 0
|
|
347
|
+
}
|