@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,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sungen contract derive --screen <u> [--grep <re>] [--json]` (DOS-14.8, phase 08): free tests'
|
|
3
|
+
* traces → `features/<u>.free.feature`, every scenario `@free @proposed`, deterministic, no LLM.
|
|
4
|
+
*
|
|
5
|
+
* exit 0 written, unchanged, every scenario already approved, or a mobile project (not supported yet)
|
|
6
|
+
* exit 1 nothing to derive (no admissible trace — each skipped test says why, #932), refused (a
|
|
7
|
+
* secret or a machine path would have been written — nothing was), or an error
|
|
8
|
+
*/
|
|
9
|
+
import type { Command } from 'commander';
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
import { deriveFreeFeature, DeriveResult, nothingDerived } from '../../contract/derive-free-feature';
|
|
12
|
+
import { registeredTraceResolver } from '../../contract/resolve-unit-trace-identities';
|
|
13
|
+
import { resolveContractUnit } from '../../contract/contract-units';
|
|
14
|
+
|
|
15
|
+
function print(r: DeriveResult, unit: string): void {
|
|
16
|
+
const L = console.log;
|
|
17
|
+
const rel = path.relative(process.cwd(), r.file);
|
|
18
|
+
L('');
|
|
19
|
+
L(`━━━ Contract derive: ${unit} — free tests' traces → ${rel} ━━━`);
|
|
20
|
+
L('');
|
|
21
|
+
if (r.note) L(` ⚠ ${r.note}`);
|
|
22
|
+
for (const s of r.scenarios) L(` + ${s.title} (${s.steps} steps${s.low ? `, ${s.low} low identity` : ''}${s.opaque ? `, ${s.opaque} opaque` : ''})`);
|
|
23
|
+
for (const s of r.skipped) L(` - ${s.id} skipped: ${s.reason}`);
|
|
24
|
+
if (r.refused?.length) {
|
|
25
|
+
L(` ✗ Refused — nothing was written. ${r.refused.length} likely secret(s) / machine path(s):`);
|
|
26
|
+
for (const h of r.refused) L(` ${h.where} — ${h.reason}`);
|
|
27
|
+
L(' Move the value into test-data (or an env overlay) and use it from there, then derive again.');
|
|
28
|
+
} else if (r.written) {
|
|
29
|
+
L(` ✓ Wrote ${rel}. Review the steps (they ARE the contract), then QA approves on a terminal:`);
|
|
30
|
+
L(` sungen contract approve --screen ${unit}`);
|
|
31
|
+
L(' After approval, re-run the free tests (trace: "on") — a trace older than the contract proves nothing.');
|
|
32
|
+
} else if (r.scenarios.length) {
|
|
33
|
+
L(` = ${rel} is already up to date.`);
|
|
34
|
+
} else if (nothingDerived(r)) {
|
|
35
|
+
L(` ✗ Nothing to derive: no admissible trace of a test for ${unit}${r.skipped.length ? ' (each skipped test above says why)' : ' (try --grep)'}.`);
|
|
36
|
+
}
|
|
37
|
+
L('');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function registerDeriveCommand(contract: Command): void {
|
|
41
|
+
contract
|
|
42
|
+
.command('derive')
|
|
43
|
+
.description("Write features/<unit>.free.feature (@free @proposed) from the free tests' traces — deterministic, no LLM")
|
|
44
|
+
.option('-s, --screen <name>', 'Screen / flow / api unit name')
|
|
45
|
+
.option('--grep <regex>', 'Which tests, matched against "<id> <title> <file>" (default: tests whose file is named after the unit)')
|
|
46
|
+
.option('--json', 'Output the result as JSON')
|
|
47
|
+
.action(async (options) => {
|
|
48
|
+
try {
|
|
49
|
+
if (!options.screen) throw new Error('Provide --screen <name>');
|
|
50
|
+
const unit = resolveContractUnit(process.cwd(), String(options.screen));
|
|
51
|
+
const r = await deriveFreeFeature({
|
|
52
|
+
projectRoot: process.cwd(), unit, grep: options.grep ? String(options.grep) : undefined, resolver: registeredTraceResolver() ?? null,
|
|
53
|
+
});
|
|
54
|
+
if (options.json) console.log(JSON.stringify(r, null, 2)); else print(r, unit.name);
|
|
55
|
+
process.exit(r.refused?.length || nothingDerived(r) ? 1 : 0);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error('Error:', error instanceof Error ? error.message : error);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sungen contract approve | check` — the Test Contract (DOS-14, phase 06a).
|
|
3
|
+
*
|
|
4
|
+
* approve --screen <u> [--scenario <id>] [--reason <text>]
|
|
5
|
+
* a human types a confirmation on a TTY; writes contracts.lock.yaml + a contract-approval
|
|
6
|
+
* decision. No TTY → refused with the exact command (exit 1).
|
|
7
|
+
* check --screen <u> [--trace] [--json]
|
|
8
|
+
* rebuilds the verdict from .feature + lock + git HEAD + recorded traces (never from a report),
|
|
9
|
+
* writes .sungen/reports/<slug>-contract.json as output (secret-scanned first). Exit 2 on a hard
|
|
10
|
+
* finding, 0 on pass or review, 1 on an error (unknown unit, untrusted lock, unparseable feature).
|
|
11
|
+
* `--trace` first asks driver-ui (a real browser) for the target identities of free / impl:code
|
|
12
|
+
* traces; without it the cached answers are used (DOS-14.5, 14.6).
|
|
13
|
+
* derive --screen <u> [--grep <re>] → contract-derive-command.ts (DOS-14.8)
|
|
14
|
+
*/
|
|
15
|
+
import { Command } from 'commander';
|
|
16
|
+
import * as fs from 'fs';
|
|
17
|
+
import * as path from 'path';
|
|
18
|
+
import { approveContract } from '../../contract/approve-contract';
|
|
19
|
+
import { buildContractVerdict, ContractVerdict } from '../../contract/build-contract-verdict';
|
|
20
|
+
import { contractReportPath, writeContractReport } from '../../contract/contract-report-file';
|
|
21
|
+
import { HARD_CLASSES, REVIEW_CLASSES } from '../../contract/contract-schema';
|
|
22
|
+
import { processIO } from '../../decisions/human-confirmation';
|
|
23
|
+
import { resolveContractUnit } from '../../contract/contract-units';
|
|
24
|
+
import { secretScanHits } from '../../contract/field-semantic-redaction';
|
|
25
|
+
import { resolveUnitTraceIdentities } from '../../contract/resolve-unit-trace-identities';
|
|
26
|
+
import { registerDeriveCommand } from './contract-derive-command';
|
|
27
|
+
|
|
28
|
+
const MARK: Record<string, string> = {
|
|
29
|
+
match: '✓', strengthened: '↑', proposed: '+', 'hash-changed': '⚖', 'oracle-weakened': '✗', 'target-changed': '✗', 'assertion-lost': '✗',
|
|
30
|
+
opaque: '◐', nondeterministic: '≈', inconclusive: '?', unproven: '✗',
|
|
31
|
+
};
|
|
32
|
+
/** `contract check` judges traces with a generous deadline (the guard path keeps ~3 s). */
|
|
33
|
+
const CHECK_TRACE_BUDGET_MS = 120_000;
|
|
34
|
+
const UNPROVEN_HINT = " → free / impl:code tests need their own config (outputDir 'test-results-free', trace: 'on', the sungen run-record reporter), then a fresh run (see `sungen contract derive`).";
|
|
35
|
+
|
|
36
|
+
function printVerdict(v: ContractVerdict, reportFile: string): void {
|
|
37
|
+
const L = console.log;
|
|
38
|
+
const head = v.verdict === 'pass' ? '✓ PASS' : v.verdict === 'review'
|
|
39
|
+
? '⚖ REVIEW — changed, not weaker. Exit 0 here, but review blocks `sungen delivery` until QA re-approves' : '✗ FAIL';
|
|
40
|
+
L('');
|
|
41
|
+
L(`━━━ Contract check: ${v.unit} — Gherkin vs the approved lock ━━━`);
|
|
42
|
+
L('');
|
|
43
|
+
L(` verdict: ${head}`);
|
|
44
|
+
const matched = v.scenarios.filter((s) => s.class === 'match').length;
|
|
45
|
+
for (const s of v.scenarios.filter((x) => x.class !== 'match')) {
|
|
46
|
+
L(` ${MARK[s.class] ?? '?'} ${s.id} ${s.class}${s.class === 'proposed' ? ' (no approved entry — does not block)' : ''}`);
|
|
47
|
+
for (const f of s.findings) L(` ${f.rule ? `[${f.rule}] ` : ''}${f.step ? `step ${f.step}: ` : ''}${f.detail}`);
|
|
48
|
+
if (s.trace?.hashes.length) L(` trace: ${[...new Set(s.trace.hashes)].join(', ')} (${s.trace.runs.length} run(s))`);
|
|
49
|
+
if (s.class === 'unproven') L(UNPROVEN_HINT);
|
|
50
|
+
}
|
|
51
|
+
if (matched) L(` ✓ ${matched} scenario(s) match the approved contract`);
|
|
52
|
+
const issue = (u: ContractVerdict['uncommitted'][number]): string =>
|
|
53
|
+
u.change === 'tampered' || u.change === 'unverified' ? `lock entry ${u.change}: ${u.detail}` : `lock entry ${u.change} and not committed`;
|
|
54
|
+
for (const u of v.uncommitted.slice(0, 10)) L(` ✗ ${u.id} ${issue(u)} [contract.lock-uncommitted]`);
|
|
55
|
+
if (v.uncommitted.length > 10) L(` ✗ … and ${v.uncommitted.length - 10} more lock entries that are not what QA approved and committed`);
|
|
56
|
+
for (const w of v.warnings) L(` ⚠ ${w}`);
|
|
57
|
+
L('');
|
|
58
|
+
// Only missing / refused traces: re-approving cannot help, a fresh traced run can.
|
|
59
|
+
const blocking = v.scenarios.filter((s) => HARD_CLASSES.has(s.class) || REVIEW_CLASSES.has(s.class));
|
|
60
|
+
const onlyUnproven = blocking.length > 0 && blocking.every((s) => s.class === 'unproven');
|
|
61
|
+
if (v.verdict === 'fail') {
|
|
62
|
+
L(v.uncommitted.length
|
|
63
|
+
? ' → Commit the approval (lock + decision) through review, or restore the lock from git (`git checkout -- <lock>`).'
|
|
64
|
+
: onlyUnproven ? " → Re-run the free / impl:code tests with trace: 'on', then check again."
|
|
65
|
+
: ' → Restore the approved checks in the .feature — or, if the change is intended, QA approves it on a terminal:');
|
|
66
|
+
}
|
|
67
|
+
if (v.verdict !== 'pass' && !v.uncommitted.length && !onlyUnproven) L(` sungen contract approve --screen ${v.unit}`);
|
|
68
|
+
L(` Report: ${path.relative(process.cwd(), reportFile)}`);
|
|
69
|
+
L('');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function unitOrThrow(name: string | undefined): { name: string; dir: string } {
|
|
73
|
+
if (!name) throw new Error('Provide --screen <name>');
|
|
74
|
+
return resolveContractUnit(process.cwd(), name);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function registerContractCommand(program: Command): void {
|
|
78
|
+
const contract = program
|
|
79
|
+
.command('contract')
|
|
80
|
+
.description('Test Contract (DOS-14): the Gherkin QA approved is the contract — lock it (TTY) and check the .feature was not weakened');
|
|
81
|
+
|
|
82
|
+
contract
|
|
83
|
+
.command('approve')
|
|
84
|
+
.description('Lock the current Gherkin as the approved contract — a human types a confirmation on a TTY')
|
|
85
|
+
.option('-s, --screen <name>', 'Screen / flow / api unit name')
|
|
86
|
+
.option('--scenario <id>', 'Approve one scenario only (its ID, e.g. VP-LOGIN-001)')
|
|
87
|
+
.option('--reason <text>', 'Why (recorded in the contract-approval decision)')
|
|
88
|
+
.action(async (options) => {
|
|
89
|
+
try {
|
|
90
|
+
const unit = unitOrThrow(options.screen);
|
|
91
|
+
const r = await approveContract({ projectRoot: process.cwd(), unit: unit.name, scenario: options.scenario, reason: options.reason, io: processIO() });
|
|
92
|
+
if (r.status === 'nothing-to-approve') { console.log(`\n= Nothing to approve: every chosen scenario of ${unit.name} already matches its approved lock entry.\n`); return; }
|
|
93
|
+
console.log(`\n✓ Approved ${r.approved.length} scenario(s)${r.removed.length ? `, removed ${r.removed.length}` : ''} → ${path.relative(process.cwd(), r.lockPath)} (decision ${r.decisionId})`);
|
|
94
|
+
console.log(' Commit the lock and the decision through review: until they are in git HEAD, `sungen contract check` reports contract.lock-uncommitted.\n');
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.error('Error:', error instanceof Error ? error.message : error);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
contract
|
|
102
|
+
.command('check')
|
|
103
|
+
.description('Compare the .feature with the approved lock on the strength ladder, and the lock with git HEAD')
|
|
104
|
+
.option('-s, --screen <name>', 'Screen / flow / api unit name')
|
|
105
|
+
.option('--trace', 'Resolve free / impl:code trace target identities with @sungen/driver-ui (a real browser) first')
|
|
106
|
+
.option('--json', 'Output the verdict as JSON')
|
|
107
|
+
.action(async (options) => {
|
|
108
|
+
let unit: { name: string; dir: string } | undefined;
|
|
109
|
+
try {
|
|
110
|
+
unit = unitOrThrow(options.screen);
|
|
111
|
+
const notes = options.trace ? await resolveUnitTraceIdentities(process.cwd(), unit) : [];
|
|
112
|
+
// The CLI may take its time; the guard (contractBlockers) keeps the ~3 s default.
|
|
113
|
+
const verdict = buildContractVerdict(process.cwd(), unit, { traceBudgetMs: CHECK_TRACE_BUDGET_MS });
|
|
114
|
+
verdict.warnings.push(...notes);
|
|
115
|
+
const hits = secretScanHits(JSON.stringify(verdict, null, 2), `${unit.name}-contract.json`);
|
|
116
|
+
if (hits.length) throw new Error(`Refused to write the contract report — likely secret(s): ${hits.map((h) => `${h.where} ${h.reason}`).join('; ')}`);
|
|
117
|
+
const file = writeContractReport(process.cwd(), verdict);
|
|
118
|
+
if (options.json) console.log(JSON.stringify(verdict, null, 2));
|
|
119
|
+
else printVerdict(verdict, file);
|
|
120
|
+
process.exit(verdict.exitCode);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
// Unreadable = not run (DOS-14.0): an earlier report must not outlive the inputs it judged.
|
|
123
|
+
if (unit) fs.rmSync(contractReportPath(process.cwd(), unit.name), { force: true });
|
|
124
|
+
console.error('Error:', error instanceof Error ? error.message : error);
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
registerDeriveCommand(contract);
|
|
130
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { resolveUnit } from '../resolve-unit';
|
|
3
|
+
import { draftDefects } from '../../harness/defect-draft';
|
|
4
|
+
import { readDefects } from '../../harness/defects';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `sungen defect draft|list` — defect records under qa/defects/ (see harness/defects.ts).
|
|
8
|
+
* `draft` writes one record per product-candidate row of the unit's last `sungen triage`.
|
|
9
|
+
*/
|
|
10
|
+
export function registerDefectCommand(program: Command): void {
|
|
11
|
+
const defect = program.command('defect').description('Draft and list defect records (qa/defects/DEF-NNN-*.md) from red scenarios');
|
|
12
|
+
|
|
13
|
+
defect
|
|
14
|
+
.command('draft')
|
|
15
|
+
.description('Draft a defect record for each product-candidate row of the last `sungen triage`')
|
|
16
|
+
.option('-s, --screen <name>', 'Screen or flow name')
|
|
17
|
+
.option('--api <name>', 'API-first area or api flow (qa/api/<name>)')
|
|
18
|
+
.option('--scenario <title|id>', 'Only the scenario whose title contains this text, or that carries this VP id')
|
|
19
|
+
.option('--json', 'Output raw JSON')
|
|
20
|
+
.action((o: { screen?: string; api?: string; scenario?: string; json?: boolean }) => {
|
|
21
|
+
try {
|
|
22
|
+
const name = o.screen || o.api;
|
|
23
|
+
if (!name) throw new Error('Provide --screen <name> (or --api <area>)');
|
|
24
|
+
const unit = resolveUnit(name, process.cwd());
|
|
25
|
+
if (!unit) throw new Error(`Not found: qa/screens/${name}, qa/flows/${name}, or qa/api/${name}`);
|
|
26
|
+
const r = draftDefects(process.cwd(), unit, { scenario: o.scenario });
|
|
27
|
+
if (o.json) { console.log(JSON.stringify(r, null, 2)); return; }
|
|
28
|
+
if (r.missingTriage) { console.log(`\n ${name}: no triage yet — run \`sungen triage --screen ${name}\` after the tests.\n`); return; }
|
|
29
|
+
for (const f of r.written) console.log(` ✎ ${f}`);
|
|
30
|
+
for (const s of r.skipped) console.log(` ○ already recorded as ${s.id}: ${s.scenario}`);
|
|
31
|
+
if (!r.written.length && !r.skipped.length) console.log(` ✓ ${name}: no product-candidate rows to draft.`);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error('Error:', error instanceof Error ? error.message : error);
|
|
34
|
+
process.exitCode = 1;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
defect
|
|
39
|
+
.command('list')
|
|
40
|
+
.description('List defect records (id, severity, status, units, scenario count)')
|
|
41
|
+
.option('--status <status>', 'Only records with this status (open, fixed, verified, closed, wont-fix)')
|
|
42
|
+
.option('--json', 'Output raw JSON')
|
|
43
|
+
.action((o: { status?: string; json?: boolean }) => {
|
|
44
|
+
const rows = readDefects(process.cwd()).filter((r) => !o.status || r.status === o.status);
|
|
45
|
+
if (o.json) { console.log(JSON.stringify(rows, null, 2)); return; }
|
|
46
|
+
if (!rows.length) { console.log(' (no defect records)'); return; }
|
|
47
|
+
for (const r of rows) console.log(` ${r.id} ${r.severity.padEnd(8)} ${r.status.padEnd(9)} ${r.units.join(',')} ${r.scenarios.length} scenario(s) ${r.title}`);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -7,7 +7,7 @@ import { Command } from 'commander';
|
|
|
7
7
|
import * as path from 'path';
|
|
8
8
|
import * as fs from 'fs';
|
|
9
9
|
import { parse as parseYaml } from 'yaml';
|
|
10
|
-
import { parseFeatureMetadata } from '../../exporters/feature-parser';
|
|
10
|
+
import { isHookScenario, parseFeatureMetadata } from '../../exporters/feature-parser';
|
|
11
11
|
import { parseSpecFile } from '../../exporters/spec-parser';
|
|
12
12
|
import { loadTestData } from '../../exporters/test-data-resolver';
|
|
13
13
|
import { loadSelectorKeyMap } from '../../exporters/selector-key-resolver';
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
renderCsv,
|
|
21
21
|
writeCsv,
|
|
22
22
|
} from '../../exporters/csv-exporter';
|
|
23
|
-
import { renderXlsxMultiSheet, writeXlsx, buildApiDetailRows, addApiDetailSheet } from '../../exporters/xlsx-exporter';
|
|
23
|
+
import { renderXlsxMultiSheet, writeXlsx, buildApiDetailRows, addApiDetailSheet, deliverableXlsxPath } from '../../exporters/xlsx-exporter';
|
|
24
24
|
import { loadApiCatalog } from '../../exporters/api-catalog-loader';
|
|
25
25
|
import { resolveApiEnvironment } from '../../exporters/api-environment';
|
|
26
26
|
import { getEnvironment, platformOfResultFile, RunEnvironment } from '../../exporters/run-environment';
|
|
@@ -38,9 +38,14 @@ import {
|
|
|
38
38
|
hasReview,
|
|
39
39
|
} from '../../exporters/matrix/export';
|
|
40
40
|
import { MatrixFinding } from '../../exporters/matrix/types';
|
|
41
|
-
import { ManualCarryReport } from '../../exporters/matrix/carry-manual-results';
|
|
41
|
+
import { applyManualCarry, ManualCarryReport, PriorManualResults, readPriorManualResults } from '../../exporters/matrix/carry-manual-results';
|
|
42
42
|
import { formatTestOutcome, resultTotals } from '../../exporters/matrix/result-totals';
|
|
43
43
|
import { readCapabilities } from '../../harness/capability';
|
|
44
|
+
import { processIO } from '../../decisions/human-confirmation';
|
|
45
|
+
import { DeliveryDecisionGate } from '../../harness/gates/delivery-decision-gate';
|
|
46
|
+
import { runDeliveryDecisionStep } from '../../harness/gates/delivery-decision-step';
|
|
47
|
+
import { deliverableGateOverrides, InRunAcceptance } from '../../harness/gates/gate-override-report';
|
|
48
|
+
import { ChecklistUnit, renderChecklist, unitChecklist } from '../../harness/gates/delivery-checklist';
|
|
44
49
|
|
|
45
50
|
const COLOR = {
|
|
46
51
|
reset: '\x1b[0m',
|
|
@@ -85,6 +90,12 @@ export interface DeliveryTarget {
|
|
|
85
90
|
isFlow: boolean;
|
|
86
91
|
}
|
|
87
92
|
|
|
93
|
+
/** The command that regenerates a target's unit — flag by kind, the unit (not feature) name. */
|
|
94
|
+
function generateCommandFor(target: DeliveryTarget): string {
|
|
95
|
+
const flag = target.kind === 'flow' ? '--flow' : target.kind === 'api' ? '--api' : '--screen';
|
|
96
|
+
return `sungen generate ${flag} ${target.screen}`;
|
|
97
|
+
}
|
|
98
|
+
|
|
88
99
|
function makeTarget(screen: string, featureBaseName: string, kind: UnitKind): DeliveryTarget {
|
|
89
100
|
return { screen, featureBaseName, name: featureBaseName, kind, isFlow: kind === 'flow' };
|
|
90
101
|
}
|
|
@@ -464,6 +475,7 @@ async function exportTarget(
|
|
|
464
475
|
if (isMobileProject(cwd)) removeBaseDeliverables(cwd, target.featureBaseName);
|
|
465
476
|
const rows = buildTestCaseRows({
|
|
466
477
|
screen: label,
|
|
478
|
+
generateCommand: generateCommandFor(target),
|
|
467
479
|
featureName: feature.featureName,
|
|
468
480
|
// OS-precise env column: a mobile dual-id Path resolves to just the
|
|
469
481
|
// android package / ios bundle id for SUNGEN_ENV=android|ios.
|
|
@@ -522,6 +534,7 @@ async function exportTarget(
|
|
|
522
534
|
for (const variant of osVariants) {
|
|
523
535
|
const variantRows = buildTestCaseRows({
|
|
524
536
|
screen: label,
|
|
537
|
+
generateCommand: generateCommandFor(target),
|
|
525
538
|
featureName: feature.featureName,
|
|
526
539
|
featurePath: resolvePlatformAppId(featurePath, variant.locale), // OS-precise app id
|
|
527
540
|
merged,
|
|
@@ -574,6 +587,7 @@ async function exportTarget(
|
|
|
574
587
|
const variantResults = variant.resultsPath ? loadPlaywrightReport(variant.resultsPath) : null;
|
|
575
588
|
const variantRows = buildTestCaseRows({
|
|
576
589
|
screen: label,
|
|
590
|
+
generateCommand: generateCommandFor(target),
|
|
577
591
|
featureName: feature.featureName,
|
|
578
592
|
// No-op for web (URL Path); for a mobile fall-through (a no-suffix result
|
|
579
593
|
// json) this collapses the dual-id to the android package so the combined
|
|
@@ -651,7 +665,7 @@ export function matrixPathsFor(cwd: string, target: DeliveryTarget): MatrixTarge
|
|
|
651
665
|
}
|
|
652
666
|
|
|
653
667
|
function printFindings(findings: MatrixFinding[]): void {
|
|
654
|
-
const icon = { error: `${COLOR.red}✗`, review: `${COLOR.yellow}⚠`, warning: `${COLOR.gray}
|
|
668
|
+
const icon = { error: `${COLOR.red}✗`, review: `${COLOR.yellow}⚠`, warning: `${COLOR.gray}·`, info: `${COLOR.gray}i` } as const;
|
|
655
669
|
for (const f of findings) {
|
|
656
670
|
log(` ${icon[f.severity]} [Gate ${f.gate}]${COLOR.reset} ${f.ref ? `${f.ref}: ` : ''}${f.message}`);
|
|
657
671
|
}
|
|
@@ -676,23 +690,29 @@ async function exportMatrixTarget(
|
|
|
676
690
|
target: DeliveryTarget,
|
|
677
691
|
opts: { check?: boolean; preview?: boolean; format?: MatrixFormat },
|
|
678
692
|
env: EnvironmentInfo,
|
|
693
|
+
decisions?: DeliveryDecisionGate,
|
|
679
694
|
): Promise<MatrixRunSummary | 'skipped' | null> {
|
|
680
695
|
const paths = matrixPathsFor(cwd, target);
|
|
681
696
|
paths.runEnv = matrixRunEnv(cwd, target, env, paths);
|
|
697
|
+
paths.gateRules = decisions?.rulesFor(qaDir(cwd, target)); // the unit's gate-overrides apply to its matrix gates
|
|
682
698
|
|
|
683
699
|
// A feature whose scenarios are ALL @exploration probes has nothing to deliver —
|
|
684
700
|
// skip it quietly (no map required) instead of demanding a reviewed grouping for
|
|
685
701
|
// probes that are, by contract, outside the official suite.
|
|
686
702
|
{
|
|
687
703
|
const featureMeta = parseFeatureMetadata(paths.featureFile);
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
704
|
+
// Hooks are setup/teardown, never test cases — they neither need nor make a deliverable (#880).
|
|
705
|
+
const scenarios = featureMeta.scenarios.filter((s) => !isHookScenario(s));
|
|
706
|
+
const deliverable = scenarios.filter((s) => !s.tags.some((t) => /^@exploration\b/i.test(t)));
|
|
707
|
+
if (scenarios.length > 0 && deliverable.length === 0) {
|
|
708
|
+
log(`${COLOR.gray}${paths.label}: nothing to deliver — all ${scenarios.length} scenario(s) are @exploration probes (outside the official suite).${COLOR.reset}`);
|
|
691
709
|
return 'skipped';
|
|
692
710
|
}
|
|
693
711
|
}
|
|
694
712
|
|
|
695
713
|
const { model, mapMissing, mapErrors } = loadMatrixModel(paths);
|
|
714
|
+
// An audit that is untrusted or FAILs never yields an official deliverable: --preview renders a DRAFT (#935).
|
|
715
|
+
if (model && decisions?.auditDraft(qaDir(cwd, target))) model.manifest.approvalState = 'draft';
|
|
696
716
|
|
|
697
717
|
if (mapMissing) {
|
|
698
718
|
log(`${COLOR.yellow}${paths.label}: no delivery map${COLOR.reset} (${path.relative(cwd, paths.mapFile)})`);
|
|
@@ -707,6 +727,18 @@ async function exportMatrixTarget(
|
|
|
707
727
|
return null;
|
|
708
728
|
}
|
|
709
729
|
|
|
730
|
+
// The tester's recorded Manual results are part of the outcome: read them BEFORE anything is
|
|
731
|
+
// counted, so this line, the workbook's totals and the summary table all agree (#891). A file
|
|
732
|
+
// that cannot be read is reported where it matters — when it would be overwritten.
|
|
733
|
+
const format = opts.format ?? 'xlsx';
|
|
734
|
+
let prior: PriorManualResults | null = null;
|
|
735
|
+
let priorError: Error | null = null;
|
|
736
|
+
try { prior = await readPriorManualResults(deliverableXlsxPath(cwd, paths.unit)); }
|
|
737
|
+
// A CSV-only export overwrites no workbook, so an unreadable one only means "nothing to carry".
|
|
738
|
+
catch (e) { if (format !== 'csv') priorError = e as Error; }
|
|
739
|
+
applyManualCarry(model, prior);
|
|
740
|
+
model.gateOverrides = deliverableGateOverrides(decisions?.overridesFor(qaDir(cwd, target)) ?? [], hasReview(model.findings), decisions?.acceptedInRun);
|
|
741
|
+
|
|
710
742
|
log(`${COLOR.bold}${paths.label}${COLOR.reset} — ${model.manifest.itemCount} delivery item(s), ${model.manifest.variantCount} coverage variant(s), review: ${model.manifest.approvalState} (design), test outcome: ${formatTestOutcome(resultTotals(model.items))}`);
|
|
711
743
|
{
|
|
712
744
|
const mocked = model.items.flatMap((it) => it.variants.filter((v) => v.mocked));
|
|
@@ -741,7 +773,8 @@ async function exportMatrixTarget(
|
|
|
741
773
|
|
|
742
774
|
let deliverables: Awaited<ReturnType<typeof writeMatrixDeliverables>>;
|
|
743
775
|
try {
|
|
744
|
-
|
|
776
|
+
if (priorError) throw priorError;
|
|
777
|
+
deliverables = await writeMatrixDeliverables(paths, model, format, prior);
|
|
745
778
|
} catch (e) {
|
|
746
779
|
// The existing workbook could not be read, so writing would destroy its Manual results.
|
|
747
780
|
log(` ${COLOR.red}not written:${COLOR.reset} ${(e as Error).message}`);
|
|
@@ -869,6 +902,19 @@ function printSummaryTable(summaries: ScreenSummary[]): void {
|
|
|
869
902
|
}
|
|
870
903
|
}
|
|
871
904
|
|
|
905
|
+
/** T6: one checklist block per delivered unit, each box from what its command says now (delivery-checklist.ts). */
|
|
906
|
+
async function printDeliveryChecklist(cwd: string, targets: DeliveryTarget[], accepted?: InRunAcceptance): Promise<void> {
|
|
907
|
+
const units = new Map<string, ChecklistUnit>();
|
|
908
|
+
for (const t of targets) {
|
|
909
|
+
const dir = qaDir(cwd, t);
|
|
910
|
+
if (!units.has(dir)) units.set(dir, { label: t.isFlow ? `flow/${t.screen}` : t.screen, unitName: t.screen, unitDir: dir, kind: t.kind, resultsPath: resolveResultsPath(cwd, t) });
|
|
911
|
+
}
|
|
912
|
+
const rows: Array<{ label: string; boxes: Awaited<ReturnType<typeof unitChecklist>> }> = [];
|
|
913
|
+
for (const u of units.values()) rows.push({ label: u.label, boxes: await unitChecklist(cwd, u, accepted) });
|
|
914
|
+
log('');
|
|
915
|
+
for (const line of renderChecklist(rows)) log(line);
|
|
916
|
+
}
|
|
917
|
+
|
|
872
918
|
// ----------------------------------------------------------------------------
|
|
873
919
|
// Command registration
|
|
874
920
|
// ----------------------------------------------------------------------------
|
|
@@ -887,10 +933,11 @@ export function registerDeliveryCommand(program: Command): void {
|
|
|
887
933
|
.option('--approve [ids]', 'Approve proposed groups (all, or a comma-separated id list) + stamp fingerprints')
|
|
888
934
|
.option('--preview', 'Render the matrix despite review-required findings (DRAFT watermark)')
|
|
889
935
|
.option('--format <format>', 'Matrix output format: xlsx (default) | csv | both', 'xlsx')
|
|
936
|
+
.option('--accept-in-run', 'Deliver despite gate-overrides/waivers/approvals recorded during the run (decision.in-run) — a human confirms on a terminal')
|
|
890
937
|
.action(async (names: string[], options: {
|
|
891
938
|
skipPreflight?: boolean; continueOnMissing?: boolean; env?: string;
|
|
892
939
|
legacy?: boolean; full?: boolean; check?: boolean; approve?: boolean | string; preview?: boolean;
|
|
893
|
-
format?: string;
|
|
940
|
+
format?: string; acceptInRun?: boolean;
|
|
894
941
|
}) => {
|
|
895
942
|
try {
|
|
896
943
|
// Same effect as running with SUNGEN_ENV=<env> — result-file resolution,
|
|
@@ -967,6 +1014,30 @@ export function registerDeliveryCommand(program: Command): void {
|
|
|
967
1014
|
.reduce<SecretScanResult>((a, r) => ({ hits: [...a.hits, ...r.hits], unscanned: [...a.unscanned, ...r.unscanned] }), { hits: [], unscanned: [] });
|
|
968
1015
|
for (const line of formatSecretScan(secretScan)) log(line);
|
|
969
1016
|
|
|
1017
|
+
// OES-11.3–11.5: decisions that do not verify, rejected overrides, a stale audit and in-run
|
|
1018
|
+
// decisions stop the delivery before anything is written (approval only stamps the map).
|
|
1019
|
+
let decisions: DeliveryDecisionGate | undefined;
|
|
1020
|
+
// --approve only stamps a matrix map. With --legacy / --full it would skip this gate and
|
|
1021
|
+
// fall through to the export, so the combination is refused before anything is written.
|
|
1022
|
+
if (options.approve !== undefined && (options.legacy || options.full)) {
|
|
1023
|
+
console.error(`${COLOR.red}--approve applies to the matrix deliverable only${COLOR.reset} — it cannot be combined with --legacy / --full`);
|
|
1024
|
+
process.exit(1);
|
|
1025
|
+
}
|
|
1026
|
+
if (options.approve === undefined) {
|
|
1027
|
+
const gate = await runDeliveryDecisionStep({
|
|
1028
|
+
projectRoot: cwd, acceptInRun: !!options.acceptInRun, io: processIO(), log,
|
|
1029
|
+
// --preview / --check soften only the matrix export; --legacy has no draft mode, so it always needs one.
|
|
1030
|
+
requireTrustedAudit: !!(options.legacy || options.full) || (!options.preview && !options.check),
|
|
1031
|
+
refs: toExport.map((t) => ({ label: t.isFlow ? `flow/${t.featureBaseName}` : t.featureBaseName, unitName: t.screen, unitDir: qaDir(cwd, t), resultsPath: resolveResultsPath(cwd, t) })),
|
|
1032
|
+
argv: ['sungen', 'delivery', ...(names ?? []), ...(options.env ? ['--env', options.env] : []), ...(options.legacy || options.full ? ['--legacy'] : [])],
|
|
1033
|
+
});
|
|
1034
|
+
if (!gate) {
|
|
1035
|
+
await printDeliveryChecklist(cwd, toExport);
|
|
1036
|
+
process.exit(1);
|
|
1037
|
+
}
|
|
1038
|
+
decisions = gate;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
970
1041
|
// 3. Export
|
|
971
1042
|
const legacy = options.legacy || options.full;
|
|
972
1043
|
if (!legacy) {
|
|
@@ -981,9 +1052,9 @@ export function registerDeliveryCommand(program: Command): void {
|
|
|
981
1052
|
// Same contract as the export path: an all-@exploration feature has no
|
|
982
1053
|
// deliverable variants, so there is no map to approve — skip, not an error.
|
|
983
1054
|
{
|
|
984
|
-
const
|
|
985
|
-
if (
|
|
986
|
-
&&
|
|
1055
|
+
const scenarios = parseFeatureMetadata(paths.featureFile).scenarios.filter((s) => !isHookScenario(s));
|
|
1056
|
+
if (scenarios.length > 0
|
|
1057
|
+
&& scenarios.every((s) => s.tags.some((t) => /^@exploration\b/i.test(t)))) {
|
|
987
1058
|
log(`${COLOR.gray}${paths.label}: nothing to approve — all scenario(s) are @exploration probes.${COLOR.reset}`);
|
|
988
1059
|
continue;
|
|
989
1060
|
}
|
|
@@ -1012,21 +1083,26 @@ export function registerDeliveryCommand(program: Command): void {
|
|
|
1012
1083
|
for (const target of toExport) {
|
|
1013
1084
|
const s = await exportMatrixTarget(cwd, target, {
|
|
1014
1085
|
check: options.check, preview: options.preview, format: format as MatrixFormat,
|
|
1015
|
-
}, env);
|
|
1086
|
+
}, env, decisions);
|
|
1016
1087
|
if (s === 'skipped') continue; // all-@exploration feature — neither exported nor a failure
|
|
1017
1088
|
if (s) matrixSummaries.push(s);
|
|
1018
1089
|
else notExported.push(target.isFlow ? `flow/${target.featureBaseName}` : target.featureBaseName);
|
|
1019
1090
|
}
|
|
1020
1091
|
if (matrixSummaries.length > 0 && !options.check) printMatrixSummaryTable(matrixSummaries);
|
|
1092
|
+
for (const line of decisions?.summaryLines() ?? []) log(line);
|
|
1021
1093
|
printSkipSummary(skipped, notExported);
|
|
1094
|
+
await printDeliveryChecklist(cwd, toExport, decisions?.acceptedInRun);
|
|
1022
1095
|
// A named target that produced nothing is a failure. A sweep is a failure
|
|
1023
1096
|
// only when it produced nothing at all — units still waiting for a map or
|
|
1024
1097
|
// an approval are the normal state of a live project. Preflight skips are
|
|
1025
1098
|
// not counted here: reaching this point in an explicit scope means
|
|
1026
1099
|
// --continue-on-missing was passed, which IS the opt-in to tolerate them.
|
|
1027
|
-
|
|
1100
|
+
// --check reports like its checklist: an audit box that does not hold is a non-zero exit (#935).
|
|
1101
|
+
const auditFails = (decisions?.untrustedAudits.length ?? 0) + (decisions?.failingAudits.length ?? 0);
|
|
1102
|
+
if (options.check && auditFails) log(`${COLOR.red}✗ --check: ${auditFails} unit(s) whose audit does not pass — see the audit box above.${COLOR.reset}`);
|
|
1103
|
+
const failed = (explicitScope
|
|
1028
1104
|
? notExported.length > 0
|
|
1029
|
-
: matrixSummaries.length === 0;
|
|
1105
|
+
: matrixSummaries.length === 0) || (!!options.check && auditFails > 0);
|
|
1030
1106
|
if (failed) process.exit(1);
|
|
1031
1107
|
return;
|
|
1032
1108
|
}
|
|
@@ -1041,6 +1117,7 @@ export function registerDeliveryCommand(program: Command): void {
|
|
|
1041
1117
|
// 4. Summary
|
|
1042
1118
|
printSummaryTable(summaries);
|
|
1043
1119
|
printSkipSummary(skipped, []);
|
|
1120
|
+
await printDeliveryChecklist(cwd, toExport, decisions?.acceptedInRun);
|
|
1044
1121
|
// Same rule as the matrix path: every attempted target in an explicit scope
|
|
1045
1122
|
// must have produced a file; a sweep only fails when nothing was written.
|
|
1046
1123
|
if (explicitScope ? summaries.length < toExport.length : summaries.length === 0) process.exit(1);
|
|
@@ -7,6 +7,7 @@ import { scanTestDataSecrets, formatSecretScan, type SecretScanResult } from '..
|
|
|
7
7
|
import { capabilityRegistry } from '../../capabilities/registry';
|
|
8
8
|
import { discoverAndRegisterCapabilities } from '../../capabilities/discover';
|
|
9
9
|
import { readCapabilities, writeCapabilities, driverMeta, loadDriverCatalog } from '../../harness/capability';
|
|
10
|
+
import { isHandWritten } from '../../harness/parse';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Find .feature files recursively in a directory
|
|
@@ -20,7 +21,8 @@ function findFeatureFiles(dir: string): string[] {
|
|
|
20
21
|
const fullPath = path.join(dir, entry.name);
|
|
21
22
|
if (entry.isDirectory()) {
|
|
22
23
|
files.push(...findFeatureFiles(fullPath));
|
|
23
|
-
} else if (entry.isFile() && entry.name.endsWith('.feature')) {
|
|
24
|
+
} else if (entry.isFile() && entry.name.endsWith('.feature') && !isHandWritten([], fullPath)) {
|
|
25
|
+
// A derived `*.free.feature` is a contract for hand-written tests — never compiled (DOS-14.8).
|
|
24
26
|
files.push(fullPath);
|
|
25
27
|
}
|
|
26
28
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
-
import
|
|
4
|
-
import { runJourney, waive, signoff, renderJourneyBoard, rollupJourney, renderRollupBoard } from '../../harness/journey';
|
|
3
|
+
import { runJourney, renderJourneyBoard, rollupJourney, renderRollupBoard, writeJourneyFileBestEffort } from '../../harness/journey';
|
|
5
4
|
import { reportSlug } from '../../harness/unit-paths';
|
|
6
5
|
import { findUnitDir } from '../resolve-unit';
|
|
6
|
+
import { answerPendingMigration, decideWithConfirmation, DECIDE_KINDS, signoffWithConfirmation, waiveWithConfirmation } from '../../decisions/confirmed-decision-commands';
|
|
7
|
+
import { processIO } from '../../decisions/human-confirmation';
|
|
7
8
|
|
|
9
|
+
const collect = (value: string, previous: string[]): string[] => [...previous, value];
|
|
8
10
|
|
|
9
11
|
export function registerJourneyCommand(program: Command): void {
|
|
10
12
|
program
|
|
@@ -12,22 +14,41 @@ export function registerJourneyCommand(program: Command): void {
|
|
|
12
14
|
.description('Durable "you are here" board (#381): obligations + what-to-review + next, synthesised read-only from the audit report + ledger already on disk.')
|
|
13
15
|
.option('-s, --screen <name>', 'Screen / flow / api unit name')
|
|
14
16
|
.option('--all', 'Roll up every unit (screens + flows + api) into one board — the serial review surface for multi-unit fan-out')
|
|
15
|
-
.option('--waive <obligation>', 'Waive an obligation (e.g. OB-coverage) — requires --reason')
|
|
16
|
-
.option('--reason <text>', '
|
|
17
|
-
.option('--
|
|
17
|
+
.option('--waive <obligation>', 'Waive an obligation (e.g. OB-coverage) — requires --reason; a human types a confirmation on a TTY')
|
|
18
|
+
.option('--reason <text>', 'Why: mandatory with --waive and --decide')
|
|
19
|
+
.option('--decide <kind>', `Record a decision (${DECIDE_KINDS.join(' | ')}) in qa/decisions/, or the unit's with --screen — a human types a confirmation on a TTY`)
|
|
20
|
+
.option('--text <text>', 'What was decided (with --decide)')
|
|
21
|
+
.option('--anchor <id>', 'Spec anchor the decision is about, e.g. SPEC-AUTH-001#A-2 (repeatable, with --decide)', collect, [])
|
|
22
|
+
.option('--payload <json>', 'Kind-specific fields as a JSON object, e.g. a gate-override\'s {"rule","severity","scope"} (with --decide)')
|
|
23
|
+
.option('--visibility <v>', 'internal (default, never exported) | client (with --decide)')
|
|
24
|
+
.option('--supersedes <id>', 'The decision this one replaces — the old entry is never edited (with --decide)')
|
|
25
|
+
.option('--signoff', 'Sign off the review queue — the single human gate (allowed only when every other obligation is satisfied/waived); a human types a confirmation on a TTY')
|
|
18
26
|
.option('--by <name>', 'Who is signing off (recorded with --signoff)')
|
|
19
27
|
.option('--json', 'Output the raw JSON report')
|
|
20
|
-
.action((options) => {
|
|
28
|
+
.action(async (options) => {
|
|
29
|
+
const io = processIO();
|
|
21
30
|
try {
|
|
31
|
+
if (options.decide) {
|
|
32
|
+
if (options.screen && !findUnitDir(options.screen)) throw new Error(`Not found: qa/screens/${options.screen}, qa/flows/${options.screen}, or qa/api/${options.screen}`);
|
|
33
|
+
const r = await decideWithConfirmation({
|
|
34
|
+
projectRoot: process.cwd(), unit: options.screen, kind: options.decide, text: options.text, reason: options.reason,
|
|
35
|
+
anchors: options.anchor, payload: options.payload, visibility: options.visibility, supersedes: options.supersedes, io,
|
|
36
|
+
});
|
|
37
|
+
if (options.json) { console.log(JSON.stringify({ status: r.status, path: path.relative(process.cwd(), r.path), entry: r.entry }, null, 2)); return; }
|
|
38
|
+
console.log(`\n${r.status === 'created' ? '✓ Recorded' : '= Already recorded'} ${r.entry.id} → ${path.relative(process.cwd(), r.path)}`);
|
|
39
|
+
console.log(' Commit it through review: a decision not yet in git HEAD is flagged at delivery (decision.in-run).\n');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
22
43
|
if (options.all) {
|
|
23
44
|
const rows = rollupJourney(process.cwd());
|
|
24
45
|
const board = renderRollupBoard(rows);
|
|
25
46
|
const outDir = path.join(process.cwd(), '.sungen', 'journey');
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
47
|
+
// Derived files: a read-only checkout still gets the board (DOS-13.3).
|
|
48
|
+
writeJourneyFileBestEffort(path.join(outDir, '_rollup.json'), JSON.stringify(rows, null, 2));
|
|
49
|
+
const written = writeJourneyFileBestEffort(path.join(outDir, '_rollup.board.md'), board);
|
|
29
50
|
if (options.json) console.log(JSON.stringify(rows, null, 2));
|
|
30
|
-
else { console.log(''); console.log(board); console.log(` Board: ${path.relative(process.cwd(),
|
|
51
|
+
else { console.log(''); console.log(board); console.log(` Board: ${written ? path.relative(process.cwd(), written) : '(not written — read-only checkout)'}`); console.log(''); }
|
|
31
52
|
return;
|
|
32
53
|
}
|
|
33
54
|
|
|
@@ -35,25 +56,29 @@ export function registerJourneyCommand(program: Command): void {
|
|
|
35
56
|
if (!name) throw new Error('Provide --screen <name> (or --all for the roll-up)');
|
|
36
57
|
if (!findUnitDir(name)) throw new Error(`Not found: qa/screens/${name}, qa/flows/${name}, or qa/api/${name}`);
|
|
37
58
|
|
|
59
|
+
// A migration killed half-way (T6): a human answers REVERT or KEEP before anything else runs.
|
|
60
|
+
const restored = await answerPendingMigration(process.cwd(), name, io);
|
|
61
|
+
if (restored) io.output.write(` Interrupted migration resolved${restored.length ? ` — restored ${restored.length} file(s)` : ' — kept the new files'}.\n`);
|
|
62
|
+
|
|
38
63
|
const report = options.waive
|
|
39
|
-
?
|
|
64
|
+
? await waiveWithConfirmation({ projectRoot: process.cwd(), unit: name, obligation: options.waive, reason: options.reason || '', io })
|
|
40
65
|
: options.signoff
|
|
41
|
-
?
|
|
66
|
+
? await signoffWithConfirmation({ projectRoot: process.cwd(), unit: name, by: options.by, io })
|
|
42
67
|
: runJourney(process.cwd(), name);
|
|
43
68
|
|
|
44
69
|
const outDir = path.join(process.cwd(), '.sungen', 'journey');
|
|
45
|
-
fs.mkdirSync(outDir, { recursive: true });
|
|
46
70
|
const slug = reportSlug(name);
|
|
47
|
-
|
|
71
|
+
// Derived files: a read-only checkout still gets the board (DOS-13.3).
|
|
72
|
+
writeJourneyFileBestEffort(path.join(outDir, `${slug}.json`), JSON.stringify(report, null, 2));
|
|
48
73
|
const board = renderJourneyBoard(report);
|
|
49
|
-
|
|
74
|
+
const written = writeJourneyFileBestEffort(path.join(outDir, `${slug}.board.md`), board);
|
|
50
75
|
|
|
51
76
|
if (options.json) {
|
|
52
77
|
console.log(JSON.stringify(report, null, 2));
|
|
53
78
|
} else {
|
|
54
79
|
console.log('');
|
|
55
80
|
console.log(board);
|
|
56
|
-
console.log(` Board: ${path.relative(process.cwd(),
|
|
81
|
+
console.log(` Board: ${written ? path.relative(process.cwd(), written) : '(not written — read-only checkout)'}`);
|
|
57
82
|
console.log('');
|
|
58
83
|
}
|
|
59
84
|
} catch (error) {
|