projscan 4.12.1 → 4.14.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 (59) hide show
  1. package/README.md +76 -12
  2. package/dist/cli/commands/prove.d.ts +3 -0
  3. package/dist/cli/commands/prove.js +379 -0
  4. package/dist/cli/commands/prove.js.map +1 -0
  5. package/dist/cli/commands/startMissionBundle.js +38 -0
  6. package/dist/cli/commands/startMissionBundle.js.map +1 -1
  7. package/dist/cli/registerCommands.js +2 -0
  8. package/dist/cli/registerCommands.js.map +1 -1
  9. package/dist/core/evidenceComment.js +31 -0
  10. package/dist/core/evidenceComment.js.map +1 -1
  11. package/dist/core/feedback.js +18 -0
  12. package/dist/core/feedback.js.map +1 -1
  13. package/dist/core/intentRouterCatalog.js +34 -0
  14. package/dist/core/intentRouterCatalog.js.map +1 -1
  15. package/dist/core/intentRouterKeywordToolGuards.js +10 -0
  16. package/dist/core/intentRouterKeywordToolGuards.js.map +1 -1
  17. package/dist/core/intentRouterWorkflowKeywordWeights.js +29 -0
  18. package/dist/core/intentRouterWorkflowKeywordWeights.js.map +1 -1
  19. package/dist/core/proofLedger.d.ts +9 -0
  20. package/dist/core/proofLedger.js +144 -0
  21. package/dist/core/proofLedger.js.map +1 -0
  22. package/dist/core/prove.d.ts +20 -0
  23. package/dist/core/prove.js +1121 -0
  24. package/dist/core/prove.js.map +1 -0
  25. package/dist/core/releaseEvidence.js +48 -0
  26. package/dist/core/releaseEvidence.js.map +1 -1
  27. package/dist/core/startFixedRouteCriteria.js +4 -0
  28. package/dist/core/startFixedRouteCriteria.js.map +1 -1
  29. package/dist/core/startRouteActions.js +5 -0
  30. package/dist/core/startRouteActions.js.map +1 -1
  31. package/dist/mcp/toolCatalog.js +2 -0
  32. package/dist/mcp/toolCatalog.js.map +1 -1
  33. package/dist/mcp/tools/prove.d.ts +2 -0
  34. package/dist/mcp/tools/prove.js +93 -0
  35. package/dist/mcp/tools/prove.js.map +1 -0
  36. package/dist/projscan-sbom.cdx.json +6 -6
  37. package/dist/publicCore.d.ts +1 -0
  38. package/dist/publicCore.js +1 -0
  39. package/dist/publicCore.js.map +1 -1
  40. package/dist/tool-manifest.json +68 -3
  41. package/dist/types/dogfood.d.ts +4 -0
  42. package/dist/types/evidencePack.d.ts +13 -0
  43. package/dist/types/proofLedger.d.ts +30 -0
  44. package/dist/types/proofLedger.js +2 -0
  45. package/dist/types/proofLedger.js.map +1 -0
  46. package/dist/types/prove.d.ts +123 -0
  47. package/dist/types/prove.js +2 -0
  48. package/dist/types/prove.js.map +1 -0
  49. package/dist/types.d.ts +2 -0
  50. package/dist/utils/formatSupport.d.ts +1 -0
  51. package/dist/utils/formatSupport.js +1 -0
  52. package/dist/utils/formatSupport.js.map +1 -1
  53. package/docs/GUIDE.md +54 -1
  54. package/docs/demos/projscan-4-1-demo.html +24 -24
  55. package/docs/projscan-mission-control.gif +0 -0
  56. package/docs/projscan-mission-control.png +0 -0
  57. package/docs/projscan-mission-proof.gif +0 -0
  58. package/docs/projscan-proof-router.png +0 -0
  59. package/package.json +1 -1
package/README.md CHANGED
@@ -24,9 +24,9 @@ Use projscan when an agent asks one of these questions:
24
24
  - Which files should I read before changing this feature?
25
25
  - Which proof commands should I run before handoff?
26
26
  - Which risks need fixes, reviewer attention, or release sign-off?
27
- - What is actually risky, and what should I fix first?
27
+ - Which risk should I fix first?
28
28
 
29
- projscan runs core scans on your machine. It respects `.gitignore`, keeps `.env` values out of scans unless you opt in, and exposes the same evidence through a CLI and a 47-tool MCP server. The language layer uses 11 AST adapters covering 12 named languages.
29
+ projscan runs core scans on your machine. It respects `.gitignore`, keeps `.env` values out of scans unless you opt in, and exposes the same evidence through a CLI and a 48-tool MCP server. The language layer uses 11 AST adapters covering 12 named languages.
30
30
 
31
31
  ```text
32
32
  Your agent / engineer
@@ -36,11 +36,14 @@ Your agent / engineer
36
36
  +----------------------------------------------------------------+
37
37
  | projscan (runs locally, source stays on this machine) |
38
38
  | ------------------------------------------------------------ |
39
- | Mission Control -> assess Proof Cards -> simulate risk |
40
- | | | |
41
- | | +- bounded extraction
42
- | | +- regression test first
43
- | | +- leave unchanged
39
+ | Mission Control -> assess Cards -> simulate risk -> prove |
40
+ | | | | |
41
+ | | | +- allowed files
42
+ | | | +- forbidden files
43
+ | | | +- proof receipt
44
+ | | +- bounded extraction |
45
+ | | +- regression test first |
46
+ | | +- leave unchanged |
44
47
  | +- evidence strength |
45
48
  | +- trust memory |
46
49
  | +- AgentLoopKit handoff |
@@ -76,20 +79,41 @@ projscan start --intent "does projscan read .env values?"
76
79
 
77
80
  ## Daily workflows
78
81
 
79
- Use these three workflows before scanning the full command catalog.
82
+ Use these four workflows before scanning the full command catalog.
80
83
 
81
84
  ### Before editing a feature
82
85
 
83
86
  ```bash
84
87
  projscan start --intent "what files do I need to change for auth?"
85
88
  projscan start --intent "what should we build next?" # Routes to a before-edit implementation workplan
89
+ projscan start --intent "is my agent allowed to change billing retry logic?"
86
90
  projscan understand --view change --intent "add auth token refresh" --format json
91
+ projscan prove --intent "is my agent allowed to change billing retry logic?"
87
92
  projscan preflight --mode before_edit --format json
88
93
  ```
89
94
 
90
- You get a cited change map, read-first files, likely touched files, blocked inputs, and a before-edit proof gate.
95
+ You get a cited change map, read-first files, likely touched files, blocked inputs, an executable Proof Contract, and a before-edit proof gate. Agent-permission intents route to `projscan prove`, so `start` can hand the next agent a contract path instead of a broad checklist.
91
96
 
92
- Success criteria: the agent can name the files to read first, the likely files to touch, and the proof command to run before editing.
97
+ Success criteria: the agent can name the files to read first, the likely files to touch, the forbidden files to avoid, and the proof commands to run before editing.
98
+
99
+ ### Verified change workflow
100
+
101
+ ```bash
102
+ projscan start --intent "is my agent allowed to change billing retry logic?"
103
+ projscan prove --intent "is my agent allowed to change billing retry logic?" --save-contract .projscan/proof-contract.json
104
+ projscan prove --run -- npm test -- tests/billing/retry.test.ts
105
+ projscan prove --changed --contract .projscan/proof-contract.json --format markdown
106
+ ```
107
+
108
+ The path is `start -> prove -> run -> changed`. `start` chooses the contract workflow. `prove --intent` writes the contract only when `--save-contract` is present. `prove --run -- <command...>` executes a local proof command, records the exit code, captures a redacted log, and fingerprints the current changed files. `prove --record-command` remains available for imported CI or external evidence when projscan did not run the command. `prove --changed` checks the current working tree against the contract and local ledger.
109
+
110
+ You get a Proof Contract before edits and a Proof Receipt after edits. The contract names allowed files, forbidden files, risky contracts, likely tests, missing regression-test evidence, proof commands, safe change shape, rollback, confidence, and reviewer guidance. The receipt checks the real working tree against that contract and classifies changed files as allowed production, expected tests, documentation, generated proof artifacts, config/security drift, forbidden touches, or unexpected production. It also reports proof replay status, risk delta, commit readiness, and a reviewer checklist.
111
+
112
+ Proof Replay records command, exit code, duration, changed-file fingerprint, redacted summary, log path, and source in `.projscan/proof-ledger.jsonl`. Executed proof logs stay under `.projscan/proof-logs/`. `prove --changed` marks proof as passed, missing, failed, partial, or stale. If the agent edits new files after proof ran, the receipt says the proof is stale before a reviewer reads the diff.
113
+
114
+ Every `prove` report includes `verifiedWorkflow`, a compact JSON summary for agents and MCP clients. It names the phase, next action, next command, scope status, proof status, risk delta direction, reviewer decision, and stale/missing/failed proof flags.
115
+
116
+ Success criteria: the reviewer sees whether the agent stayed inside the contract, whether the right proof ran, and whether that proof is still fresh.
93
117
 
94
118
  ### Before handoff or commit
95
119
 
@@ -173,6 +197,43 @@ npm run docs:screenshots
173
197
  npm run docs:demos
174
198
  ```
175
199
 
200
+ ## 4.14.0 Notes
201
+
202
+ 4.14.0 ships the Verified Change Workflow and Executed Proof Runner:
203
+
204
+ - `projscan prove --intent "<change>"` creates a local Proof Contract before
205
+ editing. It names allowed files, forbidden files, risky contracts, likely
206
+ tests, missing regression-test evidence, proof commands, rollback, confidence,
207
+ Trust Memory signals, evidence gaps, and reviewer guidance. Noisy feedback or
208
+ missing-signal feedback lowers the confidence reason instead of hiding it.
209
+ - `projscan start --intent "is my agent allowed to change billing retry logic?"`
210
+ routes directly to `projscan prove`, so agent-permission prompts start with a
211
+ bounded contract instead of a broad checklist.
212
+ - `projscan prove --run -- <command...>` executes an explicit local proof
213
+ command with shell execution disabled, writes a redacted log under
214
+ `.projscan/proof-logs/`, appends a `prove-run` ledger row, and lets
215
+ `prove --changed` replay executed proof instead of self-reported evidence.
216
+ - `projscan prove --changed` validates the current working tree against a saved
217
+ contract and emits a Proof Receipt for PRs, agents, and CI. Its changed-file
218
+ classes separate allowed production edits, expected tests, documentation,
219
+ generated proof artifacts, config/security drift, forbidden touches, and
220
+ unexpected production changes before giving a copyable reviewer decision.
221
+ - `projscan prove --record-command "<command>" --exit-code <code>` appends a
222
+ local Proof Ledger row with command, duration, changed-file fingerprint,
223
+ redacted output summary, and optional log path when importing proof from CI or
224
+ another trusted runner.
225
+ - Every `prove` JSON report includes `verifiedWorkflow`, so agents can read the
226
+ next action, next command, scope status, proof status, reviewer decision, and
227
+ stale/missing/failed proof flags without parsing Markdown.
228
+ - Saved Mission Control bundles append Proof Ledger rows while `mission.sh`
229
+ runs the existing proof queue. The script still writes proof logs and status
230
+ JSONL for humans.
231
+ - `projscan evidence-pack --pr-comment` includes the latest Proof Receipt
232
+ summary when a contract and ledger are available, so PR comments show proof
233
+ status, reviewer decision, scope, stale proof, failed proof, and the replay
234
+ command.
235
+ - MCP now includes `projscan_prove`, bringing the MCP surface to 48 tools.
236
+
176
237
  ## 4.12.1 Notes
177
238
 
178
239
  4.12.1 is the simulator precision patch for the Proof Cards V2 release:
@@ -255,6 +316,8 @@ npx -y projscan mcp --watch
255
316
  | What should I fix first? | `projscan bug-hunt --format json` |
256
317
  | What is risky and worth fixing this week? | `projscan assess --goal "make this repo safer to ship this week"` |
257
318
  | Is this refactor worth doing? | `projscan simulate --plan "split bugHunt.ts into ranking, evidence, and output modules"` |
319
+ | Is my agent allowed to make this change? | `projscan start --intent "is my agent allowed to change billing retry logic?"` |
320
+ | Did the change stay inside scope? | `projscan prove --changed --contract .projscan/proof-contract.json --format markdown` |
258
321
  | Which files have high risk and low coverage? | `projscan coverage --format json` |
259
322
  | What should my agent do next? | `projscan workplan --format json` |
260
323
  | Which proof belongs in this PR? | `projscan evidence-pack --pr-comment` |
@@ -269,6 +332,7 @@ npx -y projscan mcp --watch
269
332
  | `projscan preflight` | proceed, caution, or block gate for edit, commit, or merge |
270
333
  | `projscan assess` | proof-first assessment with Proof Cards, risk delta, and fix-first guidance |
271
334
  | `projscan simulate` | risk delta simulator for a proposed change plan before editing |
335
+ | `projscan prove` | executable Proof Contracts, Verified Workflow JSON, and Proof Receipts |
272
336
  | `projscan evidence-pack` | PR-ready proof with risks, owners, and next commands |
273
337
  | `projscan bug-hunt` | ranked fix queue from health, hotspots, session, and preflight evidence |
274
338
  | `projscan workplan` | ordered agent tasks with proof and handoff text |
@@ -458,7 +522,7 @@ Supply-chain scanners may flag package strings or APIs used by `git`, `npm audit
458
522
 
459
523
  ## Install Notes
460
524
 
461
- `projscan@4.12.1` has seven direct runtime dependencies:
525
+ `projscan@4.14.0` has seven direct runtime dependencies:
462
526
 
463
527
  - `@babel/parser`
464
528
  - `@babel/types`
@@ -468,7 +532,7 @@ Supply-chain scanners may flag package strings or APIs used by `git`, `npm audit
468
532
  - `ora`
469
533
  - `web-tree-sitter`
470
534
 
471
- If npm prints `allow-scripts` warnings during a global install, check which package names it lists. projscan core does not need `node-gyp` grammar builds at runtime in 4.12.1. Open an issue with the warning text if npm reports install scripts from `projscan@latest`, or run `projscan feedback intake --text "<warning text>" --format json` to turn it into a focused setup-trust task.
535
+ If npm prints `allow-scripts` warnings during a global install, check which package names it lists. projscan core does not need `node-gyp` grammar builds at runtime in 4.14.0. Open an issue with the warning text if npm reports install scripts from `projscan@latest`, or run `projscan feedback intake --text "<warning text>" --format json` to turn it into a focused setup-trust task.
472
536
 
473
537
  The grammar packages are build-time sources, not global-install dependencies. Published grammar assets include `tree-sitter-python.wasm` and `tree-sitter-c_sharp.wasm`.
474
538
 
@@ -0,0 +1,3 @@
1
+ import type { ProveReport } from '../../types/prove.js';
2
+ export declare function registerProve(): void;
3
+ export declare function renderProveMarkdown(report: ProveReport): string;
@@ -0,0 +1,379 @@
1
+ import chalk from 'chalk';
2
+ import { assertFormatSupported, getRootPath, maybeCompactBanner, program, setupLogLevel, } from '../_shared.js';
3
+ import { computeProve } from '../../core/prove.js';
4
+ export function registerProve() {
5
+ program
6
+ .command('prove')
7
+ .description('Create or validate an executable Proof Contract for a change')
8
+ .option('--intent <text>', 'plain-language change intent to constrain before editing')
9
+ .option('--changed', 'validate the current working tree against a Proof Contract')
10
+ .option('--contract <path>', 'Proof Contract JSON path for --changed')
11
+ .option('--save-contract <path>', 'write the generated Proof Contract JSON in --intent mode')
12
+ .option('--max-files <count>', 'maximum likely touched files to include', parsePositiveInt)
13
+ .option('--feedback <path>', 'local projscan feedback artifact to apply as trust memory')
14
+ .option('--base-ref <ref>', 'base ref for changed-file detection')
15
+ .option('--record-command <command>', 'record a proof command outcome without executing it')
16
+ .option('--exit-code <code>', 'exit code for --record-command', parseExitCode)
17
+ .option('--duration-ms <ms>', 'duration in milliseconds for --record-command', parseDurationMs)
18
+ .option('--summary <text>', 'safe proof output summary for --record-command')
19
+ .option('--log <path>', 'redacted proof log path for --record-command')
20
+ .option('--run', 'execute a local proof command supplied after -- and record the outcome')
21
+ .option('--run-timeout-ms <ms>', 'timeout in milliseconds for --run commands', parseDurationMs)
22
+ .option('--ledger <path>', 'proof ledger JSONL path')
23
+ .argument('[runCommand...]', 'command vector for --run after --')
24
+ .action(async (runCommand, cmdOpts) => {
25
+ setupLogLevel();
26
+ maybeCompactBanner();
27
+ const format = assertFormatSupported('prove');
28
+ try {
29
+ const runArgs = Array.isArray(runCommand) ? runCommand : [];
30
+ const selectedModes = [cmdOpts.intent, cmdOpts.changed, cmdOpts.recordCommand, cmdOpts.run].filter(Boolean);
31
+ if (selectedModes.length > 1) {
32
+ throw new Error('prove accepts either --intent, --changed, --record-command, or --run');
33
+ }
34
+ if (selectedModes.length === 0) {
35
+ throw new Error('prove requires --intent "<change>", --changed, --record-command, or --run -- <command>');
36
+ }
37
+ if (!cmdOpts.run && runArgs.length > 0) {
38
+ throw new Error('prove command arguments require --run before the -- delimiter');
39
+ }
40
+ if (cmdOpts.run && runArgs.length === 0) {
41
+ throw new Error('prove --run requires a command after --, for example: projscan prove --run -- npm test');
42
+ }
43
+ const report = await computeProve(getRootPath(), {
44
+ intent: cmdOpts.intent,
45
+ changed: Boolean(cmdOpts.changed),
46
+ contractPath: cmdOpts.contract,
47
+ saveContractPath: cmdOpts.saveContract,
48
+ maxFiles: cmdOpts.maxFiles,
49
+ feedbackPath: cmdOpts.feedback,
50
+ baseRef: cmdOpts.baseRef,
51
+ ledgerPath: cmdOpts.ledger,
52
+ recordCommand: cmdOpts.recordCommand,
53
+ exitCode: cmdOpts.exitCode,
54
+ durationMs: cmdOpts.durationMs,
55
+ summary: cmdOpts.summary,
56
+ logPath: cmdOpts.log,
57
+ runCommand: cmdOpts.run ? runArgs : undefined,
58
+ runTimeoutMs: cmdOpts.runTimeoutMs,
59
+ });
60
+ if (format === 'json') {
61
+ console.log(JSON.stringify(report, null, 2));
62
+ return;
63
+ }
64
+ if (format === 'markdown') {
65
+ console.log(renderProveMarkdown(report));
66
+ return;
67
+ }
68
+ printProveConsole(report);
69
+ }
70
+ catch (err) {
71
+ console.error(chalk.red(err instanceof Error ? err.message : String(err)));
72
+ process.exit(1);
73
+ }
74
+ });
75
+ }
76
+ function printProveConsole(report) {
77
+ const color = report.verdict === 'blocked'
78
+ ? chalk.red
79
+ : report.verdict === 'needs-review'
80
+ ? chalk.yellow
81
+ : chalk.green;
82
+ console.log(color(`Projscan Prove: ${report.verdict}`));
83
+ console.log(report.summary);
84
+ console.log('');
85
+ printVerifiedWorkflowConsole(report.verifiedWorkflow);
86
+ console.log('');
87
+ if (report.contract && report.mode === 'intent') {
88
+ printContractConsole(report.contract);
89
+ }
90
+ if (report.ledgerRecord) {
91
+ console.log(chalk.bold(report.ledgerRecord.source === 'prove-run' ? 'Executed Proof' : 'Recorded Proof'));
92
+ console.log(`- ${report.ledgerRecord.status}: ${report.ledgerRecord.command}`);
93
+ console.log(`- source: ${report.ledgerRecord.source}`);
94
+ console.log(`- ${report.ledgerRecord.changedFiles.length} changed file(s) fingerprinted`);
95
+ }
96
+ if (report.receipt) {
97
+ printReceiptConsole(report.receipt);
98
+ }
99
+ }
100
+ function printVerifiedWorkflowConsole(workflow) {
101
+ console.log(chalk.bold('Verified Workflow'));
102
+ console.log(`- next action: ${workflow.nextAction}`);
103
+ console.log(`- next command: ${workflow.nextCommand}`);
104
+ console.log(`- stale proof: ${workflow.staleProof ? 'yes' : 'no'}`);
105
+ console.log(`- missing proof: ${workflow.missingProof ? 'yes' : 'no'}`);
106
+ console.log(`- failed proof: ${workflow.failedProof ? 'yes' : 'no'}`);
107
+ }
108
+ function printContractConsole(contract) {
109
+ console.log(chalk.bold('Allowed Files'));
110
+ printList(contract.allowedFiles, 'No concrete allowed files inferred');
111
+ console.log('');
112
+ console.log(chalk.bold('Forbidden Files'));
113
+ printList(contract.forbiddenFiles.slice(0, 8), 'No forbidden files inferred');
114
+ console.log('');
115
+ console.log(chalk.bold('Proof Commands'));
116
+ printList(contract.proofCommands.slice(0, 8), 'No proof commands inferred');
117
+ }
118
+ function printReceiptConsole(receipt) {
119
+ console.log(chalk.bold('Scope Decision'));
120
+ console.log(`- ${receipt.scope.status}`);
121
+ console.log('');
122
+ console.log(chalk.bold('Changed Files'));
123
+ printList(receipt.scope.changedFiles, 'No changed files detected');
124
+ console.log('');
125
+ console.log(chalk.bold('Allowed production'));
126
+ printList(receipt.scope.allowedProduction, 'No allowed production files touched');
127
+ console.log('');
128
+ console.log(chalk.bold('Expected tests'));
129
+ printList(receipt.scope.expectedTests, 'No expected tests touched');
130
+ if (receipt.scope.forbiddenTouched.length > 0) {
131
+ console.log('');
132
+ console.log(chalk.bold('Forbidden Touched'));
133
+ printList(receipt.scope.forbiddenTouched, 'No forbidden files touched');
134
+ }
135
+ console.log('');
136
+ console.log(chalk.bold('Proof Commands'));
137
+ printList(receipt.proofStatus.commandsRequired.slice(0, 8), 'No proof commands required');
138
+ console.log('');
139
+ console.log(chalk.bold('Proof Replay'));
140
+ console.log(`- status: ${receipt.proofStatus.status}`);
141
+ console.log(`- reviewer decision: ${receipt.reviewerDecision}`);
142
+ }
143
+ export function renderProveMarkdown(report) {
144
+ if (report.receipt)
145
+ return renderReceiptMarkdown(report, report.receipt);
146
+ if (report.ledgerRecord)
147
+ return renderLedgerRecordMarkdown(report);
148
+ return renderContractMarkdown(report);
149
+ }
150
+ function renderLedgerRecordMarkdown(report) {
151
+ const record = report.ledgerRecord;
152
+ const lines = [
153
+ record?.source === 'prove-run' ? '# Projscan Executed Proof' : '# Projscan Recorded Proof',
154
+ '',
155
+ `- **Verdict:** ${report.verdict}`,
156
+ `- **Summary:** ${report.summary}`,
157
+ ];
158
+ if (!record)
159
+ return lines.join('\n');
160
+ lines.push(`- **Source:** ${record.source}`);
161
+ lines.push(`- **Status:** ${record.status}`);
162
+ lines.push(`- **Command:** \`${record.command}\``);
163
+ lines.push(`- **Exit code:** ${record.exitCode}`);
164
+ lines.push(`- **Duration:** ${record.durationMs}ms`);
165
+ lines.push(`- **Completed:** ${record.completedAt}`);
166
+ lines.push(`- **Changed-file fingerprint:** ${record.changedFileFingerprint}`);
167
+ if (record.logPath)
168
+ lines.push(`- **Log:** \`${record.logPath}\``);
169
+ lines.push('');
170
+ pushVerifiedWorkflow(lines, report.verifiedWorkflow);
171
+ lines.push('');
172
+ lines.push('## Output Summary');
173
+ lines.push(record.outputSummary);
174
+ lines.push('');
175
+ lines.push('## Changed Files');
176
+ pushList(lines, record.changedFiles, 'No changed files were fingerprinted.');
177
+ lines.push('');
178
+ lines.push('## Replay');
179
+ lines.push('Run `projscan prove --changed --contract .projscan/proof-contract.json --format markdown` after the edit to replay this proof against the current diff.');
180
+ return lines.join('\n');
181
+ }
182
+ function renderContractMarkdown(report) {
183
+ const contract = report.contract;
184
+ const lines = ['# Projscan Proof Contract', ''];
185
+ lines.push(`- **Verdict:** ${report.verdict}`);
186
+ lines.push(`- **Summary:** ${report.summary}`);
187
+ if (!contract)
188
+ return lines.join('\n');
189
+ lines.push(`- **Intent:** ${contract.intent}`);
190
+ lines.push(`- **Confidence:** ${contract.confidence}`);
191
+ lines.push(`- **Evidence strength:** ${contract.evidenceStrength.level} (${contract.evidenceStrength.score})`);
192
+ lines.push('');
193
+ pushVerifiedWorkflow(lines, report.verifiedWorkflow);
194
+ lines.push('');
195
+ lines.push('## Allowed Files');
196
+ pushList(lines, contract.allowedFiles, 'No concrete allowed files inferred.');
197
+ lines.push('');
198
+ lines.push('## Forbidden Files');
199
+ pushList(lines, contract.forbiddenFiles, 'No forbidden files inferred.');
200
+ lines.push('');
201
+ lines.push('## Risky Contracts');
202
+ pushList(lines, contract.riskyContracts, 'No public contract inferred.');
203
+ lines.push('');
204
+ lines.push('## Likely Tests');
205
+ pushList(lines, contract.likelyTests, 'Add or identify a regression test first.');
206
+ lines.push('');
207
+ lines.push('## Proof Commands');
208
+ pushCodeList(lines, contract.proofCommands);
209
+ lines.push('');
210
+ lines.push('## Reviewer Guidance');
211
+ lines.push(contract.reviewerGuidance);
212
+ return lines.join('\n');
213
+ }
214
+ function renderReceiptMarkdown(report, receipt) {
215
+ const lines = ['# Projscan Proof Receipt', ''];
216
+ lines.push(`- **Verdict:** ${report.verdict}`);
217
+ lines.push(`- **Summary:** ${receipt.summary}`);
218
+ lines.push(`- **Commit readiness:** ${receipt.commitReadiness}`);
219
+ lines.push(`- **Scope:** ${receipt.scope.status}`);
220
+ lines.push(`- **Proof status:** ${receipt.proofStatus.status}`);
221
+ lines.push(`- **Reviewer decision:** ${receipt.reviewerDecision}`);
222
+ lines.push('');
223
+ pushVerifiedWorkflow(lines, report.verifiedWorkflow);
224
+ lines.push('');
225
+ lines.push('## Scope Decision');
226
+ lines.push(`- **Status:** ${receipt.scope.status}`);
227
+ lines.push(`- **Allowed production:** ${receipt.scope.allowedProduction.length}`);
228
+ lines.push(`- **Expected tests:** ${receipt.scope.expectedTests.length}`);
229
+ lines.push(`- **Unexpected production:** ${receipt.scope.unexpectedProduction.length}`);
230
+ lines.push(`- **Forbidden touched:** ${receipt.scope.forbiddenTouched.length}`);
231
+ lines.push('');
232
+ lines.push('## Changed File Classes');
233
+ lines.push('');
234
+ lines.push('### Allowed production');
235
+ pushList(lines, receipt.scope.allowedProduction, 'No allowed production files touched.');
236
+ lines.push('');
237
+ lines.push('### Expected tests');
238
+ pushList(lines, receipt.scope.expectedTests, 'No expected tests touched.');
239
+ lines.push('');
240
+ lines.push('### Unexpected production');
241
+ pushList(lines, receipt.scope.unexpectedProduction, 'No unexpected production files touched.');
242
+ lines.push('');
243
+ lines.push('### Config and security');
244
+ pushList(lines, unique([...receipt.scope.configTouched, ...receipt.scope.securitySensitiveTouched]), 'No config or security-sensitive files touched.');
245
+ lines.push('');
246
+ lines.push('### Documentation and generated artifacts');
247
+ pushList(lines, unique([...receipt.scope.documentationTouched, ...receipt.scope.generatedTouched]), 'No documentation or generated artifacts touched.');
248
+ lines.push('');
249
+ lines.push('## Changed Files');
250
+ pushList(lines, receipt.scope.changedFiles, 'No changed files detected.');
251
+ lines.push('');
252
+ lines.push('## Forbidden Touched');
253
+ pushList(lines, receipt.scope.forbiddenTouched, 'No forbidden files touched.');
254
+ lines.push('');
255
+ lines.push('## Outside Allowed Scope');
256
+ pushList(lines, receipt.scope.outsideAllowed, 'No changed files outside allowed scope.');
257
+ lines.push('');
258
+ lines.push('## Proof Commands');
259
+ pushCodeList(lines, receipt.proofStatus.commandsRequired);
260
+ lines.push('');
261
+ lines.push('## Proof Replay');
262
+ lines.push(`- **Proof status:** ${receipt.proofStatus.status}`);
263
+ lines.push(`- **Reviewer decision:** ${receipt.reviewerDecision}`);
264
+ lines.push(`- **Risk delta:** ${receipt.riskDeltaDirection} (${receipt.riskDelta.delta})`);
265
+ lines.push(`- **Commands required:** ${receipt.proofStatus.commandsRequired.length}`);
266
+ lines.push(`- **Commands recorded:** ${receipt.proofStatus.commandsRun.length}`);
267
+ lines.push('');
268
+ lines.push('### Command Evidence');
269
+ pushCommandEvidence(lines, receipt.proofStatus.commandEvidence);
270
+ lines.push('');
271
+ lines.push('### Missing Commands');
272
+ pushCodeList(lines, receipt.proofStatus.missingCommands);
273
+ lines.push('');
274
+ lines.push('### Failed Commands');
275
+ pushCodeList(lines, receipt.proofStatus.failedCommands);
276
+ lines.push('');
277
+ lines.push('### Stale Commands');
278
+ pushCodeList(lines, receipt.proofStatus.staleCommands);
279
+ lines.push('');
280
+ lines.push('## Evidence Gaps');
281
+ pushList(lines, receipt.evidenceGaps, 'No evidence gaps reported.');
282
+ lines.push('');
283
+ lines.push('## Reviewer Guidance');
284
+ lines.push(receipt.reviewerGuidance);
285
+ lines.push('');
286
+ lines.push('## Reviewer Checklist');
287
+ lines.push('- [ ] Confirm unexpected production/config/security files are intentional or removed.');
288
+ lines.push('- [ ] Confirm expected tests or a documented regression-test gap cover the change.');
289
+ lines.push('- [ ] Run every required proof command before approval.');
290
+ lines.push('- [ ] Confirm new risks and evidence gaps are acceptable for this commit.');
291
+ lines.push('');
292
+ lines.push('## Copyable Decision');
293
+ lines.push(`projscan prove: ${receipt.commitReadiness} (${receipt.scope.status}); proof ${receipt.proofStatus.status}; reviewer decision ${receipt.reviewerDecision}.`);
294
+ return lines.join('\n');
295
+ }
296
+ function pushVerifiedWorkflow(lines, workflow) {
297
+ lines.push('## Verified Workflow');
298
+ lines.push(`- **phase:** ${workflow.phase}`);
299
+ lines.push(`- **status:** ${workflow.status}`);
300
+ lines.push(`- **next action:** ${workflow.nextAction}`);
301
+ lines.push(`- **next command:** \`${workflow.nextCommand}\``);
302
+ if (workflow.scopeStatus)
303
+ lines.push(`- **scope:** ${workflow.scopeStatus}`);
304
+ if (workflow.proofStatus)
305
+ lines.push(`- **proof:** ${workflow.proofStatus}`);
306
+ if (workflow.reviewerDecision)
307
+ lines.push(`- **reviewer decision:** ${workflow.reviewerDecision}`);
308
+ if (workflow.riskDeltaDirection)
309
+ lines.push(`- **risk delta:** ${workflow.riskDeltaDirection}`);
310
+ lines.push(`- **stale proof:** ${workflow.staleProof ? 'yes' : 'no'}`);
311
+ lines.push(`- **missing proof:** ${workflow.missingProof ? 'yes' : 'no'}`);
312
+ lines.push(`- **failed proof:** ${workflow.failedProof ? 'yes' : 'no'}`);
313
+ }
314
+ function printList(values, empty) {
315
+ if (values.length === 0) {
316
+ console.log(`- ${empty}`);
317
+ return;
318
+ }
319
+ for (const value of values)
320
+ console.log(`- ${value}`);
321
+ }
322
+ function pushList(lines, values, empty) {
323
+ if (values.length === 0) {
324
+ lines.push(`- ${empty}`);
325
+ return;
326
+ }
327
+ for (const value of values)
328
+ lines.push(`- ${value}`);
329
+ }
330
+ function pushCodeList(lines, values) {
331
+ if (values.length === 0) {
332
+ lines.push('- No proof commands required.');
333
+ return;
334
+ }
335
+ for (const value of values)
336
+ lines.push(`- \`${value}\``);
337
+ }
338
+ function pushCommandEvidence(lines, values) {
339
+ if (values.length === 0) {
340
+ lines.push('- No proof command evidence recorded.');
341
+ return;
342
+ }
343
+ for (const value of values)
344
+ lines.push(formatCommandEvidence(value));
345
+ }
346
+ function formatCommandEvidence(value) {
347
+ const state = value.fresh ? 'fresh' : value.staleReason ? 'stale' : value.status;
348
+ const exit = typeof value.exitCode === 'number' ? ` exit ${value.exitCode}` : ' no exit code';
349
+ const duration = typeof value.durationMs === 'number' ? `, ${value.durationMs}ms` : '';
350
+ const log = value.logPath ? `, log ${value.logPath}` : '';
351
+ const summary = value.outputSummary ? ` - ${value.outputSummary}` : '';
352
+ const stale = value.staleReason ? ` (${value.staleReason})` : '';
353
+ return `- **${value.status} ${state}:** \`${value.command}\` (${exit}${duration}${log})${stale}${summary}`;
354
+ }
355
+ function unique(values) {
356
+ return [...new Set(values)];
357
+ }
358
+ function parsePositiveInt(value) {
359
+ const parsed = Number.parseInt(value, 10);
360
+ if (!Number.isFinite(parsed) || parsed <= 0) {
361
+ throw new Error('value must be a positive integer');
362
+ }
363
+ return parsed;
364
+ }
365
+ function parseExitCode(value) {
366
+ const parsed = Number(value);
367
+ if (!Number.isInteger(parsed) || parsed < 0) {
368
+ throw new Error('exit code must be a non-negative integer');
369
+ }
370
+ return parsed;
371
+ }
372
+ function parseDurationMs(value) {
373
+ const parsed = Number(value);
374
+ if (!Number.isFinite(parsed) || parsed < 0) {
375
+ throw new Error('duration-ms must be a non-negative number');
376
+ }
377
+ return parsed;
378
+ }
379
+ //# sourceMappingURL=prove.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prove.js","sourceRoot":"","sources":["../../../src/cli/commands/prove.ts"],"names":[],"mappings":"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"}
@@ -115,13 +115,16 @@ function missionUnsafeCommandBlock() {
115
115
  function missionProofLogSetup(report) {
116
116
  return [
117
117
  'MISSION_DIR=$(CDPATH= cd "$(dirname "$0")" && pwd)',
118
+ 'PROJSCAN_ROOT=$(git -C "$MISSION_DIR" rev-parse --show-toplevel 2>/dev/null || pwd)',
118
119
  'PROOF_LOG_DIR="${MISSION_DIR}/proof-logs"',
119
120
  'PROOF_STATUS_FILE="${PROOF_LOG_DIR}/status.jsonl"',
120
121
  'PROOF_REPORT_FILE="${PROOF_LOG_DIR}/run-report.md"',
121
122
  'PROOF_SUMMARY_FILE="${PROOF_LOG_DIR}/summary.json"',
123
+ 'PROOF_LEDGER_FILE="${PROJSCAN_ROOT}/.projscan/proof-ledger.jsonl"',
122
124
  'mkdir -p "$PROOF_LOG_DIR"',
123
125
  ': > "$PROOF_STATUS_FILE"',
124
126
  ': > "$PROOF_REPORT_FILE"',
127
+ ...scriptAppendProofLedgerFunction(),
125
128
  ...scriptInitRunReport(report),
126
129
  scriptWriteSummaryJson('running'),
127
130
  scriptPrintExpanded('Proof logs: ${PROOF_LOG_DIR}'),
@@ -523,6 +526,7 @@ function scriptCommandBlock(label, command, logTarget) {
523
526
  'status=$?',
524
527
  'set -e',
525
528
  scriptAppendStatusJsonl(logTarget.id, label, logTarget.logName, command),
529
+ scriptAppendProofLedgerJsonl(logTarget.id, label, logTarget.logName, command),
526
530
  scriptAppendReportRow(logTarget.id, label, logTarget.logName),
527
531
  'if [ "$status" -ne 0 ]; then',
528
532
  ` ${scriptPrintError(`Command failed. See proof-logs/${logTarget.logName}.`)}`,
@@ -549,6 +553,40 @@ function scriptAppendStatusJsonl(id, label, logName, command) {
549
553
  }).replace(/}$/, ',"exitCode":');
550
554
  return `printf '%s%s%s\\n' ${shellQuote(prefix)} "$status" '}' >> "$PROOF_STATUS_FILE"`;
551
555
  }
556
+ function scriptAppendProofLedgerFunction() {
557
+ return [
558
+ 'append_proof_ledger_row() {',
559
+ ' mkdir -p "$(dirname "$PROOF_LEDGER_FILE")" 2>/dev/null || true',
560
+ ' node - "$PROJSCAN_ROOT" "$MISSION_DIR" "$1" "$2" "$3" "$4" "$5" <<\'NODE\' >> "$PROOF_LEDGER_FILE" 2>/dev/null || true',
561
+ 'const crypto = require("node:crypto");',
562
+ 'const path = require("node:path");',
563
+ 'const { execFileSync } = require("node:child_process");',
564
+ 'const [root, missionDir, id, label, logName, command, exitCodeRaw] = process.argv.slice(2);',
565
+ 'function normalize(value) { return String(value || "").split(path.sep).join("/").replace(/^\\.\\//, ""); }',
566
+ 'function changedFiles() {',
567
+ ' try {',
568
+ ' const output = execFileSync("git", ["-C", root, "status", "--porcelain", "--untracked-files=all"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });',
569
+ ' return [...new Set(output.split("\\n").map((line) => line.slice(3).trim()).filter(Boolean).map((file) => file.includes(" -> ") ? file.split(" -> ").pop() : file).map(normalize).filter((file) => !file.startsWith(".projscan/")))].sort();',
570
+ ' } catch {',
571
+ ' return [];',
572
+ ' }',
573
+ '}',
574
+ 'const files = changedFiles();',
575
+ 'const fingerprint = crypto.createHash("sha256").update(files.join("\\n")).digest("hex");',
576
+ 'const completedAt = new Date().toISOString();',
577
+ 'const exitCode = Number.parseInt(exitCodeRaw, 10);',
578
+ 'const logPath = normalize(path.relative(root, path.join(missionDir, "proof-logs", logName)));',
579
+ 'const digest = crypto.createHash("sha256").update(`${command}\\n${completedAt}\\n${exitCode}`).digest("hex").slice(0, 12);',
580
+ 'const record = { schemaVersion: 1, id: `proof-ledger-${digest}`, command, normalizedCommand: command.trim().replace(/\\s+/g, " "), cwd: normalize(path.relative(root, missionDir) || "."), exitCode, status: exitCode === 0 ? "passed" : "failed", startedAt: completedAt, completedAt, durationMs: 0, changedFileFingerprint: fingerprint, changedFiles: files, outputSummary: `Mission proof ${label} exited ${exitCode}.`, source: "mission", logPath };',
581
+ 'process.stdout.write(`${JSON.stringify(record)}\\n`);',
582
+ 'NODE',
583
+ '}',
584
+ '',
585
+ ];
586
+ }
587
+ function scriptAppendProofLedgerJsonl(id, label, logName, command) {
588
+ return `append_proof_ledger_row ${shellQuote(id)} ${shellQuote(label)} ${shellQuote(logName)} ${shellQuote(command)} "$status"`;
589
+ }
552
590
  function scriptInitRunReport(report) {
553
591
  const mission = report.missionControl;
554
592
  return [