@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,166 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { readFile } from 'node:fs/promises';
3
+
4
+ import Ajv2020 from 'ajv/dist/2020.js';
5
+
6
+ import { canonicalJsonBytes } from '../canonical-json.js';
7
+ import { compareText } from '../portable.js';
8
+ import {
9
+ MigrationChecklistTrustError,
10
+ validateMigrationChecklistInstructionTrust
11
+ } from './ai-candidate.js';
12
+
13
+ export const MIGRATION_EXTRACTIVE_CANDIDATE_CONTRACT =
14
+ 'migration-checklist-extractive-candidate.v2';
15
+ export const MIGRATION_EXTRACTIVE_TRUST_POLICY =
16
+ 'migration-checklist-trust.extractive.v2';
17
+ export const MIGRATION_EXTRACTIVE_PRESENTATION =
18
+ 'migration-checklist-extractive-presentation.v1';
19
+ export const MIGRATION_EXTRACTIVE_PRESENTATION_PREFIX =
20
+ 'Review this selected official migration guidance (human review required): ';
21
+ export const MIGRATION_EXTRACTIVE_CANDIDATE_ERROR_CODES = Object.freeze([
22
+ 'OUTPUT_JSON_INVALID',
23
+ 'OUTPUT_SCHEMA_INVALID',
24
+ 'OUTPUT_SEMANTICS_INVALID'
25
+ ]);
26
+
27
+ export const MIGRATION_EXTRACTIVE_CANDIDATE_SCHEMA = deepFreeze(JSON.parse(await readFile(
28
+ new URL('../../schemas/migration-checklist-extractive-candidate.schema.json', import.meta.url),
29
+ 'utf8'
30
+ )));
31
+
32
+ const ajv = new Ajv2020({ allErrors: true, strict: true });
33
+ const validateSchema = ajv.compile(MIGRATION_EXTRACTIVE_CANDIDATE_SCHEMA);
34
+
35
+ export function migrationExtractiveCandidateSchemaDigest() {
36
+ return `sha256:${createHash('sha256')
37
+ .update(canonicalJsonBytes(MIGRATION_EXTRACTIVE_CANDIDATE_SCHEMA))
38
+ .digest('hex')}`;
39
+ }
40
+
41
+ export class MigrationExtractiveCandidateError extends Error {
42
+ constructor(code, message) {
43
+ if (!MIGRATION_EXTRACTIVE_CANDIDATE_ERROR_CODES.includes(code)) {
44
+ throw new TypeError('Unknown extractive candidate error code.');
45
+ }
46
+ super(message);
47
+ this.name = 'MigrationExtractiveCandidateError';
48
+ this.code = code;
49
+ }
50
+ }
51
+
52
+ export function isMigrationExtractiveCandidateError(error) {
53
+ return error instanceof MigrationExtractiveCandidateError;
54
+ }
55
+
56
+ function deepFreeze(value) {
57
+ if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value;
58
+ for (const child of Object.values(value)) deepFreeze(child);
59
+ return Object.freeze(value);
60
+ }
61
+
62
+ function normalizeLineEndings(value) {
63
+ return value.replace(/\r\n?/g, '\n');
64
+ }
65
+
66
+ function parseCandidate(output) {
67
+ if (typeof output !== 'string') return output;
68
+ try {
69
+ return JSON.parse(output);
70
+ } catch {
71
+ throw new MigrationExtractiveCandidateError(
72
+ 'OUTPUT_JSON_INVALID',
73
+ 'Migration Checklist extractive candidate is not valid JSON.'
74
+ );
75
+ }
76
+ }
77
+
78
+ export function validateMigrationExtractiveCandidate(output) {
79
+ const candidate = parseCandidate(output);
80
+ if (!validateSchema(candidate)) {
81
+ throw new MigrationExtractiveCandidateError(
82
+ 'OUTPUT_SCHEMA_INVALID',
83
+ `Migration Checklist extractive candidate schema validation failed: ${ajv.errorsText(validateSchema.errors, { separator: '; ' })}`
84
+ );
85
+ }
86
+ if (candidate.status === 'ACTIONABLE'
87
+ && (candidate.actions.length === 0 || candidate.abstentionReason !== null)) {
88
+ throw new MigrationExtractiveCandidateError(
89
+ 'OUTPUT_SEMANTICS_INVALID',
90
+ 'ACTIONABLE extractive candidates require actions and a null abstentionReason.'
91
+ );
92
+ }
93
+ if (candidate.status === 'ABSTAIN'
94
+ && (candidate.actions.length !== 0 || candidate.abstentionReason === null)) {
95
+ throw new MigrationExtractiveCandidateError(
96
+ 'OUTPUT_SEMANTICS_INVALID',
97
+ 'ABSTAIN extractive candidates require no actions and a constrained abstentionReason.'
98
+ );
99
+ }
100
+ return deepFreeze(structuredClone(candidate));
101
+ }
102
+
103
+ function trustError(code, message, detailCode) {
104
+ return new MigrationChecklistTrustError(code, message, { detailCode });
105
+ }
106
+
107
+ function compareAction(left, right) {
108
+ return compareText(left.evidenceRef, right.evidenceRef)
109
+ || compareText(left.actionExcerpt, right.actionExcerpt);
110
+ }
111
+
112
+ /**
113
+ * Validate provenance, exact membership, ownership, and structural content only.
114
+ * This does not claim general semantic applicability to the repository.
115
+ */
116
+ export function trustValidateMigrationExtractiveCandidate(candidate, context) {
117
+ const allowlist = new Set(context.evidenceAllowlist);
118
+ const evidenceById = new Map(context.evidence.map((item) => [item.id, item]));
119
+ const seen = new Set();
120
+ const actions = [];
121
+
122
+ for (const rawAction of candidate.actions) {
123
+ if (!allowlist.has(rawAction.evidenceRef) || !evidenceById.has(rawAction.evidenceRef)) {
124
+ throw trustError(
125
+ 'EVIDENCE_REFERENCE_INVALID',
126
+ 'Extractive candidate references evidence outside its exact context allowlist.',
127
+ 'UNKNOWN_EVIDENCE_REFERENCE'
128
+ );
129
+ }
130
+ const action = {
131
+ evidenceRef: rawAction.evidenceRef,
132
+ actionExcerpt: normalizeLineEndings(rawAction.actionExcerpt)
133
+ };
134
+ const evidenceContent = normalizeLineEndings(evidenceById.get(action.evidenceRef).content);
135
+ if (!evidenceContent.includes(action.actionExcerpt)) {
136
+ throw trustError(
137
+ 'SUPPORTING_EXCERPT_INVALID',
138
+ 'Selected guidance is not an exact substring of its selected evidence record.',
139
+ 'EXCERPT_NOT_EXACT'
140
+ );
141
+ }
142
+ const key = `${action.evidenceRef}\0${action.actionExcerpt}`;
143
+ if (seen.has(key)) {
144
+ throw trustError(
145
+ 'DUPLICATE_ITEM',
146
+ 'Extractive candidate contains a duplicate evidence span.',
147
+ 'DUPLICATE_EVIDENCE_SPAN'
148
+ );
149
+ }
150
+ seen.add(key);
151
+
152
+ const instruction = `${MIGRATION_EXTRACTIVE_PRESENTATION_PREFIX}${action.actionExcerpt}`;
153
+ validateMigrationChecklistInstructionTrust(instruction, action.actionExcerpt);
154
+ actions.push({
155
+ ...action,
156
+ instruction,
157
+ evidenceRefs: [action.evidenceRef]
158
+ });
159
+ }
160
+
161
+ return deepFreeze({
162
+ status: candidate.status,
163
+ items: actions.sort(compareAction),
164
+ abstentionReason: candidate.abstentionReason
165
+ });
166
+ }
@@ -0,0 +1,62 @@
1
+ import { createHash } from 'node:crypto';
2
+
3
+ import { canonicalJsonBytes } from '../canonical-json.js';
4
+ import {
5
+ MIGRATION_EXTRACTIVE_CANDIDATE_SCHEMA
6
+ } from './extractive-candidate.js';
7
+ import { buildMigrationChecklistPromptContext } from './prompt.js';
8
+
9
+ export const MIGRATION_EXTRACTIVE_PLANNING_TASK = 'migration-planning.v2';
10
+ export const MIGRATION_EXTRACTIVE_PROMPT_VERSION = '2';
11
+ export const MIGRATION_EXTRACTIVE_SCHEMA_NAME =
12
+ 'upgradelens_migration_checklist_extractive_candidate_v2';
13
+
14
+ const PROMPT_IDENTITY = Object.freeze({
15
+ promptVersion: MIGRATION_EXTRACTIVE_PROMPT_VERSION,
16
+ role: 'bounded-evidence-span-selector',
17
+ output: 'strict-extractive-candidate-v2',
18
+ rulesVersion: '1'
19
+ });
20
+
21
+ function digest(value) {
22
+ return `sha256:${createHash('sha256').update(canonicalJsonBytes(value)).digest('hex')}`;
23
+ }
24
+
25
+ export function migrationExtractivePromptDigest() {
26
+ return digest(PROMPT_IDENTITY);
27
+ }
28
+
29
+ export function buildMigrationExtractivePrompt({
30
+ context,
31
+ outputSchema = MIGRATION_EXTRACTIVE_CANDIDATE_SCHEMA,
32
+ promptVersion = MIGRATION_EXTRACTIVE_PROMPT_VERSION
33
+ }) {
34
+ const modelContext = buildMigrationChecklistPromptContext(context);
35
+ return {
36
+ promptVersion,
37
+ system: [
38
+ 'You are the UpgradeLens bounded evidence-span selector for a human-review migration checklist.',
39
+ 'Select only verbatim migration guidance that exists in the supplied selected evidence.',
40
+ 'Do not write a final checklist instruction, explanation, or reasoning.',
41
+ 'Return only strict JSON that satisfies the structured output schema.'
42
+ ].join('\n'),
43
+ user: [
44
+ 'Rules:',
45
+ '- Copy each actionExcerpt verbatim from the same evidence record identified by evidenceRef.',
46
+ '- Use only refs in evidenceAllowlist. Never paraphrase or merge two spans into new text.',
47
+ '- Select multiple spans only when each span independently states explicit migration guidance.',
48
+ '- Return ABSTAIN for change descriptions, announcements, ambiguous text, or unclear version scope.',
49
+ '- Do not add action verbs, identifiers, config, flags, URLs, commands, code, patches, locations, prerequisites, order, rollback, effort, confidence, safety, approval, completion, or reasoning.',
50
+ '- Do not emit item, package, finding, version, status, review-state, or repository identity.',
51
+ '- Unknown currentVersion remains unknown. registryLatest is a registry fact, not a recommendation.',
52
+ '- Unsupported usage coverage does not mean unused, not impacted, or safe.',
53
+ '- Use no knowledge outside selected evidence.',
54
+ '',
55
+ 'Structured output schema:',
56
+ JSON.stringify(outputSchema),
57
+ '',
58
+ 'Migration Checklist Context:',
59
+ JSON.stringify(modelContext)
60
+ ].join('\n')
61
+ };
62
+ }