@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,536 @@
1
+ # MVP-02 — Knowledge Research Architecture
2
+
3
+ Status: architecture discovery for MVP-02-00. This document defines contracts and boundaries only; it does not specify production code, a prototype, networking implementation, or an AI runtime.
4
+
5
+ ## 1. Architecture Overview
6
+
7
+ MVP-02 adds an external knowledge boundary after deterministic repository discovery:
8
+
9
+ ```text
10
+ Repository
11
+
12
+
13
+ Project Discovery (MVP-01)
14
+
15
+
16
+ Project Manifest
17
+
18
+
19
+ Knowledge Research (MVP-02)
20
+ ┌────┼───────────────┐
21
+ ▼ ▼ ▼
22
+ Registry metadata Official sources Release metadata
23
+ └────┼───────────────┘
24
+
25
+ Knowledge Store
26
+
27
+
28
+ Knowledge Manifest
29
+
30
+
31
+ Version Analysis (MVP-03)
32
+
33
+
34
+ Impact Analysis (MVP-04)
35
+
36
+
37
+ Migration Planning (MVP-05)
38
+ ```
39
+
40
+ The sole repository-derived input to MVP-02 is the versioned Project Manifest produced by MVP-01. MVP-02 reads project identifiers, ecosystems, normalized dependency names, declaration types, declared version strings, and relative manifest paths from that artifact. It must validate the Project Manifest before doing any research. An unsupported Project Manifest schema version or structurally invalid manifest is a fatal input error; an individual dependency with incomplete data is a package-level warning.
41
+
42
+ MVP-02 must not read `package.json`, `requirements.txt`, source files, lockfiles, or any other repository content. Rescanning would create two competing discovery implementations, make later runs dependent on local filesystem state, and break provenance between stages. If later analysis needs a repository fact that the current Project Manifest does not contain, the correct response is to evolve the discovery contract in MVP-01 and version that contract—not to add an implicit scan inside MVP-02.
43
+
44
+ Knowledge Research first populates a reusable, content-addressed Knowledge Store, then projects the relevant normalized facts into a Knowledge Manifest. The store is an internal implementation detail. The manifest is the portable, deterministic, versioned output consumed by later MVPs. Raw or large upstream responses stay in the store; the manifest retains portable content digests and provenance but never exposes store paths, keys, envelope layout, validators, or storage APIs.
45
+
46
+ Determinism means that the same Project Manifest, policy configuration, clock, and source snapshots produce the same Knowledge Manifest bytes. Arrays are sorted by stable identifiers, maps use canonical key order, duplicates are merged only by documented identity rules, and asynchronous completion order never affects output. `generatedAt`, upstream publication timestamps, and cache acquisition timestamps are explicit rather than hidden. Transient headers such as request IDs and server dates are excluded. A later online run may legitimately produce a new snapshot when upstream knowledge changes; reproducibility comes from recorded provenance and content digests, not from pretending external data is immutable.
47
+
48
+ ### Research lifecycle
49
+
50
+ ```text
51
+ Project Manifest
52
+
53
+
54
+ Resolve Packages
55
+
56
+
57
+ Resolve Sources
58
+
59
+
60
+ Fetch Metadata
61
+
62
+
63
+ Normalize
64
+
65
+
66
+ Validate
67
+
68
+
69
+ Cache in Knowledge Store
70
+
71
+
72
+ Assemble Knowledge Manifest
73
+ ```
74
+
75
+ The stages have explicit responsibilities:
76
+
77
+ 1. **Resolve Packages** validates the Project Manifest, groups occurrences by registry and normalized identity, and rejects identities that cannot be researched safely.
78
+ 2. **Resolve Sources** selects registry endpoints and derives typed documentation, repository, and release candidates from explicit metadata. It does not use package-name similarity as evidence.
79
+ 3. **Fetch Metadata** obtains fresh or conditionally validated source representations under the approved network and retry policy. Offline mode substitutes available store entries and performs no network access.
80
+ 4. **Normalize** translates source-specific fields into common package, release, source, and trust records while retaining provenance.
81
+ 5. **Validate** checks normalized records, source relationships, required status/count invariants, and warning consistency before persistence or output.
82
+ 6. **Cache** writes validated response envelopes atomically to the content-addressed Knowledge Store. Invalid responses may retain sanitized diagnostics but never become successful facts.
83
+ 7. **Assemble Knowledge Manifest** selects facts relevant to the input Project Manifest, sorts them canonically, adds execution metadata, validates the artifact contract, and writes it atomically.
84
+
85
+ Package/source resolution, normalization, validation, and manifest assembly are deterministic functions of their declared inputs. Fetching and cache freshness depend on network state, policy, and time; those influences are made explicit through source snapshots and research metadata. Cache lookup must not alter output based on filesystem enumeration order or asynchronous completion order.
86
+
87
+ ## Artifact Ownership
88
+
89
+ ```text
90
+ Repository
91
+
92
+
93
+ Project Manifest owned by MVP-01
94
+
95
+
96
+ Knowledge Manifest owned by MVP-02
97
+
98
+
99
+ Version Analysis Manifest owned by MVP-03
100
+
101
+
102
+ Impact Analysis Manifest owned by MVP-04
103
+
104
+
105
+ Migration Plan owned by MVP-05
106
+ ```
107
+
108
+ Each artifact is immutable after successful validation and publication. A stage may consume outputs from one or more earlier stages, but it may not modify, repair, or silently enrich them in place. If a later stage needs a missing upstream fact, the owning stage evolves its versioned contract and regenerates a new artifact. The Knowledge Store is owned by MVP-02 but is not a pipeline artifact and is never consumed directly as a contract by MVP-03–05.
109
+
110
+ Within MVP-02, registry adapters own source-specific translation and error classification, source resolvers own source identification and provenance, the store owns response envelopes and freshness validators, and the manifest writer owns canonical ordering and artifact validation. None owns version conclusions or repository mutation.
111
+
112
+ ## 2. Responsibilities
113
+
114
+ MVP-02 is responsible for:
115
+
116
+ - validating and fingerprinting the input Project Manifest;
117
+ - deriving one research identity per unique supported package while retaining every project occurrence;
118
+ - resolving Node.js packages against the npm Registry and Python packages against PyPI;
119
+ - collecting package descriptions, licenses, publisher-provided links, canonical registry URLs, repository URLs, documentation URLs, latest registry-designated versions, and minimal release indexes;
120
+ - identifying official release feeds when the repository relationship is sufficiently supported by registry metadata;
121
+ - collecting release metadata such as version or tag, publication date, release URL, prerelease/yanked/deprecated indicators, and source provenance;
122
+ - recording which fields came from which source and whether that source was fetched, cached, stale, missing, or unavailable;
123
+ - maintaining deterministic, conditional, offline-friendly caches;
124
+ - producing partial package records and structured warnings when some sources fail;
125
+ - writing and validating the Knowledge Manifest atomically.
126
+
127
+ MVP-02 must not:
128
+
129
+ - infer the installed version from a version range;
130
+ - choose a recommended target version;
131
+ - compare current and latest versions;
132
+ - interpret semantic-version or PEP 440 compatibility;
133
+ - summarize changelogs or decide whether a change is breaking;
134
+ - map release changes to repository code;
135
+ - produce migration steps, patches, or code transformations;
136
+ - modify the Project Manifest or target repository;
137
+ - perform AI or LLM reasoning;
138
+ - introduce MCP, LangGraph, LangChain, an agent runtime, or a server;
139
+ - treat search results or community pages as equivalent to official evidence.
140
+
141
+ The boundary can be summarized as “collect facts with provenance, but draw no upgrade conclusions.”
142
+
143
+ ## 3. Knowledge Manifest
144
+
145
+ The Knowledge Manifest is a new contract with its own lifecycle. Its initial `schemaVersion` should be `1.0.0`, independent of Project Manifest schema `2.0.0` and independent of the npm package version. A future JSON Schema should define it, but this architecture task does not implement that schema.
146
+
147
+ The proposed default artifact is `.upgradelens/knowledge-manifest.json`. The name is an architecture decision for downstream consistency, not a CLI design in this task.
148
+
149
+ ### Knowledge Store versus Knowledge Manifest
150
+
151
+ The **Knowledge Store** is MVP-02's internal, reusable cache of fetched representations. It is content-addressed, may contain raw or normalized response bodies, and owns HTTP validators, TTL state, atomic storage envelopes, and implementation-specific lookup keys. Store entries are package/source-centric so unchanged external knowledge can be reused across research executions. The store can be discarded and rebuilt; its layout is not a public contract.
152
+
153
+ The **Knowledge Manifest** is the immutable output for one Project Manifest research execution. It embeds normalized facts needed downstream, package occurrences, source trust and provenance, warnings, portable content digests, and execution/cache summaries. It does not expose absolute paths, internal cache keys, ETags, storage envelope fields, directory layout, or cache APIs. MVP-03–05 consume the manifest, never the Knowledge Store. This boundary allows the store implementation to evolve without changing the manifest schema or downstream consumers.
154
+
155
+ ### Top-level contract
156
+
157
+ | Field | Meaning |
158
+ | --- | --- |
159
+ | `schemaVersion` | Knowledge Manifest contract version, initially `1.0.0` |
160
+ | `generatedAt` | ISO 8601 UTC time at which the complete manifest was assembled |
161
+ | `generator` | `name: UpgradeLens` and the producing package version |
162
+ | `input` | Project Manifest schema version, relative artifact name, full artifact SHA-256, and repository identity copied from the input |
163
+ | `policy` | Non-secret research policy: online/offline mode, registry bases, TTL policy version, prerelease inclusion policy, and source allowlist version |
164
+ | `research` | Execution metadata: research ID, start/completion times, duration, counts, retries, and partial failures |
165
+ | `summary` | Counts of input occurrences, unique research packages, resolved/partial/unresolved packages, sources, cache hits, and warnings |
166
+ | `packages` | Stable list of researched package records |
167
+ | `sources` | Stable source catalog and provenance records referenced by packages/releases |
168
+ | `cache` | Portable cache summary: mode, policy version, hit/miss/revalidation/stale counts; no store internals |
169
+ | `warnings` | Deterministically sorted non-fatal problems |
170
+
171
+ The `input.artifactDigest` hashes the exact Project Manifest bytes for provenance. Package cache keys do not use that digest; otherwise a changed `generatedAt` would invalidate unrelated package research. Research keys derive from ecosystem, registry, normalized package identity, resource kind, request representation, and adapter version.
172
+
173
+ ### Package record
174
+
175
+ Each package record should contain:
176
+
177
+ - `id`: stable identity such as `npm:react` or `pypi:fastapi`;
178
+ - `ecosystem`: `node` or `python` in MVP-02;
179
+ - `status`: `resolved`, `partial`, `notFound`, `invalid`, or `unavailable`;
180
+ - `identity`: declared names observed, normalized registry name, registry type, registry base URL, and canonical package page/API URL;
181
+ - `occurrences`: every Project Manifest occurrence with project ID, manifest path, dependency type, declared name, and declared version/reference;
182
+ - `metadata`: description, license expression/string, homepage, documentation URL, repository URL, issue URL, and deprecation/project-status facts when available;
183
+ - `latest`: the registry-designated latest version, how it was selected, publication time when available, registry release URL, and prerelease/yanked/deprecated facts;
184
+ - `releaseIndex`: minimal entries containing opaque version/tag, publication time, URL, status flags, and source IDs;
185
+ - `sourceIds`: references into the top-level source catalog;
186
+ - `warningCodes`: package-scoped warning codes, duplicated in full only in top-level `warnings`.
187
+
188
+ Occurrences preserve why a package was researched and prevent deduplication from losing project context. Package records are sorted by `id`; occurrences are sorted by project ID, manifest, dependency type, and declared version. Release identifiers are stored as provided by the source and sorted lexically in MVP-02. Semantic ordering is explicitly an MVP-03 responsibility.
189
+
190
+ `latest.selection` records registry semantics instead of an UpgradeLens recommendation. For npm it is `dist-tag:latest`; for PyPI it is `project-info-version`. MVP-02 must never compute “latest” by taking the maximum version string.
191
+
192
+ ### Source record
193
+
194
+ Every external fact must reference a source record containing:
195
+
196
+ - a stable `id`, for example `npm:react:registry` or `github:facebook/react:releases`;
197
+ - `kind`: `registry`, `officialDocumentation`, `sourceRepository`, `releaseFeed`, or `community`;
198
+ - `authority`: `registryAuthoritative`, `officialProject`, `publisherProvided`, or `community`;
199
+ - `trust`: `official`, `publisher`, `verified`, `community`, or `unknown`, with evidence references when corroborated;
200
+ - canonical HTTPS `url` and optional API URL;
201
+ - `status`: `available`, `notFound`, `unavailable`, `unverified`, or `stale`;
202
+ - `supports`: fields or evidence roles supplied by the source;
203
+ - `discoveredFrom`: source ID and field path that produced the link;
204
+ - `snapshot`: portable content digest, media type, retrieval time, and freshness state;
205
+ - optional `conflictsWith` source IDs when authoritative sources disagree.
206
+
207
+ Secrets, authorization headers, signed query parameters, local absolute paths, and raw transient error responses must never appear in this record.
208
+
209
+ ### Research and cache metadata
210
+
211
+ `research` describes the execution, not an upgrade conclusion. It contains `researchId`, `startedAt`, `completedAt`, derived `durationMs`, `inputOccurrenceCount`, `inputPackageCount`, `researchedPackageCount`, `sourceCount`, `cacheHitCount`, `cacheMissCount`, `cacheRevalidationCount`, `retryCount`, and `partialFailureCount`. `researchId` is deterministically derived from the input artifact digest, policy fingerprint, and ordered source content digests; a separate transient run ID may exist in logs but not in the manifest. Timestamps and duration are explicitly variable execution facts, while arrays and counts remain canonically derived from the completed execution.
212
+
213
+ Top-level `cache` repeats only the portable operational summary needed to explain online/offline and stale behavior. Essential normalized facts are embedded in package records, so the manifest remains useful when copied alone. Large evidence bodies remain in the Knowledge Store and are represented only by content digests; a future portable evidence bundle may copy those digest-addressed objects under a separately defined format. This does not make store keys or layout part of the Knowledge Manifest contract.
214
+
215
+ ## 4. Registry Strategy
216
+
217
+ MVP-02 officially supports exactly two registry adapters.
218
+
219
+ ### Node.js → npm Registry
220
+
221
+ The npm adapter uses the public npm Registry package metadata endpoint, `GET https://registry.npmjs.org/:package`. npm calls the response package metadata or a “packument”; the full representation includes `dist-tags`, a version map, publication times, homepage, repository, license, and other publisher-supplied fields. The [npm package metadata documentation](https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md) is the primary contract reference.
222
+
223
+ The adapter must preserve scoped identities and correctly encode scoped package paths. `dist-tags.latest` is the authoritative latest channel because npm publishers control distribution tags; npm documents that normal publication assigns the `latest` tag by default in its [dist-tag documentation](https://docs.npmjs.com/adding-dist-tags-to-packages/). Other tags are collected as registry facts but do not become recommendations.
224
+
225
+ The full packument is preferred over the abbreviated installation representation because knowledge research needs publication timestamps and source links. Individual version endpoints may be used only when full version-specific metadata is required. npm search is not an identity fallback: fuzzy search can return a different package and would make resolution non-deterministic.
226
+
227
+ ### Python → PyPI
228
+
229
+ The PyPI adapter looks up normalized names using the PyPA rule: lowercase the name and replace each run of `.`, `_`, or `-` with `-`, as specified by [Python package name normalization](https://packaging.python.org/en/latest/specifications/name-normalization/).
230
+
231
+ `GET /pypi/<project>/json` supplies latest project metadata, `info.version`, project URLs, and release information. PyPI notes that upload metadata is publisher-provided and may not exactly match distribution contents. PyPI also marks the project-level JSON `releases` field as deprecated for complete file discovery, so the adapter should use the JSON form of the [Index API](https://docs.pypi.org/api/index-api/) for the release/file index and the [PyPI JSON API](https://docs.pypi.org/api/json/) for project/latest-release metadata. No HTML scraping is required.
232
+
233
+ Project URLs must be classified through the PyPA [well-known Project-URL labels](https://packaging.python.org/en/latest/specifications/well-known-project-urls/), including documentation, source, changelog, release notes, and issues aliases. `info.version` is recorded as the registry-designated latest release; MVP-02 does not apply PEP 440 ordering or choose a non-yanked target.
234
+
235
+ ### Future registries
236
+
237
+ The architecture can later admit Maven Central, NuGet, the Go module proxy, crates.io, RubyGems, Packagist, and ecosystem-specific AL catalogs. They are not supported by MVP-02. A future adapter must provide the same conceptual operations—normalize identity, fetch registry facts, translate release metadata, expose source hints, define cache representation, and classify errors—without changing orchestration or the Knowledge Manifest’s common package fields.
238
+
239
+ Private npm registries and private Python indexes require authentication, registry selection, and trust-policy design. They remain deferred; public npm and PyPI are the deterministic defaults.
240
+
241
+ ## 5. Knowledge Sources
242
+
243
+ MVP-02 records both authority and provenance because availability does not imply reliability. Registry metadata is authoritative for what was published to that registry, but homepage and repository fields are supplied by package maintainers and can be stale or incorrect. Official documentation is strongest for usage and migration guidance, while a source repository is strongest for tags and source history. GitHub Releases are authoritative only when the repository relationship is credible, and the GitHub API explicitly omits ordinary tags that have no Release object.
244
+
245
+ ### Node.js example: React
246
+
247
+ For `react`, the source set should be:
248
+
249
+ 1. npm Registry for package identity, `dist-tags`, published versions, npm timestamps, license, and publisher-provided URLs;
250
+ 2. [React official documentation](https://react.dev/) for canonical documentation;
251
+ 3. the official [React Versions page](https://react.dev/versions) and [React blog](https://react.dev/blog) for project-maintained release and deprecation material;
252
+ 4. the `facebook/react` repository and its release/tag metadata when linked from official package/project metadata.
253
+
254
+ React illustrates why sources cannot be merged blindly: its documentation is maintained by major line rather than for every minor/patch version, while npm has package-level release facts. MVP-02 records both without claiming the documentation describes every published patch.
255
+
256
+ ### Python example: FastAPI
257
+
258
+ For `fastapi`, the source set should be:
259
+
260
+ 1. PyPI JSON/Index APIs for normalized identity, latest project metadata, distributions, publication times, and Project-URL hints;
261
+ 2. [FastAPI official documentation](https://fastapi.tiangolo.com/) and its release/version pages for project-maintained guidance;
262
+ 3. the official `fastapi/fastapi` repository and published GitHub Releases when the PyPI source URL supports that mapping.
263
+
264
+ FastAPI documents its version conventions separately from PyPI publication facts. MVP-02 stores those sources and their roles; it does not interpret whether a FastAPI release is safe for the discovered project.
265
+
266
+ ### Source trust model
267
+
268
+ Source priority answers which source is authoritative for a field; trust describes the established relationship between a source and the package/project. Every source receives one categorical trust value, without numeric scoring:
269
+
270
+ | Trust | Meaning |
271
+ | --- | --- |
272
+ | `official` | Documentation, repository, or release source demonstrably controlled by the project or governing organization |
273
+ | `publisher` | Registry record or URL supplied by an authorized package publisher; authoritative for registry publication but not automatically official for documentation claims |
274
+ | `verified` | A source relationship corroborated through independent official or publisher-controlled links, but not itself classified as official ownership |
275
+ | `community` | Third-party material with no project authority |
276
+ | `unknown` | Ownership or relationship cannot be established deterministically |
277
+
278
+ Trust matters because later analysis must distinguish a project's own compatibility statement from a maintainer-entered registry link or third-party interpretation. Official documentation is preferred for usage, policy, deprecation, and migration statements. Registries remain authoritative for package identity and publication facts, but descriptions, homepages, and repository links inside registry metadata are publisher-controlled fields and retain `publisher` trust until corroborated. Community and unknown sources may provide leads only when future policy enables them; they never override official, publisher-authoritative, or verified facts.
279
+
280
+ Trust assignment is rule-based and provenance-bearing. A source record states the classification and evidence source IDs; MVP-02 does not calculate confidence scores or infer ownership from naming similarity. Trust does not alter the field-specific priority rules in Section 8.
281
+
282
+ ### Reliability rules
283
+
284
+ - A URL from registry metadata is `publisherProvided` until corroborated by an official project or repository source.
285
+ - Repository ownership is not inferred from package-name similarity.
286
+ - Redirects are recorded at their final canonical HTTPS URL, subject to fetch safety rules.
287
+ - Conflicting values remain separate source assertions with `SOURCE_CONFLICT`; later stages do not receive a silently chosen value.
288
+ - Community resources are disabled by default in MVP-02 and can never override official or registry facts.
289
+
290
+ ## 6. Fetch Strategy
291
+
292
+ Research proceeds in deterministic phases:
293
+
294
+ 1. Validate the Project Manifest and extract Node/Python dependency occurrences.
295
+ 2. Group occurrences by `(registry, normalizedName)` while preserving all references.
296
+ 3. Validate registry eligibility. Unnamed direct references, local editable paths, and unsupported ecosystems remain visible but are not guessed into public registry identities.
297
+ 4. Resolve cache entries before scheduling network work.
298
+ 5. Fetch or conditionally revalidate registry metadata with bounded concurrency.
299
+ 6. Normalize registry responses into the common package/release contract.
300
+ 7. Resolve documentation, repository, changelog, and release URLs from authoritative metadata.
301
+ 8. Fetch GitHub release metadata only for corroborated GitHub repositories; ordinary tags remain a distinct source capability.
302
+ 9. Merge facts by field-specific authority, sort all output, validate the Knowledge Manifest, and write atomically.
303
+
304
+ For each supported registry package, MVP-02 should collect:
305
+
306
+ - canonical name and registry/package URLs;
307
+ - description and license as reported by the registry;
308
+ - registry-designated latest version and selection mechanism;
309
+ - minimal release index: version, published time if known, yanked/deprecated/prerelease indicators exposed directly by the source, and release URL;
310
+ - homepage, official documentation, source repository, issue tracker, changelog, and release-note URLs when explicitly provided;
311
+ - GitHub Release tag, title, URL, publication time, prerelease flag, and digest reference for the body snapshot;
312
+ - source retrieval status, validators, and content digests.
313
+
314
+ The release index should include all registry-published version identifiers but not every version’s full dependency graph or tarball. Large raw payloads and release bodies belong in cache objects. Output ordering is lexical because parsing and comparing version schemes belongs to MVP-03.
315
+
316
+ MVP-03, not MVP-02, determines which declared version is current, whether a range admits a release, which target is preferable, how prereleases/yanked versions should affect an upgrade, or which releases lie between current and target. MVP-02 may report the registry’s latest channel as a fact, but it cannot label it an upgrade recommendation.
317
+
318
+ Fetching must respect upstream services. GitHub recommends conditional requests using ETag or Last-Modified; a valid `304` avoids transferring an unchanged body and can avoid primary rate-limit cost when authenticated. GitHub also requires clients to handle `403`/`429`, `Retry-After`, and rate-limit reset headers rather than retrying aggressively. See the official [REST API best practices](https://docs.github.com/en/rest/using-the-rest-api/best-practices-for-using-the-rest-api), [rate-limit guidance](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api), and [release endpoints](https://docs.github.com/en/rest/releases/releases).
319
+
320
+ Only fixed registry/API hosts are fetched automatically. Publisher-provided documentation URLs require HTTPS, public-network resolution, bounded redirects, response size/type limits, and credential redaction. Loopback, link-local, private-network, and embedded-credential URLs are not fetched. Authentication is supplied out of band and never persisted in manifests or cache keys.
321
+
322
+ ## 7. Cache Strategy
323
+
324
+ The default cache root should be `.upgradelens/cache/knowledge/v1/`. Each entry is an atomic JSON envelope containing a canonical request identity, selected response headers, normalized or raw body, body SHA-256, `fetchedAt`, `validatedAt`, `expiresAt`, ETag, Last-Modified, and adapter version. No absolute path appears in the Knowledge Manifest.
325
+
326
+ A cache key is the SHA-256 of a canonical tuple:
327
+
328
+ ```text
329
+ adapter version
330
+ source kind
331
+ canonical registry/API base
332
+ normalized package or repository identity
333
+ endpoint/resource variant
334
+ Accept/API version
335
+ non-secret request parameters
336
+ ```
337
+
338
+ Authorization, user-agent, retry count, and volatile headers are excluded. Changing response translation rules increments the adapter/cache representation version, preventing old envelopes from being interpreted under new semantics.
339
+
340
+ Recommended initial TTLs are policy defaults, recorded in the manifest:
341
+
342
+ | Resource | TTL |
343
+ | --- | --- |
344
+ | Registry package metadata and release index | 24 hours |
345
+ | GitHub release metadata | 6 hours |
346
+ | Documentation/repository URL discovery | 7 days |
347
+ | Confirmed package/source `404` | 1 hour |
348
+ | Transient failures and rate limits | Not cached as successful data; honor retry metadata |
349
+
350
+ TTL indicates when to revalidate, not when facts become invalid. In online mode, a fresh hit is used directly; an expired entry is conditionally revalidated when validators exist, otherwise refetched. `304 Not Modified` updates validation/expiry metadata while retaining the same body digest. A changed `200` response creates a new snapshot.
351
+
352
+ In offline mode, no network call is attempted. Fresh entries are used normally. Expired entries may be used as stale facts, with source status `stale` and `CACHE_EXPIRED`; this is more useful than erasing known data and remains explicit. A missing entry produces `OFFLINE_CACHE_MISS` and an unresolved/partial package. Offline mode must never silently fall back to networking.
353
+
354
+ Manual invalidation is a policy operation, not a new CLI command in this architecture task. It can later support refreshing all entries, one registry, or one package. Deleting cache entries is always safe because the Knowledge Manifest is rebuilt from the Project Manifest and sources; however, reproducing an older snapshot requires retaining the referenced digest objects or exporting a future bundle.
355
+
356
+ ### Future multi-project reuse
357
+
358
+ Knowledge is package-centric rather than repository-centric. If Project A and Project B both reference `npm:react`, registry and source requests use the same package/source cache identity even though each Knowledge Manifest retains its own repository-specific occurrences and declared versions. A fresh representation can therefore satisfy both research executions without duplicating network work, and canonical normalization produces the same package facts for the same source snapshot.
359
+
360
+ The MVP-02 default remains a repository-local Knowledge Store. The package-centric key contract deliberately permits a future caller to point multiple repositories at one local store, but shared-store configuration and concurrency policy are not implemented here. Repository paths, Project Manifest digests, and occurrence data never enter reusable source keys, preventing one project's context from leaking into another project's cached knowledge.
361
+
362
+ ## 8. Knowledge Source Priority
363
+
364
+ Priority is field-specific, because no single source is best for all facts:
365
+
366
+ ```text
367
+ Official project documentation
368
+
369
+ Package registry
370
+
371
+ Official source repository / GitHub Releases
372
+
373
+ Community resources
374
+ ```
375
+
376
+ For documentation, upgrade guides, deprecations, and policy statements, official project documentation has highest authority. For package identity, publication, registry latest channel, and registry timestamps, the package registry is authoritative and overrides documentation. For source tags and published GitHub Release bodies, a corroborated official repository is authoritative for what it hosts but does not override registry publication facts. Community resources are contextual leads only, disabled by default, and never override higher levels.
377
+
378
+ The resolver stores assertions with source IDs rather than flattening conflicting values prematurely. A preferred display URL may be selected deterministically by role and authority, but conflicting facts remain inspectable. This provenance is essential for MVP-03: an analysis must be able to explain whether a claim came from npm, PyPI, official docs, or a repository release.
379
+
380
+ ## 9. Error Model
381
+
382
+ Project Manifest validation failures are fatal and prevent output replacement. All external failures are isolated by package/source so one unavailable registry record does not erase successful research for other packages. A Knowledge Manifest with warnings is still valid if its package statuses and source statuses reflect missing data.
383
+
384
+ | Warning code | When emitted |
385
+ | --- | --- |
386
+ | `INVALID_PACKAGE_REFERENCE` | A dependency cannot form a supported public registry identity, including unnamed/local references |
387
+ | `PACKAGE_NOT_FOUND` | The authoritative registry returns a confirmed `404` for a valid identity |
388
+ | `REGISTRY_UNAVAILABLE` | Registry access fails after bounded retry handling because of network or server failure |
389
+ | `REGISTRY_RATE_LIMITED` | Registry/API returns a rate limit response; include retryability without embedding credentials/headers |
390
+ | `REGISTRY_RESPONSE_INVALID` | A successful response violates the adapter’s expected shape or media type |
391
+ | `DOCUMENTATION_NOT_FOUND` | Metadata claims an official documentation URL but it is invalid or confirmed missing |
392
+ | `REPOSITORY_NOT_FOUND` | A claimed source repository is invalid, inaccessible, or confirmed missing |
393
+ | `RELEASE_METADATA_NOT_FOUND` | A corroborated repository is expected to provide release metadata but none is available; absence of GitHub Releases alone is not automatically an error because projects may publish tags only |
394
+ | `CACHE_EXPIRED` | Offline mode uses an expired cache entry explicitly as stale knowledge |
395
+ | `OFFLINE_CACHE_MISS` | Offline mode has no cache entry for a required source |
396
+ | `SOURCE_CONFLICT` | Two authoritative/publisher-supported sources disagree on a field that cannot be safely merged |
397
+
398
+ Warnings should contain `code`, stable `packageId` when known, optional `sourceId`, a sanitized deterministic message, and `retryable`. They do not contain stack traces, local paths, tokens, or occurrence timestamps. Sort order is package ID, code, source ID, then message.
399
+
400
+ Statuses follow facts: registry success plus missing optional docs is usually `partial`; registry `404` is `notFound`; invalid identity is `invalid`; transient registry failure without usable cache is `unavailable`; complete required registry facts are `resolved`. “Resolved” does not mean “safe to upgrade.”
401
+
402
+ ## 10. Extension Model
403
+
404
+ MVP-02 uses an implementation extension model, not a runtime plugin system. The orchestration pipeline depends on three conceptual boundaries:
405
+
406
+ - **Registry adapter:** recognizes supported Project Manifest records, canonicalizes identities, describes requests, translates responses, and classifies registry errors.
407
+ - **Source resolver:** converts registry/source hints into typed, provenance-bearing documentation, repository, changelog, and release sources.
408
+ - **Cache abstraction:** stores and revalidates source envelopes without understanding npm, PyPI, or GitHub business fields.
409
+
410
+ Adding an ecosystem means supplying a registry adapter and source rules plus conformance fixtures for identity, response normalization, warnings, caching, and deterministic sorting. Common package/source contracts remain unchanged. Ecosystem-specific data may live in a namespaced `extensions` object only when it cannot be represented by common fields; promotion into the common contract requires a schema version change.
411
+
412
+ Adapters are selected from a static internal registry at build time. There is no dynamic loading, marketplace, arbitrary code execution, or plugin manifest. This keeps packaging and security simple while allowing Java, .NET, Go, Rust, Ruby, PHP, and AL support to be developed independently later.
413
+
414
+ ## 11. MVP Boundary
415
+
416
+ MVP-02 ends when external package knowledge has been collected, normalized, cached, attributed, and written to a valid Knowledge Manifest. Its success criterion is factual completeness and explicit uncertainty—not an upgrade recommendation.
417
+
418
+ MVP-03 begins with version semantics and release analysis:
419
+
420
+ - interpret npm semver and Python/PEP 440 declarations;
421
+ - determine current/resolved baselines only from explicit artifacts and policy;
422
+ - compare current, candidate, and registry-designated latest versions;
423
+ - select releases relevant to an upgrade path;
424
+ - analyze release notes, changelogs, compatibility, and breaking-change evidence;
425
+ - produce semantic conclusions with citations and confidence.
426
+
427
+ This separation prevents network availability and source discovery from being entangled with semantic reasoning. MVP-02 can be replayed, cached, tested against fixtures, and run offline. MVP-03 can then operate on a frozen evidence set, making conclusions reproducible and auditable.
428
+
429
+ Breaking-change labels do not belong in the Knowledge Manifest. Even when a release source uses the words “breaking change,” MVP-02 records the source/body as evidence; MVP-03 determines the semantic meaning and relevance.
430
+
431
+ ## 12. Future Integration
432
+
433
+ The long-term artifact pipeline is:
434
+
435
+ ```text
436
+ Project Manifest (MVP-01)
437
+ │ repository facts and dependency occurrences
438
+
439
+ Knowledge Manifest (MVP-02)
440
+ │ package facts, releases, source provenance, evidence digests
441
+
442
+ Version Analysis Manifest (MVP-03)
443
+ │ baselines, targets, relevant releases, change findings and citations
444
+
445
+ Impact Analysis Manifest (MVP-04)
446
+ │ affected project components, severity, evidence and uncertainty
447
+
448
+ Migration Plan (MVP-05)
449
+ ordered actions, validation strategy, rollback and unresolved risks
450
+ ```
451
+
452
+ MVP-03 consumes both Project and Knowledge Manifests so every version conclusion retains the originating dependency occurrence. It must not alter either input. Its output references package IDs, source IDs, release IDs, and evidence digests from MVP-02.
453
+
454
+ MVP-04 consumes the Project Manifest and Version Analysis Manifest. If source-level impact analysis needs imports, API usage, configuration, or framework facts not present in the Project Manifest, the discovery artifact must be extended upstream through a new versioned contract. MVP-04 must not silently rescan the repository; otherwise impact results would not be traceable to the deterministic discovery snapshot.
455
+
456
+ MVP-05 consumes version and impact findings and emits a plan. It does not need registry access or repository scanning. Every plan item should trace back through impact/change findings to Knowledge Manifest sources and ultimately to a Project Manifest occurrence.
457
+
458
+ This chain establishes a central invariant: AI may interpret versioned artifacts and cited evidence, but raw repository traversal remains owned by deterministic discovery.
459
+
460
+ ## Open questions
461
+
462
+ These questions are non-blocking for the base architecture; recommended defaults are stated:
463
+
464
+ 1. **Complete versus bounded release indexes:** default to complete minimal registry indexes, measure manifest size, and introduce an explicit truncation policy only if evidence shows a need.
465
+ 2. **Portable evidence bundles:** keep digest references and normalized facts now; design a manifest-plus-cache export format only when offline downstream execution requires transfer between machines.
466
+ 3. **Authenticated public API usage:** support credentials out of band when implementation reaches GitHub rate limits, while preserving identical manifest contracts for authenticated and unauthenticated fetches.
467
+ 4. **Private registries:** defer registry selection/authentication semantics until public npm/PyPI behavior is stable.
468
+ 5. **Official documentation verification:** begin with publisher-provided and corroborated URLs; avoid general web search until its trust and reproducibility policy is explicitly designed.
469
+ 6. **Source-level facts for MVP-04:** decide in MVP-04 architecture discovery whether MVP-01 needs a new static usage-inventory contract.
470
+
471
+ ## Architecture decisions
472
+
473
+ - The Project Manifest is the only repository-derived input.
474
+ - The Knowledge Store is internal and reusable; the Knowledge Manifest is the only portable MVP-02 contract for downstream stages.
475
+ - Knowledge Manifest schema versioning is independent and begins at `1.0.0`.
476
+ - Public npm and PyPI are the only MVP-02 registries.
477
+ - Registry-designated latest versions are facts, not recommendations.
478
+ - Authority is field-specific, source trust is categorical, and all material facts retain provenance.
479
+ - Essential normalized metadata is embedded; large raw evidence is cached by digest.
480
+ - Partial external failure produces package/source statuses and warnings, not loss of successful results.
481
+ - Cache keys are package/source based and independent of Project Manifest generation timestamps.
482
+ - Pipeline artifacts are immutable and may be replaced only by a new validated output from their owning stage.
483
+ - All later stages consume versioned artifacts; no downstream repository rescans are permitted.
484
+ - The extension model is static and implementation-level, not a runtime plugin system.
485
+
486
+ ## Risks
487
+
488
+ - Publisher-provided registry links may be stale, malicious, or unrelated to the actual project.
489
+ - Monorepositories can publish many packages whose GitHub tags/releases do not map one-to-one to registry versions.
490
+ - npm/PyPI/GitHub schemas and deprecations can evolve independently of UpgradeLens.
491
+ - Complete release indexes can make the Knowledge Manifest large for long-lived packages.
492
+ - GitHub rate limits and network failures can produce partial snapshots.
493
+ - Mutable documentation means the same URL may serve different content over time; digests and cache retention are necessary for auditability.
494
+ - Stale offline data may be mistaken for current data unless status and warnings remain visible in every consumer.
495
+ - A Project Manifest without source-usage facts may be insufficient for future source-level impact analysis.
496
+
497
+ ## Future improvements
498
+
499
+ - Additional official registry adapters after Node/Python conformance is stable.
500
+ - Signed or portable evidence bundles containing manifest and digest-addressed cache objects.
501
+ - Mirror-aware and private-registry policies.
502
+ - Better corroboration between registry ownership, official domains, and source repositories.
503
+ - Selective collection of official upgrade guides without broad website crawling.
504
+ - Supply-chain provenance and vulnerability sources under a separately versioned contract.
505
+ - Shared artifact lineage tooling across Knowledge, Version, Impact, and Migration manifests.
506
+
507
+ ## Recommended implementation order
508
+
509
+ 1. Define and review the Knowledge Manifest JSON Schema and representative fixtures.
510
+ 2. Implement Project Manifest validation, canonical fingerprinting, package grouping, and deterministic output ordering.
511
+ 3. Implement the cache envelope, key policy, atomic persistence, conditional validation state, and offline behavior.
512
+ 4. Implement npm registry normalization against recorded fixtures, including scoped packages, dist-tags, timestamps, and errors.
513
+ 5. Implement PyPI JSON/Index normalization, name rules, Project-URL classification, yanked files, and errors.
514
+ 6. Implement source provenance and URL safety rules, then official documentation/repository discovery.
515
+ 7. Implement GitHub release metadata collection with pagination, conditional requests, and rate-limit handling.
516
+ 8. Add orchestration, partial-status propagation, warning sorting, manifest validation, and atomic write.
517
+ 9. Add reproducibility, offline, stale-cache, corrupted-cache, source-conflict, and cross-ecosystem conformance tests.
518
+ 10. Validate the complete stage against real Node/Python Project Manifests while keeping network responses recorded and repeatable in tests.
519
+
520
+ ## Technical debt intentionally deferred
521
+
522
+ - Private npm registries and private Python indexes.
523
+ - Community-source search and trust scoring.
524
+ - Full documentation-site crawling or semantic indexing.
525
+ - Version-range resolution, target selection, and breaking-change analysis.
526
+ - Installed-environment and lockfile resolution not represented by the Project Manifest.
527
+ - Vulnerability databases and package-signature verification.
528
+ - Dynamic plugins or third-party runtime adapters.
529
+ - Distributed/shared caches, databases, servers, and background workers.
530
+ - LLM, MCP, LangGraph, or agent-runtime integration.
531
+
532
+ ## Architecture Refinement Summary
533
+
534
+ This refinement adds a strict Knowledge Store/Knowledge Manifest boundary, an explicit research lifecycle, categorical source trust, portable research execution metadata, immutable artifact ownership, and a package-centric path for future multi-project cache reuse. These concepts remove ambiguity about internal state, provenance, stage responsibilities, and downstream contracts without adding a plugin system or operational infrastructure.
535
+
536
+ No MVP scope, supported ecosystem, registry strategy, fetch policy, cache policy, warning model, Project Manifest contract, extension model, or MVP boundary has changed. MVP-02 remains deterministic knowledge collection for public npm and PyPI. Its implementation can begin from this architecture without another structural redesign.
@@ -0,0 +1,50 @@
1
+ # MVP-02 CLI-Owned HTTP Runtime
2
+
3
+ ## Why it exists
4
+
5
+ VinGrade validation showed that an online research command could finish research, validate and write its Knowledge Manifest, print completion output, and still remain alive with established HTTPS sockets. Cache-heavy and offline runs exited normally. RC-01 confirmed and fixed response/body and timer cleanup, but a one-shot CLI still had no ownership over the connection pool used by `globalThis.fetch`.
6
+
7
+ The observation proves a lifecycle problem in the live command; it does not by itself prove the exact implementation detail inside the global Undici dispatcher. A one-shot CLI nevertheless needs an explicit resource boundary so its own network resources can be closed deterministically.
8
+
9
+ ## Ownership model
10
+
11
+ ```text
12
+ online CLI creates scoped runtime
13
+
14
+ adapters borrow runtime.fetch
15
+
16
+ research, validation, and output complete or fail
17
+
18
+ CLI closes its owned Agent in finally
19
+
20
+ Node exits naturally
21
+ ```
22
+
23
+ `createCliHttpRuntime()` creates one scoped Undici `Agent` for one online `research` command. Its fetch function passes that Agent only to the corresponding Undici fetch call. It uses bounded connections and short keep-alive settings so concurrent package research can reuse connections during the command without retaining the pool afterwards.
24
+
25
+ The module is internal: it is not exported from the package root and never appears in manifests, cache entries, source records, warnings, policy, or research IDs. It does not replace the process-wide dispatcher.
26
+
27
+ ## Online and offline behavior
28
+
29
+ - Online `upgradelens research` creates the runtime only when the CLI has not received an injected fetch.
30
+ - The CLI injects the runtime fetch into the existing npm and PyPI adapters.
31
+ - `research --offline`, `discover`, `--help`, and `--version` create no runtime.
32
+ - A user-injected fetch remains user-owned and is never closed by UpgradeLens.
33
+
34
+ `close()` is asynchronous and idempotent. The CLI invokes it exactly once in its ownership path after all research, manifest validation, stdout serialization, or atomic output work has finished.
35
+
36
+ ## Error behavior
37
+
38
+ The CLI closes its runtime after successful execution, package-level warning results, input failures, manifest failures, writer failures, and unexpected execution errors. If primary work fails and close also fails, the primary failure is preserved. If work succeeds but close fails, the command returns a non-zero operational result with a sanitized message. No raw Undici error, stack trace, response body, or header is emitted in normal CLI output.
39
+
40
+ The CLI never uses `process.exit()` or an unref-based shutdown workaround. Natural process exit follows closure of resources that UpgradeLens owns.
41
+
42
+ ## Validation scope
43
+
44
+ Automated tests verify scoped-dispatcher injection, idempotent close, no global fetch mutation, fetch-after-close failure, close precedence, offline/non-research gating, stdout JSON-only behavior, and user-injected fetch ownership. A local child-process integration test performs concurrent registry-like keep-alive HTTP requests through a real scoped Agent, then validates natural exit after normal, oversized, and 404/429/5xx responses.
45
+
46
+ ## Intentional limitations
47
+
48
+ This runtime has no proxy support, authentication, private registry configuration, global-dispatcher mutation, retry policy, or background worker. It is not a generic networking framework.
49
+
50
+ Vite's current full npm packument is approximately 38.9 MB, above the intentional 16 MiB npm response policy. It can therefore remain `unavailable` with `REGISTRY_RESPONSE_INVALID`; that payload-policy limitation is separate from the CLI lifecycle blocker. This task does not introduce abbreviated npm metadata, release-index redesign, or streaming JSON parsing.
@@ -0,0 +1,37 @@
1
+ # MVP-02 Registry HTTP Lifecycle
2
+
3
+ MVP-02 registry adapters share a small bounded JSON transport helper. It is an implementation detail: it does not add a public API, change either manifest schema, or introduce a network runtime framework.
4
+
5
+ ## Limits
6
+
7
+ The helper accepts a caller-provided positive safe-integer `maxResponseBytes`; it does not impose one shared registry default. Adapters own their limits because their payload shapes differ:
8
+
9
+ | Adapter | Default | Rationale |
10
+ | --- | ---: | --- |
11
+ | npm full packument | 16 MiB | Complete per-version metadata can make established package documents several megabytes. |
12
+ | PyPI project JSON | 8 MiB | Usually smaller, but established projects can exceed 1 MB. |
13
+
14
+ Both adapters reject zero, negative, fractional, unsafe, and over-ceiling values at construction. The common safety ceiling is 64 MiB. These values are execution settings only; they are not emitted in the Project Manifest or Knowledge Manifest.
15
+
16
+ ## Bounded read and cleanup guarantee
17
+
18
+ The helper uses a WHATWG stream reader when available. It counts bytes before retaining a chunk and stops accumulating as soon as the configured limit is exceeded. It does not call unrestricted `response.json()` or `response.text()` on normal WHATWG responses.
19
+
20
+ Every response owned by the helper ends in one of two states:
21
+
22
+ - a successful 200 JSON body is fully consumed before it is parsed and validated; or
23
+ - an unused or rejected body is explicitly cancelled.
24
+
25
+ This includes 404, 429, 5xx, unexpected statuses, invalid media type, declared oversize, streaming oversize, and fallback body-reader failures. An oversized reader is cancelled, its lock is released, and the response body is also best-effort cancelled after release. Cleanup failures are deliberately suppressed so they cannot expose upstream details or replace the focused sanitized error.
26
+
27
+ ## Timeout and transport ownership
28
+
29
+ An `AbortController` timeout covers fetch and bounded reading. The helper stores its handle and clears it in `finally` on success, HTTP errors, parse failures, aborts, and cleanup paths. No response, reader, or controller is retained after completion.
30
+
31
+ The transport helper accepts injected WHATWG-compatible fetch behavior and does not own a dispatcher. For an online CLI research run, the CLI now creates a scoped runtime with an Undici `Agent`, injects its fetch into the adapters, and closes that Agent after research/output handling in `finally`. The runtime does not replace Undici's global dispatcher.
32
+
33
+ Offline CLI research creates no HTTP runtime. Direct/internal consumers that inject a fetch remain its owner; UpgradeLens never attempts to close an injected fetch or its resources. See [CLI-owned HTTP runtime](MVP-02-CLI-HTTP-Runtime.md).
34
+
35
+ ## Error and cache behavior
36
+
37
+ Oversize remains bounded and is not partially parsed or cached. The internal adapter codes are `NPM_RESPONSE_TOO_LARGE` and `PYPI_RESPONSE_TOO_LARGE`; the stable public mapping remains `REGISTRY_RESPONSE_INVALID`, avoiding a schema change. Raw bodies, headers, credentials, cache details, and stack traces are not exposed.