@rpamis/comet 0.4.0-beta.6 → 0.4.0-beta.8
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 -21
- package/README.md +209 -74
- package/assets/manifest.json +14 -5
- package/assets/skills/comet/SKILL.md +17 -282
- package/assets/skills/comet/reference/comet-yaml-fields.md +1 -1
- package/assets/skills/comet/reference/context-recovery.md +3 -3
- package/assets/skills/comet/reference/intent-frame.md +2 -2
- package/assets/skills/comet/reference/scripts.md +2 -2
- package/assets/skills/comet/rules/comet-workflow-guard.en.md +32 -0
- package/assets/skills/comet/rules/comet-workflow-guard.md +32 -0
- package/assets/skills/comet/scripts/comet-entry-runtime.mjs +7855 -0
- package/assets/skills/comet/scripts/comet-hook-router.mjs +10336 -0
- package/assets/skills/comet/scripts/comet-runtime.mjs +615 -501
- package/assets/skills/comet-any/SKILL.md +4 -4
- package/assets/skills/comet-any/reference/authoring-subagents.md +1 -1
- package/assets/skills/comet-any/reference/bundle-authoring.md +1 -1
- package/assets/skills/comet-any/reference/subagents/reference-author.md +1 -1
- package/assets/skills/comet-any/reference/subagents/script-author.md +1 -1
- package/assets/skills/comet-any/reference/subagents/skill-core-author.md +1 -1
- package/assets/skills/comet-any/reference/subagents/skill-reviewer.md +2 -2
- package/assets/skills/comet-any/reference/subagents/workflow-entry-author.md +3 -3
- package/assets/skills/comet-archive/SKILL.md +1 -2
- package/assets/skills/comet-build/SKILL.md +1 -1
- package/assets/skills/comet-classic/SKILL.md +293 -0
- package/assets/skills/comet-design/SKILL.md +1 -1
- package/assets/skills/comet-hotfix/SKILL.md +4 -4
- package/assets/skills/comet-native/SKILL.md +257 -0
- package/assets/skills/comet-native/reference/artifacts.md +204 -0
- package/assets/skills/comet-native/reference/commands.md +118 -0
- package/assets/skills/comet-native/reference/recovery.md +143 -0
- package/assets/skills/comet-native/scripts/comet-native-hook-guard.mjs +4 -0
- package/assets/skills/comet-native/scripts/comet-native-runtime.mjs +28969 -0
- package/assets/skills/comet-open/SKILL.md +4 -4
- package/assets/skills/comet-tweak/SKILL.md +7 -7
- package/assets/skills-zh/comet/SKILL.md +17 -270
- package/assets/skills-zh/comet/reference/comet-yaml-fields.md +1 -1
- package/assets/skills-zh/comet/reference/context-recovery.md +3 -3
- package/assets/skills-zh/comet/reference/intent-frame.md +2 -2
- package/assets/skills-zh/comet/reference/scripts.md +2 -2
- package/assets/skills-zh/comet-any/SKILL.md +4 -4
- package/assets/skills-zh/comet-any/reference/authoring-subagents.md +1 -1
- package/assets/skills-zh/comet-any/reference/bundle-authoring.md +1 -1
- package/assets/skills-zh/comet-any/reference/subagents/reference-author.md +1 -1
- package/assets/skills-zh/comet-any/reference/subagents/script-author.md +1 -1
- package/assets/skills-zh/comet-any/reference/subagents/skill-core-author.md +1 -1
- package/assets/skills-zh/comet-any/reference/subagents/skill-reviewer.md +2 -2
- package/assets/skills-zh/comet-any/reference/subagents/workflow-entry-author.md +3 -3
- package/assets/skills-zh/comet-archive/SKILL.md +1 -2
- package/assets/skills-zh/comet-build/SKILL.md +1 -1
- package/assets/skills-zh/comet-classic/SKILL.md +281 -0
- package/assets/skills-zh/comet-design/SKILL.md +1 -1
- package/assets/skills-zh/comet-hotfix/SKILL.md +4 -4
- package/assets/skills-zh/comet-native/SKILL.md +257 -0
- package/assets/skills-zh/comet-native/reference/artifacts.md +206 -0
- package/assets/skills-zh/comet-native/reference/commands.md +118 -0
- package/assets/skills-zh/comet-native/reference/recovery.md +143 -0
- package/assets/skills-zh/comet-open/SKILL.md +4 -4
- package/assets/skills-zh/comet-tweak/SKILL.md +7 -7
- package/dist/app/cli/index.js +59 -13
- package/dist/app/cli/index.js.map +1 -1
- package/dist/app/commands/command-result.d.ts +6 -0
- package/dist/app/commands/command-result.d.ts.map +1 -0
- package/dist/app/commands/command-result.js +4 -0
- package/dist/app/commands/command-result.js.map +1 -0
- package/dist/app/commands/doctor.d.ts +1 -0
- package/dist/app/commands/doctor.d.ts.map +1 -1
- package/dist/app/commands/doctor.js +201 -26
- package/dist/app/commands/doctor.js.map +1 -1
- package/dist/app/commands/eval.d.ts +3 -1
- package/dist/app/commands/eval.d.ts.map +1 -1
- package/dist/app/commands/eval.js +17 -7
- package/dist/app/commands/eval.js.map +1 -1
- package/dist/app/commands/i18n.d.ts +1 -1
- package/dist/app/commands/i18n.d.ts.map +1 -1
- package/dist/app/commands/i18n.js +6 -2
- package/dist/app/commands/i18n.js.map +1 -1
- package/dist/app/commands/init.d.ts +10 -2
- package/dist/app/commands/init.d.ts.map +1 -1
- package/dist/app/commands/init.js +331 -50
- package/dist/app/commands/init.js.map +1 -1
- package/dist/app/commands/native.d.ts +2 -0
- package/dist/app/commands/native.d.ts.map +1 -0
- package/dist/app/commands/native.js +10 -0
- package/dist/app/commands/native.js.map +1 -0
- package/dist/app/commands/project-scope-selection.d.ts.map +1 -1
- package/dist/app/commands/project-scope-selection.js +2 -0
- package/dist/app/commands/project-scope-selection.js.map +1 -1
- package/dist/app/commands/resume-probe.d.ts.map +1 -1
- package/dist/app/commands/resume-probe.js +8 -2
- package/dist/app/commands/resume-probe.js.map +1 -1
- package/dist/app/commands/status.d.ts +0 -32
- package/dist/app/commands/status.d.ts.map +1 -1
- package/dist/app/commands/status.js +44 -177
- package/dist/app/commands/status.js.map +1 -1
- package/dist/app/commands/update.d.ts +20 -4
- package/dist/app/commands/update.d.ts.map +1 -1
- package/dist/app/commands/update.js +698 -90
- package/dist/app/commands/update.js.map +1 -1
- package/dist/app/commands/workflow.d.ts +6 -0
- package/dist/app/commands/workflow.d.ts.map +1 -0
- package/dist/app/commands/workflow.js +11 -0
- package/dist/app/commands/workflow.js.map +1 -0
- package/dist/config/repository-layout.json +21 -1
- package/dist/domains/bundle/bundle-platform.d.ts.map +1 -1
- package/dist/domains/bundle/bundle-platform.js +1 -1
- package/dist/domains/bundle/bundle-platform.js.map +1 -1
- package/dist/domains/comet-classic/classic-archive.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-archive.js +3 -0
- package/dist/domains/comet-classic/classic-archive.js.map +1 -1
- package/dist/domains/comet-classic/classic-current-change.d.ts +3 -5
- package/dist/domains/comet-classic/classic-current-change.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-current-change.js +31 -57
- package/dist/domains/comet-classic/classic-current-change.js.map +1 -1
- package/dist/domains/comet-classic/classic-guard.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-guard.js +3 -2
- package/dist/domains/comet-classic/classic-guard.js.map +1 -1
- package/dist/domains/comet-classic/classic-hook-guard.d.ts +9 -0
- package/dist/domains/comet-classic/classic-hook-guard.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-hook-guard.js +84 -11
- package/dist/domains/comet-classic/classic-hook-guard.js.map +1 -1
- package/dist/domains/comet-classic/classic-project-config.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-project-config.js +12 -8
- package/dist/domains/comet-classic/classic-project-config.js.map +1 -1
- package/dist/domains/comet-classic/classic-runtime-run.d.ts.map +1 -1
- package/dist/domains/comet-classic/classic-runtime-run.js +9 -1
- package/dist/domains/comet-classic/classic-runtime-run.js.map +1 -1
- package/dist/domains/comet-entry/current-selection-repair.d.ts +17 -0
- package/dist/domains/comet-entry/current-selection-repair.d.ts.map +1 -0
- package/dist/domains/comet-entry/current-selection-repair.js +19 -0
- package/dist/domains/comet-entry/current-selection-repair.js.map +1 -0
- package/dist/domains/comet-entry/current-selection.d.ts +28 -0
- package/dist/domains/comet-entry/current-selection.d.ts.map +1 -0
- package/dist/domains/comet-entry/current-selection.js +116 -0
- package/dist/domains/comet-entry/current-selection.js.map +1 -0
- package/dist/domains/comet-entry/entry-runtime-entry.d.ts +2 -0
- package/dist/domains/comet-entry/entry-runtime-entry.d.ts.map +1 -0
- package/dist/domains/comet-entry/entry-runtime-entry.js +3 -0
- package/dist/domains/comet-entry/entry-runtime-entry.js.map +1 -0
- package/dist/domains/comet-entry/entry-runtime.d.ts +7 -0
- package/dist/domains/comet-entry/entry-runtime.d.ts.map +1 -0
- package/dist/domains/comet-entry/entry-runtime.js +55 -0
- package/dist/domains/comet-entry/entry-runtime.js.map +1 -0
- package/dist/domains/comet-entry/hook-adapter.d.ts +6 -0
- package/dist/domains/comet-entry/hook-adapter.d.ts.map +1 -0
- package/dist/domains/comet-entry/hook-adapter.js +202 -0
- package/dist/domains/comet-entry/hook-adapter.js.map +1 -0
- package/dist/domains/comet-entry/hook-router-entry.d.ts +8 -0
- package/dist/domains/comet-entry/hook-router-entry.d.ts.map +1 -0
- package/dist/domains/comet-entry/hook-router-entry.js +92 -0
- package/dist/domains/comet-entry/hook-router-entry.js.map +1 -0
- package/dist/domains/comet-entry/hook-router.d.ts +32 -0
- package/dist/domains/comet-entry/hook-router.d.ts.map +1 -0
- package/dist/domains/comet-entry/hook-router.js +133 -0
- package/dist/domains/comet-entry/hook-router.js.map +1 -0
- package/dist/domains/comet-entry/hook-types.d.ts +20 -0
- package/dist/domains/comet-entry/hook-types.d.ts.map +1 -0
- package/dist/domains/comet-entry/hook-types.js +2 -0
- package/dist/domains/comet-entry/hook-types.js.map +1 -0
- package/dist/domains/comet-entry/init-workflow.d.ts +16 -0
- package/dist/domains/comet-entry/init-workflow.d.ts.map +1 -0
- package/dist/domains/comet-entry/init-workflow.js +103 -0
- package/dist/domains/comet-entry/init-workflow.js.map +1 -0
- package/dist/domains/comet-entry/project-status.d.ts +3 -0
- package/dist/domains/comet-entry/project-status.d.ts.map +1 -0
- package/dist/domains/comet-entry/project-status.js +222 -0
- package/dist/domains/comet-entry/project-status.js.map +1 -0
- package/dist/domains/comet-entry/resolve-entry.d.ts +3 -0
- package/dist/domains/comet-entry/resolve-entry.d.ts.map +1 -0
- package/dist/domains/comet-entry/resolve-entry.js +22 -0
- package/dist/domains/comet-entry/resolve-entry.js.map +1 -0
- package/dist/domains/comet-entry/resume-probe.d.ts +34 -0
- package/dist/domains/comet-entry/resume-probe.d.ts.map +1 -0
- package/dist/domains/comet-entry/resume-probe.js +458 -0
- package/dist/domains/comet-entry/resume-probe.js.map +1 -0
- package/dist/domains/comet-entry/types.d.ts +59 -0
- package/dist/domains/comet-entry/types.d.ts.map +1 -0
- package/dist/domains/comet-entry/types.js +2 -0
- package/dist/domains/comet-entry/types.js.map +1 -0
- package/dist/domains/comet-entry/workflow-resolution.d.ts +8 -0
- package/dist/domains/comet-entry/workflow-resolution.d.ts.map +1 -0
- package/dist/domains/comet-entry/workflow-resolution.js +16 -0
- package/dist/domains/comet-entry/workflow-resolution.js.map +1 -0
- package/dist/domains/comet-native/index.d.ts +35 -0
- package/dist/domains/comet-native/index.d.ts.map +1 -0
- package/dist/domains/comet-native/index.js +35 -0
- package/dist/domains/comet-native/index.js.map +1 -0
- package/dist/domains/comet-native/native-acceptance.d.ts +42 -0
- package/dist/domains/comet-native/native-acceptance.d.ts.map +1 -0
- package/dist/domains/comet-native/native-acceptance.js +503 -0
- package/dist/domains/comet-native/native-acceptance.js.map +1 -0
- package/dist/domains/comet-native/native-archive-content.d.ts +26 -0
- package/dist/domains/comet-native/native-archive-content.d.ts.map +1 -0
- package/dist/domains/comet-native/native-archive-content.js +159 -0
- package/dist/domains/comet-native/native-archive-content.js.map +1 -0
- package/dist/domains/comet-native/native-archive-inspection.d.ts +9 -0
- package/dist/domains/comet-native/native-archive-inspection.d.ts.map +1 -0
- package/dist/domains/comet-native/native-archive-inspection.js +94 -0
- package/dist/domains/comet-native/native-archive-inspection.js.map +1 -0
- package/dist/domains/comet-native/native-archive-preflight.d.ts +52 -0
- package/dist/domains/comet-native/native-archive-preflight.d.ts.map +1 -0
- package/dist/domains/comet-native/native-archive-preflight.js +214 -0
- package/dist/domains/comet-native/native-archive-preflight.js.map +1 -0
- package/dist/domains/comet-native/native-archive-transaction.d.ts +19 -0
- package/dist/domains/comet-native/native-archive-transaction.d.ts.map +1 -0
- package/dist/domains/comet-native/native-archive-transaction.js +1180 -0
- package/dist/domains/comet-native/native-archive-transaction.js.map +1 -0
- package/dist/domains/comet-native/native-archive.d.ts +36 -0
- package/dist/domains/comet-native/native-archive.d.ts.map +1 -0
- package/dist/domains/comet-native/native-archive.js +403 -0
- package/dist/domains/comet-native/native-archive.js.map +1 -0
- package/dist/domains/comet-native/native-artifacts.d.ts +10 -0
- package/dist/domains/comet-native/native-artifacts.d.ts.map +1 -0
- package/dist/domains/comet-native/native-artifacts.js +204 -0
- package/dist/domains/comet-native/native-artifacts.js.map +1 -0
- package/dist/domains/comet-native/native-atomic-file.d.ts +10 -0
- package/dist/domains/comet-native/native-atomic-file.d.ts.map +1 -0
- package/dist/domains/comet-native/native-atomic-file.js +179 -0
- package/dist/domains/comet-native/native-atomic-file.js.map +1 -0
- package/dist/domains/comet-native/native-bounded-file.d.ts +19 -0
- package/dist/domains/comet-native/native-bounded-file.d.ts.map +1 -0
- package/dist/domains/comet-native/native-bounded-file.js +184 -0
- package/dist/domains/comet-native/native-bounded-file.js.map +1 -0
- package/dist/domains/comet-native/native-build-evidence.d.ts +42 -0
- package/dist/domains/comet-native/native-build-evidence.d.ts.map +1 -0
- package/dist/domains/comet-native/native-build-evidence.js +257 -0
- package/dist/domains/comet-native/native-build-evidence.js.map +1 -0
- package/dist/domains/comet-native/native-canonical-hash.d.ts +10 -0
- package/dist/domains/comet-native/native-canonical-hash.d.ts.map +1 -0
- package/dist/domains/comet-native/native-canonical-hash.js +100 -0
- package/dist/domains/comet-native/native-canonical-hash.js.map +1 -0
- package/dist/domains/comet-native/native-change-recovery.d.ts +11 -0
- package/dist/domains/comet-native/native-change-recovery.d.ts.map +1 -0
- package/dist/domains/comet-native/native-change-recovery.js +15 -0
- package/dist/domains/comet-native/native-change-recovery.js.map +1 -0
- package/dist/domains/comet-native/native-change.d.ts +61 -0
- package/dist/domains/comet-native/native-change.d.ts.map +1 -0
- package/dist/domains/comet-native/native-change.js +696 -0
- package/dist/domains/comet-native/native-change.js.map +1 -0
- package/dist/domains/comet-native/native-check-receipt-model.d.ts +63 -0
- package/dist/domains/comet-native/native-check-receipt-model.d.ts.map +1 -0
- package/dist/domains/comet-native/native-check-receipt-model.js +347 -0
- package/dist/domains/comet-native/native-check-receipt-model.js.map +1 -0
- package/dist/domains/comet-native/native-check-receipt-storage.d.ts +10 -0
- package/dist/domains/comet-native/native-check-receipt-storage.d.ts.map +1 -0
- package/dist/domains/comet-native/native-check-receipt-storage.js +200 -0
- package/dist/domains/comet-native/native-check-receipt-storage.js.map +1 -0
- package/dist/domains/comet-native/native-check-receipt.d.ts +19 -0
- package/dist/domains/comet-native/native-check-receipt.d.ts.map +1 -0
- package/dist/domains/comet-native/native-check-receipt.js +449 -0
- package/dist/domains/comet-native/native-check-receipt.js.map +1 -0
- package/dist/domains/comet-native/native-check.d.ts +18 -0
- package/dist/domains/comet-native/native-check.d.ts.map +1 -0
- package/dist/domains/comet-native/native-check.js +29 -0
- package/dist/domains/comet-native/native-check.js.map +1 -0
- package/dist/domains/comet-native/native-checkpoint-journal.d.ts +13 -0
- package/dist/domains/comet-native/native-checkpoint-journal.d.ts.map +1 -0
- package/dist/domains/comet-native/native-checkpoint-journal.js +53 -0
- package/dist/domains/comet-native/native-checkpoint-journal.js.map +1 -0
- package/dist/domains/comet-native/native-checkpoint-storage.d.ts +43 -0
- package/dist/domains/comet-native/native-checkpoint-storage.d.ts.map +1 -0
- package/dist/domains/comet-native/native-checkpoint-storage.js +487 -0
- package/dist/domains/comet-native/native-checkpoint-storage.js.map +1 -0
- package/dist/domains/comet-native/native-cli-entry.d.ts +2 -0
- package/dist/domains/comet-native/native-cli-entry.d.ts.map +1 -0
- package/dist/domains/comet-native/native-cli-entry.js +18 -0
- package/dist/domains/comet-native/native-cli-entry.js.map +1 -0
- package/dist/domains/comet-native/native-cli.d.ts +7 -0
- package/dist/domains/comet-native/native-cli.d.ts.map +1 -0
- package/dist/domains/comet-native/native-cli.js +642 -0
- package/dist/domains/comet-native/native-cli.js.map +1 -0
- package/dist/domains/comet-native/native-config.d.ts +15 -0
- package/dist/domains/comet-native/native-config.d.ts.map +1 -0
- package/dist/domains/comet-native/native-config.js +281 -0
- package/dist/domains/comet-native/native-config.js.map +1 -0
- package/dist/domains/comet-native/native-conflict-inspection.d.ts +17 -0
- package/dist/domains/comet-native/native-conflict-inspection.d.ts.map +1 -0
- package/dist/domains/comet-native/native-conflict-inspection.js +90 -0
- package/dist/domains/comet-native/native-conflict-inspection.js.map +1 -0
- package/dist/domains/comet-native/native-conflict-radar.d.ts +75 -0
- package/dist/domains/comet-native/native-conflict-radar.d.ts.map +1 -0
- package/dist/domains/comet-native/native-conflict-radar.js +326 -0
- package/dist/domains/comet-native/native-conflict-radar.js.map +1 -0
- package/dist/domains/comet-native/native-continuation.d.ts +9 -0
- package/dist/domains/comet-native/native-continuation.d.ts.map +1 -0
- package/dist/domains/comet-native/native-continuation.js +146 -0
- package/dist/domains/comet-native/native-continuation.js.map +1 -0
- package/dist/domains/comet-native/native-contract-files.d.ts +24 -0
- package/dist/domains/comet-native/native-contract-files.d.ts.map +1 -0
- package/dist/domains/comet-native/native-contract-files.js +66 -0
- package/dist/domains/comet-native/native-contract-files.js.map +1 -0
- package/dist/domains/comet-native/native-contract.d.ts +41 -0
- package/dist/domains/comet-native/native-contract.d.ts.map +1 -0
- package/dist/domains/comet-native/native-contract.js +141 -0
- package/dist/domains/comet-native/native-contract.js.map +1 -0
- package/dist/domains/comet-native/native-diagnostics.d.ts +18 -0
- package/dist/domains/comet-native/native-diagnostics.d.ts.map +1 -0
- package/dist/domains/comet-native/native-diagnostics.js +522 -0
- package/dist/domains/comet-native/native-diagnostics.js.map +1 -0
- package/dist/domains/comet-native/native-doctor.d.ts +12 -0
- package/dist/domains/comet-native/native-doctor.d.ts.map +1 -0
- package/dist/domains/comet-native/native-doctor.js +768 -0
- package/dist/domains/comet-native/native-doctor.js.map +1 -0
- package/dist/domains/comet-native/native-evidence-retention.d.ts +37 -0
- package/dist/domains/comet-native/native-evidence-retention.d.ts.map +1 -0
- package/dist/domains/comet-native/native-evidence-retention.js +887 -0
- package/dist/domains/comet-native/native-evidence-retention.js.map +1 -0
- package/dist/domains/comet-native/native-evidence-storage.d.ts +41 -0
- package/dist/domains/comet-native/native-evidence-storage.d.ts.map +1 -0
- package/dist/domains/comet-native/native-evidence-storage.js +355 -0
- package/dist/domains/comet-native/native-evidence-storage.js.map +1 -0
- package/dist/domains/comet-native/native-file-identity.d.ts +9 -0
- package/dist/domains/comet-native/native-file-identity.d.ts.map +1 -0
- package/dist/domains/comet-native/native-file-identity.js +21 -0
- package/dist/domains/comet-native/native-file-identity.js.map +1 -0
- package/dist/domains/comet-native/native-findings.d.ts +8 -0
- package/dist/domains/comet-native/native-findings.d.ts.map +1 -0
- package/dist/domains/comet-native/native-findings.js +238 -0
- package/dist/domains/comet-native/native-findings.js.map +1 -0
- package/dist/domains/comet-native/native-guards.d.ts +7 -0
- package/dist/domains/comet-native/native-guards.d.ts.map +1 -0
- package/dist/domains/comet-native/native-guards.js +126 -0
- package/dist/domains/comet-native/native-guards.js.map +1 -0
- package/dist/domains/comet-native/native-hash.d.ts +3 -0
- package/dist/domains/comet-native/native-hash.d.ts.map +1 -0
- package/dist/domains/comet-native/native-hash.js +12 -0
- package/dist/domains/comet-native/native-hash.js.map +1 -0
- package/dist/domains/comet-native/native-hook-guard.d.ts +17 -0
- package/dist/domains/comet-native/native-hook-guard.d.ts.map +1 -0
- package/dist/domains/comet-native/native-hook-guard.js +154 -0
- package/dist/domains/comet-native/native-hook-guard.js.map +1 -0
- package/dist/domains/comet-native/native-lock.d.ts +47 -0
- package/dist/domains/comet-native/native-lock.d.ts.map +1 -0
- package/dist/domains/comet-native/native-lock.js +398 -0
- package/dist/domains/comet-native/native-lock.js.map +1 -0
- package/dist/domains/comet-native/native-mutation-lock.d.ts +5 -0
- package/dist/domains/comet-native/native-mutation-lock.d.ts.map +1 -0
- package/dist/domains/comet-native/native-mutation-lock.js +66 -0
- package/dist/domains/comet-native/native-mutation-lock.js.map +1 -0
- package/dist/domains/comet-native/native-paths.d.ts +10 -0
- package/dist/domains/comet-native/native-paths.d.ts.map +1 -0
- package/dist/domains/comet-native/native-paths.js +171 -0
- package/dist/domains/comet-native/native-paths.js.map +1 -0
- package/dist/domains/comet-native/native-progress-checkpoint.d.ts +13 -0
- package/dist/domains/comet-native/native-progress-checkpoint.d.ts.map +1 -0
- package/dist/domains/comet-native/native-progress-checkpoint.js +104 -0
- package/dist/domains/comet-native/native-progress-checkpoint.js.map +1 -0
- package/dist/domains/comet-native/native-protected-file.d.ts +113 -0
- package/dist/domains/comet-native/native-protected-file.d.ts.map +1 -0
- package/dist/domains/comet-native/native-protected-file.js +510 -0
- package/dist/domains/comet-native/native-protected-file.js.map +1 -0
- package/dist/domains/comet-native/native-redaction.d.ts +2 -0
- package/dist/domains/comet-native/native-redaction.d.ts.map +1 -0
- package/dist/domains/comet-native/native-redaction.js +18 -0
- package/dist/domains/comet-native/native-redaction.js.map +1 -0
- package/dist/domains/comet-native/native-repair-integration.d.ts +42 -0
- package/dist/domains/comet-native/native-repair-integration.d.ts.map +1 -0
- package/dist/domains/comet-native/native-repair-integration.js +184 -0
- package/dist/domains/comet-native/native-repair-integration.js.map +1 -0
- package/dist/domains/comet-native/native-repair-runtime.d.ts +73 -0
- package/dist/domains/comet-native/native-repair-runtime.d.ts.map +1 -0
- package/dist/domains/comet-native/native-repair-runtime.js +509 -0
- package/dist/domains/comet-native/native-repair-runtime.js.map +1 -0
- package/dist/domains/comet-native/native-repair-stagnation.d.ts +85 -0
- package/dist/domains/comet-native/native-repair-stagnation.d.ts.map +1 -0
- package/dist/domains/comet-native/native-repair-stagnation.js +256 -0
- package/dist/domains/comet-native/native-repair-stagnation.js.map +1 -0
- package/dist/domains/comet-native/native-resume-view.d.ts +14 -0
- package/dist/domains/comet-native/native-resume-view.d.ts.map +1 -0
- package/dist/domains/comet-native/native-resume-view.js +105 -0
- package/dist/domains/comet-native/native-resume-view.js.map +1 -0
- package/dist/domains/comet-native/native-revision.d.ts +20 -0
- package/dist/domains/comet-native/native-revision.d.ts.map +1 -0
- package/dist/domains/comet-native/native-revision.js +32 -0
- package/dist/domains/comet-native/native-revision.js.map +1 -0
- package/dist/domains/comet-native/native-root-move.d.ts +20 -0
- package/dist/domains/comet-native/native-root-move.d.ts.map +1 -0
- package/dist/domains/comet-native/native-root-move.js +812 -0
- package/dist/domains/comet-native/native-root-move.js.map +1 -0
- package/dist/domains/comet-native/native-run-consistency.d.ts +3 -0
- package/dist/domains/comet-native/native-run-consistency.d.ts.map +1 -0
- package/dist/domains/comet-native/native-run-consistency.js +136 -0
- package/dist/domains/comet-native/native-run-consistency.js.map +1 -0
- package/dist/domains/comet-native/native-run-store.d.ts +41 -0
- package/dist/domains/comet-native/native-run-store.d.ts.map +1 -0
- package/dist/domains/comet-native/native-run-store.js +452 -0
- package/dist/domains/comet-native/native-run-store.js.map +1 -0
- package/dist/domains/comet-native/native-runtime-package.d.ts +16 -0
- package/dist/domains/comet-native/native-runtime-package.d.ts.map +1 -0
- package/dist/domains/comet-native/native-runtime-package.js +72 -0
- package/dist/domains/comet-native/native-runtime-package.js.map +1 -0
- package/dist/domains/comet-native/native-schema-migration.d.ts +11 -0
- package/dist/domains/comet-native/native-schema-migration.d.ts.map +1 -0
- package/dist/domains/comet-native/native-schema-migration.js +899 -0
- package/dist/domains/comet-native/native-schema-migration.js.map +1 -0
- package/dist/domains/comet-native/native-selection.d.ts +12 -0
- package/dist/domains/comet-native/native-selection.d.ts.map +1 -0
- package/dist/domains/comet-native/native-selection.js +52 -0
- package/dist/domains/comet-native/native-selection.js.map +1 -0
- package/dist/domains/comet-native/native-sensitive-paths.d.ts +7 -0
- package/dist/domains/comet-native/native-sensitive-paths.d.ts.map +1 -0
- package/dist/domains/comet-native/native-sensitive-paths.js +69 -0
- package/dist/domains/comet-native/native-sensitive-paths.js.map +1 -0
- package/dist/domains/comet-native/native-snapshot.d.ts +74 -0
- package/dist/domains/comet-native/native-snapshot.d.ts.map +1 -0
- package/dist/domains/comet-native/native-snapshot.js +2312 -0
- package/dist/domains/comet-native/native-snapshot.js.map +1 -0
- package/dist/domains/comet-native/native-specs.d.ts +12 -0
- package/dist/domains/comet-native/native-specs.d.ts.map +1 -0
- package/dist/domains/comet-native/native-specs.js +270 -0
- package/dist/domains/comet-native/native-specs.js.map +1 -0
- package/dist/domains/comet-native/native-trajectory-limits.d.ts +7 -0
- package/dist/domains/comet-native/native-trajectory-limits.d.ts.map +1 -0
- package/dist/domains/comet-native/native-trajectory-limits.js +13 -0
- package/dist/domains/comet-native/native-trajectory-limits.js.map +1 -0
- package/dist/domains/comet-native/native-trajectory-recovery.d.ts +37 -0
- package/dist/domains/comet-native/native-trajectory-recovery.d.ts.map +1 -0
- package/dist/domains/comet-native/native-trajectory-recovery.js +133 -0
- package/dist/domains/comet-native/native-trajectory-recovery.js.map +1 -0
- package/dist/domains/comet-native/native-trajectory.d.ts +16 -0
- package/dist/domains/comet-native/native-trajectory.d.ts.map +1 -0
- package/dist/domains/comet-native/native-trajectory.js +27 -0
- package/dist/domains/comet-native/native-trajectory.js.map +1 -0
- package/dist/domains/comet-native/native-transaction.d.ts +45 -0
- package/dist/domains/comet-native/native-transaction.d.ts.map +1 -0
- package/dist/domains/comet-native/native-transaction.js +846 -0
- package/dist/domains/comet-native/native-transaction.js.map +1 -0
- package/dist/domains/comet-native/native-transition-evidence.d.ts +4 -0
- package/dist/domains/comet-native/native-transition-evidence.d.ts.map +1 -0
- package/dist/domains/comet-native/native-transition-evidence.js +20 -0
- package/dist/domains/comet-native/native-transition-evidence.js.map +1 -0
- package/dist/domains/comet-native/native-transition-journal.d.ts +30 -0
- package/dist/domains/comet-native/native-transition-journal.d.ts.map +1 -0
- package/dist/domains/comet-native/native-transition-journal.js +819 -0
- package/dist/domains/comet-native/native-transition-journal.js.map +1 -0
- package/dist/domains/comet-native/native-transitions.d.ts +13 -0
- package/dist/domains/comet-native/native-transitions.d.ts.map +1 -0
- package/dist/domains/comet-native/native-transitions.js +632 -0
- package/dist/domains/comet-native/native-transitions.js.map +1 -0
- package/dist/domains/comet-native/native-types.d.ts +547 -0
- package/dist/domains/comet-native/native-types.d.ts.map +1 -0
- package/dist/domains/comet-native/native-types.js +8 -0
- package/dist/domains/comet-native/native-types.js.map +1 -0
- package/dist/domains/comet-native/native-verification-evidence.d.ts +86 -0
- package/dist/domains/comet-native/native-verification-evidence.d.ts.map +1 -0
- package/dist/domains/comet-native/native-verification-evidence.js +480 -0
- package/dist/domains/comet-native/native-verification-evidence.js.map +1 -0
- package/dist/domains/comet-native/native-verification-runtime.d.ts +58 -0
- package/dist/domains/comet-native/native-verification-runtime.d.ts.map +1 -0
- package/dist/domains/comet-native/native-verification-runtime.js +321 -0
- package/dist/domains/comet-native/native-verification-runtime.js.map +1 -0
- package/dist/domains/comet-native/native-verification-scope.d.ts +117 -0
- package/dist/domains/comet-native/native-verification-scope.d.ts.map +1 -0
- package/dist/domains/comet-native/native-verification-scope.js +1040 -0
- package/dist/domains/comet-native/native-verification-scope.js.map +1 -0
- package/dist/domains/comet-native/native-workspace.d.ts +46 -0
- package/dist/domains/comet-native/native-workspace.d.ts.map +1 -0
- package/dist/domains/comet-native/native-workspace.js +276 -0
- package/dist/domains/comet-native/native-workspace.js.map +1 -0
- package/dist/domains/dashboard/collector.d.ts.map +1 -1
- package/dist/domains/dashboard/collector.js +9 -1
- package/dist/domains/dashboard/collector.js.map +1 -1
- package/dist/domains/dashboard/native-adapter.d.ts +157 -0
- package/dist/domains/dashboard/native-adapter.d.ts.map +1 -0
- package/dist/domains/dashboard/native-adapter.js +302 -0
- package/dist/domains/dashboard/native-adapter.js.map +1 -0
- package/dist/domains/dashboard/native-collector.d.ts +6 -0
- package/dist/domains/dashboard/native-collector.d.ts.map +1 -0
- package/dist/domains/dashboard/native-collector.js +285 -0
- package/dist/domains/dashboard/native-collector.js.map +1 -0
- package/dist/domains/dashboard/types.d.ts +5 -0
- package/dist/domains/dashboard/types.d.ts.map +1 -1
- package/dist/domains/dashboard/web/assets/{arc-TGVUG2WN.js → arc-CxdiLJ50.js} +1 -1
- package/dist/domains/dashboard/web/assets/{architectureDiagram-3BPJPVTR-ASHmiHoP.js → architectureDiagram-3BPJPVTR-D5YCQu4e.js} +1 -1
- package/dist/domains/dashboard/web/assets/{blockDiagram-GPEHLZMM-CwASxBKe.js → blockDiagram-GPEHLZMM-8NfdCOQ8.js} +1 -1
- package/dist/domains/dashboard/web/assets/{c4Diagram-AAUBKEIU-BU8z_WNk.js → c4Diagram-AAUBKEIU-B3cFnNT7.js} +1 -1
- package/dist/domains/dashboard/web/assets/channel-B6AFly29.js +1 -0
- package/dist/domains/dashboard/web/assets/{chunk-2J33WTMH-CBGlUx4_.js → chunk-2J33WTMH-CBNfW-Dr.js} +1 -1
- package/dist/domains/dashboard/web/assets/{chunk-4BX2VUAB-CS-iGcFz.js → chunk-4BX2VUAB-vWyemRBr.js} +1 -1
- package/dist/domains/dashboard/web/assets/{chunk-55IACEB6-BUtCVJat.js → chunk-55IACEB6-H6haOo2C.js} +1 -1
- package/dist/domains/dashboard/web/assets/{chunk-727SXJPM-C94tj_pf.js → chunk-727SXJPM-D02UjGND.js} +1 -1
- package/dist/domains/dashboard/web/assets/{chunk-AQP2D5EJ-BFOKcpdG.js → chunk-AQP2D5EJ-wKsbOw_T.js} +1 -1
- package/dist/domains/dashboard/web/assets/{chunk-FMBD7UC4-Dmx8B-st.js → chunk-FMBD7UC4-eYFEZimP.js} +1 -1
- package/dist/domains/dashboard/web/assets/{chunk-ND2GUHAM-DYV00CNn.js → chunk-ND2GUHAM-fMaIDDI2.js} +1 -1
- package/dist/domains/dashboard/web/assets/{chunk-QZHKN3VN-DMJJyQnw.js → chunk-QZHKN3VN-C9rhF6Hm.js} +1 -1
- package/dist/domains/dashboard/web/assets/classDiagram-4FO5ZUOK-BcnrxOTt.js +1 -0
- package/dist/domains/dashboard/web/assets/classDiagram-v2-Q7XG4LA2-BcnrxOTt.js +1 -0
- package/dist/domains/dashboard/web/assets/{cose-bilkent-S5V4N54A-P4nE2rea.js → cose-bilkent-S5V4N54A-CbaShPub.js} +1 -1
- package/dist/domains/dashboard/web/assets/{cynefin-VYW2F7L2-C-R1HXDv.js → cynefin-VYW2F7L2-DN4emAQv.js} +1 -1
- package/dist/domains/dashboard/web/assets/{dagre-BM42HDAG-BH8d-C9z.js → dagre-BM42HDAG-BpSzbk_V.js} +1 -1
- package/dist/domains/dashboard/web/assets/demo-BuVau32v.js +25 -0
- package/dist/domains/dashboard/web/assets/{diagram-2AECGRRQ-DpXTgQIH.js → diagram-2AECGRRQ-CfXwGGpQ.js} +1 -1
- package/dist/domains/dashboard/web/assets/{diagram-5GNKFQAL-DSiFJzSw.js → diagram-5GNKFQAL-DMp0Zmot.js} +1 -1
- package/dist/domains/dashboard/web/assets/{diagram-KO2AKTUF-DULMkben.js → diagram-KO2AKTUF-C7ZvofsM.js} +1 -1
- package/dist/domains/dashboard/web/assets/{diagram-LMA3HP47-Pi8m_NO9.js → diagram-LMA3HP47-BjmxFnap.js} +1 -1
- package/dist/domains/dashboard/web/assets/{diagram-OG6HWLK6-BSe6bCWm.js → diagram-OG6HWLK6-DFBG1Iqy.js} +1 -1
- package/dist/domains/dashboard/web/assets/{erDiagram-TEJ5UH35-zb-FEcbq.js → erDiagram-TEJ5UH35-MpNT7dzt.js} +1 -1
- package/dist/domains/dashboard/web/assets/{flowDiagram-I6XJVG4X-Dr-Gk0z2.js → flowDiagram-I6XJVG4X-_1wAR6c1.js} +1 -1
- package/dist/domains/dashboard/web/assets/{ganttDiagram-6RSMTGT7-qs6Zb2A6.js → ganttDiagram-6RSMTGT7-DJKjDeWl.js} +1 -1
- package/dist/domains/dashboard/web/assets/{gitGraphDiagram-PVQCEYII-BQ314orT.js → gitGraphDiagram-PVQCEYII-BL7yUEn-.js} +1 -1
- package/dist/domains/dashboard/web/assets/index-CjE9mHGb.js +24 -0
- package/dist/domains/dashboard/web/assets/index-D-AGxvI4.css +1 -0
- package/dist/domains/dashboard/web/assets/{infoDiagram-5YYISTIA-O0bQp98A.js → infoDiagram-5YYISTIA-Bt5fqrOd.js} +1 -1
- package/dist/domains/dashboard/web/assets/{ishikawaDiagram-YF4QCWOH-BPC7wbKh.js → ishikawaDiagram-YF4QCWOH-COCMcjBM.js} +1 -1
- package/dist/domains/dashboard/web/assets/{journeyDiagram-JHISSGLW-ohViOd4b.js → journeyDiagram-JHISSGLW-DGcpcWny.js} +1 -1
- package/dist/domains/dashboard/web/assets/{kanban-definition-UN3LZRKU-CHleNdbG.js → kanban-definition-UN3LZRKU-QSBNsWMP.js} +1 -1
- package/dist/domains/dashboard/web/assets/{linear-CyqiW--Q.js → linear-9uyeeBZf.js} +1 -1
- package/dist/domains/dashboard/web/assets/{mermaid.core-qS9XvtaK.js → mermaid.core-CkNdB471.js} +4 -4
- package/dist/domains/dashboard/web/assets/{mindmap-definition-RKZ34NQL-oaGkqO9l.js → mindmap-definition-RKZ34NQL-CiNxI0gP.js} +1 -1
- package/dist/domains/dashboard/web/assets/{pieDiagram-4H26LBE5-CPcB-AFh.js → pieDiagram-4H26LBE5-BLJ6QnRO.js} +1 -1
- package/dist/domains/dashboard/web/assets/{quadrantDiagram-W4KKPZXB-LFy52Qtj.js → quadrantDiagram-W4KKPZXB-CflW-eFH.js} +1 -1
- package/dist/domains/dashboard/web/assets/{requirementDiagram-4Y6WPE33-BdjeaYP_.js → requirementDiagram-4Y6WPE33-B9HLmRWH.js} +1 -1
- package/dist/domains/dashboard/web/assets/{sankeyDiagram-5OEKKPKP-DDJ4styL.js → sankeyDiagram-5OEKKPKP-6xnco5k5.js} +1 -1
- package/dist/domains/dashboard/web/assets/{sequenceDiagram-3UESZ5HK-BL5bFNoz.js → sequenceDiagram-3UESZ5HK-Dp1rujNZ.js} +1 -1
- package/dist/domains/dashboard/web/assets/{stateDiagram-AJRCARHV-BNUfikui.js → stateDiagram-AJRCARHV-C1Xc90ek.js} +1 -1
- package/dist/domains/dashboard/web/assets/stateDiagram-v2-BHNVJYJU-p-qmzXyE.js +1 -0
- package/dist/domains/dashboard/web/assets/{timeline-definition-PNZ67QCA--ps2uu6L.js → timeline-definition-PNZ67QCA-g9s-m5Z4.js} +1 -1
- package/dist/domains/dashboard/web/assets/{vennDiagram-CIIHVFJN-C2q8q26c.js → vennDiagram-CIIHVFJN-rkEyhyCc.js} +1 -1
- package/dist/domains/dashboard/web/assets/{wardleyDiagram-YWT4CUSO-BUH9gXqd.js → wardleyDiagram-YWT4CUSO-CJLrWGXc.js} +1 -1
- package/dist/domains/dashboard/web/assets/{xychartDiagram-2RQKCTM6-B-DielEy.js → xychartDiagram-2RQKCTM6-BxJvPNqo.js} +1 -1
- package/dist/domains/dashboard/web/index.html +16 -16
- package/dist/domains/engine/storage-layout.d.ts +14 -0
- package/dist/domains/engine/storage-layout.d.ts.map +1 -0
- package/dist/domains/engine/storage-layout.js +32 -0
- package/dist/domains/engine/storage-layout.js.map +1 -0
- package/dist/domains/engine/storage-run.d.ts +9 -0
- package/dist/domains/engine/storage-run.d.ts.map +1 -0
- package/dist/domains/engine/storage-run.js +116 -0
- package/dist/domains/engine/storage-run.js.map +1 -0
- package/dist/domains/factory/package.d.ts.map +1 -1
- package/dist/domains/factory/package.js +5 -3
- package/dist/domains/factory/package.js.map +1 -1
- package/dist/domains/integrations/openspec.d.ts.map +1 -1
- package/dist/domains/integrations/openspec.js +8 -6
- package/dist/domains/integrations/openspec.js.map +1 -1
- package/dist/domains/skill/platform-inspect.d.ts +6 -2
- package/dist/domains/skill/platform-inspect.d.ts.map +1 -1
- package/dist/domains/skill/platform-inspect.js +52 -8
- package/dist/domains/skill/platform-inspect.js.map +1 -1
- package/dist/domains/skill/platform-install.d.ts +18 -7
- package/dist/domains/skill/platform-install.d.ts.map +1 -1
- package/dist/domains/skill/platform-install.js +338 -71
- package/dist/domains/skill/platform-install.js.map +1 -1
- package/dist/domains/skill/project-instructions.d.ts.map +1 -1
- package/dist/domains/skill/project-instructions.js +12 -6
- package/dist/domains/skill/project-instructions.js.map +1 -1
- package/dist/domains/skill/uninstall.d.ts.map +1 -1
- package/dist/domains/skill/uninstall.js +15 -3
- package/dist/domains/skill/uninstall.js.map +1 -1
- package/dist/domains/workflow-contract/builtins.d.ts +6 -0
- package/dist/domains/workflow-contract/builtins.d.ts.map +1 -1
- package/dist/domains/workflow-contract/builtins.js +137 -0
- package/dist/domains/workflow-contract/builtins.js.map +1 -1
- package/dist/domains/workflow-contract/index.d.ts +3 -1
- package/dist/domains/workflow-contract/index.d.ts.map +1 -1
- package/dist/domains/workflow-contract/index.js +2 -1
- package/dist/domains/workflow-contract/index.js.map +1 -1
- package/dist/domains/workflow-contract/normalize.d.ts.map +1 -1
- package/dist/domains/workflow-contract/normalize.js +28 -10
- package/dist/domains/workflow-contract/normalize.js.map +1 -1
- package/dist/domains/workflow-contract/project-config.d.ts +7 -0
- package/dist/domains/workflow-contract/project-config.d.ts.map +1 -0
- package/dist/domains/workflow-contract/project-config.js +110 -0
- package/dist/domains/workflow-contract/project-config.js.map +1 -0
- package/dist/domains/workflow-contract/types.d.ts +4 -2
- package/dist/domains/workflow-contract/types.d.ts.map +1 -1
- package/dist/domains/workflow-contract/validation.d.ts.map +1 -1
- package/dist/domains/workflow-contract/validation.js +14 -5
- package/dist/domains/workflow-contract/validation.js.map +1 -1
- package/dist/platform/install/detect.d.ts +3 -1
- package/dist/platform/install/detect.d.ts.map +1 -1
- package/dist/platform/install/detect.js +4 -1
- package/dist/platform/install/detect.js.map +1 -1
- package/dist/platform/install/project-registry.js +2 -2
- package/dist/platform/install/project-registry.js.map +1 -1
- package/dist/platform/paths/repository-layout.d.ts +16 -0
- package/dist/platform/paths/repository-layout.d.ts.map +1 -1
- package/dist/platform/paths/repository-layout.js.map +1 -1
- package/eval/local/README.md +50 -0
- package/eval/local/scripts/compare_baselines.py +127 -1
- package/eval/local/scripts/regression_check.py +3 -4
- package/eval/local/tasks/comet-native-clarification/environment/Dockerfile +27 -0
- package/eval/local/tasks/comet-native-clarification/environment/test_wordcount.py +25 -0
- package/eval/local/tasks/comet-native-clarification/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-clarification/instruction.md +7 -0
- package/eval/local/tasks/comet-native-clarification/task.toml +40 -0
- package/eval/local/tasks/comet-native-clarification/validation/test_native_clarification.py +193 -0
- package/eval/local/tasks/comet-native-clarification-modes/environment/Dockerfile +27 -0
- package/eval/local/tasks/comet-native-clarification-modes/environment/test_wordcount.py +25 -0
- package/eval/local/tasks/comet-native-clarification-modes/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-clarification-modes/instruction.md +13 -0
- package/eval/local/tasks/comet-native-clarification-modes/task.toml +39 -0
- package/eval/local/tasks/comet-native-clarification-modes/validation/test_native_clarification_modes.py +235 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/.comet/config.yaml +6 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/Dockerfile +28 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/docs/comet/changes/add-character-counting/brief.md +17 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/docs/comet/changes/add-character-counting/comet-state.yaml +12 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/docs/comet/changes/add-character-counting/runtime/transition.json +69 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/docs/comet/changes/add-character-counting/specs/character-counting/spec.md +3 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/test_wordcount.py +20 -0
- package/eval/local/tasks/comet-native-interrupted-transition/environment/wordcount.py +27 -0
- package/eval/local/tasks/comet-native-interrupted-transition/instruction.md +7 -0
- package/eval/local/tasks/comet-native-interrupted-transition/task.toml +35 -0
- package/eval/local/tasks/comet-native-interrupted-transition/validation/test_native_interrupted_transition.py +63 -0
- package/eval/local/tasks/comet-native-repository-fact/environment/Dockerfile +26 -0
- package/eval/local/tasks/comet-native-repository-fact/environment/PRODUCT_RULES.md +3 -0
- package/eval/local/tasks/comet-native-repository-fact/environment/test_wordcount.py +20 -0
- package/eval/local/tasks/comet-native-repository-fact/environment/wordcount.py +27 -0
- package/eval/local/tasks/comet-native-repository-fact/instruction.md +7 -0
- package/eval/local/tasks/comet-native-repository-fact/task.toml +35 -0
- package/eval/local/tasks/comet-native-repository-fact/validation/test_native_repository_fact.py +53 -0
- package/eval/local/tasks/comet-native-wave-b-decision-resume/environment/Dockerfile +27 -0
- package/eval/local/tasks/comet-native-wave-b-decision-resume/environment/test_wordcount.py +27 -0
- package/eval/local/tasks/comet-native-wave-b-decision-resume/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-wave-b-decision-resume/instruction.md +9 -0
- package/eval/local/tasks/comet-native-wave-b-decision-resume/task.toml +40 -0
- package/eval/local/tasks/comet-native-wave-b-decision-resume/validation/test_native_wave_b_decision_resume.py +208 -0
- package/eval/local/tasks/comet-native-wave-c-verification-integrity/environment/Dockerfile +27 -0
- package/eval/local/tasks/comet-native-wave-c-verification-integrity/environment/test_wordcount.py +27 -0
- package/eval/local/tasks/comet-native-wave-c-verification-integrity/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-wave-c-verification-integrity/instruction.md +11 -0
- package/eval/local/tasks/comet-native-wave-c-verification-integrity/task.toml +36 -0
- package/eval/local/tasks/comet-native-wave-c-verification-integrity/validation/test_native_wave_c_verification_integrity.py +344 -0
- package/eval/local/tasks/comet-native-wave-d-stagnation-stop/environment/Dockerfile +27 -0
- package/eval/local/tasks/comet-native-wave-d-stagnation-stop/environment/test_wordcount.py +27 -0
- package/eval/local/tasks/comet-native-wave-d-stagnation-stop/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-wave-d-stagnation-stop/instruction.md +11 -0
- package/eval/local/tasks/comet-native-wave-d-stagnation-stop/task.toml +37 -0
- package/eval/local/tasks/comet-native-wave-d-stagnation-stop/validation/test_native_wave_d_stagnation_stop.py +284 -0
- package/eval/local/tasks/comet-native-wave-e-parallel-safety/environment/.include-trusted-native-runtime +1 -0
- package/eval/local/tasks/comet-native-wave-e-parallel-safety/environment/Dockerfile +27 -0
- package/eval/local/tasks/comet-native-wave-e-parallel-safety/environment/test_wordcount.py +27 -0
- package/eval/local/tasks/comet-native-wave-e-parallel-safety/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-wave-e-parallel-safety/instruction.md +9 -0
- package/eval/local/tasks/comet-native-wave-e-parallel-safety/task.toml +37 -0
- package/eval/local/tasks/comet-native-wave-e-parallel-safety/validation/test_native_wave_e_parallel_safety.py +309 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/.include-current-comet-cli +1 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/Dockerfile +31 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/current-comet-package.json +18 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/current-comet.sh +14 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/test_wordcount.py +27 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/instruction.md +7 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/task.toml +36 -0
- package/eval/local/tasks/comet-native-wave-f-dashboard-readonly/validation/test_native_wave_f_dashboard_readonly.py +469 -0
- package/eval/local/tasks/comet-native-workflow/environment/Dockerfile +27 -0
- package/eval/local/tasks/comet-native-workflow/environment/test_wordcount.py +25 -0
- package/eval/local/tasks/comet-native-workflow/environment/wordcount.py +36 -0
- package/eval/local/tasks/comet-native-workflow/instruction.md +14 -0
- package/eval/local/tasks/comet-native-workflow/task.toml +36 -0
- package/eval/local/tasks/comet-native-workflow/validation/test_native_workflow.py +149 -0
- package/eval/local/tasks/index.yaml +61 -0
- package/eval/local/tests/conftest.py +407 -22
- package/eval/local/tests/scaffold/test_aligned_comparison.py +1012 -0
- package/eval/local/tests/scaffold/test_conftest_helpers.py +187 -7
- package/eval/local/tests/scaffold/test_logging.py +135 -1
- package/eval/local/tests/scaffold/test_manifests.py +2 -0
- package/eval/local/tests/scaffold/test_native_aligned_eval.py +346 -0
- package/eval/local/tests/scaffold/test_native_wave_evaluations.py +1889 -0
- package/eval/local/tests/scaffold/test_profiles.py +33 -0
- package/eval/local/tests/scaffold/test_sample_quality.py +57 -0
- package/eval/local/tests/scaffold/test_tasks.py +377 -1
- package/eval/local/tests/scaffold/test_treatments.py +59 -13
- package/eval/local/tests/scaffold/test_utils.py +277 -4
- package/eval/local/tests/tasks/__init__.py +1 -0
- package/eval/local/tests/tasks/test_tasks.py +104 -78
- package/eval/local/tests/tasks/test_validation_scripts.py +37 -0
- package/eval/local/treatments/comet/comet_native_phase1.yaml +66 -0
- package/eval/pyproject.toml +4 -4
- package/eval/scaffold/python/aligned_comparison.py +1631 -0
- package/eval/scaffold/python/generic_llm_judge.py +3 -1
- package/eval/scaffold/python/llm_judge.py +0 -3
- package/eval/scaffold/python/logging.py +115 -16
- package/eval/scaffold/python/manifests.py +2 -0
- package/eval/scaffold/python/native_eval.py +138 -0
- package/eval/scaffold/python/pass_at_k.py +0 -1
- package/eval/scaffold/python/report_outputs.py +226 -44
- package/eval/scaffold/python/sample_quality.py +45 -2
- package/eval/scaffold/python/tasks.py +11 -0
- package/eval/scaffold/python/utils.py +108 -20
- package/eval/scaffold/python/validation/__init__.py +15 -5
- package/eval/scaffold/python/validation/comet_workflow.py +10 -5
- package/eval/scaffold/python/validation/generic_rubric.py +1 -2
- package/eval/scaffold/python/validation/native_wave.py +2154 -0
- package/eval/scaffold/python/validation/native_workflow.py +252 -0
- package/eval/scaffold/python/validation/rubric.py +0 -2
- package/eval/scaffold/shell/completion-point.sh +18 -0
- package/eval/scaffold/shell/decision-point.sh +35 -0
- package/eval/scaffold/shell/docker.sh +150 -9
- package/eval/scaffold/shell/run-claude-loop.sh +57 -27
- package/package.json +26 -5
- package/dist/domains/dashboard/web/assets/channel-kp6Ng2JJ.js +0 -1
- package/dist/domains/dashboard/web/assets/classDiagram-4FO5ZUOK-yBDjgMY_.js +0 -1
- package/dist/domains/dashboard/web/assets/classDiagram-v2-Q7XG4LA2-yBDjgMY_.js +0 -1
- package/dist/domains/dashboard/web/assets/demo-DQyfozbi.js +0 -1
- package/dist/domains/dashboard/web/assets/index-BLAfkNTu.css +0 -1
- package/dist/domains/dashboard/web/assets/index-DtLUOcAW.js +0 -24
- package/dist/domains/dashboard/web/assets/stateDiagram-v2-BHNVJYJU-DGrsmWts.js +0 -1
- package/eval/.env.example +0 -52
- package/eval/langsmith/.env.example +0 -16
|
@@ -0,0 +1,887 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { constants as fsConstants, promises as fs } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { parseNativeCheckReceipt } from './native-check-receipt-model.js';
|
|
5
|
+
import { nativeChangeDir, inspectNativeChange } from './native-change.js';
|
|
6
|
+
import { readNativeCheckpointJournal } from './native-checkpoint-storage.js';
|
|
7
|
+
import { readProjectConfig } from './native-config.js';
|
|
8
|
+
import { MAX_NATIVE_EVIDENCE_DOCUMENT_BYTES, nativeEvidenceRef, nativeReportEvidenceRef, } from './native-evidence-storage.js';
|
|
9
|
+
import { withNativeMutationLock } from './native-mutation-lock.js';
|
|
10
|
+
import { isInsidePath, resolveContainedNativePath } from './native-paths.js';
|
|
11
|
+
import { inspectPendingNativeSchemaMigration } from './native-schema-migration.js';
|
|
12
|
+
import { inspectPendingNativeTransition } from './native-transition-journal.js';
|
|
13
|
+
import { readNativeTransaction } from './native-transaction.js';
|
|
14
|
+
import { sameNativeFileObject } from './native-file-identity.js';
|
|
15
|
+
import { parseNativeImplementationScope, parseNativeSnapshotProjection, } from './native-verification-scope.js';
|
|
16
|
+
import { parseNativePartialAllowance, parseNativeVerificationEvidenceEnvelope, } from './native-verification-evidence.js';
|
|
17
|
+
export const NATIVE_EVIDENCE_RETENTION_POLICY = Object.freeze({
|
|
18
|
+
minimumAgeMs: 30 * 24 * 60 * 60 * 1_000,
|
|
19
|
+
keepLatestUnreferencedPerKind: 32,
|
|
20
|
+
maxDocuments: 4_096,
|
|
21
|
+
maxScannedBytes: 256 * 1024 * 1024,
|
|
22
|
+
maxReportedRefs: 8,
|
|
23
|
+
maxReportMessageBytes: 4_096,
|
|
24
|
+
});
|
|
25
|
+
const MAX_NATIVE_CHECK_RECEIPT_BYTES = 512 * 1024;
|
|
26
|
+
const HASH_FILE_PATTERN = /^([a-f0-9]{64})\.json$/u;
|
|
27
|
+
const CLEANUP_QUARANTINE_PATTERN = /^\.([a-f0-9]{64}\.json)\.([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})\.gc$/u;
|
|
28
|
+
const MANAGED_REF_PATTERN = /^runtime\/evidence\/(snapshots|scopes|allowances|verifications|reports|check-receipts)\/[a-f0-9]{64}\.json$/u;
|
|
29
|
+
const MANAGED_KINDS = [
|
|
30
|
+
'snapshots',
|
|
31
|
+
'scopes',
|
|
32
|
+
'allowances',
|
|
33
|
+
'verifications',
|
|
34
|
+
'reports',
|
|
35
|
+
'check-receipts',
|
|
36
|
+
];
|
|
37
|
+
function sameObjectIdentity(left, right) {
|
|
38
|
+
return sameNativeFileObject({ ...left, birthtime: left.birthtimeMs }, {
|
|
39
|
+
...right,
|
|
40
|
+
birthtime: right.birthtimeMs,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function sameIdentity(left, right) {
|
|
44
|
+
return (sameObjectIdentity(left, right) &&
|
|
45
|
+
left.birthtimeMs === right.birthtimeMs &&
|
|
46
|
+
left.ctimeMs === right.ctimeMs &&
|
|
47
|
+
left.mtimeMs === right.mtimeMs &&
|
|
48
|
+
left.size === right.size);
|
|
49
|
+
}
|
|
50
|
+
function sameContentVersionAfterLinkOrRename(left, right) {
|
|
51
|
+
return (sameObjectIdentity(left, right) &&
|
|
52
|
+
left.birthtimeMs === right.birthtimeMs &&
|
|
53
|
+
left.mtimeMs === right.mtimeMs &&
|
|
54
|
+
left.size === right.size);
|
|
55
|
+
}
|
|
56
|
+
function fileIdentity(stat) {
|
|
57
|
+
return {
|
|
58
|
+
dev: stat.dev,
|
|
59
|
+
ino: stat.ino,
|
|
60
|
+
birthtimeMs: stat.birthtimeMs,
|
|
61
|
+
ctimeMs: stat.ctimeMs,
|
|
62
|
+
mtimeMs: stat.mtimeMs,
|
|
63
|
+
size: stat.size,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function compareText(left, right) {
|
|
67
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
68
|
+
}
|
|
69
|
+
function portableProjectRef(paths, target) {
|
|
70
|
+
const relative = path.relative(paths.projectRoot, target);
|
|
71
|
+
if (relative.length === 0 ||
|
|
72
|
+
path.isAbsolute(relative) ||
|
|
73
|
+
relative === '..' ||
|
|
74
|
+
relative.startsWith(`..${path.sep}`)) {
|
|
75
|
+
throw new Error('Native evidence retention finding path is outside the project');
|
|
76
|
+
}
|
|
77
|
+
return relative.split(path.sep).join('/');
|
|
78
|
+
}
|
|
79
|
+
function evidenceRootPath(paths, name) {
|
|
80
|
+
return path.join(nativeChangeDir(paths, name), 'runtime', 'evidence');
|
|
81
|
+
}
|
|
82
|
+
function evidenceRootRef(paths, name) {
|
|
83
|
+
return portableProjectRef(paths, evidenceRootPath(paths, name));
|
|
84
|
+
}
|
|
85
|
+
async function captureDirectoryChain(managedRoot, directory) {
|
|
86
|
+
const root = path.resolve(managedRoot);
|
|
87
|
+
const target = path.resolve(directory);
|
|
88
|
+
if (!isInsidePath(root, target)) {
|
|
89
|
+
throw new Error('Native evidence retention path escapes its managed change');
|
|
90
|
+
}
|
|
91
|
+
const segments = path.relative(root, target).split(path.sep).filter(Boolean);
|
|
92
|
+
const chain = [];
|
|
93
|
+
let cursor = root;
|
|
94
|
+
for (const segment of ['', ...segments]) {
|
|
95
|
+
if (segment)
|
|
96
|
+
cursor = path.join(cursor, segment);
|
|
97
|
+
const stat = await fs.lstat(cursor);
|
|
98
|
+
if (!stat.isDirectory() || stat.isSymbolicLink()) {
|
|
99
|
+
throw new Error(`Native evidence retention parent must be a real directory: ${cursor}`);
|
|
100
|
+
}
|
|
101
|
+
const realPath = await fs.realpath(cursor);
|
|
102
|
+
if (chain.length > 0 && !isInsidePath(chain[0].realPath, realPath)) {
|
|
103
|
+
throw new Error(`Native evidence retention parent resolves outside its change: ${cursor}`);
|
|
104
|
+
}
|
|
105
|
+
chain.push({ path: cursor, realPath, ...fileIdentity(stat) });
|
|
106
|
+
}
|
|
107
|
+
return chain;
|
|
108
|
+
}
|
|
109
|
+
async function verifyDirectoryChain(chain) {
|
|
110
|
+
for (const identity of chain) {
|
|
111
|
+
const stat = await fs.lstat(identity.path);
|
|
112
|
+
if (!stat.isDirectory() ||
|
|
113
|
+
stat.isSymbolicLink() ||
|
|
114
|
+
!sameObjectIdentity(identity, stat) ||
|
|
115
|
+
(await fs.realpath(identity.path)) !== identity.realPath) {
|
|
116
|
+
throw new Error(`Native evidence retention parent changed: ${identity.path}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function refForKind(kind, hash) {
|
|
121
|
+
return kind === 'check-receipts'
|
|
122
|
+
? `runtime/evidence/check-receipts/${hash}.json`
|
|
123
|
+
: nativeEvidenceRef(kind, hash);
|
|
124
|
+
}
|
|
125
|
+
function managedDependency(value) {
|
|
126
|
+
return value !== null && MANAGED_REF_PATTERN.test(value) ? [value] : [];
|
|
127
|
+
}
|
|
128
|
+
function parseDocument(kind, hash, value, expectedChange) {
|
|
129
|
+
if (kind === 'snapshots') {
|
|
130
|
+
return {
|
|
131
|
+
canonical: parseNativeSnapshotProjection(value, hash),
|
|
132
|
+
dependencies: [],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (kind === 'scopes') {
|
|
136
|
+
const scope = parseNativeImplementationScope(value);
|
|
137
|
+
if (scope.scopeHash !== hash)
|
|
138
|
+
throw new Error('Native scope filename does not match its hash');
|
|
139
|
+
return {
|
|
140
|
+
canonical: scope,
|
|
141
|
+
dependencies: [scope.baselineProjectionRef, scope.currentProjectionRef],
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
if (kind === 'allowances') {
|
|
145
|
+
const allowance = parseNativePartialAllowance(value);
|
|
146
|
+
if (allowance.change !== expectedChange || allowance.allowanceHash !== hash) {
|
|
147
|
+
throw new Error('Native allowance filename/change does not match its content');
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
canonical: allowance,
|
|
151
|
+
dependencies: [nativeEvidenceRef('scopes', allowance.scopeHash)],
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
if (kind === 'verifications') {
|
|
155
|
+
const evidence = parseNativeVerificationEvidenceEnvelope(value);
|
|
156
|
+
if (evidence.change !== expectedChange || evidence.envelopeHash !== hash) {
|
|
157
|
+
throw new Error('Native verification filename/change does not match its content');
|
|
158
|
+
}
|
|
159
|
+
const traceDependencies = evidence.acceptanceTrace.entries.flatMap((entry) => entry.evidenceRefs.flatMap(managedDependency));
|
|
160
|
+
return {
|
|
161
|
+
canonical: evidence,
|
|
162
|
+
dependencies: [
|
|
163
|
+
evidence.implementationScopeRef,
|
|
164
|
+
nativeReportEvidenceRef(evidence.reportHash),
|
|
165
|
+
...managedDependency(evidence.partialAllowanceRef),
|
|
166
|
+
...managedDependency(evidence.receiptRef),
|
|
167
|
+
...traceDependencies,
|
|
168
|
+
],
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (kind === 'reports') {
|
|
172
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
173
|
+
throw new Error('Native report evidence must be an object');
|
|
174
|
+
}
|
|
175
|
+
const report = value;
|
|
176
|
+
if (Object.keys(report).sort().join(',') !== 'content,reportHash,schema' ||
|
|
177
|
+
report.schema !== 'comet.native.verification-report.v1' ||
|
|
178
|
+
report.reportHash !== hash ||
|
|
179
|
+
typeof report.content !== 'string' ||
|
|
180
|
+
createHash('sha256').update(Buffer.from(report.content, 'utf8')).digest('hex') !== hash) {
|
|
181
|
+
throw new Error('Native report evidence filename/hash does not match its content');
|
|
182
|
+
}
|
|
183
|
+
return { canonical: report, dependencies: [] };
|
|
184
|
+
}
|
|
185
|
+
const receipt = parseNativeCheckReceipt(value);
|
|
186
|
+
if (receipt.change !== expectedChange || receipt.receiptHash !== hash) {
|
|
187
|
+
throw new Error('Native check receipt filename/change does not match its content');
|
|
188
|
+
}
|
|
189
|
+
return { canonical: receipt, dependencies: [] };
|
|
190
|
+
}
|
|
191
|
+
async function readCanonicalDocument(options) {
|
|
192
|
+
const before = await fs.lstat(options.file);
|
|
193
|
+
if (!before.isFile() || before.isSymbolicLink()) {
|
|
194
|
+
throw new Error(`Native evidence entry is not a regular file: ${options.ref}`);
|
|
195
|
+
}
|
|
196
|
+
const maximumBytes = options.kind === 'check-receipts'
|
|
197
|
+
? MAX_NATIVE_CHECK_RECEIPT_BYTES
|
|
198
|
+
: MAX_NATIVE_EVIDENCE_DOCUMENT_BYTES;
|
|
199
|
+
if (before.size > maximumBytes) {
|
|
200
|
+
throw new Error(`Native evidence entry exceeds its byte budget: ${options.ref}`);
|
|
201
|
+
}
|
|
202
|
+
const beforeRealPath = await fs.realpath(options.file);
|
|
203
|
+
if (!isInsidePath(options.directoryChain[0].realPath, beforeRealPath)) {
|
|
204
|
+
throw new Error(`Native evidence entry resolves outside its change: ${options.ref}`);
|
|
205
|
+
}
|
|
206
|
+
const openFlags = process.platform === 'win32'
|
|
207
|
+
? 'r'
|
|
208
|
+
: fsConstants.O_RDONLY | fsConstants.O_NOFOLLOW | fsConstants.O_NONBLOCK;
|
|
209
|
+
const handle = await fs.open(options.file, openFlags).catch((error) => {
|
|
210
|
+
if (error.code === 'ELOOP' || error.code === 'ENXIO') {
|
|
211
|
+
throw new Error(`Native evidence entry became unsafe while opening: ${options.ref}`);
|
|
212
|
+
}
|
|
213
|
+
throw error;
|
|
214
|
+
});
|
|
215
|
+
try {
|
|
216
|
+
const [opened, pathAfterOpen, realPathAfterOpen] = await Promise.all([
|
|
217
|
+
handle.stat(),
|
|
218
|
+
fs.lstat(options.file),
|
|
219
|
+
fs.realpath(options.file),
|
|
220
|
+
]);
|
|
221
|
+
await verifyDirectoryChain(options.directoryChain);
|
|
222
|
+
if (!opened.isFile() ||
|
|
223
|
+
!pathAfterOpen.isFile() ||
|
|
224
|
+
pathAfterOpen.isSymbolicLink() ||
|
|
225
|
+
realPathAfterOpen !== beforeRealPath ||
|
|
226
|
+
!sameIdentity(fileIdentity(before), opened) ||
|
|
227
|
+
!sameIdentity(fileIdentity(opened), pathAfterOpen)) {
|
|
228
|
+
throw new Error(`Native evidence entry changed while opening: ${options.ref}`);
|
|
229
|
+
}
|
|
230
|
+
const chunks = [];
|
|
231
|
+
const buffer = Buffer.allocUnsafe(64 * 1024);
|
|
232
|
+
let total = 0;
|
|
233
|
+
while (true) {
|
|
234
|
+
const remaining = maximumBytes + 1 - total;
|
|
235
|
+
const read = await handle.read(buffer, 0, Math.min(buffer.length, remaining), null);
|
|
236
|
+
if (read.bytesRead === 0)
|
|
237
|
+
break;
|
|
238
|
+
total += read.bytesRead;
|
|
239
|
+
if (total > maximumBytes) {
|
|
240
|
+
throw new Error(`Native evidence entry exceeds its byte budget: ${options.ref}`);
|
|
241
|
+
}
|
|
242
|
+
chunks.push(Buffer.from(buffer.subarray(0, read.bytesRead)));
|
|
243
|
+
}
|
|
244
|
+
const [afterHandle, afterPath, afterRealPath] = await Promise.all([
|
|
245
|
+
handle.stat(),
|
|
246
|
+
fs.lstat(options.file),
|
|
247
|
+
fs.realpath(options.file),
|
|
248
|
+
]);
|
|
249
|
+
await verifyDirectoryChain(options.directoryChain);
|
|
250
|
+
if (!afterPath.isFile() ||
|
|
251
|
+
afterPath.isSymbolicLink() ||
|
|
252
|
+
afterRealPath !== beforeRealPath ||
|
|
253
|
+
!sameIdentity(fileIdentity(opened), afterHandle) ||
|
|
254
|
+
!sameIdentity(fileIdentity(opened), afterPath)) {
|
|
255
|
+
throw new Error(`Native evidence entry changed while reading: ${options.ref}`);
|
|
256
|
+
}
|
|
257
|
+
const text = Buffer.concat(chunks, total).toString('utf8');
|
|
258
|
+
let json;
|
|
259
|
+
try {
|
|
260
|
+
json = JSON.parse(text);
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
throw new Error(`Native evidence entry is not valid JSON: ${options.ref}`, {
|
|
264
|
+
cause: error,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
const parsed = parseDocument(options.kind, options.hash, json, options.name);
|
|
268
|
+
if (text !== JSON.stringify(parsed.canonical, null, 2) + '\n') {
|
|
269
|
+
throw new Error(`Native evidence entry is not canonically serialized: ${options.ref}`);
|
|
270
|
+
}
|
|
271
|
+
return {
|
|
272
|
+
ref: options.ref,
|
|
273
|
+
kind: options.kind,
|
|
274
|
+
change: options.name,
|
|
275
|
+
changeRoot: options.changeRoot,
|
|
276
|
+
file: options.file,
|
|
277
|
+
size: total,
|
|
278
|
+
mtimeMs: afterHandle.mtimeMs,
|
|
279
|
+
identity: fileIdentity(afterHandle),
|
|
280
|
+
directoryChain: options.directoryChain,
|
|
281
|
+
dependencies: [...new Set(parsed.dependencies)].sort(compareText),
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
finally {
|
|
285
|
+
await handle.close();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
async function pathIsMissing(file) {
|
|
289
|
+
try {
|
|
290
|
+
await fs.lstat(file);
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
if (error.code === 'ENOENT')
|
|
295
|
+
return true;
|
|
296
|
+
throw error;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
async function inspectCleanupQuarantines(options) {
|
|
300
|
+
const changeRoot = nativeChangeDir(options.paths, options.name);
|
|
301
|
+
const evidenceRoot = evidenceRootPath(options.paths, options.name);
|
|
302
|
+
await resolveContainedNativePath(options.paths.nativeRoot, evidenceRoot);
|
|
303
|
+
let rootEntries;
|
|
304
|
+
try {
|
|
305
|
+
const rootChain = await captureDirectoryChain(changeRoot, evidenceRoot);
|
|
306
|
+
rootEntries = await fs.readdir(evidenceRoot, { withFileTypes: true });
|
|
307
|
+
await verifyDirectoryChain(rootChain);
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
if (error.code === 'ENOENT') {
|
|
311
|
+
return { findings: [], pending: false };
|
|
312
|
+
}
|
|
313
|
+
throw error;
|
|
314
|
+
}
|
|
315
|
+
const recoveries = [];
|
|
316
|
+
for (const kind of MANAGED_KINDS) {
|
|
317
|
+
if (!rootEntries.some((entry) => entry.name === kind))
|
|
318
|
+
continue;
|
|
319
|
+
const directory = path.join(evidenceRoot, kind);
|
|
320
|
+
const directoryChain = await captureDirectoryChain(changeRoot, directory);
|
|
321
|
+
const entries = (await fs.readdir(directory, { withFileTypes: true })).sort((left, right) => compareText(left.name, right.name));
|
|
322
|
+
const byOriginal = new Map();
|
|
323
|
+
for (const entry of entries) {
|
|
324
|
+
const match = CLEANUP_QUARANTINE_PATTERN.exec(entry.name);
|
|
325
|
+
if (!match)
|
|
326
|
+
continue;
|
|
327
|
+
const grouped = byOriginal.get(match[1]) ?? [];
|
|
328
|
+
grouped.push(entry);
|
|
329
|
+
byOriginal.set(match[1], grouped);
|
|
330
|
+
}
|
|
331
|
+
for (const [originalName, entriesForOriginal] of [...byOriginal.entries()].sort(([left], [right]) => compareText(left, right))) {
|
|
332
|
+
if (entriesForOriginal.length !== 1) {
|
|
333
|
+
throw new Error(`Native evidence cleanup has multiple quarantines for ${kind}/${originalName}`);
|
|
334
|
+
}
|
|
335
|
+
const entry = entriesForOriginal[0];
|
|
336
|
+
if (!entry.isFile() || entry.isSymbolicLink()) {
|
|
337
|
+
throw new Error(`Native evidence cleanup quarantine is not a regular file: ${kind}/${entry.name}`);
|
|
338
|
+
}
|
|
339
|
+
const original = path.join(directory, originalName);
|
|
340
|
+
const hash = HASH_FILE_PATTERN.exec(originalName)?.[1];
|
|
341
|
+
if (!hash)
|
|
342
|
+
throw new Error(`Native evidence cleanup quarantine name is invalid: ${entry.name}`);
|
|
343
|
+
const ref = refForKind(kind, hash);
|
|
344
|
+
const quarantine = path.join(directory, entry.name);
|
|
345
|
+
const document = await readCanonicalDocument({
|
|
346
|
+
changeRoot,
|
|
347
|
+
file: quarantine,
|
|
348
|
+
ref,
|
|
349
|
+
kind,
|
|
350
|
+
hash,
|
|
351
|
+
name: options.name,
|
|
352
|
+
directoryChain,
|
|
353
|
+
});
|
|
354
|
+
const originalMissing = await pathIsMissing(original);
|
|
355
|
+
const originalDocument = originalMissing
|
|
356
|
+
? null
|
|
357
|
+
: await readCanonicalDocument({
|
|
358
|
+
changeRoot,
|
|
359
|
+
file: original,
|
|
360
|
+
ref,
|
|
361
|
+
kind,
|
|
362
|
+
hash,
|
|
363
|
+
name: options.name,
|
|
364
|
+
directoryChain,
|
|
365
|
+
});
|
|
366
|
+
recoveries.push({
|
|
367
|
+
ref,
|
|
368
|
+
original,
|
|
369
|
+
quarantine,
|
|
370
|
+
document,
|
|
371
|
+
action: originalMissing ? 'restore-original' : 'finish-linked-recovery',
|
|
372
|
+
originalDocument,
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
if (recoveries.length === 0)
|
|
377
|
+
return { findings: [], pending: false };
|
|
378
|
+
const refs = recoveries.map((recovery) => recovery.ref).sort(compareText);
|
|
379
|
+
if (!options.repair) {
|
|
380
|
+
return {
|
|
381
|
+
pending: true,
|
|
382
|
+
findings: [
|
|
383
|
+
{
|
|
384
|
+
severity: 'warning',
|
|
385
|
+
code: 'evidence-retention-recovery-required',
|
|
386
|
+
message: boundedMessage(`Native evidence cleanup has ${refs.length} safely recoverable quarantined document(s) for ${options.name}: ${boundedRefs(refs)}`),
|
|
387
|
+
path: evidenceRootRef(options.paths, options.name),
|
|
388
|
+
},
|
|
389
|
+
],
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
for (const recovery of recoveries.sort((left, right) => compareText(left.ref, right.ref))) {
|
|
393
|
+
await verifyDirectoryChain(recovery.document.directoryChain);
|
|
394
|
+
if (recovery.action === 'finish-linked-recovery') {
|
|
395
|
+
const original = await readCanonicalDocument({
|
|
396
|
+
changeRoot,
|
|
397
|
+
file: recovery.original,
|
|
398
|
+
ref: recovery.ref,
|
|
399
|
+
kind: recovery.document.kind,
|
|
400
|
+
hash: HASH_FILE_PATTERN.exec(path.basename(recovery.original))[1],
|
|
401
|
+
name: options.name,
|
|
402
|
+
directoryChain: recovery.document.directoryChain,
|
|
403
|
+
});
|
|
404
|
+
const quarantine = await readCanonicalDocument({
|
|
405
|
+
changeRoot,
|
|
406
|
+
file: recovery.quarantine,
|
|
407
|
+
ref: recovery.ref,
|
|
408
|
+
kind: recovery.document.kind,
|
|
409
|
+
hash: HASH_FILE_PATTERN.exec(path.basename(recovery.original))[1],
|
|
410
|
+
name: options.name,
|
|
411
|
+
directoryChain: recovery.document.directoryChain,
|
|
412
|
+
});
|
|
413
|
+
if (!recovery.originalDocument ||
|
|
414
|
+
!sameIdentity(recovery.originalDocument.identity, original.identity) ||
|
|
415
|
+
!sameIdentity(recovery.document.identity, quarantine.identity)) {
|
|
416
|
+
throw new Error(`Native evidence cleanup original or quarantine changed during recovery: ${recovery.ref}`);
|
|
417
|
+
}
|
|
418
|
+
await fs.rm(recovery.quarantine);
|
|
419
|
+
await verifyDirectoryChain(recovery.document.directoryChain);
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
if (!(await pathIsMissing(recovery.original))) {
|
|
423
|
+
throw new Error(`Native evidence cleanup original appeared during recovery: ${recovery.ref}`);
|
|
424
|
+
}
|
|
425
|
+
const quarantineStat = await fs.lstat(recovery.quarantine);
|
|
426
|
+
if (!quarantineStat.isFile() ||
|
|
427
|
+
quarantineStat.isSymbolicLink() ||
|
|
428
|
+
!sameIdentity(recovery.document.identity, quarantineStat)) {
|
|
429
|
+
throw new Error(`Native evidence cleanup quarantine changed during recovery: ${recovery.ref}`);
|
|
430
|
+
}
|
|
431
|
+
// A hard link provides portable no-overwrite placement: EEXIST is fail-closed instead of
|
|
432
|
+
// replacing a concurrently created original as rename() would on POSIX.
|
|
433
|
+
await fs.link(recovery.quarantine, recovery.original);
|
|
434
|
+
await options.hooks.afterRecoveryLink?.({
|
|
435
|
+
ref: recovery.ref,
|
|
436
|
+
original: recovery.original,
|
|
437
|
+
quarantine: recovery.quarantine,
|
|
438
|
+
});
|
|
439
|
+
const restored = await readCanonicalDocument({
|
|
440
|
+
changeRoot,
|
|
441
|
+
file: recovery.original,
|
|
442
|
+
ref: recovery.ref,
|
|
443
|
+
kind: recovery.document.kind,
|
|
444
|
+
hash: HASH_FILE_PATTERN.exec(path.basename(recovery.original))[1],
|
|
445
|
+
name: options.name,
|
|
446
|
+
directoryChain: recovery.document.directoryChain,
|
|
447
|
+
});
|
|
448
|
+
const linkedQuarantine = await readCanonicalDocument({
|
|
449
|
+
changeRoot,
|
|
450
|
+
file: recovery.quarantine,
|
|
451
|
+
ref: recovery.ref,
|
|
452
|
+
kind: recovery.document.kind,
|
|
453
|
+
hash: HASH_FILE_PATTERN.exec(path.basename(recovery.original))[1],
|
|
454
|
+
name: options.name,
|
|
455
|
+
directoryChain: recovery.document.directoryChain,
|
|
456
|
+
});
|
|
457
|
+
if (!sameContentVersionAfterLinkOrRename(recovery.document.identity, restored.identity) ||
|
|
458
|
+
!sameIdentity(restored.identity, linkedQuarantine.identity)) {
|
|
459
|
+
throw new Error(`Native evidence cleanup recovery identity changed: ${recovery.ref}`);
|
|
460
|
+
}
|
|
461
|
+
await fs.rm(recovery.quarantine);
|
|
462
|
+
await verifyDirectoryChain(recovery.document.directoryChain);
|
|
463
|
+
}
|
|
464
|
+
return {
|
|
465
|
+
pending: false,
|
|
466
|
+
findings: [
|
|
467
|
+
{
|
|
468
|
+
severity: 'info',
|
|
469
|
+
code: 'evidence-retention-cleanup-recovered',
|
|
470
|
+
message: boundedMessage(`Recovered ${refs.length} interrupted Native evidence cleanup document(s) for ${options.name}: ${boundedRefs(refs)}`),
|
|
471
|
+
path: evidenceRootRef(options.paths, options.name),
|
|
472
|
+
},
|
|
473
|
+
],
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
async function scanEvidenceStore(paths, name) {
|
|
477
|
+
const changeRoot = nativeChangeDir(paths, name);
|
|
478
|
+
const evidenceRoot = path.join(changeRoot, 'runtime', 'evidence');
|
|
479
|
+
await resolveContainedNativePath(paths.nativeRoot, evidenceRoot);
|
|
480
|
+
let rootEntries;
|
|
481
|
+
try {
|
|
482
|
+
const rootChain = await captureDirectoryChain(changeRoot, evidenceRoot);
|
|
483
|
+
rootEntries = await fs.readdir(evidenceRoot, { withFileTypes: true });
|
|
484
|
+
await verifyDirectoryChain(rootChain);
|
|
485
|
+
}
|
|
486
|
+
catch (error) {
|
|
487
|
+
if (error.code === 'ENOENT')
|
|
488
|
+
return [];
|
|
489
|
+
throw error;
|
|
490
|
+
}
|
|
491
|
+
const unknownRootEntries = rootEntries
|
|
492
|
+
.filter((entry) => !MANAGED_KINDS.includes(entry.name) ||
|
|
493
|
+
!entry.isDirectory() ||
|
|
494
|
+
entry.isSymbolicLink())
|
|
495
|
+
.map((entry) => entry.name)
|
|
496
|
+
.sort(compareText);
|
|
497
|
+
if (unknownRootEntries.length > 0) {
|
|
498
|
+
throw new Error(`Native evidence root has unknown or special entries: ${boundedRefs(unknownRootEntries)}`);
|
|
499
|
+
}
|
|
500
|
+
const documents = [];
|
|
501
|
+
let scannedBytes = 0;
|
|
502
|
+
for (const kind of MANAGED_KINDS) {
|
|
503
|
+
if (!rootEntries.some((entry) => entry.name === kind))
|
|
504
|
+
continue;
|
|
505
|
+
const directory = path.join(evidenceRoot, kind);
|
|
506
|
+
const directoryChain = await captureDirectoryChain(changeRoot, directory);
|
|
507
|
+
const entries = (await fs.readdir(directory, { withFileTypes: true })).sort((left, right) => compareText(left.name, right.name));
|
|
508
|
+
await verifyDirectoryChain(directoryChain);
|
|
509
|
+
for (const entry of entries) {
|
|
510
|
+
if (documents.length >= NATIVE_EVIDENCE_RETENTION_POLICY.maxDocuments) {
|
|
511
|
+
throw new Error(`Native evidence store exceeds ${NATIVE_EVIDENCE_RETENTION_POLICY.maxDocuments} documents`);
|
|
512
|
+
}
|
|
513
|
+
const match = HASH_FILE_PATTERN.exec(entry.name);
|
|
514
|
+
if (!match || !entry.isFile() || entry.isSymbolicLink()) {
|
|
515
|
+
throw new Error(`Native evidence kind ${kind} has an unknown or special entry: ${entry.name}`);
|
|
516
|
+
}
|
|
517
|
+
const ref = refForKind(kind, match[1]);
|
|
518
|
+
const file = path.join(directory, entry.name);
|
|
519
|
+
await resolveContainedNativePath(paths.nativeRoot, file);
|
|
520
|
+
const document = await readCanonicalDocument({
|
|
521
|
+
changeRoot,
|
|
522
|
+
file,
|
|
523
|
+
ref,
|
|
524
|
+
kind,
|
|
525
|
+
hash: match[1],
|
|
526
|
+
name,
|
|
527
|
+
directoryChain,
|
|
528
|
+
});
|
|
529
|
+
scannedBytes += document.size;
|
|
530
|
+
if (scannedBytes > NATIVE_EVIDENCE_RETENTION_POLICY.maxScannedBytes) {
|
|
531
|
+
throw new Error(`Native evidence store exceeds ${NATIVE_EVIDENCE_RETENTION_POLICY.maxScannedBytes} scanned bytes`);
|
|
532
|
+
}
|
|
533
|
+
documents.push(document);
|
|
534
|
+
}
|
|
535
|
+
await verifyDirectoryChain(directoryChain);
|
|
536
|
+
}
|
|
537
|
+
return documents;
|
|
538
|
+
}
|
|
539
|
+
function closeDependencies(seeds, documents) {
|
|
540
|
+
const retained = new Set();
|
|
541
|
+
const pending = [...seeds].sort(compareText).reverse();
|
|
542
|
+
while (pending.length > 0) {
|
|
543
|
+
const ref = pending.pop();
|
|
544
|
+
if (retained.has(ref))
|
|
545
|
+
continue;
|
|
546
|
+
const document = documents.get(ref);
|
|
547
|
+
if (!document)
|
|
548
|
+
throw new Error(`Native evidence dependency is missing: ${ref}`);
|
|
549
|
+
retained.add(ref);
|
|
550
|
+
for (const dependency of [...document.dependencies].sort(compareText).reverse()) {
|
|
551
|
+
if (!retained.has(dependency))
|
|
552
|
+
pending.push(dependency);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
return retained;
|
|
556
|
+
}
|
|
557
|
+
function dependentsBeforeDependencies(candidates) {
|
|
558
|
+
const byRef = new Map(candidates.map((candidate) => [candidate.ref, candidate]));
|
|
559
|
+
const dependencyCounts = new Map(candidates.map((candidate) => [candidate.ref, 0]));
|
|
560
|
+
for (const candidate of candidates) {
|
|
561
|
+
for (const dependency of candidate.dependencies) {
|
|
562
|
+
if (byRef.has(dependency)) {
|
|
563
|
+
dependencyCounts.set(dependency, (dependencyCounts.get(dependency) ?? 0) + 1);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
const ready = [...dependencyCounts]
|
|
568
|
+
.filter(([, count]) => count === 0)
|
|
569
|
+
.map(([ref]) => ref)
|
|
570
|
+
.sort(compareText);
|
|
571
|
+
const ordered = [];
|
|
572
|
+
while (ready.length > 0) {
|
|
573
|
+
const ref = ready.shift();
|
|
574
|
+
const candidate = byRef.get(ref);
|
|
575
|
+
ordered.push(candidate);
|
|
576
|
+
for (const dependency of candidate.dependencies) {
|
|
577
|
+
const count = dependencyCounts.get(dependency);
|
|
578
|
+
if (count === undefined)
|
|
579
|
+
continue;
|
|
580
|
+
const next = count - 1;
|
|
581
|
+
dependencyCounts.set(dependency, next);
|
|
582
|
+
if (next === 0) {
|
|
583
|
+
ready.push(dependency);
|
|
584
|
+
ready.sort(compareText);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
if (ordered.length !== candidates.length) {
|
|
589
|
+
throw new Error('Native evidence candidate dependency graph contains a cycle');
|
|
590
|
+
}
|
|
591
|
+
return ordered;
|
|
592
|
+
}
|
|
593
|
+
function planRetention(documents, rootRefs, nowMs) {
|
|
594
|
+
const byRef = new Map(documents.map((document) => [document.ref, document]));
|
|
595
|
+
if (byRef.size !== documents.length)
|
|
596
|
+
throw new Error('Native evidence store has duplicate refs');
|
|
597
|
+
// A damaged orphan is not safe to reason about either: every managed dependency must exist.
|
|
598
|
+
for (const document of documents) {
|
|
599
|
+
for (const dependency of document.dependencies) {
|
|
600
|
+
if (!byRef.has(dependency)) {
|
|
601
|
+
throw new Error(`Native evidence dependency is missing: ${dependency}`);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
const rootClosure = closeDependencies(rootRefs, byRef);
|
|
606
|
+
const retainedSeeds = new Set(rootClosure);
|
|
607
|
+
for (const document of documents) {
|
|
608
|
+
if (nowMs - document.mtimeMs < NATIVE_EVIDENCE_RETENTION_POLICY.minimumAgeMs) {
|
|
609
|
+
retainedSeeds.add(document.ref);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
for (const kind of MANAGED_KINDS) {
|
|
613
|
+
const newestUnreferenced = documents
|
|
614
|
+
.filter((document) => document.kind === kind && !rootClosure.has(document.ref))
|
|
615
|
+
.sort((left, right) => right.mtimeMs - left.mtimeMs || compareText(left.ref, right.ref))
|
|
616
|
+
.slice(0, NATIVE_EVIDENCE_RETENTION_POLICY.keepLatestUnreferencedPerKind);
|
|
617
|
+
for (const document of newestUnreferenced)
|
|
618
|
+
retainedSeeds.add(document.ref);
|
|
619
|
+
}
|
|
620
|
+
const retained = closeDependencies(retainedSeeds, byRef);
|
|
621
|
+
const candidates = documents
|
|
622
|
+
.filter((document) => !retained.has(document.ref) &&
|
|
623
|
+
nowMs - document.mtimeMs >= NATIVE_EVIDENCE_RETENTION_POLICY.minimumAgeMs)
|
|
624
|
+
.sort((left, right) => compareText(left.ref, right.ref));
|
|
625
|
+
return {
|
|
626
|
+
candidates: dependentsBeforeDependencies(candidates),
|
|
627
|
+
candidateBytes: candidates.reduce((total, candidate) => total + candidate.size, 0),
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
function boundedRefs(refs) {
|
|
631
|
+
const shown = refs.slice(0, NATIVE_EVIDENCE_RETENTION_POLICY.maxReportedRefs);
|
|
632
|
+
const omitted = refs.length - shown.length;
|
|
633
|
+
return `${shown.join(', ')}${omitted > 0 ? `, ... (${omitted} more)` : ''}`;
|
|
634
|
+
}
|
|
635
|
+
function boundedMessage(message) {
|
|
636
|
+
const maximum = NATIVE_EVIDENCE_RETENTION_POLICY.maxReportMessageBytes;
|
|
637
|
+
if (Buffer.byteLength(message, 'utf8') <= maximum)
|
|
638
|
+
return message;
|
|
639
|
+
let result = message;
|
|
640
|
+
while (result.length > 0 && Buffer.byteLength(`${result}...`, 'utf8') > maximum) {
|
|
641
|
+
result = result.slice(0, -1);
|
|
642
|
+
}
|
|
643
|
+
return `${result}...`;
|
|
644
|
+
}
|
|
645
|
+
function summaryFinding(name, plan, repaired, evidenceRoot) {
|
|
646
|
+
const refs = plan.candidates.map((candidate) => candidate.ref).sort(compareText);
|
|
647
|
+
return {
|
|
648
|
+
severity: 'info',
|
|
649
|
+
code: repaired ? 'evidence-retention-cleaned' : 'evidence-retention-candidates',
|
|
650
|
+
message: boundedMessage(`${repaired ? 'Removed' : 'Found'} ${plan.candidates.length} old unreferenced Native evidence document(s) (${plan.candidateBytes} bytes) for ${name}: ${boundedRefs(refs)}`),
|
|
651
|
+
path: evidenceRoot,
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
async function restoreQuarantineIfSafe(quarantine, original) {
|
|
655
|
+
try {
|
|
656
|
+
await fs.lstat(original);
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
catch (error) {
|
|
660
|
+
if (error.code !== 'ENOENT')
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
663
|
+
try {
|
|
664
|
+
await fs.rename(quarantine, original);
|
|
665
|
+
}
|
|
666
|
+
catch {
|
|
667
|
+
// Leave the uniquely named file in the already-validated managed directory. Never delete it.
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
async function deleteCandidate(candidate, hooks) {
|
|
671
|
+
await hooks.beforeDelete?.({ ref: candidate.ref, file: candidate.file });
|
|
672
|
+
await verifyDirectoryChain(candidate.directoryChain);
|
|
673
|
+
const beforeDocument = await readCanonicalDocument({
|
|
674
|
+
changeRoot: candidate.changeRoot,
|
|
675
|
+
file: candidate.file,
|
|
676
|
+
ref: candidate.ref,
|
|
677
|
+
kind: candidate.kind,
|
|
678
|
+
hash: HASH_FILE_PATTERN.exec(path.basename(candidate.file))[1],
|
|
679
|
+
name: candidate.change,
|
|
680
|
+
directoryChain: candidate.directoryChain,
|
|
681
|
+
});
|
|
682
|
+
const before = await fs.lstat(candidate.file);
|
|
683
|
+
const beforeRealPath = await fs.realpath(candidate.file);
|
|
684
|
+
if (!before.isFile() ||
|
|
685
|
+
before.isSymbolicLink() ||
|
|
686
|
+
!sameIdentity(candidate.identity, before) ||
|
|
687
|
+
!sameIdentity(candidate.identity, beforeDocument.identity) ||
|
|
688
|
+
!isInsidePath(candidate.directoryChain[0].realPath, beforeRealPath)) {
|
|
689
|
+
throw new Error(`Native evidence candidate changed before cleanup: ${candidate.ref}`);
|
|
690
|
+
}
|
|
691
|
+
const quarantine = path.join(path.dirname(candidate.file), `.${path.basename(candidate.file)}.${randomUUID()}.gc`);
|
|
692
|
+
await fs.rename(candidate.file, quarantine);
|
|
693
|
+
try {
|
|
694
|
+
const [moved, movedRealPath] = await Promise.all([
|
|
695
|
+
fs.lstat(quarantine),
|
|
696
|
+
fs.realpath(quarantine),
|
|
697
|
+
]);
|
|
698
|
+
await verifyDirectoryChain(candidate.directoryChain);
|
|
699
|
+
if (!moved.isFile() ||
|
|
700
|
+
moved.isSymbolicLink() ||
|
|
701
|
+
!sameContentVersionAfterLinkOrRename(candidate.identity, moved) ||
|
|
702
|
+
!isInsidePath(candidate.directoryChain[0].realPath, movedRealPath)) {
|
|
703
|
+
await restoreQuarantineIfSafe(quarantine, candidate.file);
|
|
704
|
+
throw new Error(`Native evidence candidate changed during cleanup: ${candidate.ref}`);
|
|
705
|
+
}
|
|
706
|
+
await fs.rm(quarantine);
|
|
707
|
+
await verifyDirectoryChain(candidate.directoryChain);
|
|
708
|
+
}
|
|
709
|
+
catch (error) {
|
|
710
|
+
await restoreQuarantineIfSafe(quarantine, candidate.file);
|
|
711
|
+
throw error;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
async function hasPendingRelocationOrArchive(paths) {
|
|
715
|
+
const config = await readProjectConfig(paths.projectRoot);
|
|
716
|
+
if (config?.native.pending_root_move)
|
|
717
|
+
return true;
|
|
718
|
+
let entries;
|
|
719
|
+
try {
|
|
720
|
+
entries = await fs.readdir(paths.transactionsDir, { withFileTypes: true });
|
|
721
|
+
}
|
|
722
|
+
catch (error) {
|
|
723
|
+
if (error.code === 'ENOENT')
|
|
724
|
+
return false;
|
|
725
|
+
throw error;
|
|
726
|
+
}
|
|
727
|
+
for (const entry of entries) {
|
|
728
|
+
if (!entry.isDirectory() || entry.isSymbolicLink())
|
|
729
|
+
return true;
|
|
730
|
+
try {
|
|
731
|
+
const transaction = await readNativeTransaction(paths, entry.name);
|
|
732
|
+
if (transaction.status !== 'committed' && transaction.status !== 'rolled-back')
|
|
733
|
+
return true;
|
|
734
|
+
}
|
|
735
|
+
catch {
|
|
736
|
+
return true;
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
return false;
|
|
740
|
+
}
|
|
741
|
+
async function changeNames(paths, requested) {
|
|
742
|
+
if (requested)
|
|
743
|
+
return [requested];
|
|
744
|
+
let entries;
|
|
745
|
+
try {
|
|
746
|
+
entries = await fs.readdir(paths.changesDir, { withFileTypes: true });
|
|
747
|
+
}
|
|
748
|
+
catch (error) {
|
|
749
|
+
if (error.code === 'ENOENT')
|
|
750
|
+
return [];
|
|
751
|
+
throw error;
|
|
752
|
+
}
|
|
753
|
+
return entries
|
|
754
|
+
.filter((entry) => entry.isDirectory() && !entry.isSymbolicLink())
|
|
755
|
+
.map((entry) => entry.name)
|
|
756
|
+
.sort(compareText);
|
|
757
|
+
}
|
|
758
|
+
async function retentionDeferred(paths, name) {
|
|
759
|
+
const inspection = await inspectNativeChange(paths, name);
|
|
760
|
+
if (inspection.status !== 'current' || !inspection.state || inspection.state.archived)
|
|
761
|
+
return true;
|
|
762
|
+
const [transition, migration, checkpoint] = await Promise.all([
|
|
763
|
+
inspectPendingNativeTransition(paths, name),
|
|
764
|
+
inspectPendingNativeSchemaMigration(paths, name),
|
|
765
|
+
readNativeCheckpointJournal(paths, name),
|
|
766
|
+
]);
|
|
767
|
+
return transition !== null || migration !== null || checkpoint !== null;
|
|
768
|
+
}
|
|
769
|
+
async function collectChangeRetention(options) {
|
|
770
|
+
if (await retentionDeferred(options.paths, options.name))
|
|
771
|
+
return [];
|
|
772
|
+
const inspection = await inspectNativeChange(options.paths, options.name);
|
|
773
|
+
if (inspection.status !== 'current' || !inspection.state)
|
|
774
|
+
return [];
|
|
775
|
+
if (!('implementation_scope' in inspection.state))
|
|
776
|
+
return [];
|
|
777
|
+
const cleanupRecovery = await inspectCleanupQuarantines({
|
|
778
|
+
paths: options.paths,
|
|
779
|
+
name: options.name,
|
|
780
|
+
repair: options.repair,
|
|
781
|
+
hooks: options.hooks,
|
|
782
|
+
});
|
|
783
|
+
if (cleanupRecovery.pending)
|
|
784
|
+
return cleanupRecovery.findings;
|
|
785
|
+
const rootRefs = [];
|
|
786
|
+
for (const value of [
|
|
787
|
+
inspection.state.implementation_scope,
|
|
788
|
+
inspection.state.partial_allowance,
|
|
789
|
+
inspection.state.verification_evidence,
|
|
790
|
+
]) {
|
|
791
|
+
if (value !== null)
|
|
792
|
+
rootRefs.push(value);
|
|
793
|
+
}
|
|
794
|
+
const documents = await scanEvidenceStore(options.paths, options.name);
|
|
795
|
+
const plan = planRetention(documents, rootRefs, options.nowMs);
|
|
796
|
+
if (plan.candidates.length === 0)
|
|
797
|
+
return cleanupRecovery.findings;
|
|
798
|
+
const evidenceRef = evidenceRootRef(options.paths, options.name);
|
|
799
|
+
if (!options.repair) {
|
|
800
|
+
return [...cleanupRecovery.findings, summaryFinding(options.name, plan, false, evidenceRef)];
|
|
801
|
+
}
|
|
802
|
+
const deleted = [];
|
|
803
|
+
for (const candidate of plan.candidates) {
|
|
804
|
+
try {
|
|
805
|
+
await deleteCandidate(candidate, options.hooks);
|
|
806
|
+
deleted.push(candidate);
|
|
807
|
+
}
|
|
808
|
+
catch (error) {
|
|
809
|
+
const deletedBytes = deleted.reduce((total, item) => total + item.size, 0);
|
|
810
|
+
return [
|
|
811
|
+
...cleanupRecovery.findings,
|
|
812
|
+
...(deleted.length > 0
|
|
813
|
+
? [
|
|
814
|
+
summaryFinding(options.name, { candidates: deleted, candidateBytes: deletedBytes }, true, evidenceRef),
|
|
815
|
+
]
|
|
816
|
+
: []),
|
|
817
|
+
{
|
|
818
|
+
severity: 'error',
|
|
819
|
+
code: 'evidence-retention-cleanup-failed',
|
|
820
|
+
message: boundedMessage(`Native evidence cleanup stopped safely for ${options.name}: ${error.message}`),
|
|
821
|
+
path: evidenceRef,
|
|
822
|
+
},
|
|
823
|
+
];
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
return [...cleanupRecovery.findings, summaryFinding(options.name, plan, true, evidenceRef)];
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Inspect or explicitly prune old unreferenced Native-owned evidence.
|
|
830
|
+
*
|
|
831
|
+
* The default path is read-only. Repair repeats the complete scan and plan while holding the
|
|
832
|
+
* project mutation lock, then deletes only documents whose identities remain unchanged.
|
|
833
|
+
*/
|
|
834
|
+
export async function inspectNativeEvidenceRetention(options) {
|
|
835
|
+
if (options.deferAll || (await hasPendingRelocationOrArchive(options.paths)))
|
|
836
|
+
return [];
|
|
837
|
+
const now = options.now ?? new Date();
|
|
838
|
+
if (Number.isNaN(now.getTime()))
|
|
839
|
+
throw new Error('Native evidence retention time is invalid');
|
|
840
|
+
const run = async (repair) => {
|
|
841
|
+
const findings = [];
|
|
842
|
+
for (const name of await changeNames(options.paths, options.name)) {
|
|
843
|
+
try {
|
|
844
|
+
findings.push(...(await collectChangeRetention({
|
|
845
|
+
paths: options.paths,
|
|
846
|
+
name,
|
|
847
|
+
repair,
|
|
848
|
+
nowMs: now.getTime(),
|
|
849
|
+
hooks: options.hooks ?? {},
|
|
850
|
+
})));
|
|
851
|
+
}
|
|
852
|
+
catch (error) {
|
|
853
|
+
findings.push({
|
|
854
|
+
severity: 'error',
|
|
855
|
+
code: 'evidence-retention-unsafe',
|
|
856
|
+
message: boundedMessage(`Native evidence retention refused to clean ${name}: ${error.message}`),
|
|
857
|
+
path: evidenceRootRef(options.paths, name),
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
return findings;
|
|
862
|
+
};
|
|
863
|
+
if (!(options.repair ?? false))
|
|
864
|
+
return run(false);
|
|
865
|
+
// Avoid acquiring a mutation lock when there is nothing to prune. This also lets doctor
|
|
866
|
+
// diagnose and clear unrelated proven-stale locks without retention changing that flow.
|
|
867
|
+
const preflight = await run(false);
|
|
868
|
+
if (preflight.some((finding) => finding.severity === 'error'))
|
|
869
|
+
return preflight;
|
|
870
|
+
if (!preflight.some((finding) => finding.code === 'evidence-retention-candidates' ||
|
|
871
|
+
finding.code === 'evidence-retention-recovery-required')) {
|
|
872
|
+
return preflight;
|
|
873
|
+
}
|
|
874
|
+
try {
|
|
875
|
+
return await withNativeMutationLock(options.paths, 'prune Native evidence', () => run(true));
|
|
876
|
+
}
|
|
877
|
+
catch (error) {
|
|
878
|
+
return [
|
|
879
|
+
{
|
|
880
|
+
severity: 'info',
|
|
881
|
+
code: 'evidence-retention-cleanup-deferred',
|
|
882
|
+
message: boundedMessage(`Native evidence cleanup was deferred until the project mutation lock is available: ${error.message}`),
|
|
883
|
+
},
|
|
884
|
+
];
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
//# sourceMappingURL=native-evidence-retention.js.map
|