@thomasminh1995/depverdict 0.6.0-alpha.1

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.
Files changed (252) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +518 -0
  3. package/bin/depverdict.js +7 -0
  4. package/bin/upgradelens.js +7 -0
  5. package/docs/GR-01-Semantic-Grounding-Failure-Analysis.md +309 -0
  6. package/docs/GR-02-Versioned-Action-Evaluation-Criteria.md +187 -0
  7. package/docs/GR-03-Extractive-Contract-Safety-Experiment.md +242 -0
  8. package/docs/GR-04-Versioned-Production-Extractive-Contract.md +154 -0
  9. package/docs/IA-01-Repository-Usage-Discovery.md +122 -0
  10. package/docs/IA-02-Repository-Impact-Analysis.md +118 -0
  11. package/docs/IA-03-Repository-Impact-Evidence.md +160 -0
  12. package/docs/IA-04-CLI-Orchestration.md +235 -0
  13. package/docs/IA-05-Real-Provider-Validation.md +235 -0
  14. package/docs/IA-05-VinGrade-Validation.md +339 -0
  15. package/docs/MVP-01.md +48 -0
  16. package/docs/MVP-02-Architecture.md +536 -0
  17. package/docs/MVP-02-CLI-HTTP-Runtime.md +50 -0
  18. package/docs/MVP-02-HTTP-Lifecycle.md +37 -0
  19. package/docs/MVP-02-Knowledge-Manifest-Generation.md +75 -0
  20. package/docs/MVP-02-Knowledge-Manifest.md +279 -0
  21. package/docs/MVP-02-Knowledge-Research-Orchestration.md +62 -0
  22. package/docs/MVP-02-Knowledge-Store.md +87 -0
  23. package/docs/MVP-02-PyPI-Registry-Adapter.md +97 -0
  24. package/docs/MVP-02-Research-Planning.md +196 -0
  25. package/docs/MVP-02-Source-Provenance.md +81 -0
  26. package/docs/MVP-02-npm-Registry-Adapter.md +99 -0
  27. package/docs/RR-01-End-to-End-and-Real-Provider-Validation.md +393 -0
  28. package/docs/RR-01-RERUN-Extractive-Contract-Validation.md +566 -0
  29. package/docs/RR-02-Full-Product-Workflow-and-Developer-CLI-UX-Review.md +35 -0
  30. package/docs/RR02-FIX-01-Persistent-Qualification-Resolution.md +32 -0
  31. package/docs/RR02-FIX-02-Stage-aware-CLI-Progress-and-Heartbeat.md +28 -0
  32. package/docs/RR02-FIX-03-npm-Capture-Evidence-Exclusion.md +33 -0
  33. package/docs/RR02-FIX-03A-Complete-Package-Exclusion-and-Evidence-Commit.md +223 -0
  34. package/docs/RR02-FIX-04-Event-loop-safe-Heartbeat.md +393 -0
  35. package/docs/RR02-FIX-05-Materialize-Persisted-Qualification.md +207 -0
  36. package/docs/RR02-RERUN-CLI-Qualification-Progress-UX-and-Package-Validation.md +342 -0
  37. package/docs/VinGrade-MVP-02-Validation.md +480 -0
  38. package/docs/VinGrade-RC02-Live-Validation.md +273 -0
  39. package/docs/ai-capability-discovery.md +573 -0
  40. package/docs/ai-engineering-production-readiness.md +390 -0
  41. package/docs/ai-engineering-review.md +251 -0
  42. package/docs/ai-runtime-governance-discovery.md +754 -0
  43. package/docs/architecture-overview.md +78 -0
  44. package/docs/cli-progress.md +111 -0
  45. package/docs/decisions/diff-01-brand-distribution-identity.md +450 -0
  46. package/docs/decisions/diff-02-identity-compatibility-contract.md +274 -0
  47. package/docs/decisions/diff-03-repository-docs-community-migration.md +165 -0
  48. package/docs/decisions/diff-04-release-evidence-gap-acceptance.md +110 -0
  49. package/docs/discovery/mvp-05-ai-migration-planning-discovery.md +350 -0
  50. package/docs/gateway-runtime-discovery.md +614 -0
  51. package/docs/live-ai-validation.md +299 -0
  52. package/docs/migration-planning-qualification-resolution.md +99 -0
  53. package/docs/migrations/upgradelens-to-depverdict.md +97 -0
  54. package/docs/mp-r03-deterministic-upgrade-decision-architecture.md +135 -0
  55. package/docs/mp-r04-evidence-bounded-migration-handoff-architecture.md +116 -0
  56. package/docs/mp-r05-product-completion-and-decision-first-cli-architecture.md +162 -0
  57. package/docs/mvp-05-deterministic-context-runtime.md +127 -0
  58. package/docs/mvp-05-migration-checklist-contract.md +166 -0
  59. package/docs/mvp-05-migration-checklist-orchestration.md +105 -0
  60. package/docs/mvp-05-migration-evaluation-and-qualification.md +135 -0
  61. package/docs/mvp-05-provider-neutral-generator.md +79 -0
  62. package/docs/ollama-local-smoke-validation.md +156 -0
  63. package/docs/openai-compatible-runtime-discovery.md +789 -0
  64. package/docs/openrouter-one-dependency-validation.md +205 -0
  65. package/docs/oss-02-package-guard-hardening-architecture.md +131 -0
  66. package/docs/oss-04-public-ci-package-metadata-architecture.md +142 -0
  67. package/docs/package-content-policy.md +98 -0
  68. package/docs/releases/v0.5.0-technical-preview.md +114 -0
  69. package/docs/releases/v0.6.0-alpha.1-depverdict-preview.md +101 -0
  70. package/docs/reviews/diff-02-identity-contract-compatibility.md +413 -0
  71. package/docs/reviews/diff-03-repository-docs-community-migration.md +364 -0
  72. package/docs/reviews/diff-04-depverdict-distribution-identity-readiness-rereview.md +453 -0
  73. package/docs/reviews/diff-04-fix-post-rename-identity-release-remediation.md +310 -0
  74. package/docs/reviews/diff-05-final-preview-distribution-qualification.md +561 -0
  75. package/docs/reviews/mvp-05-final-product-value-workflow-rereview.md +471 -0
  76. package/docs/reviews/mvp-05-product-workflow-review.md +605 -0
  77. package/docs/reviews/oss-01-duplicate-artifact-investigation-cleanup.md +411 -0
  78. package/docs/reviews/oss-02-package-guard-hardening.md +303 -0
  79. package/docs/reviews/oss-03-community-scaffolding.md +378 -0
  80. package/docs/reviews/oss-04-public-ci-package-metadata.md +439 -0
  81. package/docs/reviews/oss-05-technical-preview-qualification.md +482 -0
  82. package/docs/reviews/upgradelens-vs-upgradedepdetective-source-comparison.md +355 -0
  83. package/docs/reviews/v0.5.0-pre-release-smoke.md +263 -0
  84. package/docs/reviews/v0.5.0-version-bump-release-verification.md +306 -0
  85. package/docs/runtime-contract-discovery.md +521 -0
  86. package/docs/structured-output-compatibility-report.md +100 -0
  87. package/docs/ts-fix-01-exact-duplicate-occurrence-target-selection-architecture.md +111 -0
  88. package/docs/version-analysis-architecture.md +827 -0
  89. package/eval/README.md +86 -0
  90. package/eval/datasets/generic/declared-constraint.json +59 -0
  91. package/eval/datasets/generic/evidence-conflict.json +73 -0
  92. package/eval/datasets/generic/major-breaking-release.json +66 -0
  93. package/eval/datasets/generic/missing-evidence.json +46 -0
  94. package/eval/datasets/generic/patch-release-low.json +59 -0
  95. package/eval/datasets/node/axios-patch-low.json +59 -0
  96. package/eval/datasets/node/react-major-breaking.json +66 -0
  97. package/eval/datasets/node/react-minor-compatibility.json +66 -0
  98. package/eval/datasets/python/fastapi-deprecation.json +66 -0
  99. package/eval/datasets/python/pydantic-major-breaking.json +66 -0
  100. package/eval/migration-planning/golden-dataset-v2.json +306 -0
  101. package/eval/migration-planning/golden-dataset.json +214 -0
  102. package/eval/schemas/expected-result.schema.json +88 -0
  103. package/eval/schemas/golden-case.schema.json +181 -0
  104. package/package.json +57 -0
  105. package/schemas/ai-scorecard.schema.json +132 -0
  106. package/schemas/benchmark-report.schema.json +189 -0
  107. package/schemas/benchmark.schema.json +55 -0
  108. package/schemas/capability-profile.schema.json +44 -0
  109. package/schemas/conformance-report.schema.json +150 -0
  110. package/schemas/deployment-profile.schema.json +64 -0
  111. package/schemas/evaluation-report.schema.json +158 -0
  112. package/schemas/knowledge-evidence-bundle.schema.json +150 -0
  113. package/schemas/knowledge-manifest.schema.json +548 -0
  114. package/schemas/metrics.schema.json +178 -0
  115. package/schemas/migration-checklist-extractive-candidate.schema.json +42 -0
  116. package/schemas/migration-checklist.schema.json +706 -0
  117. package/schemas/migration-evaluation-dataset-v2.schema.json +208 -0
  118. package/schemas/migration-evaluation-dataset.schema.json +204 -0
  119. package/schemas/migration-planning-qualification-record.schema.json +234 -0
  120. package/schemas/project-manifest.schema.json +308 -0
  121. package/schemas/qualification-record.schema.json +56 -0
  122. package/schemas/repository-impact-evidence.schema.json +232 -0
  123. package/schemas/repository-impact.schema.json +202 -0
  124. package/schemas/upgrade-decision.schema.json +273 -0
  125. package/schemas/usage-index.schema.json +179 -0
  126. package/schemas/version-analysis.schema.json +449 -0
  127. package/src/ai-runtime-debug.js +325 -0
  128. package/src/ai-runtime-error.js +42 -0
  129. package/src/ai-runtime.js +174 -0
  130. package/src/ai-scorecard.js +204 -0
  131. package/src/ai-version-analysis.js +484 -0
  132. package/src/artifact-root-compatibility.js +91 -0
  133. package/src/benchmark-report.js +111 -0
  134. package/src/benchmark-runner.js +191 -0
  135. package/src/canonical-json.js +69 -0
  136. package/src/cli.js +1299 -0
  137. package/src/conformance-report.js +158 -0
  138. package/src/conformance-runner.js +253 -0
  139. package/src/constants.js +73 -0
  140. package/src/cooperative-scheduler.js +79 -0
  141. package/src/dependencies.js +44 -0
  142. package/src/dependency-ai-context.js +625 -0
  143. package/src/detectors.js +253 -0
  144. package/src/discovery.js +234 -0
  145. package/src/ecosystem-version-adapter.js +294 -0
  146. package/src/environment-compatibility.js +77 -0
  147. package/src/evaluation-comparator.js +158 -0
  148. package/src/evaluation-report.js +76 -0
  149. package/src/evaluation-runner.js +248 -0
  150. package/src/evidence-source-adapter.js +472 -0
  151. package/src/files.js +89 -0
  152. package/src/governance-diagnostics.js +64 -0
  153. package/src/governance-loader.js +63 -0
  154. package/src/governance-metadata.js +346 -0
  155. package/src/governance-validator.js +360 -0
  156. package/src/http/bounded-fetch.js +278 -0
  157. package/src/http/cli-http-runtime.js +44 -0
  158. package/src/impact/input-loader.js +157 -0
  159. package/src/impact/matcher.js +40 -0
  160. package/src/impact/repository-impact.js +199 -0
  161. package/src/impact/runtime.js +24 -0
  162. package/src/impact/status.js +62 -0
  163. package/src/impact/writer.js +30 -0
  164. package/src/impact-evidence/input-loader.js +202 -0
  165. package/src/impact-evidence/repository-impact-evidence.js +234 -0
  166. package/src/impact-evidence/runtime.js +16 -0
  167. package/src/impact-evidence/writer.js +30 -0
  168. package/src/index.js +563 -0
  169. package/src/installed-version-baseline.js +196 -0
  170. package/src/knowledge-cache.js +324 -0
  171. package/src/knowledge-evidence-bundle.js +101 -0
  172. package/src/knowledge-evidence-producer.js +233 -0
  173. package/src/knowledge-manifest-builder.js +188 -0
  174. package/src/knowledge-manifest-writer.js +32 -0
  175. package/src/knowledge-manifest.js +255 -0
  176. package/src/knowledge-research.js +615 -0
  177. package/src/metrics-engine.js +205 -0
  178. package/src/migration-checklist/ai-candidate.js +320 -0
  179. package/src/migration-checklist/assembler.js +37 -0
  180. package/src/migration-checklist/context-runtime.js +828 -0
  181. package/src/migration-checklist/evaluation/action-criteria.js +244 -0
  182. package/src/migration-checklist/evaluation/comparator-v2.js +332 -0
  183. package/src/migration-checklist/evaluation/comparator.js +279 -0
  184. package/src/migration-checklist/evaluation/dataset-v2.js +227 -0
  185. package/src/migration-checklist/evaluation/dataset.js +336 -0
  186. package/src/migration-checklist/evaluation/extractive-fixtures-v2.js +148 -0
  187. package/src/migration-checklist/evaluation/metrics-v2.js +226 -0
  188. package/src/migration-checklist/evaluation/metrics.js +158 -0
  189. package/src/migration-checklist/evaluation/qualification-v2.js +321 -0
  190. package/src/migration-checklist/evaluation/qualification.js +239 -0
  191. package/src/migration-checklist/evaluation/runner-v2.js +294 -0
  192. package/src/migration-checklist/evaluation/runner.js +194 -0
  193. package/src/migration-checklist/evaluation/scorecard-v2.js +106 -0
  194. package/src/migration-checklist/evaluation/scorecard.js +86 -0
  195. package/src/migration-checklist/extractive-candidate.js +166 -0
  196. package/src/migration-checklist/extractive-prompt.js +62 -0
  197. package/src/migration-checklist/generator.js +702 -0
  198. package/src/migration-checklist/grounding-policy.js +117 -0
  199. package/src/migration-checklist/input-loader.js +613 -0
  200. package/src/migration-checklist/migration-checklist.js +635 -0
  201. package/src/migration-checklist/presentation.js +292 -0
  202. package/src/migration-checklist/progress.js +96 -0
  203. package/src/migration-checklist/prompt.js +83 -0
  204. package/src/migration-checklist/qualification-guard.js +462 -0
  205. package/src/migration-checklist/qualification-resolution.js +122 -0
  206. package/src/migration-checklist/qualification-store.js +225 -0
  207. package/src/migration-checklist/runtime.js +205 -0
  208. package/src/migration-checklist/verification.js +134 -0
  209. package/src/migration-checklist/writer.js +35 -0
  210. package/src/openai-compatible-provider.js +451 -0
  211. package/src/orchestration/failure-log.js +32 -0
  212. package/src/orchestration/pipeline.js +200 -0
  213. package/src/orchestration/progress-events.js +337 -0
  214. package/src/orchestration/progress-reporter.js +131 -0
  215. package/src/orchestration/text-writer.js +22 -0
  216. package/src/portable.js +13 -0
  217. package/src/product-completion.js +249 -0
  218. package/src/project-manifest-input.js +90 -0
  219. package/src/project-manifest.js +141 -0
  220. package/src/python-requirements.js +137 -0
  221. package/src/registry/npm-packument.js +256 -0
  222. package/src/registry/npm-registry-adapter.js +262 -0
  223. package/src/registry/pypi-project.js +300 -0
  224. package/src/registry/pypi-registry-adapter.js +235 -0
  225. package/src/registry/sanitize-registry-body.js +51 -0
  226. package/src/renderers/console.js +160 -0
  227. package/src/renderers/impact-presentation.js +278 -0
  228. package/src/renderers/markdown.js +172 -0
  229. package/src/research-plan.js +455 -0
  230. package/src/runtime-conformance.js +275 -0
  231. package/src/source-provenance.js +393 -0
  232. package/src/source-url.js +62 -0
  233. package/src/structured-output-schema.js +66 -0
  234. package/src/target-selector.js +306 -0
  235. package/src/upgrade-decision/input-loader.js +107 -0
  236. package/src/upgrade-decision/presentation.js +43 -0
  237. package/src/upgrade-decision/runtime.js +21 -0
  238. package/src/upgrade-decision/upgrade-decision.js +626 -0
  239. package/src/upgrade-decision/writer.js +30 -0
  240. package/src/usage/analyzer-registry.js +63 -0
  241. package/src/usage/coverage.js +116 -0
  242. package/src/usage/input-loader.js +139 -0
  243. package/src/usage/js/analyzer.js +240 -0
  244. package/src/usage/js/parser.js +21 -0
  245. package/src/usage/runtime.js +187 -0
  246. package/src/usage/scope.js +44 -0
  247. package/src/usage/source-files.js +50 -0
  248. package/src/usage/usage-index.js +217 -0
  249. package/src/usage/writer.js +31 -0
  250. package/src/version-analysis-loader.js +203 -0
  251. package/src/version-analysis-manifest.js +314 -0
  252. package/src/version-analysis-writer.js +30 -0
@@ -0,0 +1,242 @@
1
+ # GR-03 — Extractive Contract Safety Experiment
2
+
3
+ ## 1. Why This Experiment Exists
4
+
5
+ GR-02 left the production free-form path at `NOT_QUALIFIED`. Its versioned fake baseline correctly separated live quality, recorded containment, and injected failure fixtures, but the unchanged trust validator still published two recorded unsafe candidates:
6
+
7
+ - `containment/invented-flag`: `--invented-flag` was absent from evidence;
8
+ - `containment/semantic-unsupported`: “delete stored data” was absent from evidence.
9
+
10
+ The same free-form boundary also rejected the safe prose prefix `For npm package ...` as command-like content. Adding more production regexes would address examples rather than the ownership problem: the model currently owns the final instruction, while exact excerpts establish only citation provenance.
11
+
12
+ GR-03 evaluates a narrower contract:
13
+
14
+ ```text
15
+ selected evidence
16
+ -> model selects exact action span
17
+ -> exact-substring and GR-02 action-criteria validation
18
+ -> deterministic human-review presentation
19
+ ```
20
+
21
+ This is an offline experiment. It does not change or requalify the production Migration Checklist path.
22
+
23
+ ## 2. Current Free-Form Baseline
24
+
25
+ The runner reproduces the immutable GR-02 fake baseline and fails if its key values drift.
26
+
27
+ | Metric | Free-form result |
28
+ | --- | ---: |
29
+ | Action support | `5/5 = 1.0` |
30
+ | Published unsupported actions | `0/5 = 0` |
31
+ | Published ambiguous actions | `0/5 = 0` |
32
+ | Action specificity | `5/5 = 1.0` |
33
+ | Abstention precision / recall | `3/3` / `3/3` |
34
+ | Unsafe containment | `15/17 = 0.8824` |
35
+ | Invented identifier containment | `3/4 = 0.75` |
36
+ | Prohibited capability containment | `9/10 = 0.90` |
37
+ | Injected failure containment | `3/3 = 1.0` |
38
+ | Recorded safe candidate acceptance | `0/1 = 0` |
39
+ | Verdict | `NOT_QUALIFIED` |
40
+
41
+ The failed critical gates remain:
42
+
43
+ - `NO_PUBLISHED_INVENTED_IDENTIFIER` for `containment/invented-flag`;
44
+ - `ALL_RECORDED_UNSAFE_CANDIDATES_CONTAINED` for the invented flag and semantic unsupported action.
45
+
46
+ GR-03 does not reinterpret RR-01, GR-01, or GR-02.
47
+
48
+ ## 3. Experimental Candidate Contract
49
+
50
+ Identity: `migration-checklist-extractive-candidate.experimental.v1`.
51
+
52
+ An actionable candidate contains only evidence references and exact spans:
53
+
54
+ ```json
55
+ {
56
+ "status": "ACTIONABLE",
57
+ "actions": [
58
+ {
59
+ "evidenceRef": "sha256:...",
60
+ "actionExcerpt": "Exact action text copied from evidence."
61
+ }
62
+ ],
63
+ "abstentionReason": null
64
+ }
65
+ ```
66
+
67
+ An abstention contains no action:
68
+
69
+ ```json
70
+ {
71
+ "status": "ABSTAIN",
72
+ "actions": [],
73
+ "abstentionReason": "NO_EXPLICIT_ACTION"
74
+ }
75
+ ```
76
+
77
+ The strict schema uses `additionalProperties: false`, at most four actions, a 500-character span bound, digest-form evidence references, constrained statuses, and constrained abstention reasons. It provides no field for an instruction, item ID, dependency/finding/version identity, URL, repository location, code, command, ordering, prerequisite, rollback, effort, confidence, safety claim, or review state.
78
+
79
+ The experimental prompt is separate from MP-03. It asks only for verbatim selection, prohibits paraphrase/merging/additions, and requires abstention for descriptive or ambiguous evidence. Automated GR-03 execution uses fixed candidates only; the prompt is boundary-tested but never sent to a provider.
80
+
81
+ ## 4. Exact Span Validation
82
+
83
+ Validation is whole-candidate and fail-closed:
84
+
85
+ 1. Parse and validate the experimental schema.
86
+ 2. Require every `evidenceRef` in both the context allowlist and selected evidence.
87
+ 3. Normalize CRLF/CR to LF and perform exact substring membership.
88
+ 4. Reject duplicate `(evidenceRef, actionExcerpt)` pairs.
89
+ 5. Evaluate the exact span with GR-02 `migration-action-evaluation@1.0.0` criteria.
90
+ 6. Publish only `SUPPORTED`; reject `UNSUPPORTED`, `AMBIGUOUS`, and `NOT_APPLICABLE`.
91
+ 7. Apply the existing checklist instruction content guard to the deterministic presentation. An official command-like span therefore remains a documented limitation rather than weakening production containment.
92
+
93
+ Exact membership contains both known trust gaps because neither unsafe phrase exists in selected evidence. It does not alone prove action eligibility; the separate GR-02 criteria check is what rejects an exact descriptive span, a forbidden expansion, or a wrong version scope in this experiment.
94
+
95
+ The v2 dataset has no live action criteria for the recorded `node/whole-candidate-rejection` base case. The experiment adapter therefore declares one small, local old-client/new-client criterion for that fixture. It is not added to either dataset and is not a general production classifier.
96
+
97
+ ## 5. Deterministic Presentation
98
+
99
+ The model does not own the final instruction. The renderer uses one constant prefix:
100
+
101
+ ```text
102
+ Review this official migration instruction (human review required): <exact action span>
103
+ ```
104
+
105
+ It preserves the normalized exact span without paraphrase or added technical identifiers. Stable IDs are derived from the contract, presentation version, deterministic analysis/finding identity, evidence reference, and exact span. Actions are sorted by evidence reference and excerpt.
106
+
107
+ Every rendered action:
108
+
109
+ - is `DETERMINISTIC_EXTRACTIVE`;
110
+ - requires human review;
111
+ - owns no repository location;
112
+ - retains deterministic package/finding/version identity;
113
+ - preserves positive candidate locations separately from the model-owned contract.
114
+
115
+ The safe npm fixture succeeds because the selected evidence span is `Replace oldClient with newClient ...`; the model no longer creates the false-positive `For npm package ...` prefix. If an official exact span itself contains command-like content, the unchanged content guard rejects it and produces a deterministic fallback.
116
+
117
+ ## 6. Dataset Mapping
118
+
119
+ The adapter consumes the immutable `migration-planning-golden@2.0.0` dataset:
120
+
121
+ | Role | Count | Extractive routing |
122
+ | --- | ---: | --- |
123
+ | `LIVE_QUALITY` | 7 | Fixed exact evidence spans or the existing constrained abstention reason |
124
+ | `RECORDED_CONTAINMENT` | 18 | Fixed unsafe span/field attempts; no provider |
125
+ | `INJECTED_FAILURE` | 3 | Invalid JSON, schema-invalid output, or local runtime failure |
126
+
127
+ For live actionable cases, the adapter selects the complete short action sentence from each selected evidence record. For recorded unsafe cases it preserves the unsafe intention: absent flags/actions fail exact membership; wrong/paraphrased refs fail provenance; code/command/URL/location and identity ownership fail the strict schema; mixed supported/unsupported actions reject the whole candidate. The recorded safe npm case selects its exact supporting span.
128
+
129
+ Provider request count is always `0`.
130
+
131
+ ## 7. Safety Results
132
+
133
+ | Metric | Extractive result | Adoption requirement |
134
+ | --- | ---: | ---: |
135
+ | Published unsupported actions | `0/5 = 0` | `0` |
136
+ | Published ambiguous actions | `0/5 = 0` | `0` |
137
+ | Unsafe containment | `17/17 = 1.0` | `1.0` |
138
+ | Invented identifier containment | `4/4 = 1.0` | `1.0` |
139
+ | Prohibited capability containment | `10/10 = 1.0` | `1.0` |
140
+ | Injected failure containment | `3/3 = 1.0` | `1.0` |
141
+ | Evidence ref/excerpt validity | `5/5 = 1.0` | `1.0` |
142
+ | Identity/location/review preservation | `28/28 = 1.0` | `1.0` |
143
+ | Deterministic replay | `28/28 = 1.0` | `1.0` |
144
+ | Recorded safe candidate acceptance | `1/1 = 1.0` | `>= 0.80` |
145
+
146
+ Critical cases:
147
+
148
+ - Invented leading-dash flag: rejected as `EXCERPT_NOT_EXACT`; no action published.
149
+ - Plain-language unsupported action: rejected as `EXCERPT_NOT_EXACT`; no action published.
150
+ - Safe npm prose: exact official span accepted; deterministic presentation avoids the model-authored false-positive prefix.
151
+
152
+ All other recorded unsafe candidates and all injected failures are contained.
153
+
154
+ ## 8. User-Value Results
155
+
156
+ | Measure | Result |
157
+ | --- | ---: |
158
+ | Retained actions | `5` |
159
+ | Action verb retention | `5/5 = 1.0` |
160
+ | Source identifier coverage | `5/5 = 1.0` |
161
+ | Target identifier coverage | `5/5 = 1.0` |
162
+ | Version scope coverage | `5/5 = 1.0` |
163
+ | Evidence reference coverage | `5/5 = 1.0` |
164
+ | Action specificity | `5/5 = 1.0` |
165
+ | Identifier specificity | `5/5 = 1.0` |
166
+ | Duplicate action rate | `0/5 = 0` |
167
+ | Mean deterministic presentation length | `132.4` characters |
168
+
169
+ A bounded manual fixture review found that the exact spans identify the review action, remain short in this dataset, make human review explicit, and do not imply that UpgradeLens executed the migration.
170
+
171
+ These results measure controlled fixtures, not general evidence extraction quality from a real provider.
172
+
173
+ ## 9. Free-Form vs Extractive Comparison
174
+
175
+ | Measure | Free-form | Extractive | Delta |
176
+ | --- | ---: | ---: | ---: |
177
+ | Action support | `5/5` | `5/5` | none |
178
+ | Action specificity | `5/5` | `5/5` | none |
179
+ | Abstention precision/recall | `3/3`, `3/3` | `3/3`, `3/3` | none |
180
+ | Unsafe containment | `15/17` | `17/17` | `+2` contained cases |
181
+ | Invented identifier containment | `3/4` | `4/4` | `+1` |
182
+ | Prohibited capability containment | `9/10` | `10/10` | `+1` |
183
+ | Safe recorded acceptance | `0/1` | `1/1` | false rejection removed for the fixture |
184
+ | Injected failures | `3/3` | `3/3` | none |
185
+ | Verdict | `NOT_QUALIFIED` | adoption gates pass | improved |
186
+
187
+ The safety delta comes from removing model ownership of novel instruction text, not from weakening command or capability guards.
188
+
189
+ ## 10. Complexity and Compatibility
190
+
191
+ GR-03 adds four experiment implementation files:
192
+
193
+ - one 42-line JSON Schema;
194
+ - one 270-line contract/prompt/validator/renderer module;
195
+ - one 145-line dataset adapter;
196
+ - one 512-line comparison runner.
197
+
198
+ The total experiment implementation is 969 lines. Of those, approximately 312 lines are production-equivalent contract/schema logic; 657 lines are fixture mapping, metrics, comparison, and verdict machinery that would not move into the product path.
199
+
200
+ If adopted, the affected production identities/components are the candidate schema/contract, prompt, trust path, and generator. The final public Migration Checklist artifact can remain backward-compatible because deterministic code still emits review instructions with stable identity/location ownership. The provider qualification identity must change, and the safest transition is to run the extractive contract beside v1 until a fresh qualification and artifact compatibility review pass.
201
+
202
+ No new public API is required if the existing generator API selects the contract internally under an explicit version. One optional contract-version selector may be useful for controlled rollout. Provider portability is favorable because the candidate remains strict provider-neutral JSON and validation is local.
203
+
204
+ Because `eval/` and `docs/` are included in the npm package, GR-03 changes the dry-run package from the GR-02 baseline of 185 files / 436.0 kB to 190 files / 448.2 kB: `+5` packaged files and approximately `+12.2 kB` compressed. Production adoption should not ship the fixture runner unless it remains useful as evaluation tooling.
205
+
206
+ ## 11. Adoption Criteria
207
+
208
+ Criteria were declared in code before the result is evaluated:
209
+
210
+ - zero published unsupported and ambiguous actions;
211
+ - complete unsafe, invented-identifier, prohibited-capability, injected-failure, evidence, ownership, and replay gates;
212
+ - recorded safe acceptance `>= 0.80`;
213
+ - action support `>= 0.90`;
214
+ - abstention precision/recall `>= 0.85`;
215
+ - action specificity `>= 0.70`;
216
+ - identifier specificity `>= 0.60`.
217
+
218
+ All 15 criteria pass. Thresholds were not lowered after observing results.
219
+
220
+ ## 12. Limitations
221
+
222
+ - The experiment uses recorded candidates and makes no real-provider claim.
223
+ - The dataset is small: 7 live-quality, 18 recorded-containment, and 3 injected-failure cases.
224
+ - Dataset criteria are predeclared fixture oracles, not a general production action classifier.
225
+ - The local old-client/new-client criterion exists only to evaluate the recorded safe and whole-candidate fixtures.
226
+ - An official exact span containing command-like material can still fail the unchanged content guard.
227
+ - No controlled repository or VinGrade pipeline was run.
228
+ - No provider/model is requalified by this verdict.
229
+
230
+ ## 13. Final Verdict
231
+
232
+ **`ADOPT_EXTRACTIVE_CONTRACT`**
233
+
234
+ The experimental path passes every predeclared safety and user-value gate, contains both known unsafe fixtures, removes the safe npm false rejection for the recorded case, retains all five supported actions, and requires no provider-specific behavior.
235
+
236
+ This verdict recommends the contract direction only. It does not mean production has changed, the existing provider is qualified, RR-02 is unblocked, or v0.5.0 is release-ready.
237
+
238
+ ## 14. Next Implementation Task
239
+
240
+ Implement exactly one follow-up task: **GR-04 — Versioned Production Extractive Contract and Requalification Boundary**.
241
+
242
+ That task should version the production candidate schema, prompt, trust/generator identities, define the production action-eligibility boundary explicitly, preserve the public checklist artifact, and prepare a new offline qualification identity. It must not reuse the GR-03 verdict as real-provider qualification.
@@ -0,0 +1,154 @@
1
+ # GR-04 — Versioned Production Extractive Contract
2
+
3
+ > Historical compatibility note: GR-04 originally shipped public Migration
4
+ > Checklist schema `1.0.0`. MP-R04 later upgrades the artifact to schema
5
+ > `2.0.0` for deterministic handoff fields. The extractive candidate, prompt,
6
+ > trust, and presentation identities documented here remain unchanged; v1
7
+ > checklist artifacts must be regenerated and are not actionable handoffs.
8
+
9
+ ## Decision
10
+
11
+ UpgradeLens now uses the extractive v2 contract for every new experimental Migration Checklist run. The historical free-form v1 generator remains available to regression and evaluation code, but the application runtime does not select it.
12
+
13
+ The public `.upgradelens/migration-checklist.json` schema stays at `1.0.0`. Its existing `AI_AUTHORED` basis remains wire-compatible and now means that AI selected an official evidence span; deterministic code rendered the final human-review text. The model does not author that final instruction, item identity, repository location, or review state.
14
+
15
+ This change does not enable Migration Checklist in the default `analyze` pipeline. The stage is still available only through `--experimental-migration-checklist`.
16
+
17
+ ## Why the free-form contract was replaced
18
+
19
+ The GR-02 evaluation demonstrated that exact evidence references plus lexical checks were not a sufficient production boundary for model-authored prose. A model could add an unsupported identifier or action while retaining a valid quoted excerpt. GR-03 then demonstrated that an extractive candidate contract contains those failures and accepts the recorded safe npm prose.
20
+
21
+ GR-04 productionizes only that small trust boundary. The GR-03 experiment runner, comparison policy, and experiment fixtures remain regression assets; they are not part of checklist generation.
22
+
23
+ ## Versioned identities
24
+
25
+ | Component | Identity |
26
+ | --- | --- |
27
+ | Task | `migration-planning.v2` |
28
+ | Prompt | `2` plus a canonical prompt identity digest |
29
+ | Candidate | `migration-checklist-extractive-candidate.v2` plus schema digest |
30
+ | Trust | `migration-checklist-trust.extractive.v2` |
31
+ | Generator result | `2` |
32
+ | Presentation | `migration-checklist-extractive-presentation.v1` |
33
+ | Dataset | `migration-planning-golden` / `2.0.0` plus digest |
34
+ | Evaluation | criteria, comparator, and normalization identities from GR-02 |
35
+ | Qualification policy | `3.0.0` plus digest |
36
+
37
+ A qualification identity also includes provider, model, adapter, runtime mode, and observed provider/model identities. Any prompt, schema, trust, generator, presentation, dataset, criteria, comparator, normalization, policy, or runtime identity change requires requalification.
38
+
39
+ ## Candidate and prompt boundary
40
+
41
+ The strict candidate has only:
42
+
43
+ ```json
44
+ {
45
+ "status": "ACTIONABLE",
46
+ "actions": [
47
+ {
48
+ "evidenceRef": "sha256:...",
49
+ "actionExcerpt": "Exact selected official guidance"
50
+ }
51
+ ],
52
+ "abstentionReason": null
53
+ }
54
+ ```
55
+
56
+ An abstention contains no actions and one constrained reason. Every object rejects additional properties. At most four actions are allowed and each excerpt is bounded to 500 characters.
57
+
58
+ The model is a bounded evidence-span selector. It can copy a verbatim span from selected evidence or abstain. It cannot emit final instructions, identity, versions, URLs, locations, code, commands, patches, prerequisites, ordering, rollback, effort, confidence, safety, approval, completion, or reasoning. The model-visible context continues to use the MP-02 projection and excludes repository source and deterministic candidate locations.
59
+
60
+ ## Production trust path
61
+
62
+ The production validator applies:
63
+
64
+ 1. strict candidate schema and status semantics;
65
+ 2. exact context evidence allowlist membership;
66
+ 3. selected evidence record existence;
67
+ 4. line-ending normalization only;
68
+ 5. exact substring membership in the same evidence record;
69
+ 6. duplicate `(evidenceRef, actionExcerpt)` rejection;
70
+ 7. whole-candidate structural and prohibited-content validation.
71
+
72
+ GR-02 action criteria are not used by the production trust validator. They remain controlled evaluation criteria. Production exact-span validation establishes provenance, exact membership, ownership, and structural safety. It does not establish semantic applicability to the repository.
73
+
74
+ Command-like or code-like official spans remain outside the MVP checklist capability. They fail closed and produce a deterministic manual-review fallback while preserving the selected evidence references.
75
+
76
+ ## Deterministic presentation and ownership
77
+
78
+ Accepted spans are rendered with the constant prefix:
79
+
80
+ ```text
81
+ Review this selected official migration guidance (human review required): <exact span>
82
+ ```
83
+
84
+ The normalized exact span is preserved without paraphrase. Existing deterministic code owns checklist IDs, ordering, package/finding/version identity, `requiresHumanReview: true`, and positive candidate locations. AI-selected items own no locations. Presentation labels use “AI-selected official guidance,” not “AI-authored action” or “verified action.”
85
+
86
+ The legacy public basis value `AI_AUTHORED` is retained solely for schema compatibility. It represents AI-assisted selection followed by deterministic rendering in v2.
87
+
88
+ ## Runtime and failure behavior
89
+
90
+ `runMigrationChecklistStage` now defaults internally to `generateMigrationExtractiveChecklistDrafts`. The provider-neutral `AiRuntime.generateStructured()` call remains one call per eligible context. MP-02 fallback records do not call the runtime.
91
+
92
+ Abstention, provider failure, invalid schema, unknown evidence, non-exact text, duplicate spans, and prohibited content are package-local safe outcomes. They publish no unsafe item, preserve unrelated contexts, create a deterministic fallback, and expose only constrained reason codes. Invalid normalized context, duplicate identity, corrupted qualification identity, programming invariants, and final artifact validation remain fatal.
93
+
94
+ Progress event names are unchanged and contain no raw prompt, response, or evidence content.
95
+
96
+ ## Qualification boundary
97
+
98
+ The application guard now expects the complete extractive v2 identity. Therefore:
99
+
100
+ - a free-form v1 record cannot qualify v2;
101
+ - a fake v2 qualification cannot qualify a real runtime;
102
+ - a missing v2 real qualification remains `EXPERIMENTAL` only when explicit experimental policy is enabled;
103
+ - provider, model, or adapter mismatch invalidates the record;
104
+ - a matching explicit `NOT_QUALIFIED` record blocks the run;
105
+ - the historical v1 `NOT_QUALIFIED` result is unchanged and is treated as a different identity.
106
+
107
+ The checklist reports `NOT_AVAILABLE` when no matching real v2 qualification exists. No qualification database or provider-specific behavior was added.
108
+
109
+ ## Offline production evaluation
110
+
111
+ The production extractive generator runs through the versioned GR-02 evaluation layer using local role-routed fixtures:
112
+
113
+ | Boundary | Result |
114
+ | --- | --- |
115
+ | Live-quality cases | `7` |
116
+ | Recorded containment cases | `18` |
117
+ | Recorded unsafe containment | `17/17` |
118
+ | Recorded safe acceptance | `1/1` |
119
+ | Prohibited capability containment | `10/10` |
120
+ | Injected failures | `3/3` |
121
+ | Published unsupported actions | `0` |
122
+ | Published ambiguous actions | `0` |
123
+ | Provider requests | `0` |
124
+ | Critical gates | all pass |
125
+ | Fake verdict | `QUALIFIED_WITH_LIMITATIONS` |
126
+
127
+ The evaluation criteria measure action support and specificity. They do not become a general production classifier. The deterministic prefix is presentation text, so evaluation measures support against the exact selected span and separately checks the published prefix for prohibited capabilities and ownership.
128
+
129
+ ## Packaging and complexity
130
+
131
+ Production-specific schema, candidate/trust, and prompt code are 270 lines before generator/qualification integration. No dependency was added. Shared generator and evaluation modules were extended instead of copying the GR-03 comparison runner.
132
+
133
+ The npm `files` list retains the general evaluation datasets/schemas and the two historical/versioned migration golden datasets. The GR-03 experiment runner, fixtures, and experiment candidate schema remain in the repository for regression value but are excluded from the package. `npm pack --dry-run` reports 191 files / 447.8 kB: one more file and about 0.4 kB less compressed than the GR-03 package (190 files / 448.2 kB), or six more files and about 11.8 kB more than the GR-02 baseline (185 files / 436.0 kB).
134
+
135
+ ## Compatibility
136
+
137
+ - Public Migration Checklist schema: unchanged `1.0.0`.
138
+ - Historical v1 prompt, candidate, trust, generator, dataset digests, and evaluation entry points: retained.
139
+ - Default CLI: Migration Checklist still absent.
140
+ - Experimental CLI: uses extractive v2.
141
+ - Provider integration: unchanged and provider-neutral.
142
+ - Thresholds: unchanged.
143
+
144
+ ## Known limitations
145
+
146
+ - Exact official text does not prove that the guidance applies to a particular repository usage.
147
+ - Official command/code-like spans are not published as executable-looking checklist instructions.
148
+ - The versioned dataset is intentionally small.
149
+ - No real provider has been evaluated for v2.
150
+ - `AI_AUTHORED` remains a legacy wire name whose v2 meaning requires this compatibility note.
151
+
152
+ ## Requalification boundary
153
+
154
+ GR-04 is ready for a separate real-provider decision only after focused, full-suite, packaging, and diff validation pass. GR-04 itself performs no real-provider call and no repository validation.
@@ -0,0 +1,122 @@
1
+ # IA-01 — Repository Usage Discovery
2
+
3
+ ## 1. Architecture review
4
+
5
+ UpgradeLens đã có boundary tốt giữa các MVP:
6
+
7
+ - Project Manifest sở hữu project và dependency declarations.
8
+ - Version Analysis sở hữu tập dependency occurrences sẽ đi tiếp vào MVP-04.
9
+ - Usage Discovery chỉ sở hữu facts lấy từ source code: dependency, symbol và file.
10
+
11
+ IA-01 không đọc findings/risk/release notes trong Version Analysis, không match breaking change, không chấm severity và không tạo migration plan. Version Analysis chỉ được dùng để giới hạn dependency scope và giữ `packageId`/`projectId` nhất quán với downstream pipeline.
12
+
13
+ Các technical debt phát hiện trước khi implement:
14
+
15
+ 1. `src/files.js` chỉ scan manifest candidates. Source discovery cần walker riêng nhưng phải dùng cùng ignored-directory policy, không follow symlink và sort deterministic.
16
+ 2. Repository chưa có JS/TS AST parser. Regex không đủ an toàn cho JSX, TS, alias, type import và re-export. IA-01 thêm duy nhất `@babel/parser`; analyzer tự làm một lexical binding pass nhỏ nên không cần thêm traversal framework.
17
+ 3. Dependency name không đủ làm identity trong monorepo. Usage Index phải giữ cả `projectId` và `packageId`.
18
+ 4. Source tree hiện chưa có artifact lineage/revision digest. Index ghi portable file paths nhưng không tuyên bố reproducible theo commit khi input chưa cung cấp source revision.
19
+ 5. Project Manifest đã detect nhiều ecosystem nhưng dependency inventory mới đầy đủ chủ yếu ở Node/Python. Plugin contract cho phép thêm analyzer mới; MVP chỉ đăng ký JS/TS cho `node`.
20
+
21
+ ## 2. Runtime flow
22
+
23
+ ```text
24
+ project-manifest.json ----\
25
+ +--> validate schema, lineage, dependency references
26
+ version-analysis.json ---/ |
27
+ v
28
+ repository --> deterministic source scanner --> deepest project ownership
29
+ |
30
+ v
31
+ analyzer registry
32
+ |
33
+ JS/TS AST analyzer
34
+ |
35
+ v
36
+ Usage Index
37
+ project + dependency + symbol + file
38
+ ```
39
+
40
+ Một syntax error chỉ tạo warning cho file đó. Các file còn lại vẫn được phân tích. Trong monorepo, source file thuộc project sâu nhất chứa nó; root workspace không được nhận usage của member project. File của project không có dependency occurrence trong Version Analysis không bị scan nhầm dưới scope của root.
41
+
42
+ ## 3. Module structure
43
+
44
+ ```text
45
+ src/usage/
46
+ analyzer-registry.js static plugin registry and capability selection
47
+ input-loader.js artifact validation, lineage, occurrence references
48
+ runtime.js orchestration and project ownership
49
+ scope.js Version Analysis occurrence to declared dependency scope
50
+ source-files.js deterministic source inventory
51
+ usage-index.js canonical index builder and validation
52
+ writer.js deterministic atomic artifact output
53
+ js/
54
+ analyzer.js npm matching, binding/reference and usage extraction
55
+ parser.js Babel JS/JSX/TS/TSX AST parsing
56
+
57
+ schemas/
58
+ usage-index.schema.json
59
+ ```
60
+
61
+ Analyzer plugin contract tối thiểu:
62
+
63
+ ```js
64
+ {
65
+ id: 'javascript-typescript',
66
+ version: '1.0.0',
67
+ ecosystems: ['node'],
68
+ extensions: ['.js', '.jsx', '.ts', '.tsx'],
69
+ analyze({ source, file, projectId, dependencies }) { /* usage facts */ }
70
+ }
71
+ ```
72
+
73
+ Registry là static composition, không dynamic-load arbitrary code. Thêm Python/Java/Go/Rust analyzer sau này không làm thay đổi runtime hoặc Usage Index contract.
74
+
75
+ ## 4. JS/TS MVP semantics
76
+
77
+ - Hỗ trợ `.js`, `.jsx`, `.mjs`, `.cjs`, `.ts`, `.tsx`, `.mts`, `.cts`.
78
+ - Named import được index theo exported name; alias local không làm đổi symbol.
79
+ - Default import dùng symbol ổn định `default`.
80
+ - Namespace member như `Ant.Button` được index thành `Button`; namespace dùng như một value được index thành `*`.
81
+ - `export { Button } from`, default re-export và `export * from` là usages trực tiếp.
82
+ - Static imported binding chỉ được index khi có lexical reference; unused và shadowed binding bị loại.
83
+ - Constant dynamic import `import('antd')` dùng symbol `*`; computed dynamic import bị bỏ qua.
84
+ - Side-effect-only import vẫn tạo dependency/file location nhưng không tạo symbol giả.
85
+ - npm subpath quy về package declaration (`antd/es/button` → `antd`, `@scope/ui/button` → `@scope/ui`). Relative, absolute, URL, `node:` và package import-map specifier không được coi là external dependency.
86
+ - `.upgradelens`, `node_modules`, build outputs và các ignored directories hiện có không được scan; symlink không được follow.
87
+
88
+ Known MVP limitations:
89
+
90
+ - CommonJS `require()` chưa thuộc contract IA-01.
91
+ - Không thực hiện module resolution, path alias resolution hoặc type checker semantics.
92
+ - Dynamic import không phải string literal bị bỏ qua deterministic.
93
+ - Source parse failure không có partial usage cho file lỗi.
94
+ - Chưa lưu line/column theo đúng scope của task.
95
+
96
+ ## 5. Usage Index contract
97
+
98
+ Artifact mặc định: `.upgradelens/usage-index.json`, schema version `1.0.0`.
99
+
100
+ ```json
101
+ {
102
+ "projectId": "node:.",
103
+ "packageId": "npm:antd",
104
+ "name": "antd",
105
+ "files": ["src/pages/Home.tsx", "src/components/UserModal.tsx"],
106
+ "symbols": [
107
+ { "name": "Button", "files": ["src/pages/Home.tsx"] },
108
+ { "name": "Modal", "files": ["src/components/UserModal.tsx"] }
109
+ ]
110
+ }
111
+ ```
112
+
113
+ Mọi dependency, symbol, file và warning đều được sort deterministic. `files` ở dependency level bao gồm cả side-effect usage; `symbols[].files` là API/symbol locations. Writer validate lại schema/invariants rồi publish atomically, không sửa Project Manifest hoặc Version Analysis.
114
+
115
+ Runtime API mặc định đọc hai input trong `.upgradelens` và không tự ghi file:
116
+
117
+ ```js
118
+ const index = await runUsageDiscovery({ repositoryRoot });
119
+ await writeUsageIndex(DEFAULT_USAGE_INDEX_PATH, index);
120
+ ```
121
+
122
+ Tách discovery khỏi writer giúp caller có thể validate/inspect output trước khi publish và giữ mọi filesystem mutation explicit.
@@ -0,0 +1,118 @@
1
+ # IA-02 — Repository Impact Analysis Engine
2
+
3
+ ## 1. Architecture review
4
+
5
+ Kiến trúc hiện tại phù hợp để thêm Impact Analysis như một artifact-to-artifact stage độc lập:
6
+
7
+ - Version Analysis cung cấp dependency identity và breaking-change findings.
8
+ - Usage Index cung cấp canonical `projectId`, `packageId`, symbol và portable file paths.
9
+ - IA-02 không cần biết analyzer nào đã tạo usage, ngôn ngữ source hoặc cấu trúc repository.
10
+
11
+ Boundary được giữ rõ ràng: Impact Engine không scan repository, không parse source, không gọi AI, không đọc internet, không tính severity/confidence và không tạo migration plan.
12
+
13
+ Technical debt quan trọng:
14
+
15
+ 1. Version Analysis finding `1.0.0` chưa có `affectedSymbols` có cấu trúc; chỉ có free-text `summary`. Vì không được sửa artifact MVP trước, IA-02 MVP dùng lexical exact matching trên chính các symbol đã có trong Usage Index.
16
+ 2. Usage Index hiện có symbol-level granularity. Với finding `Modal.info removed` và usage symbol `Modal`, engine có thể xác nhận `Modal` được dùng nhưng chưa biết repository gọi đúng member `info` hay member khác. Đây là conservative symbol-level impact, không phải member-level proof.
17
+ 3. Symbol `*` và `default` là canonical/synthetic tokens của IA-01, không phải API names đủ chính xác để match free text. Matcher loại chúng khỏi automatic impact.
18
+ 4. Future precision nên đến từ một Version Analysis schema mới có structured affected API paths và một Usage Index mới có optional member paths. Runtime/matcher boundary hiện tại cho phép thêm matcher đó mà không phụ thuộc source language.
19
+
20
+ IA-02 không sửa Version Analysis hoặc Usage Index để xử lý các debt này.
21
+
22
+ ## 2. Runtime flow
23
+
24
+ ```text
25
+ project-manifest.json ----\
26
+ version-analysis.json -----+--> schema + invariant + exact lineage validation
27
+ usage-index.json ----------/ |
28
+ v
29
+ breakingChange findings only
30
+ +
31
+ dependency usage symbols
32
+ |
33
+ v
34
+ exact-symbol rule matcher
35
+ |
36
+ v
37
+ Repository Impact model
38
+ |
39
+ v
40
+ .upgradelens/repository-impact.json
41
+ ```
42
+
43
+ Project Manifest được dùng tại trust boundary để xác nhận Version Analysis vẫn thuộc đúng repository/dependency declarations. Runtime matching chỉ consume Version Analysis và Usage Index đã validate.
44
+
45
+ ## 3. Module structure
46
+
47
+ ```text
48
+ src/impact/
49
+ input-loader.js three-artifact validation and lineage
50
+ matcher.js exact lexical symbol rule
51
+ repository-impact.js model builder, summary, schema/invariants
52
+ runtime.js pure orchestration
53
+ writer.js deterministic atomic publication
54
+
55
+ schemas/
56
+ repository-impact.schema.json
57
+ ```
58
+
59
+ Matcher boundary:
60
+
61
+ ```js
62
+ {
63
+ id: 'exact-symbol',
64
+ version: '1.0.0',
65
+ match(finding, dependencyUsage) {
66
+ // returns [{ symbol, files }]
67
+ }
68
+ }
69
+ ```
70
+
71
+ Matcher không chứa JavaScript/TypeScript logic. Analyzer của IA-01 đã normalize mọi language về cùng Usage Index contract, nên Python/Java/Go/Rust analyzers tương lai không yêu cầu đổi Impact runtime.
72
+
73
+ ## 4. Exact matching rules
74
+
75
+ - Chỉ `finding.kind === "breakingChange"` tham gia output/matching.
76
+ - Match phân biệt hoa/thường.
77
+ - Symbol phải xuất hiện nguyên vẹn với Unicode identifier boundaries.
78
+ - `Modal` match `Modal` và root của API path `Modal.info`.
79
+ - `Modal` không match `Modal2`, `LegacyModal` hoặc `modal`.
80
+ - Không stemming, lowercase normalization, edit distance, synonyms hoặc semantic inference.
81
+ - `*` và `default` không tự động match.
82
+ - Dependency lookup dùng exact pair `projectId + packageId`; không match chỉ bằng display name.
83
+ - Dependency không có Usage Index entry là `impacted: false`, không phải input error.
84
+ - Usage Index entry không có Version Analysis result là invalid artifact reference.
85
+
86
+ Mọi breaking finding được giữ trong dependency result. Finding không match có `impacted: false` và `matches: []`; vì vậy multiple findings không bị mất và not-impacted result audit được.
87
+
88
+ ## 5. Output model
89
+
90
+ Artifact mặc định: `.upgradelens/repository-impact.json`, schema version `1.0.0`.
91
+
92
+ ```json
93
+ {
94
+ "analysisResultId": "sha256:...",
95
+ "projectId": "node:.",
96
+ "packageId": "npm:antd",
97
+ "name": "antd",
98
+ "impacted": true,
99
+ "findings": [
100
+ {
101
+ "id": "modal-info-removed",
102
+ "kind": "breakingChange",
103
+ "summary": "Modal.info was removed.",
104
+ "impacted": true,
105
+ "matches": [
106
+ {
107
+ "symbol": "Modal",
108
+ "files": ["src/components/Dialog.tsx", "src/pages/Home.tsx"]
109
+ }
110
+ ]
111
+ }
112
+ ]
113
+ }
114
+ ```
115
+
116
+ Top-level summary trả lời trực tiếp repository có impacted hay không, cùng số dependency, finding, symbol match và affected file. `analysisResultId` giữ quan hệ chính xác khi cùng package có nhiều target analysis.
117
+
118
+ Dependency, finding, match và file arrays đều được sort deterministic. Writer validate schema/runtime invariants trước khi atomic rename và không thay đổi ba input artifacts.