@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,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit findings pinned to the test case they name, in the shared trace vocabulary (DOS-12.1, takumi
|
|
3
|
+
* T7): a citation `repo@SHA:path#Lx-Ly` plus a confidence label.
|
|
4
|
+
*
|
|
5
|
+
* EXTRACTED 0.95 the finding names the case's VP-id, and only that case carries it
|
|
6
|
+
* EXTRACTED 0.90 the finding quotes the case's full title, and only that case has it
|
|
7
|
+
* INFERRED 0.60 the finding names the id's family (`VP-LOGIC` for `VP-LOGIC-003`), shared by ≤ 3 cases
|
|
8
|
+
* AMBIGUOUS 0.40 the id or title it names is carried by several cases — each is cited
|
|
9
|
+
* A finding that names no case is located nowhere (it stays a unit-level finding).
|
|
10
|
+
*
|
|
11
|
+
* SHA is the HEAD commit when the file's bytes equal its HEAD blob; otherwise (no git, uncommitted
|
|
12
|
+
* edit) it is `worktree`, so a citation never points a commit at lines it does not hold. git runs
|
|
13
|
+
* twice per unit at most, with fixed arguments and a short timeout; a git failure only means `worktree`.
|
|
14
|
+
*/
|
|
15
|
+
import { execFileSync } from 'child_process';
|
|
16
|
+
import * as fs from 'fs';
|
|
17
|
+
import * as path from 'path';
|
|
18
|
+
import { gitBlobId, GUARD_GIT_TIMEOUT_MS } from '../contract/contract-git';
|
|
19
|
+
import { idPrefix } from '../harness/parse';
|
|
20
|
+
import type { ConfidenceLabel, LocatedFinding } from './test-case-state-shape';
|
|
21
|
+
|
|
22
|
+
export interface CitableCase { id: string; unstableId?: true; title: string; absFile: string; lines: [number, number] }
|
|
23
|
+
export interface GitCitationContext { repo: string; repoRoot: string; sha: string | null; headBlobs: Map<string, string> }
|
|
24
|
+
|
|
25
|
+
/** git reports real paths (macOS `/var` is `/private/var`), so paths are compared real. */
|
|
26
|
+
const real = (p: string): string => { try { return fs.realpathSync(p); } catch { return path.resolve(p); } };
|
|
27
|
+
|
|
28
|
+
function git(cwd: string, args: string[]): string | null {
|
|
29
|
+
try {
|
|
30
|
+
return execFileSync('git', args, { cwd, stdio: ['ignore', 'pipe', 'ignore'], timeout: GUARD_GIT_TIMEOUT_MS }).toString('utf8');
|
|
31
|
+
} catch { return null; }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** HEAD sha, repository root and HEAD blob ids of `files` — or a no-git context. */
|
|
35
|
+
export function gitCitationContext(projectRoot: string, files: string[]): GitCitationContext {
|
|
36
|
+
const top = git(projectRoot, ['rev-parse', '--show-toplevel', 'HEAD'])?.trim().split('\n');
|
|
37
|
+
if (!top || top.length < 2 || !/^[0-9a-f]{40,64}$/.test(top[1])) {
|
|
38
|
+
return { repo: path.basename(projectRoot), repoRoot: real(projectRoot), sha: null, headBlobs: new Map() };
|
|
39
|
+
}
|
|
40
|
+
const repoRoot = real(top[0]);
|
|
41
|
+
const root = real(projectRoot);
|
|
42
|
+
const rels = files.map((f) => path.relative(root, real(f)));
|
|
43
|
+
const headBlobs = new Map<string, string>();
|
|
44
|
+
for (const line of (git(projectRoot, ['ls-tree', 'HEAD', '--', ...rels]) ?? '').split('\n')) {
|
|
45
|
+
const m = line.match(/^\d+ blob ([0-9a-f]+)\t(.+)$/);
|
|
46
|
+
if (m) headBlobs.set(path.resolve(root, m[2]), m[1]);
|
|
47
|
+
}
|
|
48
|
+
return { repo: path.basename(repoRoot), repoRoot, sha: top[1].slice(0, 12), headBlobs };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function citationOf(ctx: GitCitationContext, absFile: string, lines: [number, number]): string {
|
|
52
|
+
const file = real(absFile);
|
|
53
|
+
let sha = 'worktree';
|
|
54
|
+
try {
|
|
55
|
+
if (ctx.sha && ctx.headBlobs.get(file) === gitBlobId(fs.readFileSync(file, 'utf8'))) sha = ctx.sha;
|
|
56
|
+
} catch { /* unreadable now — cite the working tree */ }
|
|
57
|
+
const rel = path.relative(ctx.repoRoot, file).split(path.sep).join('/');
|
|
58
|
+
return `${ctx.repo}@${sha}:${rel}#L${lines[0]}-L${lines[1]}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const escapeRe = (s: string): string => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
62
|
+
/** `id` as a whole token — `VP-UI-001` in "VP-UI-001 does not…", never inside `VP-UI-0012`. */
|
|
63
|
+
const namesId = (text: string, id: string): boolean => new RegExp(`(?<![A-Za-z0-9-])${escapeRe(id)}(?![A-Za-z0-9-])`).test(text);
|
|
64
|
+
/** A family token standing alone — `VP-LOGIC` but not the start of another case's `VP-LOGIC-004`. */
|
|
65
|
+
const namesFamily = (text: string, family: string): boolean => new RegExp(`(?<![A-Za-z0-9-])${escapeRe(family)}(?![A-Za-z0-9])(?!-[A-Za-z0-9])`).test(text);
|
|
66
|
+
|
|
67
|
+
/** Which cases a finding names, and how surely. */
|
|
68
|
+
function matchesOf(finding: string, cases: CitableCase[]): { hits: CitableCase[]; label: ConfidenceLabel; score: number } | null {
|
|
69
|
+
const byId = cases.filter((c) => !c.unstableId && namesId(finding, c.id));
|
|
70
|
+
if (byId.length) return byId.length === 1 ? { hits: byId, label: 'EXTRACTED', score: 0.95 } : { hits: byId, label: 'AMBIGUOUS', score: 0.4 };
|
|
71
|
+
const byTitle = cases.filter((c) => c.title.length >= 8 && finding.includes(c.title));
|
|
72
|
+
if (byTitle.length) return byTitle.length === 1 ? { hits: byTitle, label: 'EXTRACTED', score: 0.9 } : { hits: byTitle, label: 'AMBIGUOUS', score: 0.4 };
|
|
73
|
+
const byFamily = cases.filter((c) => !c.unstableId && idPrefix(c.id) !== c.id && namesFamily(finding, idPrefix(c.id)));
|
|
74
|
+
if (byFamily.length && byFamily.length <= 3) return { hits: byFamily, label: 'INFERRED', score: 0.6 };
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Every finding that names a case, keyed by the case's index in `cases`. */
|
|
79
|
+
export function locateFindings(findings: string[], cases: CitableCase[], ctx: GitCitationContext): Map<number, LocatedFinding[]> {
|
|
80
|
+
const out = new Map<number, LocatedFinding[]>();
|
|
81
|
+
for (const text of findings) {
|
|
82
|
+
if (typeof text !== 'string' || !text.trim()) continue;
|
|
83
|
+
const m = matchesOf(text, cases);
|
|
84
|
+
if (!m) continue;
|
|
85
|
+
const head = text.split(':')[0].trim();
|
|
86
|
+
const code = /^[A-Z][A-Z0-9-]+$/.test(head) ? head : 'FINDING';
|
|
87
|
+
for (const c of m.hits) {
|
|
88
|
+
const i = cases.indexOf(c);
|
|
89
|
+
out.set(i, [...(out.get(i) ?? []), { code, text, citation: citationOf(ctx, c.absFile, c.lines), confidence: { label: m.label, score: m.score } }]);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return out;
|
|
93
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One node of the `sungen next` graph (OES-10.1) — core-internal, no SPI (red-team #10).
|
|
3
|
+
*
|
|
4
|
+
* `deriveSteps` used to be a chain of if/return in which every `return` was a blocking node that cut
|
|
5
|
+
* everything after it. Each branch is now one declaration: when it applies (`active`), when its goal
|
|
6
|
+
* is met (`satisfied`), the step it offers, and whether an open instance cuts the nodes ranked after
|
|
7
|
+
* it (`blocking`). `evaluateGraph` walks them by `rank`.
|
|
8
|
+
*
|
|
9
|
+
* Granularity: a `unit` node judges the unit's state; a `test-case` node judges one test case at a
|
|
10
|
+
* time, and the cases that need it fold into ONE step at unit level (one step per case under
|
|
11
|
+
* `sungen next <unit> --case <id>`).
|
|
12
|
+
*/
|
|
13
|
+
import type { NextStep, UnitState } from '../harness/next-step';
|
|
14
|
+
import type { TestCaseState } from './test-case-state-shape';
|
|
15
|
+
|
|
16
|
+
export type NodeActor = 'ai' | 'human' | 'deterministic';
|
|
17
|
+
export type NodeGranularity = 'unit' | 'test-case';
|
|
18
|
+
export type UnitKind = UnitState['kind'];
|
|
19
|
+
|
|
20
|
+
/** What a node's `step` returns; the engine adds `nodeId`, `granularity`, `gates`, `testCase`. */
|
|
21
|
+
export type StepCore = Pick<NextStep, 'kind' | 'command' | 'because'>;
|
|
22
|
+
|
|
23
|
+
interface NodeDeclBase {
|
|
24
|
+
id: string;
|
|
25
|
+
title: string;
|
|
26
|
+
/** Who runs the step: an AI agent, a human (`decide`, never auto-run), or sungen itself. */
|
|
27
|
+
actor: NodeActor;
|
|
28
|
+
appliesTo: readonly UnitKind[];
|
|
29
|
+
/** Nodes that must be satisfied first. Each is a lower-ranked blocking node (pinned by a test). */
|
|
30
|
+
requires: readonly string[];
|
|
31
|
+
/** An active, unsatisfied blocking node cuts every node ranked after it. */
|
|
32
|
+
blocking: boolean;
|
|
33
|
+
rank: number;
|
|
34
|
+
/** Catalog rule ids (gate-rules.yaml) this step answers to. */
|
|
35
|
+
gates: readonly string[];
|
|
36
|
+
/** Artifacts the step produces, for a reader of the graph. */
|
|
37
|
+
produces: readonly string[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface UnitNodeDecl extends NodeDeclBase {
|
|
41
|
+
granularity: 'unit';
|
|
42
|
+
active(s: UnitState): boolean;
|
|
43
|
+
satisfied(s: UnitState): boolean;
|
|
44
|
+
step(s: UnitState): StepCore;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface TestCaseNodeDecl extends NodeDeclBase {
|
|
48
|
+
granularity: 'test-case';
|
|
49
|
+
/**
|
|
50
|
+
* Speaks only under `--case <id>`: the unit view already carries the decision at unit level (the
|
|
51
|
+
* contract's unit.contract-approve), so folding the cases there would say it twice.
|
|
52
|
+
*/
|
|
53
|
+
caseOnly?: true;
|
|
54
|
+
active(s: UnitState, tc: TestCaseState): boolean;
|
|
55
|
+
satisfied(s: UnitState, tc: TestCaseState): boolean;
|
|
56
|
+
/** One step for `cases` (all open at this node): a unit-level fold, or exactly one case when `single`. */
|
|
57
|
+
step(s: UnitState, cases: TestCaseState[], single: boolean): StepCore;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type NodeDecl = UnitNodeDecl | TestCaseNodeDecl;
|
|
61
|
+
|
|
62
|
+
/** `qa/<dir>/<unit>` for the unit kind, as the steps name it. */
|
|
63
|
+
export const unitKindDir = (kind: UnitKind): string => (kind === 'screen' ? 'screens' : kind === 'flow' ? 'flows' : 'api');
|
|
64
|
+
|
|
65
|
+
export const ALL_KINDS: readonly UnitKind[] = ['screen', 'flow', 'api'];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The core node catalog of `sungen next` (OES-10.1), in rank order. Internal to core: there is no
|
|
3
|
+
* SPI slot for driver-contributed nodes in P0 (red-team #10).
|
|
4
|
+
*/
|
|
5
|
+
import type { NodeDecl } from '../node-decl';
|
|
6
|
+
import { TEST_CASE_CONTRACT_NODES } from './test-case-contract-nodes';
|
|
7
|
+
import { TEST_CASE_NODES } from './test-case-nodes';
|
|
8
|
+
import { UNIT_AUDIT_NODES } from './unit-audit-nodes';
|
|
9
|
+
import { UNIT_CONTRACT_NODES } from './unit-contract-node';
|
|
10
|
+
import { UNIT_DESIGN_NODES } from './unit-design-nodes';
|
|
11
|
+
import { UNIT_EXECUTION_NODES } from './unit-execution-nodes';
|
|
12
|
+
|
|
13
|
+
export const CORE_NODES: readonly NodeDecl[] = [
|
|
14
|
+
...UNIT_DESIGN_NODES, ...UNIT_AUDIT_NODES, ...UNIT_CONTRACT_NODES, ...UNIT_EXECUTION_NODES, ...TEST_CASE_NODES, ...TEST_CASE_CONTRACT_NODES,
|
|
15
|
+
].sort((a, b) => a.rank - b.rank);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Test Contract per test case (P0 phase 09, DOS-14.4–14.6) — read off each case's class in the
|
|
3
|
+
* verdict `sungen contract check` and the delivery guard rebuild (TestCaseState.contract), so the
|
|
4
|
+
* three never disagree. The unit view keeps phase 05's QA decisions (unit.contract-approve,
|
|
5
|
+
* unit.contract-proposed); these add what only a case can say:
|
|
6
|
+
*
|
|
7
|
+
* tc.contract-approve --case only approved, changed, not weaker decide approve --scenario <id>
|
|
8
|
+
* tc.contract-check --case only weaker / other target / lost check,
|
|
9
|
+
* or its lock entry is uncommitted blocked contract check
|
|
10
|
+
* tc.unproven approved free / impl:code, no admissible trace do run-test --ids (traced)
|
|
11
|
+
* tc.conformance its trace is in review: a `low` target identity do contract check --trace
|
|
12
|
+
* · its final attempt did not pass (inconclusive) do run-test --ids
|
|
13
|
+
* · a step no code can compare (opaque) decide contract check
|
|
14
|
+
* Exempt cases (DOS-11.2) open nothing. A proposed case (never approved) asks nothing of its own: a
|
|
15
|
+
* compiled test without a lock is never blocked, and the unit view offers the approval.
|
|
16
|
+
*/
|
|
17
|
+
import { ALL_KINDS, StepCore, TestCaseNodeDecl } from '../node-decl';
|
|
18
|
+
import type { UnitState } from '../../harness/next-step';
|
|
19
|
+
import type { TestCaseState } from '../test-case-state-shape';
|
|
20
|
+
import { exemptionOf } from '../test-case-satisfied';
|
|
21
|
+
import { idsArg, listed } from './test-case-nodes';
|
|
22
|
+
|
|
23
|
+
type Step = (s: UnitState, cases: TestCaseState[], single: boolean) => StepCore;
|
|
24
|
+
const HARD_LADDER = new Set(['oracle-weakened', 'target-changed', 'assertion-lost']);
|
|
25
|
+
const classOf = (tc: TestCaseState): string | undefined => tc.contract?.class;
|
|
26
|
+
/** Up to three cases with the finding behind each. */
|
|
27
|
+
const withDetail = (cases: TestCaseState[]): string =>
|
|
28
|
+
`${cases.slice(0, 3).map((c) => (c.contract?.detail ? `${c.id}: ${c.contract.detail}` : c.id)).join('; ')}${cases.length > 3 ? '; …' : ''}`;
|
|
29
|
+
const check = (s: UnitState, trace = false): string => `sungen contract check --screen ${s.unit}${trace ? ' --trace' : ''}`;
|
|
30
|
+
|
|
31
|
+
function contractNode(id: string, rank: number, title: string, actor: TestCaseNodeDecl['actor'], gates: string[], caseOnly: boolean,
|
|
32
|
+
active: (tc: TestCaseState) => boolean, step: Step): TestCaseNodeDecl {
|
|
33
|
+
return {
|
|
34
|
+
id, title, actor, granularity: 'test-case', appliesTo: ALL_KINDS, blocking: false, rank, gates, step,
|
|
35
|
+
requires: caseOnly ? ['unit.gate-fail'] : ['unit.run'], produces: ['contracts.lock.yaml', 'decisions/<id>.yaml'],
|
|
36
|
+
...(caseOnly ? { caseOnly: true as const } : {}),
|
|
37
|
+
active: (_s, tc) => active(tc),
|
|
38
|
+
satisfied: (_s, tc) => exemptionOf(tc) !== null,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const conformanceStep: Step = (s, cases) => {
|
|
43
|
+
const low = cases.filter((c) => c.contract?.lowIdentity);
|
|
44
|
+
if (low.length) {
|
|
45
|
+
return { kind: 'do', command: check(s, true), because: `${low.length} free / impl:code test case(s) act on a target whose identity is only \`low\` (${listed(low)}) — resolve them in a real browser (needs @sungen/driver-ui). A low identity is never a match, so the contract stays in review and \`sungen delivery\` waits` };
|
|
46
|
+
}
|
|
47
|
+
const failed = cases.filter((c) => classOf(c) === 'inconclusive');
|
|
48
|
+
if (failed.length) {
|
|
49
|
+
return { kind: 'do', command: `/sungen:run-test ${s.unit}${idsArg(failed)}`, because: `${failed.length} approved free / impl:code test case(s) have no passing final attempt (${listed(failed)}) — the trace of a failed run proves nothing (contract.inconclusive): fix and triage the red, get a passing run, then \`${check(s, true)}\`` };
|
|
50
|
+
}
|
|
51
|
+
return { kind: 'decide', command: check(s), because: `${cases.length} free / impl:code test case(s) carry a step sungen cannot compare (${withDetail(cases)}) — a QA reviews it in \`sungen contract check\`; until then the contract is in review and \`sungen delivery\` waits. An agent presents this and never approves it` };
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const TEST_CASE_CONTRACT_NODES: readonly TestCaseNodeDecl[] = [
|
|
55
|
+
contractNode('tc.contract-approve', 106, 'Re-approve this changed case', 'human', ['contract.hash-changed'], true,
|
|
56
|
+
(tc) => classOf(tc) === 'hash-changed' && !tc.contract?.uncommitted,
|
|
57
|
+
(s, [c]) => ({ kind: 'decide', command: `sungen contract approve --screen ${s.unit} --scenario ${c.id}`, because: `this case changed since QA approved it, not weaker${c.contract?.detail ? ` (${c.contract.detail})` : ''} — a QA re-approves this scenario on a terminal; until then review blocks \`sungen delivery\`. An agent presents it and never approves its own edit` })),
|
|
58
|
+
contractNode('tc.contract-check', 107, 'Restore the approved check of this case', 'human',
|
|
59
|
+
['contract.oracle-weakened', 'contract.target-changed', 'contract.assertion-lost', 'contract.lock-uncommitted'], true,
|
|
60
|
+
(tc) => Boolean(tc.contract?.uncommitted) || HARD_LADDER.has(classOf(tc) ?? ''),
|
|
61
|
+
(s, [c]) => ({ kind: 'blocked', command: check(s), because: c.contract?.uncommitted
|
|
62
|
+
? `its lock entry is not what QA approved and committed (contract.lock-uncommitted) — \`sungen next ${s.unit}\` names the repair; \`sungen delivery\` is blocked until then`
|
|
63
|
+
: `this case breaks its approved contract (${c.contract?.class}${c.contract?.detail ? `: ${c.contract.detail}` : ''}) — restore the approved check (in the .feature, or in the hand-written test of a free / impl:code case), or a QA approves the change on a terminal (\`sungen contract approve --screen ${s.unit} --scenario ${c.id}\`). \`sungen delivery\` is blocked until then; never weaken an expected value to go green` })),
|
|
64
|
+
contractNode('tc.unproven', 136, 'Prove the approved free cases with a trace', 'ai', ['contract.unproven'], false,
|
|
65
|
+
(tc) => classOf(tc) === 'unproven',
|
|
66
|
+
(s, cases) => ({ kind: 'do', command: `/sungen:run-test ${s.unit}${idsArg(cases)}`, because: `${cases.length} approved free / impl:code test case(s) have no trace that proves them (${withDetail(cases)}) — run them again with trace: 'on' and the sungen run-record reporter (run-test Phase 4 does), then \`${check(s, true)}\`. Until then \`sungen contract check\` fails (contract.unproven) and \`sungen delivery\` is blocked; re-approving or editing the .feature cannot prove them` })),
|
|
67
|
+
contractNode('tc.conformance', 138, 'Settle the traces in review', 'ai', ['contract.opaque-step', 'contract.inconclusive'], false,
|
|
68
|
+
(tc) => classOf(tc) === 'opaque' || classOf(tc) === 'inconclusive', conformanceStep),
|
|
69
|
+
];
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-case nodes (OES-10.3) — added after parity, as an intentional output change. Each judges one
|
|
3
|
+
* case at a time; the cases open at a node fold into ONE step at unit level ("N test case(s) …"),
|
|
4
|
+
* and `sungen next <unit> --case <id>` shows the one case's step. Satisfied semantics: DOS-11.2
|
|
5
|
+
* (test-case-satisfied.ts) — exempt cases never open a node.
|
|
6
|
+
*
|
|
7
|
+
* tc.run never run (a case added after the run) do run-test --ids
|
|
8
|
+
* tc.rerun-stale changed after the recorded run (run manifest) do run-test --change-only
|
|
9
|
+
* tc.triage red, not classified by a current triage do sungen triage
|
|
10
|
+
* tc.product-candidate triage found a product-defect candidate decide sungen defect draft
|
|
11
|
+
* They sit after unit.run (which cuts a unit that never ran) and before delivery. tc.triage takes
|
|
12
|
+
* the reds the cases account for; unit.triage keeps the rest (unattributedReds), so a red no case
|
|
13
|
+
* explains — an @cases row, a renamed scenario, a nested describe title — still gets a triage step.
|
|
14
|
+
*/
|
|
15
|
+
import { ALL_KINDS, StepCore, TestCaseNodeDecl } from '../node-decl';
|
|
16
|
+
import type { UnitState } from '../../harness/next-step';
|
|
17
|
+
import type { TestCaseState } from '../test-case-state-shape';
|
|
18
|
+
import { exemptionOf, TestCaseNeed, triggerOf } from '../test-case-satisfied';
|
|
19
|
+
|
|
20
|
+
const MAX_IDS = 10;
|
|
21
|
+
export const listed = (cases: TestCaseState[]): string => `${cases.slice(0, 4).map((c) => c.id).join(', ')}${cases.length > 4 ? ', …' : ''}`;
|
|
22
|
+
/** `--ids` only names cases `sungen select` can resolve: stable ids, a short list. */
|
|
23
|
+
export const idsArg = (cases: TestCaseState[]): string =>
|
|
24
|
+
(cases.length <= MAX_IDS && cases.every((c) => !c.unstableId) ? ` --ids ${cases.map((c) => c.id).join(',')}` : '');
|
|
25
|
+
const flag = (s: UnitState): string => (s.kind === 'api' ? '--api' : '--screen');
|
|
26
|
+
|
|
27
|
+
function caseNode(id: string, need: TestCaseNeed, rank: number, title: string, actor: TestCaseNodeDecl['actor'],
|
|
28
|
+
step: (s: UnitState, cases: TestCaseState[], single: boolean) => StepCore, produces: string[]): TestCaseNodeDecl {
|
|
29
|
+
return {
|
|
30
|
+
id, title, actor, granularity: 'test-case', appliesTo: ALL_KINDS, requires: ['unit.run'], blocking: false, rank,
|
|
31
|
+
gates: [], produces, step,
|
|
32
|
+
active: (_s, tc) => triggerOf(tc) === need,
|
|
33
|
+
satisfied: (_s, tc) => exemptionOf(tc) !== null,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const TEST_CASE_NODES: readonly TestCaseNodeDecl[] = [
|
|
38
|
+
caseNode('tc.run', 'run', 131, 'Run the cases that never ran', 'ai', (s, cases) => ({
|
|
39
|
+
kind: 'do',
|
|
40
|
+
command: `/sungen:run-test ${s.unit}${idsArg(cases)}`,
|
|
41
|
+
because: `${cases.length} test case(s) have never run (${listed(cases)}) — their rows read Pending in the deliverable`,
|
|
42
|
+
}), ['specs/generated/<unit>/<unit>-test-result.json']),
|
|
43
|
+
caseNode('tc.rerun-stale', 'rerun-stale', 132, 'Re-run the cases that changed after their run', 'ai', (s, cases, single) => ({
|
|
44
|
+
kind: 'do',
|
|
45
|
+
command: single && idsArg(cases) ? `/sungen:run-test ${s.unit}${idsArg(cases)}` : `/sungen:run-test ${s.unit} --change-only`,
|
|
46
|
+
because: `${cases.length} test case(s) changed after the run that produced their result (${cases.slice(0, 3).map((c) => `${c.id}: ${c.stale}`).join('; ')}${cases.length > 3 ? '; …' : ''}) — that result no longer describes the scenario`,
|
|
47
|
+
}), ['specs/generated/<unit>/<unit>-test-result.json', '.sungen/run-manifest/<unit>.json']),
|
|
48
|
+
caseNode('tc.triage', 'triage', 133, 'Classify the red cases', 'deterministic', (s, cases) => {
|
|
49
|
+
const left = cases.filter((c) => c.triage?.class === 'unclassified').length;
|
|
50
|
+
return {
|
|
51
|
+
kind: 'do',
|
|
52
|
+
command: `sungen triage ${flag(s)} ${s.unit}`,
|
|
53
|
+
because: `${cases.length} test case(s) failed in the latest run and are not classified yet${left ? ` (${left} left unclassified by the last triage — read its evidence and classify by hand)` : ''} — classify each (known defect, test defect, environment, product candidate) before exporting or extending: an unexplained red in the deliverable is a finding nobody has judged`,
|
|
54
|
+
};
|
|
55
|
+
}, ['.sungen/triage/<unit>.json']),
|
|
56
|
+
caseNode('tc.product-candidate', 'product-candidate', 134, 'Decide on the product-defect candidates', 'human', (s, cases, single) => ({
|
|
57
|
+
kind: 'decide',
|
|
58
|
+
command: `sungen defect draft ${flag(s)} ${s.unit}${single ? ` --scenario ${cases[0].id}` : ''}`,
|
|
59
|
+
because: `${cases.length} red test case(s) look like a product defect (${listed(cases)}) — the app answered and the answer differs from the oracle. A QA decides whether it is a defect to record; an agent presents it and does not draft it on its own`,
|
|
60
|
+
}), ['qa/defects/DEF-<n>-<slug>.md']),
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
/** Red final attempts the test cases account for (a case read without the count stands for one). */
|
|
64
|
+
export const attributedReds = (s: UnitState): number =>
|
|
65
|
+
(s.testCases ?? []).reduce((n, tc) => n + (tc.failedResults ?? (tc.result === 'failed' ? 1 : 0)), 0);
|
|
66
|
+
|
|
67
|
+
/** The reds unit.triage still owns: all of them without test-case states, else those no case accounts for. */
|
|
68
|
+
export const unattributedReds = (s: UnitState): number => (s.failedCount ?? 0) - (s.testCases ? attributedReds(s) : 0);
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit-stage unit nodes — rows 7–10 of the OES-10.2 parity table (exact words of the frozen oracle).
|
|
3
|
+
*
|
|
4
|
+
* 7 unit.audit-missing never audited → `sungen audit`, cuts
|
|
5
|
+
* 7 unit.audit-stale a report that does not count (stale, untrusted) → re-audit, cuts (OES-10.3,
|
|
6
|
+
* phase 05: the report is read through verifyAuditReport, as gate and delivery do)
|
|
7
|
+
* 8 unit.baseline-changed viewpoint baseline moved → `--accept-viewpoint`, a QA DECISION (#660)
|
|
8
|
+
* 9 unit.repair-findings findings with a known repair → repair + re-audit, names ≤ 4 codes
|
|
9
|
+
* 10 unit.gate-fail gateStatus FAIL → blocked, cuts
|
|
10
|
+
*/
|
|
11
|
+
import { ALL_KINDS, UnitNodeDecl } from '../node-decl';
|
|
12
|
+
import type { UnitState } from '../../harness/next-step';
|
|
13
|
+
|
|
14
|
+
/** The finding codes worth naming in a next step — each maps to a specific repair. */
|
|
15
|
+
export const REPAIRABLE: readonly string[] = [
|
|
16
|
+
'FLOW-CONTRACT-MISSING', 'FLOW-INVENTORY-MISSING', 'FLOW-UNCOVERED', 'FLOW-UNDECLARED',
|
|
17
|
+
'FLOW-PHASE-MISFILED', 'FLOW-GUARANTEE-MISSING', 'FLOW-OUTCOME-UNPROVEN', 'CONTINUITY-ONE-SIDED',
|
|
18
|
+
'ORACLE-URL-ONLY',
|
|
19
|
+
'SPEC-RESTATED-UNVERIFIED', 'VIEWPOINT-GESTURE-SUBSTITUTED', 'SPEC-UNCOVERED', 'SPEC-CLAUSE-UNCOVERED',
|
|
20
|
+
'TRIGGER-UNCOVERED', 'PERMISSION-PAIR-MISSING', 'VISIBILITY-PAIR-MISSING',
|
|
21
|
+
'VIEWPOINT-ITEM-MISSING', 'MANUAL-CODE-MISSING', 'MANUAL-AUTOMATABLE', 'DEPTH-DEFERRED',
|
|
22
|
+
'UI-INVENTORY-MISSING', 'UI-INVENTORY-INCOMPLETE', 'UI-ITEM-UNCOVERED',
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
/** The repairable codes of the audit's findings, in finding order, duplicates kept (they are counted). */
|
|
26
|
+
export function repairableCodes(s: UnitState): string[] {
|
|
27
|
+
return (s.audit?.findings ?? [])
|
|
28
|
+
.map((f) => f.split(':')[0].trim())
|
|
29
|
+
.filter((code) => REPAIRABLE.includes(code));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** The rules whose conjunction is the audit's gateStatus (audit-gate-terms.ts). */
|
|
33
|
+
const AUDIT_GATE_RULES = ['audit.viewpoint-coverage', 'audit.assertion-depth', 'audit.claim-proof', 'audit.spec-coverage',
|
|
34
|
+
'audit.taxonomy-mismatch', 'audit.gate-sensor-error', 'audit.scenario-id-reuse'];
|
|
35
|
+
|
|
36
|
+
export const UNIT_AUDIT_NODES: readonly UnitNodeDecl[] = [
|
|
37
|
+
{
|
|
38
|
+
id: 'unit.audit-missing', title: 'Measure the suite', actor: 'deterministic', granularity: 'unit',
|
|
39
|
+
appliesTo: ALL_KINDS, requires: ['unit.no-scenarios'], blocking: true, rank: 70, gates: [], produces: ['.sungen/reports/<unit>-audit.json'],
|
|
40
|
+
active: (s) => !s.auditNotCounted,
|
|
41
|
+
satisfied: (s) => Boolean(s.audit),
|
|
42
|
+
step: (s) => ({ kind: 'do', command: `sungen audit --screen ${s.unit}`, because: 'the suite has never been measured' }),
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
// OES-11.4: next, gate and delivery read one verdict — a report that does not count blocks all three.
|
|
46
|
+
id: 'unit.audit-stale', title: 'Re-measure the suite', actor: 'deterministic', granularity: 'unit',
|
|
47
|
+
appliesTo: ALL_KINDS, requires: ['unit.no-scenarios'], blocking: true, rank: 71, gates: [], produces: ['.sungen/reports/<unit>-audit.json'],
|
|
48
|
+
active: (s) => Boolean(s.auditNotCounted),
|
|
49
|
+
satisfied: (s) => Boolean(s.audit),
|
|
50
|
+
step: (s) => ({
|
|
51
|
+
kind: 'do',
|
|
52
|
+
command: `sungen audit --screen ${s.unit}`,
|
|
53
|
+
because: s.auditNotCounted!.state === 'stale'
|
|
54
|
+
? `the audit report is stale (${s.auditNotCounted!.reason}) — it no longer describes the suite and the decisions in force, so \`sungen gate\` and \`sungen delivery\` treat the unit as never audited until it is re-run`
|
|
55
|
+
: `the audit report is not trusted (${s.auditNotCounted!.reason}) — it counts as never audited (DOS-14.0) until \`sungen audit\` writes it again; never edit the report`,
|
|
56
|
+
}),
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
// A decision, not a step: accepting the yardstick an agent just wrote makes both axes read 100% (#660).
|
|
60
|
+
id: 'unit.baseline-changed', title: 'Accept the changed viewpoint', actor: 'human', granularity: 'unit',
|
|
61
|
+
appliesTo: ALL_KINDS, requires: ['unit.audit-missing', 'unit.audit-stale'], blocking: false, rank: 80, gates: [], produces: ['.sungen/viewpoint-baseline.json'],
|
|
62
|
+
active: (s) => Boolean(s.audit),
|
|
63
|
+
satisfied: (s) => s.audit?.viewpointBaselineStatus !== 'changed',
|
|
64
|
+
step: (s) => ({
|
|
65
|
+
kind: 'decide',
|
|
66
|
+
command: `sungen audit --screen ${s.unit} --accept-viewpoint`,
|
|
67
|
+
because: 'test-viewpoint.md changed since the accepted baseline, so the ledger and traceability axes are not evidence until a QA confirms the new declaration. A decision, not a step: an agent presents it and does not run it — accepting the yardstick you just wrote makes both axes read 100% by construction',
|
|
68
|
+
}),
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 'unit.repair-findings', title: 'Repair the named findings', actor: 'ai', granularity: 'unit',
|
|
72
|
+
appliesTo: ALL_KINDS, requires: ['unit.audit-missing', 'unit.audit-stale'], blocking: false, rank: 90, gates: [], produces: ['features/<unit>.feature'],
|
|
73
|
+
active: (s) => Boolean(s.audit),
|
|
74
|
+
satisfied: (s) => repairableCodes(s).length === 0,
|
|
75
|
+
step: (s) => {
|
|
76
|
+
const repair = repairableCodes(s);
|
|
77
|
+
return {
|
|
78
|
+
kind: 'do',
|
|
79
|
+
command: `repair, then sungen audit --screen ${s.unit}`,
|
|
80
|
+
because: `${repair.length} finding(s) name a specific repair: ${[...new Set(repair)].slice(0, 4).join(', ')}`,
|
|
81
|
+
};
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: 'unit.gate-fail', title: 'Repair the failing gate', actor: 'ai', granularity: 'unit',
|
|
86
|
+
appliesTo: ALL_KINDS, requires: ['unit.audit-missing', 'unit.audit-stale'], blocking: true, rank: 100, gates: AUDIT_GATE_RULES, produces: ['features/<unit>.feature'],
|
|
87
|
+
active: (s) => Boolean(s.audit),
|
|
88
|
+
satisfied: (s) => s.audit?.gateStatus !== 'FAIL',
|
|
89
|
+
step: (s) => ({
|
|
90
|
+
kind: 'blocked',
|
|
91
|
+
command: `repair the gate, then sungen audit --screen ${s.unit}`,
|
|
92
|
+
because: `the viewpoint gate is FAIL at ${s.audit!.overall}/10 — running tests against a design that fails its own gate measures the wrong thing`,
|
|
93
|
+
}),
|
|
94
|
+
},
|
|
95
|
+
];
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Test Contract as a QA DECISION in `sungen next` (DOS-14.4, phase 06 residual) — built from the
|
|
3
|
+
* verdict `sungen contract check` and the delivery guard rebuild (buildContractVerdict), so the three
|
|
4
|
+
* never disagree. Always `decide`: an agent presents it and never approves its own edit.
|
|
5
|
+
*
|
|
6
|
+
* unit.contract-approve (rank 105, after the audit gate, before the first run)
|
|
7
|
+
* error the verdict could not be built → check it on a terminal
|
|
8
|
+
* uncommitted by kind: tampered → re-approve or restore · untracked → commit after review ·
|
|
9
|
+
* edited → review and commit, or `git checkout --` the lock · unverified → commit the
|
|
10
|
+
* decision (approving again cannot fix a commit, and offering it would loop)
|
|
11
|
+
* hard a check got weaker / changed target / was lost → restore it, or QA approves
|
|
12
|
+
* review changed, not weaker → QA re-approves (review blocks delivery)
|
|
13
|
+
* unit.contract-proposed (rank 137, after every blocking unit step — it never preempts one)
|
|
14
|
+
* proposed never approved → QA approves (proposed scenarios never block)
|
|
15
|
+
* A free / impl:code scenario only its TRACE cannot prove — unproven, inconclusive, opaque — is not a
|
|
16
|
+
* unit decision: the case nodes say what proves it (test-case-contract-nodes.ts, phase 09).
|
|
17
|
+
*/
|
|
18
|
+
import { ALL_KINDS, StepCore, UnitNodeDecl, unitKindDir } from '../node-decl';
|
|
19
|
+
import type { UnitState } from '../../harness/next-step';
|
|
20
|
+
|
|
21
|
+
const HUMAN_ONLY = 'A QA decision on a terminal: an agent presents it and never approves its own edit';
|
|
22
|
+
const approveCmd = (s: UnitState): string => `sungen contract approve --screen ${s.unit}`;
|
|
23
|
+
|
|
24
|
+
function uncommittedStep(s: UnitState): StepCore {
|
|
25
|
+
const c = s.contract!;
|
|
26
|
+
const lock = `qa/${unitKindDir(s.kind)}/${s.unit}/contracts.lock.yaml`;
|
|
27
|
+
const n = c.uncommitted;
|
|
28
|
+
switch (c.uncommittedKind) {
|
|
29
|
+
case 'tampered':
|
|
30
|
+
return { kind: 'decide', command: approveCmd(s), because: `${n} lock entr(ies) no longer match their steps (edited by hand) — re-approve with \`${approveCmd(s)}\` on a terminal, or restore the lock from git` };
|
|
31
|
+
case 'untracked':
|
|
32
|
+
return { kind: 'decide', command: `commit ${lock} and its contract-approval decision after review`, because: `the lock has never been committed — ${n} entr(ies) are not in git HEAD (contract.lock-uncommitted); commit it after review` };
|
|
33
|
+
case 'unverified':
|
|
34
|
+
return { kind: 'decide', command: `commit the contract-approval decision behind ${lock} after review`, because: `${n} lock entr(ies) are not vouched for by a committed contract-approval decision (contract.lock-uncommitted) — commit the decision after review, or re-approve with \`${approveCmd(s)}\` on a terminal` };
|
|
35
|
+
default:
|
|
36
|
+
return { kind: 'decide', command: `review and commit ${lock}, or restore it: git checkout -- ${lock}`, because: `${n} lock entr(ies) differ from the lock in git HEAD (contract.lock-uncommitted) — review and commit the lock, or restore it with \`git checkout -- ${lock}\`; approving again cannot fix that` };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function contractStep(s: UnitState): StepCore {
|
|
41
|
+
const c = s.contract!;
|
|
42
|
+
if (c.error) {
|
|
43
|
+
return { kind: 'decide', command: `sungen contract check --screen ${s.unit}`, because: `the contract verdict could not be built (${c.error}) — check it on a terminal; until it builds, the delivery guard asks instead of passing` };
|
|
44
|
+
}
|
|
45
|
+
if (c.uncommitted > 0) return uncommittedStep(s);
|
|
46
|
+
if (c.hard > 0) {
|
|
47
|
+
return { kind: 'decide', command: approveCmd(s), because: `${c.hard} scenario(s) break the approved contract (${c.headline}) — restore the approved checks in the .feature, or, if the change is intended, a QA approves it on a terminal. An agent presents this and never approves its own edit` };
|
|
48
|
+
}
|
|
49
|
+
return { kind: 'decide', command: approveCmd(s), because: `${c.review} approved scenario(s) changed since QA approved them (changed, not weaker) — review blocks \`sungen delivery\` until QA re-approves. ${HUMAN_ONLY}` };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const CONTRACT_RULES = ['contract.hash-changed', 'contract.oracle-weakened', 'contract.target-changed', 'contract.assertion-lost', 'contract.lock-uncommitted'];
|
|
53
|
+
/** The verdict is a pass and it was built: nothing blocks, nothing to repair. */
|
|
54
|
+
const verdictClean = (s: UnitState): boolean => !s.contract!.error && s.contract!.verdict === 'pass';
|
|
55
|
+
/** Nothing for a QA to decide at unit level: built, committed, nothing approved got weaker or changed. */
|
|
56
|
+
const nothingToDecide = (s: UnitState): boolean => {
|
|
57
|
+
const c = s.contract!;
|
|
58
|
+
return !c.error && c.uncommitted === 0 && c.hard === 0 && c.review === 0 && (c.verdict === 'pass' || (c.unproven ?? 0) + (c.traceReview ?? 0) > 0);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const UNIT_CONTRACT_NODES: readonly UnitNodeDecl[] = [
|
|
62
|
+
{
|
|
63
|
+
id: 'unit.contract-approve', title: 'Resolve the Test Contract', actor: 'human', granularity: 'unit',
|
|
64
|
+
appliesTo: ALL_KINDS, requires: ['unit.gate-fail'], blocking: false, rank: 105, gates: CONTRACT_RULES,
|
|
65
|
+
produces: ['contracts.lock.yaml', 'decisions/<id>.yaml'],
|
|
66
|
+
active: (s) => Boolean(s.contract),
|
|
67
|
+
satisfied: nothingToDecide,
|
|
68
|
+
step: contractStep,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 'unit.contract-proposed', title: 'Approve the Test Contract', actor: 'human', granularity: 'unit',
|
|
72
|
+
appliesTo: ALL_KINDS, requires: ['unit.run'], blocking: false, rank: 137, gates: [],
|
|
73
|
+
produces: ['contracts.lock.yaml', 'decisions/<id>.yaml'],
|
|
74
|
+
active: (s) => Boolean(s.contract) && verdictClean(s),
|
|
75
|
+
satisfied: (s) => s.contract!.proposed === 0,
|
|
76
|
+
step: (s) => ({
|
|
77
|
+
kind: 'decide',
|
|
78
|
+
command: approveCmd(s),
|
|
79
|
+
because: `${s.contract!.proposed} scenario(s) have no approved contract yet — approving locks the checks QA reviewed, so a later edit that weakens one (a healer's included) fails \`sungen contract check\`. ${HUMAN_ONLY}; proposed scenarios do not block`,
|
|
80
|
+
}),
|
|
81
|
+
},
|
|
82
|
+
];
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Design-stage unit nodes — rows 1–6 of the OES-10.2 parity table, in the order and with the exact
|
|
3
|
+
* words `deriveSteps` used (frozen in tests/graph/fixtures/legacy-derive-steps.ts).
|
|
4
|
+
*
|
|
5
|
+
* 1 unit.no-source no spec and no viewpoint → blocked; cuts BEFORE even `sungen update`
|
|
6
|
+
* 2 unit.assets-drift AI assets from another build → `sungen update` (first, it voids the rest)
|
|
7
|
+
* 3 unit.viewpoint-missing no test-viewpoint.md → blocked, does not cut
|
|
8
|
+
* 4 unit.flow-contract a flow without flow-contract.yaml → blocked, cuts
|
|
9
|
+
* 5 unit.no-scenarios zero scenarios → create-test, cuts
|
|
10
|
+
* 6 unit.flow-inventory a flow contract without `flows:` → add it, re-audit
|
|
11
|
+
*/
|
|
12
|
+
import { ALL_KINDS, UnitNodeDecl, unitKindDir } from '../node-decl';
|
|
13
|
+
|
|
14
|
+
const design = (unit: string): string => `/sungen:create-test ${unit}`;
|
|
15
|
+
|
|
16
|
+
export const UNIT_DESIGN_NODES: readonly UnitNodeDecl[] = [
|
|
17
|
+
{
|
|
18
|
+
id: 'unit.no-source', title: 'Write a source to generate from', actor: 'human', granularity: 'unit',
|
|
19
|
+
appliesTo: ALL_KINDS, requires: [], blocking: true, rank: 10, gates: [], produces: ['requirements/spec.md'],
|
|
20
|
+
active: () => true,
|
|
21
|
+
satisfied: (s) => s.hasSpec || s.hasViewpoint,
|
|
22
|
+
step: (s) => ({
|
|
23
|
+
kind: 'blocked',
|
|
24
|
+
command: `write qa/${unitKindDir(s.kind)}/${s.unit}/requirements/spec.md`,
|
|
25
|
+
because: 'the unit has neither a spec nor a test-viewpoint, so there is nothing to generate FROM — generation without a source invents behaviour',
|
|
26
|
+
}),
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
// Stale AI assets come FIRST: a HARD RULE added to `create-test` reaches nobody until `sungen update`
|
|
30
|
+
// runs, and upgrading the package alone does not refresh them (#620).
|
|
31
|
+
id: 'unit.assets-drift', title: 'Refresh the AI commands and skills', actor: 'ai', granularity: 'unit',
|
|
32
|
+
appliesTo: ALL_KINDS, requires: ['unit.no-source'], blocking: false, rank: 20, gates: [], produces: ['.claude/', '.github/', '.agents/'],
|
|
33
|
+
active: () => true,
|
|
34
|
+
satisfied: (s) => !s.assetsDrift,
|
|
35
|
+
step: (s) => ({
|
|
36
|
+
kind: 'do',
|
|
37
|
+
command: 'sungen update',
|
|
38
|
+
because: `this project's AI commands/skills were written by sungen ${s.assetsDrift!.recordedVersion} and you are running ${s.assetsDrift!.runningVersion} — upgrading the package does NOT refresh them, so any rule added since ${s.assetsDrift!.recordedVersion} is not in effect for the next run`,
|
|
39
|
+
}),
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
// The yardstick `atomicLedger` and `traceability` are measured against; it can go missing from a
|
|
43
|
+
// unit that already HAS a spec, which unit.no-source never sees.
|
|
44
|
+
id: 'unit.viewpoint-missing', title: 'Restore the test viewpoint', actor: 'human', granularity: 'unit',
|
|
45
|
+
appliesTo: ALL_KINDS, requires: ['unit.no-source'], blocking: false, rank: 30, gates: [], produces: ['requirements/test-viewpoint.md'],
|
|
46
|
+
active: () => true,
|
|
47
|
+
satisfied: (s) => s.hasViewpoint,
|
|
48
|
+
step: (s) => ({
|
|
49
|
+
kind: 'blocked',
|
|
50
|
+
command: s.kind === 'flow'
|
|
51
|
+
? `sungen add-flow --flow ${s.unit} --path <start-url> # repairs the missing scaffold; never overwrites`
|
|
52
|
+
: `write qa/screens/${s.unit}/requirements/test-viewpoint.md`,
|
|
53
|
+
because: 'requirements/test-viewpoint.md is missing — it is the yardstick `atomicLedger` and `traceability` are measured against, and four sensors read it, so the audit reports VIEWPOINT-MISSING and those axes are excluded. A flow contract does not substitute: it declares the use case, the viewpoint declares the claims',
|
|
54
|
+
}),
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 'unit.flow-contract', title: 'Author the flow contract', actor: 'human', granularity: 'unit',
|
|
58
|
+
appliesTo: ['flow'], requires: ['unit.no-source'], blocking: true, rank: 40, gates: [], produces: ['requirements/flow-contract.yaml'],
|
|
59
|
+
active: () => true,
|
|
60
|
+
satisfied: (s) => s.hasContract,
|
|
61
|
+
step: (s) => ({
|
|
62
|
+
kind: 'blocked',
|
|
63
|
+
command: `author requirements/flow-contract.yaml, then ${design(s.unit)}`,
|
|
64
|
+
because: 'a flow with no contract is scored as a generic screen against page-type themes a journey cannot have (FLOW-CONTRACT-MISSING)',
|
|
65
|
+
}),
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: 'unit.no-scenarios', title: 'Generate the scenarios', actor: 'ai', granularity: 'unit',
|
|
69
|
+
appliesTo: ALL_KINDS, requires: ['unit.no-source', 'unit.flow-contract'], blocking: true, rank: 50,
|
|
70
|
+
gates: ['journey.phase-create'], produces: ['features/<unit>.feature'],
|
|
71
|
+
active: () => true,
|
|
72
|
+
satisfied: (s) => s.scenarioCount !== 0,
|
|
73
|
+
step: (s) => ({ kind: 'do', command: design(s.unit), because: 'no scenarios exist yet' }),
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
// Without the inventory, coverage is per PHASE, and a phase counts as covered once one scenario
|
|
77
|
+
// carries it — so the number cannot show a missing flow.
|
|
78
|
+
id: 'unit.flow-inventory', title: 'Declare the flow inventory', actor: 'ai', granularity: 'unit',
|
|
79
|
+
appliesTo: ['flow'], requires: ['unit.no-scenarios'], blocking: false, rank: 60, gates: [], produces: ['requirements/flow-contract.yaml'],
|
|
80
|
+
active: () => true,
|
|
81
|
+
satisfied: (s) => s.hasFlowInventory,
|
|
82
|
+
step: (s) => ({
|
|
83
|
+
kind: 'do',
|
|
84
|
+
command: `add \`flows:\` to requirements/flow-contract.yaml, then sungen audit --screen ${s.unit}`,
|
|
85
|
+
because: 'without the inventory, coverage is measured per PHASE — and a phase counts as covered as soon as one scenario carries it, so the number cannot tell you a flow is missing',
|
|
86
|
+
}),
|
|
87
|
+
},
|
|
88
|
+
];
|