@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
|
@@ -0,0 +1,66 @@
|
|
|
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, except a
|
|
8
|
+
* node's instances that `surfacesPastCut` (a hard contract verdict, #940), which follow
|
|
9
|
+
* the cutting step and never cut themselves
|
|
10
|
+
*
|
|
11
|
+
* `--case <id>` (`testCase` option): the frontier is that case's test-case nodes plus the blocking
|
|
12
|
+
* unit nodes before them; non-blocking unit advice is left to the unit view. A `caseOnly` test-case
|
|
13
|
+
* node speaks only there (its unit-level decision is in the unit view already).
|
|
14
|
+
*/
|
|
15
|
+
import type { NextStep, UnitState } from '../harness/next-step';
|
|
16
|
+
import type { NodeDecl, StepCore } from './node-decl';
|
|
17
|
+
import type { TestCaseState } from './test-case-state-shape';
|
|
18
|
+
|
|
19
|
+
export interface EvaluateOptions {
|
|
20
|
+
/** Only this test case's nodes (plus the blocking unit nodes before them). */
|
|
21
|
+
testCase?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function withMeta(node: NodeDecl, core: StepCore, testCase?: string): NextStep {
|
|
25
|
+
return {
|
|
26
|
+
...core,
|
|
27
|
+
nodeId: node.id,
|
|
28
|
+
granularity: node.granularity,
|
|
29
|
+
...(testCase ? { testCase } : {}),
|
|
30
|
+
...(node.gates.length ? { gates: [...node.gates] } : {}),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** The cases open at a test-case node, in their given order; none without test-case states. */
|
|
35
|
+
function openCases(node: NodeDecl, s: UnitState, tcStates: TestCaseState[] | undefined, only?: string): TestCaseState[] {
|
|
36
|
+
if (node.granularity !== 'test-case' || !tcStates) return [];
|
|
37
|
+
return tcStates.filter((tc) => (!only || tc.id === only) && node.active(s, tc) && !node.satisfied(s, tc));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function evaluateGraph(
|
|
41
|
+
nodes: readonly NodeDecl[], s: UnitState, tcStates?: TestCaseState[], opts: EvaluateOptions = {},
|
|
42
|
+
): NextStep[] {
|
|
43
|
+
const ordered = [...nodes].sort((a, b) => a.rank - b.rank);
|
|
44
|
+
const open = new Set<string>();
|
|
45
|
+
const out: NextStep[] = [];
|
|
46
|
+
let cut = false;
|
|
47
|
+
for (const node of ordered) {
|
|
48
|
+
if (!node.appliesTo.includes(s.kind) || (node.granularity === 'test-case' && node.caseOnly && !opts.testCase)) continue;
|
|
49
|
+
if (cut && !node.surfacesPastCut) continue;
|
|
50
|
+
let step: NextStep | null = null;
|
|
51
|
+
if (node.granularity === 'unit') {
|
|
52
|
+
if (!node.active(s) || node.satisfied(s) || (cut && !node.surfacesPastCut!(s))) continue;
|
|
53
|
+
if (!opts.testCase || node.blocking) step = withMeta(node, node.step(s));
|
|
54
|
+
} else {
|
|
55
|
+
const cases = openCases(node, s, tcStates, opts.testCase).filter((tc) => !cut || node.surfacesPastCut!(s, tc));
|
|
56
|
+
if (!cases.length) continue;
|
|
57
|
+
const single = Boolean(opts.testCase);
|
|
58
|
+
step = withMeta(node, node.step(s, cases, single), single ? cases[0].id : undefined);
|
|
59
|
+
}
|
|
60
|
+
open.add(node.id);
|
|
61
|
+
const ready = node.requires.every((r) => !open.has(r));
|
|
62
|
+
if (step && (cut || ready || !node.blocking)) out.push(step);
|
|
63
|
+
if (node.blocking && !cut) cut = true;
|
|
64
|
+
}
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
@@ -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,72 @@
|
|
|
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
|
+
* Offered even when a blocking node ranked before it cut the walk — only while this holds (#940: a
|
|
47
|
+
* hard contract verdict must not hide behind a stale or failing audit). It never cuts by itself.
|
|
48
|
+
*/
|
|
49
|
+
surfacesPastCut?(s: UnitState): boolean;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface TestCaseNodeDecl extends NodeDeclBase {
|
|
53
|
+
granularity: 'test-case';
|
|
54
|
+
/**
|
|
55
|
+
* Speaks only under `--case <id>`: the unit view already carries the decision at unit level (the
|
|
56
|
+
* contract's unit.contract-approve), so folding the cases there would say it twice.
|
|
57
|
+
*/
|
|
58
|
+
caseOnly?: true;
|
|
59
|
+
active(s: UnitState, tc: TestCaseState): boolean;
|
|
60
|
+
satisfied(s: UnitState, tc: TestCaseState): boolean;
|
|
61
|
+
/** One step for `cases` (all open at this node): a unit-level fold, or exactly one case when `single`. */
|
|
62
|
+
step(s: UnitState, cases: TestCaseState[], single: boolean): StepCore;
|
|
63
|
+
/** The cases offered even past a cut (see UnitNodeDecl.surfacesPastCut). */
|
|
64
|
+
surfacesPastCut?(s: UnitState, tc: TestCaseState): boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export type NodeDecl = UnitNodeDecl | TestCaseNodeDecl;
|
|
68
|
+
|
|
69
|
+
/** `qa/<dir>/<unit>` for the unit kind, as the steps name it. */
|
|
70
|
+
export const unitKindDir = (kind: UnitKind): string => (kind === 'screen' ? 'screens' : kind === 'flow' ? 'flows' : 'api');
|
|
71
|
+
|
|
72
|
+
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,74 @@
|
|
|
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
|
+
* tc.contract-check (a weaker / retargeted / lost check, or an uncommitted lock entry) and tc.unproven
|
|
15
|
+
* are hard verdicts: they are offered past a stale or failing audit (the cut at unit.audit-stale /
|
|
16
|
+
* unit.gate-fail), #940; tc.contract-approve (changed, not weaker) is review and waits behind it. Exempt cases (DOS-11.2) open nothing. A proposed case (never approved) asks nothing of its own: a
|
|
17
|
+
* compiled test without a lock is never blocked, and the unit view offers the approval.
|
|
18
|
+
*/
|
|
19
|
+
import { ALL_KINDS, StepCore, TestCaseNodeDecl } from '../node-decl';
|
|
20
|
+
import type { UnitState } from '../../harness/next-step';
|
|
21
|
+
import type { TestCaseState } from '../test-case-state-shape';
|
|
22
|
+
import { exemptionOf } from '../test-case-satisfied';
|
|
23
|
+
import { idsArg, listed } from './test-case-nodes';
|
|
24
|
+
|
|
25
|
+
type Step = (s: UnitState, cases: TestCaseState[], single: boolean) => StepCore;
|
|
26
|
+
const HARD_LADDER = new Set(['oracle-weakened', 'target-changed', 'assertion-lost']);
|
|
27
|
+
const classOf = (tc: TestCaseState): string | undefined => tc.contract?.class;
|
|
28
|
+
/** Up to three cases with the finding behind each. */
|
|
29
|
+
const withDetail = (cases: TestCaseState[]): string =>
|
|
30
|
+
`${cases.slice(0, 3).map((c) => (c.contract?.detail ? `${c.id}: ${c.contract.detail}` : c.id)).join('; ')}${cases.length > 3 ? '; …' : ''}`;
|
|
31
|
+
const check = (s: UnitState, trace = false): string => `sungen contract check --screen ${s.unit}${trace ? ' --trace' : ''}`;
|
|
32
|
+
|
|
33
|
+
function contractNode(id: string, rank: number, title: string, actor: TestCaseNodeDecl['actor'], gates: string[], caseOnly: boolean,
|
|
34
|
+
active: (tc: TestCaseState) => boolean, step: Step, hard?: (tc: TestCaseState) => boolean): TestCaseNodeDecl {
|
|
35
|
+
return {
|
|
36
|
+
id, title, actor, granularity: 'test-case', appliesTo: ALL_KINDS, blocking: false, rank, gates, step,
|
|
37
|
+
requires: caseOnly ? ['unit.gate-fail'] : ['unit.run'], produces: ['contracts.lock.yaml', 'decisions/<id>.yaml'],
|
|
38
|
+
...(caseOnly ? { caseOnly: true as const } : {}),
|
|
39
|
+
active: (_s, tc) => active(tc),
|
|
40
|
+
satisfied: (_s, tc) => exemptionOf(tc) !== null,
|
|
41
|
+
...(hard ? { surfacesPastCut: (_s: UnitState, tc: TestCaseState) => hard(tc) } : {}),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const conformanceStep: Step = (s, cases) => {
|
|
46
|
+
const low = cases.filter((c) => c.contract?.lowIdentity);
|
|
47
|
+
if (low.length) {
|
|
48
|
+
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` };
|
|
49
|
+
}
|
|
50
|
+
const failed = cases.filter((c) => classOf(c) === 'inconclusive');
|
|
51
|
+
if (failed.length) {
|
|
52
|
+
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)}\`` };
|
|
53
|
+
}
|
|
54
|
+
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` };
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const TEST_CASE_CONTRACT_NODES: readonly TestCaseNodeDecl[] = [
|
|
58
|
+
contractNode('tc.contract-approve', 106, 'Re-approve this changed case', 'human', ['contract.hash-changed'], true,
|
|
59
|
+
(tc) => classOf(tc) === 'hash-changed' && !tc.contract?.uncommitted,
|
|
60
|
+
(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` })),
|
|
61
|
+
contractNode('tc.contract-check', 107, 'Restore the approved check of this case', 'human',
|
|
62
|
+
['contract.oracle-weakened', 'contract.target-changed', 'contract.assertion-lost', 'contract.lock-uncommitted'], true,
|
|
63
|
+
(tc) => Boolean(tc.contract?.uncommitted) || HARD_LADDER.has(classOf(tc) ?? ''),
|
|
64
|
+
(s, [c]) => ({ kind: 'blocked', command: check(s), because: c.contract?.uncommitted
|
|
65
|
+
? `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`
|
|
66
|
+
: `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` }),
|
|
67
|
+
(tc) => Boolean(tc.contract?.uncommitted) || HARD_LADDER.has(classOf(tc) ?? '')),
|
|
68
|
+
contractNode('tc.unproven', 136, 'Prove the approved free cases with a trace', 'ai', ['contract.unproven'], false,
|
|
69
|
+
(tc) => classOf(tc) === 'unproven',
|
|
70
|
+
(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` }),
|
|
71
|
+
(tc) => classOf(tc) === 'unproven'),
|
|
72
|
+
contractNode('tc.conformance', 138, 'Settle the traces in review', 'ai', ['contract.opaque-step', 'contract.inconclusive'], false,
|
|
73
|
+
(tc) => classOf(tc) === 'opaque' || classOf(tc) === 'inconclusive', conformanceStep),
|
|
74
|
+
];
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-case nodes (OES-10.3) — added after parity, as an intentional output change. Each judges one
|
|
3
|
+
* case at a time; the cases open at a node fold into ONE step at unit level ("N test case(s) …"),
|
|
4
|
+
* and `sungen next <unit> --case <id>` shows the one case's step. Satisfied semantics: DOS-11.2
|
|
5
|
+
* (test-case-satisfied.ts) — exempt cases never open a node.
|
|
6
|
+
*
|
|
7
|
+
* tc.run never run (a case added after the run) do run-test --ids
|
|
8
|
+
* tc.rerun-stale changed after the recorded run (run manifest) do run-test --change-only
|
|
9
|
+
* tc.triage red, not classified by a current triage do sungen triage
|
|
10
|
+
* tc.product-candidate triage found a product-defect candidate decide sungen defect draft
|
|
11
|
+
* They sit after unit.run (which cuts a unit that never ran) and before delivery. tc.triage takes
|
|
12
|
+
* the reds the cases account for; unit.triage keeps the rest (unattributedReds), so a red no case
|
|
13
|
+
* explains — an @cases row, a renamed scenario, a nested describe title — still gets a triage step.
|
|
14
|
+
*/
|
|
15
|
+
import { ALL_KINDS, StepCore, TestCaseNodeDecl } from '../node-decl';
|
|
16
|
+
import type { UnitState } from '../../harness/next-step';
|
|
17
|
+
import type { TestCaseState } from '../test-case-state-shape';
|
|
18
|
+
import { exemptionOf, TestCaseNeed, triggerOf } from '../test-case-satisfied';
|
|
19
|
+
|
|
20
|
+
const MAX_IDS = 10;
|
|
21
|
+
export const listed = (cases: TestCaseState[]): string => `${cases.slice(0, 4).map((c) => c.id).join(', ')}${cases.length > 4 ? ', …' : ''}`;
|
|
22
|
+
/** `--ids` only names cases `sungen select` can resolve: stable ids, a short list. */
|
|
23
|
+
export const idsArg = (cases: TestCaseState[]): string =>
|
|
24
|
+
(cases.length <= MAX_IDS && cases.every((c) => !c.unstableId) ? ` --ids ${cases.map((c) => c.id).join(',')}` : '');
|
|
25
|
+
const flag = (s: UnitState): string => (s.kind === 'api' ? '--api' : '--screen');
|
|
26
|
+
|
|
27
|
+
function caseNode(id: string, need: TestCaseNeed, rank: number, title: string, actor: TestCaseNodeDecl['actor'],
|
|
28
|
+
step: (s: UnitState, cases: TestCaseState[], single: boolean) => StepCore, produces: string[]): TestCaseNodeDecl {
|
|
29
|
+
return {
|
|
30
|
+
id, title, actor, granularity: 'test-case', appliesTo: ALL_KINDS, requires: ['unit.run'], blocking: false, rank,
|
|
31
|
+
gates: [], produces, step,
|
|
32
|
+
active: (_s, tc) => triggerOf(tc) === need,
|
|
33
|
+
satisfied: (_s, tc) => exemptionOf(tc) !== null,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const TEST_CASE_NODES: readonly TestCaseNodeDecl[] = [
|
|
38
|
+
caseNode('tc.run', 'run', 131, 'Run the cases that never ran', 'ai', (s, cases) => ({
|
|
39
|
+
kind: 'do',
|
|
40
|
+
command: `/sungen:run-test ${s.unit}${idsArg(cases)}`,
|
|
41
|
+
because: `${cases.length} test case(s) have never run (${listed(cases)}) — their rows read Pending in the deliverable`,
|
|
42
|
+
}), ['specs/generated/<unit>/<unit>-test-result.json']),
|
|
43
|
+
caseNode('tc.rerun-stale', 'rerun-stale', 132, 'Re-run the cases that changed after their run', 'ai', (s, cases, single) => ({
|
|
44
|
+
kind: 'do',
|
|
45
|
+
command: single && idsArg(cases) ? `/sungen:run-test ${s.unit}${idsArg(cases)}` : `/sungen:run-test ${s.unit} --change-only`,
|
|
46
|
+
because: `${cases.length} test case(s) changed after the run that produced their result (${cases.slice(0, 3).map((c) => `${c.id}: ${c.stale}`).join('; ')}${cases.length > 3 ? '; …' : ''}) — that result no longer describes the scenario`,
|
|
47
|
+
}), ['specs/generated/<unit>/<unit>-test-result.json', '.sungen/run-manifest/<unit>.json']),
|
|
48
|
+
caseNode('tc.triage', 'triage', 133, 'Classify the red cases', 'deterministic', (s, cases) => {
|
|
49
|
+
const left = cases.filter((c) => c.triage?.class === 'unclassified').length;
|
|
50
|
+
return {
|
|
51
|
+
kind: 'do',
|
|
52
|
+
command: `sungen triage ${flag(s)} ${s.unit}`,
|
|
53
|
+
because: `${cases.length} test case(s) failed in the latest run and are not classified yet${left ? ` (${left} left unclassified by the last triage — read its evidence and classify by hand)` : ''} — classify each (known defect, test defect, environment, product candidate) before exporting or extending: an unexplained red in the deliverable is a finding nobody has judged`,
|
|
54
|
+
};
|
|
55
|
+
}, ['.sungen/triage/<unit>.json']),
|
|
56
|
+
caseNode('tc.product-candidate', 'product-candidate', 134, 'Decide on the product-defect candidates', 'human', (s, cases, single) => ({
|
|
57
|
+
kind: 'decide',
|
|
58
|
+
command: `sungen defect draft ${flag(s)} ${s.unit}${single ? ` --scenario ${cases[0].id}` : ''}`,
|
|
59
|
+
because: `${cases.length} red test case(s) look like a product defect (${listed(cases)}) — the app answered and the answer differs from the oracle. A QA decides whether it is a defect to record; an agent presents it and does not draft it on its own`,
|
|
60
|
+
}), ['qa/defects/DEF-<n>-<slug>.md']),
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
/** Red final attempts the test cases account for (a case read without the count stands for one). */
|
|
64
|
+
export const attributedReds = (s: UnitState): number =>
|
|
65
|
+
(s.testCases ?? []).reduce((n, tc) => n + (tc.failedResults ?? (tc.result === 'failed' ? 1 : 0)), 0);
|
|
66
|
+
|
|
67
|
+
/** The reds unit.triage still owns: all of them without test-case states, else those no case accounts for. */
|
|
68
|
+
export const unattributedReds = (s: UnitState): number => (s.failedCount ?? 0) - (s.testCases ? attributedReds(s) : 0);
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit-stage unit nodes — rows 7–10 of the OES-10.2 parity table (exact words of the frozen oracle).
|
|
3
|
+
*
|
|
4
|
+
* 7 unit.audit-missing never audited → `sungen audit`, cuts
|
|
5
|
+
* 7 unit.audit-stale a report that does not count (stale, untrusted) → re-audit, cuts (OES-10.3,
|
|
6
|
+
* phase 05: the report is read through verifyAuditReport, as gate and delivery do)
|
|
7
|
+
* 8 unit.baseline-changed viewpoint baseline moved → `--accept-viewpoint`, a QA DECISION (#660)
|
|
8
|
+
* 9 unit.repair-findings findings with a known repair → repair + re-audit, names ≤ 4 codes
|
|
9
|
+
* 10 unit.gate-fail gateStatus FAIL → blocked, cuts
|
|
10
|
+
*/
|
|
11
|
+
import { ALL_KINDS, UnitNodeDecl } from '../node-decl';
|
|
12
|
+
import type { UnitState } from '../../harness/next-step';
|
|
13
|
+
|
|
14
|
+
/** The finding codes worth naming in a next step — each maps to a specific repair. */
|
|
15
|
+
export const REPAIRABLE: readonly string[] = [
|
|
16
|
+
'FLOW-CONTRACT-MISSING', 'FLOW-INVENTORY-MISSING', 'FLOW-UNCOVERED', 'FLOW-UNDECLARED',
|
|
17
|
+
'FLOW-PHASE-MISFILED', 'FLOW-GUARANTEE-MISSING', 'FLOW-OUTCOME-UNPROVEN', 'CONTINUITY-ONE-SIDED',
|
|
18
|
+
'ORACLE-URL-ONLY',
|
|
19
|
+
'SPEC-RESTATED-UNVERIFIED', 'VIEWPOINT-GESTURE-SUBSTITUTED', 'SPEC-UNCOVERED', 'SPEC-CLAUSE-UNCOVERED',
|
|
20
|
+
'TRIGGER-UNCOVERED', 'PERMISSION-PAIR-MISSING', 'VISIBILITY-PAIR-MISSING',
|
|
21
|
+
'VIEWPOINT-ITEM-MISSING', 'MANUAL-CODE-MISSING', 'MANUAL-AUTOMATABLE', 'DEPTH-DEFERRED',
|
|
22
|
+
'UI-INVENTORY-MISSING', 'UI-INVENTORY-INCOMPLETE', 'UI-ITEM-UNCOVERED',
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
/** The repairable codes of the audit's findings, in finding order, duplicates kept (they are counted). */
|
|
26
|
+
export function repairableCodes(s: UnitState): string[] {
|
|
27
|
+
return (s.audit?.findings ?? [])
|
|
28
|
+
.map((f) => f.split(':')[0].trim())
|
|
29
|
+
.filter((code) => REPAIRABLE.includes(code));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** The rules whose conjunction is the audit's gateStatus (audit-gate-terms.ts). */
|
|
33
|
+
const AUDIT_GATE_RULES = ['audit.viewpoint-coverage', 'audit.assertion-depth', 'audit.claim-proof', 'audit.spec-coverage',
|
|
34
|
+
'audit.taxonomy-mismatch', 'audit.gate-sensor-error', 'audit.scenario-id-reuse'];
|
|
35
|
+
|
|
36
|
+
export const UNIT_AUDIT_NODES: readonly UnitNodeDecl[] = [
|
|
37
|
+
{
|
|
38
|
+
id: 'unit.audit-missing', title: 'Measure the suite', actor: 'deterministic', granularity: 'unit',
|
|
39
|
+
appliesTo: ALL_KINDS, requires: ['unit.no-scenarios'], blocking: true, rank: 70, gates: [], produces: ['.sungen/reports/<unit>-audit.json'],
|
|
40
|
+
active: (s) => !s.auditNotCounted,
|
|
41
|
+
satisfied: (s) => Boolean(s.audit),
|
|
42
|
+
step: (s) => ({ kind: 'do', command: `sungen audit --screen ${s.unit}`, because: 'the suite has never been measured' }),
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
// OES-11.4: next, gate and delivery read one verdict — a report that does not count blocks all three.
|
|
46
|
+
id: 'unit.audit-stale', title: 'Re-measure the suite', actor: 'deterministic', granularity: 'unit',
|
|
47
|
+
appliesTo: ALL_KINDS, requires: ['unit.no-scenarios'], blocking: true, rank: 71, gates: [], produces: ['.sungen/reports/<unit>-audit.json'],
|
|
48
|
+
active: (s) => Boolean(s.auditNotCounted),
|
|
49
|
+
satisfied: (s) => Boolean(s.audit),
|
|
50
|
+
step: (s) => ({
|
|
51
|
+
kind: 'do',
|
|
52
|
+
command: `sungen audit --screen ${s.unit}`,
|
|
53
|
+
because: s.auditNotCounted!.state === 'stale'
|
|
54
|
+
? `the audit report is stale (${s.auditNotCounted!.reason}) — it no longer describes the suite and the decisions in force, so \`sungen gate\` and \`sungen delivery\` treat the unit as never audited until it is re-run`
|
|
55
|
+
: `the audit report is not trusted (${s.auditNotCounted!.reason}) — it counts as never audited (DOS-14.0) until \`sungen audit\` writes it again; never edit the report`,
|
|
56
|
+
}),
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
// A decision, not a step: accepting the yardstick an agent just wrote makes both axes read 100% (#660).
|
|
60
|
+
id: 'unit.baseline-changed', title: 'Accept the changed viewpoint', actor: 'human', granularity: 'unit',
|
|
61
|
+
appliesTo: ALL_KINDS, requires: ['unit.audit-missing', 'unit.audit-stale'], blocking: false, rank: 80, gates: [], produces: ['.sungen/viewpoint-baseline.json'],
|
|
62
|
+
active: (s) => Boolean(s.audit),
|
|
63
|
+
satisfied: (s) => s.audit?.viewpointBaselineStatus !== 'changed',
|
|
64
|
+
step: (s) => ({
|
|
65
|
+
kind: 'decide',
|
|
66
|
+
command: `sungen audit --screen ${s.unit} --accept-viewpoint`,
|
|
67
|
+
because: 'test-viewpoint.md changed since the accepted baseline, so the ledger and traceability axes are not evidence until a QA confirms the new declaration. A decision, not a step: an agent presents it and does not run it — accepting the yardstick you just wrote makes both axes read 100% by construction',
|
|
68
|
+
}),
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 'unit.repair-findings', title: 'Repair the named findings', actor: 'ai', granularity: 'unit',
|
|
72
|
+
appliesTo: ALL_KINDS, requires: ['unit.audit-missing', 'unit.audit-stale'], blocking: false, rank: 90, gates: [], produces: ['features/<unit>.feature'],
|
|
73
|
+
active: (s) => Boolean(s.audit),
|
|
74
|
+
satisfied: (s) => repairableCodes(s).length === 0,
|
|
75
|
+
step: (s) => {
|
|
76
|
+
const repair = repairableCodes(s);
|
|
77
|
+
return {
|
|
78
|
+
kind: 'do',
|
|
79
|
+
command: `repair, then sungen audit --screen ${s.unit}`,
|
|
80
|
+
because: `${repair.length} finding(s) name a specific repair: ${[...new Set(repair)].slice(0, 4).join(', ')}`,
|
|
81
|
+
};
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: 'unit.gate-fail', title: 'Repair the failing gate', actor: 'ai', granularity: 'unit',
|
|
86
|
+
appliesTo: ALL_KINDS, requires: ['unit.audit-missing', 'unit.audit-stale'], blocking: true, rank: 100, gates: AUDIT_GATE_RULES, produces: ['features/<unit>.feature'],
|
|
87
|
+
active: (s) => Boolean(s.audit),
|
|
88
|
+
satisfied: (s) => s.audit?.gateStatus !== 'FAIL',
|
|
89
|
+
step: (s) => ({
|
|
90
|
+
kind: 'blocked',
|
|
91
|
+
command: `repair the gate, then sungen audit --screen ${s.unit}`,
|
|
92
|
+
because: `the viewpoint gate is FAIL at ${s.audit!.overall}/10 — running tests against a design that fails its own gate measures the wrong thing`,
|
|
93
|
+
}),
|
|
94
|
+
},
|
|
95
|
+
];
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Test Contract as a QA DECISION in `sungen next` (DOS-14.4, phase 06 residual) — built from the
|
|
3
|
+
* verdict `sungen contract check` and the delivery guard rebuild (buildContractVerdict), so the three
|
|
4
|
+
* never disagree. Always `decide`: an agent presents it and never approves its own edit.
|
|
5
|
+
*
|
|
6
|
+
* unit.contract-approve (rank 105, after the audit gate, before the first run; a hard verdict —
|
|
7
|
+
* hard or uncommitted — is offered past a stale or failing audit too, #940)
|
|
8
|
+
* error the verdict could not be built → check it on a terminal
|
|
9
|
+
* uncommitted by kind: tampered → re-approve or restore · untracked → commit after review ·
|
|
10
|
+
* edited → review and commit, or `git checkout --` the lock · unverified → commit the
|
|
11
|
+
* decision (approving again cannot fix a commit, and offering it would loop)
|
|
12
|
+
* hard a check got weaker / changed target / was lost → restore it, or QA approves
|
|
13
|
+
* review changed, not weaker → QA re-approves (review blocks delivery)
|
|
14
|
+
* unit.contract-proposed (rank 137, after every blocking unit step — it never preempts one)
|
|
15
|
+
* proposed never approved → QA approves (proposed scenarios never block)
|
|
16
|
+
* A free / impl:code scenario only its TRACE cannot prove — unproven, inconclusive, opaque — is not a
|
|
17
|
+
* unit decision: the case nodes say what proves it (test-case-contract-nodes.ts, phase 09).
|
|
18
|
+
*/
|
|
19
|
+
import { ALL_KINDS, StepCore, UnitNodeDecl, unitKindDir } from '../node-decl';
|
|
20
|
+
import type { UnitState } from '../../harness/next-step';
|
|
21
|
+
|
|
22
|
+
const HUMAN_ONLY = 'A QA decision on a terminal: an agent presents it and never approves its own edit';
|
|
23
|
+
const approveCmd = (s: UnitState): string => `sungen contract approve --screen ${s.unit}`;
|
|
24
|
+
|
|
25
|
+
function uncommittedStep(s: UnitState): StepCore {
|
|
26
|
+
const c = s.contract!;
|
|
27
|
+
const lock = `qa/${unitKindDir(s.kind)}/${s.unit}/contracts.lock.yaml`;
|
|
28
|
+
const n = c.uncommitted;
|
|
29
|
+
switch (c.uncommittedKind) {
|
|
30
|
+
case 'tampered':
|
|
31
|
+
return { kind: 'decide', command: approveCmd(s), because: `${n} lock entr(ies) no longer match their steps (edited by hand) — re-approve with \`${approveCmd(s)}\` on a terminal, or restore the lock from git` };
|
|
32
|
+
case 'untracked':
|
|
33
|
+
return { kind: 'decide', command: `commit ${lock} and its contract-approval decision after review`, because: `the lock has never been committed — ${n} entr(ies) are not in git HEAD (contract.lock-uncommitted); commit it after review` };
|
|
34
|
+
case 'unverified':
|
|
35
|
+
return { kind: 'decide', command: `commit the contract-approval decision behind ${lock} after review`, because: `${n} lock entr(ies) are not vouched for by a committed contract-approval decision (contract.lock-uncommitted) — commit the decision after review, or re-approve with \`${approveCmd(s)}\` on a terminal` };
|
|
36
|
+
default:
|
|
37
|
+
return { kind: 'decide', command: `review and commit ${lock}, or restore it: git checkout -- ${lock}`, because: `${n} lock entr(ies) differ from the lock in git HEAD (contract.lock-uncommitted) — review and commit the lock, or restore it with \`git checkout -- ${lock}\`; approving again cannot fix that` };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function contractStep(s: UnitState): StepCore {
|
|
42
|
+
const c = s.contract!;
|
|
43
|
+
if (c.error) {
|
|
44
|
+
return { kind: 'decide', command: `sungen contract check --screen ${s.unit}`, because: `the contract verdict could not be built (${c.error}) — check it on a terminal; until it builds, the delivery guard asks instead of passing` };
|
|
45
|
+
}
|
|
46
|
+
if (c.uncommitted > 0) return uncommittedStep(s);
|
|
47
|
+
if (c.hard > 0) {
|
|
48
|
+
return { kind: 'decide', command: approveCmd(s), because: `${c.hard} scenario(s) break the approved contract (${c.headline}) — restore the approved checks in the .feature, or, if the change is intended, a QA approves it on a terminal. An agent presents this and never approves its own edit` };
|
|
49
|
+
}
|
|
50
|
+
return { kind: 'decide', command: approveCmd(s), because: `${c.review} approved scenario(s) changed since QA approved them (changed, not weaker) — review blocks \`sungen delivery\` until QA re-approves. ${HUMAN_ONLY}` };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const CONTRACT_RULES = ['contract.hash-changed', 'contract.oracle-weakened', 'contract.target-changed', 'contract.assertion-lost', 'contract.lock-uncommitted'];
|
|
54
|
+
/** The verdict is a pass and it was built: nothing blocks, nothing to repair. */
|
|
55
|
+
const verdictClean = (s: UnitState): boolean => !s.contract!.error && s.contract!.verdict === 'pass';
|
|
56
|
+
/** Nothing for a QA to decide at unit level: built, committed, nothing approved got weaker or changed. */
|
|
57
|
+
const nothingToDecide = (s: UnitState): boolean => {
|
|
58
|
+
const c = s.contract!;
|
|
59
|
+
return !c.error && c.uncommitted === 0 && c.hard === 0 && c.review === 0 && (c.verdict === 'pass' || (c.unproven ?? 0) + (c.traceReview ?? 0) > 0);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const UNIT_CONTRACT_NODES: readonly UnitNodeDecl[] = [
|
|
63
|
+
{
|
|
64
|
+
id: 'unit.contract-approve', title: 'Resolve the Test Contract', actor: 'human', granularity: 'unit',
|
|
65
|
+
appliesTo: ALL_KINDS, requires: ['unit.gate-fail'], blocking: false, rank: 105, gates: CONTRACT_RULES,
|
|
66
|
+
produces: ['contracts.lock.yaml', 'decisions/<id>.yaml'],
|
|
67
|
+
active: (s) => Boolean(s.contract),
|
|
68
|
+
satisfied: nothingToDecide,
|
|
69
|
+
step: contractStep,
|
|
70
|
+
// A hard verdict must not wait behind a re-audit (#940): the audit's PASS says nothing about it —
|
|
71
|
+
// a broken approved check, or a lock that is not what QA approved and committed (contract.lock-
|
|
72
|
+
// uncommitted, hard in `contract check`; the step names that repair first). What stays behind the
|
|
73
|
+
// cut: a changed-not-weaker contract (review — QA re-approves after the design is fixed) and a
|
|
74
|
+
// verdict that could not be built (not a verdict; `contract check` names the error).
|
|
75
|
+
surfacesPastCut: (s) => !s.contract!.error && (s.contract!.uncommitted > 0 || s.contract!.hard > 0),
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
id: 'unit.contract-proposed', title: 'Approve the Test Contract', actor: 'human', granularity: 'unit',
|
|
79
|
+
appliesTo: ALL_KINDS, requires: ['unit.run'], blocking: false, rank: 137, gates: [],
|
|
80
|
+
produces: ['contracts.lock.yaml', 'decisions/<id>.yaml'],
|
|
81
|
+
active: (s) => Boolean(s.contract) && verdictClean(s),
|
|
82
|
+
satisfied: (s) => s.contract!.proposed === 0,
|
|
83
|
+
step: (s) => ({
|
|
84
|
+
kind: 'decide',
|
|
85
|
+
command: approveCmd(s),
|
|
86
|
+
because: `${s.contract!.proposed} scenario(s) have no approved contract yet — approving locks the checks QA reviewed, so a later edit that weakens one (a healer's included) fails \`sungen contract check\`. ${HUMAN_ONLY}; proposed scenarios do not block`,
|
|
87
|
+
}),
|
|
88
|
+
},
|
|
89
|
+
];
|