@sun-asterisk/sungen 3.2.34-beta.1 → 3.3.0-alpha.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/dist/basis/anchor-grammar.d.ts +32 -0
- package/dist/basis/anchor-grammar.d.ts.map +1 -0
- package/dist/basis/anchor-grammar.js +82 -0
- package/dist/basis/anchor-grammar.js.map +1 -0
- package/dist/basis/anchor-hash.d.ts +6 -0
- package/dist/basis/anchor-hash.d.ts.map +1 -0
- package/dist/basis/anchor-hash.js +28 -0
- package/dist/basis/anchor-hash.js.map +1 -0
- package/dist/basis/bm51-tables.d.ts +20 -0
- package/dist/basis/bm51-tables.d.ts.map +1 -0
- package/dist/basis/bm51-tables.js +71 -0
- package/dist/basis/bm51-tables.js.map +1 -0
- package/dist/basis/extract-spec-anchors.d.ts +39 -0
- package/dist/basis/extract-spec-anchors.d.ts.map +1 -0
- package/dist/basis/extract-spec-anchors.js +81 -0
- package/dist/basis/extract-spec-anchors.js.map +1 -0
- package/dist/basis/migration-sentinel.d.ts +47 -0
- package/dist/basis/migration-sentinel.d.ts.map +1 -0
- package/dist/basis/migration-sentinel.js +219 -0
- package/dist/basis/migration-sentinel.js.map +1 -0
- package/dist/basis/spec-frontmatter.d.ts +18 -0
- package/dist/basis/spec-frontmatter.d.ts.map +1 -0
- package/dist/basis/spec-frontmatter.js +55 -0
- package/dist/basis/spec-frontmatter.js.map +1 -0
- package/dist/basis/spec-sections.d.ts +18 -0
- package/dist/basis/spec-sections.d.ts.map +1 -0
- package/dist/basis/spec-sections.js +27 -0
- package/dist/basis/spec-sections.js.map +1 -0
- package/dist/basis/test-basis-schema.d.ts +28 -0
- package/dist/basis/test-basis-schema.d.ts.map +1 -0
- package/dist/basis/test-basis-schema.js +141 -0
- package/dist/basis/test-basis-schema.js.map +1 -0
- package/dist/capabilities/registry.d.ts +15 -0
- package/dist/capabilities/registry.d.ts.map +1 -1
- package/dist/capabilities/registry.js.map +1 -1
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/audit.js +3 -29
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/capability.js +1 -1
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/cli/commands/contract-derive-command.d.ts +10 -0
- package/dist/cli/commands/contract-derive-command.d.ts.map +1 -0
- package/dist/cli/commands/contract-derive-command.js +99 -0
- package/dist/cli/commands/contract-derive-command.js.map +1 -0
- package/dist/cli/commands/contract.d.ts +17 -0
- package/dist/cli/commands/contract.d.ts.map +1 -0
- package/dist/cli/commands/contract.js +162 -0
- package/dist/cli/commands/contract.js.map +1 -0
- package/dist/cli/commands/delivery.d.ts.map +1 -1
- package/dist/cli/commands/delivery.js +52 -3
- package/dist/cli/commands/delivery.js.map +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +3 -1
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/journey.d.ts.map +1 -1
- package/dist/cli/commands/journey.js +41 -13
- package/dist/cli/commands/journey.js.map +1 -1
- package/dist/cli/commands/next.d.ts +8 -0
- package/dist/cli/commands/next.d.ts.map +1 -1
- package/dist/cli/commands/next.js +64 -6
- package/dist/cli/commands/next.js.map +1 -1
- package/dist/cli/commands/update.d.ts +11 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +31 -6
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/index.js +20 -35
- package/dist/cli/index.js.map +1 -1
- package/dist/contract/approve-contract.d.ts +31 -0
- package/dist/contract/approve-contract.d.ts.map +1 -0
- package/dist/contract/approve-contract.js +87 -0
- package/dist/contract/approve-contract.js.map +1 -0
- package/dist/contract/assertion-matcher-vocabulary.d.ts +24 -0
- package/dist/contract/assertion-matcher-vocabulary.d.ts.map +1 -0
- package/dist/contract/assertion-matcher-vocabulary.js +100 -0
- package/dist/contract/assertion-matcher-vocabulary.js.map +1 -0
- package/dist/contract/build-contract-verdict.d.ts +32 -0
- package/dist/contract/build-contract-verdict.d.ts.map +1 -0
- package/dist/contract/build-contract-verdict.js +123 -0
- package/dist/contract/build-contract-verdict.js.map +1 -0
- package/dist/contract/build-trace-conformance.d.ts +18 -0
- package/dist/contract/build-trace-conformance.d.ts.map +1 -0
- package/dist/contract/build-trace-conformance.js +153 -0
- package/dist/contract/build-trace-conformance.js.map +1 -0
- package/dist/contract/classify-contract-change.d.ts +23 -0
- package/dist/contract/classify-contract-change.d.ts.map +1 -0
- package/dist/contract/classify-contract-change.js +98 -0
- package/dist/contract/classify-contract-change.js.map +1 -0
- package/dist/contract/classify-contract-unit.d.ts +18 -0
- package/dist/contract/classify-contract-unit.d.ts.map +1 -0
- package/dist/contract/classify-contract-unit.js +49 -0
- package/dist/contract/classify-contract-unit.js.map +1 -0
- package/dist/contract/classify-trace-conformance.d.ts +32 -0
- package/dist/contract/classify-trace-conformance.d.ts.map +1 -0
- package/dist/contract/classify-trace-conformance.js +117 -0
- package/dist/contract/classify-trace-conformance.js.map +1 -0
- package/dist/contract/contract-git.d.ts +24 -0
- package/dist/contract/contract-git.d.ts.map +1 -0
- package/dist/contract/contract-git.js +144 -0
- package/dist/contract/contract-git.js.map +1 -0
- package/dist/contract/contract-hash.d.ts +7 -0
- package/dist/contract/contract-hash.d.ts.map +1 -0
- package/dist/contract/contract-hash.js +38 -0
- package/dist/contract/contract-hash.js.map +1 -0
- package/dist/contract/contract-report-file.d.ts +4 -0
- package/dist/contract/contract-report-file.d.ts.map +1 -0
- package/dist/contract/contract-report-file.js +60 -0
- package/dist/contract/contract-report-file.js.map +1 -0
- package/dist/contract/contract-schema.d.ts +71 -0
- package/dist/contract/contract-schema.d.ts.map +1 -0
- package/dist/contract/contract-schema.js +102 -0
- package/dist/contract/contract-schema.js.map +1 -0
- package/dist/contract/contract-units.d.ts +12 -0
- package/dist/contract/contract-units.d.ts.map +1 -0
- package/dist/contract/contract-units.js +96 -0
- package/dist/contract/contract-units.js.map +1 -0
- package/dist/contract/contracts-lock-file.d.ts +24 -0
- package/dist/contract/contracts-lock-file.d.ts.map +1 -0
- package/dist/contract/contracts-lock-file.js +140 -0
- package/dist/contract/contracts-lock-file.js.map +1 -0
- package/dist/contract/data-normalize.d.ts +10 -0
- package/dist/contract/data-normalize.d.ts.map +1 -0
- package/dist/contract/data-normalize.js +110 -0
- package/dist/contract/data-normalize.js.map +1 -0
- package/dist/contract/derive-free-feature.d.ts +30 -0
- package/dist/contract/derive-free-feature.d.ts.map +1 -0
- package/dist/contract/derive-free-feature.js +145 -0
- package/dist/contract/derive-free-feature.js.map +1 -0
- package/dist/contract/field-semantic-redaction.d.ts +21 -0
- package/dist/contract/field-semantic-redaction.d.ts.map +1 -0
- package/dist/contract/field-semantic-redaction.js +118 -0
- package/dist/contract/field-semantic-redaction.js.map +1 -0
- package/dist/contract/free-feature-blocks.d.ts +10 -0
- package/dist/contract/free-feature-blocks.d.ts.map +1 -0
- package/dist/contract/free-feature-blocks.js +94 -0
- package/dist/contract/free-feature-blocks.js.map +1 -0
- package/dist/contract/lock-secret-guard.d.ts +22 -0
- package/dist/contract/lock-secret-guard.d.ts.map +1 -0
- package/dist/contract/lock-secret-guard.js +134 -0
- package/dist/contract/lock-secret-guard.js.map +1 -0
- package/dist/contract/lock-vs-git-head.d.ts +26 -0
- package/dist/contract/lock-vs-git-head.d.ts.map +1 -0
- package/dist/contract/lock-vs-git-head.js +28 -0
- package/dist/contract/lock-vs-git-head.js.map +1 -0
- package/dist/contract/normalize-contract-step.d.ts +21 -0
- package/dist/contract/normalize-contract-step.d.ts.map +1 -0
- package/dist/contract/normalize-contract-step.js +70 -0
- package/dist/contract/normalize-contract-step.js.map +1 -0
- package/dist/contract/normalize-feature-steps.d.ts +7 -0
- package/dist/contract/normalize-feature-steps.d.ts.map +1 -0
- package/dist/contract/normalize-feature-steps.js +127 -0
- package/dist/contract/normalize-feature-steps.js.map +1 -0
- package/dist/contract/oracle-strength.d.ts +12 -0
- package/dist/contract/oracle-strength.d.ts.map +1 -0
- package/dist/contract/oracle-strength.js +88 -0
- package/dist/contract/oracle-strength.js.map +1 -0
- package/dist/contract/project-contract-blockers.d.ts +10 -0
- package/dist/contract/project-contract-blockers.d.ts.map +1 -0
- package/dist/contract/project-contract-blockers.js +73 -0
- package/dist/contract/project-contract-blockers.js.map +1 -0
- package/dist/contract/record-contract-approval.d.ts +21 -0
- package/dist/contract/record-contract-approval.d.ts.map +1 -0
- package/dist/contract/record-contract-approval.js +98 -0
- package/dist/contract/record-contract-approval.js.map +1 -0
- package/dist/contract/render-free-gherkin.d.ts +40 -0
- package/dist/contract/render-free-gherkin.d.ts.map +1 -0
- package/dist/contract/render-free-gherkin.js +141 -0
- package/dist/contract/render-free-gherkin.js.map +1 -0
- package/dist/contract/render-trace-sentence.d.ts +20 -0
- package/dist/contract/render-trace-sentence.d.ts.map +1 -0
- package/dist/contract/render-trace-sentence.js +109 -0
- package/dist/contract/render-trace-sentence.js.map +1 -0
- package/dist/contract/render-trace-target.d.ts +14 -0
- package/dist/contract/render-trace-target.d.ts.map +1 -0
- package/dist/contract/render-trace-target.js +70 -0
- package/dist/contract/render-trace-target.js.map +1 -0
- package/dist/contract/resolve-unit-trace-identities.d.ts +8 -0
- package/dist/contract/resolve-unit-trace-identities.d.ts.map +1 -0
- package/dist/contract/resolve-unit-trace-identities.js +78 -0
- package/dist/contract/resolve-unit-trace-identities.js.map +1 -0
- package/dist/contract/trace/collect-trace-evidence.d.ts +33 -0
- package/dist/contract/trace/collect-trace-evidence.d.ts.map +1 -0
- package/dist/contract/trace/collect-trace-evidence.js +161 -0
- package/dist/contract/trace/collect-trace-evidence.js.map +1 -0
- package/dist/contract/trace/identity-cache.d.ts +19 -0
- package/dist/contract/trace/identity-cache.d.ts.map +1 -0
- package/dist/contract/trace/identity-cache.js +104 -0
- package/dist/contract/trace/identity-cache.js.map +1 -0
- package/dist/contract/trace/select-final-attempt.d.ts +27 -0
- package/dist/contract/trace/select-final-attempt.d.ts.map +1 -0
- package/dist/contract/trace/select-final-attempt.js +116 -0
- package/dist/contract/trace/select-final-attempt.js.map +1 -0
- package/dist/contract/trace/snapshot-html-renderer.d.ts +31 -0
- package/dist/contract/trace/snapshot-html-renderer.d.ts.map +1 -0
- package/dist/contract/trace/snapshot-html-renderer.js +172 -0
- package/dist/contract/trace/snapshot-html-renderer.js.map +1 -0
- package/dist/contract/trace/snapshot-resolver.d.ts +21 -0
- package/dist/contract/trace/snapshot-resolver.d.ts.map +1 -0
- package/dist/contract/trace/snapshot-resolver.js +65 -0
- package/dist/contract/trace/snapshot-resolver.js.map +1 -0
- package/dist/contract/trace/snapshot-store.d.ts +66 -0
- package/dist/contract/trace/snapshot-store.d.ts.map +1 -0
- package/dist/contract/trace/snapshot-store.js +173 -0
- package/dist/contract/trace/snapshot-store.js.map +1 -0
- package/dist/contract/trace/target-identity.d.ts +74 -0
- package/dist/contract/trace/target-identity.d.ts.map +1 -0
- package/dist/contract/trace/target-identity.js +68 -0
- package/dist/contract/trace/target-identity.js.map +1 -0
- package/dist/contract/trace/test-step-join.d.ts +65 -0
- package/dist/contract/trace/test-step-join.d.ts.map +1 -0
- package/dist/contract/trace/test-step-join.js +80 -0
- package/dist/contract/trace/test-step-join.js.map +1 -0
- package/dist/contract/trace/trace-binding.d.ts +21 -0
- package/dist/contract/trace/trace-binding.d.ts.map +1 -0
- package/dist/contract/trace/trace-binding.js +88 -0
- package/dist/contract/trace/trace-binding.js.map +1 -0
- package/dist/contract/trace/trace-file-reader.d.ts +35 -0
- package/dist/contract/trace/trace-file-reader.d.ts.map +1 -0
- package/dist/contract/trace/trace-file-reader.js +155 -0
- package/dist/contract/trace/trace-file-reader.js.map +1 -0
- package/dist/contract/trace/trace-fingerprint.d.ts +22 -0
- package/dist/contract/trace/trace-fingerprint.d.ts.map +1 -0
- package/dist/contract/trace/trace-fingerprint.js +96 -0
- package/dist/contract/trace/trace-fingerprint.js.map +1 -0
- package/dist/contract/trace/trace-identity-resolution.d.ts +26 -0
- package/dist/contract/trace/trace-identity-resolution.d.ts.map +1 -0
- package/dist/contract/trace/trace-identity-resolution.js +84 -0
- package/dist/contract/trace/trace-identity-resolution.js.map +1 -0
- package/dist/contract/trace/trace-run-record.d.ts +27 -0
- package/dist/contract/trace/trace-run-record.d.ts.map +1 -0
- package/dist/contract/trace/trace-run-record.js +115 -0
- package/dist/contract/trace/trace-run-record.js.map +1 -0
- package/dist/contract/trace/trace-steps.d.ts +19 -0
- package/dist/contract/trace/trace-steps.d.ts.map +1 -0
- package/dist/contract/trace/trace-steps.js +79 -0
- package/dist/contract/trace/trace-steps.js.map +1 -0
- package/dist/contract/trace/trace-zip-limits.d.ts +41 -0
- package/dist/contract/trace/trace-zip-limits.d.ts.map +1 -0
- package/dist/contract/trace/trace-zip-limits.js +48 -0
- package/dist/contract/trace/trace-zip-limits.js.map +1 -0
- package/dist/contract/trace/trace-zip-reader.d.ts +10 -0
- package/dist/contract/trace/trace-zip-reader.d.ts.map +1 -0
- package/dist/contract/trace/trace-zip-reader.js +186 -0
- package/dist/contract/trace/trace-zip-reader.js.map +1 -0
- package/dist/contract/verify-approval-decisions.d.ts +5 -0
- package/dist/contract/verify-approval-decisions.d.ts.map +1 -0
- package/dist/contract/verify-approval-decisions.js +104 -0
- package/dist/contract/verify-approval-decisions.js.map +1 -0
- package/dist/decisions/append-decision.d.ts +12 -0
- package/dist/decisions/append-decision.d.ts.map +1 -0
- package/dist/decisions/append-decision.js +73 -0
- package/dist/decisions/append-decision.js.map +1 -0
- package/dist/decisions/confirmed-decision-commands.d.ts +30 -0
- package/dist/decisions/confirmed-decision-commands.d.ts.map +1 -0
- package/dist/decisions/confirmed-decision-commands.js +172 -0
- package/dist/decisions/confirmed-decision-commands.js.map +1 -0
- package/dist/decisions/decision-file.d.ts +31 -0
- package/dist/decisions/decision-file.d.ts.map +1 -0
- package/dist/decisions/decision-file.js +139 -0
- package/dist/decisions/decision-file.js.map +1 -0
- package/dist/decisions/decision-identity.d.ts +12 -0
- package/dist/decisions/decision-identity.d.ts.map +1 -0
- package/dist/decisions/decision-identity.js +78 -0
- package/dist/decisions/decision-identity.js.map +1 -0
- package/dist/decisions/decision-integrity-check.d.ts +12 -0
- package/dist/decisions/decision-integrity-check.d.ts.map +1 -0
- package/dist/decisions/decision-integrity-check.js +102 -0
- package/dist/decisions/decision-integrity-check.js.map +1 -0
- package/dist/decisions/decision-schema.d.ts +42 -0
- package/dist/decisions/decision-schema.d.ts.map +1 -0
- package/dist/decisions/decision-schema.js +75 -0
- package/dist/decisions/decision-schema.js.map +1 -0
- package/dist/decisions/decision-source.d.ts +2 -0
- package/dist/decisions/decision-source.d.ts.map +1 -0
- package/dist/decisions/decision-source.js +18 -0
- package/dist/decisions/decision-source.js.map +1 -0
- package/dist/decisions/exclusive-file-create.d.ts +3 -0
- package/dist/decisions/exclusive-file-create.d.ts.map +1 -0
- package/dist/decisions/exclusive-file-create.js +84 -0
- package/dist/decisions/exclusive-file-create.js.map +1 -0
- package/dist/decisions/git-head-trust.d.ts +7 -0
- package/dist/decisions/git-head-trust.d.ts.map +1 -0
- package/dist/decisions/git-head-trust.js +76 -0
- package/dist/decisions/git-head-trust.js.map +1 -0
- package/dist/decisions/human-confirmation.d.ts +33 -0
- package/dist/decisions/human-confirmation.d.ts.map +1 -0
- package/dist/decisions/human-confirmation.js +155 -0
- package/dist/decisions/human-confirmation.js.map +1 -0
- package/dist/decisions/legacy-waiver-migration.d.ts +31 -0
- package/dist/decisions/legacy-waiver-migration.d.ts.map +1 -0
- package/dist/decisions/legacy-waiver-migration.js +170 -0
- package/dist/decisions/legacy-waiver-migration.js.map +1 -0
- package/dist/decisions/read-decisions.d.ts +19 -0
- package/dist/decisions/read-decisions.d.ts.map +1 -0
- package/dist/decisions/read-decisions.js +90 -0
- package/dist/decisions/read-decisions.js.map +1 -0
- package/dist/decisions/viewpoint-baseline-adapter.d.ts +7 -0
- package/dist/decisions/viewpoint-baseline-adapter.d.ts.map +1 -0
- package/dist/decisions/viewpoint-baseline-adapter.js +109 -0
- package/dist/decisions/viewpoint-baseline-adapter.js.map +1 -0
- package/dist/decisions/waiver-decisions.d.ts +24 -0
- package/dist/decisions/waiver-decisions.d.ts.map +1 -0
- package/dist/decisions/waiver-decisions.js +46 -0
- package/dist/decisions/waiver-decisions.js.map +1 -0
- package/dist/exporters/matrix/build.d.ts +3 -0
- package/dist/exporters/matrix/build.d.ts.map +1 -1
- package/dist/exporters/matrix/build.js +10 -9
- package/dist/exporters/matrix/build.js.map +1 -1
- package/dist/exporters/matrix/export.d.ts +3 -0
- package/dist/exporters/matrix/export.d.ts.map +1 -1
- package/dist/exporters/matrix/export.js +2 -0
- package/dist/exporters/matrix/export.js.map +1 -1
- package/dist/exporters/matrix/gates.d.ts +6 -1
- package/dist/exporters/matrix/gates.d.ts.map +1 -1
- package/dist/exporters/matrix/gates.js +57 -128
- package/dist/exporters/matrix/gates.js.map +1 -1
- package/dist/exporters/matrix/render-csv.d.ts.map +1 -1
- package/dist/exporters/matrix/render-csv.js +3 -0
- package/dist/exporters/matrix/render-csv.js.map +1 -1
- package/dist/exporters/matrix/render-gate-overrides-sheet.d.ts +13 -0
- package/dist/exporters/matrix/render-gate-overrides-sheet.d.ts.map +1 -0
- package/dist/exporters/matrix/render-gate-overrides-sheet.js +44 -0
- package/dist/exporters/matrix/render-gate-overrides-sheet.js.map +1 -0
- package/dist/exporters/matrix/render-xlsx.d.ts +1 -0
- package/dist/exporters/matrix/render-xlsx.d.ts.map +1 -1
- package/dist/exporters/matrix/render-xlsx.js +3 -0
- package/dist/exporters/matrix/render-xlsx.js.map +1 -1
- package/dist/exporters/matrix/types.d.ts +4 -1
- package/dist/exporters/matrix/types.d.ts.map +1 -1
- package/dist/exporters/matrix/types.js.map +1 -1
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +13 -0
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/graph/evaluate-graph.d.ts +21 -0
- package/dist/graph/evaluate-graph.d.ts.map +1 -0
- package/dist/graph/evaluate-graph.js +49 -0
- package/dist/graph/evaluate-graph.js.map +1 -0
- package/dist/graph/locate-finding.d.ts +20 -0
- package/dist/graph/locate-finding.d.ts.map +1 -0
- package/dist/graph/locate-finding.js +137 -0
- package/dist/graph/locate-finding.js.map +1 -0
- package/dist/graph/node-decl.d.ts +59 -0
- package/dist/graph/node-decl.d.ts.map +1 -0
- package/dist/graph/node-decl.js +8 -0
- package/dist/graph/node-decl.js.map +1 -0
- package/dist/graph/nodes/core-node-catalog.d.ts +7 -0
- package/dist/graph/nodes/core-node-catalog.d.ts.map +1 -0
- package/dist/graph/nodes/core-node-catalog.js +13 -0
- package/dist/graph/nodes/core-node-catalog.js.map +1 -0
- package/dist/graph/nodes/test-case-contract-nodes.d.ts +19 -0
- package/dist/graph/nodes/test-case-contract-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/test-case-contract-nodes.js +56 -0
- package/dist/graph/nodes/test-case-contract-nodes.js.map +1 -0
- package/dist/graph/nodes/test-case-nodes.d.ts +26 -0
- package/dist/graph/nodes/test-case-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/test-case-nodes.js +66 -0
- package/dist/graph/nodes/test-case-nodes.js.map +1 -0
- package/dist/graph/nodes/unit-audit-nodes.d.ts +18 -0
- package/dist/graph/nodes/unit-audit-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/unit-audit-nodes.js +95 -0
- package/dist/graph/nodes/unit-audit-nodes.js.map +1 -0
- package/dist/graph/nodes/unit-contract-node.d.ts +20 -0
- package/dist/graph/nodes/unit-contract-node.d.ts.map +1 -0
- package/dist/graph/nodes/unit-contract-node.js +81 -0
- package/dist/graph/nodes/unit-contract-node.js.map +1 -0
- package/dist/graph/nodes/unit-design-nodes.d.ts +14 -0
- package/dist/graph/nodes/unit-design-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/unit-design-nodes.js +90 -0
- package/dist/graph/nodes/unit-design-nodes.js.map +1 -0
- package/dist/graph/nodes/unit-execution-nodes.d.ts +16 -0
- package/dist/graph/nodes/unit-execution-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/unit-execution-nodes.js +79 -0
- package/dist/graph/nodes/unit-execution-nodes.js.map +1 -0
- package/dist/graph/test-case-identity.d.ts +13 -0
- package/dist/graph/test-case-identity.d.ts.map +1 -0
- package/dist/graph/test-case-identity.js +106 -0
- package/dist/graph/test-case-identity.js.map +1 -0
- package/dist/graph/test-case-results.d.ts +11 -0
- package/dist/graph/test-case-results.d.ts.map +1 -0
- package/dist/graph/test-case-results.js +137 -0
- package/dist/graph/test-case-results.js.map +1 -0
- package/dist/graph/test-case-satisfied.d.ts +25 -0
- package/dist/graph/test-case-satisfied.d.ts.map +1 -0
- package/dist/graph/test-case-satisfied.js +51 -0
- package/dist/graph/test-case-satisfied.js.map +1 -0
- package/dist/graph/test-case-state-shape.d.ts +67 -0
- package/dist/graph/test-case-state-shape.d.ts.map +1 -0
- package/dist/graph/test-case-state-shape.js +3 -0
- package/dist/graph/test-case-state-shape.js.map +1 -0
- package/dist/graph/test-case-states.d.ts +9 -0
- package/dist/graph/test-case-states.d.ts.map +1 -0
- package/dist/graph/test-case-states.js +116 -0
- package/dist/graph/test-case-states.js.map +1 -0
- package/dist/graph/unit-artifact-probes.d.ts +19 -0
- package/dist/graph/unit-artifact-probes.d.ts.map +1 -0
- package/dist/graph/unit-artifact-probes.js +133 -0
- package/dist/graph/unit-artifact-probes.js.map +1 -0
- package/dist/graph/unit-state-facts.d.ts +43 -0
- package/dist/graph/unit-state-facts.d.ts.map +1 -0
- package/dist/graph/unit-state-facts.js +87 -0
- package/dist/graph/unit-state-facts.js.map +1 -0
- package/dist/harness/audit.d.ts +11 -0
- package/dist/harness/audit.d.ts.map +1 -1
- package/dist/harness/audit.js +18 -17
- package/dist/harness/audit.js.map +1 -1
- package/dist/harness/catalog/gate-rules.yaml +647 -0
- package/dist/harness/gates/audit-gate-terms.d.ts +41 -0
- package/dist/harness/gates/audit-gate-terms.d.ts.map +1 -0
- package/dist/harness/gates/audit-gate-terms.js +72 -0
- package/dist/harness/gates/audit-gate-terms.js.map +1 -0
- package/dist/harness/gates/audit-gate-verdict.d.ts +31 -0
- package/dist/harness/gates/audit-gate-verdict.d.ts.map +1 -0
- package/dist/harness/gates/audit-gate-verdict.js +101 -0
- package/dist/harness/gates/audit-gate-verdict.js.map +1 -0
- package/dist/harness/gates/audit-input-hash.d.ts +4 -0
- package/dist/harness/gates/audit-input-hash.d.ts.map +1 -0
- package/dist/harness/gates/audit-input-hash.js +96 -0
- package/dist/harness/gates/audit-input-hash.js.map +1 -0
- package/dist/harness/gates/audit-report-verification.d.ts +32 -0
- package/dist/harness/gates/audit-report-verification.d.ts.map +1 -0
- package/dist/harness/gates/audit-report-verification.js +207 -0
- package/dist/harness/gates/audit-report-verification.js.map +1 -0
- package/dist/harness/gates/decisions-hash.d.ts +13 -0
- package/dist/harness/gates/decisions-hash.d.ts.map +1 -0
- package/dist/harness/gates/decisions-hash.js +72 -0
- package/dist/harness/gates/decisions-hash.js.map +1 -0
- package/dist/harness/gates/delivery-checklist.d.ts +21 -0
- package/dist/harness/gates/delivery-checklist.d.ts.map +1 -0
- package/dist/harness/gates/delivery-checklist.js +128 -0
- package/dist/harness/gates/delivery-checklist.js.map +1 -0
- package/dist/harness/gates/delivery-decision-gate.d.ts +29 -0
- package/dist/harness/gates/delivery-decision-gate.d.ts.map +1 -0
- package/dist/harness/gates/delivery-decision-gate.js +91 -0
- package/dist/harness/gates/delivery-decision-gate.js.map +1 -0
- package/dist/harness/gates/delivery-decision-step.d.ts +16 -0
- package/dist/harness/gates/delivery-decision-step.d.ts.map +1 -0
- package/dist/harness/gates/delivery-decision-step.js +71 -0
- package/dist/harness/gates/delivery-decision-step.js.map +1 -0
- package/dist/harness/gates/gate-override-report.d.ts +59 -0
- package/dist/harness/gates/gate-override-report.d.ts.map +1 -0
- package/dist/harness/gates/gate-override-report.js +86 -0
- package/dist/harness/gates/gate-override-report.js.map +1 -0
- package/dist/harness/gates/gate-override-scope.d.ts +18 -0
- package/dist/harness/gates/gate-override-scope.d.ts.map +1 -0
- package/dist/harness/gates/gate-override-scope.js +98 -0
- package/dist/harness/gates/gate-override-scope.js.map +1 -0
- package/dist/harness/gates/gate-override-validation.d.ts +25 -0
- package/dist/harness/gates/gate-override-validation.d.ts.map +1 -0
- package/dist/harness/gates/gate-override-validation.js +81 -0
- package/dist/harness/gates/gate-override-validation.js.map +1 -0
- package/dist/harness/gates/gate-rule-catalog.d.ts +24 -0
- package/dist/harness/gates/gate-rule-catalog.d.ts.map +1 -0
- package/dist/harness/gates/gate-rule-catalog.js +112 -0
- package/dist/harness/gates/gate-rule-catalog.js.map +1 -0
- package/dist/harness/gates/gate-terms.d.ts +33 -0
- package/dist/harness/gates/gate-terms.d.ts.map +1 -0
- package/dist/harness/gates/gate-terms.js +41 -0
- package/dist/harness/gates/gate-terms.js.map +1 -0
- package/dist/harness/gates/in-run-decision-check.d.ts +21 -0
- package/dist/harness/gates/in-run-decision-check.d.ts.map +1 -0
- package/dist/harness/gates/in-run-decision-check.js +138 -0
- package/dist/harness/gates/in-run-decision-check.js.map +1 -0
- package/dist/harness/gates/journey-gate-inputs.d.ts +37 -0
- package/dist/harness/gates/journey-gate-inputs.d.ts.map +1 -0
- package/dist/harness/gates/journey-gate-inputs.js +81 -0
- package/dist/harness/gates/journey-gate-inputs.js.map +1 -0
- package/dist/harness/gates/migrated-waiver-review.d.ts +6 -0
- package/dist/harness/gates/migrated-waiver-review.d.ts.map +1 -0
- package/dist/harness/gates/migrated-waiver-review.js +116 -0
- package/dist/harness/gates/migrated-waiver-review.js.map +1 -0
- package/dist/harness/gates/resolve-rule.d.ts +59 -0
- package/dist/harness/gates/resolve-rule.d.ts.map +1 -0
- package/dist/harness/gates/resolve-rule.js +41 -0
- package/dist/harness/gates/resolve-rule.js.map +1 -0
- package/dist/harness/gates/unit-gate-overrides.d.ts +25 -0
- package/dist/harness/gates/unit-gate-overrides.d.ts.map +1 -0
- package/dist/harness/gates/unit-gate-overrides.js +122 -0
- package/dist/harness/gates/unit-gate-overrides.js.map +1 -0
- package/dist/harness/journey.d.ts +24 -1
- package/dist/harness/journey.d.ts.map +1 -1
- package/dist/harness/journey.js +114 -23
- package/dist/harness/journey.js.map +1 -1
- package/dist/harness/manifest.d.ts +12 -0
- package/dist/harness/manifest.d.ts.map +1 -1
- package/dist/harness/manifest.js +71 -43
- package/dist/harness/manifest.js.map +1 -1
- package/dist/harness/next-step.d.ts +39 -6
- package/dist/harness/next-step.d.ts.map +1 -1
- package/dist/harness/next-step.js +34 -218
- package/dist/harness/next-step.js.map +1 -1
- package/dist/harness/parse.d.ts +10 -6
- package/dist/harness/parse.d.ts.map +1 -1
- package/dist/harness/parse.js +22 -11
- package/dist/harness/parse.js.map +1 -1
- package/dist/harness/script-check.d.ts.map +1 -1
- package/dist/harness/script-check.js +22 -5
- package/dist/harness/script-check.js.map +1 -1
- package/dist/harness/sensors.d.ts +14 -3
- package/dist/harness/sensors.d.ts.map +1 -1
- package/dist/harness/sensors.js +50 -49
- package/dist/harness/sensors.js.map +1 -1
- package/dist/harness/viewpoint-baseline.d.ts.map +1 -1
- package/dist/harness/viewpoint-baseline.js +1 -7
- package/dist/harness/viewpoint-baseline.js.map +1 -1
- package/dist/harness/viewpoint-ledger.d.ts +3 -13
- package/dist/harness/viewpoint-ledger.d.ts.map +1 -1
- package/dist/harness/viewpoint-ledger.js +8 -38
- package/dist/harness/viewpoint-ledger.js.map +1 -1
- package/dist/hooks/bash-write-targets.d.ts +15 -0
- package/dist/hooks/bash-write-targets.d.ts.map +1 -0
- package/dist/hooks/bash-write-targets.js +173 -0
- package/dist/hooks/bash-write-targets.js.map +1 -0
- package/dist/hooks/claude-hook-entry.d.ts +11 -0
- package/dist/hooks/claude-hook-entry.d.ts.map +1 -0
- package/dist/hooks/claude-hook-entry.js +137 -0
- package/dist/hooks/claude-hook-entry.js.map +1 -0
- package/dist/hooks/claude-transcript-turn.d.ts +11 -0
- package/dist/hooks/claude-transcript-turn.d.ts.map +1 -0
- package/dist/hooks/claude-transcript-turn.js +143 -0
- package/dist/hooks/claude-transcript-turn.js.map +1 -0
- package/dist/hooks/guard-delivery-contract-rule.d.ts +10 -0
- package/dist/hooks/guard-delivery-contract-rule.d.ts.map +1 -0
- package/dist/hooks/guard-delivery-contract-rule.js +152 -0
- package/dist/hooks/guard-delivery-contract-rule.js.map +1 -0
- package/dist/hooks/guard-protected-paths.d.ts +9 -0
- package/dist/hooks/guard-protected-paths.d.ts.map +1 -0
- package/dist/hooks/guard-protected-paths.js +106 -0
- package/dist/hooks/guard-protected-paths.js.map +1 -0
- package/dist/hooks/guard-rules.d.ts +37 -0
- package/dist/hooks/guard-rules.d.ts.map +1 -0
- package/dist/hooks/guard-rules.js +61 -0
- package/dist/hooks/guard-rules.js.map +1 -0
- package/dist/hooks/guard-tty-spoof-rule.d.ts +15 -0
- package/dist/hooks/guard-tty-spoof-rule.d.ts.map +1 -0
- package/dist/hooks/guard-tty-spoof-rule.js +21 -0
- package/dist/hooks/guard-tty-spoof-rule.js.map +1 -0
- package/dist/hooks/hand-back-core.d.ts +37 -0
- package/dist/hooks/hand-back-core.d.ts.map +1 -0
- package/dist/hooks/hand-back-core.js +115 -0
- package/dist/hooks/hand-back-core.js.map +1 -0
- package/dist/hooks/hook-cli-command.d.ts +9 -0
- package/dist/hooks/hook-cli-command.d.ts.map +1 -0
- package/dist/hooks/hook-cli-command.js +46 -0
- package/dist/hooks/hook-cli-command.js.map +1 -0
- package/dist/hooks/hook-registry.d.ts +10 -0
- package/dist/hooks/hook-registry.d.ts.map +1 -0
- package/dist/hooks/hook-registry.js +24 -0
- package/dist/hooks/hook-registry.js.map +1 -0
- package/dist/hooks/hook-result-contract.d.ts +50 -0
- package/dist/hooks/hook-result-contract.d.ts.map +1 -0
- package/dist/hooks/hook-result-contract.js +80 -0
- package/dist/hooks/hook-result-contract.js.map +1 -0
- package/dist/hooks/hook-toggles.d.ts +10 -0
- package/dist/hooks/hook-toggles.d.ts.map +1 -0
- package/dist/hooks/hook-toggles.js +107 -0
- package/dist/hooks/hook-toggles.js.map +1 -0
- package/dist/hooks/pre-tool-guard-hook.d.ts +10 -0
- package/dist/hooks/pre-tool-guard-hook.d.ts.map +1 -0
- package/dist/hooks/pre-tool-guard-hook.js +105 -0
- package/dist/hooks/pre-tool-guard-hook.js.map +1 -0
- package/dist/hooks/session-start-unit-state-hook.d.ts +13 -0
- package/dist/hooks/session-start-unit-state-hook.d.ts.map +1 -0
- package/dist/hooks/session-start-unit-state-hook.js +55 -0
- package/dist/hooks/session-start-unit-state-hook.js.map +1 -0
- package/dist/hooks/stop-next-step-hook.d.ts +16 -0
- package/dist/hooks/stop-next-step-hook.d.ts.map +1 -0
- package/dist/hooks/stop-next-step-hook.js +42 -0
- package/dist/hooks/stop-next-step-hook.js.map +1 -0
- package/dist/hooks/sungen-project-root.d.ts +19 -0
- package/dist/hooks/sungen-project-root.d.ts.map +1 -0
- package/dist/hooks/sungen-project-root.js +130 -0
- package/dist/hooks/sungen-project-root.js.map +1 -0
- package/dist/orchestrator/ai-skills/command-partial-includes.d.ts +15 -0
- package/dist/orchestrator/ai-skills/command-partial-includes.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/command-partial-includes.js +106 -0
- package/dist/orchestrator/ai-skills/command-partial-includes.js.map +1 -0
- package/dist/orchestrator/ai-skills/commands.d.ts +5 -1
- package/dist/orchestrator/ai-skills/commands.d.ts.map +1 -1
- package/dist/orchestrator/ai-skills/commands.js +16 -6
- package/dist/orchestrator/ai-skills/commands.js.map +1 -1
- package/dist/orchestrator/ai-skills/golden-skills.test.js +29 -0
- package/dist/orchestrator/ai-skills/golden-skills.test.js.map +1 -1
- package/dist/orchestrator/claude-hooks-install.d.ts +27 -0
- package/dist/orchestrator/claude-hooks-install.d.ts.map +1 -0
- package/dist/orchestrator/claude-hooks-install.js +203 -0
- package/dist/orchestrator/claude-hooks-install.js.map +1 -0
- package/dist/orchestrator/flow-manager.d.ts +1 -0
- package/dist/orchestrator/flow-manager.d.ts.map +1 -1
- package/dist/orchestrator/flow-manager.js +52 -3
- package/dist/orchestrator/flow-manager.js.map +1 -1
- package/dist/orchestrator/lockstep-version.d.ts +15 -5
- package/dist/orchestrator/lockstep-version.d.ts.map +1 -1
- package/dist/orchestrator/lockstep-version.js +30 -17
- package/dist/orchestrator/lockstep-version.js.map +1 -1
- package/dist/orchestrator/project-initializer.d.ts +6 -0
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +23 -0
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/screen-manager.d.ts.map +1 -1
- package/dist/orchestrator/screen-manager.js +52 -4
- package/dist/orchestrator/screen-manager.js.map +1 -1
- package/dist/orchestrator/templates/ai-src/commands/add-api.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/add-flow.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/add-screen.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/create-data-test.md +1 -0
- package/dist/orchestrator/templates/ai-src/commands/create-test.md +36 -46
- package/dist/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/delivery.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/design.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/feedback.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/locale.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/review.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/run-test.md +6 -8
- package/dist/orchestrator/templates/ai-src/config/claude.md +20 -7
- package/dist/orchestrator/templates/ai-src/config/copilot.md +20 -7
- package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.claude.md +20 -0
- package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.codex.md +20 -0
- package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.copilot.md +20 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-api-coverage-model/SKILL.md +1 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md +3 -3
- package/dist/orchestrator/templates/ai-src/skills/sungen-data-factory/SKILL.md +9 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md +1 -3
- package/dist/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +1 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-viewpoint/SKILL.md +0 -18
- package/dist/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
- package/dist/orchestrator/viewpoint-pattern-catalog.d.ts +1 -4
- package/dist/orchestrator/viewpoint-pattern-catalog.d.ts.map +1 -1
- package/dist/orchestrator/viewpoint-pattern-catalog.js +2 -5
- package/dist/orchestrator/viewpoint-pattern-catalog.js.map +1 -1
- package/dist/utils/safe-yaml-parse.d.ts +8 -0
- package/dist/utils/safe-yaml-parse.d.ts.map +1 -0
- package/dist/utils/safe-yaml-parse.js +51 -0
- package/dist/utils/safe-yaml-parse.js.map +1 -0
- package/package.json +3 -3
- package/src/basis/anchor-grammar.ts +83 -0
- package/src/basis/anchor-hash.ts +27 -0
- package/src/basis/bm51-tables.ts +65 -0
- package/src/basis/extract-spec-anchors.ts +95 -0
- package/src/basis/migration-sentinel.ts +175 -0
- package/src/basis/spec-frontmatter.ts +68 -0
- package/src/basis/spec-sections.ts +35 -0
- package/src/basis/test-basis-schema.ts +81 -0
- package/src/capabilities/registry.ts +16 -0
- package/src/cli/commands/audit.ts +3 -26
- package/src/cli/commands/capability.ts +1 -1
- package/src/cli/commands/contract-derive-command.ts +60 -0
- package/src/cli/commands/contract.ts +130 -0
- package/src/cli/commands/delivery.ts +52 -3
- package/src/cli/commands/generate.ts +3 -1
- package/src/cli/commands/journey.ts +39 -14
- package/src/cli/commands/next.ts +60 -8
- package/src/cli/commands/update.ts +35 -8
- package/src/cli/index.ts +20 -32
- package/src/contract/approve-contract.ts +94 -0
- package/src/contract/assertion-matcher-vocabulary.ts +93 -0
- package/src/contract/build-contract-verdict.ts +108 -0
- package/src/contract/build-trace-conformance.ts +100 -0
- package/src/contract/classify-contract-change.ts +92 -0
- package/src/contract/classify-contract-unit.ts +47 -0
- package/src/contract/classify-trace-conformance.ts +116 -0
- package/src/contract/contract-git.ts +106 -0
- package/src/contract/contract-hash.ts +34 -0
- package/src/contract/contract-report-file.ts +25 -0
- package/src/contract/contract-schema.ts +137 -0
- package/src/contract/contract-units.ts +52 -0
- package/src/contract/contracts-lock-file.ts +97 -0
- package/src/contract/data-normalize.ts +66 -0
- package/src/contract/derive-free-feature.ts +110 -0
- package/src/contract/field-semantic-redaction.ts +80 -0
- package/src/contract/free-feature-blocks.ts +56 -0
- package/src/contract/lock-secret-guard.ts +95 -0
- package/src/contract/lock-vs-git-head.ts +38 -0
- package/src/contract/normalize-contract-step.ts +74 -0
- package/src/contract/normalize-feature-steps.ts +93 -0
- package/src/contract/oracle-strength.ts +80 -0
- package/src/contract/project-contract-blockers.ts +36 -0
- package/src/contract/record-contract-approval.ts +70 -0
- package/src/contract/render-free-gherkin.ts +113 -0
- package/src/contract/render-trace-sentence.ts +98 -0
- package/src/contract/render-trace-target.ts +68 -0
- package/src/contract/resolve-unit-trace-identities.ts +35 -0
- package/src/contract/trace/collect-trace-evidence.ts +109 -0
- package/src/contract/trace/identity-cache.ts +61 -0
- package/src/contract/trace/select-final-attempt.ts +70 -0
- package/src/contract/trace/snapshot-html-renderer.ts +136 -0
- package/src/contract/trace/snapshot-resolver.ts +66 -0
- package/src/contract/trace/snapshot-store.ts +151 -0
- package/src/contract/trace/target-identity.ts +104 -0
- package/src/contract/trace/test-step-join.ts +103 -0
- package/src/contract/trace/trace-binding.ts +56 -0
- package/src/contract/trace/trace-file-reader.ts +123 -0
- package/src/contract/trace/trace-fingerprint.ts +68 -0
- package/src/contract/trace/trace-identity-resolution.ts +74 -0
- package/src/contract/trace/trace-run-record.ts +74 -0
- package/src/contract/trace/trace-steps.ts +88 -0
- package/src/contract/trace/trace-zip-limits.ts +73 -0
- package/src/contract/trace/trace-zip-reader.ts +127 -0
- package/src/contract/verify-approval-decisions.ts +60 -0
- package/src/decisions/append-decision.ts +35 -0
- package/src/decisions/confirmed-decision-commands.ts +128 -0
- package/src/decisions/decision-file.ts +93 -0
- package/src/decisions/decision-identity.ts +73 -0
- package/src/decisions/decision-integrity-check.ts +61 -0
- package/src/decisions/decision-schema.ts +76 -0
- package/src/decisions/decision-source.ts +14 -0
- package/src/decisions/exclusive-file-create.ts +42 -0
- package/src/decisions/git-head-trust.ts +32 -0
- package/src/decisions/human-confirmation.ts +114 -0
- package/src/decisions/legacy-waiver-migration.ts +135 -0
- package/src/decisions/read-decisions.ts +61 -0
- package/src/decisions/viewpoint-baseline-adapter.ts +74 -0
- package/src/decisions/waiver-decisions.ts +56 -0
- package/src/exporters/matrix/build.ts +11 -9
- package/src/exporters/matrix/export.ts +5 -0
- package/src/exporters/matrix/gates.ts +62 -129
- package/src/exporters/matrix/render-csv.ts +3 -0
- package/src/exporters/matrix/render-gate-overrides-sheet.ts +50 -0
- package/src/exporters/matrix/render-xlsx.ts +3 -0
- package/src/exporters/matrix/types.ts +4 -1
- package/src/generators/test-generator/code-generator.ts +13 -0
- package/src/graph/evaluate-graph.ts +62 -0
- package/src/graph/locate-finding.ts +93 -0
- package/src/graph/node-decl.ts +65 -0
- package/src/graph/nodes/core-node-catalog.ts +15 -0
- package/src/graph/nodes/test-case-contract-nodes.ts +69 -0
- package/src/graph/nodes/test-case-nodes.ts +68 -0
- package/src/graph/nodes/unit-audit-nodes.ts +95 -0
- package/src/graph/nodes/unit-contract-node.ts +82 -0
- package/src/graph/nodes/unit-design-nodes.ts +88 -0
- package/src/graph/nodes/unit-execution-nodes.ts +77 -0
- package/src/graph/test-case-identity.ts +75 -0
- package/src/graph/test-case-results.ts +90 -0
- package/src/graph/test-case-satisfied.ts +55 -0
- package/src/graph/test-case-state-shape.ts +62 -0
- package/src/graph/test-case-states.ts +84 -0
- package/src/graph/unit-artifact-probes.ts +77 -0
- package/src/graph/unit-state-facts.ts +112 -0
- package/src/harness/audit.ts +29 -18
- package/src/harness/catalog/gate-rules.yaml +647 -0
- package/src/harness/gates/audit-gate-terms.ts +80 -0
- package/src/harness/gates/audit-gate-verdict.ts +78 -0
- package/src/harness/gates/audit-input-hash.ts +55 -0
- package/src/harness/gates/audit-report-verification.ts +173 -0
- package/src/harness/gates/decisions-hash.ts +42 -0
- package/src/harness/gates/delivery-checklist.ts +120 -0
- package/src/harness/gates/delivery-decision-gate.ts +111 -0
- package/src/harness/gates/delivery-decision-step.ts +73 -0
- package/src/harness/gates/gate-override-report.ts +114 -0
- package/src/harness/gates/gate-override-scope.ts +66 -0
- package/src/harness/gates/gate-override-validation.ts +75 -0
- package/src/harness/gates/gate-rule-catalog.ts +82 -0
- package/src/harness/gates/gate-terms.ts +59 -0
- package/src/harness/gates/in-run-decision-check.ts +99 -0
- package/src/harness/gates/journey-gate-inputs.ts +89 -0
- package/src/harness/gates/migrated-waiver-review.ts +68 -0
- package/src/harness/gates/resolve-rule.ts +94 -0
- package/src/harness/gates/unit-gate-overrides.ts +99 -0
- package/src/harness/journey.ts +122 -27
- package/src/harness/manifest.ts +67 -43
- package/src/harness/next-step.ts +59 -210
- package/src/harness/parse.ts +25 -15
- package/src/harness/script-check.ts +20 -5
- package/src/harness/sensors.ts +55 -49
- package/src/harness/viewpoint-baseline.ts +1 -7
- package/src/harness/viewpoint-ledger.ts +11 -52
- package/src/hooks/bash-write-targets.ts +109 -0
- package/src/hooks/claude-hook-entry.ts +85 -0
- package/src/hooks/claude-transcript-turn.ts +96 -0
- package/src/hooks/guard-delivery-contract-rule.ts +110 -0
- package/src/hooks/guard-protected-paths.ts +70 -0
- package/src/hooks/guard-rules.ts +98 -0
- package/src/hooks/guard-tty-spoof-rule.ts +31 -0
- package/src/hooks/hand-back-core.ts +106 -0
- package/src/hooks/hook-cli-command.ts +17 -0
- package/src/hooks/hook-registry.ts +24 -0
- package/src/hooks/hook-result-contract.ts +114 -0
- package/src/hooks/hook-toggles.ts +66 -0
- package/src/hooks/pre-tool-guard-hook.ts +67 -0
- package/src/hooks/session-start-unit-state-hook.ts +54 -0
- package/src/hooks/stop-next-step-hook.ts +37 -0
- package/src/hooks/sungen-project-root.ts +80 -0
- package/src/orchestrator/ai-skills/command-partial-includes.ts +72 -0
- package/src/orchestrator/ai-skills/commands.ts +22 -8
- package/src/orchestrator/ai-skills/golden-skills.test.ts +23 -0
- package/src/orchestrator/claude-hooks-install.ts +168 -0
- package/src/orchestrator/flow-manager.ts +53 -3
- package/src/orchestrator/lockstep-version.ts +28 -15
- package/src/orchestrator/project-initializer.ts +21 -0
- package/src/orchestrator/screen-manager.ts +52 -4
- package/src/orchestrator/templates/ai-src/commands/add-api.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/add-flow.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/add-screen.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/create-data-test.md +1 -0
- package/src/orchestrator/templates/ai-src/commands/create-test.md +36 -46
- package/src/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/delivery.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/design.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/feedback.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/locale.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/review.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/run-test.md +6 -8
- package/src/orchestrator/templates/ai-src/config/claude.md +20 -7
- package/src/orchestrator/templates/ai-src/config/copilot.md +20 -7
- package/src/orchestrator/templates/ai-src/partials/hand-back-rule.claude.md +20 -0
- package/src/orchestrator/templates/ai-src/partials/hand-back-rule.codex.md +20 -0
- package/src/orchestrator/templates/ai-src/partials/hand-back-rule.copilot.md +20 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-api-coverage-model/SKILL.md +1 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md +3 -3
- package/src/orchestrator/templates/ai-src/skills/sungen-data-factory/SKILL.md +9 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md +1 -3
- package/src/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +1 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-viewpoint/SKILL.md +0 -18
- package/src/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
- package/src/orchestrator/viewpoint-pattern-catalog.ts +2 -5
- package/src/utils/safe-yaml-parse.ts +44 -0
- package/dist/cli/commands/viewpoint.d.ts +0 -7
- package/dist/cli/commands/viewpoint.d.ts.map +0 -1
- package/dist/cli/commands/viewpoint.js +0 -70
- package/dist/cli/commands/viewpoint.js.map +0 -1
- package/dist/harness/viewpoint-draft-header.d.ts +0 -7
- package/dist/harness/viewpoint-draft-header.d.ts.map +0 -1
- package/dist/harness/viewpoint-draft-header.js +0 -100
- package/dist/harness/viewpoint-draft-header.js.map +0 -1
- package/dist/harness/viewpoint-mode.d.ts +0 -9
- package/dist/harness/viewpoint-mode.d.ts.map +0 -1
- package/dist/harness/viewpoint-mode.js +0 -52
- package/dist/harness/viewpoint-mode.js.map +0 -1
- package/dist/harness/viewpoint-priority.d.ts +0 -19
- package/dist/harness/viewpoint-priority.d.ts.map +0 -1
- package/dist/harness/viewpoint-priority.js +0 -36
- package/dist/harness/viewpoint-priority.js.map +0 -1
- package/dist/harness/viewpoint-review-open.d.ts +0 -6
- package/dist/harness/viewpoint-review-open.d.ts.map +0 -1
- package/dist/harness/viewpoint-review-open.js +0 -90
- package/dist/harness/viewpoint-review-open.js.map +0 -1
- package/dist/harness/viewpoint-scan-refs.d.ts +0 -50
- package/dist/harness/viewpoint-scan-refs.d.ts.map +0 -1
- package/dist/harness/viewpoint-scan-refs.js +0 -200
- package/dist/harness/viewpoint-scan-refs.js.map +0 -1
- package/dist/harness/viewpoint-scan.d.ts +0 -41
- package/dist/harness/viewpoint-scan.d.ts.map +0 -1
- package/dist/harness/viewpoint-scan.js +0 -118
- package/dist/harness/viewpoint-scan.js.map +0 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-viewpoint/review-checklist.md +0 -63
- package/dist/orchestrator/templates/ai-src/skills/sungen-viewpoint/viewpoint-template.md +0 -158
- package/dist/orchestrator/viewpoint-scaffold.d.ts +0 -3
- package/dist/orchestrator/viewpoint-scaffold.d.ts.map +0 -1
- package/dist/orchestrator/viewpoint-scaffold.js +0 -70
- package/dist/orchestrator/viewpoint-scaffold.js.map +0 -1
- package/src/cli/commands/viewpoint.ts +0 -58
- package/src/harness/viewpoint-draft-header.ts +0 -55
- package/src/harness/viewpoint-mode.ts +0 -49
- package/src/harness/viewpoint-priority.ts +0 -38
- package/src/harness/viewpoint-review-open.ts +0 -51
- package/src/harness/viewpoint-scan-refs.ts +0 -154
- package/src/harness/viewpoint-scan.ts +0 -111
- package/src/orchestrator/templates/ai-src/skills/sungen-viewpoint/review-checklist.md +0 -63
- package/src/orchestrator/templates/ai-src/skills/sungen-viewpoint/viewpoint-template.md +0 -158
- package/src/orchestrator/viewpoint-scaffold.ts +0 -36
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional `spec.md` frontmatter (DOS-12.2).
|
|
3
|
+
*
|
|
4
|
+
* `source_mode: linked|authored` (default `authored`), `id` and `version` (both in the BM-51
|
|
5
|
+
* template), and `status`, `superseded_by` when present. `screen_id` is kept as metadata only — it
|
|
6
|
+
* never enters an anchor. No frontmatter = the old behavior, so this never throws: a malformed
|
|
7
|
+
* block is reported as a problem and read as absent.
|
|
8
|
+
*/
|
|
9
|
+
import { safeYamlParse } from '../utils/safe-yaml-parse';
|
|
10
|
+
import { isDocId } from './anchor-grammar';
|
|
11
|
+
|
|
12
|
+
export type SourceMode = 'linked' | 'authored';
|
|
13
|
+
|
|
14
|
+
export interface SpecFrontmatter {
|
|
15
|
+
source_mode: SourceMode;
|
|
16
|
+
id?: string;
|
|
17
|
+
version?: string;
|
|
18
|
+
status?: string;
|
|
19
|
+
superseded_by?: string;
|
|
20
|
+
screen_id?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface FrontmatterRead {
|
|
24
|
+
present: boolean;
|
|
25
|
+
frontmatter: SpecFrontmatter;
|
|
26
|
+
/** 0-based index of the first line after the closing fence (0 when there is no frontmatter). */
|
|
27
|
+
bodyStartIndex: number;
|
|
28
|
+
problems: string[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const scalar = (v: unknown): string | undefined =>
|
|
32
|
+
typeof v === 'string' ? v.trim() || undefined : typeof v === 'number' ? String(v) : undefined;
|
|
33
|
+
|
|
34
|
+
export function readSpecFrontmatter(text: string, source = 'spec.md'): FrontmatterRead {
|
|
35
|
+
const absent: FrontmatterRead = { present: false, frontmatter: { source_mode: 'authored' }, bodyStartIndex: 0, problems: [] };
|
|
36
|
+
const lines = text.replace(/^/, '').replace(/\r\n?/g, '\n').split('\n');
|
|
37
|
+
if (lines[0]?.trim() !== '---') return absent;
|
|
38
|
+
const close = lines.findIndex((l, i) => i > 0 && (l.trim() === '---' || l.trim() === '...'));
|
|
39
|
+
if (close < 0) return { ...absent, problems: [`${source}: frontmatter opened with --- but never closed; read as absent`] };
|
|
40
|
+
|
|
41
|
+
const problems: string[] = [];
|
|
42
|
+
let raw: unknown;
|
|
43
|
+
try {
|
|
44
|
+
raw = safeYamlParse(lines.slice(1, close).join('\n'), `${source} frontmatter`);
|
|
45
|
+
} catch (err) {
|
|
46
|
+
return { ...absent, bodyStartIndex: close + 1, problems: [err instanceof Error ? err.message : String(err)] };
|
|
47
|
+
}
|
|
48
|
+
if (raw === null || raw === undefined) raw = {};
|
|
49
|
+
if (typeof raw !== 'object' || Array.isArray(raw)) {
|
|
50
|
+
return { ...absent, bodyStartIndex: close + 1, problems: [`${source}: frontmatter is not a mapping; read as absent`] };
|
|
51
|
+
}
|
|
52
|
+
const fm = raw as Record<string, unknown>;
|
|
53
|
+
const out: SpecFrontmatter = { source_mode: 'authored' };
|
|
54
|
+
|
|
55
|
+
const mode = scalar(fm.source_mode);
|
|
56
|
+
if (mode === 'linked' || mode === 'authored') out.source_mode = mode;
|
|
57
|
+
else if (mode !== undefined) problems.push(`${source}: source_mode "${mode}" is not linked|authored; using authored`);
|
|
58
|
+
|
|
59
|
+
const id = scalar(fm.id);
|
|
60
|
+
if (id && isDocId(id)) out.id = id;
|
|
61
|
+
else if (id) problems.push(`${source}: id "${id}" is not a document id like SPEC-AUTH-001; item anchors are not derived`);
|
|
62
|
+
|
|
63
|
+
for (const key of ['version', 'status', 'superseded_by', 'screen_id'] as const) {
|
|
64
|
+
const v = scalar(fm[key]);
|
|
65
|
+
if (v) out[key] = v;
|
|
66
|
+
}
|
|
67
|
+
return { present: true, frontmatter: out, bodyStartIndex: close + 1, problems };
|
|
68
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `##` / `###` section split of `spec.md`, shared by the manifest and the anchor reader so a
|
|
3
|
+
* `sec-<slug>` anchor and a manifest section can never disagree about where a section starts or
|
|
4
|
+
* what it hashes. The rules are the manifest's original ones, moved here unchanged (red-team #1):
|
|
5
|
+
* every line is scanned, a `Section:` prefix is stripped, the body is everything up to the next
|
|
6
|
+
* `##`/`###` heading.
|
|
7
|
+
*/
|
|
8
|
+
export interface SpecSectionBlock {
|
|
9
|
+
/** Heading text with any `Section:` prefix stripped (not yet normalized). */
|
|
10
|
+
name: string;
|
|
11
|
+
/** 0-based index of the heading line. */
|
|
12
|
+
headingIndex: number;
|
|
13
|
+
body: string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function readSpecSectionBlocks(lines: string[]): SpecSectionBlock[] {
|
|
17
|
+
const out: SpecSectionBlock[] = [];
|
|
18
|
+
let cur: SpecSectionBlock | null = null;
|
|
19
|
+
for (let i = 0; i < lines.length; i++) {
|
|
20
|
+
const h = lines[i].match(/^#{2,3}\s+(.*)$/);
|
|
21
|
+
if (h) {
|
|
22
|
+
if (cur) out.push(cur);
|
|
23
|
+
cur = { name: h[1].replace(/^Section:\s*/i, '').trim(), headingIndex: i, body: [] };
|
|
24
|
+
} else if (cur) {
|
|
25
|
+
cur.body.push(lines[i]);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (cur) out.push(cur);
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** The manifest's section-name key: tier suffix and markdown marks dropped, lower-case, spaces collapsed. */
|
|
33
|
+
export function normalizeSectionName(s: string): string {
|
|
34
|
+
return s.replace(/\(Tier[^)]*\)/i, '').replace(/[#*-]/g, '').trim().toLowerCase().replace(/\s+/g, ' ');
|
|
35
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-basis schema, validator and reader (DOS-12.4). P0 ships only these; the generator and a
|
|
3
|
+
* `BasisProvider` are P1, and there is no `basis.hand-edited` rule.
|
|
4
|
+
*
|
|
5
|
+
* { schema, source_mode, sources:[{docId, uri, version, hash}], anchors:[{id, kind, hash, location}] }
|
|
6
|
+
*
|
|
7
|
+
* It stores pointers and hashes, NEVER spec text (red-team #14). The validator enforces that
|
|
8
|
+
* structurally rather than by promise: unknown keys, multi-line values and long strings are refused,
|
|
9
|
+
* and every id, hash and citation must parse.
|
|
10
|
+
*/
|
|
11
|
+
import * as fs from 'fs';
|
|
12
|
+
import { safeYamlParse } from '../utils/safe-yaml-parse';
|
|
13
|
+
import { AnchorKind, isDocId, parseAnchorId, parseCitation } from './anchor-grammar';
|
|
14
|
+
import { SourceMode } from './spec-frontmatter';
|
|
15
|
+
|
|
16
|
+
export const TEST_BASIS_SCHEMA = 1;
|
|
17
|
+
|
|
18
|
+
export interface TestBasisSource { docId: string; uri: string; version: string; hash: string }
|
|
19
|
+
export interface TestBasisAnchor { id: string; kind: AnchorKind; hash: string; location: string }
|
|
20
|
+
export interface TestBasis { schema: 1; source_mode: SourceMode; sources: TestBasisSource[]; anchors: TestBasisAnchor[] }
|
|
21
|
+
|
|
22
|
+
const MAX_LEN: Record<string, number> = { docId: 64, uri: 2048, version: 64, hash: 64, id: 256, kind: 16, location: 2048 };
|
|
23
|
+
const isObject = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
24
|
+
|
|
25
|
+
/** A pointer field: a short single-line string. Anything longer or multi-line is text, not a pointer. */
|
|
26
|
+
function pointerErrors(where: string, obj: Record<string, unknown>, keys: string[]): string[] {
|
|
27
|
+
const e: string[] = [];
|
|
28
|
+
for (const k of Object.keys(obj)) if (!keys.includes(k)) e.push(`${where}: unknown key "${k}" (a test-basis holds pointers and hashes, never spec text)`);
|
|
29
|
+
for (const k of keys) {
|
|
30
|
+
const v = obj[k];
|
|
31
|
+
if (typeof v !== 'string' || !v.trim()) e.push(`${where}.${k} must be a non-empty string`);
|
|
32
|
+
else if (/[\r\n]/.test(v) || v.length > MAX_LEN[k]) e.push(`${where}.${k} must be a single line of at most ${MAX_LEN[k]} characters`);
|
|
33
|
+
}
|
|
34
|
+
return e;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function validateTestBasis(raw: unknown): string[] {
|
|
38
|
+
if (!isObject(raw)) return ['test-basis must be a mapping'];
|
|
39
|
+
const e: string[] = [];
|
|
40
|
+
for (const k of Object.keys(raw)) if (!['schema', 'source_mode', 'sources', 'anchors'].includes(k)) e.push(`unknown top-level key "${k}"`);
|
|
41
|
+
if (raw.schema !== TEST_BASIS_SCHEMA) e.push(`schema must be ${TEST_BASIS_SCHEMA}`);
|
|
42
|
+
if (raw.source_mode !== 'linked' && raw.source_mode !== 'authored') e.push('source_mode must be linked|authored');
|
|
43
|
+
|
|
44
|
+
const docIds = new Set<string>();
|
|
45
|
+
if (!Array.isArray(raw.sources)) e.push('sources must be a list');
|
|
46
|
+
else raw.sources.forEach((s, i) => {
|
|
47
|
+
if (!isObject(s)) { e.push(`sources[${i}] must be a mapping`); return; }
|
|
48
|
+
e.push(...pointerErrors(`sources[${i}]`, s, ['docId', 'uri', 'version', 'hash']));
|
|
49
|
+
if (typeof s.docId === 'string' && !isDocId(s.docId)) e.push(`sources[${i}].docId "${s.docId}" is not a document id like SPEC-AUTH-001`);
|
|
50
|
+
if (typeof s.hash === 'string' && !/^[0-9a-f]{12,64}$/.test(s.hash)) e.push(`sources[${i}].hash must be 12-64 lowercase hex`);
|
|
51
|
+
if (typeof s.docId === 'string') docIds.add(s.docId);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const seen = new Set<string>();
|
|
55
|
+
if (!Array.isArray(raw.anchors)) e.push('anchors must be a list');
|
|
56
|
+
else raw.anchors.forEach((a, i) => {
|
|
57
|
+
if (!isObject(a)) { e.push(`anchors[${i}] must be a mapping`); return; }
|
|
58
|
+
e.push(...pointerErrors(`anchors[${i}]`, a, ['id', 'kind', 'hash', 'location']));
|
|
59
|
+
const parsed = typeof a.id === 'string' ? parseAnchorId(a.id) : null;
|
|
60
|
+
if (!parsed) e.push(`anchors[${i}].id "${a.id}" is not an anchor (SPEC-ID#A-2, SPEC-ID#A-2/val, sec-<slug>)`);
|
|
61
|
+
else if (parsed.kind !== a.kind) e.push(`anchors[${i}].kind "${a.kind}" disagrees with its id (${parsed.kind})`);
|
|
62
|
+
if (parsed?.docId && !docIds.has(parsed.docId)) e.push(`anchors[${i}] points into ${parsed.docId}, which is not a listed source`);
|
|
63
|
+
if (typeof a.hash === 'string' && !/^[0-9a-f]{12}$/.test(a.hash)) e.push(`anchors[${i}].hash must be 12 lowercase hex (sha1-12 or sha256-12)`);
|
|
64
|
+
if (typeof a.location === 'string' && !parseCitation(a.location)) e.push(`anchors[${i}].location must be repo@SHA:path#Lx-Ly`);
|
|
65
|
+
if (typeof a.id === 'string') { if (seen.has(a.id)) e.push(`anchors[${i}].id "${a.id}" is listed twice`); seen.add(a.id); }
|
|
66
|
+
});
|
|
67
|
+
return e;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Best-effort reader: no file → no basis (an authored spec); a bad file → problems, never a throw. */
|
|
71
|
+
export function readTestBasis(file: string): { basis?: TestBasis; problems: string[] } {
|
|
72
|
+
if (!fs.existsSync(file)) return { problems: [] };
|
|
73
|
+
let raw: unknown;
|
|
74
|
+
try {
|
|
75
|
+
raw = safeYamlParse(fs.readFileSync(file, 'utf8'), file);
|
|
76
|
+
} catch (err) {
|
|
77
|
+
return { problems: [err instanceof Error ? err.message : String(err)] };
|
|
78
|
+
}
|
|
79
|
+
const problems = validateTestBasis(raw);
|
|
80
|
+
return problems.length ? { problems } : { basis: raw as TestBasis, problems };
|
|
81
|
+
}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import type { StepPattern } from '../generators/test-generator/patterns/types';
|
|
15
15
|
import type { Sensor } from './sensor';
|
|
16
16
|
import type { DiscoveryProvider, ContextMapper, RepairProvider } from './context';
|
|
17
|
+
import type { TraceIdentityResolver } from '../contract/trace/target-identity';
|
|
17
18
|
|
|
18
19
|
export interface CapabilityDescriptor {
|
|
19
20
|
/** Stable id: 'ui' | 'db' | 'api' | 'core' | … */
|
|
@@ -70,6 +71,21 @@ export interface CapabilityDescriptor {
|
|
|
70
71
|
*/
|
|
71
72
|
appProfilePresets?: Record<string, unknown>;
|
|
72
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Target-identity resolver for trace-derived contracts: maps a replayed page snapshot + a
|
|
76
|
+
* recorded action to `{role, name, identityConfidence}` using the runtime's own accessibility
|
|
77
|
+
* engine (UI → Playwright `getByRole` / `ariaSnapshot`). Spec: `sungen_capability_spi_spec.md`
|
|
78
|
+
* §4.5, `sungen_durable_orchestration_spec.md` DOS-14.5.
|
|
79
|
+
*
|
|
80
|
+
* Pinned in phase 08 (the phase 07 spike gate passed): core renders each snapshot as inert HTML
|
|
81
|
+
* and asks the resolver for role + name + optional scope per target; a result that is not
|
|
82
|
+
* well-formed is rejected, and anything core already knows forces `low` (missing CSS…). Called
|
|
83
|
+
* only by `sungen contract check --trace` / `contract derive`; the verdict reads the cached
|
|
84
|
+
* answers. There is deliberately no `nodes?` slot: the graph node API is internal to core in P0
|
|
85
|
+
* (OES-10).
|
|
86
|
+
*/
|
|
87
|
+
traceIdentity?: TraceIdentityResolver;
|
|
88
|
+
|
|
73
89
|
// --- Declared for later R-steps; not consumed yet (kept here so the SPI shape is visible). ---
|
|
74
90
|
// adapter?: string; // codegen adapter id (existing adapterRegistry)
|
|
75
91
|
}
|
|
@@ -4,7 +4,6 @@ import * as fs from 'fs';
|
|
|
4
4
|
import { runAudit, AuditReport, catalogIdFromScreenDir } from '../../harness/audit';
|
|
5
5
|
import { reportSlug } from '../../harness/unit-paths';
|
|
6
6
|
import { acceptViewpointBaseline } from '../../harness/viewpoint-baseline';
|
|
7
|
-
import { removeDraftLineFromFile, viewpointFileIsAiDraft } from '../../harness/viewpoint-draft-header';
|
|
8
7
|
import { findUnitDir } from '../resolve-unit';
|
|
9
8
|
|
|
10
9
|
|
|
@@ -144,7 +143,7 @@ function render(r: AuditReport): void {
|
|
|
144
143
|
const held = new Set(r.score.axes.filter((x) => x.withheld).map((x) => x.key));
|
|
145
144
|
const absent = na.filter((k) => !held.has(k));
|
|
146
145
|
if (absent.length) L(` not scored (no evidence in this unit): ${absent.join(', ')}`);
|
|
147
|
-
if (held.size) L(` measured but held (viewpoint
|
|
146
|
+
if (held.size) L(` measured but held (viewpoint baseline changed — review, then --accept-viewpoint): ${[...held].join(', ')}`);
|
|
148
147
|
}
|
|
149
148
|
L(` weakest: ${r.calibration.weakest.axis} ${(r.calibration.weakest.value * 100).toFixed(0)}%${r.calibration.inflated ? ' ⚠ SCORE-INFLATED-BY-BREADTH' : ''}`);
|
|
150
149
|
if (r.calibration.cappedAt !== undefined) {
|
|
@@ -174,14 +173,10 @@ export function registerAuditCommand(program: Command): void {
|
|
|
174
173
|
.option('--area <name>', 'Alias of --api — an API-first area (qa/api/<name>)')
|
|
175
174
|
.option('--json', 'Output the raw JSON report')
|
|
176
175
|
.option('--accept-viewpoint', 'Accept the current test-viewpoint.md as the baseline the suite is measured against')
|
|
177
|
-
.option('--no-baseline', 'Measure without writing .sungen/viewpoint-baseline.json (audit a drafted viewpoint before generating)')
|
|
178
176
|
.action((options) => {
|
|
179
177
|
try {
|
|
180
178
|
const name = options.screen || options.api || options.area;
|
|
181
179
|
if (!name) throw new Error('Provide --screen <name> (or --api <area>)');
|
|
182
|
-
// Commander's `--no-*`: `baseline` is true unless the flag is passed.
|
|
183
|
-
const recordBaseline = options.baseline !== false;
|
|
184
|
-
if (!recordBaseline && options.acceptViewpoint) throw new Error('--no-baseline and --accept-viewpoint cannot be combined');
|
|
185
180
|
const dir = findUnitDir(name);
|
|
186
181
|
if (!dir) throw new Error(`Not found: qa/screens/${name}, qa/flows/${name}, or qa/api/${name}`);
|
|
187
182
|
|
|
@@ -200,35 +195,18 @@ export function registerAuditCommand(program: Command): void {
|
|
|
200
195
|
const unitId = catalogIdFromScreenDir(dir);
|
|
201
196
|
const vb = report.viewpointBaseline;
|
|
202
197
|
const postHoc = vb.status === 'new' && report.scenarioCount > 0;
|
|
203
|
-
// `drafted-by: ai` — a viewpoint the AI wrote is never accepted by the audit that measures it,
|
|
204
|
-
// with scenarios or without: only `--accept-viewpoint` does, and that removes the line.
|
|
205
|
-
const vpPath = path.join(dir, 'requirements', 'test-viewpoint.md');
|
|
206
|
-
const hasDraftMarker = viewpointFileIsAiDraft(vpPath);
|
|
207
|
-
// A draft with no VP id has nothing to accept — only VIEWPOINT-MISSING speaks for it. Fail
|
|
208
|
-
// here, before any write, so the file stays as it is and the QA is told why.
|
|
209
|
-
if (options.acceptViewpoint && vb.status === 'absent' && hasDraftMarker) {
|
|
210
|
-
throw new Error('the draft declares no VP ids — nothing to accept. Add the viewpoint ids (VP-… in the Priority Viewpoints table or checks), then run --accept-viewpoint again.');
|
|
211
|
-
}
|
|
212
|
-
const aiDraft = vb.status !== 'absent' && hasDraftMarker;
|
|
213
198
|
// A re-parsed baseline is a CACHE migration, not an acceptance: the comparison already
|
|
214
199
|
// resolved to `unchanged`, and rewriting the record only lets the NEXT real edit be
|
|
215
200
|
// detected. Left unwritten it would re-migrate — and re-announce — on every run.
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
// scenarios exist is `new` and not post-hoc, and a plain audit would record it as the yardstick.
|
|
219
|
-
if (recordBaseline && !aiDraft && vb.reparsed) acceptViewpointBaseline(process.cwd(), unitId, { hash: vb.hash, ids: vb.ids, fileHash: vb.fileHash });
|
|
220
|
-
if (recordBaseline && ((vb.status === 'new' && !postHoc && !aiDraft) || (options.acceptViewpoint && (vb.status === 'changed' || postHoc || aiDraft)))) {
|
|
201
|
+
if (vb.reparsed) acceptViewpointBaseline(process.cwd(), unitId, { hash: vb.hash, ids: vb.ids, fileHash: vb.fileHash });
|
|
202
|
+
if ((vb.status === 'new' && !postHoc) || (options.acceptViewpoint && (vb.status === 'changed' || postHoc))) {
|
|
221
203
|
acceptViewpointBaseline(process.cwd(), unitId, { hash: vb.hash, ids: vb.ids, fileHash: vb.fileHash });
|
|
222
204
|
if (options.acceptViewpoint) {
|
|
223
|
-
// The baseline is recorded first: if the line cannot be removed the draft stays flagged
|
|
224
|
-
// (held, finding, decide step) and the accept can simply be run again.
|
|
225
|
-
const lineRemoved = aiDraft && removeDraftLineFromFile(vpPath);
|
|
226
205
|
// Measure again against what was just accepted: the report printed and saved below (the
|
|
227
206
|
// one `sungen next` reads) must not be the pre-accept one, still holding the axes (#867).
|
|
228
207
|
report = runAudit(dir, name);
|
|
229
208
|
if (!options.json) {
|
|
230
209
|
console.log(`\n ✓ test-viewpoint.md accepted as the baseline for ${name} (${vb.ids.length} viewpoint id(s)).`);
|
|
231
|
-
if (lineRemoved) console.log(' Removed the `drafted-by: ai` line from test-viewpoint.md — it is QA-reviewed from here on.');
|
|
232
210
|
console.log(' The report below is measured against it.\n');
|
|
233
211
|
}
|
|
234
212
|
}
|
|
@@ -250,7 +228,6 @@ export function registerAuditCommand(program: Command): void {
|
|
|
250
228
|
} else {
|
|
251
229
|
render(report);
|
|
252
230
|
console.log(` Report: ${path.relative(process.cwd(), outPath)}`);
|
|
253
|
-
if (!recordBaseline) console.log(' ○ baseline not recorded (--no-baseline)');
|
|
254
231
|
console.log('');
|
|
255
232
|
}
|
|
256
233
|
// Non-zero exit when the gate fails — usable in CI / repair loop. Set exitCode (not
|
|
@@ -209,7 +209,7 @@ export function registerCapabilityCommand(program: Command): void {
|
|
|
209
209
|
// beta channel can lag (e.g. a prerelease first-published-as-latest), pulling a driver
|
|
210
210
|
// whose core dep resolves to the wrong @sun-asterisk/sungen and fails to load.
|
|
211
211
|
const core = coreVersion();
|
|
212
|
-
const target = resolveDriverVersion(meta.package, core); // exact core, else same-line
|
|
212
|
+
const target = resolveDriverVersion(meta.package, core); // exact core, else same-line build of core's channel, else that channel's tag
|
|
213
213
|
const spec = `${meta.package}@${target}`;
|
|
214
214
|
if (target !== core) {
|
|
215
215
|
console.log(`ℹ ${meta.package}@${core} is not published yet — installing ${spec} (closest on the ${core} line).`);
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sungen contract derive --screen <u> [--grep <re>] [--json]` (DOS-14.8, phase 08): free tests'
|
|
3
|
+
* traces → `features/<u>.free.feature`, every scenario `@free @proposed`, deterministic, no LLM.
|
|
4
|
+
*
|
|
5
|
+
* exit 0 written, unchanged, nothing to derive, or a mobile project (not supported yet)
|
|
6
|
+
* exit 1 refused (a secret or a machine path would have been written — nothing was), or an error
|
|
7
|
+
*/
|
|
8
|
+
import type { Command } from 'commander';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import { deriveFreeFeature, DeriveResult } from '../../contract/derive-free-feature';
|
|
11
|
+
import { registeredTraceResolver } from '../../contract/resolve-unit-trace-identities';
|
|
12
|
+
import { resolveContractUnit } from '../../contract/contract-units';
|
|
13
|
+
|
|
14
|
+
function print(r: DeriveResult, unit: string): void {
|
|
15
|
+
const L = console.log;
|
|
16
|
+
const rel = path.relative(process.cwd(), r.file);
|
|
17
|
+
L('');
|
|
18
|
+
L(`━━━ Contract derive: ${unit} — free tests' traces → ${rel} ━━━`);
|
|
19
|
+
L('');
|
|
20
|
+
if (r.note) L(` ⚠ ${r.note}`);
|
|
21
|
+
for (const s of r.scenarios) L(` + ${s.title} (${s.steps} steps${s.low ? `, ${s.low} low identity` : ''}${s.opaque ? `, ${s.opaque} opaque` : ''})`);
|
|
22
|
+
for (const s of r.skipped) L(` - ${s.id} skipped: ${s.reason}`);
|
|
23
|
+
if (r.refused?.length) {
|
|
24
|
+
L(` ✗ Refused — nothing was written. ${r.refused.length} likely secret(s) / machine path(s):`);
|
|
25
|
+
for (const h of r.refused) L(` ${h.where} — ${h.reason}`);
|
|
26
|
+
L(' Move the value into test-data (or an env overlay) and use it from there, then derive again.');
|
|
27
|
+
} else if (r.written) {
|
|
28
|
+
L(` ✓ Wrote ${rel}. Review the steps (they ARE the contract), then QA approves on a terminal:`);
|
|
29
|
+
L(` sungen contract approve --screen ${unit}`);
|
|
30
|
+
L(' After approval, re-run the free tests (trace: "on") — a trace older than the contract proves nothing.');
|
|
31
|
+
} else if (r.scenarios.length) {
|
|
32
|
+
L(` = ${rel} is already up to date.`);
|
|
33
|
+
} else if (!r.note) {
|
|
34
|
+
L(` = Nothing to derive: no admissible trace of a test for ${unit} (try --grep).`);
|
|
35
|
+
}
|
|
36
|
+
L('');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function registerDeriveCommand(contract: Command): void {
|
|
40
|
+
contract
|
|
41
|
+
.command('derive')
|
|
42
|
+
.description("Write features/<unit>.free.feature (@free @proposed) from the free tests' traces — deterministic, no LLM")
|
|
43
|
+
.option('-s, --screen <name>', 'Screen / flow / api unit name')
|
|
44
|
+
.option('--grep <regex>', 'Which tests, matched against "<id> <title> <file>" (default: tests whose file is named after the unit)')
|
|
45
|
+
.option('--json', 'Output the result as JSON')
|
|
46
|
+
.action(async (options) => {
|
|
47
|
+
try {
|
|
48
|
+
if (!options.screen) throw new Error('Provide --screen <name>');
|
|
49
|
+
const unit = resolveContractUnit(process.cwd(), String(options.screen));
|
|
50
|
+
const r = await deriveFreeFeature({
|
|
51
|
+
projectRoot: process.cwd(), unit, grep: options.grep ? String(options.grep) : undefined, resolver: registeredTraceResolver() ?? null,
|
|
52
|
+
});
|
|
53
|
+
if (options.json) console.log(JSON.stringify(r, null, 2)); else print(r, unit.name);
|
|
54
|
+
process.exit(r.refused?.length ? 1 : 0);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.error('Error:', error instanceof Error ? error.message : error);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sungen contract approve | check` — the Test Contract (DOS-14, phase 06a).
|
|
3
|
+
*
|
|
4
|
+
* approve --screen <u> [--scenario <id>] [--reason <text>]
|
|
5
|
+
* a human types a confirmation on a TTY; writes contracts.lock.yaml + a contract-approval
|
|
6
|
+
* decision. No TTY → refused with the exact command (exit 1).
|
|
7
|
+
* check --screen <u> [--trace] [--json]
|
|
8
|
+
* rebuilds the verdict from .feature + lock + git HEAD + recorded traces (never from a report),
|
|
9
|
+
* writes .sungen/reports/<slug>-contract.json as output (secret-scanned first). Exit 2 on a hard
|
|
10
|
+
* finding, 0 on pass or review, 1 on an error (unknown unit, untrusted lock, unparseable feature).
|
|
11
|
+
* `--trace` first asks driver-ui (a real browser) for the target identities of free / impl:code
|
|
12
|
+
* traces; without it the cached answers are used (DOS-14.5, 14.6).
|
|
13
|
+
* derive --screen <u> [--grep <re>] → contract-derive-command.ts (DOS-14.8)
|
|
14
|
+
*/
|
|
15
|
+
import { Command } from 'commander';
|
|
16
|
+
import * as fs from 'fs';
|
|
17
|
+
import * as path from 'path';
|
|
18
|
+
import { approveContract } from '../../contract/approve-contract';
|
|
19
|
+
import { buildContractVerdict, ContractVerdict } from '../../contract/build-contract-verdict';
|
|
20
|
+
import { contractReportPath, writeContractReport } from '../../contract/contract-report-file';
|
|
21
|
+
import { HARD_CLASSES, REVIEW_CLASSES } from '../../contract/contract-schema';
|
|
22
|
+
import { processIO } from '../../decisions/human-confirmation';
|
|
23
|
+
import { resolveContractUnit } from '../../contract/contract-units';
|
|
24
|
+
import { secretScanHits } from '../../contract/field-semantic-redaction';
|
|
25
|
+
import { resolveUnitTraceIdentities } from '../../contract/resolve-unit-trace-identities';
|
|
26
|
+
import { registerDeriveCommand } from './contract-derive-command';
|
|
27
|
+
|
|
28
|
+
const MARK: Record<string, string> = {
|
|
29
|
+
match: '✓', strengthened: '↑', proposed: '+', 'hash-changed': '⚖', 'oracle-weakened': '✗', 'target-changed': '✗', 'assertion-lost': '✗',
|
|
30
|
+
opaque: '◐', nondeterministic: '≈', inconclusive: '?', unproven: '✗',
|
|
31
|
+
};
|
|
32
|
+
/** `contract check` judges traces with a generous deadline (the guard path keeps ~3 s). */
|
|
33
|
+
const CHECK_TRACE_BUDGET_MS = 120_000;
|
|
34
|
+
const UNPROVEN_HINT = " → free / impl:code tests need trace: 'on' and the sungen run-record reporter, then a fresh run (see `sungen contract derive`).";
|
|
35
|
+
|
|
36
|
+
function printVerdict(v: ContractVerdict, reportFile: string): void {
|
|
37
|
+
const L = console.log;
|
|
38
|
+
const head = v.verdict === 'pass' ? '✓ PASS' : v.verdict === 'review'
|
|
39
|
+
? '⚖ REVIEW — changed, not weaker. Exit 0 here, but review blocks `sungen delivery` until QA re-approves' : '✗ FAIL';
|
|
40
|
+
L('');
|
|
41
|
+
L(`━━━ Contract check: ${v.unit} — Gherkin vs the approved lock ━━━`);
|
|
42
|
+
L('');
|
|
43
|
+
L(` verdict: ${head}`);
|
|
44
|
+
const matched = v.scenarios.filter((s) => s.class === 'match').length;
|
|
45
|
+
for (const s of v.scenarios.filter((x) => x.class !== 'match')) {
|
|
46
|
+
L(` ${MARK[s.class] ?? '?'} ${s.id} ${s.class}${s.class === 'proposed' ? ' (no approved entry — does not block)' : ''}`);
|
|
47
|
+
for (const f of s.findings) L(` ${f.rule ? `[${f.rule}] ` : ''}${f.step ? `step ${f.step}: ` : ''}${f.detail}`);
|
|
48
|
+
if (s.trace?.hashes.length) L(` trace: ${[...new Set(s.trace.hashes)].join(', ')} (${s.trace.runs.length} run(s))`);
|
|
49
|
+
if (s.class === 'unproven') L(UNPROVEN_HINT);
|
|
50
|
+
}
|
|
51
|
+
if (matched) L(` ✓ ${matched} scenario(s) match the approved contract`);
|
|
52
|
+
const issue = (u: ContractVerdict['uncommitted'][number]): string =>
|
|
53
|
+
u.change === 'tampered' || u.change === 'unverified' ? `lock entry ${u.change}: ${u.detail}` : `lock entry ${u.change} and not committed`;
|
|
54
|
+
for (const u of v.uncommitted.slice(0, 10)) L(` ✗ ${u.id} ${issue(u)} [contract.lock-uncommitted]`);
|
|
55
|
+
if (v.uncommitted.length > 10) L(` ✗ … and ${v.uncommitted.length - 10} more lock entries that are not what QA approved and committed`);
|
|
56
|
+
for (const w of v.warnings) L(` ⚠ ${w}`);
|
|
57
|
+
L('');
|
|
58
|
+
// Only missing / refused traces: re-approving cannot help, a fresh traced run can.
|
|
59
|
+
const blocking = v.scenarios.filter((s) => HARD_CLASSES.has(s.class) || REVIEW_CLASSES.has(s.class));
|
|
60
|
+
const onlyUnproven = blocking.length > 0 && blocking.every((s) => s.class === 'unproven');
|
|
61
|
+
if (v.verdict === 'fail') {
|
|
62
|
+
L(v.uncommitted.length
|
|
63
|
+
? ' → Commit the approval (lock + decision) through review, or restore the lock from git (`git checkout -- <lock>`).'
|
|
64
|
+
: onlyUnproven ? " → Re-run the free / impl:code tests with trace: 'on', then check again."
|
|
65
|
+
: ' → Restore the approved checks in the .feature — or, if the change is intended, QA approves it on a terminal:');
|
|
66
|
+
}
|
|
67
|
+
if (v.verdict !== 'pass' && !v.uncommitted.length && !onlyUnproven) L(` sungen contract approve --screen ${v.unit}`);
|
|
68
|
+
L(` Report: ${path.relative(process.cwd(), reportFile)}`);
|
|
69
|
+
L('');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function unitOrThrow(name: string | undefined): { name: string; dir: string } {
|
|
73
|
+
if (!name) throw new Error('Provide --screen <name>');
|
|
74
|
+
return resolveContractUnit(process.cwd(), name);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function registerContractCommand(program: Command): void {
|
|
78
|
+
const contract = program
|
|
79
|
+
.command('contract')
|
|
80
|
+
.description('Test Contract (DOS-14): the Gherkin QA approved is the contract — lock it (TTY) and check the .feature was not weakened');
|
|
81
|
+
|
|
82
|
+
contract
|
|
83
|
+
.command('approve')
|
|
84
|
+
.description('Lock the current Gherkin as the approved contract — a human types a confirmation on a TTY')
|
|
85
|
+
.option('-s, --screen <name>', 'Screen / flow / api unit name')
|
|
86
|
+
.option('--scenario <id>', 'Approve one scenario only (its ID, e.g. VP-LOGIN-001)')
|
|
87
|
+
.option('--reason <text>', 'Why (recorded in the contract-approval decision)')
|
|
88
|
+
.action(async (options) => {
|
|
89
|
+
try {
|
|
90
|
+
const unit = unitOrThrow(options.screen);
|
|
91
|
+
const r = await approveContract({ projectRoot: process.cwd(), unit: unit.name, scenario: options.scenario, reason: options.reason, io: processIO() });
|
|
92
|
+
if (r.status === 'nothing-to-approve') { console.log(`\n= Nothing to approve: every chosen scenario of ${unit.name} already matches its approved lock entry.\n`); return; }
|
|
93
|
+
console.log(`\n✓ Approved ${r.approved.length} scenario(s)${r.removed.length ? `, removed ${r.removed.length}` : ''} → ${path.relative(process.cwd(), r.lockPath)} (decision ${r.decisionId})`);
|
|
94
|
+
console.log(' Commit the lock and the decision through review: until they are in git HEAD, `sungen contract check` reports contract.lock-uncommitted.\n');
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.error('Error:', error instanceof Error ? error.message : error);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
contract
|
|
102
|
+
.command('check')
|
|
103
|
+
.description('Compare the .feature with the approved lock on the strength ladder, and the lock with git HEAD')
|
|
104
|
+
.option('-s, --screen <name>', 'Screen / flow / api unit name')
|
|
105
|
+
.option('--trace', 'Resolve free / impl:code trace target identities with @sungen/driver-ui (a real browser) first')
|
|
106
|
+
.option('--json', 'Output the verdict as JSON')
|
|
107
|
+
.action(async (options) => {
|
|
108
|
+
let unit: { name: string; dir: string } | undefined;
|
|
109
|
+
try {
|
|
110
|
+
unit = unitOrThrow(options.screen);
|
|
111
|
+
const notes = options.trace ? await resolveUnitTraceIdentities(process.cwd(), unit) : [];
|
|
112
|
+
// The CLI may take its time; the guard (contractBlockers) keeps the ~3 s default.
|
|
113
|
+
const verdict = buildContractVerdict(process.cwd(), unit, { traceBudgetMs: CHECK_TRACE_BUDGET_MS });
|
|
114
|
+
verdict.warnings.push(...notes);
|
|
115
|
+
const hits = secretScanHits(JSON.stringify(verdict, null, 2), `${unit.name}-contract.json`);
|
|
116
|
+
if (hits.length) throw new Error(`Refused to write the contract report — likely secret(s): ${hits.map((h) => `${h.where} ${h.reason}`).join('; ')}`);
|
|
117
|
+
const file = writeContractReport(process.cwd(), verdict);
|
|
118
|
+
if (options.json) console.log(JSON.stringify(verdict, null, 2));
|
|
119
|
+
else printVerdict(verdict, file);
|
|
120
|
+
process.exit(verdict.exitCode);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
// Unreadable = not run (DOS-14.0): an earlier report must not outlive the inputs it judged.
|
|
123
|
+
if (unit) fs.rmSync(contractReportPath(process.cwd(), unit.name), { force: true });
|
|
124
|
+
console.error('Error:', error instanceof Error ? error.message : error);
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
registerDeriveCommand(contract);
|
|
130
|
+
}
|
|
@@ -41,6 +41,11 @@ import { MatrixFinding } from '../../exporters/matrix/types';
|
|
|
41
41
|
import { applyManualCarry, ManualCarryReport, PriorManualResults, readPriorManualResults } from '../../exporters/matrix/carry-manual-results';
|
|
42
42
|
import { formatTestOutcome, resultTotals } from '../../exporters/matrix/result-totals';
|
|
43
43
|
import { readCapabilities } from '../../harness/capability';
|
|
44
|
+
import { processIO } from '../../decisions/human-confirmation';
|
|
45
|
+
import { DeliveryDecisionGate } from '../../harness/gates/delivery-decision-gate';
|
|
46
|
+
import { runDeliveryDecisionStep } from '../../harness/gates/delivery-decision-step';
|
|
47
|
+
import { deliverableGateOverrides, InRunAcceptance } from '../../harness/gates/gate-override-report';
|
|
48
|
+
import { ChecklistUnit, renderChecklist, unitChecklist } from '../../harness/gates/delivery-checklist';
|
|
44
49
|
|
|
45
50
|
const COLOR = {
|
|
46
51
|
reset: '\x1b[0m',
|
|
@@ -660,7 +665,7 @@ export function matrixPathsFor(cwd: string, target: DeliveryTarget): MatrixTarge
|
|
|
660
665
|
}
|
|
661
666
|
|
|
662
667
|
function printFindings(findings: MatrixFinding[]): void {
|
|
663
|
-
const icon = { error: `${COLOR.red}✗`, review: `${COLOR.yellow}⚠`, warning: `${COLOR.gray}
|
|
668
|
+
const icon = { error: `${COLOR.red}✗`, review: `${COLOR.yellow}⚠`, warning: `${COLOR.gray}·`, info: `${COLOR.gray}i` } as const;
|
|
664
669
|
for (const f of findings) {
|
|
665
670
|
log(` ${icon[f.severity]} [Gate ${f.gate}]${COLOR.reset} ${f.ref ? `${f.ref}: ` : ''}${f.message}`);
|
|
666
671
|
}
|
|
@@ -685,9 +690,11 @@ async function exportMatrixTarget(
|
|
|
685
690
|
target: DeliveryTarget,
|
|
686
691
|
opts: { check?: boolean; preview?: boolean; format?: MatrixFormat },
|
|
687
692
|
env: EnvironmentInfo,
|
|
693
|
+
decisions?: DeliveryDecisionGate,
|
|
688
694
|
): Promise<MatrixRunSummary | 'skipped' | null> {
|
|
689
695
|
const paths = matrixPathsFor(cwd, target);
|
|
690
696
|
paths.runEnv = matrixRunEnv(cwd, target, env, paths);
|
|
697
|
+
paths.gateRules = decisions?.rulesFor(qaDir(cwd, target)); // the unit's gate-overrides apply to its matrix gates
|
|
691
698
|
|
|
692
699
|
// A feature whose scenarios are ALL @exploration probes has nothing to deliver —
|
|
693
700
|
// skip it quietly (no map required) instead of demanding a reviewed grouping for
|
|
@@ -728,6 +735,7 @@ async function exportMatrixTarget(
|
|
|
728
735
|
// A CSV-only export overwrites no workbook, so an unreadable one only means "nothing to carry".
|
|
729
736
|
catch (e) { if (format !== 'csv') priorError = e as Error; }
|
|
730
737
|
applyManualCarry(model, prior);
|
|
738
|
+
model.gateOverrides = deliverableGateOverrides(decisions?.overridesFor(qaDir(cwd, target)) ?? [], hasReview(model.findings), decisions?.acceptedInRun);
|
|
731
739
|
|
|
732
740
|
log(`${COLOR.bold}${paths.label}${COLOR.reset} — ${model.manifest.itemCount} delivery item(s), ${model.manifest.variantCount} coverage variant(s), review: ${model.manifest.approvalState} (design), test outcome: ${formatTestOutcome(resultTotals(model.items))}`);
|
|
733
741
|
{
|
|
@@ -892,6 +900,19 @@ function printSummaryTable(summaries: ScreenSummary[]): void {
|
|
|
892
900
|
}
|
|
893
901
|
}
|
|
894
902
|
|
|
903
|
+
/** T6: one checklist block per delivered unit, each box from what its command says now (delivery-checklist.ts). */
|
|
904
|
+
async function printDeliveryChecklist(cwd: string, targets: DeliveryTarget[], accepted?: InRunAcceptance): Promise<void> {
|
|
905
|
+
const units = new Map<string, ChecklistUnit>();
|
|
906
|
+
for (const t of targets) {
|
|
907
|
+
const dir = qaDir(cwd, t);
|
|
908
|
+
if (!units.has(dir)) units.set(dir, { label: t.isFlow ? `flow/${t.screen}` : t.screen, unitName: t.screen, unitDir: dir, kind: t.kind, resultsPath: resolveResultsPath(cwd, t) });
|
|
909
|
+
}
|
|
910
|
+
const rows: Array<{ label: string; boxes: Awaited<ReturnType<typeof unitChecklist>> }> = [];
|
|
911
|
+
for (const u of units.values()) rows.push({ label: u.label, boxes: await unitChecklist(cwd, u, accepted) });
|
|
912
|
+
log('');
|
|
913
|
+
for (const line of renderChecklist(rows)) log(line);
|
|
914
|
+
}
|
|
915
|
+
|
|
895
916
|
// ----------------------------------------------------------------------------
|
|
896
917
|
// Command registration
|
|
897
918
|
// ----------------------------------------------------------------------------
|
|
@@ -910,10 +931,11 @@ export function registerDeliveryCommand(program: Command): void {
|
|
|
910
931
|
.option('--approve [ids]', 'Approve proposed groups (all, or a comma-separated id list) + stamp fingerprints')
|
|
911
932
|
.option('--preview', 'Render the matrix despite review-required findings (DRAFT watermark)')
|
|
912
933
|
.option('--format <format>', 'Matrix output format: xlsx (default) | csv | both', 'xlsx')
|
|
934
|
+
.option('--accept-in-run', 'Deliver despite gate-overrides/waivers/approvals recorded during the run (decision.in-run) — a human confirms on a terminal')
|
|
913
935
|
.action(async (names: string[], options: {
|
|
914
936
|
skipPreflight?: boolean; continueOnMissing?: boolean; env?: string;
|
|
915
937
|
legacy?: boolean; full?: boolean; check?: boolean; approve?: boolean | string; preview?: boolean;
|
|
916
|
-
format?: string;
|
|
938
|
+
format?: string; acceptInRun?: boolean;
|
|
917
939
|
}) => {
|
|
918
940
|
try {
|
|
919
941
|
// Same effect as running with SUNGEN_ENV=<env> — result-file resolution,
|
|
@@ -990,6 +1012,30 @@ export function registerDeliveryCommand(program: Command): void {
|
|
|
990
1012
|
.reduce<SecretScanResult>((a, r) => ({ hits: [...a.hits, ...r.hits], unscanned: [...a.unscanned, ...r.unscanned] }), { hits: [], unscanned: [] });
|
|
991
1013
|
for (const line of formatSecretScan(secretScan)) log(line);
|
|
992
1014
|
|
|
1015
|
+
// OES-11.3–11.5: decisions that do not verify, rejected overrides, a stale audit and in-run
|
|
1016
|
+
// decisions stop the delivery before anything is written (approval only stamps the map).
|
|
1017
|
+
let decisions: DeliveryDecisionGate | undefined;
|
|
1018
|
+
// --approve only stamps a matrix map. With --legacy / --full it would skip this gate and
|
|
1019
|
+
// fall through to the export, so the combination is refused before anything is written.
|
|
1020
|
+
if (options.approve !== undefined && (options.legacy || options.full)) {
|
|
1021
|
+
console.error(`${COLOR.red}--approve applies to the matrix deliverable only${COLOR.reset} — it cannot be combined with --legacy / --full`);
|
|
1022
|
+
process.exit(1);
|
|
1023
|
+
}
|
|
1024
|
+
if (options.approve === undefined) {
|
|
1025
|
+
const gate = await runDeliveryDecisionStep({
|
|
1026
|
+
projectRoot: cwd, acceptInRun: !!options.acceptInRun, io: processIO(), log,
|
|
1027
|
+
// --preview / --check soften only the matrix export; --legacy has no draft mode, so it always needs one.
|
|
1028
|
+
requireTrustedAudit: !!(options.legacy || options.full) || (!options.preview && !options.check),
|
|
1029
|
+
refs: toExport.map((t) => ({ label: t.isFlow ? `flow/${t.featureBaseName}` : t.featureBaseName, unitName: t.screen, unitDir: qaDir(cwd, t), resultsPath: resolveResultsPath(cwd, t) })),
|
|
1030
|
+
argv: ['sungen', 'delivery', ...(names ?? []), ...(options.env ? ['--env', options.env] : []), ...(options.legacy || options.full ? ['--legacy'] : [])],
|
|
1031
|
+
});
|
|
1032
|
+
if (!gate) {
|
|
1033
|
+
await printDeliveryChecklist(cwd, toExport);
|
|
1034
|
+
process.exit(1);
|
|
1035
|
+
}
|
|
1036
|
+
decisions = gate;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
993
1039
|
// 3. Export
|
|
994
1040
|
const legacy = options.legacy || options.full;
|
|
995
1041
|
if (!legacy) {
|
|
@@ -1035,13 +1081,15 @@ export function registerDeliveryCommand(program: Command): void {
|
|
|
1035
1081
|
for (const target of toExport) {
|
|
1036
1082
|
const s = await exportMatrixTarget(cwd, target, {
|
|
1037
1083
|
check: options.check, preview: options.preview, format: format as MatrixFormat,
|
|
1038
|
-
}, env);
|
|
1084
|
+
}, env, decisions);
|
|
1039
1085
|
if (s === 'skipped') continue; // all-@exploration feature — neither exported nor a failure
|
|
1040
1086
|
if (s) matrixSummaries.push(s);
|
|
1041
1087
|
else notExported.push(target.isFlow ? `flow/${target.featureBaseName}` : target.featureBaseName);
|
|
1042
1088
|
}
|
|
1043
1089
|
if (matrixSummaries.length > 0 && !options.check) printMatrixSummaryTable(matrixSummaries);
|
|
1090
|
+
for (const line of decisions?.summaryLines() ?? []) log(line);
|
|
1044
1091
|
printSkipSummary(skipped, notExported);
|
|
1092
|
+
await printDeliveryChecklist(cwd, toExport, decisions?.acceptedInRun);
|
|
1045
1093
|
// A named target that produced nothing is a failure. A sweep is a failure
|
|
1046
1094
|
// only when it produced nothing at all — units still waiting for a map or
|
|
1047
1095
|
// an approval are the normal state of a live project. Preflight skips are
|
|
@@ -1064,6 +1112,7 @@ export function registerDeliveryCommand(program: Command): void {
|
|
|
1064
1112
|
// 4. Summary
|
|
1065
1113
|
printSummaryTable(summaries);
|
|
1066
1114
|
printSkipSummary(skipped, []);
|
|
1115
|
+
await printDeliveryChecklist(cwd, toExport, decisions?.acceptedInRun);
|
|
1067
1116
|
// Same rule as the matrix path: every attempted target in an explicit scope
|
|
1068
1117
|
// must have produced a file; a sweep only fails when nothing was written.
|
|
1069
1118
|
if (explicitScope ? summaries.length < toExport.length : summaries.length === 0) process.exit(1);
|
|
@@ -7,6 +7,7 @@ import { scanTestDataSecrets, formatSecretScan, type SecretScanResult } from '..
|
|
|
7
7
|
import { capabilityRegistry } from '../../capabilities/registry';
|
|
8
8
|
import { discoverAndRegisterCapabilities } from '../../capabilities/discover';
|
|
9
9
|
import { readCapabilities, writeCapabilities, driverMeta, loadDriverCatalog } from '../../harness/capability';
|
|
10
|
+
import { isHandWritten } from '../../harness/parse';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Find .feature files recursively in a directory
|
|
@@ -20,7 +21,8 @@ function findFeatureFiles(dir: string): string[] {
|
|
|
20
21
|
const fullPath = path.join(dir, entry.name);
|
|
21
22
|
if (entry.isDirectory()) {
|
|
22
23
|
files.push(...findFeatureFiles(fullPath));
|
|
23
|
-
} else if (entry.isFile() && entry.name.endsWith('.feature')) {
|
|
24
|
+
} else if (entry.isFile() && entry.name.endsWith('.feature') && !isHandWritten([], fullPath)) {
|
|
25
|
+
// A derived `*.free.feature` is a contract for hand-written tests — never compiled (DOS-14.8).
|
|
24
26
|
files.push(fullPath);
|
|
25
27
|
}
|
|
26
28
|
}
|