@sun-asterisk/sungen 3.2.34 → 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 +9 -4
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/capability.d.ts.map +1 -1
- package/dist/cli/commands/capability.js +6 -2
- 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/defect.d.ts +7 -0
- package/dist/cli/commands/defect.d.ts.map +1 -0
- package/dist/cli/commands/defect.js +68 -0
- package/dist/cli/commands/defect.js.map +1 -0
- package/dist/cli/commands/delivery.d.ts.map +1 -1
- package/dist/cli/commands/delivery.js +87 -10
- 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/triage.d.ts +7 -0
- package/dist/cli/commands/triage.d.ts.map +1 -0
- package/dist/cli/commands/triage.js +98 -0
- package/dist/cli/commands/triage.js.map +1 -0
- 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 +24 -33
- 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/csv-exporter.d.ts +4 -0
- package/dist/exporters/csv-exporter.d.ts.map +1 -1
- package/dist/exporters/csv-exporter.js +1 -1
- package/dist/exporters/csv-exporter.js.map +1 -1
- package/dist/exporters/feature-parser.d.ts +8 -0
- package/dist/exporters/feature-parser.d.ts.map +1 -1
- package/dist/exporters/feature-parser.js +12 -0
- package/dist/exporters/feature-parser.js.map +1 -1
- 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 +59 -19
- package/dist/exporters/matrix/build.js.map +1 -1
- package/dist/exporters/matrix/carry-manual-results.d.ts +19 -0
- package/dist/exporters/matrix/carry-manual-results.d.ts.map +1 -1
- package/dist/exporters/matrix/carry-manual-results.js +76 -6
- package/dist/exporters/matrix/carry-manual-results.js.map +1 -1
- package/dist/exporters/matrix/export.d.ts +8 -2
- package/dist/exporters/matrix/export.d.ts.map +1 -1
- package/dist/exporters/matrix/export.js +16 -3
- 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 +4 -1
- 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 +6 -0
- package/dist/exporters/matrix/render-xlsx.js.map +1 -1
- package/dist/exporters/matrix/types.d.ts +9 -1
- package/dist/exporters/matrix/types.d.ts.map +1 -1
- package/dist/exporters/matrix/types.js.map +1 -1
- package/dist/exporters/playwright-report-parser.d.ts.map +1 -1
- package/dist/exporters/playwright-report-parser.js +1 -0
- package/dist/exporters/playwright-report-parser.js.map +1 -1
- package/dist/exporters/scenario-merger.d.ts.map +1 -1
- package/dist/exporters/scenario-merger.js +2 -0
- package/dist/exporters/scenario-merger.js.map +1 -1
- package/dist/exporters/types.d.ts +5 -0
- package/dist/exporters/types.d.ts.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 +34 -9
- package/dist/harness/audit.js.map +1 -1
- package/dist/harness/catalog/gate-rules.yaml +647 -0
- package/dist/harness/counted-assertions.d.ts +2 -0
- package/dist/harness/counted-assertions.d.ts.map +1 -0
- package/dist/harness/counted-assertions.js +38 -0
- package/dist/harness/counted-assertions.js.map +1 -0
- package/dist/harness/defect-draft.d.ts +14 -0
- package/dist/harness/defect-draft.d.ts.map +1 -0
- package/dist/harness/defect-draft.js +143 -0
- package/dist/harness/defect-draft.js.map +1 -0
- package/dist/harness/defects.d.ts +24 -0
- package/dist/harness/defects.d.ts.map +1 -0
- package/dist/harness/defects.js +118 -0
- package/dist/harness/defects.js.map +1 -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 +73 -45
- package/dist/harness/manifest.js.map +1 -1
- package/dist/harness/next-step.d.ts +37 -6
- package/dist/harness/next-step.d.ts.map +1 -1
- package/dist/harness/next-step.js +34 -174
- package/dist/harness/next-step.js.map +1 -1
- package/dist/harness/parse.d.ts +25 -0
- package/dist/harness/parse.d.ts.map +1 -1
- package/dist/harness/parse.js +38 -13
- package/dist/harness/parse.js.map +1 -1
- package/dist/harness/script-check.d.ts.map +1 -1
- package/dist/harness/script-check.js +29 -6
- 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 +64 -44
- package/dist/harness/sensors.js.map +1 -1
- package/dist/harness/triage-signals.d.ts +20 -0
- package/dist/harness/triage-signals.d.ts.map +1 -0
- package/dist/harness/triage-signals.js +30 -0
- package/dist/harness/triage-signals.js.map +1 -0
- package/dist/harness/triage-unit.d.ts +23 -0
- package/dist/harness/triage-unit.d.ts.map +1 -0
- package/dist/harness/triage-unit.js +142 -0
- package/dist/harness/triage-unit.js.map +1 -0
- package/dist/harness/triage.d.ts +28 -0
- package/dist/harness/triage.d.ts.map +1 -0
- package/dist/harness/triage.js +99 -0
- package/dist/harness/triage.js.map +1 -0
- package/dist/harness/viewpoint-ledger.d.ts.map +1 -1
- package/dist/harness/viewpoint-ledger.js +2 -1
- 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/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 +4 -2
- 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 +14 -16
- 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 +14 -10
- 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-error-mapping/SKILL.md +2 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +1 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md +2 -0
- package/dist/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
- 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 +9 -4
- package/src/cli/commands/capability.ts +4 -2
- package/src/cli/commands/contract-derive-command.ts +60 -0
- package/src/cli/commands/contract.ts +130 -0
- package/src/cli/commands/defect.ts +49 -0
- package/src/cli/commands/delivery.ts +85 -13
- 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/triage.ts +57 -0
- package/src/cli/commands/update.ts +35 -8
- package/src/cli/index.ts +24 -30
- 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/csv-exporter.ts +5 -1
- package/src/exporters/feature-parser.ts +12 -0
- package/src/exporters/matrix/build.ts +62 -18
- package/src/exporters/matrix/carry-manual-results.ts +70 -7
- package/src/exporters/matrix/export.ts +17 -2
- package/src/exporters/matrix/gates.ts +62 -129
- package/src/exporters/matrix/render-csv.ts +4 -1
- package/src/exporters/matrix/render-gate-overrides-sheet.ts +50 -0
- package/src/exporters/matrix/render-xlsx.ts +6 -0
- package/src/exporters/matrix/types.ts +9 -1
- package/src/exporters/playwright-report-parser.ts +1 -0
- package/src/exporters/scenario-merger.ts +2 -1
- package/src/exporters/types.ts +5 -0
- 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 +46 -11
- package/src/harness/catalog/gate-rules.yaml +647 -0
- package/src/harness/counted-assertions.ts +33 -0
- package/src/harness/defect-draft.ts +115 -0
- package/src/harness/defects.ts +94 -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 +69 -45
- package/src/harness/next-step.ts +60 -170
- package/src/harness/parse.ts +40 -13
- package/src/harness/script-check.ts +27 -6
- package/src/harness/sensors.ts +73 -47
- package/src/harness/triage-signals.ts +46 -0
- package/src/harness/triage-unit.ts +113 -0
- package/src/harness/triage.ts +127 -0
- package/src/harness/viewpoint-ledger.ts +2 -2
- 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/lockstep-version.ts +28 -15
- package/src/orchestrator/project-initializer.ts +21 -0
- package/src/orchestrator/screen-manager.ts +3 -1
- 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 +14 -16
- 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 +14 -10
- 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-error-mapping/SKILL.md +2 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +1 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md +2 -0
- package/src/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
- package/src/utils/safe-yaml-parse.ts +44 -0
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* 3. Manual — the cases a person runs.
|
|
9
9
|
* 4. Coverage — requirement coverage, the target × category grid,
|
|
10
10
|
* dispositions and the generation manifest, over the whole model.
|
|
11
|
+
* 5. Gate overrides — only when a gate-override touches the unit (client rows only).
|
|
11
12
|
*
|
|
12
13
|
* Auto and Manual are always both created, even when one side is empty: the
|
|
13
14
|
* Overview then always reads the same two rows, and QA has a place to add
|
|
@@ -20,6 +21,7 @@ import { DeliveryItem, MatrixModel } from './types';
|
|
|
20
21
|
import { addTestcaseSheet } from './render-testcase-sheet';
|
|
21
22
|
import { addCoverageSheet } from './render-coverage-sheet';
|
|
22
23
|
import { addMatrixOverviewSheet, SheetProjection } from './render-overview-sheet';
|
|
24
|
+
import { addGateOverridesSheet } from './render-gate-overrides-sheet';
|
|
23
25
|
|
|
24
26
|
// The CSV renderer and the tests import these from here — they moved to
|
|
25
27
|
// `item-labels.ts` when this module was split, and stay reachable at the old path.
|
|
@@ -74,6 +76,9 @@ export function projectItems(model: MatrixModel, mode: 'auto' | 'manual'): Deliv
|
|
|
74
76
|
|
|
75
77
|
export function renderMatrixXlsx(model: MatrixModel, sungenVersion?: string): ExcelJS.Workbook {
|
|
76
78
|
const wb = new ExcelJS.Workbook();
|
|
79
|
+
// Every total and roll-up is a formula with a cached result. The cache is what a preview
|
|
80
|
+
// (GitHub, Drive, QuickLook) shows; a spreadsheet app recomputes on open as well (#891).
|
|
81
|
+
wb.calcProperties.fullCalcOnLoad = true;
|
|
77
82
|
const sheets: SheetProjection[] = [
|
|
78
83
|
{ sheetName: 'Auto', items: projectItems(model, 'auto') },
|
|
79
84
|
{ sheetName: 'Manual', items: projectItems(model, 'manual') },
|
|
@@ -82,5 +87,6 @@ export function renderMatrixXlsx(model: MatrixModel, sungenVersion?: string): Ex
|
|
|
82
87
|
addMatrixOverviewSheet(wb, model, sheets, sungenVersion);
|
|
83
88
|
for (const s of sheets) addTestcaseSheet(wb, s.sheetName, model, s.items, sungenVersion);
|
|
84
89
|
addCoverageSheet(wb, model, sungenVersion);
|
|
90
|
+
addGateOverridesSheet(wb, model); // only when a gate-override touches the unit (OES-11.6)
|
|
85
91
|
return wb;
|
|
86
92
|
}
|
|
@@ -147,6 +147,11 @@ export interface CoverageVariant {
|
|
|
147
147
|
fingerprint: string;
|
|
148
148
|
/** Execution result, when the run report has one for this variant. */
|
|
149
149
|
result?: PlaywrightResult;
|
|
150
|
+
/** A Manual variant's result as the tester recorded it in the previous workbook, carried
|
|
151
|
+
* BEFORE rendering so every total, roll-up, the CSV and the CLI count it (#891). */
|
|
152
|
+
manualState?: VariantState;
|
|
153
|
+
/** The Executed Date the tester recorded with it (yyyy-mm-dd, or as typed). */
|
|
154
|
+
manualDate?: string;
|
|
150
155
|
}
|
|
151
156
|
|
|
152
157
|
export type ItemResult = 'passed' | 'failed' | 'blocked' | 'partial' | 'not_run' | 'na';
|
|
@@ -214,7 +219,8 @@ export interface RequirementCoverage {
|
|
|
214
219
|
// ---------------------------------------------------------------------------
|
|
215
220
|
|
|
216
221
|
export type GateId = 'A' | 'B' | 'C' | 'D' | 'E' | 'G' | 'K' | 'R' | 'W';
|
|
217
|
-
|
|
222
|
+
/** `info` appears only when a gate-override lowered a soft rule (OES-11.3). */
|
|
223
|
+
export type FindingSeverity = 'error' | 'review' | 'warning' | 'info';
|
|
218
224
|
|
|
219
225
|
export interface MatrixFinding {
|
|
220
226
|
gate: GateId;
|
|
@@ -260,6 +266,8 @@ export interface MatrixModel {
|
|
|
260
266
|
/** Who ran the suite and against what — fills Test Executor / Test Environment on rows that
|
|
261
267
|
* ran (#850). Absent when the caller has no run context (gates-only paths). */
|
|
262
268
|
runEnv?: import('../run-environment').RunEnvironment;
|
|
269
|
+
/** Gate overrides touching the unit (OES-11.6) — client-visible rows only; internal ones are only counted. */
|
|
270
|
+
gateOverrides?: import('../../harness/gates/gate-override-report').DeliverableGateOverrides;
|
|
263
271
|
}
|
|
264
272
|
|
|
265
273
|
/** Complexity warning threshold (rules draft Gate I; raised for compact grouping) — echoed in the manifest. */
|
|
@@ -161,6 +161,7 @@ export function loadPlaywrightReport(reportPath: string): Map<string, Playwright
|
|
|
161
161
|
errorMessages: distinct.length > 0 ? distinct : undefined,
|
|
162
162
|
tracePath: trace,
|
|
163
163
|
projectName: test?.projectName,
|
|
164
|
+
attempts: results.length || undefined,
|
|
164
165
|
});
|
|
165
166
|
}
|
|
166
167
|
return result;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { FeatureMetadata, OrderedStep, ScenarioMetadata, SpecFileData, SpecTest } from './types';
|
|
12
|
-
import { isStepsBaseScenario, isSampleScaffoldScenario, extractTestcaseType } from './feature-parser';
|
|
12
|
+
import { isStepsBaseScenario, isSampleScaffoldScenario, isHookScenario, extractTestcaseType } from './feature-parser';
|
|
13
13
|
import { SCENARIO_ID } from './feature-parser';
|
|
14
14
|
import { extractUnlabeledOracle, onlyPresenceAssertions } from './manual-hybrid-oracle';
|
|
15
15
|
|
|
@@ -139,6 +139,7 @@ export function mergeFeatureAndSpec(
|
|
|
139
139
|
for (const scenario of feature.scenarios) {
|
|
140
140
|
if (isStepsBaseScenario(scenario)) continue; // skip @steps base scenarios
|
|
141
141
|
if (isSampleScaffoldScenario(scenario)) continue; // skip default sample
|
|
142
|
+
if (isHookScenario(scenario)) continue; // skip @beforeAll/@afterEach/@afterAll hooks
|
|
142
143
|
|
|
143
144
|
const specTest = findMatchingSpecTest(scenario, spec.tests, feature.scenarios);
|
|
144
145
|
const base = scenario.extendsName ? stepsBaseByName.get(scenario.extendsName) : undefined;
|
package/src/exporters/types.ts
CHANGED
|
@@ -95,6 +95,9 @@ export interface ScenarioMetadata {
|
|
|
95
95
|
* as Gherkin steps — the merger parses these into Steps/Expected for the report.
|
|
96
96
|
*/
|
|
97
97
|
comments?: string[];
|
|
98
|
+
/** Set for a `@beforeAll` / `@afterEach` / `@afterAll` scenario — a hook the compiler emits as
|
|
99
|
+
* `test.beforeAll()` etc., never a test case (#880). */
|
|
100
|
+
hookType?: 'beforeAll' | 'afterEach' | 'afterAll';
|
|
98
101
|
}
|
|
99
102
|
|
|
100
103
|
/**
|
|
@@ -134,6 +137,8 @@ export interface PlaywrightResult {
|
|
|
134
137
|
errorMessages?: string[];
|
|
135
138
|
tracePath?: string;
|
|
136
139
|
projectName?: string;
|
|
140
|
+
/** How many attempts the test took (retries + 1). A pass with attempts > 1 is flaky. */
|
|
141
|
+
attempts?: number;
|
|
137
142
|
}
|
|
138
143
|
|
|
139
144
|
/**
|
|
@@ -9,6 +9,7 @@ import { parseResetTier, DEFAULT_RESET_TIER } from './reset-tier';
|
|
|
9
9
|
import { capabilityRegistry } from '../../capabilities/registry';
|
|
10
10
|
import { discoverAndRegisterCapabilities } from '../../capabilities/discover';
|
|
11
11
|
import { readCapabilities } from '../../harness/capability';
|
|
12
|
+
import { isHandWritten } from '../../harness/parse';
|
|
12
13
|
import { parseManualComments } from '../../exporters/scenario-merger';
|
|
13
14
|
import { isPresencePlaceholderHybrid } from '../../exporters/manual-hybrid-oracle';
|
|
14
15
|
import { findSyntaxError } from './utils/spec-syntax-check';
|
|
@@ -780,6 +781,12 @@ export class CodeGenerator {
|
|
|
780
781
|
|
|
781
782
|
const renderedScenarios: Array<{ code: string; authRole?: string; noAuth?: boolean }> = [];
|
|
782
783
|
for (const scenario of feature.scenarios) {
|
|
784
|
+
// @free / @impl:code / @proposed: implemented by hand-written code and proven by its trace —
|
|
785
|
+
// never compiled (DOS-14.8). The same predicate script-check uses, so the counts agree.
|
|
786
|
+
if (!scenario.stepsName && !scenario.hookType && isHandWritten([...(feature.tags || []), ...(scenario.tags || [])], feature.sourceFile)) {
|
|
787
|
+
console.log(` ⊘ Skipped hand-written scenario: ${scenario.name}`);
|
|
788
|
+
continue;
|
|
789
|
+
}
|
|
783
790
|
if (isManual(scenario.tags)) {
|
|
784
791
|
// SG-W008 — two-direction rule for @manual scenarios:
|
|
785
792
|
// • HAS Gherkin steps → the Gherkin must be COMPLETE: Given/When/Then. A dangling
|
|
@@ -1458,6 +1465,12 @@ export class CodeGenerator {
|
|
|
1458
1465
|
console.log(`⊘ Skipped @manual feature: ${feature.name}`);
|
|
1459
1466
|
continue;
|
|
1460
1467
|
}
|
|
1468
|
+
// A feature whose scenarios are all hand-written (a derived *.free.feature) emits no spec.
|
|
1469
|
+
const own = feature.scenarios.filter((sc) => !sc.stepsName && !sc.hookType);
|
|
1470
|
+
if (own.length && own.every((sc) => isHandWritten([...(feature.tags || []), ...(sc.tags || [])], feature.sourceFile))) {
|
|
1471
|
+
console.log(`⊘ Skipped hand-written feature: ${feature.name}`);
|
|
1472
|
+
continue;
|
|
1473
|
+
}
|
|
1461
1474
|
|
|
1462
1475
|
try {
|
|
1463
1476
|
const generatedTest = await this.generateTest(feature, outputDir);
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ready frontier of the `sungen next` graph (OES-10.1). Deterministic, read-only: the same
|
|
3
|
+
* unit state and test-case states always give the same steps, in rank order.
|
|
4
|
+
*
|
|
5
|
+
* open active ∧ ¬satisfied (a test-case node is open when at least one case is)
|
|
6
|
+
* frontier open ∧ (every `requires` satisfied ∨ ¬blocking)
|
|
7
|
+
* cut an open blocking node ends the walk — nothing ranked after it is offered
|
|
8
|
+
*
|
|
9
|
+
* `--case <id>` (`testCase` option): the frontier is that case's test-case nodes plus the blocking
|
|
10
|
+
* unit nodes before them; non-blocking unit advice is left to the unit view. A `caseOnly` test-case
|
|
11
|
+
* node speaks only there (its unit-level decision is in the unit view already).
|
|
12
|
+
*/
|
|
13
|
+
import type { NextStep, UnitState } from '../harness/next-step';
|
|
14
|
+
import type { NodeDecl, StepCore } from './node-decl';
|
|
15
|
+
import type { TestCaseState } from './test-case-state-shape';
|
|
16
|
+
|
|
17
|
+
export interface EvaluateOptions {
|
|
18
|
+
/** Only this test case's nodes (plus the blocking unit nodes before them). */
|
|
19
|
+
testCase?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function withMeta(node: NodeDecl, core: StepCore, testCase?: string): NextStep {
|
|
23
|
+
return {
|
|
24
|
+
...core,
|
|
25
|
+
nodeId: node.id,
|
|
26
|
+
granularity: node.granularity,
|
|
27
|
+
...(testCase ? { testCase } : {}),
|
|
28
|
+
...(node.gates.length ? { gates: [...node.gates] } : {}),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** The cases open at a test-case node, in their given order; none without test-case states. */
|
|
33
|
+
function openCases(node: NodeDecl, s: UnitState, tcStates: TestCaseState[] | undefined, only?: string): TestCaseState[] {
|
|
34
|
+
if (node.granularity !== 'test-case' || !tcStates) return [];
|
|
35
|
+
return tcStates.filter((tc) => (!only || tc.id === only) && node.active(s, tc) && !node.satisfied(s, tc));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function evaluateGraph(
|
|
39
|
+
nodes: readonly NodeDecl[], s: UnitState, tcStates?: TestCaseState[], opts: EvaluateOptions = {},
|
|
40
|
+
): NextStep[] {
|
|
41
|
+
const ordered = [...nodes].sort((a, b) => a.rank - b.rank);
|
|
42
|
+
const open = new Set<string>();
|
|
43
|
+
const out: NextStep[] = [];
|
|
44
|
+
for (const node of ordered) {
|
|
45
|
+
if (!node.appliesTo.includes(s.kind) || (node.granularity === 'test-case' && node.caseOnly && !opts.testCase)) continue;
|
|
46
|
+
let step: NextStep | null = null;
|
|
47
|
+
if (node.granularity === 'unit') {
|
|
48
|
+
if (!node.active(s) || node.satisfied(s)) continue;
|
|
49
|
+
if (!opts.testCase || node.blocking) step = withMeta(node, node.step(s));
|
|
50
|
+
} else {
|
|
51
|
+
const cases = openCases(node, s, tcStates, opts.testCase);
|
|
52
|
+
if (!cases.length) continue;
|
|
53
|
+
const single = Boolean(opts.testCase);
|
|
54
|
+
step = withMeta(node, node.step(s, cases, single), single ? cases[0].id : undefined);
|
|
55
|
+
}
|
|
56
|
+
open.add(node.id);
|
|
57
|
+
const ready = node.requires.every((r) => !open.has(r));
|
|
58
|
+
if (step && (ready || !node.blocking)) out.push(step);
|
|
59
|
+
if (node.blocking) break;
|
|
60
|
+
}
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
@@ -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
|
+
];
|