project-tiny-context-harness 0.2.85 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +164 -427
- package/assets/README.md +284 -455
- package/assets/README.zh-CN.md +200 -123
- package/assets/agents/AGENTS_CORE.md +54 -67
- package/assets/context_templates/context.toml +3 -0
- package/assets/context_templates/global.md +6 -6
- package/assets/github/harness.yml +2 -2
- package/assets/skills/context_development_engineer/SKILL.md +91 -107
- package/assets/skills/context_product_plan/SKILL.md +18 -28
- package/assets/skills/context_surface_contract/SKILL.md +35 -38
- package/assets/skills/context_uiux_design/SKILL.md +31 -30
- package/assets/skills/long-task-workflow/SKILL.md +76 -0
- package/assets/skills/long-task-workflow/agents/openai.yaml +4 -0
- package/assets/skills/long-task-workflow/references/authority-lifecycle.md +41 -0
- package/assets/skills/long-task-workflow/references/contract-authoring.md +63 -0
- package/assets/skills/long-task-workflow/references/evidence-design.md +45 -0
- package/assets/skills/normal-long-task/SKILL.md +12 -489
- package/assets/skills/source-plan-authoring/SKILL.md +467 -0
- package/assets/tools/validate_context.py +293 -127
- package/dist/cli.js +3 -1
- package/dist/commands/check-modularity.js +33 -10
- package/dist/commands/composite-campaign.d.ts +1 -0
- package/dist/commands/composite-campaign.js +8 -0
- package/dist/commands/composite-long-task.d.ts +1 -6
- package/dist/commands/composite-long-task.js +7 -163
- package/dist/commands/delivery-set.d.ts +1 -0
- package/dist/commands/delivery-set.js +8 -0
- package/dist/commands/disable.d.ts +1 -0
- package/dist/commands/disable.js +15 -0
- package/dist/commands/enable.d.ts +1 -0
- package/dist/commands/enable.js +14 -0
- package/dist/commands/export-context-args.js +13 -4
- package/dist/commands/export-context.js +18 -7
- package/dist/commands/index.js +42 -30
- package/dist/commands/init.js +12 -6
- package/dist/commands/long-task-authoring.d.ts +3 -0
- package/dist/commands/long-task-authoring.js +92 -0
- package/dist/commands/long-task-explain.d.ts +1 -0
- package/dist/commands/long-task-explain.js +52 -0
- package/dist/commands/long-task.d.ts +1 -0
- package/dist/commands/long-task.js +226 -0
- package/dist/commands/package-source.js +2 -2
- package/dist/commands/upgrade.js +10 -10
- package/dist/index.d.ts +11 -1
- package/dist/index.js +8 -0
- package/dist/lib/config.js +34 -8
- package/dist/lib/context-default-footprint.d.ts +16 -0
- package/dist/lib/context-default-footprint.js +107 -0
- package/dist/lib/context-export.js +105 -41
- package/dist/lib/context-graph-snapshot.d.ts +18 -0
- package/dist/lib/context-graph-snapshot.js +171 -0
- package/dist/lib/context-manifest-schema.d.ts +28 -0
- package/dist/lib/context-manifest-schema.js +150 -0
- package/dist/lib/context-manifest.js +28 -20
- package/dist/lib/context-templates.js +5 -5
- package/dist/lib/design-md.js +1 -1
- package/dist/lib/doctor.js +54 -1
- package/dist/lib/harness-root.js +25 -8
- package/dist/lib/init.js +6 -3
- package/dist/lib/legacy-managed-scan.js +23 -7
- package/dist/lib/legacy-sdlc-migration.js +21 -11
- package/dist/lib/long-task-acceptance-reference.d.ts +22 -0
- package/dist/lib/long-task-acceptance-reference.js +46 -0
- package/dist/lib/long-task-acceptance-shape.d.ts +5 -0
- package/dist/lib/long-task-acceptance-shape.js +131 -0
- package/dist/lib/long-task-activation-validation.d.ts +21 -0
- package/dist/lib/long-task-activation-validation.js +136 -0
- package/dist/lib/long-task-artifacts.d.ts +5 -0
- package/dist/lib/long-task-artifacts.js +34 -0
- package/dist/lib/long-task-assertions-v2.d.ts +22 -0
- package/dist/lib/long-task-assertions-v2.js +212 -0
- package/dist/lib/long-task-authoring-authority-preview.d.ts +5 -0
- package/dist/lib/long-task-authoring-authority-preview.js +85 -0
- package/dist/lib/long-task-authoring-preflight-diagnostics.d.ts +8 -0
- package/dist/lib/long-task-authoring-preflight-diagnostics.js +179 -0
- package/dist/lib/long-task-authoring-preflight-repair-order.d.ts +8 -0
- package/dist/lib/long-task-authoring-preflight-repair-order.js +95 -0
- package/dist/lib/long-task-authoring-preflight-types.d.ts +46 -0
- package/dist/lib/long-task-authoring-preflight-types.js +38 -0
- package/dist/lib/long-task-authoring-preflight.d.ts +3 -0
- package/dist/lib/long-task-authoring-preflight.js +44 -0
- package/dist/lib/long-task-authority-material-diff.d.ts +17 -0
- package/dist/lib/long-task-authority-material-diff.js +152 -0
- package/dist/lib/long-task-authority-materials.d.ts +7 -0
- package/dist/lib/long-task-authority-materials.js +83 -0
- package/dist/lib/long-task-authority-policy.d.ts +168 -0
- package/dist/lib/long-task-authority-policy.js +181 -0
- package/dist/lib/long-task-authority-revision-details.d.ts +19 -0
- package/dist/lib/long-task-authority-revision-details.js +192 -0
- package/dist/lib/long-task-authority-revision-enforcement.d.ts +3 -0
- package/dist/lib/long-task-authority-revision-enforcement.js +41 -0
- package/dist/lib/long-task-authority-revision-types.d.ts +50 -0
- package/dist/lib/long-task-authority-revision-types.js +1 -0
- package/dist/lib/long-task-authority-revision.d.ts +4 -0
- package/dist/lib/long-task-authority-revision.js +188 -0
- package/dist/lib/long-task-authority-transition-policy.d.ts +62 -0
- package/dist/lib/long-task-authority-transition-policy.js +62 -0
- package/dist/lib/long-task-authority-types.d.ts +96 -0
- package/dist/lib/long-task-authority-types.js +1 -0
- package/dist/lib/long-task-authority.d.ts +7 -0
- package/dist/lib/long-task-authority.js +142 -0
- package/dist/lib/long-task-boundary-check.d.ts +15 -0
- package/dist/lib/long-task-boundary-check.js +9 -0
- package/dist/lib/long-task-check-evidence-decoder.d.ts +3 -0
- package/dist/lib/long-task-check-evidence-decoder.js +74 -0
- package/dist/lib/long-task-check-execution-policy.d.ts +18 -0
- package/dist/lib/long-task-check-execution-policy.js +36 -0
- package/dist/lib/long-task-check-runner.d.ts +2 -0
- package/dist/lib/long-task-check-runner.js +181 -0
- package/dist/lib/long-task-check-shape.d.ts +2 -0
- package/dist/lib/long-task-check-shape.js +136 -0
- package/dist/lib/long-task-claim-definitions.d.ts +7 -0
- package/dist/lib/long-task-claim-definitions.js +78 -0
- package/dist/lib/long-task-claim-proof-policy.d.ts +4 -0
- package/dist/lib/long-task-claim-proof-policy.js +57 -0
- package/dist/lib/long-task-claims.d.ts +10 -0
- package/dist/lib/long-task-claims.js +187 -0
- package/dist/lib/long-task-context-authority-topology.d.ts +7 -0
- package/dist/lib/long-task-context-authority-topology.js +37 -0
- package/dist/lib/long-task-context-authority.d.ts +14 -0
- package/dist/lib/long-task-context-authority.js +66 -0
- package/dist/lib/long-task-contract-types.d.ts +203 -0
- package/dist/lib/long-task-contract-types.js +1 -0
- package/dist/lib/long-task-counterfactual-claim-policy.d.ts +10 -0
- package/dist/lib/long-task-counterfactual-claim-policy.js +57 -0
- package/dist/lib/long-task-counterfactual-sandbox.d.ts +6 -0
- package/dist/lib/long-task-counterfactual-sandbox.js +87 -0
- package/dist/lib/long-task-counterfactual-types.d.ts +24 -0
- package/dist/lib/long-task-counterfactual-types.js +1 -0
- package/dist/lib/long-task-delivery-compiler.d.ts +10 -0
- package/dist/lib/long-task-delivery-compiler.js +129 -0
- package/dist/lib/long-task-delivery-parser.d.ts +13 -0
- package/dist/lib/long-task-delivery-parser.js +90 -0
- package/dist/lib/long-task-delivery-preflight.d.ts +5 -0
- package/dist/lib/long-task-delivery-preflight.js +151 -0
- package/dist/lib/long-task-delivery-shape.d.ts +5 -0
- package/dist/lib/long-task-delivery-shape.js +5 -0
- package/dist/lib/long-task-delivery-types.d.ts +8 -0
- package/dist/lib/long-task-delivery-types.js +8 -0
- package/dist/lib/long-task-delivery-validation.d.ts +3 -0
- package/dist/lib/long-task-delivery-validation.js +175 -0
- package/dist/lib/long-task-evidence-adapter-policy.d.ts +4 -0
- package/dist/lib/long-task-evidence-adapter-policy.js +15 -0
- package/dist/lib/long-task-evidence-adapter-types.d.ts +1 -0
- package/dist/lib/long-task-evidence-adapter-types.js +1 -0
- package/dist/lib/long-task-evidence-findings.d.ts +5 -0
- package/dist/lib/long-task-evidence-findings.js +113 -0
- package/dist/lib/long-task-evidence-sensitivity-policy.d.ts +4 -0
- package/dist/lib/long-task-evidence-sensitivity-policy.js +98 -0
- package/dist/lib/long-task-evidence-v2.d.ts +5 -0
- package/dist/lib/long-task-evidence-v2.js +226 -0
- package/dist/lib/long-task-explain-acceptance-link.d.ts +46 -0
- package/dist/lib/long-task-explain-acceptance-link.js +96 -0
- package/dist/lib/long-task-explain-claim-links.d.ts +45 -0
- package/dist/lib/long-task-explain-claim-links.js +88 -0
- package/dist/lib/long-task-explain-source-links.d.ts +93 -0
- package/dist/lib/long-task-explain-source-links.js +51 -0
- package/dist/lib/long-task-final-v2.d.ts +2 -0
- package/dist/lib/long-task-final-v2.js +124 -0
- package/dist/lib/long-task-finding-context.d.ts +3 -0
- package/dist/lib/long-task-finding-context.js +63 -0
- package/dist/lib/long-task-freshness.d.ts +3 -0
- package/dist/lib/long-task-freshness.js +80 -0
- package/dist/lib/long-task-hook-install.d.ts +9 -0
- package/dist/lib/long-task-hook-install.js +184 -0
- package/dist/lib/long-task-hook-preflight.d.ts +7 -0
- package/dist/lib/long-task-hook-preflight.js +58 -0
- package/dist/lib/long-task-observation-ownership.d.ts +2 -0
- package/dist/lib/long-task-observation-ownership.js +22 -0
- package/dist/lib/long-task-outcome-parser.d.ts +4 -0
- package/dist/lib/long-task-outcome-parser.js +100 -0
- package/dist/lib/long-task-paths.d.ts +49 -0
- package/dist/lib/long-task-paths.js +418 -0
- package/dist/lib/long-task-playwright-counterfactual-policy.d.ts +7 -0
- package/dist/lib/long-task-playwright-counterfactual-policy.js +125 -0
- package/dist/lib/long-task-playwright-evidence.d.ts +6 -0
- package/dist/lib/long-task-playwright-evidence.js +244 -0
- package/dist/lib/long-task-product-shape.d.ts +6 -0
- package/dist/lib/long-task-product-shape.js +73 -0
- package/dist/lib/long-task-progress.d.ts +4 -0
- package/dist/lib/long-task-progress.js +114 -0
- package/dist/lib/long-task-protected-files.d.ts +1 -0
- package/dist/lib/long-task-protected-files.js +30 -0
- package/dist/lib/long-task-required-proof-surfaces.d.ts +2 -0
- package/dist/lib/long-task-required-proof-surfaces.js +13 -0
- package/dist/lib/long-task-requirement-shape.d.ts +2 -0
- package/dist/lib/long-task-requirement-shape.js +18 -0
- package/dist/lib/long-task-risk-surfaces.d.ts +2 -0
- package/dist/lib/long-task-risk-surfaces.js +60 -0
- package/dist/lib/long-task-risk-types.d.ts +5 -0
- package/dist/lib/long-task-risk-types.js +12 -0
- package/dist/lib/long-task-risk.d.ts +9 -0
- package/dist/lib/long-task-risk.js +132 -0
- package/dist/lib/long-task-root-shape.d.ts +4 -0
- package/dist/lib/long-task-root-shape.js +86 -0
- package/dist/lib/long-task-runner-environment.d.ts +7 -0
- package/dist/lib/long-task-runner-environment.js +57 -0
- package/dist/lib/long-task-runner-files.d.ts +3 -0
- package/dist/lib/long-task-runner-files.js +39 -0
- package/dist/lib/long-task-runner-freeze.d.ts +2 -0
- package/dist/lib/long-task-runner-freeze.js +168 -0
- package/dist/lib/long-task-runtime-types.d.ts +214 -0
- package/dist/lib/long-task-runtime-types.js +1 -0
- package/dist/lib/long-task-shape-primitives.d.ts +17 -0
- package/dist/lib/long-task-shape-primitives.js +81 -0
- package/dist/lib/long-task-source-authority-types.d.ts +13 -0
- package/dist/lib/long-task-source-authority-types.js +1 -0
- package/dist/lib/long-task-source-claim-validation.d.ts +5 -0
- package/dist/lib/long-task-source-claim-validation.js +96 -0
- package/dist/lib/long-task-source-continuity.d.ts +4 -0
- package/dist/lib/long-task-source-continuity.js +57 -0
- package/dist/lib/long-task-source-inventory.d.ts +2 -0
- package/dist/lib/long-task-source-inventory.js +21 -0
- package/dist/lib/long-task-source-item-parser.d.ts +3 -0
- package/dist/lib/long-task-source-item-parser.js +112 -0
- package/dist/lib/long-task-source-shape.d.ts +2 -0
- package/dist/lib/long-task-source-shape.js +56 -0
- package/dist/lib/long-task-source-target-continuity.d.ts +4 -0
- package/dist/lib/long-task-source-target-continuity.js +80 -0
- package/dist/lib/long-task-source-target-index.d.ts +12 -0
- package/dist/lib/long-task-source-target-index.js +76 -0
- package/dist/lib/long-task-source-validation.d.ts +3 -0
- package/dist/lib/long-task-source-validation.js +46 -0
- package/dist/lib/long-task-state.d.ts +91 -0
- package/dist/lib/long-task-state.js +611 -0
- package/dist/lib/long-task-status-projection.d.ts +21 -0
- package/dist/lib/long-task-status-projection.js +116 -0
- package/dist/lib/long-task-status-v2.d.ts +37 -0
- package/dist/lib/long-task-status-v2.js +306 -0
- package/dist/lib/long-task-technical-shape.d.ts +3 -0
- package/dist/lib/long-task-technical-shape.js +44 -0
- package/dist/lib/long-task-verifier-authority.d.ts +12 -0
- package/dist/lib/long-task-verifier-authority.js +47 -0
- package/dist/lib/long-task-verifier-identity.d.ts +2 -0
- package/dist/lib/long-task-verifier-identity.js +55 -0
- package/dist/lib/long-task-verifier-v2.d.ts +13 -0
- package/dist/lib/long-task-verifier-v2.js +266 -0
- package/dist/lib/long-task-workspace-runtime-types.d.ts +23 -0
- package/dist/lib/long-task-workspace-runtime-types.js +1 -0
- package/dist/lib/long-task-workspace.d.ts +25 -0
- package/dist/lib/long-task-workspace.js +366 -0
- package/dist/lib/managed-file.js +20 -5
- package/dist/lib/migrations.js +156 -32
- package/dist/lib/modularity.d.ts +27 -1
- package/dist/lib/modularity.js +499 -23
- package/dist/lib/package-json-config.js +14 -5
- package/dist/lib/package-source.js +4 -2
- package/dist/lib/profiles.d.ts +13 -0
- package/dist/lib/profiles.js +66 -0
- package/dist/lib/schema-guard.js +4 -2
- package/dist/lib/source-files.js +14 -7
- package/dist/lib/source-pack-classify.js +91 -19
- package/dist/lib/source-pack-config.js +25 -8
- package/dist/lib/source-pack-export.js +84 -25
- package/dist/lib/source-pack-manifest.js +18 -6
- package/dist/lib/source-pack-records.js +35 -11
- package/dist/lib/source-pack-render.js +47 -18
- package/dist/lib/stable-json.d.ts +2 -0
- package/dist/lib/stable-json.js +21 -0
- package/dist/lib/strict-codec.d.ts +4 -0
- package/dist/lib/strict-codec.js +65 -0
- package/dist/lib/sync-engine.js +76 -24
- package/dist/lib/types.d.ts +8 -1
- package/dist/lib/upgrade.js +4 -3
- package/dist/lib/validators.js +218 -191
- package/dist/long-task-hook.d.ts +2 -0
- package/dist/long-task-hook.js +55 -0
- package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +340 -0
- package/dist/schemas/long-task-delivery-v2/long-task-outcomes-v2.schema.json +18 -0
- package/migrations/README.md +8 -3
- package/package.json +17 -6
- package/source-mappings.yaml +0 -3
- package/assets/protected-harness-baseline.json +0 -20
- package/assets/skills/composite-long-task-workflow/SKILL.md +0 -245
- package/assets/skills/composite-long-task-workflow/assets/execution-binding.template.md +0 -62
- package/assets/skills/composite-long-task-workflow/assets/goal-objective.template.md +0 -17
- package/assets/skills/composite-long-task-workflow/references/composite-long-task-workflow-protocol.md +0 -682
- package/dist/commands/superpowers.d.ts +0 -1
- package/dist/commands/superpowers.js +0 -8
- package/dist/lib/composite-long-task-renderer.d.ts +0 -12
- package/dist/lib/composite-long-task-renderer.js +0 -109
- package/dist/lib/plan-acceptance-artifacts.d.ts +0 -1
- package/dist/lib/plan-acceptance-artifacts.js +0 -220
- package/dist/lib/plan-acceptance-evidence.d.ts +0 -2
- package/dist/lib/plan-acceptance-evidence.js +0 -108
- package/dist/lib/plan-acceptance-json.d.ts +0 -15
- package/dist/lib/plan-acceptance-json.js +0 -133
- package/dist/lib/plan-acceptance-validator.d.ts +0 -2
- package/dist/lib/plan-acceptance-validator.js +0 -209
- package/dist/lib/plan-contract-validator.d.ts +0 -2
- package/dist/lib/plan-contract-validator.js +0 -127
- package/dist/lib/plan-validator-common.d.ts +0 -24
- package/dist/lib/plan-validator-common.js +0 -196
- package/dist/lib/superpowers-task-ac010.d.ts +0 -6
- package/dist/lib/superpowers-task-ac010.js +0 -26
- package/dist/lib/superpowers-task-assertion-normalizers.d.ts +0 -3
- package/dist/lib/superpowers-task-assertion-normalizers.js +0 -74
- package/dist/lib/superpowers-task-assertions.d.ts +0 -20
- package/dist/lib/superpowers-task-assertions.js +0 -257
- package/dist/lib/superpowers-task-attempt.d.ts +0 -4
- package/dist/lib/superpowers-task-attempt.js +0 -102
- package/dist/lib/superpowers-task-command-run-correlation.d.ts +0 -8
- package/dist/lib/superpowers-task-command-run-correlation.js +0 -103
- package/dist/lib/superpowers-task-command-specs.d.ts +0 -3
- package/dist/lib/superpowers-task-command-specs.js +0 -52
- package/dist/lib/superpowers-task-compile-diagnostics.d.ts +0 -5
- package/dist/lib/superpowers-task-compile-diagnostics.js +0 -20
- package/dist/lib/superpowers-task-compile-guards.d.ts +0 -2
- package/dist/lib/superpowers-task-compile-guards.js +0 -66
- package/dist/lib/superpowers-task-compile.d.ts +0 -6
- package/dist/lib/superpowers-task-compile.js +0 -133
- package/dist/lib/superpowers-task-completion-output.d.ts +0 -91
- package/dist/lib/superpowers-task-completion-output.js +0 -374
- package/dist/lib/superpowers-task-conformance.d.ts +0 -2
- package/dist/lib/superpowers-task-conformance.js +0 -24
- package/dist/lib/superpowers-task-contradictions.d.ts +0 -6
- package/dist/lib/superpowers-task-contradictions.js +0 -126
- package/dist/lib/superpowers-task-current-evidence.d.ts +0 -3
- package/dist/lib/superpowers-task-current-evidence.js +0 -176
- package/dist/lib/superpowers-task-delivery.d.ts +0 -4
- package/dist/lib/superpowers-task-delivery.js +0 -96
- package/dist/lib/superpowers-task-derive.d.ts +0 -14
- package/dist/lib/superpowers-task-derive.js +0 -393
- package/dist/lib/superpowers-task-events.d.ts +0 -1
- package/dist/lib/superpowers-task-events.js +0 -13
- package/dist/lib/superpowers-task-evidence-kernel.d.ts +0 -19
- package/dist/lib/superpowers-task-evidence-kernel.js +0 -347
- package/dist/lib/superpowers-task-evidence-records.d.ts +0 -2
- package/dist/lib/superpowers-task-evidence-records.js +0 -55
- package/dist/lib/superpowers-task-evidence.d.ts +0 -10
- package/dist/lib/superpowers-task-evidence.js +0 -147
- package/dist/lib/superpowers-task-fields.d.ts +0 -22
- package/dist/lib/superpowers-task-fields.js +0 -276
- package/dist/lib/superpowers-task-final-card.d.ts +0 -3
- package/dist/lib/superpowers-task-final-card.js +0 -35
- package/dist/lib/superpowers-task-gates.d.ts +0 -12
- package/dist/lib/superpowers-task-gates.js +0 -267
- package/dist/lib/superpowers-task-harness-drift.d.ts +0 -11
- package/dist/lib/superpowers-task-harness-drift.js +0 -90
- package/dist/lib/superpowers-task-next-slices.d.ts +0 -1
- package/dist/lib/superpowers-task-next-slices.js +0 -12
- package/dist/lib/superpowers-task-protected-baseline.d.ts +0 -10
- package/dist/lib/superpowers-task-protected-baseline.js +0 -66
- package/dist/lib/superpowers-task-source-compile.d.ts +0 -5
- package/dist/lib/superpowers-task-source-compile.js +0 -226
- package/dist/lib/superpowers-task-source-parser.d.ts +0 -23
- package/dist/lib/superpowers-task-source-parser.js +0 -218
- package/dist/lib/superpowers-task-state-schema.d.ts +0 -460
- package/dist/lib/superpowers-task-state-schema.js +0 -66
- package/dist/lib/superpowers-task-state-shape.d.ts +0 -3
- package/dist/lib/superpowers-task-state-shape.js +0 -50
- package/dist/lib/superpowers-task-state.d.ts +0 -16
- package/dist/lib/superpowers-task-state.js +0 -246
- package/dist/lib/superpowers-task-status.d.ts +0 -2
- package/dist/lib/superpowers-task-status.js +0 -24
- package/dist/lib/superpowers-task-under-specified.d.ts +0 -7
- package/dist/lib/superpowers-task-under-specified.js +0 -61
- package/dist/lib/superpowers-task-unregistered-evidence.d.ts +0 -11
- package/dist/lib/superpowers-task-unregistered-evidence.js +0 -72
- package/dist/lib/superpowers-task-validator.d.ts +0 -5
- package/dist/lib/superpowers-task-validator.js +0 -293
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { normalizeProofLayerId } from "./superpowers-task-fields.js";
|
|
2
|
-
import { isRecord } from "./superpowers-task-state-schema.js";
|
|
3
|
-
export function normalizeAssertionResult(value) {
|
|
4
|
-
if (!isRecord(value)) {
|
|
5
|
-
return undefined;
|
|
6
|
-
}
|
|
7
|
-
return {
|
|
8
|
-
schema_version: String(value.schema_version ?? ""),
|
|
9
|
-
status: String(value.status ?? ""),
|
|
10
|
-
runner: String(value.runner ?? ""),
|
|
11
|
-
exit_code: numberValue(value.exit_code),
|
|
12
|
-
target_ac_ids: stringArray(value.target_ac_ids),
|
|
13
|
-
target_pi_ids: stringArray(value.target_pi_ids),
|
|
14
|
-
target_proof_layers: stringArray(value.target_proof_layers).map(normalizeProofLayerId),
|
|
15
|
-
owner_surface: value.owner_surface === undefined ? undefined : String(value.owner_surface),
|
|
16
|
-
route: value.route === undefined ? undefined : String(value.route),
|
|
17
|
-
action: value.action === undefined ? undefined : String(value.action),
|
|
18
|
-
positive_assertions: checkArray(value.positive_assertions),
|
|
19
|
-
negative_assertions: checkArray(value.negative_assertions),
|
|
20
|
-
invalid_completion_signals: checkArray(value.invalid_completion_signals),
|
|
21
|
-
negative_evidence_scan: normalizeNegativeEvidenceScan(value.negative_evidence_scan),
|
|
22
|
-
required_test_ids: stringArray(value.required_test_ids),
|
|
23
|
-
artifacts: stringArray(value.artifacts)
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
export function normalizeNegativeEvidenceScan(value) {
|
|
27
|
-
if (!isRecord(value)) {
|
|
28
|
-
return undefined;
|
|
29
|
-
}
|
|
30
|
-
return {
|
|
31
|
-
schema_version: String(value.schema_version ?? ""),
|
|
32
|
-
status: String(value.status ?? ""),
|
|
33
|
-
target_ac_ids: stringArray(value.target_ac_ids),
|
|
34
|
-
target_proof_layers: stringArray(value.target_proof_layers).map(normalizeProofLayerId),
|
|
35
|
-
invalid_completion_signals_checked: stringArray(value.invalid_completion_signals_checked),
|
|
36
|
-
owner_surface: value.owner_surface === undefined ? undefined : String(value.owner_surface),
|
|
37
|
-
route: value.route === undefined ? undefined : String(value.route),
|
|
38
|
-
forbidden_findings: findingArray(value.forbidden_findings),
|
|
39
|
-
required_findings: checkArray(value.required_findings),
|
|
40
|
-
artifacts: stringArray(value.artifacts)
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
function checkArray(value) {
|
|
44
|
-
if (!Array.isArray(value)) {
|
|
45
|
-
return [];
|
|
46
|
-
}
|
|
47
|
-
return value.filter(isRecord).map((item) => ({
|
|
48
|
-
id: String(item.id ?? ""),
|
|
49
|
-
status: String(item.status ?? ""),
|
|
50
|
-
actual: item.actual === undefined ? undefined : String(item.actual),
|
|
51
|
-
expected: item.expected === undefined ? undefined : String(item.expected),
|
|
52
|
-
forbidden_text: item.forbidden_text === undefined ? undefined : String(item.forbidden_text)
|
|
53
|
-
}));
|
|
54
|
-
}
|
|
55
|
-
function findingArray(value) {
|
|
56
|
-
if (!Array.isArray(value)) {
|
|
57
|
-
return [];
|
|
58
|
-
}
|
|
59
|
-
return value.filter(isRecord).map((item) => ({
|
|
60
|
-
id: String(item.id ?? ""),
|
|
61
|
-
status: String(item.status ?? ""),
|
|
62
|
-
forbidden_text: item.forbidden_text === undefined ? undefined : String(item.forbidden_text),
|
|
63
|
-
actual: item.actual === undefined ? undefined : String(item.actual)
|
|
64
|
-
}));
|
|
65
|
-
}
|
|
66
|
-
function stringArray(value) {
|
|
67
|
-
if (!Array.isArray(value)) {
|
|
68
|
-
return [];
|
|
69
|
-
}
|
|
70
|
-
return value.map((item) => String(item)).filter(Boolean);
|
|
71
|
-
}
|
|
72
|
-
function numberValue(value) {
|
|
73
|
-
return typeof value === "number" && Number.isFinite(value) ? value : Number.NaN;
|
|
74
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { type SuperpowersEvidenceRecord, type SuperpowersTaskState } from "./superpowers-task-state-schema.js";
|
|
2
|
-
export { normalizeAssertionResult, normalizeNegativeEvidenceScan } from "./superpowers-task-assertion-normalizers.js";
|
|
3
|
-
export type AssertionStatus = "passed" | "failed" | "missing" | "stale" | "not_applicable";
|
|
4
|
-
export interface ProofLayerAssertionEvaluation {
|
|
5
|
-
assertion_status: AssertionStatus;
|
|
6
|
-
blocking_assertion_failures: string[];
|
|
7
|
-
negative_evidence_findings: string[];
|
|
8
|
-
}
|
|
9
|
-
export declare const MACHINE_VERIFIABLE_PROOF_LAYERS: Set<string>;
|
|
10
|
-
export declare const UI_BROWSER_ASSERTION_TYPES: Set<string>;
|
|
11
|
-
export declare function proofLayerName(layerId: string): string;
|
|
12
|
-
export declare function proofLayerAcId(layerId: string): string;
|
|
13
|
-
export declare function isMachineVerifiableLayer(layerId: string): boolean;
|
|
14
|
-
export declare function isUiBrowserLayer(layerId: string): boolean;
|
|
15
|
-
export declare function evaluateAcEvidence(state: SuperpowersTaskState, acId: string): ProofLayerAssertionEvaluation;
|
|
16
|
-
export declare function evaluateProofLayer(state: SuperpowersTaskState, layerId: string): ProofLayerAssertionEvaluation;
|
|
17
|
-
export declare function evaluateProofLayerAssertions(state: SuperpowersTaskState, layerId: string): ProofLayerAssertionEvaluation;
|
|
18
|
-
export declare function assertionFailuresForState(state: SuperpowersTaskState): string[];
|
|
19
|
-
export declare function evaluateAssertionEvidence(evidence: SuperpowersEvidenceRecord, layerId: string): string[];
|
|
20
|
-
export declare function evaluateNegativeEvidence(evidence: SuperpowersEvidenceRecord, layerId: string): string[];
|
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
import { evaluateCurrentAttemptEvidence } from "./superpowers-task-current-evidence.js";
|
|
2
|
-
import { MACHINE_VERIFIABLE_LAYER_NAMES, normalizeProofLayerId, normalizeProofLayerName } from "./superpowers-task-fields.js";
|
|
3
|
-
export { normalizeAssertionResult, normalizeNegativeEvidenceScan } from "./superpowers-task-assertion-normalizers.js";
|
|
4
|
-
export const MACHINE_VERIFIABLE_PROOF_LAYERS = new Set(MACHINE_VERIFIABLE_LAYER_NAMES);
|
|
5
|
-
export const UI_BROWSER_ASSERTION_TYPES = new Set(["browser_assertion", "playwright_assertion", "ui_browser_assertion"]);
|
|
6
|
-
const DEFAULT_UI_FORBIDDEN_FINAL_STATES = ["未验证", "不可用", "暂不可用", "页面无明显变化"];
|
|
7
|
-
const GENERIC_INVALID_EVIDENCE_TYPE_PATTERNS = [
|
|
8
|
-
/\bfinal[-_ ]?(?:result[-_ ]?)?card\b/i,
|
|
9
|
-
/\b(?:plan[-_ ]?conformance[-_ ]?)?matrix\b/i,
|
|
10
|
-
/\b(?:final[-_ ]?acceptance[-_ ]?)?verdict\b/i,
|
|
11
|
-
/\bvalidator[-_ ]?pass\b/i,
|
|
12
|
-
/\bauditor[-_ ]?pass\b/i,
|
|
13
|
-
/\bsubagent[-_ ]?summary\b/i,
|
|
14
|
-
/\bagent[-_ ]?summary\b/i,
|
|
15
|
-
/\bprose[-_ ]?summary\b/i,
|
|
16
|
-
/\bfile[-_ ]?exists\b/i,
|
|
17
|
-
/\bartifact[-_ ]?exists\b/i,
|
|
18
|
-
/\btest[-_ ]?name[-_ ]?only\b/i,
|
|
19
|
-
/\bdiagnostic[-_ ]?(?:surface|page)?\b/i,
|
|
20
|
-
/\blocal[-_ ]?audit\b/i,
|
|
21
|
-
/\bcomponent[-_ ]?screenshot\b/i,
|
|
22
|
-
/\bstorybook\b/i,
|
|
23
|
-
/\bdom[-_ ]?snippet\b/i,
|
|
24
|
-
/\bsample[-_ ]?for[-_ ]?full[-_ ]?population\b/i
|
|
25
|
-
];
|
|
26
|
-
export function proofLayerName(layerId) {
|
|
27
|
-
const raw = layerId.includes(".") ? layerId.slice(layerId.lastIndexOf(".") + 1) : layerId;
|
|
28
|
-
return normalizeProofLayerName(raw);
|
|
29
|
-
}
|
|
30
|
-
export function proofLayerAcId(layerId) {
|
|
31
|
-
return layerId.includes(".") ? layerId.slice(0, layerId.lastIndexOf(".")) : "";
|
|
32
|
-
}
|
|
33
|
-
export function isMachineVerifiableLayer(layerId) {
|
|
34
|
-
return MACHINE_VERIFIABLE_PROOF_LAYERS.has(proofLayerName(layerId));
|
|
35
|
-
}
|
|
36
|
-
export function isUiBrowserLayer(layerId) {
|
|
37
|
-
return proofLayerName(layerId) === "ui_browser";
|
|
38
|
-
}
|
|
39
|
-
export function evaluateAcEvidence(state, acId) {
|
|
40
|
-
const ac = state.graph.acceptance_criteria[acId];
|
|
41
|
-
if (!ac) {
|
|
42
|
-
return {
|
|
43
|
-
assertion_status: "missing",
|
|
44
|
-
blocking_assertion_failures: [`AC ${acId} missing from task graph`],
|
|
45
|
-
negative_evidence_findings: []
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
const evaluations = ac.required_proof_layers.map((layer) => evaluateProofLayer(state, `${acId}.${layer}`));
|
|
49
|
-
const applicable = evaluations.filter((item) => item.assertion_status !== "not_applicable");
|
|
50
|
-
const blocking_assertion_failures = applicable.flatMap((item) => item.blocking_assertion_failures);
|
|
51
|
-
const negative_evidence_findings = applicable.flatMap((item) => item.negative_evidence_findings);
|
|
52
|
-
const statuses = applicable.map((item) => item.assertion_status);
|
|
53
|
-
const assertion_status = applicable.length === 0
|
|
54
|
-
? "not_applicable"
|
|
55
|
-
: statuses.includes("failed")
|
|
56
|
-
? "failed"
|
|
57
|
-
: statuses.includes("stale")
|
|
58
|
-
? "stale"
|
|
59
|
-
: statuses.includes("missing")
|
|
60
|
-
? "missing"
|
|
61
|
-
: "passed";
|
|
62
|
-
return { assertion_status, blocking_assertion_failures, negative_evidence_findings };
|
|
63
|
-
}
|
|
64
|
-
export function evaluateProofLayer(state, layerId) {
|
|
65
|
-
return evaluateProofLayerAssertions(state, layerId);
|
|
66
|
-
}
|
|
67
|
-
export function evaluateProofLayerAssertions(state, layerId) {
|
|
68
|
-
if (!isMachineVerifiableLayer(layerId)) {
|
|
69
|
-
return { assertion_status: "not_applicable", blocking_assertion_failures: [], negative_evidence_findings: [] };
|
|
70
|
-
}
|
|
71
|
-
if (!state.current_attempt_id) {
|
|
72
|
-
return {
|
|
73
|
-
assertion_status: "missing",
|
|
74
|
-
blocking_assertion_failures: [`proof layer ${layerId} missing current attempt; current attempt is required for machine-backed completion`],
|
|
75
|
-
negative_evidence_findings: []
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
const layer = state.graph.proof_layers[layerId];
|
|
79
|
-
const evidenceById = new Map((state.evidence ?? []).map((item) => [item.evidence_id, item]));
|
|
80
|
-
const evidenceRecords = (layer?.evidence_ids ?? []).map((id) => evidenceById.get(id)).filter((item) => Boolean(item));
|
|
81
|
-
if (!layer || evidenceRecords.length === 0) {
|
|
82
|
-
return {
|
|
83
|
-
assertion_status: "missing",
|
|
84
|
-
blocking_assertion_failures: [`proof layer ${layerId} missing assertion result`],
|
|
85
|
-
negative_evidence_findings: []
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
const blocking = [];
|
|
89
|
-
const negative = [];
|
|
90
|
-
for (const evidence of evidenceRecords) {
|
|
91
|
-
blocking.push(...evaluateCurrentAttemptEvidence(state, evidence, layerId));
|
|
92
|
-
blocking.push(...evaluateAssertionEvidence(evidence, layerId));
|
|
93
|
-
negative.push(...evaluateNegativeEvidence(evidence, layerId));
|
|
94
|
-
}
|
|
95
|
-
const combined = [...blocking, ...negative];
|
|
96
|
-
if (combined.length === 0) {
|
|
97
|
-
return { assertion_status: "passed", blocking_assertion_failures: [], negative_evidence_findings: [] };
|
|
98
|
-
}
|
|
99
|
-
const text = combined.join("\n");
|
|
100
|
-
const status = /missing assertion result/i.test(text)
|
|
101
|
-
? "missing"
|
|
102
|
-
: /\bstale\b/i.test(text)
|
|
103
|
-
? "stale"
|
|
104
|
-
: "failed";
|
|
105
|
-
return { assertion_status: status, blocking_assertion_failures: blocking, negative_evidence_findings: negative };
|
|
106
|
-
}
|
|
107
|
-
export function assertionFailuresForState(state) {
|
|
108
|
-
return Object.keys(state.graph?.proof_layers ?? {}).flatMap((layerId) => {
|
|
109
|
-
const evaluation = evaluateProofLayerAssertions(state, layerId);
|
|
110
|
-
return [...evaluation.blocking_assertion_failures, ...evaluation.negative_evidence_findings];
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
export function evaluateAssertionEvidence(evidence, layerId) {
|
|
114
|
-
const failures = [];
|
|
115
|
-
const acId = proofLayerAcId(layerId);
|
|
116
|
-
const layerName = proofLayerName(layerId);
|
|
117
|
-
const assertion = evidence.assertion_result;
|
|
118
|
-
const label = `proof layer ${layerId} evidence ${evidence.evidence_id}`;
|
|
119
|
-
const invalidEvidence = invalidEvidenceReason(evidence, layerName);
|
|
120
|
-
if (invalidEvidence) {
|
|
121
|
-
failures.push(`${label} invalid evidence forbidden shortcut ${evidence.type || "(missing)"} cannot satisfy ${layerName}: ${invalidEvidence}`);
|
|
122
|
-
}
|
|
123
|
-
if (!assertion) {
|
|
124
|
-
failures.push(`${label} missing assertion result; ${layerName} proof not machine-backed`);
|
|
125
|
-
return failures;
|
|
126
|
-
}
|
|
127
|
-
if (assertion.schema_version !== "assertion-result-v1" && assertion.schema_version !== "assertion-result-v2") {
|
|
128
|
-
failures.push(`${label} assertion_result.schema_version must be assertion-result-v1 or assertion-result-v2`);
|
|
129
|
-
}
|
|
130
|
-
if (assertion.status !== "passed") {
|
|
131
|
-
failures.push(`${label} assertion_result.status=${assertion.status}; expected passed`);
|
|
132
|
-
}
|
|
133
|
-
if (assertion.exit_code !== 0) {
|
|
134
|
-
failures.push(`${label} assertion exit_code=${assertion.exit_code}; expected 0`);
|
|
135
|
-
}
|
|
136
|
-
if (evidence.command_exit_code !== undefined && evidence.command_exit_code !== 0) {
|
|
137
|
-
failures.push(`${label} command_exit_code=${evidence.command_exit_code}; expected 0`);
|
|
138
|
-
}
|
|
139
|
-
if (!assertion.target_ac_ids.includes(acId)) {
|
|
140
|
-
failures.push(`${label} assertion target ACs ${assertion.target_ac_ids.join(", ") || "(none)"} do not include ${acId}`);
|
|
141
|
-
}
|
|
142
|
-
const assertionTargetLayers = assertion.target_proof_layers.map(normalizeProofLayerId);
|
|
143
|
-
const normalizedLayerId = normalizeProofLayerId(layerId);
|
|
144
|
-
if (!assertionTargetLayers.includes(normalizedLayerId) && !assertionTargetLayers.includes(layerName)) {
|
|
145
|
-
failures.push(`${label} assertion target_proof_layers ${assertion.target_proof_layers.join(", ") || "(none)"} do not include ${layerId} or ${layerName}`);
|
|
146
|
-
}
|
|
147
|
-
failures.push(...checkAssertions(`${label} positive assertion`, assertion.positive_assertions));
|
|
148
|
-
failures.push(...checkAssertions(`${label} negative assertion`, assertion.negative_assertions));
|
|
149
|
-
failures.push(...checkAssertions(`${label} invalid completion signal`, assertion.invalid_completion_signals ?? []));
|
|
150
|
-
const missingRequiredTests = (assertion.required_test_ids ?? []).filter((testId) => !testId);
|
|
151
|
-
if (missingRequiredTests.length > 0) {
|
|
152
|
-
failures.push(`${label} assertion_result.required_test_ids contains empty test ids`);
|
|
153
|
-
}
|
|
154
|
-
if ((assertion.artifacts?.length ?? 0) === 0 && evidence.artifact_paths.length === 0) {
|
|
155
|
-
failures.push(`${label} assertion-backed evidence must include artifacts`);
|
|
156
|
-
}
|
|
157
|
-
if (isUiBrowserLayer(layerId)) {
|
|
158
|
-
failures.push(...validateUiBrowserAssertion(evidence, assertion, layerId));
|
|
159
|
-
}
|
|
160
|
-
return failures;
|
|
161
|
-
}
|
|
162
|
-
function validateUiBrowserAssertion(evidence, assertion, layerId) {
|
|
163
|
-
const failures = [];
|
|
164
|
-
const label = `proof layer ${layerId} evidence ${evidence.evidence_id}`;
|
|
165
|
-
if (!UI_BROWSER_ASSERTION_TYPES.has(evidence.type)) {
|
|
166
|
-
const apiOnly = /\bapi\b/i.test(evidence.type) ? "; API-only cannot satisfy UI Path AC" : "";
|
|
167
|
-
failures.push(`${label} ui_browser evidence type ${evidence.type || "(missing)"} is not allowed${apiOnly}`);
|
|
168
|
-
}
|
|
169
|
-
if (!assertion.owner_surface) {
|
|
170
|
-
failures.push(`${label} missing owner_surface`);
|
|
171
|
-
}
|
|
172
|
-
if (!assertion.route) {
|
|
173
|
-
failures.push(`${label} missing route`);
|
|
174
|
-
}
|
|
175
|
-
if (!assertion.action) {
|
|
176
|
-
failures.push(`${label} missing action-level UI proof`);
|
|
177
|
-
}
|
|
178
|
-
const artifacts = [...(assertion.artifacts ?? []), ...evidence.artifact_paths];
|
|
179
|
-
if (!artifacts.some((artifact) => /\.(png|jpe?g|zip|json)$/i.test(artifact) || /\b(trace|screenshot|report)\b/i.test(artifact))) {
|
|
180
|
-
failures.push(`${label} ui_browser assertion must include screenshot, trace or report artifact`);
|
|
181
|
-
}
|
|
182
|
-
const negativeCoverage = assertion.negative_assertions.map((item) => `${item.id} ${item.forbidden_text ?? ""}`).join("\n");
|
|
183
|
-
for (const forbidden of DEFAULT_UI_FORBIDDEN_FINAL_STATES) {
|
|
184
|
-
if (!negativeCoverage.includes(forbidden)) {
|
|
185
|
-
failures.push(`${label} missing negative assertion coverage for forbidden final state ${forbidden}`);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
if (!evidence.negative_evidence_scan) {
|
|
189
|
-
failures.push(`${label} missing negative_evidence_scan for ui_browser layer`);
|
|
190
|
-
}
|
|
191
|
-
return failures;
|
|
192
|
-
}
|
|
193
|
-
function checkAssertions(prefix, checks) {
|
|
194
|
-
return checks
|
|
195
|
-
.filter((check) => check.status !== "passed")
|
|
196
|
-
.map((check) => `${prefix} ${check.id || "(unnamed)"} status=${check.status}; expected passed${check.forbidden_text ? ` forbidden_text=${check.forbidden_text}` : ""}`);
|
|
197
|
-
}
|
|
198
|
-
export function evaluateNegativeEvidence(evidence, layerId) {
|
|
199
|
-
const scan = evidence.assertion_result?.negative_evidence_scan ?? evidence.negative_evidence_scan;
|
|
200
|
-
if (!scan) {
|
|
201
|
-
return [`proof layer ${layerId} evidence ${evidence.evidence_id} missing negative_evidence_scan`];
|
|
202
|
-
}
|
|
203
|
-
const acId = proofLayerAcId(layerId);
|
|
204
|
-
const label = `proof layer ${layerId} evidence ${evidence.evidence_id}`;
|
|
205
|
-
const findings = [];
|
|
206
|
-
if (scan.schema_version !== "negative-evidence-scan-v1") {
|
|
207
|
-
findings.push(`${label} negative_evidence_scan.schema_version must be negative-evidence-scan-v1`);
|
|
208
|
-
}
|
|
209
|
-
if (scan.status !== "passed") {
|
|
210
|
-
findings.push(`${label} negative evidence scan status=${scan.status}; expected passed`);
|
|
211
|
-
}
|
|
212
|
-
if (!scan.target_ac_ids.includes(acId)) {
|
|
213
|
-
findings.push(`${label} negative evidence scan target ACs ${scan.target_ac_ids.join(", ") || "(none)"} do not include ${acId}`);
|
|
214
|
-
}
|
|
215
|
-
const targetLayers = (scan.target_proof_layers ?? []).map(normalizeProofLayerId);
|
|
216
|
-
const normalizedLayerId = normalizeProofLayerId(layerId);
|
|
217
|
-
if (targetLayers.length === 0) {
|
|
218
|
-
findings.push(`${label} negative evidence scan target proof layers are missing; expected ${normalizedLayerId}`);
|
|
219
|
-
}
|
|
220
|
-
else if (!targetLayers.includes(normalizedLayerId) && !targetLayers.includes(proofLayerName(layerId))) {
|
|
221
|
-
findings.push(`${label} negative evidence scan target proof layers ${targetLayers.join(", ") || "(none)"} do not include ${normalizedLayerId}`);
|
|
222
|
-
}
|
|
223
|
-
for (const finding of scan.forbidden_findings ?? []) {
|
|
224
|
-
if (finding.status === "found") {
|
|
225
|
-
findings.push(`${label} negative evidence found forbidden text ${finding.forbidden_text ?? finding.id}: ${finding.actual ?? ""}`.trim());
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
for (const required of scan.required_findings ?? []) {
|
|
229
|
-
if (required.status !== "passed") {
|
|
230
|
-
findings.push(`${label} negative evidence required finding ${required.id} status=${required.status}; expected passed`);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
if ((scan.artifacts ?? []).length === 0) {
|
|
234
|
-
findings.push(`${label} negative evidence scan must include artifacts`);
|
|
235
|
-
}
|
|
236
|
-
return findings;
|
|
237
|
-
}
|
|
238
|
-
function invalidEvidenceReason(evidence, layerName) {
|
|
239
|
-
const evidenceText = [evidence.type, evidence.command, ...evidence.artifact_paths, ...evidence.proves, ...evidence.does_not_prove].join("\n");
|
|
240
|
-
const genericShortcut = GENERIC_INVALID_EVIDENCE_TYPE_PATTERNS.find((pattern) => pattern.test(evidenceText));
|
|
241
|
-
if (genericShortcut) {
|
|
242
|
-
return `matches invalid completion evidence ${genericShortcut}`;
|
|
243
|
-
}
|
|
244
|
-
if ((layerName === "worker_runtime" || layerName === "integration" || layerName === "ui_browser") && /\b(unit|mock|viewmodel)\b/i.test(evidence.type)) {
|
|
245
|
-
return "unit, mock or viewmodel evidence is auxiliary only for runtime, worker, integration and UI layers";
|
|
246
|
-
}
|
|
247
|
-
if (layerName === "ui_browser" && /\b(api|schema)\b/i.test(evidence.type)) {
|
|
248
|
-
return "API-only evidence cannot satisfy UI Path AC";
|
|
249
|
-
}
|
|
250
|
-
if (layerName === "ui_browser" && /^screenshot$/i.test(evidence.type)) {
|
|
251
|
-
return "screenshot-only evidence cannot satisfy UI Path AC";
|
|
252
|
-
}
|
|
253
|
-
if ((layerName === "worker_runtime" || layerName === "data_artifact" || layerName === "security_redaction") && /\b(ui|browser|playwright|screenshot)\b/i.test(evidence.type)) {
|
|
254
|
-
return "UI-only evidence cannot satisfy runtime, data or security proof layers";
|
|
255
|
-
}
|
|
256
|
-
return undefined;
|
|
257
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { ExecutionAttempt, SuperpowersAttemptMode, SuperpowersTaskState } from "./superpowers-task-state-schema.js";
|
|
2
|
-
export declare function startSuperpowersAttempt(workdir: string, state: SuperpowersTaskState, mode?: SuperpowersAttemptMode): Promise<ExecutionAttempt>;
|
|
3
|
-
export declare function startAndSaveSuperpowersAttempt(workdir: string, mode?: SuperpowersAttemptMode): Promise<ExecutionAttempt>;
|
|
4
|
-
export declare function computeSourceBundleHash(state: SuperpowersTaskState, specsHash?: string): string;
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import { execFile } from "node:child_process";
|
|
2
|
-
import { promisify } from "node:util";
|
|
3
|
-
import { appendSuperpowersEvent } from "./superpowers-task-events.js";
|
|
4
|
-
import { requiredCommandSpecsHash } from "./superpowers-task-command-specs.js";
|
|
5
|
-
import { loadSuperpowersState, saveSuperpowersState, sha256, stableJson } from "./superpowers-task-state.js";
|
|
6
|
-
const execFileAsync = promisify(execFile);
|
|
7
|
-
export async function startSuperpowersAttempt(workdir, state, mode = "product_task") {
|
|
8
|
-
const now = new Date().toISOString();
|
|
9
|
-
const specsHash = requiredCommandSpecsHash(state.required_command_specs ?? []);
|
|
10
|
-
const sourceBundleHash = computeSourceBundleHash(state, specsHash);
|
|
11
|
-
const git = await readGitIdentity(workdir);
|
|
12
|
-
const worktreeFingerprint = sha256(stableJson(git));
|
|
13
|
-
const attemptOrdinal = (state.attempts ?? []).length + 1;
|
|
14
|
-
const attempt = {
|
|
15
|
-
task_attempt_id: `ATT-${compactDate(now)}-${attemptOrdinal}-${sourceBundleHash.slice(0, 8)}`,
|
|
16
|
-
source_bundle_hash: sourceBundleHash,
|
|
17
|
-
product_source_hash: state.sources.product_architecture_source?.sha256 ?? "",
|
|
18
|
-
technical_plan_hash: state.sources.technical_realization_plan?.sha256 ?? "",
|
|
19
|
-
acceptance_checklist_hash: state.sources.acceptance_checklist?.sha256 ?? "",
|
|
20
|
-
git_head: git.git_head,
|
|
21
|
-
git_status_short: git.git_status_short,
|
|
22
|
-
tracked_diff_hash: git.tracked_diff_hash,
|
|
23
|
-
relevant_untracked_hash: git.relevant_untracked_hash,
|
|
24
|
-
untracked_relevant_hash: git.relevant_untracked_hash,
|
|
25
|
-
worktree_fingerprint: worktreeFingerprint,
|
|
26
|
-
started_at: now,
|
|
27
|
-
ended_at: null,
|
|
28
|
-
finalized_at: null,
|
|
29
|
-
required_command_specs_hash: specsHash,
|
|
30
|
-
mode,
|
|
31
|
-
changed_files: git.changed_files
|
|
32
|
-
};
|
|
33
|
-
state.attempts = [...(state.attempts ?? []).filter((item) => item.task_attempt_id !== attempt.task_attempt_id), attempt];
|
|
34
|
-
state.current_attempt_id = attempt.task_attempt_id;
|
|
35
|
-
return attempt;
|
|
36
|
-
}
|
|
37
|
-
export async function startAndSaveSuperpowersAttempt(workdir, mode = "product_task") {
|
|
38
|
-
const state = await loadSuperpowersState(workdir);
|
|
39
|
-
const attempt = await startSuperpowersAttempt(workdir, state, mode);
|
|
40
|
-
await saveSuperpowersState(workdir, state);
|
|
41
|
-
await appendSuperpowersEvent(workdir, "attempt_started", { task_attempt_id: attempt.task_attempt_id });
|
|
42
|
-
return attempt;
|
|
43
|
-
}
|
|
44
|
-
export function computeSourceBundleHash(state, specsHash = requiredCommandSpecsHash(state.required_command_specs ?? [])) {
|
|
45
|
-
return sha256(stableJson({
|
|
46
|
-
product_source_hash: state.sources.product_architecture_source?.sha256 ?? "",
|
|
47
|
-
technical_plan_hash: state.sources.technical_realization_plan?.sha256 ?? "",
|
|
48
|
-
acceptance_checklist_hash: state.sources.acceptance_checklist?.sha256 ?? "",
|
|
49
|
-
required_command_specs_hash: specsHash
|
|
50
|
-
}));
|
|
51
|
-
}
|
|
52
|
-
async function readGitIdentity(workdir) {
|
|
53
|
-
const head = await git(workdir, ["rev-parse", "HEAD"]);
|
|
54
|
-
if (!head.ok) {
|
|
55
|
-
return {
|
|
56
|
-
git_head: "no-git",
|
|
57
|
-
git_status_short: "no-git",
|
|
58
|
-
tracked_diff_hash: sha256("no-git-tracked-diff"),
|
|
59
|
-
relevant_untracked_hash: "ignored:no-git",
|
|
60
|
-
changed_files: []
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
const status = await git(workdir, ["status", "--short"]);
|
|
64
|
-
const diff = await git(workdir, ["diff", "--binary"]);
|
|
65
|
-
const stagedDiff = await git(workdir, ["diff", "--cached", "--binary"]);
|
|
66
|
-
const untracked = await git(workdir, ["ls-files", "--others", "--exclude-standard"]);
|
|
67
|
-
const trackedNames = await git(workdir, ["diff", "--name-only"]);
|
|
68
|
-
const stagedNames = await git(workdir, ["diff", "--cached", "--name-only"]);
|
|
69
|
-
const changedFiles = unique([
|
|
70
|
-
...lines(trackedNames.ok ? trackedNames.stdout : ""),
|
|
71
|
-
...lines(stagedNames.ok ? stagedNames.stdout : ""),
|
|
72
|
-
...lines(untracked.ok ? untracked.stdout : "")
|
|
73
|
-
]);
|
|
74
|
-
return {
|
|
75
|
-
git_head: head.stdout.trim(),
|
|
76
|
-
git_status_short: status.ok ? status.stdout.trim() : "git-status-unavailable",
|
|
77
|
-
tracked_diff_hash: sha256(`${diff.ok ? diff.stdout : "git-diff-unavailable"}\n${stagedDiff.ok ? stagedDiff.stdout : ""}`),
|
|
78
|
-
relevant_untracked_hash: untracked.ok && untracked.stdout.trim() ? sha256(untracked.stdout.trim()) : "none",
|
|
79
|
-
changed_files: changedFiles
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
async function git(workdir, args) {
|
|
83
|
-
try {
|
|
84
|
-
const result = await execFileAsync("git", args, { cwd: workdir, windowsHide: true, timeout: 10000 });
|
|
85
|
-
return { ok: true, stdout: result.stdout };
|
|
86
|
-
}
|
|
87
|
-
catch {
|
|
88
|
-
return { ok: false, stdout: "" };
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
function compactDate(value) {
|
|
92
|
-
return value.replace(/[-:.TZ]/g, "").slice(0, 14);
|
|
93
|
-
}
|
|
94
|
-
function lines(value) {
|
|
95
|
-
return value
|
|
96
|
-
.split(/\r?\n/)
|
|
97
|
-
.map((item) => item.trim().replace(/\\/g, "/"))
|
|
98
|
-
.filter(Boolean);
|
|
99
|
-
}
|
|
100
|
-
function unique(values) {
|
|
101
|
-
return [...new Set(values.filter(Boolean))];
|
|
102
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { CommandRunRecord, ExecutionAttempt, RequiredCommandSpec, SuperpowersTaskState } from "./superpowers-task-state-schema.js";
|
|
2
|
-
export interface CommandRunCorrelationResult {
|
|
3
|
-
errors: string[];
|
|
4
|
-
invalidated_evidence_ids: string[];
|
|
5
|
-
}
|
|
6
|
-
export declare function validateRequiredCommandCorrelation(state: SuperpowersTaskState, attempt: ExecutionAttempt | undefined, expectedSpecs: RequiredCommandSpec[]): CommandRunCorrelationResult;
|
|
7
|
-
export declare function validateCommandRunsForSpec(state: SuperpowersTaskState, attempt: ExecutionAttempt | undefined, spec: RequiredCommandSpec): string[];
|
|
8
|
-
export declare function validateCommandRun(run: CommandRunRecord, attempt: ExecutionAttempt | undefined): string[];
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { isMachineVerifiableLayer } from "./superpowers-task-assertions.js";
|
|
2
|
-
import { normalizeProofLayerName } from "./superpowers-task-fields.js";
|
|
3
|
-
import { requiredCommandSpecsHash } from "./superpowers-task-command-specs.js";
|
|
4
|
-
export function validateRequiredCommandCorrelation(state, attempt, expectedSpecs) {
|
|
5
|
-
const errors = [];
|
|
6
|
-
const invalidated = new Set();
|
|
7
|
-
const expectedByAc = new Map(expectedSpecs.map((spec) => [spec.ac_id, spec]));
|
|
8
|
-
for (const [acId, ac] of Object.entries(state.graph?.acceptance_criteria ?? {})) {
|
|
9
|
-
if (ac.machine_blocking !== true && ac.assertion_result_required !== true) {
|
|
10
|
-
continue;
|
|
11
|
-
}
|
|
12
|
-
const expected = expectedByAc.get(acId);
|
|
13
|
-
const actual = (state.required_command_specs ?? []).find((spec) => spec.ac_id === acId);
|
|
14
|
-
if (!expected || !actual) {
|
|
15
|
-
errors.push(`${acId} missing required_command_spec`);
|
|
16
|
-
continue;
|
|
17
|
-
}
|
|
18
|
-
if (actual.command_spec_id !== expected.command_spec_id) {
|
|
19
|
-
errors.push(`${acId} command_spec_id mismatch; required command specs must be recompiled from Acceptance Checklist`);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
if (attempt) {
|
|
23
|
-
const specsHash = requiredCommandSpecsHash(state.required_command_specs ?? []);
|
|
24
|
-
if (attempt.required_command_specs_hash !== specsHash) {
|
|
25
|
-
errors.push("required_command_specs_hash mismatch for current attempt");
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
for (const spec of expectedSpecs) {
|
|
29
|
-
errors.push(...validateCommandRunsForSpec(state, attempt, spec));
|
|
30
|
-
}
|
|
31
|
-
for (const finding of findFailedCommandInvalidations(state)) {
|
|
32
|
-
invalidated.add(finding.evidence_id);
|
|
33
|
-
errors.push(`${finding.evidence_id} newer failed command invalidates older passed evidence for ${finding.ac_id}.${finding.proof_layer}: ${finding.command_run_id}`);
|
|
34
|
-
}
|
|
35
|
-
return { errors: unique(errors), invalidated_evidence_ids: [...invalidated] };
|
|
36
|
-
}
|
|
37
|
-
export function validateCommandRunsForSpec(state, attempt, spec) {
|
|
38
|
-
const errors = [];
|
|
39
|
-
for (const proofLayer of spec.proof_layers.filter((layer) => isMachineVerifiableLayer(`${spec.ac_id}.${layer}`))) {
|
|
40
|
-
const run = (state.command_runs ?? []).find((item) => item.task_attempt_id === state.current_attempt_id &&
|
|
41
|
-
item.command_spec_id === spec.command_spec_id &&
|
|
42
|
-
item.ac_id === spec.ac_id &&
|
|
43
|
-
normalizeProofLayerName(item.proof_layer) === normalizeProofLayerName(proofLayer));
|
|
44
|
-
if (!run) {
|
|
45
|
-
errors.push(`${spec.ac_id}.${proofLayer} missing current attempt command-run record for command_spec_id ${spec.command_spec_id}`);
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
errors.push(...validateCommandRun(run, attempt));
|
|
49
|
-
}
|
|
50
|
-
return errors;
|
|
51
|
-
}
|
|
52
|
-
export function validateCommandRun(run, attempt) {
|
|
53
|
-
const errors = [];
|
|
54
|
-
if (attempt && run.task_attempt_id !== attempt.task_attempt_id) {
|
|
55
|
-
errors.push(`${run.command_run_id} stale command run from ${run.task_attempt_id}; expected ${attempt.task_attempt_id}`);
|
|
56
|
-
}
|
|
57
|
-
if (run.exit_code !== 0) {
|
|
58
|
-
errors.push(`${run.command_run_id} command_exit_code=${run.exit_code}; expected 0`);
|
|
59
|
-
}
|
|
60
|
-
if (!run.command_line.trim()) {
|
|
61
|
-
errors.push(`${run.command_run_id} missing command_line`);
|
|
62
|
-
}
|
|
63
|
-
if (!run.started_at) {
|
|
64
|
-
errors.push(`${run.command_run_id} missing started_at`);
|
|
65
|
-
}
|
|
66
|
-
if (!run.completed_at) {
|
|
67
|
-
errors.push(`${run.command_run_id} missing completed_at`);
|
|
68
|
-
}
|
|
69
|
-
if (!run.task_attempt_id) {
|
|
70
|
-
errors.push(`${run.command_run_id} missing attempt_id`);
|
|
71
|
-
}
|
|
72
|
-
return errors;
|
|
73
|
-
}
|
|
74
|
-
function findFailedCommandInvalidations(state) {
|
|
75
|
-
const evidence = state.evidence ?? [];
|
|
76
|
-
const failedRuns = (state.command_runs ?? []).filter((run) => run.task_attempt_id === state.current_attempt_id && Number(run.exit_code) !== 0);
|
|
77
|
-
return failedRuns.flatMap((run) => evidence
|
|
78
|
-
.filter((item) => evidenceTargetsRunLayer(item, run) && evidencePredatesRun(item, run))
|
|
79
|
-
.map((item) => ({
|
|
80
|
-
evidence_id: item.evidence_id,
|
|
81
|
-
command_run_id: run.command_run_id,
|
|
82
|
-
ac_id: run.ac_id,
|
|
83
|
-
proof_layer: run.proof_layer
|
|
84
|
-
})));
|
|
85
|
-
}
|
|
86
|
-
function evidenceTargetsRunLayer(evidence, run) {
|
|
87
|
-
const layerId = `${run.ac_id}.${normalizeProofLayerName(run.proof_layer)}`;
|
|
88
|
-
const targetLayers = (evidence.target_proof_layers ?? evidence.assertion_result?.target_proof_layers ?? []).map((item) => item.includes(".") ? item : `${run.ac_id}.${normalizeProofLayerName(item)}`);
|
|
89
|
-
return (evidence.task_attempt_id === run.task_attempt_id &&
|
|
90
|
-
(evidence.target_ac_ids ?? evidence.assertion_result?.target_ac_ids ?? []).includes(run.ac_id) &&
|
|
91
|
-
(targetLayers.includes(layerId) || evidence.proves.includes(layerId)));
|
|
92
|
-
}
|
|
93
|
-
function evidencePredatesRun(evidence, run) {
|
|
94
|
-
const evidenceTime = Date.parse(evidence.generated_at ?? evidence.freshness?.created_at ?? evidence.artifact_mtime ?? "");
|
|
95
|
-
const runTime = Date.parse(run.started_at || run.completed_at || run.ended_at || "");
|
|
96
|
-
if (Number.isNaN(evidenceTime) || Number.isNaN(runTime)) {
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
return evidenceTime <= runTime;
|
|
100
|
-
}
|
|
101
|
-
function unique(values) {
|
|
102
|
-
return [...new Set(values.filter(Boolean))];
|
|
103
|
-
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { RequiredCommandSpec, SuperpowersTaskState } from "./superpowers-task-state-schema.js";
|
|
2
|
-
export declare function deriveRequiredCommandSpecs(state: SuperpowersTaskState): RequiredCommandSpec[];
|
|
3
|
-
export declare function requiredCommandSpecsHash(specs: RequiredCommandSpec[]): string;
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import { stableJson } from "./superpowers-task-state.js";
|
|
3
|
-
export function deriveRequiredCommandSpecs(state) {
|
|
4
|
-
return Object.entries(state.graph.acceptance_criteria).flatMap(([acId, ac]) => {
|
|
5
|
-
const proofLayers = [...new Set((ac.required_proof_layers ?? []).filter(Boolean))];
|
|
6
|
-
if (proofLayers.length === 0) {
|
|
7
|
-
return [];
|
|
8
|
-
}
|
|
9
|
-
const spec = {
|
|
10
|
-
ac_id: acId,
|
|
11
|
-
proof_layers: proofLayers,
|
|
12
|
-
command: ac.assertion_command ?? "",
|
|
13
|
-
assertion_artifacts: ac.assertion_artifacts ?? [],
|
|
14
|
-
required_test_ids: ac.required_test_ids ?? [],
|
|
15
|
-
machine_blocking: ac.machine_blocking !== false,
|
|
16
|
-
assertion_result_required: ac.assertion_result_required !== false,
|
|
17
|
-
positive_assertions: ac.positive_assertions ?? [],
|
|
18
|
-
negative_assertions: ac.negative_assertions ?? [],
|
|
19
|
-
invalid_completion_signals: ac.invalid_completion_signals ?? [],
|
|
20
|
-
final_evidence_expected: ac.final_evidence_expected ?? []
|
|
21
|
-
};
|
|
22
|
-
return [{ command_spec_id: commandSpecId(spec), ...spec }];
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
export function requiredCommandSpecsHash(specs) {
|
|
26
|
-
return sha256(stableJson(specs.map((spec) => ({
|
|
27
|
-
...spec,
|
|
28
|
-
proof_layers: [...(spec.proof_layers ?? [])].sort(),
|
|
29
|
-
assertion_artifacts: [...(spec.assertion_artifacts ?? [])].sort(),
|
|
30
|
-
required_test_ids: [...(spec.required_test_ids ?? [])].sort(),
|
|
31
|
-
positive_assertions: [...(spec.positive_assertions ?? [])].sort(),
|
|
32
|
-
negative_assertions: [...(spec.negative_assertions ?? [])].sort(),
|
|
33
|
-
invalid_completion_signals: [...(spec.invalid_completion_signals ?? [])].sort(),
|
|
34
|
-
final_evidence_expected: [...(spec.final_evidence_expected ?? [])].sort()
|
|
35
|
-
}))));
|
|
36
|
-
}
|
|
37
|
-
function commandSpecId(spec) {
|
|
38
|
-
return sha256([
|
|
39
|
-
spec.ac_id,
|
|
40
|
-
spec.proof_layers.join(","),
|
|
41
|
-
spec.command,
|
|
42
|
-
spec.assertion_artifacts.join(","),
|
|
43
|
-
spec.required_test_ids.join(","),
|
|
44
|
-
spec.positive_assertions.join(","),
|
|
45
|
-
spec.negative_assertions.join(","),
|
|
46
|
-
spec.invalid_completion_signals.join(","),
|
|
47
|
-
spec.final_evidence_expected.join(",")
|
|
48
|
-
].join("\n"));
|
|
49
|
-
}
|
|
50
|
-
function sha256(value) {
|
|
51
|
-
return createHash("sha256").update(value).digest("hex");
|
|
52
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export type CompileReportCategory = "blocking_missing_source" | "blocking_missing_plan" | "blocking_missing_checklist" | "blocking_unparseable_object" | "blocking_scope_conflict" | "blocking_missing_assertion_spec" | "blocking_missing_owner_boundary" | "blocking_missing_primary_path" | "blocking_missing_observable_result" | "blocking_missing_invalid_evidence" | "warning_weak_acceptance_wording" | "hygiene_non_canonical_field_order";
|
|
2
|
-
export declare function compileError(message: string, category: CompileReportCategory, file: string, line: number, field: string, whyBlocking: string, requiredFix: string): string;
|
|
3
|
-
export declare function compileReportSuffix(category: CompileReportCategory, file: string, line: number, field: string, whyBlocking: string, requiredFix: string): string;
|
|
4
|
-
export declare function missingCategory(label: string): CompileReportCategory;
|
|
5
|
-
export declare function throwCompileErrors(errors: string[]): void;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export function compileError(message, category, file, line, field, whyBlocking, requiredFix) {
|
|
2
|
-
return `${message}${compileReportSuffix(category, file, line, field, whyBlocking, requiredFix)}`;
|
|
3
|
-
}
|
|
4
|
-
export function compileReportSuffix(category, file, line, field, whyBlocking, requiredFix) {
|
|
5
|
-
return ` [category=${category}; file=${file}; line=${line}; invalid_or_missing_field=${field}; why_blocking=${whyBlocking}; required_fix=${requiredFix}; rerun_compile_enough=true]`;
|
|
6
|
-
}
|
|
7
|
-
export function missingCategory(label) {
|
|
8
|
-
if (/^PI-\d+/i.test(label)) {
|
|
9
|
-
return "blocking_missing_plan";
|
|
10
|
-
}
|
|
11
|
-
if (/^AC-\d+/i.test(label)) {
|
|
12
|
-
return "blocking_missing_checklist";
|
|
13
|
-
}
|
|
14
|
-
return "blocking_missing_source";
|
|
15
|
-
}
|
|
16
|
-
export function throwCompileErrors(errors) {
|
|
17
|
-
if (errors.length > 0) {
|
|
18
|
-
throw new Error(`Superpowers source compile failed:\n- ${errors.join("\n- ")}`);
|
|
19
|
-
}
|
|
20
|
-
}
|