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 +0,0 @@
|
|
|
1
|
-
export declare function superpowers(args: string[]): Promise<void>;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export interface CompositeLongTaskGoalRenderResult {
|
|
2
|
-
workdir: string;
|
|
3
|
-
protocolPath: string;
|
|
4
|
-
protocolSha256: string;
|
|
5
|
-
executionBindingPath: string;
|
|
6
|
-
goalObjectivePath: string;
|
|
7
|
-
goalObjectiveLength: number;
|
|
8
|
-
}
|
|
9
|
-
export declare function renderCompositeLongTaskGoal(workdir: string): Promise<CompositeLongTaskGoalRenderResult>;
|
|
10
|
-
export declare const COMPOSITE_LONG_TASK_WORKFLOW_SKILL_NAME = "composite-long-task-workflow";
|
|
11
|
-
export declare const COMPOSITE_LONG_TASK_PUBLIC_COMMAND = "composite-long-task";
|
|
12
|
-
export declare const COMPOSITE_LONG_TASK_PACKAGE = "project-tiny-context-harness";
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { CANONICAL_CORE_PACKAGE } from "./constants.js";
|
|
4
|
-
import { pathExists, readText, writeTextIfChanged } from "./fs.js";
|
|
5
|
-
import { packageAssetPath, packageRoot } from "./paths.js";
|
|
6
|
-
const SOURCE_ASSET = "packages/ty-context/assets/skills/composite-long-task-workflow/references/composite-long-task-workflow-protocol.md";
|
|
7
|
-
const REQUIRED_SOURCE_FILES = [
|
|
8
|
-
"product-architecture-source.md",
|
|
9
|
-
"technical-realization-plan.md",
|
|
10
|
-
"acceptance-checklist.md"
|
|
11
|
-
];
|
|
12
|
-
export async function renderCompositeLongTaskGoal(workdir) {
|
|
13
|
-
const resolvedWorkdir = path.resolve(workdir);
|
|
14
|
-
await assertReadyWorkdir(resolvedWorkdir);
|
|
15
|
-
const protocolBody = ensureTrailingNewline(normalizeNewlines(await readText(packageAssetPath("skills", "composite-long-task-workflow", "references", "composite-long-task-workflow-protocol.md"))));
|
|
16
|
-
const protocolSha256 = sha256(protocolBody);
|
|
17
|
-
const protocolVersion = await packageVersion();
|
|
18
|
-
const protocolSnapshot = [
|
|
19
|
-
"protocol_name: composite-long-task-workflow",
|
|
20
|
-
`protocol_version: ${protocolVersion}`,
|
|
21
|
-
`protocol_sha256: ${protocolSha256}`,
|
|
22
|
-
`generated_at: ${new Date().toISOString()}`,
|
|
23
|
-
`source_asset: ${SOURCE_ASSET}`,
|
|
24
|
-
"---",
|
|
25
|
-
protocolBody.trimEnd()
|
|
26
|
-
].join("\n") + "\n";
|
|
27
|
-
const protocolPath = path.join(resolvedWorkdir, "workflow-protocol.md");
|
|
28
|
-
await writeTextIfChanged(protocolPath, protocolSnapshot);
|
|
29
|
-
const executionBinding = await renderExecutionBinding(resolvedWorkdir, protocolSha256);
|
|
30
|
-
const executionBindingPath = path.join(resolvedWorkdir, "execution-binding.md");
|
|
31
|
-
await writeTextIfChanged(executionBindingPath, executionBinding);
|
|
32
|
-
const goalObjective = await renderGoalObjective(workdirForPrompt(resolvedWorkdir));
|
|
33
|
-
if (goalObjective.length > 3850) {
|
|
34
|
-
throw new Error(`goal-objective.txt exceeds 3850 characters (${goalObjective.length})`);
|
|
35
|
-
}
|
|
36
|
-
if (/^\/goal\s+read\s+\S+\s*\.?$/i.test(goalObjective.trim())) {
|
|
37
|
-
throw new Error("goal-objective.txt must not be a single read-file pointer");
|
|
38
|
-
}
|
|
39
|
-
const goalObjectivePath = path.join(resolvedWorkdir, "goal-objective.txt");
|
|
40
|
-
await writeTextIfChanged(goalObjectivePath, goalObjective);
|
|
41
|
-
return {
|
|
42
|
-
workdir: resolvedWorkdir,
|
|
43
|
-
protocolPath,
|
|
44
|
-
protocolSha256,
|
|
45
|
-
executionBindingPath,
|
|
46
|
-
goalObjectivePath,
|
|
47
|
-
goalObjectiveLength: goalObjective.length
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
async function assertReadyWorkdir(workdir) {
|
|
51
|
-
for (const sourceFile of REQUIRED_SOURCE_FILES) {
|
|
52
|
-
const sourcePath = path.join(workdir, sourceFile);
|
|
53
|
-
if (!(await pathExists(sourcePath))) {
|
|
54
|
-
throw new Error(`render-goal requires ${sourceFile}; provide the three input files first`);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
const statePath = path.join(workdir, "task-state.json");
|
|
58
|
-
if (!(await pathExists(statePath))) {
|
|
59
|
-
throw new Error("render-goal requires task-state.json; run ty-context composite-long-task init/compile before render-goal");
|
|
60
|
-
}
|
|
61
|
-
const state = JSON.parse(await readText(statePath));
|
|
62
|
-
const planItemCount = Object.keys(state.graph?.plan_items ?? {}).length;
|
|
63
|
-
const acceptanceCriteriaCount = Object.keys(state.graph?.acceptance_criteria ?? {}).length;
|
|
64
|
-
if (planItemCount === 0 || acceptanceCriteriaCount === 0) {
|
|
65
|
-
throw new Error("render-goal requires compiled task-state.json; run ty-context composite-long-task compile before render-goal");
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
async function renderExecutionBinding(workdir, protocolSha256) {
|
|
69
|
-
return renderTemplateAsset(["skills", "composite-long-task-workflow", "assets", "execution-binding.template.md"], {
|
|
70
|
-
workdir: path.normalize(workdir),
|
|
71
|
-
protocol_sha256: protocolSha256
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
async function renderGoalObjective(workdir) {
|
|
75
|
-
return renderTemplateAsset(["skills", "composite-long-task-workflow", "assets", "goal-objective.template.md"], {
|
|
76
|
-
workdir
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
async function packageVersion() {
|
|
80
|
-
const packageJson = JSON.parse(await readText(path.join(packageRoot(), "package.json")));
|
|
81
|
-
return packageJson.version ?? "unknown";
|
|
82
|
-
}
|
|
83
|
-
function workdirForPrompt(workdir) {
|
|
84
|
-
const cwd = process.cwd();
|
|
85
|
-
const relative = path.relative(cwd, workdir);
|
|
86
|
-
if (relative && !relative.startsWith("..") && !path.isAbsolute(relative)) {
|
|
87
|
-
return relative.replace(/\\/g, "/");
|
|
88
|
-
}
|
|
89
|
-
return workdir.replace(/\\/g, "/");
|
|
90
|
-
}
|
|
91
|
-
function normalizeNewlines(value) {
|
|
92
|
-
return value.replace(/\r\n/g, "\n");
|
|
93
|
-
}
|
|
94
|
-
function ensureTrailingNewline(value) {
|
|
95
|
-
return `${value.trimEnd()}\n`;
|
|
96
|
-
}
|
|
97
|
-
async function renderTemplateAsset(segments, values) {
|
|
98
|
-
let rendered = normalizeNewlines(await readText(packageAssetPath(...segments)));
|
|
99
|
-
for (const [key, value] of Object.entries(values)) {
|
|
100
|
-
rendered = rendered.replaceAll(`{{${key}}}`, value);
|
|
101
|
-
}
|
|
102
|
-
return ensureTrailingNewline(rendered);
|
|
103
|
-
}
|
|
104
|
-
function sha256(value) {
|
|
105
|
-
return createHash("sha256").update(value).digest("hex");
|
|
106
|
-
}
|
|
107
|
-
export const COMPOSITE_LONG_TASK_WORKFLOW_SKILL_NAME = "composite-long-task-workflow";
|
|
108
|
-
export const COMPOSITE_LONG_TASK_PUBLIC_COMMAND = "composite-long-task";
|
|
109
|
-
export const COMPOSITE_LONG_TASK_PACKAGE = CANONICAL_CORE_PACKAGE;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function validateAcceptanceArtifactDiagnostics(projectRoot: string, targetDir: string, matrixRows: Record<string, unknown>[], verdictRows: Record<string, unknown>[], verdictOverall: string, errors: string[], warnings: string[], hygiene: string[]): Promise<void>;
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import { promises as fs } from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { readText } from "./fs.js";
|
|
4
|
-
import { findSensitiveEvidence } from "./plan-acceptance-evidence.js";
|
|
5
|
-
import { isOutOfScope, statusOf } from "./plan-acceptance-json.js";
|
|
6
|
-
import { isBlankish, primitiveText, repoRelative, valuesAsArray } from "./plan-validator-common.js";
|
|
7
|
-
const MILESTONE_STATUSES = new Set([
|
|
8
|
-
"not_started",
|
|
9
|
-
"implemented_no_proof",
|
|
10
|
-
"proof_partial",
|
|
11
|
-
"proof_ready",
|
|
12
|
-
"complete",
|
|
13
|
-
"blocked",
|
|
14
|
-
"out_of_scope_NA"
|
|
15
|
-
]);
|
|
16
|
-
const GENERATED_ACTIVE_COUNTS = /<!--\s*generated:active-counts:start\s*-->([\s\S]*?)<!--\s*generated:active-counts:end\s*-->/i;
|
|
17
|
-
export async function validateAcceptanceArtifactDiagnostics(projectRoot, targetDir, matrixRows, verdictRows, verdictOverall, errors, warnings, hygiene) {
|
|
18
|
-
validateRows(matrixRows, "plan-conformance matrix row", warnings, hygiene);
|
|
19
|
-
validateRows(verdictRows, "final acceptance verdict row", warnings, hygiene);
|
|
20
|
-
const manifestEvidenceIds = await validateEvidenceManifest(projectRoot, targetDir, errors, warnings);
|
|
21
|
-
if (manifestEvidenceIds.size > 0) {
|
|
22
|
-
validateEvidenceIdReferences(matrixRows, "plan-conformance matrix row", manifestEvidenceIds, errors);
|
|
23
|
-
validateEvidenceIdReferences(verdictRows, "final acceptance verdict row", manifestEvidenceIds, errors);
|
|
24
|
-
}
|
|
25
|
-
await validateFinalVerdictMarkdown(projectRoot, targetDir, verdictRows, verdictOverall, errors, warnings, hygiene);
|
|
26
|
-
}
|
|
27
|
-
function validateRows(rows, labelPrefix, warnings, hygiene) {
|
|
28
|
-
for (const [index, row] of rows.entries()) {
|
|
29
|
-
const label = `${labelPrefix} ${index + 1}`;
|
|
30
|
-
validateMilestones(row, label, warnings);
|
|
31
|
-
validateStalePartialText(row, label, hygiene);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
function validateMilestones(row, label, warnings) {
|
|
35
|
-
const milestones = row.milestones ?? row.proof_layer_milestones ?? row.proofLayerMilestones;
|
|
36
|
-
if (isBlankish(milestones)) {
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
for (const status of extractMilestoneStatuses(milestones)) {
|
|
40
|
-
if (!MILESTONE_STATUSES.has(status)) {
|
|
41
|
-
warnings.push(`${label} has unsupported milestone status: ${status || "<empty>"}`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
function extractMilestoneStatuses(value) {
|
|
46
|
-
if (Array.isArray(value)) {
|
|
47
|
-
return value.flatMap(extractMilestoneStatuses);
|
|
48
|
-
}
|
|
49
|
-
if (!value || typeof value !== "object") {
|
|
50
|
-
return valuesAsArray(value).map((item) => item.trim());
|
|
51
|
-
}
|
|
52
|
-
const object = value;
|
|
53
|
-
if (!isBlankish(object.status)) {
|
|
54
|
-
return [String(object.status).trim()];
|
|
55
|
-
}
|
|
56
|
-
return Object.values(object).flatMap(extractMilestoneStatuses);
|
|
57
|
-
}
|
|
58
|
-
function validateStalePartialText(row, label, hygiene) {
|
|
59
|
-
const status = statusOf(row);
|
|
60
|
-
if (status === "complete" || status === "out_of_scope_NA") {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
const text = primitiveText(row);
|
|
64
|
-
const hasCompletionClaim = /\b(accepted|complete|final passed|goal achieved|product_goal_complete=true)\b/i.test(text);
|
|
65
|
-
const hasStaleQualifier = /\b(old|stale|previously|prior|outdated|superseded|no longer current)\b/i.test(text);
|
|
66
|
-
if (hasCompletionClaim && hasStaleQualifier) {
|
|
67
|
-
hygiene.push(`${label} has stale or overclaim completion prose while status is ${status || "<empty>"}`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
async function validateEvidenceManifest(projectRoot, targetDir, errors, warnings) {
|
|
71
|
-
const manifestFile = await findFile(targetDir, "evidence-manifest", ".json");
|
|
72
|
-
const evidenceIds = new Set();
|
|
73
|
-
if (!manifestFile) {
|
|
74
|
-
return evidenceIds;
|
|
75
|
-
}
|
|
76
|
-
let parsed;
|
|
77
|
-
try {
|
|
78
|
-
parsed = JSON.parse(await readText(manifestFile));
|
|
79
|
-
}
|
|
80
|
-
catch (error) {
|
|
81
|
-
errors.push(`${repoRelative(projectRoot, manifestFile)} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
82
|
-
return evidenceIds;
|
|
83
|
-
}
|
|
84
|
-
const entries = findManifestEntries(parsed);
|
|
85
|
-
if (entries.length === 0) {
|
|
86
|
-
warnings.push(`${repoRelative(projectRoot, manifestFile)} has no evidence entries`);
|
|
87
|
-
return evidenceIds;
|
|
88
|
-
}
|
|
89
|
-
for (const [index, entry] of entries.entries()) {
|
|
90
|
-
const label = `evidence manifest entry ${index + 1}`;
|
|
91
|
-
const evidenceId = firstString(entry.evidence_id, entry.evidenceId, entry.id);
|
|
92
|
-
if (evidenceId) {
|
|
93
|
-
evidenceIds.add(evidenceId);
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
errors.push(`${label} is missing evidence_id`);
|
|
97
|
-
}
|
|
98
|
-
warnIfBlank(entry, label, warnings, "slice_id", "sliceId");
|
|
99
|
-
warnIfBlank(entry, label, warnings, "slice_goal", "sliceGoal");
|
|
100
|
-
warnIfBlank(entry, label, warnings, "touched_plan_item_ids", "touched_plan_ids", "plan_item_ids");
|
|
101
|
-
warnIfBlank(entry, label, warnings, "touched_ac_ids", "acceptance_ids", "ac_ids");
|
|
102
|
-
warnIfBlank(entry, label, warnings, "missing_layer_classes");
|
|
103
|
-
warnIfBlank(entry, label, warnings, "proves");
|
|
104
|
-
warnIfBlank(entry, label, warnings, "explicitly_does_not_prove", "does_not_prove");
|
|
105
|
-
warnIfBlank(entry, label, warnings, "closed_missing_layers", "closed_layers");
|
|
106
|
-
warnIfBlank(entry, label, warnings, "remaining_missing_layers", "remaining_layers");
|
|
107
|
-
warnIfBlank(entry, label, warnings, "cleanup_status");
|
|
108
|
-
warnIfBlank(entry, label, warnings, "redaction_security_status", "security_redaction_status");
|
|
109
|
-
warnIfBlank(entry, label, warnings, "freshness");
|
|
110
|
-
const sensitiveEvidence = findSensitiveEvidence(primitiveText(entry));
|
|
111
|
-
if (sensitiveEvidence) {
|
|
112
|
-
errors.push(`${label} contains raw secret/token/cookie material: ${sensitiveEvidence}`);
|
|
113
|
-
}
|
|
114
|
-
if (entry.safe_to_sync_to_verdict === true && !isBlankish(entry.remaining_missing_layers ?? entry.remaining_layers)) {
|
|
115
|
-
warnings.push(`${label} is safe_to_sync_to_verdict but still has remaining missing layers`);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return evidenceIds;
|
|
119
|
-
}
|
|
120
|
-
function findManifestEntries(value) {
|
|
121
|
-
if (Array.isArray(value)) {
|
|
122
|
-
return value.filter(isRecord);
|
|
123
|
-
}
|
|
124
|
-
if (!isRecord(value)) {
|
|
125
|
-
return [];
|
|
126
|
-
}
|
|
127
|
-
for (const key of ["evidence", "entries", "items", "manifest"]) {
|
|
128
|
-
const rows = findManifestEntries(value[key]);
|
|
129
|
-
if (rows.length > 0) {
|
|
130
|
-
return rows;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return [];
|
|
134
|
-
}
|
|
135
|
-
function validateEvidenceIdReferences(rows, labelPrefix, evidenceIds, errors) {
|
|
136
|
-
for (const [index, row] of rows.entries()) {
|
|
137
|
-
for (const evidenceId of valuesAsArray(row.evidence_id ?? row.evidence_ids ?? row.evidenceId ?? row.evidenceIds)) {
|
|
138
|
-
if (!evidenceIds.has(evidenceId)) {
|
|
139
|
-
errors.push(`${labelPrefix} ${index + 1} references unknown evidence_id: ${evidenceId}`);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
async function validateFinalVerdictMarkdown(projectRoot, targetDir, verdictRows, verdictOverall, errors, warnings, hygiene) {
|
|
145
|
-
const markdownFile = await findFile(targetDir, "final-acceptance-verdict", ".md");
|
|
146
|
-
if (!markdownFile) {
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
const content = await readText(markdownFile);
|
|
150
|
-
const match = GENERATED_ACTIVE_COUNTS.exec(content);
|
|
151
|
-
if (!match) {
|
|
152
|
-
if (/\b(active[-_ ]?count|complete_count|acceptance_required_count|missing_layer_count)\b/i.test(content)) {
|
|
153
|
-
hygiene.push(`${repoRelative(projectRoot, markdownFile)} has active-count-like prose outside generated active-count markers`);
|
|
154
|
-
}
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
const declared = parseCountBlock(match[1]);
|
|
158
|
-
const actual = activeCounts(verdictRows);
|
|
159
|
-
for (const [key, expected] of Object.entries(actual)) {
|
|
160
|
-
const declaredValue = declared[key];
|
|
161
|
-
if (declaredValue === undefined) {
|
|
162
|
-
warnings.push(`${repoRelative(projectRoot, markdownFile)} generated active-count block is missing ${key}`);
|
|
163
|
-
continue;
|
|
164
|
-
}
|
|
165
|
-
if (declaredValue !== expected) {
|
|
166
|
-
const message = `${repoRelative(projectRoot, markdownFile)} generated active-count ${key}=${declaredValue} but current verdict has ${expected}`;
|
|
167
|
-
if (verdictOverall === "complete") {
|
|
168
|
-
errors.push(message);
|
|
169
|
-
}
|
|
170
|
-
else {
|
|
171
|
-
warnings.push(message);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
function parseCountBlock(content) {
|
|
177
|
-
const counts = {};
|
|
178
|
-
for (const line of content.split(/\r?\n/)) {
|
|
179
|
-
const match = /^\s*([A-Za-z0-9_-]+)\s*[:=]\s*(\d+)\s*$/.exec(line);
|
|
180
|
-
if (match) {
|
|
181
|
-
counts[match[1].replace(/-/g, "_")] = Number(match[2]);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
return counts;
|
|
185
|
-
}
|
|
186
|
-
function activeCounts(rows) {
|
|
187
|
-
return {
|
|
188
|
-
complete_count: rows.filter((row) => statusOf(row) === "complete").length,
|
|
189
|
-
partial_count: rows.filter((row) => statusOf(row) === "partial").length,
|
|
190
|
-
acceptance_required_count: rows.filter((row) => !isOutOfScope(row)).length,
|
|
191
|
-
missing_layer_count: rows.reduce((sum, row) => sum + missingLayerCount(row), 0)
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
function missingLayerCount(row) {
|
|
195
|
-
return valuesAsArray(row.missing_required_layers ?? row.missingRequiredLayers ?? row.missing_proof_layers ?? row.missing_evidence).length;
|
|
196
|
-
}
|
|
197
|
-
async function findFile(targetDir, marker, extension) {
|
|
198
|
-
const entries = await fs.readdir(targetDir, { withFileTypes: true });
|
|
199
|
-
return entries
|
|
200
|
-
.filter((entry) => entry.isFile() && entry.name.endsWith(extension) && entry.name.includes(marker))
|
|
201
|
-
.map((entry) => path.join(targetDir, entry.name))
|
|
202
|
-
.sort()[0];
|
|
203
|
-
}
|
|
204
|
-
function warnIfBlank(entry, label, warnings, ...keys) {
|
|
205
|
-
if (keys.some((key) => !isBlankish(entry[key]))) {
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
warnings.push(`${label} is missing ${keys[0]}`);
|
|
209
|
-
}
|
|
210
|
-
function firstString(...values) {
|
|
211
|
-
for (const value of values) {
|
|
212
|
-
if (!isBlankish(value)) {
|
|
213
|
-
return String(value).trim();
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
return undefined;
|
|
217
|
-
}
|
|
218
|
-
function isRecord(value) {
|
|
219
|
-
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
220
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { isOutOfScope } from "./plan-acceptance-json.js";
|
|
2
|
-
import { isBlankish, primitiveText, valuesAsArray } from "./plan-validator-common.js";
|
|
3
|
-
const BLOCKING_AUDITOR_STATUSES = new Set(["partial", "blocked", "invalidated"]);
|
|
4
|
-
const SENSITIVE_EVIDENCE_PATTERNS = [
|
|
5
|
-
{
|
|
6
|
-
label: "Authorization bearer token",
|
|
7
|
-
pattern: /\bauthorization\s*:\s*bearer\s+(?!<redacted>|redacted|\[redacted\])[A-Za-z0-9._~+/=-]{8,}/i
|
|
8
|
-
},
|
|
9
|
-
{
|
|
10
|
-
label: "cookie value",
|
|
11
|
-
pattern: /\bcookie\s*[:=]\s*(?!<redacted>|redacted|\[redacted\])[^;\s]{8,}/i
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
label: "secret assignment",
|
|
15
|
-
pattern: /\b(?:api[_-]?key|access[_-]?token|refresh[_-]?token|token|secret|password)\s*[:=]\s*["']?(?!<redacted>|redacted|\[redacted\])[A-Za-z0-9_./+=-]{8,}/i
|
|
16
|
-
}
|
|
17
|
-
];
|
|
18
|
-
export function assertExternalReviewerFields(label, row, evidenceText, errors) {
|
|
19
|
-
if (hasUnresolvedMissingRequiredLayers(row)) {
|
|
20
|
-
errors.push(`${label} is complete but missing_required_layers is not empty`);
|
|
21
|
-
}
|
|
22
|
-
const driftSeverity = String(row.drift_severity ?? row.driftSeverity ?? "").trim().toLowerCase();
|
|
23
|
-
if (driftSeverity === "material" || driftSeverity === "critical") {
|
|
24
|
-
errors.push(`${label} is complete but drift_severity is ${driftSeverity}`);
|
|
25
|
-
}
|
|
26
|
-
if (siblingSubstitutionUsed(row) && !hasSiblingSubstitutionApproval(row)) {
|
|
27
|
-
errors.push(`${label} is complete but sibling_substitution_used without approval`);
|
|
28
|
-
}
|
|
29
|
-
if (liveProofSubstitutionUsed(row) && !hasLiveProofSubstitutionApproval(row)) {
|
|
30
|
-
errors.push(`${label} is complete but live_proof_substitution_used without approval`);
|
|
31
|
-
}
|
|
32
|
-
const auditorStatus = String(row.auditor_status ?? row.auditorStatus ?? "").trim().toLowerCase();
|
|
33
|
-
if (BLOCKING_AUDITOR_STATUSES.has(auditorStatus)) {
|
|
34
|
-
errors.push(`${label} is complete but auditor_status is ${auditorStatus}`);
|
|
35
|
-
}
|
|
36
|
-
if (hasOnlySelfCertifyingEvidence(evidenceText)) {
|
|
37
|
-
errors.push(`${label} is complete but fresh_evidence contains only summary or self-certifying evidence`);
|
|
38
|
-
}
|
|
39
|
-
const sensitiveEvidence = findSensitiveEvidence(evidenceText);
|
|
40
|
-
if (sensitiveEvidence) {
|
|
41
|
-
errors.push(`${label} is complete but evidence contains raw secret/token/cookie material: ${sensitiveEvidence}`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
export function findSensitiveEvidence(text) {
|
|
45
|
-
return SENSITIVE_EVIDENCE_PATTERNS.find((item) => item.pattern.test(text))?.label;
|
|
46
|
-
}
|
|
47
|
-
function hasUnresolvedMissingRequiredLayers(row) {
|
|
48
|
-
const value = row.missing_required_layers ?? row.missingRequiredLayers ?? row.missing_proof_layers;
|
|
49
|
-
if (isBlankish(value)) {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
if (Array.isArray(value)) {
|
|
53
|
-
return value.some((item) => !isBlankish(item) && !isStructuredLayerNa(item));
|
|
54
|
-
}
|
|
55
|
-
return !isStructuredLayerNa(value);
|
|
56
|
-
}
|
|
57
|
-
function isStructuredLayerNa(value) {
|
|
58
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
const object = value;
|
|
62
|
-
const text = primitiveText(object);
|
|
63
|
-
const hasNaStatus = isOutOfScope(object) || /\bout[_ -]?of[_ -]?scope[_ -]?NA\b/i.test(text);
|
|
64
|
-
const hasSource = !isBlankish(object.scope_source) ||
|
|
65
|
-
!isBlankish(object.approval_source) ||
|
|
66
|
-
!isBlankish(object.source_reference) ||
|
|
67
|
-
!isBlankish(object.sourceReference);
|
|
68
|
-
return hasNaStatus && hasSource;
|
|
69
|
-
}
|
|
70
|
-
function siblingSubstitutionUsed(row) {
|
|
71
|
-
const value = row.sibling_substitution_used ?? row.siblingSubstitutionUsed;
|
|
72
|
-
if (value === true) {
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
const text = primitiveText(value);
|
|
76
|
-
if (/\b(false|no|none|not used|not_used)\b/i.test(text)) {
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
return /\b(true|yes|used|present)\b/i.test(text);
|
|
80
|
-
}
|
|
81
|
-
function hasSiblingSubstitutionApproval(row) {
|
|
82
|
-
return (!isBlankish(row.sibling_substitution_approval_source) ||
|
|
83
|
-
!isBlankish(row.substitution_approval_source) ||
|
|
84
|
-
/\b(approved|explicitly allowed|out[_ -]?of[_ -]?scope[_ -]?NA)\b/i.test(primitiveText([row.sibling_substitution_approved, row.substitution_approval])));
|
|
85
|
-
}
|
|
86
|
-
function liveProofSubstitutionUsed(row) {
|
|
87
|
-
const value = row.live_proof_substitution_used ?? row.liveProofSubstitutionUsed;
|
|
88
|
-
if (value === true) {
|
|
89
|
-
return true;
|
|
90
|
-
}
|
|
91
|
-
const text = primitiveText(value);
|
|
92
|
-
if (/\b(false|no|none|not used|not_used)\b/i.test(text)) {
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
95
|
-
return /\b(true|yes|used|present|substituted)\b/i.test(text);
|
|
96
|
-
}
|
|
97
|
-
function hasLiveProofSubstitutionApproval(row) {
|
|
98
|
-
return (!isBlankish(row.live_proof_substitution_approval_source) ||
|
|
99
|
-
!isBlankish(row.liveProofSubstitutionApprovalSource) ||
|
|
100
|
-
/\b(approved|explicitly allowed|out[_ -]?of[_ -]?scope[_ -]?NA)\b/i.test(primitiveText([row.live_proof_substitution_approved, row.liveProofSubstitutionApproved])));
|
|
101
|
-
}
|
|
102
|
-
function hasOnlySelfCertifyingEvidence(text) {
|
|
103
|
-
const entries = valuesAsArray(text);
|
|
104
|
-
return entries.length > 0 && entries.every(isSelfCertifyingEvidence);
|
|
105
|
-
}
|
|
106
|
-
function isSelfCertifyingEvidence(text) {
|
|
107
|
-
return /\b(local audit|audit says|plan[- ]conformance(?: matrix)?|matrix row|final[- ]acceptance[- ]verdict|final verdict|verdict row|subagent summary|agent summary|reviewer summary|validator pass|validate-plan-acceptance(?: passed| pass)?|green check|final result card)\b/i.test(text);
|
|
108
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export declare const MATRIX_STATUSES: Set<string>;
|
|
2
|
-
export declare const AC_STATUSES: Set<string>;
|
|
3
|
-
export declare const NON_COMPLETE_MATRIX: Set<string>;
|
|
4
|
-
export declare const NON_COMPLETE_AC: Set<string>;
|
|
5
|
-
export declare function findJsonFile(targetDir: string, marker: string): Promise<string | undefined>;
|
|
6
|
-
export declare function readJson(file: string, errors: string[]): Promise<unknown>;
|
|
7
|
-
export declare function findRows(value: unknown, preferredKeys: string[]): Record<string, unknown>[];
|
|
8
|
-
export declare function overallStatus(value: unknown): string;
|
|
9
|
-
export declare function statusOf(row: Record<string, unknown>): string;
|
|
10
|
-
export declare function isOutOfScope(row: Record<string, unknown>): boolean;
|
|
11
|
-
export declare function contextDeltaRequired(value: unknown): boolean;
|
|
12
|
-
export declare function isSurfaceConformanceRow(row: Record<string, unknown>): boolean;
|
|
13
|
-
export declare function hasExplicitNoTestScope(row: Record<string, unknown>): boolean;
|
|
14
|
-
export declare function assertSurfaceConformance(row: Record<string, unknown>, label: string, errors: string[]): void;
|
|
15
|
-
export declare function assertStructuredNa(row: Record<string, unknown>, label: string, errors: string[]): void;
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { promises as fs } from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { readText } from "./fs.js";
|
|
4
|
-
import { isBlankish, primitiveText, valuesAsArray } from "./plan-validator-common.js";
|
|
5
|
-
export const MATRIX_STATUSES = new Set([
|
|
6
|
-
"complete",
|
|
7
|
-
"partial",
|
|
8
|
-
"sampled_only",
|
|
9
|
-
"not_implemented",
|
|
10
|
-
"blocked",
|
|
11
|
-
"scope_changed_requires_user_approval",
|
|
12
|
-
"contradicted_by_current_state",
|
|
13
|
-
"out_of_scope_NA"
|
|
14
|
-
]);
|
|
15
|
-
export const AC_STATUSES = new Set(["complete", "partial", "blocked", "not_run", "invalidated", "out_of_scope_NA"]);
|
|
16
|
-
export const NON_COMPLETE_MATRIX = new Set([
|
|
17
|
-
"partial",
|
|
18
|
-
"sampled_only",
|
|
19
|
-
"not_implemented",
|
|
20
|
-
"blocked",
|
|
21
|
-
"scope_changed_requires_user_approval",
|
|
22
|
-
"contradicted_by_current_state"
|
|
23
|
-
]);
|
|
24
|
-
export const NON_COMPLETE_AC = new Set(["partial", "blocked", "not_run", "invalidated"]);
|
|
25
|
-
export async function findJsonFile(targetDir, marker) {
|
|
26
|
-
const entries = await fs.readdir(targetDir, { withFileTypes: true });
|
|
27
|
-
return entries
|
|
28
|
-
.filter((entry) => entry.isFile() && entry.name.endsWith(".json") && entry.name.includes(marker))
|
|
29
|
-
.map((entry) => path.join(targetDir, entry.name))
|
|
30
|
-
.sort()[0];
|
|
31
|
-
}
|
|
32
|
-
export async function readJson(file, errors) {
|
|
33
|
-
try {
|
|
34
|
-
return JSON.parse(await readText(file));
|
|
35
|
-
}
|
|
36
|
-
catch (error) {
|
|
37
|
-
errors.push(`${file} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
38
|
-
return undefined;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
export function findRows(value, preferredKeys) {
|
|
42
|
-
if (Array.isArray(value) && value.every((item) => item && typeof item === "object" && !Array.isArray(item))) {
|
|
43
|
-
return value;
|
|
44
|
-
}
|
|
45
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
46
|
-
return [];
|
|
47
|
-
}
|
|
48
|
-
const object = value;
|
|
49
|
-
for (const key of preferredKeys) {
|
|
50
|
-
const rows = findRows(object[key], []);
|
|
51
|
-
if (rows.length > 0) {
|
|
52
|
-
return rows;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return Object.values(object).map((item) => findRows(item, [])).sort((a, b) => b.length - a.length)[0] ?? [];
|
|
56
|
-
}
|
|
57
|
-
export function overallStatus(value) {
|
|
58
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
59
|
-
return "";
|
|
60
|
-
}
|
|
61
|
-
const object = value;
|
|
62
|
-
return String(object.overall_status ?? object.overallStatus ?? object.status ?? "").trim();
|
|
63
|
-
}
|
|
64
|
-
export function statusOf(row) {
|
|
65
|
-
return String(row.status ?? "").trim();
|
|
66
|
-
}
|
|
67
|
-
export function isOutOfScope(row) {
|
|
68
|
-
return statusOf(row) === "out_of_scope_NA" || /out[_ -]?of[_ -]?scope|n\/a|not applicable/i.test(primitiveText(row));
|
|
69
|
-
}
|
|
70
|
-
export function contextDeltaRequired(value) {
|
|
71
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
const object = value;
|
|
75
|
-
return [
|
|
76
|
-
object.context_delta,
|
|
77
|
-
object.contextDelta,
|
|
78
|
-
object.product_context_delta,
|
|
79
|
-
object.productContextDelta,
|
|
80
|
-
object.technical_context_delta,
|
|
81
|
-
object.technicalContextDelta
|
|
82
|
-
].some((item) => /\brequired\b/i.test(primitiveText(item)));
|
|
83
|
-
}
|
|
84
|
-
export function isSurfaceConformanceRow(row) {
|
|
85
|
-
return (/\b(product[_ -]?surface|surface|ia|information[_ -]?architecture|architecture[_ -]?migration|ui)\b/i.test(primitiveText(row.conformance_type)) ||
|
|
86
|
-
!isBlankish(row.owner_surface) ||
|
|
87
|
-
!isBlankish(row.forbidden_primary_surfaces) ||
|
|
88
|
-
!isBlankish(row.required_user_paths));
|
|
89
|
-
}
|
|
90
|
-
export function hasExplicitNoTestScope(row) {
|
|
91
|
-
return /\b(no[- ]?test|no automated test|test out of scope|tests? not required)\b/i.test(primitiveText([row.test_scope, row.no_test_scope, row.tests]));
|
|
92
|
-
}
|
|
93
|
-
export function assertSurfaceConformance(row, label, errors) {
|
|
94
|
-
if (isBlankish(row.owner_surface)) {
|
|
95
|
-
errors.push(`${label} is surface/architecture conformance but owner_surface is empty`);
|
|
96
|
-
}
|
|
97
|
-
if (isBlankish(row.required_user_paths)) {
|
|
98
|
-
errors.push(`${label} is surface/architecture conformance but required_user_paths is empty`);
|
|
99
|
-
}
|
|
100
|
-
if (isBlankish(row.real_page_evidence)) {
|
|
101
|
-
errors.push(`${label} is surface/architecture conformance but real_page_evidence is empty`);
|
|
102
|
-
}
|
|
103
|
-
if (isBlankish(row.context_fact_refs)) {
|
|
104
|
-
errors.push(`${label} is surface/architecture conformance but context_fact_refs is empty`);
|
|
105
|
-
}
|
|
106
|
-
if (!isBlankish(row.forbidden_primary_surfaces) && isBlankish(row.negative_surface_checks)) {
|
|
107
|
-
errors.push(`${label} declares forbidden_primary_surfaces but negative_surface_checks is empty`);
|
|
108
|
-
}
|
|
109
|
-
const userPathText = primitiveText([row.required_user_paths, row.primary_user_paths]);
|
|
110
|
-
const evidenceText = primitiveText([row.real_page_evidence, row.user_path_evidence, row.fresh_evidence, row.runtime_evidence, row.artifact_evidence]);
|
|
111
|
-
for (const forbiddenSurface of valuesAsArray(row.forbidden_primary_surfaces)) {
|
|
112
|
-
if (userPathText.toLowerCase().includes(forbiddenSurface.toLowerCase())) {
|
|
113
|
-
errors.push(`${label} routes a required/primary user path through forbidden surface: ${forbiddenSurface}`);
|
|
114
|
-
}
|
|
115
|
-
if (evidenceText.toLowerCase().includes(forbiddenSurface.toLowerCase())) {
|
|
116
|
-
errors.push(`${label} uses wrong owner surface evidence from forbidden surface: ${forbiddenSurface}`);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
if (row.default_visibility_required === true && !mentionsDefaultVisibility(primitiveText(row.real_page_evidence))) {
|
|
120
|
-
errors.push(`${label} requires default visibility but real_page_evidence does not record default-visible proof`);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
export function assertStructuredNa(row, label, errors) {
|
|
124
|
-
if (isBlankish(row.na_reason) && isBlankish(row.out_of_scope_reason)) {
|
|
125
|
-
errors.push(`${label} is out_of_scope_NA but lacks na_reason or out_of_scope_reason`);
|
|
126
|
-
}
|
|
127
|
-
if (isBlankish(row.scope_source) && isBlankish(row.approval_source) && isBlankish(row.source_reference)) {
|
|
128
|
-
errors.push(`${label} is out_of_scope_NA but lacks scope_source, approval_source or source_reference`);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
function mentionsDefaultVisibility(value) {
|
|
132
|
-
return /\b(default[- ]?visible|visible by default|primary entry|first-level|top-level|main entry)\b/i.test(value);
|
|
133
|
-
}
|