@sun-asterisk/sungen 3.2.34 → 3.3.0-alpha.2
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/discover.d.ts +4 -0
- package/dist/capabilities/discover.d.ts.map +1 -1
- package/dist/capabilities/discover.js +16 -2
- package/dist/capabilities/discover.js.map +1 -1
- 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 +10 -5
- 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 +11 -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 +96 -12
- 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 +43 -15
- 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 +68 -8
- 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/cli/project-sungen-invocation.d.ts +7 -0
- package/dist/cli/project-sungen-invocation.d.ts.map +1 -0
- package/dist/cli/project-sungen-invocation.js +76 -0
- package/dist/cli/project-sungen-invocation.js.map +1 -0
- 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 +38 -0
- package/dist/contract/derive-free-feature.d.ts.map +1 -0
- package/dist/contract/derive-free-feature.js +154 -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 +41 -0
- package/dist/contract/trace/trace-file-reader.d.ts.map +1 -0
- package/dist/contract/trace/trace-file-reader.js +161 -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 +30 -0
- package/dist/contract/trace/trace-run-record.d.ts.map +1 -0
- package/dist/contract/trace/trace-run-record.js +121 -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 +45 -0
- package/dist/contract/trace/trace-zip-limits.d.ts.map +1 -0
- package/dist/contract/trace/trace-zip-limits.js +52 -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 +41 -0
- package/dist/decisions/confirmed-decision-commands.d.ts.map +1 -0
- package/dist/decisions/confirmed-decision-commands.js +190 -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 +35 -0
- package/dist/decisions/human-confirmation.d.ts.map +1 -0
- package/dist/decisions/human-confirmation.js +161 -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/matrix/xlsx-cells.js +1 -1
- package/dist/exporters/matrix/xlsx-cells.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 +23 -0
- package/dist/graph/evaluate-graph.d.ts.map +1 -0
- package/dist/graph/evaluate-graph.js +52 -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 +66 -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 +21 -0
- package/dist/graph/nodes/test-case-contract-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/test-case-contract-nodes.js +59 -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 +21 -0
- package/dist/graph/nodes/unit-contract-node.d.ts.map +1 -0
- package/dist/graph/nodes/unit-contract-node.js +88 -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 +91 -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 +41 -0
- package/dist/harness/gates/audit-report-verification.d.ts.map +1 -0
- package/dist/harness/gates/audit-report-verification.js +236 -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 +33 -0
- package/dist/harness/gates/delivery-decision-gate.d.ts.map +1 -0
- package/dist/harness/gates/delivery-decision-gate.js +116 -0
- package/dist/harness/gates/delivery-decision-gate.js.map +1 -0
- package/dist/harness/gates/delivery-decision-step.d.ts +19 -0
- package/dist/harness/gates/delivery-decision-step.d.ts.map +1 -0
- package/dist/harness/gates/delivery-decision-step.js +86 -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 +43 -1
- package/dist/harness/journey.d.ts.map +1 -1
- package/dist/harness/journey.js +207 -33
- 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/provenance.d.ts +29 -0
- package/dist/harness/provenance.d.ts.map +1 -1
- package/dist/harness/provenance.js +109 -9
- package/dist/harness/provenance.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 +107 -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 +39 -0
- package/dist/hooks/hand-back-core.d.ts.map +1 -0
- package/dist/hooks/hand-back-core.js +122 -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 +57 -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/assets-drift.d.ts +5 -0
- package/dist/orchestrator/assets-drift.d.ts.map +1 -1
- package/dist/orchestrator/assets-drift.js +12 -3
- package/dist/orchestrator/assets-drift.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 +24 -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/discover.ts +15 -2
- package/src/capabilities/registry.ts +16 -0
- package/src/cli/commands/audit.ts +10 -5
- package/src/cli/commands/capability.ts +4 -2
- package/src/cli/commands/contract-derive-command.ts +61 -0
- package/src/cli/commands/contract.ts +130 -0
- package/src/cli/commands/defect.ts +49 -0
- package/src/cli/commands/delivery.ts +92 -15
- package/src/cli/commands/generate.ts +3 -1
- package/src/cli/commands/journey.ts +41 -16
- package/src/cli/commands/next.ts +64 -10
- 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/cli/project-sungen-invocation.ts +39 -0
- 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 +120 -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 +104 -0
- package/src/contract/trace/trace-binding.ts +56 -0
- package/src/contract/trace/trace-file-reader.ts +133 -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 +80 -0
- package/src/contract/trace/trace-steps.ts +88 -0
- package/src/contract/trace/trace-zip-limits.ts +77 -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 +149 -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 +119 -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/matrix/xlsx-cells.ts +1 -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 +66 -0
- package/src/graph/locate-finding.ts +93 -0
- package/src/graph/node-decl.ts +72 -0
- package/src/graph/nodes/core-node-catalog.ts +15 -0
- package/src/graph/nodes/test-case-contract-nodes.ts +74 -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 +89 -0
- package/src/graph/nodes/unit-design-nodes.ts +89 -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 +201 -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 +139 -0
- package/src/harness/gates/delivery-decision-step.ts +89 -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 +215 -38
- 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/provenance.ts +99 -11
- 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 +71 -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 +112 -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 +56 -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/assets-drift.ts +12 -5
- package/src/orchestrator/claude-hooks-install.ts +168 -0
- package/src/orchestrator/lockstep-version.ts +28 -15
- package/src/orchestrator/project-initializer.ts +22 -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
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
* Deterministic quality gates for the Test Case & Coverage Matrix
|
|
3
3
|
* (docs/spec/delivery-coverage-matrix-spec.md §6).
|
|
4
4
|
*
|
|
5
|
-
* Severity behavior
|
|
5
|
+
* Severity behavior (the level of each finding comes from the gate-rule catalog through
|
|
6
|
+
* `resolveRule`, never from this file — OES-11.2):
|
|
6
7
|
* error → blocks any render
|
|
7
8
|
* review → blocks the official render; `--preview` renders with a DRAFT watermark
|
|
8
9
|
* warning → prints + renders
|
|
10
|
+
* info → prints (only when a gate-override lowered a soft rule); `off` drops the finding
|
|
9
11
|
*
|
|
10
12
|
* The gates recompute every signature part from the .feature — the map is never
|
|
11
13
|
* trusted for derivable facts, only for the semantic fields (target/intent/oracle).
|
|
@@ -14,25 +16,37 @@
|
|
|
14
16
|
import { splitVpAndName, extractTestcaseType } from '../feature-parser';
|
|
15
17
|
import { mapContentFingerprint } from './fingerprint';
|
|
16
18
|
import { bucketTexts } from './step-buckets';
|
|
17
|
-
import { CoverageVariant, MatrixFinding, MAX_VARIANTS_PER_ITEM } from './types';
|
|
19
|
+
import { CoverageVariant, GateId, MatrixFinding, MAX_VARIANTS_PER_ITEM } from './types';
|
|
18
20
|
import { expandMapRef, BuildInputs } from './build';
|
|
21
|
+
import { CATALOG_GATE_RULES, GateRules } from '../../harness/gates/resolve-rule';
|
|
19
22
|
|
|
20
23
|
export interface GateContext {
|
|
21
24
|
inputs: BuildInputs;
|
|
22
25
|
variants: CoverageVariant[];
|
|
23
26
|
variantsByVp: Map<string, CoverageVariant[]>;
|
|
27
|
+
/** The unit's gate rules (catalog + its gate-overrides); the catalog alone when absent. */
|
|
28
|
+
rules?: GateRules;
|
|
24
29
|
}
|
|
25
30
|
|
|
31
|
+
/** A gate site found its condition: the rule decides the finding's severity, or drops it. */
|
|
32
|
+
type ReportFinding = (rule: string, gate: GateId, message: string, ref?: string) => void;
|
|
33
|
+
|
|
26
34
|
export function runGates(ctx: GateContext): MatrixFinding[] {
|
|
27
35
|
const findings: MatrixFinding[] = [];
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
const rules = ctx.rules ?? CATALOG_GATE_RULES;
|
|
37
|
+
const report: ReportFinding = (rule, gate, message, ref) => {
|
|
38
|
+
const { severity } = rules.resolve(rule);
|
|
39
|
+
if (severity === 'off') return;
|
|
40
|
+
findings.push({ gate, severity, ...(ref !== undefined ? { ref } : {}), message });
|
|
41
|
+
};
|
|
42
|
+
gateASource(ctx, report);
|
|
43
|
+
gateBMapping(ctx, report);
|
|
44
|
+
gateCAggregation(ctx, report);
|
|
45
|
+
gateDExecutability(ctx, report);
|
|
46
|
+
gateEDrift(ctx, report);
|
|
47
|
+
gateGReviewState(ctx, report);
|
|
48
|
+
gateWWording(ctx, report);
|
|
49
|
+
gateKCategory(ctx, report);
|
|
36
50
|
return findings;
|
|
37
51
|
}
|
|
38
52
|
|
|
@@ -54,16 +68,13 @@ const VP_CATEGORY_RULE: Array<[RegExp, string, string]> = [
|
|
|
54
68
|
* have while hiding the security work it does have. Same for `VP-NFR-*`.
|
|
55
69
|
* (normal vs abnormal stays a judgement call and is never checked.)
|
|
56
70
|
*/
|
|
57
|
-
function gateKCategory(ctx: GateContext,
|
|
71
|
+
function gateKCategory(ctx: GateContext, report: ReportFinding): void {
|
|
58
72
|
for (const g of ctx.inputs.map.groups) {
|
|
59
73
|
const vs = g.variants.flatMap((ref) => expandMapRef(ref, ctx.variantsByVp));
|
|
60
74
|
for (const [re, expected, label] of VP_CATEGORY_RULE) {
|
|
61
75
|
const hits = vs.filter((v) => re.test(v.vpCategory));
|
|
62
76
|
if (hits.length > 0 && g.category !== expected) {
|
|
63
|
-
|
|
64
|
-
gate: 'K', severity: 'warning', ref: g.id,
|
|
65
|
-
message: `group ${g.id} is \`category: ${g.category}\` but ${hits.length}/${vs.length} of its variants are ${label} scenarios (${hits.slice(0, 3).map((v) => v.vpId).join(', ')}) — use \`category: ${expected}\` or the Coverage grid's ${expected} column stays empty`,
|
|
66
|
-
});
|
|
77
|
+
report('matrix.gate-k.category-mismatch', 'K', `group ${g.id} is \`category: ${g.category}\` but ${hits.length}/${vs.length} of its variants are ${label} scenarios (${hits.slice(0, 3).map((v) => v.vpId).join(', ')}) — use \`category: ${expected}\` or the Coverage grid's ${expected} column stays empty`, g.id);
|
|
67
78
|
}
|
|
68
79
|
}
|
|
69
80
|
}
|
|
@@ -71,52 +82,40 @@ function gateKCategory(ctx: GateContext, findings: MatrixFinding[]): void {
|
|
|
71
82
|
|
|
72
83
|
// --- Gate A — source quality ------------------------------------------------
|
|
73
84
|
|
|
74
|
-
function gateASource(ctx: GateContext,
|
|
85
|
+
function gateASource(ctx: GateContext, report: ReportFinding): void {
|
|
75
86
|
const { feature, merged } = ctx.inputs;
|
|
76
87
|
|
|
77
88
|
if (bucketTexts(feature.backgroundOrderedSteps, 'when').length > 0 || bucketTexts(feature.backgroundOrderedSteps, 'then').length > 0) {
|
|
78
|
-
|
|
79
|
-
gate: 'A', severity: 'error',
|
|
80
|
-
message: 'Background contains When/Then steps — setup only; move the action/oracle into scenarios',
|
|
81
|
-
});
|
|
89
|
+
report('matrix.gate-a.background-when-then', 'A', 'Background contains When/Then steps — setup only; move the action/oracle into scenarios');
|
|
82
90
|
}
|
|
83
91
|
|
|
84
92
|
const seen = new Map<string, number>();
|
|
85
93
|
for (const m of merged) {
|
|
86
94
|
const { vpId } = splitVpAndName(m.feature.name);
|
|
87
95
|
if (!vpId) {
|
|
88
|
-
|
|
89
|
-
gate: 'A', severity: 'error', ref: m.feature.name,
|
|
90
|
-
message: `scenario "${m.feature.name}" has no VP-id prefix — matrix variants must be addressable`,
|
|
91
|
-
});
|
|
96
|
+
report('matrix.gate-a.no-vp-id', 'A', `scenario "${m.feature.name}" has no VP-id prefix — matrix variants must be addressable`, m.feature.name);
|
|
92
97
|
continue;
|
|
93
98
|
}
|
|
94
99
|
seen.set(vpId, (seen.get(vpId) ?? 0) + 1);
|
|
95
100
|
|
|
96
101
|
const isManual = extractTestcaseType(m.feature.tags) === 'Manual';
|
|
97
102
|
if (m.resolvedExpected.length === 0) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
? `manual scenario ${vpId} has no observable oracle (no Then steps and no Observable/Oracle comment lines)`
|
|
102
|
-
: `scenario ${vpId} has no Then step — a variant without an observable oracle cannot be delivered`,
|
|
103
|
-
});
|
|
103
|
+
report('matrix.gate-a.no-oracle', 'A', isManual
|
|
104
|
+
? `manual scenario ${vpId} has no observable oracle (no Then steps and no Observable/Oracle comment lines)`
|
|
105
|
+
: `scenario ${vpId} has no Then step — a variant without an observable oracle cannot be delivered`, vpId);
|
|
104
106
|
}
|
|
105
107
|
if (m.unlabeledManualOracle) {
|
|
106
|
-
|
|
107
|
-
gate: 'A', severity: 'warning', ref: vpId,
|
|
108
|
-
message: `manual oracle found only in an unlabeled comment — exported verbatim into Expected; write the \`# Tester verifies:\` block as numbered "N. Observable: …" lines`,
|
|
109
|
-
});
|
|
108
|
+
report('matrix.gate-a.unlabeled-manual-oracle', 'A', `manual oracle found only in an unlabeled comment — exported verbatim into Expected; write the \`# Tester verifies:\` block as numbered "N. Observable: …" lines`, vpId);
|
|
110
109
|
}
|
|
111
110
|
}
|
|
112
111
|
for (const [vpId, n] of seen) {
|
|
113
|
-
if (n > 1)
|
|
112
|
+
if (n > 1) report('matrix.gate-a.duplicate-vp-id', 'A', `duplicate VP-id ${vpId} (${n} scenarios)`, vpId);
|
|
114
113
|
}
|
|
115
114
|
}
|
|
116
115
|
|
|
117
116
|
// --- Gate B — mapping completeness -------------------------------------------
|
|
118
117
|
|
|
119
|
-
function gateBMapping(ctx: GateContext,
|
|
118
|
+
function gateBMapping(ctx: GateContext, report: ReportFinding): void {
|
|
120
119
|
const { map } = ctx.inputs;
|
|
121
120
|
const { variants, variantsByVp } = ctx;
|
|
122
121
|
|
|
@@ -126,10 +125,7 @@ function gateBMapping(ctx: GateContext, findings: MatrixFinding[]): void {
|
|
|
126
125
|
for (const ref of g.variants) {
|
|
127
126
|
const expanded = expandMapRef(ref, variantsByVp);
|
|
128
127
|
if (expanded.length === 0) {
|
|
129
|
-
|
|
130
|
-
gate: 'B', severity: 'error', ref: g.id,
|
|
131
|
-
message: `group ${g.id} references ${ref} which matches no scenario/@cases row in the .feature`,
|
|
132
|
-
});
|
|
128
|
+
report('matrix.gate-b.ref-matches-nothing', 'B', `group ${g.id} references ${ref} which matches no scenario/@cases row in the .feature`, g.id);
|
|
133
129
|
continue;
|
|
134
130
|
}
|
|
135
131
|
for (const v of expanded) {
|
|
@@ -142,10 +138,7 @@ function gateBMapping(ctx: GateContext, findings: MatrixFinding[]): void {
|
|
|
142
138
|
|
|
143
139
|
for (const [ref, groups] of owners) {
|
|
144
140
|
if (groups.length > 1) {
|
|
145
|
-
|
|
146
|
-
gate: 'B', severity: 'error', ref,
|
|
147
|
-
message: `variant ${ref} belongs to ${groups.length} groups (${groups.join(', ')}) — exactly one required`,
|
|
148
|
-
});
|
|
141
|
+
report('matrix.gate-b.double-mapped', 'B', `variant ${ref} belongs to ${groups.length} groups (${groups.join(', ')}) — exactly one required`, ref);
|
|
149
142
|
}
|
|
150
143
|
}
|
|
151
144
|
|
|
@@ -153,32 +146,23 @@ function gateBMapping(ctx: GateContext, findings: MatrixFinding[]): void {
|
|
|
153
146
|
const grouped = owners.has(v.ref);
|
|
154
147
|
const disposed = v.vpId in map.dispositions;
|
|
155
148
|
if (!grouped && !disposed) {
|
|
156
|
-
|
|
157
|
-
gate: 'B', severity: 'error', ref: v.ref,
|
|
158
|
-
message: `variant ${v.ref} is in no group and has no disposition — 100% source disposition is required`,
|
|
159
|
-
});
|
|
149
|
+
report('matrix.gate-b.unmapped', 'B', `variant ${v.ref} is in no group and has no disposition — 100% source disposition is required`, v.ref);
|
|
160
150
|
}
|
|
161
151
|
if (grouped && disposed) {
|
|
162
|
-
|
|
163
|
-
gate: 'B', severity: 'error', ref: v.ref,
|
|
164
|
-
message: `variant ${v.ref} is grouped AND disposed (${map.dispositions[v.vpId].as}) — pick one`,
|
|
165
|
-
});
|
|
152
|
+
report('matrix.gate-b.grouped-and-disposed', 'B', `variant ${v.ref} is grouped AND disposed (${map.dispositions[v.vpId].as}) — pick one`, v.ref);
|
|
166
153
|
}
|
|
167
154
|
}
|
|
168
155
|
|
|
169
156
|
for (const vpId of Object.keys(map.dispositions)) {
|
|
170
157
|
if (!variantsByVp.has(vpId)) {
|
|
171
|
-
|
|
172
|
-
gate: 'B', severity: 'warning', ref: vpId,
|
|
173
|
-
message: `disposition for ${vpId} matches no scenario (stale entry?)`,
|
|
174
|
-
});
|
|
158
|
+
report('matrix.gate-b.stale-disposition', 'B', `disposition for ${vpId} matches no scenario (stale entry?)`, vpId);
|
|
175
159
|
}
|
|
176
160
|
}
|
|
177
161
|
}
|
|
178
162
|
|
|
179
163
|
// --- Gate C — aggregation safety ---------------------------------------------
|
|
180
164
|
|
|
181
|
-
function gateCAggregation(ctx: GateContext,
|
|
165
|
+
function gateCAggregation(ctx: GateContext, report: ReportFinding): void {
|
|
182
166
|
const { map } = ctx.inputs;
|
|
183
167
|
const { variantsByVp } = ctx;
|
|
184
168
|
|
|
@@ -207,47 +191,32 @@ function gateCAggregation(ctx: GateContext, findings: MatrixFinding[]): void {
|
|
|
207
191
|
for (const [label, keyOf] of hard) {
|
|
208
192
|
const distinct = new Set(vs.map(keyOf));
|
|
209
193
|
if (distinct.size > 1) {
|
|
210
|
-
|
|
211
|
-
gate: 'C', severity: 'error', ref: g.id,
|
|
212
|
-
message: `group ${g.id} mixes ${label}s (${[...distinct].join(' vs ')}) — mandatory split`,
|
|
213
|
-
});
|
|
194
|
+
report('matrix.gate-c.mixed-layers', 'C', `group ${g.id} mixes ${label}s (${[...distinct].join(' vs ')}) — mandatory split`, g.id);
|
|
214
195
|
}
|
|
215
196
|
}
|
|
216
197
|
|
|
217
198
|
// Heuristic signature parts — REVIEW_REQUIRED (equivalence was inferred, not declared).
|
|
218
199
|
const preProfiles = new Set(vs.map((v) => v.preconditionProfile));
|
|
219
200
|
if (!heuristicsConfirmed && preProfiles.size > 1) {
|
|
220
|
-
|
|
221
|
-
gate: 'C', severity: 'review', ref: g.id,
|
|
222
|
-
message: `group ${g.id} variants have different precondition profiles — confirm the grouping is safe or split`,
|
|
223
|
-
});
|
|
201
|
+
report('matrix.gate-c.precondition-profiles', 'C', `group ${g.id} variants have different precondition profiles — confirm the grouping is safe or split`, g.id);
|
|
224
202
|
}
|
|
225
203
|
const oracleShapes = new Set(vs.map((v) => v.oracleShape.join(' ; ')));
|
|
226
204
|
if (!heuristicsConfirmed && oracleShapes.size > 1) {
|
|
227
|
-
|
|
228
|
-
gate: 'C', severity: 'review', ref: g.id,
|
|
229
|
-
message: `group ${g.id} variants assert different oracle shapes (${oracleShapes.size} shapes) — confirm they are one oracle family`,
|
|
230
|
-
});
|
|
205
|
+
report('matrix.gate-c.oracle-shapes', 'C', `group ${g.id} variants assert different oracle shapes (${oracleShapes.size} shapes) — confirm they are one oracle family`, g.id);
|
|
231
206
|
}
|
|
232
207
|
if (!heuristicsConfirmed && vs.some((v) => v.procedureProfile === 'sequence')) {
|
|
233
|
-
|
|
234
|
-
gate: 'C', severity: 'review', ref: g.id,
|
|
235
|
-
message: `group ${g.id} contains a sequence-sensitive scenario — ordered flows stay solo items unless QA confirms`,
|
|
236
|
-
});
|
|
208
|
+
report('matrix.gate-c.sequence-sensitive', 'C', `group ${g.id} contains a sequence-sensitive scenario — ordered flows stay solo items unless QA confirms`, g.id);
|
|
237
209
|
}
|
|
238
210
|
|
|
239
211
|
if (vs.length > MAX_VARIANTS_PER_ITEM) {
|
|
240
|
-
|
|
241
|
-
gate: 'C', severity: 'warning', ref: g.id,
|
|
242
|
-
message: `group ${g.id} has ${vs.length} variants (> ${MAX_VARIANTS_PER_ITEM}) — consider splitting for reviewability`,
|
|
243
|
-
});
|
|
212
|
+
report('matrix.gate-c.too-many-variants', 'C', `group ${g.id} has ${vs.length} variants (> ${MAX_VARIANTS_PER_ITEM}) — consider splitting for reviewability`, g.id);
|
|
244
213
|
}
|
|
245
214
|
}
|
|
246
215
|
}
|
|
247
216
|
|
|
248
217
|
// --- Gate D — manual executability -------------------------------------------
|
|
249
218
|
|
|
250
|
-
function gateDExecutability(ctx: GateContext,
|
|
219
|
+
function gateDExecutability(ctx: GateContext, report: ReportFinding): void {
|
|
251
220
|
const { map, testData, feature } = ctx.inputs;
|
|
252
221
|
const { variantsByVp } = ctx;
|
|
253
222
|
|
|
@@ -262,16 +231,10 @@ function gateDExecutability(ctx: GateContext, findings: MatrixFinding[]): void {
|
|
|
262
231
|
|| bucketTexts(feature.backgroundOrderedSteps, 'given').length > 0
|
|
263
232
|
|| v.apiCalls > 0;
|
|
264
233
|
if (!hasPrecondition) {
|
|
265
|
-
|
|
266
|
-
gate: 'D', severity: 'error', ref: v.ref,
|
|
267
|
-
message: `${v.ref}: no precondition (no Background, auth tag, or Given) — a tester cannot establish the start state`,
|
|
268
|
-
});
|
|
234
|
+
report('matrix.gate-d.no-precondition', 'D', `${v.ref}: no precondition (no Background, auth tag, or Given) — a tester cannot establish the start state`, v.ref);
|
|
269
235
|
}
|
|
270
236
|
if (v.trigger.length === 0) {
|
|
271
|
-
|
|
272
|
-
gate: 'D', severity: 'error', ref: v.ref,
|
|
273
|
-
message: `${v.ref}: no action/trigger (no When steps${v.mode === 'manual' ? ' and no Setup/Action comment lines' : ''})`,
|
|
274
|
-
});
|
|
237
|
+
report('matrix.gate-d.no-trigger', 'D', `${v.ref}: no action/trigger (no When steps${v.mode === 'manual' ? ' and no Setup/Action comment lines' : ''})`, v.ref);
|
|
275
238
|
}
|
|
276
239
|
// Oracle emptiness is Gate A (source) — not repeated here.
|
|
277
240
|
}
|
|
@@ -289,10 +252,7 @@ function gateDExecutability(ctx: GateContext, findings: MatrixFinding[]): void {
|
|
|
289
252
|
const inRows = vs.some((v) => v.caseLabel !== undefined); // dataset rows carry their own columns
|
|
290
253
|
const atRuntime = runtime.has(varName) || runtime.has(varName.split(/[.[]/)[0]);
|
|
291
254
|
if (!inRows && !atRuntime && (!testData || !(varName in testData))) {
|
|
292
|
-
|
|
293
|
-
gate: 'D', severity: 'error', ref: vpId,
|
|
294
|
-
message: `${vpId}: {{${varName}}} does not resolve in test-data — the variant is not reproducible`,
|
|
295
|
-
});
|
|
255
|
+
report('matrix.gate-d.unresolved-var', 'D', `${vpId}: {{${varName}}} does not resolve in test-data — the variant is not reproducible`, vpId);
|
|
296
256
|
}
|
|
297
257
|
}
|
|
298
258
|
}
|
|
@@ -304,10 +264,7 @@ function gateDExecutability(ctx: GateContext, findings: MatrixFinding[]): void {
|
|
|
304
264
|
const rendered = [...v.precondition, ...v.trigger, ...v.oracle, ...v.verification, ...v.data];
|
|
305
265
|
const token = rendered.map((t) => t.match(/\{\{[^}]*\}\}/)).find(Boolean);
|
|
306
266
|
if (token) {
|
|
307
|
-
|
|
308
|
-
gate: 'D', severity: 'error', ref: v.ref,
|
|
309
|
-
message: `${v.ref}: unresolved template token ${token[0]} remains in the rendered output — the export is not deterministic for a tester`,
|
|
310
|
-
});
|
|
267
|
+
report('matrix.gate-d.template-token-remains', 'D', `${v.ref}: unresolved template token ${token[0]} remains in the rendered output — the export is not deterministic for a tester`, v.ref);
|
|
311
268
|
}
|
|
312
269
|
}
|
|
313
270
|
}
|
|
@@ -315,7 +272,7 @@ function gateDExecutability(ctx: GateContext, findings: MatrixFinding[]): void {
|
|
|
315
272
|
|
|
316
273
|
// --- Gate E — drift (stale approval) ------------------------------------------
|
|
317
274
|
|
|
318
|
-
function gateEDrift(ctx: GateContext,
|
|
275
|
+
function gateEDrift(ctx: GateContext, report: ReportFinding): void {
|
|
319
276
|
const { map } = ctx.inputs;
|
|
320
277
|
const { variantsByVp } = ctx;
|
|
321
278
|
|
|
@@ -326,15 +283,9 @@ function gateEDrift(ctx: GateContext, findings: MatrixFinding[]): void {
|
|
|
326
283
|
const liveMap = mapContentFingerprint(map.groups, map.dispositions);
|
|
327
284
|
if (map.groups.some((g) => g.review === 'approved')) {
|
|
328
285
|
if (!stampedMap) {
|
|
329
|
-
|
|
330
|
-
gate: 'E', severity: 'review',
|
|
331
|
-
message: 'the delivery map has no stamped content fingerprint — run `sungen delivery --approve` to record the reviewed wording',
|
|
332
|
-
});
|
|
286
|
+
report('matrix.gate-e.map-unstamped', 'E', 'the delivery map has no stamped content fingerprint — run `sungen delivery --approve` to record the reviewed wording');
|
|
333
287
|
} else if (stampedMap !== liveMap) {
|
|
334
|
-
|
|
335
|
-
gate: 'E', severity: 'review',
|
|
336
|
-
message: 'the delivery map wording/grouping changed since approval — re-review, then `sungen delivery --approve`',
|
|
337
|
-
});
|
|
288
|
+
report('matrix.gate-e.map-drift', 'E', 'the delivery map wording/grouping changed since approval — re-review, then `sungen delivery --approve`');
|
|
338
289
|
}
|
|
339
290
|
}
|
|
340
291
|
|
|
@@ -345,15 +296,9 @@ function gateEDrift(ctx: GateContext, findings: MatrixFinding[]): void {
|
|
|
345
296
|
for (const v of vs) {
|
|
346
297
|
const stamped = map.fingerprints[v.ref] ?? map.fingerprints[v.vpId];
|
|
347
298
|
if (!stamped) {
|
|
348
|
-
|
|
349
|
-
gate: 'E', severity: 'review', ref: g.id,
|
|
350
|
-
message: `group ${g.id}: ${v.ref} has no stamped fingerprint — run \`sungen delivery --approve\` after review`,
|
|
351
|
-
});
|
|
299
|
+
report('matrix.gate-e.variant-unstamped', 'E', `group ${g.id}: ${v.ref} has no stamped fingerprint — run \`sungen delivery --approve\` after review`, g.id);
|
|
352
300
|
} else if (stamped !== v.fingerprint) {
|
|
353
|
-
|
|
354
|
-
gate: 'E', severity: 'review', ref: g.id,
|
|
355
|
-
message: `group ${g.id}: ${v.ref} changed since approval (fingerprint drift) — re-review the grouping`,
|
|
356
|
-
});
|
|
301
|
+
report('matrix.gate-e.variant-drift', 'E', `group ${g.id}: ${v.ref} changed since approval (fingerprint drift) — re-review the grouping`, g.id);
|
|
357
302
|
}
|
|
358
303
|
}
|
|
359
304
|
}
|
|
@@ -370,30 +315,21 @@ const WORDING_SMELLS: Array<[RegExp, string]> = [
|
|
|
370
315
|
[/\[[^\]]+\]/, 'a [selector-style] reference — use the visible UI label'],
|
|
371
316
|
];
|
|
372
317
|
|
|
373
|
-
function gateWWording(ctx: GateContext,
|
|
318
|
+
function gateWWording(ctx: GateContext, report: ReportFinding): void {
|
|
374
319
|
for (const g of ctx.inputs.map.groups) {
|
|
375
320
|
const variantCount = g.variants.flatMap((ref) => expandMapRef(ref, ctx.variantsByVp)).length;
|
|
376
321
|
// Without a digest the parent row can only list variant refs — a reviewer
|
|
377
322
|
// then has to expand the item to learn which dimensions it covers.
|
|
378
323
|
if (variantCount > 3 && !g.dimensions) {
|
|
379
|
-
|
|
380
|
-
gate: 'W', severity: 'warning', ref: g.id,
|
|
381
|
-
message: `group ${g.id} has ${variantCount} variants and no \`dimensions:\` digest — add a short one (e.g. "required ×3 · format ×9") so the collapsed view stays informative`,
|
|
382
|
-
});
|
|
324
|
+
report('matrix.gate-w.dimensions-missing', 'W', `group ${g.id} has ${variantCount} variants and no \`dimensions:\` digest — add a short one (e.g. "required ×3 · format ×9") so the collapsed view stays informative`, g.id);
|
|
383
325
|
}
|
|
384
326
|
if (g.dimensions && g.dimensions.length > 120) {
|
|
385
|
-
|
|
386
|
-
gate: 'W', severity: 'warning', ref: g.id,
|
|
387
|
-
message: `group ${g.id} \`dimensions:\` is ${g.dimensions.length} chars — keep the digest short (≤120)`,
|
|
388
|
-
});
|
|
327
|
+
report('matrix.gate-w.dimensions-long', 'W', `group ${g.id} \`dimensions:\` is ${g.dimensions.length} chars — keep the digest short (≤120)`, g.id);
|
|
389
328
|
}
|
|
390
329
|
for (const [field, text] of ([['intent', g.intent], ['oracle', g.oracle], ...(g.dimensions ? [['dimensions', g.dimensions] as const] : [])] as const)) {
|
|
391
330
|
for (const [re, what] of WORDING_SMELLS) {
|
|
392
331
|
if (re.test(text)) {
|
|
393
|
-
|
|
394
|
-
gate: 'W', severity: 'warning', ref: g.id,
|
|
395
|
-
message: `group ${g.id} ${field} contains ${what}`,
|
|
396
|
-
});
|
|
332
|
+
report('matrix.gate-w.wording-smell', 'W', `group ${g.id} ${field} contains ${what}`, g.id);
|
|
397
333
|
}
|
|
398
334
|
}
|
|
399
335
|
}
|
|
@@ -402,12 +338,9 @@ function gateWWording(ctx: GateContext, findings: MatrixFinding[]): void {
|
|
|
402
338
|
|
|
403
339
|
// --- Gate G — review state -----------------------------------------------------
|
|
404
340
|
|
|
405
|
-
function gateGReviewState(ctx: GateContext,
|
|
341
|
+
function gateGReviewState(ctx: GateContext, report: ReportFinding): void {
|
|
406
342
|
const proposed = ctx.inputs.map.groups.filter((g) => g.review !== 'approved');
|
|
407
343
|
if (proposed.length > 0) {
|
|
408
|
-
|
|
409
|
-
gate: 'G', severity: 'review',
|
|
410
|
-
message: `${proposed.length} group(s) still \`proposed\` (${proposed.slice(0, 5).map((g) => g.id).join(', ')}${proposed.length > 5 ? ', …' : ''}) — approve them or render with --preview`,
|
|
411
|
-
});
|
|
344
|
+
report('matrix.gate-g.groups-proposed', 'G', `${proposed.length} group(s) still \`proposed\` (${proposed.slice(0, 5).map((g) => g.id).join(', ')}${proposed.length > 5 ? ', …' : ''}) — approve them or render with --preview`);
|
|
412
345
|
}
|
|
413
346
|
}
|
|
@@ -11,6 +11,7 @@ import { variantState } from './build';
|
|
|
11
11
|
import { coverageSummary, itemModeLabel, itemResultLabel } from './render-xlsx';
|
|
12
12
|
import { MatrixModel } from './types';
|
|
13
13
|
import { formatTestOutcome, resultTotals } from './result-totals';
|
|
14
|
+
import { overrideManifestLines } from '../../harness/gates/gate-override-report';
|
|
14
15
|
|
|
15
16
|
const HEADERS = [
|
|
16
17
|
'Level', 'ID', 'Target', 'Test Intent / Condition', 'Category', 'Priority',
|
|
@@ -36,6 +37,8 @@ export function renderMatrixCsv(model: MatrixModel): string {
|
|
|
36
37
|
lines.push(`# Test Case & Coverage Matrix — ${model.unit}`);
|
|
37
38
|
// Two different facts, two different words: the map's design REVIEW state, and the runs' OUTCOME.
|
|
38
39
|
lines.push(`# delivery items: ${model.manifest.itemCount} · coverage variants: ${model.manifest.variantCount} · review: ${model.manifest.approvalState} (design) · test outcome: ${formatTestOutcome(resultTotals(model.items))}`);
|
|
40
|
+
// OES-11.6: a CSV-only reader still learns which client-visible gate overrides the delivery leaned on.
|
|
41
|
+
lines.push(...overrideManifestLines(model.gateOverrides));
|
|
39
42
|
lines.push(HEADERS.map(esc).join(','));
|
|
40
43
|
|
|
41
44
|
for (const item of model.items) {
|
|
@@ -78,7 +81,7 @@ export function renderMatrixCsv(model: MatrixModel): string {
|
|
|
78
81
|
v.mode === 'manual' ? 'Manual' : 'Auto',
|
|
79
82
|
v.traces.join(' '),
|
|
80
83
|
variantState(v),
|
|
81
|
-
isoDate(v.result?.startTime),
|
|
84
|
+
v.manualDate ?? isoDate(v.result?.startTime),
|
|
82
85
|
// Redact BEFORE clipping — a clip boundary must never split a secret in
|
|
83
86
|
// a way that lets its prefix through. Same denylist as the Note column.
|
|
84
87
|
v.result?.error ? clipNoteField(redactSecrets(String(v.result.error), model.secretValues)) : '',
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sheet 5 — "Gate overrides" (OES-11.6): which quality gate a human relaxed for this unit, why, and
|
|
3
|
+
* whether the delivery leaned on it (`PASS (overridden)`). Present only when a gate-override touches
|
|
4
|
+
* the unit, so a workbook without overrides is unchanged.
|
|
5
|
+
*
|
|
6
|
+
* `visibility: internal` decisions never reach this sheet — the model carries only client-visible
|
|
7
|
+
* rows plus a count of the withheld ones (red-team #14).
|
|
8
|
+
*/
|
|
9
|
+
import * as ExcelJS from 'exceljs';
|
|
10
|
+
import { MatrixModel } from './types';
|
|
11
|
+
import { dataCell, headerCell } from './xlsx-cells';
|
|
12
|
+
|
|
13
|
+
export const GATE_OVERRIDES_SHEET = 'Gate overrides';
|
|
14
|
+
|
|
15
|
+
const COLUMNS: Array<{ label: string; width: number }> = [
|
|
16
|
+
{ label: 'Rule', width: 34 }, { label: 'Catalog level', width: 13 }, { label: 'Override level', width: 14 },
|
|
17
|
+
{ label: 'Scope', width: 22 }, { label: 'Status', width: 12 }, { label: 'Changed an outcome', width: 12 },
|
|
18
|
+
{ label: 'Reason', width: 60 }, { label: 'Decision', width: 20 }, { label: 'Recorded by', width: 18 }, { label: 'Recorded at', width: 24 },
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export function addGateOverridesSheet(wb: ExcelJS.Workbook, model: MatrixModel): void {
|
|
22
|
+
const o = model.gateOverrides;
|
|
23
|
+
if (!o) return;
|
|
24
|
+
const ws = wb.addWorksheet(GATE_OVERRIDES_SHEET);
|
|
25
|
+
COLUMNS.forEach((c, i) => { ws.getColumn(i + 1).width = c.width; });
|
|
26
|
+
ws.getCell('A1').value = 'Gate status';
|
|
27
|
+
ws.getCell('A1').font = { bold: true };
|
|
28
|
+
ws.getCell('B1').value = o.status;
|
|
29
|
+
ws.getCell('B1').font = { bold: true };
|
|
30
|
+
ws.getCell('A2').value = 'Internal decisions (counted, not listed)';
|
|
31
|
+
ws.getCell('B2').value = o.internalCount;
|
|
32
|
+
const header = ws.getRow(4);
|
|
33
|
+
COLUMNS.forEach((c, i) => headerCell(header.getCell(i + 1), c.label));
|
|
34
|
+
o.rows.forEach((r, n) => {
|
|
35
|
+
const row = ws.getRow(5 + n);
|
|
36
|
+
[r.rule, r.catalogSeverity ?? '', r.severity, r.scope, r.status, r.triggered ? 'yes' : 'no', r.reason, r.decisionId, r.by, r.validFrom]
|
|
37
|
+
.forEach((v, i) => dataCell(row.getCell(i + 1), v));
|
|
38
|
+
});
|
|
39
|
+
let next = 5 + o.rows.length;
|
|
40
|
+
if (o.rows.length === 0) ws.getCell(`A${next++}`).value = 'No client-visible gate override.';
|
|
41
|
+
const a = o.acceptedInRun;
|
|
42
|
+
if (a) {
|
|
43
|
+
// L5: who accepted decisions recorded during the run, on a terminal, for this delivery.
|
|
44
|
+
ws.getCell(`A${next + 1}`).value = 'In-run decisions accepted';
|
|
45
|
+
ws.getCell(`A${next + 1}`).font = { bold: true };
|
|
46
|
+
ws.getCell(`B${next + 1}`).value = `by ${a.by} at ${a.at}`;
|
|
47
|
+
ws.getCell(`A${next + 2}`).value = 'Decisions';
|
|
48
|
+
ws.getCell(`B${next + 2}`).value = [a.ids.join(', '), a.internalCount ? `${a.internalCount} internal (ids withheld)` : ''].filter(Boolean).join(' · ') || '—';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -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. */
|
|
@@ -49,7 +49,7 @@ export function draftBanner(ws: ExcelJS.Worksheet, model: MatrixModel): void {
|
|
|
49
49
|
if (model.manifest.approvalState !== 'draft') return;
|
|
50
50
|
ws.mergeCells('A5:H5');
|
|
51
51
|
const c = ws.getCell('A5');
|
|
52
|
-
c.value = 'DRAFT — NOT APPROVED FOR OFFICIAL DELIVERY (review-required findings
|
|
52
|
+
c.value = 'DRAFT — NOT APPROVED FOR OFFICIAL DELIVERY (review-required findings, proposed groups, or an audit that does not pass)';
|
|
53
53
|
c.font = { bold: true, size: 11, name: ARIAL_FONT, color: { argb: 'FFFFFFFF' } };
|
|
54
54
|
c.fill = { type: 'pattern', pattern: 'solid', fgColor: DRAFT_RED };
|
|
55
55
|
c.alignment = { horizontal: 'center', vertical: 'middle' };
|
|
@@ -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);
|