@accelerator-mzq/forge 1.4.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.
- package/LICENSE +21 -0
- package/LICENSE-THIRD-PARTY.md +50 -0
- package/README.md +159 -0
- package/dist/cli/commands/ack.d.ts +7 -0
- package/dist/cli/commands/ack.d.ts.map +1 -0
- package/dist/cli/commands/ack.js +223 -0
- package/dist/cli/commands/ack.js.map +1 -0
- package/dist/cli/commands/archive.d.ts +44 -0
- package/dist/cli/commands/archive.d.ts.map +1 -0
- package/dist/cli/commands/archive.js +689 -0
- package/dist/cli/commands/archive.js.map +1 -0
- package/dist/cli/commands/backlog.d.ts +3 -0
- package/dist/cli/commands/backlog.d.ts.map +1 -0
- package/dist/cli/commands/backlog.js +55 -0
- package/dist/cli/commands/backlog.js.map +1 -0
- package/dist/cli/commands/config.d.ts +3 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +107 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/evidence.d.ts +7 -0
- package/dist/cli/commands/evidence.d.ts.map +1 -0
- package/dist/cli/commands/evidence.js +662 -0
- package/dist/cli/commands/evidence.js.map +1 -0
- package/dist/cli/commands/finding.d.ts +3 -0
- package/dist/cli/commands/finding.d.ts.map +1 -0
- package/dist/cli/commands/finding.js +93 -0
- package/dist/cli/commands/finding.js.map +1 -0
- package/dist/cli/commands/init.d.ts +3 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +126 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/legacy-bridge.d.ts +11 -0
- package/dist/cli/commands/legacy-bridge.d.ts.map +1 -0
- package/dist/cli/commands/legacy-bridge.js +586 -0
- package/dist/cli/commands/legacy-bridge.js.map +1 -0
- package/dist/cli/commands/migrate.d.ts +3 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -0
- package/dist/cli/commands/migrate.js +34 -0
- package/dist/cli/commands/migrate.js.map +1 -0
- package/dist/cli/commands/monitor.d.ts +3 -0
- package/dist/cli/commands/monitor.d.ts.map +1 -0
- package/dist/cli/commands/monitor.js +113 -0
- package/dist/cli/commands/monitor.js.map +1 -0
- package/dist/cli/commands/preflight.d.ts +7 -0
- package/dist/cli/commands/preflight.d.ts.map +1 -0
- package/dist/cli/commands/preflight.js +63 -0
- package/dist/cli/commands/preflight.js.map +1 -0
- package/dist/cli/commands/scope.d.ts +3 -0
- package/dist/cli/commands/scope.d.ts.map +1 -0
- package/dist/cli/commands/scope.js +32 -0
- package/dist/cli/commands/scope.js.map +1 -0
- package/dist/cli/commands/stage-extensions.d.ts +45 -0
- package/dist/cli/commands/stage-extensions.d.ts.map +1 -0
- package/dist/cli/commands/stage-extensions.js +590 -0
- package/dist/cli/commands/stage-extensions.js.map +1 -0
- package/dist/cli/commands/update.d.ts +3 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +98 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/commands/upgrade.d.ts +3 -0
- package/dist/cli/commands/upgrade.d.ts.map +1 -0
- package/dist/cli/commands/upgrade.js +277 -0
- package/dist/cli/commands/upgrade.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +3 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +66 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +69 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core/ack-log.d.ts +107 -0
- package/dist/core/ack-log.d.ts.map +1 -0
- package/dist/core/ack-log.js +197 -0
- package/dist/core/ack-log.js.map +1 -0
- package/dist/core/archive/ack-log-consistency.d.ts +15 -0
- package/dist/core/archive/ack-log-consistency.d.ts.map +1 -0
- package/dist/core/archive/ack-log-consistency.js +164 -0
- package/dist/core/archive/ack-log-consistency.js.map +1 -0
- package/dist/core/archive/fence.d.ts +66 -0
- package/dist/core/archive/fence.d.ts.map +1 -0
- package/dist/core/archive/fence.js +218 -0
- package/dist/core/archive/fence.js.map +1 -0
- package/dist/core/archive/index.d.ts +4 -0
- package/dist/core/archive/index.d.ts.map +1 -0
- package/dist/core/archive/index.js +6 -0
- package/dist/core/archive/index.js.map +1 -0
- package/dist/core/archive/legacy-exemption.d.ts +14 -0
- package/dist/core/archive/legacy-exemption.d.ts.map +1 -0
- package/dist/core/archive/legacy-exemption.js +82 -0
- package/dist/core/archive/legacy-exemption.js.map +1 -0
- package/dist/core/archive/lock.d.ts +46 -0
- package/dist/core/archive/lock.d.ts.map +1 -0
- package/dist/core/archive/lock.js +98 -0
- package/dist/core/archive/lock.js.map +1 -0
- package/dist/core/archive/pause-decisions-fence.d.ts +13 -0
- package/dist/core/archive/pause-decisions-fence.d.ts.map +1 -0
- package/dist/core/archive/pause-decisions-fence.js +384 -0
- package/dist/core/archive/pause-decisions-fence.js.map +1 -0
- package/dist/core/archive/process-evidence-fence.d.ts +110 -0
- package/dist/core/archive/process-evidence-fence.d.ts.map +1 -0
- package/dist/core/archive/process-evidence-fence.js +449 -0
- package/dist/core/archive/process-evidence-fence.js.map +1 -0
- package/dist/core/archive/process-evidence-rerun.d.ts +9 -0
- package/dist/core/archive/process-evidence-rerun.d.ts.map +1 -0
- package/dist/core/archive/process-evidence-rerun.js +238 -0
- package/dist/core/archive/process-evidence-rerun.js.map +1 -0
- package/dist/core/archive/recover-prompt.d.ts +10 -0
- package/dist/core/archive/recover-prompt.d.ts.map +1 -0
- package/dist/core/archive/recover-prompt.js +29 -0
- package/dist/core/archive/recover-prompt.js.map +1 -0
- package/dist/core/archive/recover.d.ts +83 -0
- package/dist/core/archive/recover.d.ts.map +1 -0
- package/dist/core/archive/recover.js +219 -0
- package/dist/core/archive/recover.js.map +1 -0
- package/dist/core/archive/resume-summary.d.ts +22 -0
- package/dist/core/archive/resume-summary.d.ts.map +1 -0
- package/dist/core/archive/resume-summary.js +82 -0
- package/dist/core/archive/resume-summary.js.map +1 -0
- package/dist/core/archive/summary-builder.d.ts +28 -0
- package/dist/core/archive/summary-builder.d.ts.map +1 -0
- package/dist/core/archive/summary-builder.js +287 -0
- package/dist/core/archive/summary-builder.js.map +1 -0
- package/dist/core/archive/summary-render.d.ts +8 -0
- package/dist/core/archive/summary-render.d.ts.map +1 -0
- package/dist/core/archive/summary-render.js +64 -0
- package/dist/core/archive/summary-render.js.map +1 -0
- package/dist/core/archive/three-level-fence.d.ts +10 -0
- package/dist/core/archive/three-level-fence.d.ts.map +1 -0
- package/dist/core/archive/three-level-fence.js +93 -0
- package/dist/core/archive/three-level-fence.js.map +1 -0
- package/dist/core/archive/transaction.d.ts +41 -0
- package/dist/core/archive/transaction.d.ts.map +1 -0
- package/dist/core/archive/transaction.js +184 -0
- package/dist/core/archive/transaction.js.map +1 -0
- package/dist/core/archive/verify-findings-fence.d.ts +11 -0
- package/dist/core/archive/verify-findings-fence.d.ts.map +1 -0
- package/dist/core/archive/verify-findings-fence.js +80 -0
- package/dist/core/archive/verify-findings-fence.js.map +1 -0
- package/dist/core/archive/version-retrograde-fence.d.ts +10 -0
- package/dist/core/archive/version-retrograde-fence.d.ts.map +1 -0
- package/dist/core/archive/version-retrograde-fence.js +103 -0
- package/dist/core/archive/version-retrograde-fence.js.map +1 -0
- package/dist/core/artifact-graph/builder.d.ts +16 -0
- package/dist/core/artifact-graph/builder.d.ts.map +1 -0
- package/dist/core/artifact-graph/builder.js +32 -0
- package/dist/core/artifact-graph/builder.js.map +1 -0
- package/dist/core/artifact-graph/index.d.ts +3 -0
- package/dist/core/artifact-graph/index.d.ts.map +1 -0
- package/dist/core/artifact-graph/index.js +4 -0
- package/dist/core/artifact-graph/index.js.map +1 -0
- package/dist/core/artifact-graph/types.d.ts +14 -0
- package/dist/core/artifact-graph/types.d.ts.map +1 -0
- package/dist/core/artifact-graph/types.js +2 -0
- package/dist/core/artifact-graph/types.js.map +1 -0
- package/dist/core/backlog/assets/backlog-readme.md +11 -0
- package/dist/core/backlog/index.d.ts +20 -0
- package/dist/core/backlog/index.d.ts.map +1 -0
- package/dist/core/backlog/index.js +60 -0
- package/dist/core/backlog/index.js.map +1 -0
- package/dist/core/backlog/render.d.ts +51 -0
- package/dist/core/backlog/render.d.ts.map +1 -0
- package/dist/core/backlog/render.js +196 -0
- package/dist/core/backlog/render.js.map +1 -0
- package/dist/core/bootstrap/index.d.ts +2 -0
- package/dist/core/bootstrap/index.d.ts.map +1 -0
- package/dist/core/bootstrap/index.js +5 -0
- package/dist/core/bootstrap/index.js.map +1 -0
- package/dist/core/canonical-json.d.ts +11 -0
- package/dist/core/canonical-json.d.ts.map +1 -0
- package/dist/core/canonical-json.js +43 -0
- package/dist/core/canonical-json.js.map +1 -0
- package/dist/core/git/utils.d.ts +27 -0
- package/dist/core/git/utils.d.ts.map +1 -0
- package/dist/core/git/utils.js +53 -0
- package/dist/core/git/utils.js.map +1 -0
- package/dist/core/harness-adapters/claude.d.ts +13 -0
- package/dist/core/harness-adapters/claude.d.ts.map +1 -0
- package/dist/core/harness-adapters/claude.js +53 -0
- package/dist/core/harness-adapters/claude.js.map +1 -0
- package/dist/core/harness-adapters/codex.d.ts +14 -0
- package/dist/core/harness-adapters/codex.d.ts.map +1 -0
- package/dist/core/harness-adapters/codex.js +60 -0
- package/dist/core/harness-adapters/codex.js.map +1 -0
- package/dist/core/harness-adapters/detector.d.ts +15 -0
- package/dist/core/harness-adapters/detector.d.ts.map +1 -0
- package/dist/core/harness-adapters/detector.js +45 -0
- package/dist/core/harness-adapters/detector.js.map +1 -0
- package/dist/core/harness-adapters/hash-compare.d.ts +21 -0
- package/dist/core/harness-adapters/hash-compare.d.ts.map +1 -0
- package/dist/core/harness-adapters/hash-compare.js +49 -0
- package/dist/core/harness-adapters/hash-compare.js.map +1 -0
- package/dist/core/harness-adapters/index.d.ts +8 -0
- package/dist/core/harness-adapters/index.d.ts.map +1 -0
- package/dist/core/harness-adapters/index.js +8 -0
- package/dist/core/harness-adapters/index.js.map +1 -0
- package/dist/core/harness-adapters/interface.d.ts +52 -0
- package/dist/core/harness-adapters/interface.d.ts.map +1 -0
- package/dist/core/harness-adapters/interface.js +3 -0
- package/dist/core/harness-adapters/interface.js.map +1 -0
- package/dist/core/harness-adapters/legacy-detector.d.ts +14 -0
- package/dist/core/harness-adapters/legacy-detector.d.ts.map +1 -0
- package/dist/core/harness-adapters/legacy-detector.js +83 -0
- package/dist/core/harness-adapters/legacy-detector.js.map +1 -0
- package/dist/core/harness-adapters/transaction.d.ts +12 -0
- package/dist/core/harness-adapters/transaction.d.ts.map +1 -0
- package/dist/core/harness-adapters/transaction.js +113 -0
- package/dist/core/harness-adapters/transaction.js.map +1 -0
- package/dist/core/harness-adapters/types.d.ts +45 -0
- package/dist/core/harness-adapters/types.d.ts.map +1 -0
- package/dist/core/harness-adapters/types.js +3 -0
- package/dist/core/harness-adapters/types.js.map +1 -0
- package/dist/core/hash/content.d.ts +10 -0
- package/dist/core/hash/content.d.ts.map +1 -0
- package/dist/core/hash/content.js +131 -0
- package/dist/core/hash/content.js.map +1 -0
- package/dist/core/hash/diff.d.ts +26 -0
- package/dist/core/hash/diff.d.ts.map +1 -0
- package/dist/core/hash/diff.js +40 -0
- package/dist/core/hash/diff.js.map +1 -0
- package/dist/core/hash/index.d.ts +6 -0
- package/dist/core/hash/index.d.ts.map +1 -0
- package/dist/core/hash/index.js +7 -0
- package/dist/core/hash/index.js.map +1 -0
- package/dist/core/hash/log.d.ts +7 -0
- package/dist/core/hash/log.d.ts.map +1 -0
- package/dist/core/hash/log.js +14 -0
- package/dist/core/hash/log.js.map +1 -0
- package/dist/core/hash/tasks.d.ts +9 -0
- package/dist/core/hash/tasks.d.ts.map +1 -0
- package/dist/core/hash/tasks.js +20 -0
- package/dist/core/hash/tasks.js.map +1 -0
- package/dist/core/legacy-bridge/ack.d.ts +30 -0
- package/dist/core/legacy-bridge/ack.d.ts.map +1 -0
- package/dist/core/legacy-bridge/ack.js +133 -0
- package/dist/core/legacy-bridge/ack.js.map +1 -0
- package/dist/core/legacy-bridge/anchors.d.ts +15 -0
- package/dist/core/legacy-bridge/anchors.d.ts.map +1 -0
- package/dist/core/legacy-bridge/anchors.js +119 -0
- package/dist/core/legacy-bridge/anchors.js.map +1 -0
- package/dist/core/legacy-bridge/budget.d.ts +39 -0
- package/dist/core/legacy-bridge/budget.d.ts.map +1 -0
- package/dist/core/legacy-bridge/budget.js +83 -0
- package/dist/core/legacy-bridge/budget.js.map +1 -0
- package/dist/core/legacy-bridge/conflict.d.ts +44 -0
- package/dist/core/legacy-bridge/conflict.d.ts.map +1 -0
- package/dist/core/legacy-bridge/conflict.js +105 -0
- package/dist/core/legacy-bridge/conflict.js.map +1 -0
- package/dist/core/legacy-bridge/diff-report.d.ts +14 -0
- package/dist/core/legacy-bridge/diff-report.d.ts.map +1 -0
- package/dist/core/legacy-bridge/diff-report.js +105 -0
- package/dist/core/legacy-bridge/diff-report.js.map +1 -0
- package/dist/core/legacy-bridge/encoding.d.ts +42 -0
- package/dist/core/legacy-bridge/encoding.d.ts.map +1 -0
- package/dist/core/legacy-bridge/encoding.js +104 -0
- package/dist/core/legacy-bridge/encoding.js.map +1 -0
- package/dist/core/legacy-bridge/excel.d.ts +32 -0
- package/dist/core/legacy-bridge/excel.d.ts.map +1 -0
- package/dist/core/legacy-bridge/excel.js +124 -0
- package/dist/core/legacy-bridge/excel.js.map +1 -0
- package/dist/core/legacy-bridge/hash-anchor.d.ts +23 -0
- package/dist/core/legacy-bridge/hash-anchor.d.ts.map +1 -0
- package/dist/core/legacy-bridge/hash-anchor.js +55 -0
- package/dist/core/legacy-bridge/hash-anchor.js.map +1 -0
- package/dist/core/legacy-bridge/indexer.d.ts +28 -0
- package/dist/core/legacy-bridge/indexer.d.ts.map +1 -0
- package/dist/core/legacy-bridge/indexer.js +145 -0
- package/dist/core/legacy-bridge/indexer.js.map +1 -0
- package/dist/core/legacy-bridge/mapper.d.ts +40 -0
- package/dist/core/legacy-bridge/mapper.d.ts.map +1 -0
- package/dist/core/legacy-bridge/mapper.js +241 -0
- package/dist/core/legacy-bridge/mapper.js.map +1 -0
- package/dist/core/legacy-bridge/quality-judge.d.ts +65 -0
- package/dist/core/legacy-bridge/quality-judge.d.ts.map +1 -0
- package/dist/core/legacy-bridge/quality-judge.js +277 -0
- package/dist/core/legacy-bridge/quality-judge.js.map +1 -0
- package/dist/core/legacy-bridge/redact.d.ts +28 -0
- package/dist/core/legacy-bridge/redact.d.ts.map +1 -0
- package/dist/core/legacy-bridge/redact.js +121 -0
- package/dist/core/legacy-bridge/redact.js.map +1 -0
- package/dist/core/legacy-bridge/regenerator.d.ts +50 -0
- package/dist/core/legacy-bridge/regenerator.d.ts.map +1 -0
- package/dist/core/legacy-bridge/regenerator.js +193 -0
- package/dist/core/legacy-bridge/regenerator.js.map +1 -0
- package/dist/core/legacy-bridge/resolve.d.ts +28 -0
- package/dist/core/legacy-bridge/resolve.d.ts.map +1 -0
- package/dist/core/legacy-bridge/resolve.js +75 -0
- package/dist/core/legacy-bridge/resolve.js.map +1 -0
- package/dist/core/legacy-bridge/sync-check.d.ts +47 -0
- package/dist/core/legacy-bridge/sync-check.d.ts.map +1 -0
- package/dist/core/legacy-bridge/sync-check.js +198 -0
- package/dist/core/legacy-bridge/sync-check.js.map +1 -0
- package/dist/core/legacy-bridge/types.d.ts +114 -0
- package/dist/core/legacy-bridge/types.d.ts.map +1 -0
- package/dist/core/legacy-bridge/types.js +4 -0
- package/dist/core/legacy-bridge/types.js.map +1 -0
- package/dist/core/markers/index.d.ts +3 -0
- package/dist/core/markers/index.d.ts.map +1 -0
- package/dist/core/markers/index.js +3 -0
- package/dist/core/markers/index.js.map +1 -0
- package/dist/core/markers/parse.d.ts +12 -0
- package/dist/core/markers/parse.d.ts.map +1 -0
- package/dist/core/markers/parse.js +31 -0
- package/dist/core/markers/parse.js.map +1 -0
- package/dist/core/markers/types.d.ts +142 -0
- package/dist/core/markers/types.d.ts.map +1 -0
- package/dist/core/markers/types.js +3 -0
- package/dist/core/markers/types.js.map +1 -0
- package/dist/core/migrate/ack.d.ts +13 -0
- package/dist/core/migrate/ack.d.ts.map +1 -0
- package/dist/core/migrate/ack.js +62 -0
- package/dist/core/migrate/ack.js.map +1 -0
- package/dist/core/migrate/archive-detect.d.ts +19 -0
- package/dist/core/migrate/archive-detect.d.ts.map +1 -0
- package/dist/core/migrate/archive-detect.js +89 -0
- package/dist/core/migrate/archive-detect.js.map +1 -0
- package/dist/core/migrate/budget.d.ts +7 -0
- package/dist/core/migrate/budget.d.ts.map +1 -0
- package/dist/core/migrate/budget.js +25 -0
- package/dist/core/migrate/budget.js.map +1 -0
- package/dist/core/migrate/conflict.d.ts +49 -0
- package/dist/core/migrate/conflict.d.ts.map +1 -0
- package/dist/core/migrate/conflict.js +99 -0
- package/dist/core/migrate/conflict.js.map +1 -0
- package/dist/core/migrate/index.d.ts +7 -0
- package/dist/core/migrate/index.d.ts.map +1 -0
- package/dist/core/migrate/index.js +389 -0
- package/dist/core/migrate/index.js.map +1 -0
- package/dist/core/migrate/markdown-aware.d.ts +27 -0
- package/dist/core/migrate/markdown-aware.d.ts.map +1 -0
- package/dist/core/migrate/markdown-aware.js +112 -0
- package/dist/core/migrate/markdown-aware.js.map +1 -0
- package/dist/core/migrate/quality.d.ts +66 -0
- package/dist/core/migrate/quality.d.ts.map +1 -0
- package/dist/core/migrate/quality.js +302 -0
- package/dist/core/migrate/quality.js.map +1 -0
- package/dist/core/migrate/regenerate.d.ts +24 -0
- package/dist/core/migrate/regenerate.d.ts.map +1 -0
- package/dist/core/migrate/regenerate.js +145 -0
- package/dist/core/migrate/regenerate.js.map +1 -0
- package/dist/core/migrate/report.d.ts +36 -0
- package/dist/core/migrate/report.d.ts.map +1 -0
- package/dist/core/migrate/report.js +154 -0
- package/dist/core/migrate/report.js.map +1 -0
- package/dist/core/migrate/sources/index.d.ts +4 -0
- package/dist/core/migrate/sources/index.d.ts.map +1 -0
- package/dist/core/migrate/sources/index.js +17 -0
- package/dist/core/migrate/sources/index.js.map +1 -0
- package/dist/core/migrate/sources/openspec.d.ts +14 -0
- package/dist/core/migrate/sources/openspec.d.ts.map +1 -0
- package/dist/core/migrate/sources/openspec.js +453 -0
- package/dist/core/migrate/sources/openspec.js.map +1 -0
- package/dist/core/migrate/sources/superpowers.d.ts +12 -0
- package/dist/core/migrate/sources/superpowers.d.ts.map +1 -0
- package/dist/core/migrate/sources/superpowers.js +310 -0
- package/dist/core/migrate/sources/superpowers.js.map +1 -0
- package/dist/core/migrate/types.d.ts +183 -0
- package/dist/core/migrate/types.d.ts.map +1 -0
- package/dist/core/migrate/types.js +5 -0
- package/dist/core/migrate/types.js.map +1 -0
- package/dist/core/migrate/utils.d.ts +2 -0
- package/dist/core/migrate/utils.d.ts.map +1 -0
- package/dist/core/migrate/utils.js +28 -0
- package/dist/core/migrate/utils.js.map +1 -0
- package/dist/core/monitor/artifact-observer.d.ts +9 -0
- package/dist/core/monitor/artifact-observer.d.ts.map +1 -0
- package/dist/core/monitor/artifact-observer.js +180 -0
- package/dist/core/monitor/artifact-observer.js.map +1 -0
- package/dist/core/monitor/config.d.ts +16 -0
- package/dist/core/monitor/config.d.ts.map +1 -0
- package/dist/core/monitor/config.js +48 -0
- package/dist/core/monitor/config.js.map +1 -0
- package/dist/core/monitor/divergence-map.d.ts +5 -0
- package/dist/core/monitor/divergence-map.d.ts.map +1 -0
- package/dist/core/monitor/divergence-map.js +92 -0
- package/dist/core/monitor/divergence-map.js.map +1 -0
- package/dist/core/monitor/exit-handler.d.ts +6 -0
- package/dist/core/monitor/exit-handler.d.ts.map +1 -0
- package/dist/core/monitor/exit-handler.js +27 -0
- package/dist/core/monitor/exit-handler.js.map +1 -0
- package/dist/core/monitor/health-verdict.d.ts +9 -0
- package/dist/core/monitor/health-verdict.d.ts.map +1 -0
- package/dist/core/monitor/health-verdict.js +55 -0
- package/dist/core/monitor/health-verdict.js.map +1 -0
- package/dist/core/monitor/report-renderer.d.ts +4 -0
- package/dist/core/monitor/report-renderer.d.ts.map +1 -0
- package/dist/core/monitor/report-renderer.js +82 -0
- package/dist/core/monitor/report-renderer.js.map +1 -0
- package/dist/core/monitor/trace-store.d.ts +39 -0
- package/dist/core/monitor/trace-store.d.ts.map +1 -0
- package/dist/core/monitor/trace-store.js +130 -0
- package/dist/core/monitor/trace-store.js.map +1 -0
- package/dist/core/monitor/types.d.ts +63 -0
- package/dist/core/monitor/types.d.ts.map +1 -0
- package/dist/core/monitor/types.js +26 -0
- package/dist/core/monitor/types.js.map +1 -0
- package/dist/core/parse/design.d.ts +14 -0
- package/dist/core/parse/design.d.ts.map +1 -0
- package/dist/core/parse/design.js +17 -0
- package/dist/core/parse/design.js.map +1 -0
- package/dist/core/parse/fenced-yaml.d.ts +18 -0
- package/dist/core/parse/fenced-yaml.d.ts.map +1 -0
- package/dist/core/parse/fenced-yaml.js +45 -0
- package/dist/core/parse/fenced-yaml.js.map +1 -0
- package/dist/core/parse/index.d.ts +7 -0
- package/dist/core/parse/index.d.ts.map +1 -0
- package/dist/core/parse/index.js +8 -0
- package/dist/core/parse/index.js.map +1 -0
- package/dist/core/parse/markdown.d.ts +30 -0
- package/dist/core/parse/markdown.d.ts.map +1 -0
- package/dist/core/parse/markdown.js +66 -0
- package/dist/core/parse/markdown.js.map +1 -0
- package/dist/core/parse/proposal.d.ts +18 -0
- package/dist/core/parse/proposal.d.ts.map +1 -0
- package/dist/core/parse/proposal.js +22 -0
- package/dist/core/parse/proposal.js.map +1 -0
- package/dist/core/parse/specs.d.ts +25 -0
- package/dist/core/parse/specs.d.ts.map +1 -0
- package/dist/core/parse/specs.js +58 -0
- package/dist/core/parse/specs.js.map +1 -0
- package/dist/core/parse/tasks.d.ts +33 -0
- package/dist/core/parse/tasks.d.ts.map +1 -0
- package/dist/core/parse/tasks.js +82 -0
- package/dist/core/parse/tasks.js.map +1 -0
- package/dist/core/parse/yaml.d.ts +13 -0
- package/dist/core/parse/yaml.d.ts.map +1 -0
- package/dist/core/parse/yaml.js +39 -0
- package/dist/core/parse/yaml.js.map +1 -0
- package/dist/core/process-evidence-freeze-warnings.d.ts +24 -0
- package/dist/core/process-evidence-freeze-warnings.d.ts.map +1 -0
- package/dist/core/process-evidence-freeze-warnings.js +153 -0
- package/dist/core/process-evidence-freeze-warnings.js.map +1 -0
- package/dist/core/schema/index.d.ts +5 -0
- package/dist/core/schema/index.d.ts.map +1 -0
- package/dist/core/schema/index.js +6 -0
- package/dist/core/schema/index.js.map +1 -0
- package/dist/core/schema/model-tiers-config.d.ts +41 -0
- package/dist/core/schema/model-tiers-config.d.ts.map +1 -0
- package/dist/core/schema/model-tiers-config.js +85 -0
- package/dist/core/schema/model-tiers-config.js.map +1 -0
- package/dist/core/schema/process-verification-config.d.ts +18 -0
- package/dist/core/schema/process-verification-config.d.ts.map +1 -0
- package/dist/core/schema/process-verification-config.js +74 -0
- package/dist/core/schema/process-verification-config.js.map +1 -0
- package/dist/core/schema/stage-extensions-config.d.ts +28 -0
- package/dist/core/schema/stage-extensions-config.d.ts.map +1 -0
- package/dist/core/schema/stage-extensions-config.js +228 -0
- package/dist/core/schema/stage-extensions-config.js.map +1 -0
- package/dist/core/schema/types.d.ts +262 -0
- package/dist/core/schema/types.d.ts.map +1 -0
- package/dist/core/schema/types.js +51 -0
- package/dist/core/schema/types.js.map +1 -0
- package/dist/core/schema/writing-plans-config.d.ts +11 -0
- package/dist/core/schema/writing-plans-config.d.ts.map +1 -0
- package/dist/core/schema/writing-plans-config.js +40 -0
- package/dist/core/schema/writing-plans-config.js.map +1 -0
- package/dist/core/schemas/archive-summary.d.ts +131 -0
- package/dist/core/schemas/archive-summary.d.ts.map +1 -0
- package/dist/core/schemas/archive-summary.js +31 -0
- package/dist/core/schemas/archive-summary.js.map +1 -0
- package/dist/core/schemas/process-evidence.d.ts +156 -0
- package/dist/core/schemas/process-evidence.d.ts.map +1 -0
- package/dist/core/schemas/process-evidence.js +12 -0
- package/dist/core/schemas/process-evidence.js.map +1 -0
- package/dist/core/schemas/scope-entries.d.ts +68 -0
- package/dist/core/schemas/scope-entries.d.ts.map +1 -0
- package/dist/core/schemas/scope-entries.js +47 -0
- package/dist/core/schemas/scope-entries.js.map +1 -0
- package/dist/core/schemas/severity.d.ts +58 -0
- package/dist/core/schemas/severity.d.ts.map +1 -0
- package/dist/core/schemas/severity.js +26 -0
- package/dist/core/schemas/severity.js.map +1 -0
- package/dist/core/scope/aggregator.d.ts +49 -0
- package/dist/core/scope/aggregator.d.ts.map +1 -0
- package/dist/core/scope/aggregator.js +141 -0
- package/dist/core/scope/aggregator.js.map +1 -0
- package/dist/core/scope/index.d.ts +2 -0
- package/dist/core/scope/index.d.ts.map +1 -0
- package/dist/core/scope/index.js +2 -0
- package/dist/core/scope/index.js.map +1 -0
- package/dist/core/specs-sync/apply.d.ts +8 -0
- package/dist/core/specs-sync/apply.d.ts.map +1 -0
- package/dist/core/specs-sync/apply.js +26 -0
- package/dist/core/specs-sync/apply.js.map +1 -0
- package/dist/core/specs-sync/deltas.d.ts +15 -0
- package/dist/core/specs-sync/deltas.d.ts.map +1 -0
- package/dist/core/specs-sync/deltas.js +27 -0
- package/dist/core/specs-sync/deltas.js.map +1 -0
- package/dist/core/specs-sync/index.d.ts +3 -0
- package/dist/core/specs-sync/index.d.ts.map +1 -0
- package/dist/core/specs-sync/index.js +4 -0
- package/dist/core/specs-sync/index.js.map +1 -0
- package/dist/core/stage-extensions/convergence-judge.d.ts +35 -0
- package/dist/core/stage-extensions/convergence-judge.d.ts.map +1 -0
- package/dist/core/stage-extensions/convergence-judge.js +47 -0
- package/dist/core/stage-extensions/convergence-judge.js.map +1 -0
- package/dist/core/stage-extensions/index.d.ts +13 -0
- package/dist/core/stage-extensions/index.d.ts.map +1 -0
- package/dist/core/stage-extensions/index.js +11 -0
- package/dist/core/stage-extensions/index.js.map +1 -0
- package/dist/core/stage-extensions/output-watcher.d.ts +93 -0
- package/dist/core/stage-extensions/output-watcher.d.ts.map +1 -0
- package/dist/core/stage-extensions/output-watcher.js +163 -0
- package/dist/core/stage-extensions/output-watcher.js.map +1 -0
- package/dist/core/stage-extensions/severity-mapper.d.ts +21 -0
- package/dist/core/stage-extensions/severity-mapper.d.ts.map +1 -0
- package/dist/core/stage-extensions/severity-mapper.js +26 -0
- package/dist/core/stage-extensions/severity-mapper.js.map +1 -0
- package/dist/core/stage-extensions/state-machine.d.ts +43 -0
- package/dist/core/stage-extensions/state-machine.d.ts.map +1 -0
- package/dist/core/stage-extensions/state-machine.js +19 -0
- package/dist/core/stage-extensions/state-machine.js.map +1 -0
- package/dist/core/stage-extensions/thread-map.d.ts +60 -0
- package/dist/core/stage-extensions/thread-map.d.ts.map +1 -0
- package/dist/core/stage-extensions/thread-map.js +107 -0
- package/dist/core/stage-extensions/thread-map.js.map +1 -0
- package/dist/core/stage-extensions/trend-analyzer.d.ts +29 -0
- package/dist/core/stage-extensions/trend-analyzer.d.ts.map +1 -0
- package/dist/core/stage-extensions/trend-analyzer.js +60 -0
- package/dist/core/stage-extensions/trend-analyzer.js.map +1 -0
- package/dist/core/stage-extensions/types.d.ts +39 -0
- package/dist/core/stage-extensions/types.d.ts.map +1 -0
- package/dist/core/stage-extensions/types.js +5 -0
- package/dist/core/stage-extensions/types.js.map +1 -0
- package/dist/core/staging-lock.d.ts +36 -0
- package/dist/core/staging-lock.d.ts.map +1 -0
- package/dist/core/staging-lock.js +122 -0
- package/dist/core/staging-lock.js.map +1 -0
- package/dist/core/templates/commands/ack-confirm.md +32 -0
- package/dist/core/templates/commands/apply.md +220 -0
- package/dist/core/templates/commands/archive.md +178 -0
- package/dist/core/templates/commands/brainstorm.md +58 -0
- package/dist/core/templates/commands/codex-adversarial.md +95 -0
- package/dist/core/templates/commands/explore.md +29 -0
- package/dist/core/templates/commands/index.d.ts +12 -0
- package/dist/core/templates/commands/index.d.ts.map +1 -0
- package/dist/core/templates/commands/index.js +26 -0
- package/dist/core/templates/commands/index.js.map +1 -0
- package/dist/core/templates/commands/propose.md +90 -0
- package/dist/core/templates/commands/review.md +105 -0
- package/dist/core/templates/commands/upgrade.md +58 -0
- package/dist/core/templates/commands/verify.md +186 -0
- package/dist/core/templates/index.d.ts +3 -0
- package/dist/core/templates/index.d.ts.map +1 -0
- package/dist/core/templates/index.js +5 -0
- package/dist/core/templates/index.js.map +1 -0
- package/dist/core/templates/skills/_shared/scope-category-guidance.md +40 -0
- package/dist/core/templates/skills/brainstorming.md +161 -0
- package/dist/core/templates/skills/dispatching-parallel-agents.md +209 -0
- package/dist/core/templates/skills/exploring.md +476 -0
- package/dist/core/templates/skills/finishing-a-development-branch.md +251 -0
- package/dist/core/templates/skills/index.d.ts +17 -0
- package/dist/core/templates/skills/index.d.ts.map +1 -0
- package/dist/core/templates/skills/index.js +53 -0
- package/dist/core/templates/skills/index.js.map +1 -0
- package/dist/core/templates/skills/process-evidence.md +146 -0
- package/dist/core/templates/skills/receiving-code-review.md +294 -0
- package/dist/core/templates/skills/requesting-code-review.md +108 -0
- package/dist/core/templates/skills/subagent-driven-development.md +405 -0
- package/dist/core/templates/skills/subagent-driven-discipline/references/codex-tools.md +72 -0
- package/dist/core/templates/skills/subagent-driven-discipline/references/opencode-tools.md +104 -0
- package/dist/core/templates/skills/subagent-driven-discipline.md +725 -0
- package/dist/core/templates/skills/systematic-debugging.md +297 -0
- package/dist/core/templates/skills/test-driven-development.md +402 -0
- package/dist/core/templates/skills/using-forge.md +163 -0
- package/dist/core/templates/skills/using-git-worktrees.md +229 -0
- package/dist/core/templates/skills/verification-before-completion.md +175 -0
- package/dist/core/templates/skills/verifying-three-dimensions.md +245 -0
- package/dist/core/templates/skills/writing-plans.md +259 -0
- package/dist/core/templates/skills/writing-skills.md +214 -0
- package/dist/core/test-reporters/index.d.ts +41 -0
- package/dist/core/test-reporters/index.d.ts.map +1 -0
- package/dist/core/test-reporters/index.js +39 -0
- package/dist/core/test-reporters/index.js.map +1 -0
- package/dist/core/test-reporters/junit.d.ts +8 -0
- package/dist/core/test-reporters/junit.d.ts.map +1 -0
- package/dist/core/test-reporters/junit.js +94 -0
- package/dist/core/test-reporters/junit.js.map +1 -0
- package/dist/core/test-reporters/tap.d.ts +18 -0
- package/dist/core/test-reporters/tap.d.ts.map +1 -0
- package/dist/core/test-reporters/tap.js +73 -0
- package/dist/core/test-reporters/tap.js.map +1 -0
- package/dist/core/test-reporters/vitest-json.d.ts +8 -0
- package/dist/core/test-reporters/vitest-json.d.ts.map +1 -0
- package/dist/core/test-reporters/vitest-json.js +56 -0
- package/dist/core/test-reporters/vitest-json.js.map +1 -0
- package/dist/core/upgrade/resign-markers.d.ts +14 -0
- package/dist/core/upgrade/resign-markers.d.ts.map +1 -0
- package/dist/core/upgrade/resign-markers.js +245 -0
- package/dist/core/upgrade/resign-markers.js.map +1 -0
- package/dist/core/validate/archive-summary-schema.d.ts +8 -0
- package/dist/core/validate/archive-summary-schema.d.ts.map +1 -0
- package/dist/core/validate/archive-summary-schema.js +186 -0
- package/dist/core/validate/archive-summary-schema.js.map +1 -0
- package/dist/core/validate/auto-findings.d.ts +36 -0
- package/dist/core/validate/auto-findings.d.ts.map +1 -0
- package/dist/core/validate/auto-findings.js +38 -0
- package/dist/core/validate/auto-findings.js.map +1 -0
- package/dist/core/validate/candidate-validators.d.ts +22 -0
- package/dist/core/validate/candidate-validators.d.ts.map +1 -0
- package/dist/core/validate/candidate-validators.js +46 -0
- package/dist/core/validate/candidate-validators.js.map +1 -0
- package/dist/core/validate/change.d.ts +3 -0
- package/dist/core/validate/change.d.ts.map +1 -0
- package/dist/core/validate/change.js +205 -0
- package/dist/core/validate/change.js.map +1 -0
- package/dist/core/validate/coverage-gap.d.ts +37 -0
- package/dist/core/validate/coverage-gap.d.ts.map +1 -0
- package/dist/core/validate/coverage-gap.js +181 -0
- package/dist/core/validate/coverage-gap.js.map +1 -0
- package/dist/core/validate/finding-hash.d.ts +14 -0
- package/dist/core/validate/finding-hash.d.ts.map +1 -0
- package/dist/core/validate/finding-hash.js +29 -0
- package/dist/core/validate/finding-hash.js.map +1 -0
- package/dist/core/validate/index.d.ts +15 -0
- package/dist/core/validate/index.d.ts.map +1 -0
- package/dist/core/validate/index.js +19 -0
- package/dist/core/validate/index.js.map +1 -0
- package/dist/core/validate/marker-integrity.d.ts +28 -0
- package/dist/core/validate/marker-integrity.d.ts.map +1 -0
- package/dist/core/validate/marker-integrity.js +170 -0
- package/dist/core/validate/marker-integrity.js.map +1 -0
- package/dist/core/validate/marker-schema.d.ts +10 -0
- package/dist/core/validate/marker-schema.d.ts.map +1 -0
- package/dist/core/validate/marker-schema.js +661 -0
- package/dist/core/validate/marker-schema.js.map +1 -0
- package/dist/core/validate/orphan-tmp.d.ts +13 -0
- package/dist/core/validate/orphan-tmp.d.ts.map +1 -0
- package/dist/core/validate/orphan-tmp.js +49 -0
- package/dist/core/validate/orphan-tmp.js.map +1 -0
- package/dist/core/validate/proposal.d.ts +4 -0
- package/dist/core/validate/proposal.d.ts.map +1 -0
- package/dist/core/validate/proposal.js +40 -0
- package/dist/core/validate/proposal.js.map +1 -0
- package/dist/core/validate/scope-entries.d.ts +23 -0
- package/dist/core/validate/scope-entries.d.ts.map +1 -0
- package/dist/core/validate/scope-entries.js +108 -0
- package/dist/core/validate/scope-entries.js.map +1 -0
- package/dist/core/validate/specs.d.ts +4 -0
- package/dist/core/validate/specs.d.ts.map +1 -0
- package/dist/core/validate/specs.js +74 -0
- package/dist/core/validate/specs.js.map +1 -0
- package/dist/core/validate/tasks.d.ts +4 -0
- package/dist/core/validate/tasks.d.ts.map +1 -0
- package/dist/core/validate/tasks.js +48 -0
- package/dist/core/validate/tasks.js.map +1 -0
- package/dist/core/validate/test-failure-stub.d.ts +23 -0
- package/dist/core/validate/test-failure-stub.d.ts.map +1 -0
- package/dist/core/validate/test-failure-stub.js +21 -0
- package/dist/core/validate/test-failure-stub.js.map +1 -0
- package/dist/core/validate/types.d.ts +33 -0
- package/dist/core/validate/types.d.ts.map +1 -0
- package/dist/core/validate/types.js +20 -0
- package/dist/core/validate/types.js.map +1 -0
- package/dist/core/worktree.d.ts +52 -0
- package/dist/core/worktree.d.ts.map +1 -0
- package/dist/core/worktree.js +145 -0
- package/dist/core/worktree.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
// forge evidence 子命令 — plan-9a Task 5 + plan-9g Task 3.3 扩展
|
|
2
|
+
// 提供三个 evidence helper 子命令:
|
|
3
|
+
// forge evidence record-tdd <changeId> --task <ref> --red-commit <sha> --green-commit <sha> [+14 new options]
|
|
4
|
+
// forge evidence record-verify <changeId> --task-refs <list> --scope <type> --report <path> [+6 new options]
|
|
5
|
+
// forge evidence record-review <changeId> --task <ref> --implementer-commit <sha> [+3 new options]
|
|
6
|
+
//
|
|
7
|
+
// plan-9g Task 3.3 扩展:
|
|
8
|
+
// - 三 helper 各加新 commander options(沿 plan §4.3.0 字段映射表)
|
|
9
|
+
// - 三 helper 内部新增 staging.yaml 写入路径(acquireStagingLock wrapper)
|
|
10
|
+
// - 同时仍调 appendAckLog(已扩 prev_entry_hash 链)
|
|
11
|
+
//
|
|
12
|
+
// Observation(plan §4.3.0 表 vs 行 2906 数字差异):
|
|
13
|
+
// - record-tdd 按表实际新增 14 项(超 plan 行 2906 "+12" 字面;含 tdd-exemption/tdd-exemption-acked-by)
|
|
14
|
+
// - record-verify 按表实际新增 6 项(超 plan 行 2907 "+5";含 v6 修订 --result)
|
|
15
|
+
// - record-review 按表实际新增 3 项(--spec-iterations/--quality-iterations rename + --main-check-off-at)
|
|
16
|
+
// 按表对齐 master spec 字段名严格
|
|
17
|
+
import { Command } from 'commander';
|
|
18
|
+
import { execFileSync } from 'node:child_process';
|
|
19
|
+
import { resolve, join } from 'node:path';
|
|
20
|
+
import { readFile, writeFile, mkdir, rename } from 'node:fs/promises';
|
|
21
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
22
|
+
import { createHash } from 'node:crypto';
|
|
23
|
+
import { stringify, parse } from 'yaml';
|
|
24
|
+
import { appendAckLog, readAllAckLogEntries } from '../../core/ack-log.js';
|
|
25
|
+
import { canonicalHash } from '../../core/canonical-json.js';
|
|
26
|
+
import { acquireStagingLock } from '../../core/staging-lock.js';
|
|
27
|
+
import { computeFreezeWarnings } from '../../core/process-evidence-freeze-warnings.js';
|
|
28
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
29
|
+
// staging.yaml 路径
|
|
30
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
31
|
+
/** staging.yaml 相对于 changeRoot 的路径(plan §4 行 5 字面) */
|
|
32
|
+
const STAGING_YAML_REL = '.evidence/process-evidence.staging.yaml';
|
|
33
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
34
|
+
// 内部 helper
|
|
35
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
36
|
+
/**
|
|
37
|
+
* getGitHead — 获取当前 git HEAD 提交 SHA。
|
|
38
|
+
* 与 ack.ts 中的模式一致:execFileSync + try/catch,非 git 仓库返回 null。
|
|
39
|
+
* @param cwd 工作目录(change 根目录)
|
|
40
|
+
*/
|
|
41
|
+
function getGitHead(cwd) {
|
|
42
|
+
try {
|
|
43
|
+
return execFileSync('git', ['rev-parse', 'HEAD'], {
|
|
44
|
+
cwd,
|
|
45
|
+
encoding: 'utf8',
|
|
46
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
47
|
+
}).trim();
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// 非 git 工作树或 git 不可用时静默返回 null
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* computeEnvHash — 计算环境三因子(plan §4.3.0 行 2897-2900)
|
|
56
|
+
* 在 record-tdd 第一次写 staging 时调用
|
|
57
|
+
* @param changeRoot change 根目录
|
|
58
|
+
*/
|
|
59
|
+
function computeEnvHash(changeRoot) {
|
|
60
|
+
// 查找 pnpm-lock.yaml 或 package-lock.json(从 changeRoot 向上到项目根)
|
|
61
|
+
// 实际项目锁文件通常在 repo 根,非 change 目录;从 cwd 找
|
|
62
|
+
const candidates = [
|
|
63
|
+
join(process.cwd(), 'pnpm-lock.yaml'),
|
|
64
|
+
join(process.cwd(), 'package-lock.json'),
|
|
65
|
+
join(changeRoot, 'pnpm-lock.yaml'),
|
|
66
|
+
join(changeRoot, 'package-lock.json'),
|
|
67
|
+
];
|
|
68
|
+
let lockfileHash = 'none';
|
|
69
|
+
for (const c of candidates) {
|
|
70
|
+
if (existsSync(c)) {
|
|
71
|
+
const content = readFileSync(c);
|
|
72
|
+
lockfileHash = createHash('sha256').update(content).digest('hex');
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
lockfile_hash: lockfileHash,
|
|
78
|
+
node_version: process.version.slice(1), // 去掉前缀 'v'
|
|
79
|
+
os_platform: process.platform,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* readStagingYaml — 读取 staging.yaml,不存在时返回 null(新建)
|
|
84
|
+
*/
|
|
85
|
+
async function readStagingYaml(changeRoot) {
|
|
86
|
+
const stagingPath = join(changeRoot, STAGING_YAML_REL);
|
|
87
|
+
if (!existsSync(stagingPath))
|
|
88
|
+
return null;
|
|
89
|
+
const content = await readFile(stagingPath, 'utf8');
|
|
90
|
+
return parse(content);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* writeStagingYaml — 覆写 staging.yaml(重算 staging_hash 写入)
|
|
94
|
+
* staging_hash = canonicalHash(ProcessEvidence struct)(plan §4.3 留白展开)
|
|
95
|
+
*
|
|
96
|
+
* round 2 fix (I2):改原子写 — 先写 .tmp,再 rename 到目标
|
|
97
|
+
* 沿 plan-9e1 transaction.ts atomic 模式
|
|
98
|
+
* POSIX 平台 rename 是 atomic;NTFS 是 near-atomic
|
|
99
|
+
* 中途崩溃(磁盘满 / SIGKILL)→ staging.yaml 不会半写损坏
|
|
100
|
+
*/
|
|
101
|
+
async function writeStagingYaml(changeRoot, data) {
|
|
102
|
+
const evidenceDir = join(changeRoot, '.evidence');
|
|
103
|
+
await mkdir(evidenceDir, { recursive: true });
|
|
104
|
+
const stagingPath = join(changeRoot, STAGING_YAML_REL);
|
|
105
|
+
// staging_hash:对完整 ProcessEvidence struct 做 canonicalHash
|
|
106
|
+
const stagingHash = canonicalHash(data);
|
|
107
|
+
// 写入时附加 staging_hash 顶级字段(额外信封字段,不影响 schema)
|
|
108
|
+
const withHash = { ...data, staging_hash: stagingHash };
|
|
109
|
+
// round 2 (I2):原子写 — tmp + rename
|
|
110
|
+
const tmpPath = stagingPath + '.tmp';
|
|
111
|
+
await writeFile(tmpPath, stringify(withHash), 'utf8');
|
|
112
|
+
await rename(tmpPath, stagingPath);
|
|
113
|
+
}
|
|
114
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
115
|
+
// buildEvidenceCommand — 导出顶层 evidence 命令组
|
|
116
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
117
|
+
/**
|
|
118
|
+
* buildEvidenceCommand — 构建含三个子命令的 evidence 命令组。
|
|
119
|
+
* 模式与 buildAckCommand() 一致:返回 Command 对象,由 index.ts 通过 addCommand() 注册。
|
|
120
|
+
*/
|
|
121
|
+
export function buildEvidenceCommand() {
|
|
122
|
+
const evidence = new Command('evidence').description('Evidence helper 子命令:记录 TDD / verify / review 事件到 ack-log.jsonl + staging.yaml');
|
|
123
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
124
|
+
// 子命令 1: forge evidence record-tdd
|
|
125
|
+
// plan-9g Task 3.3:+14 新 options(按 plan §4.3.0 表;超 plan 行 2906 "+12" 字面)
|
|
126
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
127
|
+
evidence
|
|
128
|
+
.command('record-tdd')
|
|
129
|
+
.description('记录 TDD red→green 事件:写 payload hash 到 ack-log.jsonl + staging.yaml')
|
|
130
|
+
.argument('<changeId>', 'change 目录 ID,如 add-login')
|
|
131
|
+
.requiredOption('--task <task-ref>', 'task 引用,如 tasks.md#task-1')
|
|
132
|
+
// round 2 fix (I3):--red-commit 改 optional,以兼容 schema TddEventChain.red_commit | null
|
|
133
|
+
// 验证:若 !tddExemption && !redCommit → exit 2(在 action 内显式检查)
|
|
134
|
+
.option('--red-commit <sha>', 'failing test(红) 提交 SHA;tdd_exemption 非空时可省')
|
|
135
|
+
.requiredOption('--green-commit <sha>', 'passing test(绿) 提交 SHA')
|
|
136
|
+
.option('--expected-failures <json>', '预期失败列表,JSON 数组格式,如 ["test-a"]')
|
|
137
|
+
// plan-9g Task 3.3 新增 options(red 系列 — 沿 plan §4.3.0 表)
|
|
138
|
+
.option('--red-timestamp <iso>', 'RED commit 时间戳(ISO 8601 UTC)')
|
|
139
|
+
.option('--red-log <path>', 'RED plain log 路径')
|
|
140
|
+
.option('--red-log-hash <sha256>', 'sha256(RED log content)')
|
|
141
|
+
.option('--red-report <path>', 'RED runner 报告路径(JUnit XML / TAP / Vitest JSON)')
|
|
142
|
+
.option('--red-report-hash <sha256>', 'sha256(RED runner report content)')
|
|
143
|
+
.option('--red-exit <int>', 'RED 阶段进程 exit code(必 != 0)')
|
|
144
|
+
// plan-9g Task 3.3 新增 options(green 系列 — 沿 plan §4.3.0 表)
|
|
145
|
+
.option('--green-timestamp <iso>', 'GREEN commit 时间戳(ISO 8601 UTC)')
|
|
146
|
+
.option('--green-log <path>', 'GREEN plain log 路径')
|
|
147
|
+
.option('--green-log-hash <sha256>', 'sha256(GREEN log content)')
|
|
148
|
+
.option('--green-report <path>', 'GREEN runner 报告路径')
|
|
149
|
+
.option('--green-report-hash <sha256>', 'sha256(GREEN runner report content)')
|
|
150
|
+
.option('--green-exit <int>', 'GREEN 阶段进程 exit code(必 == 0)')
|
|
151
|
+
// plan-9g Task 3.3 新增 options(顶级 + 免 RED — 沿 plan §4.3.0 表)
|
|
152
|
+
.option('--mode <full|sample|hash-only>', 'process_verification_mode(顶级字段;默认 full)')
|
|
153
|
+
.option('--tdd-exemption <json>', 'TDD 免 RED JSON 对象(light-mode-trivial)')
|
|
154
|
+
.option('--tdd-exemption-acked-by <user>', 'tdd_exemption ack-log 中对应 acked_by user(v6 Codex 修订)')
|
|
155
|
+
.action(async (changeId, opts) => {
|
|
156
|
+
const changeRoot = resolve(process.cwd(), 'forge', 'changes', changeId);
|
|
157
|
+
// 解析可选 --expected-failures(JSON 字符串)
|
|
158
|
+
let expectedFailures = [];
|
|
159
|
+
if (opts.expectedFailures) {
|
|
160
|
+
try {
|
|
161
|
+
expectedFailures = JSON.parse(opts.expectedFailures);
|
|
162
|
+
}
|
|
163
|
+
catch (e) {
|
|
164
|
+
process.stderr.write(`Invalid --expected-failures JSON: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
165
|
+
process.exit(2);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// 解析可选 --tdd-exemption(JSON 对象)
|
|
169
|
+
let tddExemption = null;
|
|
170
|
+
if (opts.tddExemption) {
|
|
171
|
+
try {
|
|
172
|
+
tddExemption = JSON.parse(opts.tddExemption);
|
|
173
|
+
}
|
|
174
|
+
catch (e) {
|
|
175
|
+
process.stderr.write(`Invalid --tdd-exemption JSON: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
176
|
+
process.exit(2);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// round 2 fix (I3):--red-commit 必填校验
|
|
180
|
+
// 仅当 tdd_exemption 非空时可省;否则必须提供 --red-commit
|
|
181
|
+
if (!tddExemption && !opts.redCommit) {
|
|
182
|
+
process.stderr.write(`forge evidence record-tdd: --red-commit is required unless --tdd-exemption is provided\n`);
|
|
183
|
+
process.exit(2);
|
|
184
|
+
}
|
|
185
|
+
// plan-9g Task 5 round 2 (Critical fix):payload = staging-built object
|
|
186
|
+
// 历史 bug:payload 用 `?? null` fallback;staging 用 `?? ''` / `?? -1` / `?? new Date()` fallback
|
|
187
|
+
// → record-tdd 省略 optional arg 时两路径 hash 不同 → fence-9.2 永误报 → archive 系统性 broken
|
|
188
|
+
// 修复:先构造 tddEntry(staging-side fallback,single source of truth),
|
|
189
|
+
// 再用 tddEntry 字段构造 payload(identity mapping,无需额外 fallback)
|
|
190
|
+
const release = await acquireStagingLock(changeRoot);
|
|
191
|
+
try {
|
|
192
|
+
const existing = await readStagingYaml(changeRoot);
|
|
193
|
+
const mode = opts.mode ?? 'full';
|
|
194
|
+
const staging = existing ?? {
|
|
195
|
+
schema: 'forge-process-evidence/v1',
|
|
196
|
+
process_verification_mode: mode,
|
|
197
|
+
process_verification_mode_acked_by: null,
|
|
198
|
+
process_verification_mode_acked_at: null,
|
|
199
|
+
// 第一次写 staging 时自动检测 env_hash(plan §4.3.0 行 2897-2900)
|
|
200
|
+
env_hash: computeEnvHash(changeRoot),
|
|
201
|
+
tdd_event_chain: [],
|
|
202
|
+
verify_invocations: [],
|
|
203
|
+
subagent_review_chain: [],
|
|
204
|
+
};
|
|
205
|
+
// 若已存在且 mode 参数变化,更新顶级 mode
|
|
206
|
+
if (opts.mode) {
|
|
207
|
+
staging.process_verification_mode = mode;
|
|
208
|
+
}
|
|
209
|
+
// 构建 TddEventChain 条目 — single source of truth
|
|
210
|
+
// (沿 plan §4.3.0 表 "写入 staging.yaml 字段" 列;round 2 (I3):tddExemption 非空时 red_commit = null)
|
|
211
|
+
const tddEntry = {
|
|
212
|
+
task_ref: opts.task,
|
|
213
|
+
red_commit: tddExemption
|
|
214
|
+
? null
|
|
215
|
+
: {
|
|
216
|
+
sha: opts.redCommit,
|
|
217
|
+
timestamp: opts.redTimestamp ?? new Date().toISOString(),
|
|
218
|
+
red_log_path: opts.redLog ?? '',
|
|
219
|
+
red_log_hash: opts.redLogHash ?? '',
|
|
220
|
+
exit_code: opts.redExit !== undefined ? parseInt(opts.redExit, 10) : -1,
|
|
221
|
+
runner_report_path: opts.redReport ?? '',
|
|
222
|
+
runner_report_hash: opts.redReportHash ?? '',
|
|
223
|
+
expected_failures: expectedFailures,
|
|
224
|
+
},
|
|
225
|
+
green_commit: {
|
|
226
|
+
sha: opts.greenCommit,
|
|
227
|
+
timestamp: opts.greenTimestamp ?? new Date().toISOString(),
|
|
228
|
+
green_log_path: opts.greenLog ?? '',
|
|
229
|
+
green_log_hash: opts.greenLogHash ?? '',
|
|
230
|
+
exit_code: opts.greenExit !== undefined ? parseInt(opts.greenExit, 10) : 0,
|
|
231
|
+
runner_report_path: opts.greenReport ?? '',
|
|
232
|
+
runner_report_hash: opts.greenReportHash ?? '',
|
|
233
|
+
},
|
|
234
|
+
tdd_exemption: tddExemption,
|
|
235
|
+
tdd_exemption_acked_by: opts.tddExemptionAckedBy ?? null,
|
|
236
|
+
};
|
|
237
|
+
// payload = tddEntry 字段 + helper 元数据(reconstructProjectionFromAckLog identity cast 用)
|
|
238
|
+
// 关键:payload 字段名与 TddEventChain 严格一致,无独立 fallback default
|
|
239
|
+
const payload = {
|
|
240
|
+
helper: 'record-tdd',
|
|
241
|
+
change_id: changeId,
|
|
242
|
+
task_ref: tddEntry.task_ref,
|
|
243
|
+
red_commit: tddEntry.red_commit,
|
|
244
|
+
green_commit: tddEntry.green_commit,
|
|
245
|
+
mode: opts.mode ?? null,
|
|
246
|
+
tdd_exemption: tddEntry.tdd_exemption,
|
|
247
|
+
tdd_exemption_acked_by: tddEntry.tdd_exemption_acked_by,
|
|
248
|
+
};
|
|
249
|
+
const payloadHash = canonicalHash(payload);
|
|
250
|
+
// 构建 EvidenceHelperEntry(extra = payload,reconstructProjectionFromAckLog identity cast)
|
|
251
|
+
const entry = {
|
|
252
|
+
schema: 'forge-ack-log/v1',
|
|
253
|
+
kind: 'evidence-helper',
|
|
254
|
+
timestamp: new Date().toISOString(),
|
|
255
|
+
helper_name: 'record-tdd',
|
|
256
|
+
change_id: changeId,
|
|
257
|
+
task_ref: opts.task,
|
|
258
|
+
payload_hash: payloadHash,
|
|
259
|
+
status: 'success',
|
|
260
|
+
git_head: getGitHead(changeRoot),
|
|
261
|
+
extra: payload,
|
|
262
|
+
};
|
|
263
|
+
staging.tdd_event_chain.push(tddEntry);
|
|
264
|
+
await writeStagingYaml(changeRoot, staging);
|
|
265
|
+
// round 2 fix (C5):appendAckLog 移入 lock 内防并发链断 race
|
|
266
|
+
// 否则 staging release 与 ack-log 读 last entry 之间存在 race window,
|
|
267
|
+
// 双进程可能读到同一 last 写入相同 prev_entry_hash → 链断
|
|
268
|
+
await appendAckLog(changeRoot, entry);
|
|
269
|
+
}
|
|
270
|
+
finally {
|
|
271
|
+
await release();
|
|
272
|
+
}
|
|
273
|
+
process.exit(0);
|
|
274
|
+
});
|
|
275
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
276
|
+
// 子命令 2: forge evidence record-verify
|
|
277
|
+
// plan-9g Task 3.3:+6 新 options(按 plan §4.3.0 表;超 plan 行 2907 "+5" 字面,含 v6 修订 --result)
|
|
278
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
279
|
+
evidence
|
|
280
|
+
.command('record-verify')
|
|
281
|
+
.description('记录 verify 报告事件:写 payload hash 到 ack-log.jsonl + staging.yaml')
|
|
282
|
+
.argument('<changeId>', 'change 目录 ID')
|
|
283
|
+
.requiredOption('--task-refs <list>', 'task 引用列表,逗号分隔,如 tasks.md#task-1,tasks.md#task-2')
|
|
284
|
+
.requiredOption('--scope <type>', 'verify 范围:per-task(每 task)或 change-level(整个 change)')
|
|
285
|
+
.requiredOption('--report <path>', 'verify 报告文件路径')
|
|
286
|
+
// plan-9g Task 3.3 新增 options(沿 plan §4.3.0 表)
|
|
287
|
+
.option('--result <pass|fail|skip>', 'verify 结果(v6 修订 Codex 七轮 MAJOR)')
|
|
288
|
+
.option('--report-hash <sha256>', 'sha256(verify runner report content)')
|
|
289
|
+
.option('--log <path>', 'verify plain log 路径')
|
|
290
|
+
.option('--log-hash <sha256>', 'sha256(verify log content)')
|
|
291
|
+
.option('--exit-code <int>', 'verify 进程 exit code')
|
|
292
|
+
.option('--invoked-at <iso>', 'verify 命令调用时间戳(ISO 8601 UTC)')
|
|
293
|
+
.action(async (changeId, opts) => {
|
|
294
|
+
// 验证 scope 取值:仅允许 per-task 或 change-level
|
|
295
|
+
const validScopes = ['per-task', 'change-level'];
|
|
296
|
+
if (!validScopes.includes(opts.scope)) {
|
|
297
|
+
process.stderr.write(`forge evidence record-verify: invalid --scope "${opts.scope}". ` +
|
|
298
|
+
`Allowed values: per-task, change-level\n`);
|
|
299
|
+
process.exit(2);
|
|
300
|
+
}
|
|
301
|
+
const changeRoot = resolve(process.cwd(), 'forge', 'changes', changeId);
|
|
302
|
+
// 解析逗号分隔的 task-refs 列表
|
|
303
|
+
const taskRefList = opts.taskRefs
|
|
304
|
+
.split(',')
|
|
305
|
+
.map((r) => r.trim())
|
|
306
|
+
.filter((r) => r.length > 0);
|
|
307
|
+
// plan-9g Task 5 round 2 (Critical fix):payload = staging-built object(同 record-tdd 模式)
|
|
308
|
+
const release = await acquireStagingLock(changeRoot);
|
|
309
|
+
try {
|
|
310
|
+
const existing = await readStagingYaml(changeRoot);
|
|
311
|
+
const staging = existing ?? {
|
|
312
|
+
schema: 'forge-process-evidence/v1',
|
|
313
|
+
process_verification_mode: 'full',
|
|
314
|
+
process_verification_mode_acked_by: null,
|
|
315
|
+
process_verification_mode_acked_at: null,
|
|
316
|
+
env_hash: computeEnvHash(changeRoot),
|
|
317
|
+
tdd_event_chain: [],
|
|
318
|
+
verify_invocations: [],
|
|
319
|
+
subagent_review_chain: [],
|
|
320
|
+
};
|
|
321
|
+
// 构建 VerifyInvocation 条目 — single source of truth
|
|
322
|
+
// (沿 plan §4.3.0 表 "写入 staging.yaml 字段" 列)
|
|
323
|
+
const verifyEntry = {
|
|
324
|
+
invoked_at: opts.invokedAt ?? new Date().toISOString(),
|
|
325
|
+
task_refs: taskRefList,
|
|
326
|
+
verify_scope: opts.scope,
|
|
327
|
+
result: opts.result ?? 'pass',
|
|
328
|
+
exit_code: opts.exitCode !== undefined ? parseInt(opts.exitCode, 10) : 0,
|
|
329
|
+
log_path: opts.log ?? '',
|
|
330
|
+
log_hash: opts.logHash ?? '',
|
|
331
|
+
runner_report_path: opts.report,
|
|
332
|
+
runner_report_hash: opts.reportHash ?? '',
|
|
333
|
+
};
|
|
334
|
+
// payload = verifyEntry 字段 + helper 元数据(identity mapping;无独立 fallback default)
|
|
335
|
+
const payload = {
|
|
336
|
+
helper: 'record-verify',
|
|
337
|
+
change_id: changeId,
|
|
338
|
+
task_refs: verifyEntry.task_refs,
|
|
339
|
+
verify_scope: verifyEntry.verify_scope,
|
|
340
|
+
result: verifyEntry.result,
|
|
341
|
+
invoked_at: verifyEntry.invoked_at,
|
|
342
|
+
exit_code: verifyEntry.exit_code,
|
|
343
|
+
log_path: verifyEntry.log_path,
|
|
344
|
+
log_hash: verifyEntry.log_hash,
|
|
345
|
+
runner_report_path: verifyEntry.runner_report_path,
|
|
346
|
+
runner_report_hash: verifyEntry.runner_report_hash,
|
|
347
|
+
};
|
|
348
|
+
const payloadHash = canonicalHash(payload);
|
|
349
|
+
const entry = {
|
|
350
|
+
schema: 'forge-ack-log/v1',
|
|
351
|
+
kind: 'evidence-helper',
|
|
352
|
+
timestamp: new Date().toISOString(),
|
|
353
|
+
helper_name: 'record-verify',
|
|
354
|
+
change_id: changeId,
|
|
355
|
+
task_ref: opts.taskRefs,
|
|
356
|
+
payload_hash: payloadHash,
|
|
357
|
+
status: 'success',
|
|
358
|
+
git_head: getGitHead(changeRoot),
|
|
359
|
+
extra: payload,
|
|
360
|
+
};
|
|
361
|
+
staging.verify_invocations.push(verifyEntry);
|
|
362
|
+
await writeStagingYaml(changeRoot, staging);
|
|
363
|
+
// round 2 fix (C5):appendAckLog 移入 lock 内防并发链断 race
|
|
364
|
+
await appendAckLog(changeRoot, entry);
|
|
365
|
+
}
|
|
366
|
+
finally {
|
|
367
|
+
await release();
|
|
368
|
+
}
|
|
369
|
+
process.exit(0);
|
|
370
|
+
});
|
|
371
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
372
|
+
// 子命令 3: forge evidence record-review
|
|
373
|
+
// plan-9g Task 3.3:+3 new options(按 plan §4.3.0 表;--spec-iterations/--quality-iterations rename)
|
|
374
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
375
|
+
evidence
|
|
376
|
+
.command('record-review')
|
|
377
|
+
.description('记录 code review 事件:写 payload hash 到 ack-log.jsonl + staging.yaml')
|
|
378
|
+
.argument('<changeId>', 'change 目录 ID')
|
|
379
|
+
.requiredOption('--task <task-ref>', 'task 引用,如 tasks.md#task-5')
|
|
380
|
+
.requiredOption('--implementer-commit <sha>', 'implementer 最终提交 SHA')
|
|
381
|
+
// plan-9g Task 3.3:--spec-iterations(rename from --spec-iteration;JSON array 格式)
|
|
382
|
+
.option('--spec-iterations <json>', 'spec review 迭代 JSON 数组,[{reviewer_commit,outcome,notes_log_path},...](v6 修订,rename from --spec-iteration)')
|
|
383
|
+
// plan-9g Task 3.3:--quality-iterations(rename from --quality-iteration;JSON array 格式)
|
|
384
|
+
.option('--quality-iterations <json>', 'quality review 迭代 JSON 数组,[{reviewer_commit,outcome,notes_log_path},...](v6 修订,rename from --quality-iteration)')
|
|
385
|
+
// plan-9g Task 3.3:--main-check-off-at 新增
|
|
386
|
+
.option('--main-check-off-at <iso>', '主代理 check-off 时间戳(ISO 8601 UTC)')
|
|
387
|
+
.action(async (changeId, opts) => {
|
|
388
|
+
const changeRoot = resolve(process.cwd(), 'forge', 'changes', changeId);
|
|
389
|
+
// 解析 --spec-iterations JSON 数组
|
|
390
|
+
let specIterations = [];
|
|
391
|
+
if (opts.specIterations) {
|
|
392
|
+
try {
|
|
393
|
+
specIterations = JSON.parse(opts.specIterations);
|
|
394
|
+
}
|
|
395
|
+
catch (e) {
|
|
396
|
+
process.stderr.write(`Invalid --spec-iterations JSON: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
397
|
+
process.exit(2);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
// 解析 --quality-iterations JSON 数组
|
|
401
|
+
let qualityIterations = [];
|
|
402
|
+
if (opts.qualityIterations) {
|
|
403
|
+
try {
|
|
404
|
+
qualityIterations = JSON.parse(opts.qualityIterations);
|
|
405
|
+
}
|
|
406
|
+
catch (e) {
|
|
407
|
+
process.stderr.write(`Invalid --quality-iterations JSON: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
408
|
+
process.exit(2);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
// plan-9g Task 5 round 2 (Critical fix):payload = staging-built object(同 record-tdd 模式)
|
|
412
|
+
const release = await acquireStagingLock(changeRoot);
|
|
413
|
+
try {
|
|
414
|
+
const existing = await readStagingYaml(changeRoot);
|
|
415
|
+
const staging = existing ?? {
|
|
416
|
+
schema: 'forge-process-evidence/v1',
|
|
417
|
+
process_verification_mode: 'full',
|
|
418
|
+
process_verification_mode_acked_by: null,
|
|
419
|
+
process_verification_mode_acked_at: null,
|
|
420
|
+
env_hash: computeEnvHash(changeRoot),
|
|
421
|
+
tdd_event_chain: [],
|
|
422
|
+
verify_invocations: [],
|
|
423
|
+
subagent_review_chain: [],
|
|
424
|
+
};
|
|
425
|
+
// 构建 SubagentReviewChain 条目 — single source of truth
|
|
426
|
+
// (沿 plan §4.3.0 表 "写入 staging.yaml 字段" 列)
|
|
427
|
+
const reviewEntry = {
|
|
428
|
+
task_ref: opts.task,
|
|
429
|
+
implementer_commit: opts.implementerCommit,
|
|
430
|
+
spec_reviewer_iterations: specIterations,
|
|
431
|
+
quality_reviewer_iterations: qualityIterations,
|
|
432
|
+
main_agent_check_off_at: opts.mainCheckOffAt ?? new Date().toISOString(),
|
|
433
|
+
};
|
|
434
|
+
// payload = reviewEntry 字段 + helper 元数据(identity mapping)
|
|
435
|
+
// 注:ack-log payload 字段名沿用历史 record-review payload key 名(spec_iterations / quality_iterations /
|
|
436
|
+
// main_check_off_at),reconstructProjectionFromAckLog 已按这些 key 名 cast,无 mismatch
|
|
437
|
+
const payload = {
|
|
438
|
+
helper: 'record-review',
|
|
439
|
+
change_id: changeId,
|
|
440
|
+
task_ref: reviewEntry.task_ref,
|
|
441
|
+
implementer_commit: reviewEntry.implementer_commit,
|
|
442
|
+
spec_iterations: reviewEntry.spec_reviewer_iterations,
|
|
443
|
+
quality_iterations: reviewEntry.quality_reviewer_iterations,
|
|
444
|
+
main_check_off_at: reviewEntry.main_agent_check_off_at,
|
|
445
|
+
};
|
|
446
|
+
const payloadHash = canonicalHash(payload);
|
|
447
|
+
const entry = {
|
|
448
|
+
schema: 'forge-ack-log/v1',
|
|
449
|
+
kind: 'evidence-helper',
|
|
450
|
+
timestamp: new Date().toISOString(),
|
|
451
|
+
helper_name: 'record-review',
|
|
452
|
+
change_id: changeId,
|
|
453
|
+
task_ref: opts.task,
|
|
454
|
+
payload_hash: payloadHash,
|
|
455
|
+
status: 'success',
|
|
456
|
+
git_head: getGitHead(changeRoot),
|
|
457
|
+
extra: payload,
|
|
458
|
+
};
|
|
459
|
+
staging.subagent_review_chain.push(reviewEntry);
|
|
460
|
+
await writeStagingYaml(changeRoot, staging);
|
|
461
|
+
// round 2 fix (C5):appendAckLog 移入 lock 内防并发链断 race
|
|
462
|
+
await appendAckLog(changeRoot, entry);
|
|
463
|
+
}
|
|
464
|
+
finally {
|
|
465
|
+
await release();
|
|
466
|
+
}
|
|
467
|
+
process.exit(0);
|
|
468
|
+
});
|
|
469
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
470
|
+
// 子命令 4: forge evidence freeze <changeId> --kind <verify|review>
|
|
471
|
+
// plan-9g Task 4 — staging → marker 凝固 + transaction + WARNING 转 VerifyFinding
|
|
472
|
+
// brainstorm spec §5 数据流 + §9.6 锁定 B(transaction)+ §9.11(ack-log tail+count 固化)
|
|
473
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
474
|
+
evidence
|
|
475
|
+
.command('freeze')
|
|
476
|
+
.description('staging → marker 凝固;主代理在 verify/review marker 写完后显式调用')
|
|
477
|
+
.argument('<changeId>', 'change 目录 ID')
|
|
478
|
+
.requiredOption('--kind <verify|review>', 'freeze 目标 marker:verify 或 review(commander.requiredOption,omit 自动 exit 1)')
|
|
479
|
+
.option('--marker <path>', 'marker 路径(可选,默认按 --kind 派生)')
|
|
480
|
+
.action(async (changeId, opts) => {
|
|
481
|
+
// 校验 --kind 取值(commander.requiredOption 已保证非空,但仍校 enum)
|
|
482
|
+
if (opts.kind !== 'verify' && opts.kind !== 'review') {
|
|
483
|
+
process.stderr.write(`forge evidence freeze: invalid --kind "${opts.kind}". Must be 'verify' or 'review'\n`);
|
|
484
|
+
process.exit(2);
|
|
485
|
+
}
|
|
486
|
+
const kind = opts.kind;
|
|
487
|
+
const changeRoot = resolve(process.cwd(), 'forge', 'changes', changeId);
|
|
488
|
+
const markerFilename = kind === 'verify' ? '.verify-passed' : '.review-passed';
|
|
489
|
+
const markerPath = opts.marker ?? join(changeRoot, markerFilename);
|
|
490
|
+
// 路径冲突检测(--marker 与 --kind 派生不一致 → stderr WARNING)
|
|
491
|
+
const derivedPath = join(changeRoot, markerFilename);
|
|
492
|
+
if (opts.marker && opts.marker !== derivedPath) {
|
|
493
|
+
process.stderr.write(`⚠ forge evidence freeze: --marker (${opts.marker}) 与 --kind=${kind} 派生路径 (${derivedPath}) 不一致;以 --marker 为准\n`);
|
|
494
|
+
}
|
|
495
|
+
// 1. acquireStagingLock(防 freeze 期间 helper 再 append)
|
|
496
|
+
const releaseLock = await acquireStagingLock(changeRoot);
|
|
497
|
+
try {
|
|
498
|
+
// 2. 读 staging.yaml
|
|
499
|
+
const stagingPath = join(changeRoot, '.evidence', 'process-evidence.staging.yaml');
|
|
500
|
+
if (!existsSync(stagingPath)) {
|
|
501
|
+
process.stderr.write(`forge evidence freeze: staging file not found at ${stagingPath};` +
|
|
502
|
+
` 主代理必须先调 forge evidence record-tdd/verify/review 写 staging\n`);
|
|
503
|
+
process.exit(1);
|
|
504
|
+
}
|
|
505
|
+
const stagingContent = await readFile(stagingPath, 'utf8');
|
|
506
|
+
const staging = parse(stagingContent);
|
|
507
|
+
// 3. 重算 staging_hash 校验未被中间篡改
|
|
508
|
+
// Observation(latent bug 1):plan §5.1.1 字面 projection 三数组与 Task 3 实际公式不一致。
|
|
509
|
+
// Task 3 writeStagingYaml:stagingHash = canonicalHash(data) 其中 data 是完整 ProcessEvidence struct
|
|
510
|
+
// (不含 staging_hash),再写 { ...data, staging_hash }。
|
|
511
|
+
// 所以读取后 staging 含 staging_hash 信封字段;重算需剥离该字段对剩余做 canonicalHash。
|
|
512
|
+
// 沿 Task 3 落地公式(backward-compatible)。
|
|
513
|
+
const { staging_hash: storedHash, ...stagingForHash } = staging;
|
|
514
|
+
const recomputedHash = canonicalHash(stagingForHash);
|
|
515
|
+
if (recomputedHash !== storedHash) {
|
|
516
|
+
process.stderr.write(`✗ forge evidence freeze: staging_hash mismatch — staging tampered\n`);
|
|
517
|
+
process.exit(1);
|
|
518
|
+
}
|
|
519
|
+
// 4. 读 marker(主代理刚写的 .verify-passed/.review-passed)
|
|
520
|
+
if (!existsSync(markerPath)) {
|
|
521
|
+
process.stderr.write(`forge evidence freeze: marker not found at ${markerPath};` +
|
|
522
|
+
` 主代理必须先写 .${kind}-passed yaml(沿 commands/verify.md 步骤 4.3)\n`);
|
|
523
|
+
process.exit(1);
|
|
524
|
+
}
|
|
525
|
+
const markerContent = await readFile(markerPath, 'utf8');
|
|
526
|
+
const marker = parse(markerContent);
|
|
527
|
+
// 5. staging schema 强制必填 mode/ack/env_hash;freeze 时缺字段 → exit 1
|
|
528
|
+
// (v3 修订:mode != full 时 acked_by/acked_at 必填;env_hash 子字段完整性)
|
|
529
|
+
const stagingTyped = staging;
|
|
530
|
+
const missingFields = [];
|
|
531
|
+
if (!stagingTyped.process_verification_mode)
|
|
532
|
+
missingFields.push('process_verification_mode');
|
|
533
|
+
// mode != full 时 acked_by + acked_at 必填(沿不变量 12 CRITICAL)
|
|
534
|
+
if (stagingTyped.process_verification_mode &&
|
|
535
|
+
stagingTyped.process_verification_mode !== 'full') {
|
|
536
|
+
if (!stagingTyped.process_verification_mode_acked_by)
|
|
537
|
+
missingFields.push('process_verification_mode_acked_by (mode != full required)');
|
|
538
|
+
if (!stagingTyped.process_verification_mode_acked_at)
|
|
539
|
+
missingFields.push('process_verification_mode_acked_at (mode != full required)');
|
|
540
|
+
}
|
|
541
|
+
if (!stagingTyped.env_hash) {
|
|
542
|
+
missingFields.push('env_hash');
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
545
|
+
// env_hash 子字段完整性
|
|
546
|
+
if (!stagingTyped.env_hash.lockfile_hash)
|
|
547
|
+
missingFields.push('env_hash.lockfile_hash');
|
|
548
|
+
if (!stagingTyped.env_hash.node_version)
|
|
549
|
+
missingFields.push('env_hash.node_version');
|
|
550
|
+
if (!stagingTyped.env_hash.os_platform)
|
|
551
|
+
missingFields.push('env_hash.os_platform');
|
|
552
|
+
}
|
|
553
|
+
if (missingFields.length > 0) {
|
|
554
|
+
process.stderr.write(`forge evidence freeze: staging.yaml missing required fields: ${missingFields.join(', ')};` +
|
|
555
|
+
` 主代理必须先调 forge evidence record-tdd 写完整 staging(含 --mode + --lockfile-hash + 环境字段)\n`);
|
|
556
|
+
process.exit(1);
|
|
557
|
+
}
|
|
558
|
+
// 构造 processEvidence(不含 staging_hash 信封字段)
|
|
559
|
+
const processEvidence = {
|
|
560
|
+
schema: 'forge-process-evidence/v1',
|
|
561
|
+
process_verification_mode: stagingTyped.process_verification_mode,
|
|
562
|
+
process_verification_mode_acked_by: stagingTyped.process_verification_mode_acked_by ?? null,
|
|
563
|
+
process_verification_mode_acked_at: stagingTyped.process_verification_mode_acked_at ?? null,
|
|
564
|
+
env_hash: stagingTyped.env_hash,
|
|
565
|
+
tdd_event_chain: staging.tdd_event_chain,
|
|
566
|
+
verify_invocations: staging.verify_invocations,
|
|
567
|
+
subagent_review_chain: staging.subagent_review_chain,
|
|
568
|
+
};
|
|
569
|
+
marker.process_evidence = processEvidence;
|
|
570
|
+
// 6. 写 process_evidence_staging_hash 快照(archive fence cross-check 用)
|
|
571
|
+
marker.process_evidence_staging_hash = storedHash;
|
|
572
|
+
// 7. 三段式 entry 处理:
|
|
573
|
+
// a) entriesBeforeFreeze:用于 11/12 ack 检测(freeze entry 还未在)
|
|
574
|
+
// b) appendAckLog(freezeEntry):写 freeze 行(参与全 JSONL 链)
|
|
575
|
+
// c) entriesAfterFreeze:用于 tail/count 固化(含 freeze entry)
|
|
576
|
+
// 避免 happy path 自拒签(原 v0/v1:用同名 allEntries 跨两阶段导致顺序错乱)
|
|
577
|
+
const entriesBeforeFreeze = await readAllAckLogEntries(changeRoot);
|
|
578
|
+
// 8. 算 freeze-time WARNING(仅不变量 7 + 10)→ 转 VerifyFinding 写 marker.verify_findings
|
|
579
|
+
// + CRITICAL 11/12(tdd_exemption ack / mode ack)freeze 时直接 exit 1
|
|
580
|
+
// (brainstorm spec §3 WARNING 流转两段闭合)
|
|
581
|
+
// 用 entriesBeforeFreeze(freeze entry 还未在);避免循环依赖
|
|
582
|
+
const warningFindings = computeFreezeWarnings(processEvidence, changeRoot, entriesBeforeFreeze);
|
|
583
|
+
// 若 fence-ctx 检测到不变量 11/12 失败 → CRITICAL,exit 1
|
|
584
|
+
if (warningFindings.criticals.length > 0) {
|
|
585
|
+
for (const c of warningFindings.criticals) {
|
|
586
|
+
process.stderr.write(`✗ ${c.evidence}\n`);
|
|
587
|
+
}
|
|
588
|
+
process.stderr.write(`forge evidence freeze: CRITICAL invariant failed;` +
|
|
589
|
+
` 必须先跑 forge ack propose 处理后 retry freeze\n`);
|
|
590
|
+
process.exit(1);
|
|
591
|
+
}
|
|
592
|
+
// WARNING 7/10 转 VerifyFinding 追加 marker.verify_findings
|
|
593
|
+
// v8.1 round 2 (I-2 fix):re-freeze 时 dedup by finding_hash,
|
|
594
|
+
// 防 marker.verify_findings 重复 id(checkVerifyFindingsArray seenIds detection 拒签)
|
|
595
|
+
if (warningFindings.warnings.length > 0) {
|
|
596
|
+
const existingFindings = marker.verify_findings ?? [];
|
|
597
|
+
const existingHashes = new Set(existingFindings.map((f) => f.finding_hash));
|
|
598
|
+
const newFindings = warningFindings.warnings.filter((f) => !existingHashes.has(f.finding_hash));
|
|
599
|
+
marker.verify_findings = [...existingFindings, ...newFindings];
|
|
600
|
+
}
|
|
601
|
+
// 9. 先 append freeze entry 到 ack-log,再读全文件算 tail/count 固化
|
|
602
|
+
// freeze entry payload_hash 不含 ack_log_tail_hash(循环依赖避免)
|
|
603
|
+
// markerPath 跨平台归一化正斜杠(plan-9g 注:Windows 反斜杠路径 hash 不一致)
|
|
604
|
+
const normalizedMarkerPath = markerPath.replace(/\\/g, '/');
|
|
605
|
+
const freezePayloadHash = canonicalHash({
|
|
606
|
+
helper: 'freeze',
|
|
607
|
+
change_id: changeId,
|
|
608
|
+
kind,
|
|
609
|
+
marker_path: normalizedMarkerPath,
|
|
610
|
+
staging_hash: storedHash,
|
|
611
|
+
warning_count: warningFindings.warnings.length,
|
|
612
|
+
});
|
|
613
|
+
// v8.1 round 2 (I-1 fix):idempotency guard 防 retry 时多余 freeze entry
|
|
614
|
+
// 场景:appendAckLog 成功 → writeFile/rename 失败 → ack-log 已含 freeze entry,marker 未更新。
|
|
615
|
+
// Retry freeze 不加 guard 会再 appendAckLog → entry_count mismatch + 链不可信。
|
|
616
|
+
// 判定:last entry kind=evidence-helper + helper_name=freeze + payload_hash 完全相同 → replay
|
|
617
|
+
const lastEntry = entriesBeforeFreeze[entriesBeforeFreeze.length - 1];
|
|
618
|
+
const isReplay = lastEntry?.kind === 'evidence-helper' &&
|
|
619
|
+
lastEntry.helper_name === 'freeze' &&
|
|
620
|
+
lastEntry.payload_hash === freezePayloadHash;
|
|
621
|
+
if (!isReplay) {
|
|
622
|
+
const freezeEntry = {
|
|
623
|
+
schema: 'forge-ack-log/v1',
|
|
624
|
+
kind: 'evidence-helper',
|
|
625
|
+
timestamp: new Date().toISOString(),
|
|
626
|
+
helper_name: 'freeze',
|
|
627
|
+
change_id: changeId,
|
|
628
|
+
task_ref: `freeze-${kind}`, // 标志 freeze 而非 record-*
|
|
629
|
+
payload_hash: freezePayloadHash,
|
|
630
|
+
status: 'success',
|
|
631
|
+
git_head: getGitHead(changeRoot),
|
|
632
|
+
extra: { kind, warning_count: warningFindings.warnings.length },
|
|
633
|
+
};
|
|
634
|
+
await appendAckLog(changeRoot, freezeEntry);
|
|
635
|
+
}
|
|
636
|
+
// 否则:retry 复用已有 freeze entry,不再 append(ack-log 不长第二条)
|
|
637
|
+
// 10. 读 entriesAfterFreeze(此时已含 freeze entry)→ 算 tail/count 固化到 marker
|
|
638
|
+
const entriesAfterFreeze = await readAllAckLogEntries(changeRoot);
|
|
639
|
+
marker.ack_log_entry_count = entriesAfterFreeze.length;
|
|
640
|
+
marker.ack_log_tail_hash =
|
|
641
|
+
entriesAfterFreeze.length > 0
|
|
642
|
+
? canonicalHash(entriesAfterFreeze[entriesAfterFreeze.length - 1])
|
|
643
|
+
: null;
|
|
644
|
+
// 11. transaction 落 marker(沿 brainstorm spec §9.6 锁定 B + plan-9e1 transaction.ts 模式)
|
|
645
|
+
// tmp 文件写 + rename atomic(POSIX + Windows NTFS 同卷)
|
|
646
|
+
const tmpPath = `${markerPath}.tmp.${process.pid}`;
|
|
647
|
+
const updatedYaml = stringify(marker);
|
|
648
|
+
await writeFile(tmpPath, updatedYaml, 'utf8');
|
|
649
|
+
// rename atomic(POSIX + Windows NTFS 同卷)
|
|
650
|
+
await rename(tmpPath, markerPath);
|
|
651
|
+
process.stdout.write(`✓ forge evidence freeze: ${kind} marker frozen` +
|
|
652
|
+
` (staging_hash=${storedHash.slice(0, 16)}..., ` +
|
|
653
|
+
`${warningFindings.warnings.length} WARNING(s) → marker.verify_findings)\n`);
|
|
654
|
+
process.exit(0);
|
|
655
|
+
}
|
|
656
|
+
finally {
|
|
657
|
+
await releaseLock();
|
|
658
|
+
}
|
|
659
|
+
});
|
|
660
|
+
return evidence;
|
|
661
|
+
}
|
|
662
|
+
//# sourceMappingURL=evidence.js.map
|