projscan 4.13.0 → 4.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/README.md +90 -24
  2. package/dist/cli/commands/evidencePack.js +2 -0
  3. package/dist/cli/commands/evidencePack.js.map +1 -1
  4. package/dist/cli/commands/prove.js +253 -23
  5. package/dist/cli/commands/prove.js.map +1 -1
  6. package/dist/cli/commands/startConsole.d.ts +2 -2
  7. package/dist/cli/commands/startConsole.js +2 -260
  8. package/dist/cli/commands/startConsole.js.map +1 -1
  9. package/dist/cli/commands/startConsoleExecution.d.ts +5 -0
  10. package/dist/cli/commands/startConsoleExecution.js +108 -0
  11. package/dist/cli/commands/startConsoleExecution.js.map +1 -0
  12. package/dist/cli/commands/startConsoleMission.d.ts +6 -0
  13. package/dist/cli/commands/startConsoleMission.js +157 -0
  14. package/dist/cli/commands/startConsoleMission.js.map +1 -0
  15. package/dist/cli/commands/startMissionBundle.js +24 -27
  16. package/dist/cli/commands/startMissionBundle.js.map +1 -1
  17. package/dist/core/adoption.d.ts +8 -81
  18. package/dist/core/adoption.js +4 -549
  19. package/dist/core/adoption.js.map +1 -1
  20. package/dist/core/adoptionFirstRunDiagnostics.d.ts +20 -0
  21. package/dist/core/adoptionFirstRunDiagnostics.js +240 -0
  22. package/dist/core/adoptionFirstRunDiagnostics.js.map +1 -0
  23. package/dist/core/adoptionMcpConfig.d.ts +27 -0
  24. package/dist/core/adoptionMcpConfig.js +123 -0
  25. package/dist/core/adoptionMcpConfig.js.map +1 -0
  26. package/dist/core/adoptionMcpDoctor.d.ts +23 -0
  27. package/dist/core/adoptionMcpDoctor.js +87 -0
  28. package/dist/core/adoptionMcpDoctor.js.map +1 -0
  29. package/dist/core/adoptionWorkflowRecipes.d.ts +14 -0
  30. package/dist/core/adoptionWorkflowRecipes.js +110 -0
  31. package/dist/core/adoptionWorkflowRecipes.js.map +1 -0
  32. package/dist/core/bugHunt.js +26 -255
  33. package/dist/core/bugHunt.js.map +1 -1
  34. package/dist/core/bugHuntPreflightFindings.d.ts +2 -1
  35. package/dist/core/bugHuntPreflightFindings.js +20 -0
  36. package/dist/core/bugHuntPreflightFindings.js.map +1 -1
  37. package/dist/core/bugHuntReportAssembly.d.ts +20 -0
  38. package/dist/core/bugHuntReportAssembly.js +179 -0
  39. package/dist/core/bugHuntReportAssembly.js.map +1 -0
  40. package/dist/core/bugHuntSourceFindings.d.ts +3 -0
  41. package/dist/core/bugHuntSourceFindings.js +61 -0
  42. package/dist/core/bugHuntSourceFindings.js.map +1 -0
  43. package/dist/core/dogfood.js +4 -393
  44. package/dist/core/dogfood.js.map +1 -1
  45. package/dist/core/dogfoodMarketValidation.d.ts +5 -0
  46. package/dist/core/dogfoodMarketValidation.js +265 -0
  47. package/dist/core/dogfoodMarketValidation.js.map +1 -0
  48. package/dist/core/dogfoodRepoEvaluation.d.ts +4 -0
  49. package/dist/core/dogfoodRepoEvaluation.js +137 -0
  50. package/dist/core/dogfoodRepoEvaluation.js.map +1 -0
  51. package/dist/core/evidenceComment.js +50 -13
  52. package/dist/core/evidenceComment.js.map +1 -1
  53. package/dist/core/feedback.js +2 -252
  54. package/dist/core/feedback.js.map +1 -1
  55. package/dist/core/feedbackIntakeClassifier.d.ts +2 -0
  56. package/dist/core/feedbackIntakeClassifier.js +255 -0
  57. package/dist/core/feedbackIntakeClassifier.js.map +1 -0
  58. package/dist/core/intentRouterCatalog.js +34 -0
  59. package/dist/core/intentRouterCatalog.js.map +1 -1
  60. package/dist/core/intentRouterKeywordToolGuards.js +2 -46
  61. package/dist/core/intentRouterKeywordToolGuards.js.map +1 -1
  62. package/dist/core/intentRouterKeywordWeights.js +13 -28
  63. package/dist/core/intentRouterKeywordWeights.js.map +1 -1
  64. package/dist/core/intentRouterProductGuardSignals.d.ts +3 -0
  65. package/dist/core/intentRouterProductGuardSignals.js +59 -0
  66. package/dist/core/intentRouterProductGuardSignals.js.map +1 -0
  67. package/dist/core/intentRouterWorkflowKeywordWeights.js +29 -0
  68. package/dist/core/intentRouterWorkflowKeywordWeights.js.map +1 -1
  69. package/dist/core/markdownSafety.d.ts +3 -0
  70. package/dist/core/markdownSafety.js +14 -0
  71. package/dist/core/markdownSafety.js.map +1 -0
  72. package/dist/core/preflight.d.ts +2 -0
  73. package/dist/core/preflight.js.map +1 -1
  74. package/dist/core/preflightChangedFiles.d.ts +2 -0
  75. package/dist/core/preflightChangedFiles.js +1 -1
  76. package/dist/core/preflightChangedFiles.js.map +1 -1
  77. package/dist/core/preflightInputs.d.ts +2 -0
  78. package/dist/core/preflightInputs.js +5 -2
  79. package/dist/core/preflightInputs.js.map +1 -1
  80. package/dist/core/proofLedger.d.ts +6 -1
  81. package/dist/core/proofLedger.js +174 -15
  82. package/dist/core/proofLedger.js.map +1 -1
  83. package/dist/core/proofReplay.d.ts +9 -0
  84. package/dist/core/proofReplay.js +164 -0
  85. package/dist/core/proofReplay.js.map +1 -0
  86. package/dist/core/proofSufficiency.d.ts +19 -0
  87. package/dist/core/proofSufficiency.js +425 -0
  88. package/dist/core/proofSufficiency.js.map +1 -0
  89. package/dist/core/prove.d.ts +8 -0
  90. package/dist/core/prove.js +578 -88
  91. package/dist/core/prove.js.map +1 -1
  92. package/dist/core/qualityScorecard.js +8 -238
  93. package/dist/core/qualityScorecard.js.map +1 -1
  94. package/dist/core/qualityScorecardDimensions.d.ts +14 -0
  95. package/dist/core/qualityScorecardDimensions.js +99 -0
  96. package/dist/core/qualityScorecardDimensions.js.map +1 -0
  97. package/dist/core/qualityScorecardRisks.d.ts +8 -0
  98. package/dist/core/qualityScorecardRisks.js +107 -0
  99. package/dist/core/qualityScorecardRisks.js.map +1 -0
  100. package/dist/core/qualityScorecardSignals.d.ts +20 -0
  101. package/dist/core/qualityScorecardSignals.js +59 -0
  102. package/dist/core/qualityScorecardSignals.js.map +1 -0
  103. package/dist/core/releaseEvidence.d.ts +1 -0
  104. package/dist/core/releaseEvidence.js +15 -40
  105. package/dist/core/releaseEvidence.js.map +1 -1
  106. package/dist/core/releaseEvidenceBaseline.js +4 -1
  107. package/dist/core/releaseEvidenceBaseline.js.map +1 -1
  108. package/dist/core/releaseEvidenceProofReceipt.d.ts +6 -0
  109. package/dist/core/releaseEvidenceProofReceipt.js +140 -0
  110. package/dist/core/releaseEvidenceProofReceipt.js.map +1 -0
  111. package/dist/core/releaseEvidenceVerdict.d.ts +5 -2
  112. package/dist/core/releaseEvidenceVerdict.js +39 -1
  113. package/dist/core/releaseEvidenceVerdict.js.map +1 -1
  114. package/dist/core/repositoryScanner.d.ts +1 -0
  115. package/dist/core/repositoryScanner.js +5 -4
  116. package/dist/core/repositoryScanner.js.map +1 -1
  117. package/dist/core/sessionResources.d.ts +14 -2
  118. package/dist/core/sessionResources.js +3 -3
  119. package/dist/core/sessionResources.js.map +1 -1
  120. package/dist/core/startFixedRouteCriteria.js +4 -0
  121. package/dist/core/startFixedRouteCriteria.js.map +1 -1
  122. package/dist/core/startInputs.d.ts +1 -1
  123. package/dist/core/startIntentTargets.d.ts +1 -1
  124. package/dist/core/startIntentTargets.js +1 -16
  125. package/dist/core/startIntentTargets.js.map +1 -1
  126. package/dist/core/startMissionInputStatusPolicy.d.ts +7 -0
  127. package/dist/core/startMissionInputStatusPolicy.js +74 -0
  128. package/dist/core/startMissionInputStatusPolicy.js.map +1 -0
  129. package/dist/core/startMissionPolicy.d.ts +6 -15
  130. package/dist/core/startMissionPolicy.js +4 -305
  131. package/dist/core/startMissionPolicy.js.map +1 -1
  132. package/dist/core/startMissionProofPolicy.d.ts +6 -0
  133. package/dist/core/startMissionProofPolicy.js +84 -0
  134. package/dist/core/startMissionProofPolicy.js.map +1 -0
  135. package/dist/core/startMissionRiskPolicy.d.ts +4 -0
  136. package/dist/core/startMissionRiskPolicy.js +85 -0
  137. package/dist/core/startMissionRiskPolicy.js.map +1 -0
  138. package/dist/core/startMissionRoutingPolicy.d.ts +6 -0
  139. package/dist/core/startMissionRoutingPolicy.js +67 -0
  140. package/dist/core/startMissionRoutingPolicy.js.map +1 -0
  141. package/dist/core/startMode.d.ts +1 -2
  142. package/dist/core/startMode.js +4 -151
  143. package/dist/core/startMode.js.map +1 -1
  144. package/dist/core/startModeIntentPolicy.d.ts +12 -0
  145. package/dist/core/startModeIntentPolicy.js +41 -0
  146. package/dist/core/startModeIntentPolicy.js.map +1 -0
  147. package/dist/core/startModeRoutingPolicy.d.ts +4 -0
  148. package/dist/core/startModeRoutingPolicy.js +117 -0
  149. package/dist/core/startModeRoutingPolicy.js.map +1 -0
  150. package/dist/core/startRouteActions.js +5 -0
  151. package/dist/core/startRouteActions.js.map +1 -1
  152. package/dist/core/startSearchQueryTargets.d.ts +1 -0
  153. package/dist/core/startSearchQueryTargets.js +17 -0
  154. package/dist/core/startSearchQueryTargets.js.map +1 -0
  155. package/dist/core/workplan.d.ts +3 -2
  156. package/dist/core/workplan.js +11 -585
  157. package/dist/core/workplan.js.map +1 -1
  158. package/dist/core/workplanCoordinationTasks.d.ts +3 -0
  159. package/dist/core/workplanCoordinationTasks.js +82 -0
  160. package/dist/core/workplanCoordinationTasks.js.map +1 -0
  161. package/dist/core/workplanModeTasks.d.ts +2 -0
  162. package/dist/core/workplanModeTasks.js +192 -0
  163. package/dist/core/workplanModeTasks.js.map +1 -0
  164. package/dist/core/workplanPreflightTasks.d.ts +2 -0
  165. package/dist/core/workplanPreflightTasks.js +126 -0
  166. package/dist/core/workplanPreflightTasks.js.map +1 -0
  167. package/dist/core/workplanQualitySignals.d.ts +7 -0
  168. package/dist/core/workplanQualitySignals.js +63 -0
  169. package/dist/core/workplanQualitySignals.js.map +1 -0
  170. package/dist/core/workplanReport.d.ts +4 -0
  171. package/dist/core/workplanReport.js +79 -0
  172. package/dist/core/workplanReport.js.map +1 -0
  173. package/dist/core/workplanRiskOwnership.d.ts +5 -0
  174. package/dist/core/workplanRiskOwnership.js +97 -0
  175. package/dist/core/workplanRiskOwnership.js.map +1 -0
  176. package/dist/core/workplanSuggestedActions.d.ts +2 -0
  177. package/dist/core/workplanSuggestedActions.js +43 -0
  178. package/dist/core/workplanSuggestedActions.js.map +1 -0
  179. package/dist/mcp/tools/prove.js +24 -18
  180. package/dist/mcp/tools/prove.js.map +1 -1
  181. package/dist/projscan-sbom.cdx.json +6 -6
  182. package/dist/tool-manifest.json +3 -3
  183. package/dist/types/config.d.ts +15 -0
  184. package/dist/types/evidencePack.d.ts +21 -0
  185. package/dist/types/proofLedger.d.ts +1 -1
  186. package/dist/types/prove.d.ts +96 -1
  187. package/dist/utils/changedFiles.js +57 -16
  188. package/dist/utils/changedFiles.js.map +1 -1
  189. package/dist/utils/config.js +2 -0
  190. package/dist/utils/config.js.map +1 -1
  191. package/dist/utils/configProofRecipes.d.ts +2 -0
  192. package/dist/utils/configProofRecipes.js +91 -0
  193. package/dist/utils/configProofRecipes.js.map +1 -0
  194. package/docs/GUIDE.md +145 -25
  195. package/package.json +1 -1
@@ -1,33 +1,48 @@
1
1
  import crypto from 'node:crypto';
2
+ import { createReadStream } from 'node:fs';
2
3
  import fs from 'node:fs/promises';
3
4
  import path from 'node:path';
5
+ import readline from 'node:readline';
4
6
  export const DEFAULT_PROOF_LEDGER_PATH = '.projscan/proof-ledger.jsonl';
5
7
  const MAX_SUMMARY_LENGTH = 240;
6
8
  const REDACTION_PATTERNS = [
9
+ /-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z0-9 ]*PRIVATE KEY-----/g,
10
+ /\beyJ[A-Za-z0-9_-]{8,}\.eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g,
11
+ /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g,
7
12
  /\bBearer\s+[A-Za-z0-9._~+/=-]+/gi,
8
- /\b(?:sk|pk|whsec|ghp|gho|github_pat)_[A-Za-z0-9_=-]{8,}/gi,
9
- /\b(password|passwd|pwd|token|secret|api[_-]?key)\s*[:=]\s*["']?[^"'\s,;]+/gi,
10
- /\b[A-Za-z_][A-Za-z0-9_]*\.env\s*[:=]\s*[^"'\s,;]+/gi,
13
+ /\b(?:sk|pk|whsec|ghp|gho|github_pat)[_-][A-Za-z0-9_=-]{8,}/gi,
14
+ /\b[A-Z0-9_]*(?:TOKEN|SECRET|PASSWORD|PASSWD|PWD|API[_-]?KEY|ACCESS[_-]?KEY|PRIVATE[_-]?KEY)[A-Z0-9_]*\s*=\s*(?:"[^"]*"|'[^']*'|[^"'\s,;]+)/gi,
15
+ /\b(password|passwd|pwd|token|secret|api[_-]?key)\s*[:=]\s*(?:"[^"]*"|'[^']*'|[^"'\s,;]+)/gi,
16
+ /(--?(?:password|passwd|pwd|token|secret|api[_-]?key))\s+(?:"[^"]*"|'[^']*'|[^"'\s,;]+)/gi,
17
+ /\b[A-Za-z_][A-Za-z0-9_]*\.env\s*[:=]\s*(?:"[^"]*"|'[^']*'|[^"'\s,;]+)/gi,
11
18
  ];
12
19
  export function normalizeProofCommand(command) {
13
20
  return command.trim().replace(/\s+/g, ' ');
14
21
  }
15
- export function changedFileFingerprint(files) {
22
+ export function redactProofCommand(command) {
23
+ return redactProofOutput(command);
24
+ }
25
+ export async function changedFileFingerprint(rootPath, files) {
16
26
  const normalized = [...new Set(files.map(normalizePath).filter(Boolean))].sort();
17
- return crypto.createHash('sha256').update(normalized.join('\n')).digest('hex');
27
+ const entries = await Promise.all(normalized.map((file) => changedFileFingerprintEntry(rootPath, file)));
28
+ return crypto.createHash('sha256').update(entries.join('\n')).digest('hex');
18
29
  }
19
30
  export function redactProofSummary(value) {
20
- let summary = (value ?? '').replace(/\s+/g, ' ').trim();
31
+ let summary = redactProofOutput(value ?? '').replace(/\s+/g, ' ').trim();
21
32
  if (summary.length === 0)
22
33
  summary = 'No proof output summary supplied.';
23
- for (const pattern of REDACTION_PATTERNS) {
24
- summary = summary.replace(pattern, (match, label) => label ? `${label}=[redacted]` : '[redacted]');
25
- }
26
34
  if (summary.length > MAX_SUMMARY_LENGTH) {
27
35
  return `${summary.slice(0, MAX_SUMMARY_LENGTH - 1)}...`;
28
36
  }
29
37
  return summary;
30
38
  }
39
+ export function redactProofOutput(value) {
40
+ let output = value;
41
+ for (const pattern of REDACTION_PATTERNS) {
42
+ output = output.replace(pattern, redactionReplacement);
43
+ }
44
+ return output;
45
+ }
31
46
  export async function appendProofLedgerRecord(rootPath, ledgerPath, input) {
32
47
  const completedAt = input.completedAt ?? new Date().toISOString();
33
48
  const durationMs = Math.max(0, Math.round(input.durationMs));
@@ -36,25 +51,26 @@ export async function appendProofLedgerRecord(rootPath, ledgerPath, input) {
36
51
  ? new Date(completedMs - durationMs).toISOString()
37
52
  : completedAt;
38
53
  const changedFiles = [...new Set(input.changedFiles.map(normalizePath).filter(Boolean))].sort();
54
+ const command = redactProofCommand(input.command);
39
55
  const record = {
40
56
  schemaVersion: 1,
41
- id: proofRecordId(input.command, completedAt, input.exitCode),
42
- command: input.command,
43
- normalizedCommand: normalizeProofCommand(input.command),
57
+ id: proofRecordId(command, completedAt, input.exitCode),
58
+ command,
59
+ normalizedCommand: normalizeProofCommand(command),
44
60
  cwd: normalizePath(input.cwd ?? '.'),
45
61
  exitCode: input.exitCode,
46
62
  status: input.exitCode === 0 ? 'passed' : 'failed',
47
63
  startedAt,
48
64
  completedAt,
49
65
  durationMs,
50
- changedFileFingerprint: changedFileFingerprint(changedFiles),
66
+ changedFileFingerprint: await changedFileFingerprint(rootPath, changedFiles),
51
67
  changedFiles,
52
68
  outputSummary: redactProofSummary(input.outputSummary),
53
69
  source: input.source ?? 'prove-record',
54
- ...(input.logPath ? { logPath: normalizePath(input.logPath) } : {}),
70
+ ...(input.logPath ? { logPath: normalizeProofLogPath(input.logPath) } : {}),
55
71
  };
56
72
  const fullPath = resolveProofLedgerPath(rootPath, ledgerPath);
57
- await fs.mkdir(path.dirname(fullPath), { recursive: true });
73
+ await prepareProofArtifactWritePath(rootPath, fullPath);
58
74
  await fs.appendFile(fullPath, `${JSON.stringify(record)}\n`, 'utf-8');
59
75
  return record;
60
76
  }
@@ -62,6 +78,7 @@ export async function readProofLedger(rootPath, ledgerPath) {
62
78
  const fullPath = resolveProofLedgerPath(rootPath, ledgerPath);
63
79
  let raw;
64
80
  try {
81
+ await prepareProofArtifactReadPath(rootPath, fullPath);
65
82
  raw = await fs.readFile(fullPath, 'utf-8');
66
83
  }
67
84
  catch (error) {
@@ -74,6 +91,41 @@ export async function readProofLedger(rootPath, ledgerPath) {
74
91
  .map(parseProofLedgerRow)
75
92
  .filter((record) => Boolean(record));
76
93
  }
94
+ export async function readLatestProofLedgerRecords(rootPath, ledgerPath, commands) {
95
+ const normalizedCommands = uniqueNormalizedCommands(commands);
96
+ if (normalizedCommands.length === 0)
97
+ return [];
98
+ const fullPath = resolveProofLedgerPath(rootPath, ledgerPath);
99
+ const latestByCommand = new Map();
100
+ let stream;
101
+ try {
102
+ await prepareProofArtifactReadPath(rootPath, fullPath);
103
+ await fs.access(fullPath);
104
+ stream = createReadStream(fullPath, { encoding: 'utf-8' });
105
+ }
106
+ catch (error) {
107
+ if (isNodeErrorCode(error, 'ENOENT'))
108
+ return [];
109
+ throw error;
110
+ }
111
+ const lines = readline.createInterface({
112
+ input: stream,
113
+ crlfDelay: Infinity,
114
+ });
115
+ const requested = new Set(normalizedCommands);
116
+ for await (const line of lines) {
117
+ const record = parseProofLedgerRow(line);
118
+ if (!record || !requested.has(record.normalizedCommand))
119
+ continue;
120
+ const latest = latestByCommand.get(record.normalizedCommand);
121
+ if (!latest || record.completedAt.localeCompare(latest.completedAt) >= 0) {
122
+ latestByCommand.set(record.normalizedCommand, record);
123
+ }
124
+ }
125
+ return normalizedCommands
126
+ .map((command) => latestByCommand.get(command))
127
+ .filter((record) => Boolean(record));
128
+ }
77
129
  export function latestProofRecordFor(records, command) {
78
130
  const normalized = normalizeProofCommand(command);
79
131
  let latest;
@@ -85,6 +137,28 @@ export function latestProofRecordFor(records, command) {
85
137
  }
86
138
  return latest;
87
139
  }
140
+ export async function prepareProofArtifactWritePath(rootPath, fullPath) {
141
+ const root = path.resolve(rootPath);
142
+ const target = path.resolve(fullPath);
143
+ const relative = path.relative(root, target);
144
+ if (!relative || relative.startsWith('..') || path.isAbsolute(relative)) {
145
+ throw new Error('Proof artifact path must stay inside the project root.');
146
+ }
147
+ const parent = path.dirname(target);
148
+ await assertNoSymlinkInExistingPath(root, parent);
149
+ await fs.mkdir(parent, { recursive: true });
150
+ await assertNoSymlinkInExistingPath(root, parent);
151
+ await assertPathIsNotSymlink(target);
152
+ }
153
+ export async function prepareProofArtifactReadPath(rootPath, fullPath) {
154
+ const root = path.resolve(rootPath);
155
+ const target = path.resolve(fullPath);
156
+ const relative = path.relative(root, target);
157
+ if (!relative || relative.startsWith('..') || path.isAbsolute(relative)) {
158
+ throw new Error('Proof artifact path must stay inside the project root.');
159
+ }
160
+ await assertNoSymlinkInExistingPath(root, target);
161
+ }
88
162
  function proofRecordId(command, completedAt, exitCode) {
89
163
  const digest = crypto
90
164
  .createHash('sha256')
@@ -101,8 +175,80 @@ function resolveProofLedgerPath(rootPath, ledgerPath) {
101
175
  if (!relative || relative.startsWith('..') || path.isAbsolute(relative)) {
102
176
  throw new Error('Proof ledger path must stay inside the project root.');
103
177
  }
178
+ const normalizedRequested = normalizePath(relative);
179
+ if (normalizedRequested !== DEFAULT_PROOF_LEDGER_PATH &&
180
+ !/^\.projscan\/proof-ledgers\/[^/]+\.jsonl$/.test(normalizedRequested)) {
181
+ throw new Error('Proof ledger path must be .projscan/proof-ledger.jsonl or .projscan/proof-ledgers/<name>.jsonl.');
182
+ }
104
183
  return fullPath;
105
184
  }
185
+ async function changedFileFingerprintEntry(rootPath, file) {
186
+ const fullPath = resolvePathInsideRoot(rootPath, file);
187
+ if (!fullPath)
188
+ return `${file}\0outside-root`;
189
+ try {
190
+ const stat = await fs.lstat(fullPath);
191
+ if (stat.isSymbolicLink()) {
192
+ const linkTarget = await fs.readlink(fullPath);
193
+ const digest = crypto.createHash('sha256').update(linkTarget).digest('hex');
194
+ return `${file}\0symlink\0${digest}`;
195
+ }
196
+ if (!stat.isFile())
197
+ return `${file}\0${stat.isDirectory() ? 'directory' : 'non-file'}`;
198
+ const digest = crypto.createHash('sha256').update(await fs.readFile(fullPath)).digest('hex');
199
+ return `${file}\0file\0${digest}`;
200
+ }
201
+ catch (error) {
202
+ if (isNodeErrorCode(error, 'ENOENT'))
203
+ return `${file}\0missing`;
204
+ throw error;
205
+ }
206
+ }
207
+ function resolvePathInsideRoot(rootPath, file) {
208
+ const root = path.resolve(rootPath);
209
+ const fullPath = path.resolve(root, file);
210
+ const relative = path.relative(root, fullPath);
211
+ if (!relative || relative.startsWith('..') || path.isAbsolute(relative))
212
+ return null;
213
+ return fullPath;
214
+ }
215
+ function normalizeProofLogPath(logPath) {
216
+ const normalized = normalizePath(logPath);
217
+ if (!/^\.projscan\/proof-logs\/[^/]+\.log$/.test(normalized)) {
218
+ throw new Error('Proof log path must stay under .projscan/proof-logs/ and end with .log.');
219
+ }
220
+ return normalized;
221
+ }
222
+ async function assertNoSymlinkInExistingPath(root, target) {
223
+ const relative = path.relative(root, target);
224
+ const segments = relative.split(path.sep).filter(Boolean);
225
+ let current = root;
226
+ for (const segment of segments) {
227
+ current = path.join(current, segment);
228
+ try {
229
+ const stat = await fs.lstat(current);
230
+ if (stat.isSymbolicLink())
231
+ throw new Error('Proof artifact paths must not contain symlinks.');
232
+ }
233
+ catch (error) {
234
+ if (isNodeErrorCode(error, 'ENOENT'))
235
+ return;
236
+ throw error;
237
+ }
238
+ }
239
+ }
240
+ async function assertPathIsNotSymlink(target) {
241
+ try {
242
+ const stat = await fs.lstat(target);
243
+ if (stat.isSymbolicLink())
244
+ throw new Error('Proof artifact paths must not contain symlinks.');
245
+ }
246
+ catch (error) {
247
+ if (isNodeErrorCode(error, 'ENOENT'))
248
+ return;
249
+ throw error;
250
+ }
251
+ }
106
252
  function parseProofLedgerRow(line) {
107
253
  const trimmed = line.trim();
108
254
  if (!trimmed)
@@ -122,9 +268,22 @@ function isProofLedgerRecord(value) {
122
268
  typeof value.normalizedCommand === 'string' &&
123
269
  typeof value.exitCode === 'number');
124
270
  }
271
+ function uniqueNormalizedCommands(commands) {
272
+ return [...new Set(commands.map(normalizeProofCommand).filter(Boolean))];
273
+ }
125
274
  function normalizePath(value) {
126
275
  return value.split(path.sep).join('/').replace(/^\.\//, '');
127
276
  }
277
+ function redactionReplacement(_match, ...args) {
278
+ const captures = args.slice(0, -2);
279
+ const label = captures.find((value) => typeof value === 'string' && value.length > 0);
280
+ if (!label) {
281
+ const assignment = /^([A-Za-z0-9_-]*(?:TOKEN|SECRET|PASSWORD|PASSWD|PWD|API[_-]?KEY|ACCESS[_-]?KEY|PRIVATE[_-]?KEY)[A-Za-z0-9_-]*)\s*[:=]/i.exec(_match);
282
+ if (assignment?.[1])
283
+ return `${assignment[1]}=[redacted]`;
284
+ }
285
+ return label ? `${label}=[redacted]` : '[redacted]';
286
+ }
128
287
  function isNodeErrorCode(error, code) {
129
288
  return (typeof error === 'object' &&
130
289
  error !== null &&
@@ -1 +1 @@
1
- {"version":3,"file":"proofLedger.js","sourceRoot":"","sources":["../../src/core/proofLedger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proofLedger.js","sourceRoot":"","sources":["../../src/core/proofLedger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { ProveProofReplay, ProveProofSufficiency, ProveReceipt, ProveReviewerDecision, ProveRiskDeltaDirection } from '../types/prove.js';
2
+ export declare function buildProofReplay(input: {
3
+ scope: ProveReceipt['scope'];
4
+ proofStatus: ProveReceipt['proofStatus'];
5
+ proofSufficiency: ProveProofSufficiency;
6
+ riskDeltaDirection: ProveRiskDeltaDirection;
7
+ reviewerDecision: ProveReviewerDecision;
8
+ replayCommand: string;
9
+ }): ProveProofReplay;
@@ -0,0 +1,164 @@
1
+ import crypto from 'node:crypto';
2
+ import { proofRelevantChangedFiles } from './proofSufficiency.js';
3
+ export function buildProofReplay(input) {
4
+ const currentChangedFiles = proofRelevantChangedFiles(input.scope.changedFiles);
5
+ const changedAfterProof = changedAfterProofForCommands(currentChangedFiles, input.proofStatus.commandEvidence);
6
+ const status = proofReplayStatus({
7
+ scopeStatus: input.scope.status,
8
+ proofStatus: input.proofStatus.status,
9
+ proofSufficiencyStatus: input.proofSufficiency.status,
10
+ });
11
+ const events = proofReplayEvents({
12
+ status,
13
+ scope: input.scope,
14
+ proofStatus: input.proofStatus,
15
+ proofSufficiency: input.proofSufficiency,
16
+ currentChangedFiles,
17
+ changedAfterProof,
18
+ });
19
+ return {
20
+ status,
21
+ summary: proofReplaySummary(status, changedAfterProof),
22
+ events,
23
+ changedAfterProof,
24
+ replayCommand: input.replayCommand,
25
+ receiptFingerprint: receiptFingerprint({
26
+ status,
27
+ scopeStatus: input.scope.status,
28
+ changedFiles: input.scope.changedFiles,
29
+ proofStatus: input.proofStatus.status,
30
+ proofSufficiencyStatus: input.proofSufficiency.status,
31
+ proofSufficiencyRequirements: input.proofSufficiency.requirements.map((requirement) => ({
32
+ id: requirement.id,
33
+ status: requirement.status,
34
+ matchedCommands: requirement.matchedCommands,
35
+ })),
36
+ commandEvidence: input.proofStatus.commandEvidence.map((entry) => ({
37
+ command: entry.command,
38
+ status: entry.status,
39
+ fresh: entry.fresh,
40
+ source: entry.source,
41
+ exitCode: entry.exitCode,
42
+ completedAt: entry.completedAt,
43
+ recordedChangedFileFingerprint: entry.recordedChangedFileFingerprint,
44
+ })),
45
+ changedAfterProof,
46
+ riskDeltaDirection: input.riskDeltaDirection,
47
+ reviewerDecision: input.reviewerDecision,
48
+ }),
49
+ };
50
+ }
51
+ function proofReplayStatus(input) {
52
+ if (input.proofStatus === 'failed' || input.proofSufficiencyStatus === 'failed')
53
+ return 'failed';
54
+ if (input.proofStatus === 'stale' || input.proofSufficiencyStatus === 'stale')
55
+ return 'stale';
56
+ if (input.scopeStatus === 'drifted')
57
+ return 'drifted';
58
+ if (input.scopeStatus === 'missing-contract' ||
59
+ input.proofStatus === 'missing' ||
60
+ input.proofStatus === 'partial' ||
61
+ input.proofSufficiencyStatus === 'missing' ||
62
+ input.proofSufficiencyStatus === 'weak') {
63
+ return 'needs-proof';
64
+ }
65
+ return 'verified';
66
+ }
67
+ function proofReplayEvents(input) {
68
+ return [
69
+ contractEvent(input.scope),
70
+ {
71
+ kind: 'change-set',
72
+ status: input.scope.status === 'within-contract' ? 'passed' : input.scope.status,
73
+ summary: `${input.scope.changedFiles.length} changed file(s) replayed against the Proof Contract.`,
74
+ changedFiles: input.scope.changedFiles,
75
+ },
76
+ ...input.proofStatus.commandEvidence.map((entry) => proofCommandEvent(entry, input.currentChangedFiles)),
77
+ {
78
+ kind: 'proof-sufficiency',
79
+ status: input.proofSufficiency.status,
80
+ summary: input.proofSufficiency.summary,
81
+ },
82
+ {
83
+ kind: 'receipt',
84
+ status: input.status,
85
+ summary: proofReplaySummary(input.status, input.changedAfterProof),
86
+ },
87
+ ];
88
+ }
89
+ function contractEvent(scope) {
90
+ if (scope.status === 'missing-contract') {
91
+ return {
92
+ kind: 'contract',
93
+ status: 'missing',
94
+ summary: 'No saved Proof Contract was available for replay.',
95
+ };
96
+ }
97
+ if (scope.status === 'drifted') {
98
+ return {
99
+ kind: 'contract',
100
+ status: 'drifted',
101
+ summary: 'Changed files drifted outside the Proof Contract.',
102
+ changedFiles: scope.outsideAllowed,
103
+ };
104
+ }
105
+ return {
106
+ kind: 'contract',
107
+ status: 'passed',
108
+ summary: 'Changed files stayed inside the Proof Contract.',
109
+ };
110
+ }
111
+ function proofCommandEvent(entry, currentChangedFiles) {
112
+ const changedAfterProof = changedAfterProofForCommand(currentChangedFiles, entry);
113
+ return {
114
+ kind: 'proof-command',
115
+ status: entry.status,
116
+ summary: proofCommandSummary(entry, changedAfterProof),
117
+ command: entry.command,
118
+ completedAt: entry.completedAt,
119
+ ...(entry.source ? { source: entry.source } : {}),
120
+ ...(entry.recordedChangedFiles ? { changedFiles: entry.recordedChangedFiles } : {}),
121
+ ...(changedAfterProof.length > 0 ? { changedAfterProof } : {}),
122
+ };
123
+ }
124
+ function proofCommandSummary(entry, changedAfterProof) {
125
+ if (entry.status === 'missing')
126
+ return 'No ledger record exists for this required command.';
127
+ if (entry.status === 'failed')
128
+ return 'The latest ledger record for this command failed.';
129
+ if (entry.status === 'stale') {
130
+ const files = changedAfterProof.length > 0 ? ` ${changedAfterProof.length} file(s) appeared after proof.` : '';
131
+ return `The latest ledger record no longer matches the current changed-file set.${files}`;
132
+ }
133
+ return 'The latest ledger record passed and matches the current changed-file set.';
134
+ }
135
+ function changedAfterProofForCommands(currentChangedFiles, evidence) {
136
+ return unique(evidence.flatMap((entry) => changedAfterProofForCommand(currentChangedFiles, entry)));
137
+ }
138
+ function changedAfterProofForCommand(currentChangedFiles, evidence) {
139
+ if (!evidence.recordedChangedFiles || evidence.recordedChangedFiles.length === 0)
140
+ return [];
141
+ const recorded = new Set(evidence.recordedChangedFiles);
142
+ return currentChangedFiles.filter((file) => !recorded.has(file)).sort();
143
+ }
144
+ function proofReplaySummary(status, changedAfterProof) {
145
+ if (status === 'verified')
146
+ return 'Proof replay is verified: scope and proof evidence match.';
147
+ if (status === 'failed')
148
+ return 'Proof replay found failed proof evidence.';
149
+ if (status === 'drifted')
150
+ return 'Proof replay found scope drift outside the contract.';
151
+ if (status === 'stale') {
152
+ return changedAfterProof.length > 0
153
+ ? `Proof replay is stale: ${changedAfterProof.length} file(s) appeared after proof.`
154
+ : 'Proof replay is stale: recorded proof no longer matches the current changed-file set.';
155
+ }
156
+ return 'Proof replay needs more evidence before reviewer approval.';
157
+ }
158
+ function receiptFingerprint(value) {
159
+ return crypto.createHash('sha256').update(JSON.stringify(value)).digest('hex').slice(0, 16);
160
+ }
161
+ function unique(values) {
162
+ return [...new Set(values)];
163
+ }
164
+ //# sourceMappingURL=proofReplay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proofReplay.js","sourceRoot":"","sources":["../../src/core/proofReplay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { ProveContract, ProveProofRequirement, ProveProofSufficiency, ProveReceipt } from '../types/prove.js';
2
+ export declare function buildProofRequirements(input: {
3
+ allowedFiles: string[];
4
+ likelyTests: string[];
5
+ riskyContracts: string[];
6
+ proofCommands: string[];
7
+ }): ProveProofRequirement[];
8
+ export declare function proofSufficiencyFor(input: {
9
+ contract?: ProveContract;
10
+ scope: ProveReceipt['scope'];
11
+ proofStatus: ProveReceipt['proofStatus'];
12
+ }): ProveProofSufficiency;
13
+ export declare function proofRelevantChangedFiles(files: string[]): string[];
14
+ export declare function isDocumentationPath(file: string): boolean;
15
+ export declare function isGeneratedPath(file: string): boolean;
16
+ export declare function isSecuritySensitivePath(file: string): boolean;
17
+ export declare function isConfigPath(file: string): boolean;
18
+ export declare function isTestPath(file: string): boolean;
19
+ export declare function isProductionPath(file: string): boolean;