@sun-asterisk/sungen 3.2.34 → 3.3.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/basis/anchor-grammar.d.ts +32 -0
- package/dist/basis/anchor-grammar.d.ts.map +1 -0
- package/dist/basis/anchor-grammar.js +82 -0
- package/dist/basis/anchor-grammar.js.map +1 -0
- package/dist/basis/anchor-hash.d.ts +6 -0
- package/dist/basis/anchor-hash.d.ts.map +1 -0
- package/dist/basis/anchor-hash.js +28 -0
- package/dist/basis/anchor-hash.js.map +1 -0
- package/dist/basis/bm51-tables.d.ts +20 -0
- package/dist/basis/bm51-tables.d.ts.map +1 -0
- package/dist/basis/bm51-tables.js +71 -0
- package/dist/basis/bm51-tables.js.map +1 -0
- package/dist/basis/extract-spec-anchors.d.ts +39 -0
- package/dist/basis/extract-spec-anchors.d.ts.map +1 -0
- package/dist/basis/extract-spec-anchors.js +81 -0
- package/dist/basis/extract-spec-anchors.js.map +1 -0
- package/dist/basis/migration-sentinel.d.ts +47 -0
- package/dist/basis/migration-sentinel.d.ts.map +1 -0
- package/dist/basis/migration-sentinel.js +219 -0
- package/dist/basis/migration-sentinel.js.map +1 -0
- package/dist/basis/spec-frontmatter.d.ts +18 -0
- package/dist/basis/spec-frontmatter.d.ts.map +1 -0
- package/dist/basis/spec-frontmatter.js +55 -0
- package/dist/basis/spec-frontmatter.js.map +1 -0
- package/dist/basis/spec-sections.d.ts +18 -0
- package/dist/basis/spec-sections.d.ts.map +1 -0
- package/dist/basis/spec-sections.js +27 -0
- package/dist/basis/spec-sections.js.map +1 -0
- package/dist/basis/test-basis-schema.d.ts +28 -0
- package/dist/basis/test-basis-schema.d.ts.map +1 -0
- package/dist/basis/test-basis-schema.js +141 -0
- package/dist/basis/test-basis-schema.js.map +1 -0
- package/dist/capabilities/registry.d.ts +15 -0
- package/dist/capabilities/registry.d.ts.map +1 -1
- package/dist/capabilities/registry.js.map +1 -1
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/audit.js +9 -4
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/capability.d.ts.map +1 -1
- package/dist/cli/commands/capability.js +6 -2
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/cli/commands/contract-derive-command.d.ts +10 -0
- package/dist/cli/commands/contract-derive-command.d.ts.map +1 -0
- package/dist/cli/commands/contract-derive-command.js +99 -0
- package/dist/cli/commands/contract-derive-command.js.map +1 -0
- package/dist/cli/commands/contract.d.ts +17 -0
- package/dist/cli/commands/contract.d.ts.map +1 -0
- package/dist/cli/commands/contract.js +162 -0
- package/dist/cli/commands/contract.js.map +1 -0
- package/dist/cli/commands/defect.d.ts +7 -0
- package/dist/cli/commands/defect.d.ts.map +1 -0
- package/dist/cli/commands/defect.js +68 -0
- package/dist/cli/commands/defect.js.map +1 -0
- package/dist/cli/commands/delivery.d.ts.map +1 -1
- package/dist/cli/commands/delivery.js +87 -10
- package/dist/cli/commands/delivery.js.map +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +3 -1
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/journey.d.ts.map +1 -1
- package/dist/cli/commands/journey.js +41 -13
- package/dist/cli/commands/journey.js.map +1 -1
- package/dist/cli/commands/next.d.ts +8 -0
- package/dist/cli/commands/next.d.ts.map +1 -1
- package/dist/cli/commands/next.js +64 -6
- package/dist/cli/commands/next.js.map +1 -1
- package/dist/cli/commands/triage.d.ts +7 -0
- package/dist/cli/commands/triage.d.ts.map +1 -0
- package/dist/cli/commands/triage.js +98 -0
- package/dist/cli/commands/triage.js.map +1 -0
- package/dist/cli/commands/update.d.ts +11 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +31 -6
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/index.js +24 -33
- package/dist/cli/index.js.map +1 -1
- package/dist/contract/approve-contract.d.ts +31 -0
- package/dist/contract/approve-contract.d.ts.map +1 -0
- package/dist/contract/approve-contract.js +87 -0
- package/dist/contract/approve-contract.js.map +1 -0
- package/dist/contract/assertion-matcher-vocabulary.d.ts +24 -0
- package/dist/contract/assertion-matcher-vocabulary.d.ts.map +1 -0
- package/dist/contract/assertion-matcher-vocabulary.js +100 -0
- package/dist/contract/assertion-matcher-vocabulary.js.map +1 -0
- package/dist/contract/build-contract-verdict.d.ts +32 -0
- package/dist/contract/build-contract-verdict.d.ts.map +1 -0
- package/dist/contract/build-contract-verdict.js +123 -0
- package/dist/contract/build-contract-verdict.js.map +1 -0
- package/dist/contract/build-trace-conformance.d.ts +18 -0
- package/dist/contract/build-trace-conformance.d.ts.map +1 -0
- package/dist/contract/build-trace-conformance.js +153 -0
- package/dist/contract/build-trace-conformance.js.map +1 -0
- package/dist/contract/classify-contract-change.d.ts +23 -0
- package/dist/contract/classify-contract-change.d.ts.map +1 -0
- package/dist/contract/classify-contract-change.js +98 -0
- package/dist/contract/classify-contract-change.js.map +1 -0
- package/dist/contract/classify-contract-unit.d.ts +18 -0
- package/dist/contract/classify-contract-unit.d.ts.map +1 -0
- package/dist/contract/classify-contract-unit.js +49 -0
- package/dist/contract/classify-contract-unit.js.map +1 -0
- package/dist/contract/classify-trace-conformance.d.ts +32 -0
- package/dist/contract/classify-trace-conformance.d.ts.map +1 -0
- package/dist/contract/classify-trace-conformance.js +117 -0
- package/dist/contract/classify-trace-conformance.js.map +1 -0
- package/dist/contract/contract-git.d.ts +24 -0
- package/dist/contract/contract-git.d.ts.map +1 -0
- package/dist/contract/contract-git.js +144 -0
- package/dist/contract/contract-git.js.map +1 -0
- package/dist/contract/contract-hash.d.ts +7 -0
- package/dist/contract/contract-hash.d.ts.map +1 -0
- package/dist/contract/contract-hash.js +38 -0
- package/dist/contract/contract-hash.js.map +1 -0
- package/dist/contract/contract-report-file.d.ts +4 -0
- package/dist/contract/contract-report-file.d.ts.map +1 -0
- package/dist/contract/contract-report-file.js +60 -0
- package/dist/contract/contract-report-file.js.map +1 -0
- package/dist/contract/contract-schema.d.ts +71 -0
- package/dist/contract/contract-schema.d.ts.map +1 -0
- package/dist/contract/contract-schema.js +102 -0
- package/dist/contract/contract-schema.js.map +1 -0
- package/dist/contract/contract-units.d.ts +12 -0
- package/dist/contract/contract-units.d.ts.map +1 -0
- package/dist/contract/contract-units.js +96 -0
- package/dist/contract/contract-units.js.map +1 -0
- package/dist/contract/contracts-lock-file.d.ts +24 -0
- package/dist/contract/contracts-lock-file.d.ts.map +1 -0
- package/dist/contract/contracts-lock-file.js +140 -0
- package/dist/contract/contracts-lock-file.js.map +1 -0
- package/dist/contract/data-normalize.d.ts +10 -0
- package/dist/contract/data-normalize.d.ts.map +1 -0
- package/dist/contract/data-normalize.js +110 -0
- package/dist/contract/data-normalize.js.map +1 -0
- package/dist/contract/derive-free-feature.d.ts +30 -0
- package/dist/contract/derive-free-feature.d.ts.map +1 -0
- package/dist/contract/derive-free-feature.js +145 -0
- package/dist/contract/derive-free-feature.js.map +1 -0
- package/dist/contract/field-semantic-redaction.d.ts +21 -0
- package/dist/contract/field-semantic-redaction.d.ts.map +1 -0
- package/dist/contract/field-semantic-redaction.js +118 -0
- package/dist/contract/field-semantic-redaction.js.map +1 -0
- package/dist/contract/free-feature-blocks.d.ts +10 -0
- package/dist/contract/free-feature-blocks.d.ts.map +1 -0
- package/dist/contract/free-feature-blocks.js +94 -0
- package/dist/contract/free-feature-blocks.js.map +1 -0
- package/dist/contract/lock-secret-guard.d.ts +22 -0
- package/dist/contract/lock-secret-guard.d.ts.map +1 -0
- package/dist/contract/lock-secret-guard.js +134 -0
- package/dist/contract/lock-secret-guard.js.map +1 -0
- package/dist/contract/lock-vs-git-head.d.ts +26 -0
- package/dist/contract/lock-vs-git-head.d.ts.map +1 -0
- package/dist/contract/lock-vs-git-head.js +28 -0
- package/dist/contract/lock-vs-git-head.js.map +1 -0
- package/dist/contract/normalize-contract-step.d.ts +21 -0
- package/dist/contract/normalize-contract-step.d.ts.map +1 -0
- package/dist/contract/normalize-contract-step.js +70 -0
- package/dist/contract/normalize-contract-step.js.map +1 -0
- package/dist/contract/normalize-feature-steps.d.ts +7 -0
- package/dist/contract/normalize-feature-steps.d.ts.map +1 -0
- package/dist/contract/normalize-feature-steps.js +127 -0
- package/dist/contract/normalize-feature-steps.js.map +1 -0
- package/dist/contract/oracle-strength.d.ts +12 -0
- package/dist/contract/oracle-strength.d.ts.map +1 -0
- package/dist/contract/oracle-strength.js +88 -0
- package/dist/contract/oracle-strength.js.map +1 -0
- package/dist/contract/project-contract-blockers.d.ts +10 -0
- package/dist/contract/project-contract-blockers.d.ts.map +1 -0
- package/dist/contract/project-contract-blockers.js +73 -0
- package/dist/contract/project-contract-blockers.js.map +1 -0
- package/dist/contract/record-contract-approval.d.ts +21 -0
- package/dist/contract/record-contract-approval.d.ts.map +1 -0
- package/dist/contract/record-contract-approval.js +98 -0
- package/dist/contract/record-contract-approval.js.map +1 -0
- package/dist/contract/render-free-gherkin.d.ts +40 -0
- package/dist/contract/render-free-gherkin.d.ts.map +1 -0
- package/dist/contract/render-free-gherkin.js +141 -0
- package/dist/contract/render-free-gherkin.js.map +1 -0
- package/dist/contract/render-trace-sentence.d.ts +20 -0
- package/dist/contract/render-trace-sentence.d.ts.map +1 -0
- package/dist/contract/render-trace-sentence.js +109 -0
- package/dist/contract/render-trace-sentence.js.map +1 -0
- package/dist/contract/render-trace-target.d.ts +14 -0
- package/dist/contract/render-trace-target.d.ts.map +1 -0
- package/dist/contract/render-trace-target.js +70 -0
- package/dist/contract/render-trace-target.js.map +1 -0
- package/dist/contract/resolve-unit-trace-identities.d.ts +8 -0
- package/dist/contract/resolve-unit-trace-identities.d.ts.map +1 -0
- package/dist/contract/resolve-unit-trace-identities.js +78 -0
- package/dist/contract/resolve-unit-trace-identities.js.map +1 -0
- package/dist/contract/trace/collect-trace-evidence.d.ts +33 -0
- package/dist/contract/trace/collect-trace-evidence.d.ts.map +1 -0
- package/dist/contract/trace/collect-trace-evidence.js +161 -0
- package/dist/contract/trace/collect-trace-evidence.js.map +1 -0
- package/dist/contract/trace/identity-cache.d.ts +19 -0
- package/dist/contract/trace/identity-cache.d.ts.map +1 -0
- package/dist/contract/trace/identity-cache.js +104 -0
- package/dist/contract/trace/identity-cache.js.map +1 -0
- package/dist/contract/trace/select-final-attempt.d.ts +27 -0
- package/dist/contract/trace/select-final-attempt.d.ts.map +1 -0
- package/dist/contract/trace/select-final-attempt.js +116 -0
- package/dist/contract/trace/select-final-attempt.js.map +1 -0
- package/dist/contract/trace/snapshot-html-renderer.d.ts +31 -0
- package/dist/contract/trace/snapshot-html-renderer.d.ts.map +1 -0
- package/dist/contract/trace/snapshot-html-renderer.js +172 -0
- package/dist/contract/trace/snapshot-html-renderer.js.map +1 -0
- package/dist/contract/trace/snapshot-resolver.d.ts +21 -0
- package/dist/contract/trace/snapshot-resolver.d.ts.map +1 -0
- package/dist/contract/trace/snapshot-resolver.js +65 -0
- package/dist/contract/trace/snapshot-resolver.js.map +1 -0
- package/dist/contract/trace/snapshot-store.d.ts +66 -0
- package/dist/contract/trace/snapshot-store.d.ts.map +1 -0
- package/dist/contract/trace/snapshot-store.js +173 -0
- package/dist/contract/trace/snapshot-store.js.map +1 -0
- package/dist/contract/trace/target-identity.d.ts +74 -0
- package/dist/contract/trace/target-identity.d.ts.map +1 -0
- package/dist/contract/trace/target-identity.js +68 -0
- package/dist/contract/trace/target-identity.js.map +1 -0
- package/dist/contract/trace/test-step-join.d.ts +65 -0
- package/dist/contract/trace/test-step-join.d.ts.map +1 -0
- package/dist/contract/trace/test-step-join.js +80 -0
- package/dist/contract/trace/test-step-join.js.map +1 -0
- package/dist/contract/trace/trace-binding.d.ts +21 -0
- package/dist/contract/trace/trace-binding.d.ts.map +1 -0
- package/dist/contract/trace/trace-binding.js +88 -0
- package/dist/contract/trace/trace-binding.js.map +1 -0
- package/dist/contract/trace/trace-file-reader.d.ts +35 -0
- package/dist/contract/trace/trace-file-reader.d.ts.map +1 -0
- package/dist/contract/trace/trace-file-reader.js +155 -0
- package/dist/contract/trace/trace-file-reader.js.map +1 -0
- package/dist/contract/trace/trace-fingerprint.d.ts +22 -0
- package/dist/contract/trace/trace-fingerprint.d.ts.map +1 -0
- package/dist/contract/trace/trace-fingerprint.js +96 -0
- package/dist/contract/trace/trace-fingerprint.js.map +1 -0
- package/dist/contract/trace/trace-identity-resolution.d.ts +26 -0
- package/dist/contract/trace/trace-identity-resolution.d.ts.map +1 -0
- package/dist/contract/trace/trace-identity-resolution.js +84 -0
- package/dist/contract/trace/trace-identity-resolution.js.map +1 -0
- package/dist/contract/trace/trace-run-record.d.ts +27 -0
- package/dist/contract/trace/trace-run-record.d.ts.map +1 -0
- package/dist/contract/trace/trace-run-record.js +115 -0
- package/dist/contract/trace/trace-run-record.js.map +1 -0
- package/dist/contract/trace/trace-steps.d.ts +19 -0
- package/dist/contract/trace/trace-steps.d.ts.map +1 -0
- package/dist/contract/trace/trace-steps.js +79 -0
- package/dist/contract/trace/trace-steps.js.map +1 -0
- package/dist/contract/trace/trace-zip-limits.d.ts +41 -0
- package/dist/contract/trace/trace-zip-limits.d.ts.map +1 -0
- package/dist/contract/trace/trace-zip-limits.js +48 -0
- package/dist/contract/trace/trace-zip-limits.js.map +1 -0
- package/dist/contract/trace/trace-zip-reader.d.ts +10 -0
- package/dist/contract/trace/trace-zip-reader.d.ts.map +1 -0
- package/dist/contract/trace/trace-zip-reader.js +186 -0
- package/dist/contract/trace/trace-zip-reader.js.map +1 -0
- package/dist/contract/verify-approval-decisions.d.ts +5 -0
- package/dist/contract/verify-approval-decisions.d.ts.map +1 -0
- package/dist/contract/verify-approval-decisions.js +104 -0
- package/dist/contract/verify-approval-decisions.js.map +1 -0
- package/dist/decisions/append-decision.d.ts +12 -0
- package/dist/decisions/append-decision.d.ts.map +1 -0
- package/dist/decisions/append-decision.js +73 -0
- package/dist/decisions/append-decision.js.map +1 -0
- package/dist/decisions/confirmed-decision-commands.d.ts +30 -0
- package/dist/decisions/confirmed-decision-commands.d.ts.map +1 -0
- package/dist/decisions/confirmed-decision-commands.js +172 -0
- package/dist/decisions/confirmed-decision-commands.js.map +1 -0
- package/dist/decisions/decision-file.d.ts +31 -0
- package/dist/decisions/decision-file.d.ts.map +1 -0
- package/dist/decisions/decision-file.js +139 -0
- package/dist/decisions/decision-file.js.map +1 -0
- package/dist/decisions/decision-identity.d.ts +12 -0
- package/dist/decisions/decision-identity.d.ts.map +1 -0
- package/dist/decisions/decision-identity.js +78 -0
- package/dist/decisions/decision-identity.js.map +1 -0
- package/dist/decisions/decision-integrity-check.d.ts +12 -0
- package/dist/decisions/decision-integrity-check.d.ts.map +1 -0
- package/dist/decisions/decision-integrity-check.js +102 -0
- package/dist/decisions/decision-integrity-check.js.map +1 -0
- package/dist/decisions/decision-schema.d.ts +42 -0
- package/dist/decisions/decision-schema.d.ts.map +1 -0
- package/dist/decisions/decision-schema.js +75 -0
- package/dist/decisions/decision-schema.js.map +1 -0
- package/dist/decisions/decision-source.d.ts +2 -0
- package/dist/decisions/decision-source.d.ts.map +1 -0
- package/dist/decisions/decision-source.js +18 -0
- package/dist/decisions/decision-source.js.map +1 -0
- package/dist/decisions/exclusive-file-create.d.ts +3 -0
- package/dist/decisions/exclusive-file-create.d.ts.map +1 -0
- package/dist/decisions/exclusive-file-create.js +84 -0
- package/dist/decisions/exclusive-file-create.js.map +1 -0
- package/dist/decisions/git-head-trust.d.ts +7 -0
- package/dist/decisions/git-head-trust.d.ts.map +1 -0
- package/dist/decisions/git-head-trust.js +76 -0
- package/dist/decisions/git-head-trust.js.map +1 -0
- package/dist/decisions/human-confirmation.d.ts +33 -0
- package/dist/decisions/human-confirmation.d.ts.map +1 -0
- package/dist/decisions/human-confirmation.js +155 -0
- package/dist/decisions/human-confirmation.js.map +1 -0
- package/dist/decisions/legacy-waiver-migration.d.ts +31 -0
- package/dist/decisions/legacy-waiver-migration.d.ts.map +1 -0
- package/dist/decisions/legacy-waiver-migration.js +170 -0
- package/dist/decisions/legacy-waiver-migration.js.map +1 -0
- package/dist/decisions/read-decisions.d.ts +19 -0
- package/dist/decisions/read-decisions.d.ts.map +1 -0
- package/dist/decisions/read-decisions.js +90 -0
- package/dist/decisions/read-decisions.js.map +1 -0
- package/dist/decisions/viewpoint-baseline-adapter.d.ts +7 -0
- package/dist/decisions/viewpoint-baseline-adapter.d.ts.map +1 -0
- package/dist/decisions/viewpoint-baseline-adapter.js +109 -0
- package/dist/decisions/viewpoint-baseline-adapter.js.map +1 -0
- package/dist/decisions/waiver-decisions.d.ts +24 -0
- package/dist/decisions/waiver-decisions.d.ts.map +1 -0
- package/dist/decisions/waiver-decisions.js +46 -0
- package/dist/decisions/waiver-decisions.js.map +1 -0
- package/dist/exporters/csv-exporter.d.ts +4 -0
- package/dist/exporters/csv-exporter.d.ts.map +1 -1
- package/dist/exporters/csv-exporter.js +1 -1
- package/dist/exporters/csv-exporter.js.map +1 -1
- package/dist/exporters/feature-parser.d.ts +8 -0
- package/dist/exporters/feature-parser.d.ts.map +1 -1
- package/dist/exporters/feature-parser.js +12 -0
- package/dist/exporters/feature-parser.js.map +1 -1
- package/dist/exporters/matrix/build.d.ts +3 -0
- package/dist/exporters/matrix/build.d.ts.map +1 -1
- package/dist/exporters/matrix/build.js +59 -19
- package/dist/exporters/matrix/build.js.map +1 -1
- package/dist/exporters/matrix/carry-manual-results.d.ts +19 -0
- package/dist/exporters/matrix/carry-manual-results.d.ts.map +1 -1
- package/dist/exporters/matrix/carry-manual-results.js +76 -6
- package/dist/exporters/matrix/carry-manual-results.js.map +1 -1
- package/dist/exporters/matrix/export.d.ts +8 -2
- package/dist/exporters/matrix/export.d.ts.map +1 -1
- package/dist/exporters/matrix/export.js +16 -3
- package/dist/exporters/matrix/export.js.map +1 -1
- package/dist/exporters/matrix/gates.d.ts +6 -1
- package/dist/exporters/matrix/gates.d.ts.map +1 -1
- package/dist/exporters/matrix/gates.js +57 -128
- package/dist/exporters/matrix/gates.js.map +1 -1
- package/dist/exporters/matrix/render-csv.d.ts.map +1 -1
- package/dist/exporters/matrix/render-csv.js +4 -1
- package/dist/exporters/matrix/render-csv.js.map +1 -1
- package/dist/exporters/matrix/render-gate-overrides-sheet.d.ts +13 -0
- package/dist/exporters/matrix/render-gate-overrides-sheet.d.ts.map +1 -0
- package/dist/exporters/matrix/render-gate-overrides-sheet.js +44 -0
- package/dist/exporters/matrix/render-gate-overrides-sheet.js.map +1 -0
- package/dist/exporters/matrix/render-xlsx.d.ts +1 -0
- package/dist/exporters/matrix/render-xlsx.d.ts.map +1 -1
- package/dist/exporters/matrix/render-xlsx.js +6 -0
- package/dist/exporters/matrix/render-xlsx.js.map +1 -1
- package/dist/exporters/matrix/types.d.ts +9 -1
- package/dist/exporters/matrix/types.d.ts.map +1 -1
- package/dist/exporters/matrix/types.js.map +1 -1
- package/dist/exporters/playwright-report-parser.d.ts.map +1 -1
- package/dist/exporters/playwright-report-parser.js +1 -0
- package/dist/exporters/playwright-report-parser.js.map +1 -1
- package/dist/exporters/scenario-merger.d.ts.map +1 -1
- package/dist/exporters/scenario-merger.js +2 -0
- package/dist/exporters/scenario-merger.js.map +1 -1
- package/dist/exporters/types.d.ts +5 -0
- package/dist/exporters/types.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +13 -0
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/graph/evaluate-graph.d.ts +21 -0
- package/dist/graph/evaluate-graph.d.ts.map +1 -0
- package/dist/graph/evaluate-graph.js +49 -0
- package/dist/graph/evaluate-graph.js.map +1 -0
- package/dist/graph/locate-finding.d.ts +20 -0
- package/dist/graph/locate-finding.d.ts.map +1 -0
- package/dist/graph/locate-finding.js +137 -0
- package/dist/graph/locate-finding.js.map +1 -0
- package/dist/graph/node-decl.d.ts +59 -0
- package/dist/graph/node-decl.d.ts.map +1 -0
- package/dist/graph/node-decl.js +8 -0
- package/dist/graph/node-decl.js.map +1 -0
- package/dist/graph/nodes/core-node-catalog.d.ts +7 -0
- package/dist/graph/nodes/core-node-catalog.d.ts.map +1 -0
- package/dist/graph/nodes/core-node-catalog.js +13 -0
- package/dist/graph/nodes/core-node-catalog.js.map +1 -0
- package/dist/graph/nodes/test-case-contract-nodes.d.ts +19 -0
- package/dist/graph/nodes/test-case-contract-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/test-case-contract-nodes.js +56 -0
- package/dist/graph/nodes/test-case-contract-nodes.js.map +1 -0
- package/dist/graph/nodes/test-case-nodes.d.ts +26 -0
- package/dist/graph/nodes/test-case-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/test-case-nodes.js +66 -0
- package/dist/graph/nodes/test-case-nodes.js.map +1 -0
- package/dist/graph/nodes/unit-audit-nodes.d.ts +18 -0
- package/dist/graph/nodes/unit-audit-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/unit-audit-nodes.js +95 -0
- package/dist/graph/nodes/unit-audit-nodes.js.map +1 -0
- package/dist/graph/nodes/unit-contract-node.d.ts +20 -0
- package/dist/graph/nodes/unit-contract-node.d.ts.map +1 -0
- package/dist/graph/nodes/unit-contract-node.js +81 -0
- package/dist/graph/nodes/unit-contract-node.js.map +1 -0
- package/dist/graph/nodes/unit-design-nodes.d.ts +14 -0
- package/dist/graph/nodes/unit-design-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/unit-design-nodes.js +90 -0
- package/dist/graph/nodes/unit-design-nodes.js.map +1 -0
- package/dist/graph/nodes/unit-execution-nodes.d.ts +16 -0
- package/dist/graph/nodes/unit-execution-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/unit-execution-nodes.js +79 -0
- package/dist/graph/nodes/unit-execution-nodes.js.map +1 -0
- package/dist/graph/test-case-identity.d.ts +13 -0
- package/dist/graph/test-case-identity.d.ts.map +1 -0
- package/dist/graph/test-case-identity.js +106 -0
- package/dist/graph/test-case-identity.js.map +1 -0
- package/dist/graph/test-case-results.d.ts +11 -0
- package/dist/graph/test-case-results.d.ts.map +1 -0
- package/dist/graph/test-case-results.js +137 -0
- package/dist/graph/test-case-results.js.map +1 -0
- package/dist/graph/test-case-satisfied.d.ts +25 -0
- package/dist/graph/test-case-satisfied.d.ts.map +1 -0
- package/dist/graph/test-case-satisfied.js +51 -0
- package/dist/graph/test-case-satisfied.js.map +1 -0
- package/dist/graph/test-case-state-shape.d.ts +67 -0
- package/dist/graph/test-case-state-shape.d.ts.map +1 -0
- package/dist/graph/test-case-state-shape.js +3 -0
- package/dist/graph/test-case-state-shape.js.map +1 -0
- package/dist/graph/test-case-states.d.ts +9 -0
- package/dist/graph/test-case-states.d.ts.map +1 -0
- package/dist/graph/test-case-states.js +116 -0
- package/dist/graph/test-case-states.js.map +1 -0
- package/dist/graph/unit-artifact-probes.d.ts +19 -0
- package/dist/graph/unit-artifact-probes.d.ts.map +1 -0
- package/dist/graph/unit-artifact-probes.js +133 -0
- package/dist/graph/unit-artifact-probes.js.map +1 -0
- package/dist/graph/unit-state-facts.d.ts +43 -0
- package/dist/graph/unit-state-facts.d.ts.map +1 -0
- package/dist/graph/unit-state-facts.js +87 -0
- package/dist/graph/unit-state-facts.js.map +1 -0
- package/dist/harness/audit.d.ts +11 -0
- package/dist/harness/audit.d.ts.map +1 -1
- package/dist/harness/audit.js +34 -9
- package/dist/harness/audit.js.map +1 -1
- package/dist/harness/catalog/gate-rules.yaml +647 -0
- package/dist/harness/counted-assertions.d.ts +2 -0
- package/dist/harness/counted-assertions.d.ts.map +1 -0
- package/dist/harness/counted-assertions.js +38 -0
- package/dist/harness/counted-assertions.js.map +1 -0
- package/dist/harness/defect-draft.d.ts +14 -0
- package/dist/harness/defect-draft.d.ts.map +1 -0
- package/dist/harness/defect-draft.js +143 -0
- package/dist/harness/defect-draft.js.map +1 -0
- package/dist/harness/defects.d.ts +24 -0
- package/dist/harness/defects.d.ts.map +1 -0
- package/dist/harness/defects.js +118 -0
- package/dist/harness/defects.js.map +1 -0
- package/dist/harness/gates/audit-gate-terms.d.ts +41 -0
- package/dist/harness/gates/audit-gate-terms.d.ts.map +1 -0
- package/dist/harness/gates/audit-gate-terms.js +72 -0
- package/dist/harness/gates/audit-gate-terms.js.map +1 -0
- package/dist/harness/gates/audit-gate-verdict.d.ts +31 -0
- package/dist/harness/gates/audit-gate-verdict.d.ts.map +1 -0
- package/dist/harness/gates/audit-gate-verdict.js +101 -0
- package/dist/harness/gates/audit-gate-verdict.js.map +1 -0
- package/dist/harness/gates/audit-input-hash.d.ts +4 -0
- package/dist/harness/gates/audit-input-hash.d.ts.map +1 -0
- package/dist/harness/gates/audit-input-hash.js +96 -0
- package/dist/harness/gates/audit-input-hash.js.map +1 -0
- package/dist/harness/gates/audit-report-verification.d.ts +32 -0
- package/dist/harness/gates/audit-report-verification.d.ts.map +1 -0
- package/dist/harness/gates/audit-report-verification.js +207 -0
- package/dist/harness/gates/audit-report-verification.js.map +1 -0
- package/dist/harness/gates/decisions-hash.d.ts +13 -0
- package/dist/harness/gates/decisions-hash.d.ts.map +1 -0
- package/dist/harness/gates/decisions-hash.js +72 -0
- package/dist/harness/gates/decisions-hash.js.map +1 -0
- package/dist/harness/gates/delivery-checklist.d.ts +21 -0
- package/dist/harness/gates/delivery-checklist.d.ts.map +1 -0
- package/dist/harness/gates/delivery-checklist.js +128 -0
- package/dist/harness/gates/delivery-checklist.js.map +1 -0
- package/dist/harness/gates/delivery-decision-gate.d.ts +29 -0
- package/dist/harness/gates/delivery-decision-gate.d.ts.map +1 -0
- package/dist/harness/gates/delivery-decision-gate.js +91 -0
- package/dist/harness/gates/delivery-decision-gate.js.map +1 -0
- package/dist/harness/gates/delivery-decision-step.d.ts +16 -0
- package/dist/harness/gates/delivery-decision-step.d.ts.map +1 -0
- package/dist/harness/gates/delivery-decision-step.js +71 -0
- package/dist/harness/gates/delivery-decision-step.js.map +1 -0
- package/dist/harness/gates/gate-override-report.d.ts +59 -0
- package/dist/harness/gates/gate-override-report.d.ts.map +1 -0
- package/dist/harness/gates/gate-override-report.js +86 -0
- package/dist/harness/gates/gate-override-report.js.map +1 -0
- package/dist/harness/gates/gate-override-scope.d.ts +18 -0
- package/dist/harness/gates/gate-override-scope.d.ts.map +1 -0
- package/dist/harness/gates/gate-override-scope.js +98 -0
- package/dist/harness/gates/gate-override-scope.js.map +1 -0
- package/dist/harness/gates/gate-override-validation.d.ts +25 -0
- package/dist/harness/gates/gate-override-validation.d.ts.map +1 -0
- package/dist/harness/gates/gate-override-validation.js +81 -0
- package/dist/harness/gates/gate-override-validation.js.map +1 -0
- package/dist/harness/gates/gate-rule-catalog.d.ts +24 -0
- package/dist/harness/gates/gate-rule-catalog.d.ts.map +1 -0
- package/dist/harness/gates/gate-rule-catalog.js +112 -0
- package/dist/harness/gates/gate-rule-catalog.js.map +1 -0
- package/dist/harness/gates/gate-terms.d.ts +33 -0
- package/dist/harness/gates/gate-terms.d.ts.map +1 -0
- package/dist/harness/gates/gate-terms.js +41 -0
- package/dist/harness/gates/gate-terms.js.map +1 -0
- package/dist/harness/gates/in-run-decision-check.d.ts +21 -0
- package/dist/harness/gates/in-run-decision-check.d.ts.map +1 -0
- package/dist/harness/gates/in-run-decision-check.js +138 -0
- package/dist/harness/gates/in-run-decision-check.js.map +1 -0
- package/dist/harness/gates/journey-gate-inputs.d.ts +37 -0
- package/dist/harness/gates/journey-gate-inputs.d.ts.map +1 -0
- package/dist/harness/gates/journey-gate-inputs.js +81 -0
- package/dist/harness/gates/journey-gate-inputs.js.map +1 -0
- package/dist/harness/gates/migrated-waiver-review.d.ts +6 -0
- package/dist/harness/gates/migrated-waiver-review.d.ts.map +1 -0
- package/dist/harness/gates/migrated-waiver-review.js +116 -0
- package/dist/harness/gates/migrated-waiver-review.js.map +1 -0
- package/dist/harness/gates/resolve-rule.d.ts +59 -0
- package/dist/harness/gates/resolve-rule.d.ts.map +1 -0
- package/dist/harness/gates/resolve-rule.js +41 -0
- package/dist/harness/gates/resolve-rule.js.map +1 -0
- package/dist/harness/gates/unit-gate-overrides.d.ts +25 -0
- package/dist/harness/gates/unit-gate-overrides.d.ts.map +1 -0
- package/dist/harness/gates/unit-gate-overrides.js +122 -0
- package/dist/harness/gates/unit-gate-overrides.js.map +1 -0
- package/dist/harness/journey.d.ts +24 -1
- package/dist/harness/journey.d.ts.map +1 -1
- package/dist/harness/journey.js +114 -23
- package/dist/harness/journey.js.map +1 -1
- package/dist/harness/manifest.d.ts +12 -0
- package/dist/harness/manifest.d.ts.map +1 -1
- package/dist/harness/manifest.js +73 -45
- package/dist/harness/manifest.js.map +1 -1
- package/dist/harness/next-step.d.ts +37 -6
- package/dist/harness/next-step.d.ts.map +1 -1
- package/dist/harness/next-step.js +34 -174
- package/dist/harness/next-step.js.map +1 -1
- package/dist/harness/parse.d.ts +25 -0
- package/dist/harness/parse.d.ts.map +1 -1
- package/dist/harness/parse.js +38 -13
- package/dist/harness/parse.js.map +1 -1
- package/dist/harness/script-check.d.ts.map +1 -1
- package/dist/harness/script-check.js +29 -6
- package/dist/harness/script-check.js.map +1 -1
- package/dist/harness/sensors.d.ts +14 -3
- package/dist/harness/sensors.d.ts.map +1 -1
- package/dist/harness/sensors.js +64 -44
- package/dist/harness/sensors.js.map +1 -1
- package/dist/harness/triage-signals.d.ts +20 -0
- package/dist/harness/triage-signals.d.ts.map +1 -0
- package/dist/harness/triage-signals.js +30 -0
- package/dist/harness/triage-signals.js.map +1 -0
- package/dist/harness/triage-unit.d.ts +23 -0
- package/dist/harness/triage-unit.d.ts.map +1 -0
- package/dist/harness/triage-unit.js +142 -0
- package/dist/harness/triage-unit.js.map +1 -0
- package/dist/harness/triage.d.ts +28 -0
- package/dist/harness/triage.d.ts.map +1 -0
- package/dist/harness/triage.js +99 -0
- package/dist/harness/triage.js.map +1 -0
- package/dist/harness/viewpoint-ledger.d.ts.map +1 -1
- package/dist/harness/viewpoint-ledger.js +2 -1
- package/dist/harness/viewpoint-ledger.js.map +1 -1
- package/dist/hooks/bash-write-targets.d.ts +15 -0
- package/dist/hooks/bash-write-targets.d.ts.map +1 -0
- package/dist/hooks/bash-write-targets.js +173 -0
- package/dist/hooks/bash-write-targets.js.map +1 -0
- package/dist/hooks/claude-hook-entry.d.ts +11 -0
- package/dist/hooks/claude-hook-entry.d.ts.map +1 -0
- package/dist/hooks/claude-hook-entry.js +137 -0
- package/dist/hooks/claude-hook-entry.js.map +1 -0
- package/dist/hooks/claude-transcript-turn.d.ts +11 -0
- package/dist/hooks/claude-transcript-turn.d.ts.map +1 -0
- package/dist/hooks/claude-transcript-turn.js +143 -0
- package/dist/hooks/claude-transcript-turn.js.map +1 -0
- package/dist/hooks/guard-delivery-contract-rule.d.ts +10 -0
- package/dist/hooks/guard-delivery-contract-rule.d.ts.map +1 -0
- package/dist/hooks/guard-delivery-contract-rule.js +152 -0
- package/dist/hooks/guard-delivery-contract-rule.js.map +1 -0
- package/dist/hooks/guard-protected-paths.d.ts +9 -0
- package/dist/hooks/guard-protected-paths.d.ts.map +1 -0
- package/dist/hooks/guard-protected-paths.js +106 -0
- package/dist/hooks/guard-protected-paths.js.map +1 -0
- package/dist/hooks/guard-rules.d.ts +37 -0
- package/dist/hooks/guard-rules.d.ts.map +1 -0
- package/dist/hooks/guard-rules.js +61 -0
- package/dist/hooks/guard-rules.js.map +1 -0
- package/dist/hooks/guard-tty-spoof-rule.d.ts +15 -0
- package/dist/hooks/guard-tty-spoof-rule.d.ts.map +1 -0
- package/dist/hooks/guard-tty-spoof-rule.js +21 -0
- package/dist/hooks/guard-tty-spoof-rule.js.map +1 -0
- package/dist/hooks/hand-back-core.d.ts +37 -0
- package/dist/hooks/hand-back-core.d.ts.map +1 -0
- package/dist/hooks/hand-back-core.js +115 -0
- package/dist/hooks/hand-back-core.js.map +1 -0
- package/dist/hooks/hook-cli-command.d.ts +9 -0
- package/dist/hooks/hook-cli-command.d.ts.map +1 -0
- package/dist/hooks/hook-cli-command.js +46 -0
- package/dist/hooks/hook-cli-command.js.map +1 -0
- package/dist/hooks/hook-registry.d.ts +10 -0
- package/dist/hooks/hook-registry.d.ts.map +1 -0
- package/dist/hooks/hook-registry.js +24 -0
- package/dist/hooks/hook-registry.js.map +1 -0
- package/dist/hooks/hook-result-contract.d.ts +50 -0
- package/dist/hooks/hook-result-contract.d.ts.map +1 -0
- package/dist/hooks/hook-result-contract.js +80 -0
- package/dist/hooks/hook-result-contract.js.map +1 -0
- package/dist/hooks/hook-toggles.d.ts +10 -0
- package/dist/hooks/hook-toggles.d.ts.map +1 -0
- package/dist/hooks/hook-toggles.js +107 -0
- package/dist/hooks/hook-toggles.js.map +1 -0
- package/dist/hooks/pre-tool-guard-hook.d.ts +10 -0
- package/dist/hooks/pre-tool-guard-hook.d.ts.map +1 -0
- package/dist/hooks/pre-tool-guard-hook.js +105 -0
- package/dist/hooks/pre-tool-guard-hook.js.map +1 -0
- package/dist/hooks/session-start-unit-state-hook.d.ts +13 -0
- package/dist/hooks/session-start-unit-state-hook.d.ts.map +1 -0
- package/dist/hooks/session-start-unit-state-hook.js +55 -0
- package/dist/hooks/session-start-unit-state-hook.js.map +1 -0
- package/dist/hooks/stop-next-step-hook.d.ts +16 -0
- package/dist/hooks/stop-next-step-hook.d.ts.map +1 -0
- package/dist/hooks/stop-next-step-hook.js +42 -0
- package/dist/hooks/stop-next-step-hook.js.map +1 -0
- package/dist/hooks/sungen-project-root.d.ts +19 -0
- package/dist/hooks/sungen-project-root.d.ts.map +1 -0
- package/dist/hooks/sungen-project-root.js +130 -0
- package/dist/hooks/sungen-project-root.js.map +1 -0
- package/dist/orchestrator/ai-skills/command-partial-includes.d.ts +15 -0
- package/dist/orchestrator/ai-skills/command-partial-includes.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/command-partial-includes.js +106 -0
- package/dist/orchestrator/ai-skills/command-partial-includes.js.map +1 -0
- package/dist/orchestrator/ai-skills/commands.d.ts +5 -1
- package/dist/orchestrator/ai-skills/commands.d.ts.map +1 -1
- package/dist/orchestrator/ai-skills/commands.js +16 -6
- package/dist/orchestrator/ai-skills/commands.js.map +1 -1
- package/dist/orchestrator/ai-skills/golden-skills.test.js +29 -0
- package/dist/orchestrator/ai-skills/golden-skills.test.js.map +1 -1
- package/dist/orchestrator/claude-hooks-install.d.ts +27 -0
- package/dist/orchestrator/claude-hooks-install.d.ts.map +1 -0
- package/dist/orchestrator/claude-hooks-install.js +203 -0
- package/dist/orchestrator/claude-hooks-install.js.map +1 -0
- package/dist/orchestrator/lockstep-version.d.ts +15 -5
- package/dist/orchestrator/lockstep-version.d.ts.map +1 -1
- package/dist/orchestrator/lockstep-version.js +30 -17
- package/dist/orchestrator/lockstep-version.js.map +1 -1
- package/dist/orchestrator/project-initializer.d.ts +6 -0
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +23 -0
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/screen-manager.d.ts.map +1 -1
- package/dist/orchestrator/screen-manager.js +4 -2
- package/dist/orchestrator/screen-manager.js.map +1 -1
- package/dist/orchestrator/templates/ai-src/commands/add-api.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/add-flow.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/add-screen.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/create-data-test.md +1 -0
- package/dist/orchestrator/templates/ai-src/commands/create-test.md +14 -16
- package/dist/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/delivery.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/design.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/feedback.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/locale.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/review.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/run-test.md +14 -10
- package/dist/orchestrator/templates/ai-src/config/claude.md +20 -7
- package/dist/orchestrator/templates/ai-src/config/copilot.md +20 -7
- package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.claude.md +20 -0
- package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.codex.md +20 -0
- package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.copilot.md +20 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-api-coverage-model/SKILL.md +1 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md +3 -3
- package/dist/orchestrator/templates/ai-src/skills/sungen-data-factory/SKILL.md +9 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +2 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +1 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md +2 -0
- package/dist/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
- package/dist/utils/safe-yaml-parse.d.ts +8 -0
- package/dist/utils/safe-yaml-parse.d.ts.map +1 -0
- package/dist/utils/safe-yaml-parse.js +51 -0
- package/dist/utils/safe-yaml-parse.js.map +1 -0
- package/package.json +3 -3
- package/src/basis/anchor-grammar.ts +83 -0
- package/src/basis/anchor-hash.ts +27 -0
- package/src/basis/bm51-tables.ts +65 -0
- package/src/basis/extract-spec-anchors.ts +95 -0
- package/src/basis/migration-sentinel.ts +175 -0
- package/src/basis/spec-frontmatter.ts +68 -0
- package/src/basis/spec-sections.ts +35 -0
- package/src/basis/test-basis-schema.ts +81 -0
- package/src/capabilities/registry.ts +16 -0
- package/src/cli/commands/audit.ts +9 -4
- package/src/cli/commands/capability.ts +4 -2
- package/src/cli/commands/contract-derive-command.ts +60 -0
- package/src/cli/commands/contract.ts +130 -0
- package/src/cli/commands/defect.ts +49 -0
- package/src/cli/commands/delivery.ts +85 -13
- package/src/cli/commands/generate.ts +3 -1
- package/src/cli/commands/journey.ts +39 -14
- package/src/cli/commands/next.ts +60 -8
- package/src/cli/commands/triage.ts +57 -0
- package/src/cli/commands/update.ts +35 -8
- package/src/cli/index.ts +24 -30
- package/src/contract/approve-contract.ts +94 -0
- package/src/contract/assertion-matcher-vocabulary.ts +93 -0
- package/src/contract/build-contract-verdict.ts +108 -0
- package/src/contract/build-trace-conformance.ts +100 -0
- package/src/contract/classify-contract-change.ts +92 -0
- package/src/contract/classify-contract-unit.ts +47 -0
- package/src/contract/classify-trace-conformance.ts +116 -0
- package/src/contract/contract-git.ts +106 -0
- package/src/contract/contract-hash.ts +34 -0
- package/src/contract/contract-report-file.ts +25 -0
- package/src/contract/contract-schema.ts +137 -0
- package/src/contract/contract-units.ts +52 -0
- package/src/contract/contracts-lock-file.ts +97 -0
- package/src/contract/data-normalize.ts +66 -0
- package/src/contract/derive-free-feature.ts +110 -0
- package/src/contract/field-semantic-redaction.ts +80 -0
- package/src/contract/free-feature-blocks.ts +56 -0
- package/src/contract/lock-secret-guard.ts +95 -0
- package/src/contract/lock-vs-git-head.ts +38 -0
- package/src/contract/normalize-contract-step.ts +74 -0
- package/src/contract/normalize-feature-steps.ts +93 -0
- package/src/contract/oracle-strength.ts +80 -0
- package/src/contract/project-contract-blockers.ts +36 -0
- package/src/contract/record-contract-approval.ts +70 -0
- package/src/contract/render-free-gherkin.ts +113 -0
- package/src/contract/render-trace-sentence.ts +98 -0
- package/src/contract/render-trace-target.ts +68 -0
- package/src/contract/resolve-unit-trace-identities.ts +35 -0
- package/src/contract/trace/collect-trace-evidence.ts +109 -0
- package/src/contract/trace/identity-cache.ts +61 -0
- package/src/contract/trace/select-final-attempt.ts +70 -0
- package/src/contract/trace/snapshot-html-renderer.ts +136 -0
- package/src/contract/trace/snapshot-resolver.ts +66 -0
- package/src/contract/trace/snapshot-store.ts +151 -0
- package/src/contract/trace/target-identity.ts +104 -0
- package/src/contract/trace/test-step-join.ts +103 -0
- package/src/contract/trace/trace-binding.ts +56 -0
- package/src/contract/trace/trace-file-reader.ts +123 -0
- package/src/contract/trace/trace-fingerprint.ts +68 -0
- package/src/contract/trace/trace-identity-resolution.ts +74 -0
- package/src/contract/trace/trace-run-record.ts +74 -0
- package/src/contract/trace/trace-steps.ts +88 -0
- package/src/contract/trace/trace-zip-limits.ts +73 -0
- package/src/contract/trace/trace-zip-reader.ts +127 -0
- package/src/contract/verify-approval-decisions.ts +60 -0
- package/src/decisions/append-decision.ts +35 -0
- package/src/decisions/confirmed-decision-commands.ts +128 -0
- package/src/decisions/decision-file.ts +93 -0
- package/src/decisions/decision-identity.ts +73 -0
- package/src/decisions/decision-integrity-check.ts +61 -0
- package/src/decisions/decision-schema.ts +76 -0
- package/src/decisions/decision-source.ts +14 -0
- package/src/decisions/exclusive-file-create.ts +42 -0
- package/src/decisions/git-head-trust.ts +32 -0
- package/src/decisions/human-confirmation.ts +114 -0
- package/src/decisions/legacy-waiver-migration.ts +135 -0
- package/src/decisions/read-decisions.ts +61 -0
- package/src/decisions/viewpoint-baseline-adapter.ts +74 -0
- package/src/decisions/waiver-decisions.ts +56 -0
- package/src/exporters/csv-exporter.ts +5 -1
- package/src/exporters/feature-parser.ts +12 -0
- package/src/exporters/matrix/build.ts +62 -18
- package/src/exporters/matrix/carry-manual-results.ts +70 -7
- package/src/exporters/matrix/export.ts +17 -2
- package/src/exporters/matrix/gates.ts +62 -129
- package/src/exporters/matrix/render-csv.ts +4 -1
- package/src/exporters/matrix/render-gate-overrides-sheet.ts +50 -0
- package/src/exporters/matrix/render-xlsx.ts +6 -0
- package/src/exporters/matrix/types.ts +9 -1
- package/src/exporters/playwright-report-parser.ts +1 -0
- package/src/exporters/scenario-merger.ts +2 -1
- package/src/exporters/types.ts +5 -0
- package/src/generators/test-generator/code-generator.ts +13 -0
- package/src/graph/evaluate-graph.ts +62 -0
- package/src/graph/locate-finding.ts +93 -0
- package/src/graph/node-decl.ts +65 -0
- package/src/graph/nodes/core-node-catalog.ts +15 -0
- package/src/graph/nodes/test-case-contract-nodes.ts +69 -0
- package/src/graph/nodes/test-case-nodes.ts +68 -0
- package/src/graph/nodes/unit-audit-nodes.ts +95 -0
- package/src/graph/nodes/unit-contract-node.ts +82 -0
- package/src/graph/nodes/unit-design-nodes.ts +88 -0
- package/src/graph/nodes/unit-execution-nodes.ts +77 -0
- package/src/graph/test-case-identity.ts +75 -0
- package/src/graph/test-case-results.ts +90 -0
- package/src/graph/test-case-satisfied.ts +55 -0
- package/src/graph/test-case-state-shape.ts +62 -0
- package/src/graph/test-case-states.ts +84 -0
- package/src/graph/unit-artifact-probes.ts +77 -0
- package/src/graph/unit-state-facts.ts +112 -0
- package/src/harness/audit.ts +46 -11
- package/src/harness/catalog/gate-rules.yaml +647 -0
- package/src/harness/counted-assertions.ts +33 -0
- package/src/harness/defect-draft.ts +115 -0
- package/src/harness/defects.ts +94 -0
- package/src/harness/gates/audit-gate-terms.ts +80 -0
- package/src/harness/gates/audit-gate-verdict.ts +78 -0
- package/src/harness/gates/audit-input-hash.ts +55 -0
- package/src/harness/gates/audit-report-verification.ts +173 -0
- package/src/harness/gates/decisions-hash.ts +42 -0
- package/src/harness/gates/delivery-checklist.ts +120 -0
- package/src/harness/gates/delivery-decision-gate.ts +111 -0
- package/src/harness/gates/delivery-decision-step.ts +73 -0
- package/src/harness/gates/gate-override-report.ts +114 -0
- package/src/harness/gates/gate-override-scope.ts +66 -0
- package/src/harness/gates/gate-override-validation.ts +75 -0
- package/src/harness/gates/gate-rule-catalog.ts +82 -0
- package/src/harness/gates/gate-terms.ts +59 -0
- package/src/harness/gates/in-run-decision-check.ts +99 -0
- package/src/harness/gates/journey-gate-inputs.ts +89 -0
- package/src/harness/gates/migrated-waiver-review.ts +68 -0
- package/src/harness/gates/resolve-rule.ts +94 -0
- package/src/harness/gates/unit-gate-overrides.ts +99 -0
- package/src/harness/journey.ts +122 -27
- package/src/harness/manifest.ts +69 -45
- package/src/harness/next-step.ts +60 -170
- package/src/harness/parse.ts +40 -13
- package/src/harness/script-check.ts +27 -6
- package/src/harness/sensors.ts +73 -47
- package/src/harness/triage-signals.ts +46 -0
- package/src/harness/triage-unit.ts +113 -0
- package/src/harness/triage.ts +127 -0
- package/src/harness/viewpoint-ledger.ts +2 -2
- package/src/hooks/bash-write-targets.ts +109 -0
- package/src/hooks/claude-hook-entry.ts +85 -0
- package/src/hooks/claude-transcript-turn.ts +96 -0
- package/src/hooks/guard-delivery-contract-rule.ts +110 -0
- package/src/hooks/guard-protected-paths.ts +70 -0
- package/src/hooks/guard-rules.ts +98 -0
- package/src/hooks/guard-tty-spoof-rule.ts +31 -0
- package/src/hooks/hand-back-core.ts +106 -0
- package/src/hooks/hook-cli-command.ts +17 -0
- package/src/hooks/hook-registry.ts +24 -0
- package/src/hooks/hook-result-contract.ts +114 -0
- package/src/hooks/hook-toggles.ts +66 -0
- package/src/hooks/pre-tool-guard-hook.ts +67 -0
- package/src/hooks/session-start-unit-state-hook.ts +54 -0
- package/src/hooks/stop-next-step-hook.ts +37 -0
- package/src/hooks/sungen-project-root.ts +80 -0
- package/src/orchestrator/ai-skills/command-partial-includes.ts +72 -0
- package/src/orchestrator/ai-skills/commands.ts +22 -8
- package/src/orchestrator/ai-skills/golden-skills.test.ts +23 -0
- package/src/orchestrator/claude-hooks-install.ts +168 -0
- package/src/orchestrator/lockstep-version.ts +28 -15
- package/src/orchestrator/project-initializer.ts +21 -0
- package/src/orchestrator/screen-manager.ts +3 -1
- package/src/orchestrator/templates/ai-src/commands/add-api.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/add-flow.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/add-screen.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/create-data-test.md +1 -0
- package/src/orchestrator/templates/ai-src/commands/create-test.md +14 -16
- package/src/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/delivery.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/design.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/feedback.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/locale.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/review.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/run-test.md +14 -10
- package/src/orchestrator/templates/ai-src/config/claude.md +20 -7
- package/src/orchestrator/templates/ai-src/config/copilot.md +20 -7
- package/src/orchestrator/templates/ai-src/partials/hand-back-rule.claude.md +20 -0
- package/src/orchestrator/templates/ai-src/partials/hand-back-rule.codex.md +20 -0
- package/src/orchestrator/templates/ai-src/partials/hand-back-rule.copilot.md +20 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-api-coverage-model/SKILL.md +1 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md +3 -3
- package/src/orchestrator/templates/ai-src/skills/sungen-data-factory/SKILL.md +9 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +2 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +1 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md +2 -0
- package/src/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
- package/src/utils/safe-yaml-parse.ts +44 -0
|
@@ -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 trace: 'on' and 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,18 +690,22 @@ 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
|
}
|
|
@@ -707,6 +725,18 @@ async function exportMatrixTarget(
|
|
|
707
725
|
return null;
|
|
708
726
|
}
|
|
709
727
|
|
|
728
|
+
// The tester's recorded Manual results are part of the outcome: read them BEFORE anything is
|
|
729
|
+
// counted, so this line, the workbook's totals and the summary table all agree (#891). A file
|
|
730
|
+
// that cannot be read is reported where it matters — when it would be overwritten.
|
|
731
|
+
const format = opts.format ?? 'xlsx';
|
|
732
|
+
let prior: PriorManualResults | null = null;
|
|
733
|
+
let priorError: Error | null = null;
|
|
734
|
+
try { prior = await readPriorManualResults(deliverableXlsxPath(cwd, paths.unit)); }
|
|
735
|
+
// A CSV-only export overwrites no workbook, so an unreadable one only means "nothing to carry".
|
|
736
|
+
catch (e) { if (format !== 'csv') priorError = e as Error; }
|
|
737
|
+
applyManualCarry(model, prior);
|
|
738
|
+
model.gateOverrides = deliverableGateOverrides(decisions?.overridesFor(qaDir(cwd, target)) ?? [], hasReview(model.findings), decisions?.acceptedInRun);
|
|
739
|
+
|
|
710
740
|
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
741
|
{
|
|
712
742
|
const mocked = model.items.flatMap((it) => it.variants.filter((v) => v.mocked));
|
|
@@ -741,7 +771,8 @@ async function exportMatrixTarget(
|
|
|
741
771
|
|
|
742
772
|
let deliverables: Awaited<ReturnType<typeof writeMatrixDeliverables>>;
|
|
743
773
|
try {
|
|
744
|
-
|
|
774
|
+
if (priorError) throw priorError;
|
|
775
|
+
deliverables = await writeMatrixDeliverables(paths, model, format, prior);
|
|
745
776
|
} catch (e) {
|
|
746
777
|
// The existing workbook could not be read, so writing would destroy its Manual results.
|
|
747
778
|
log(` ${COLOR.red}not written:${COLOR.reset} ${(e as Error).message}`);
|
|
@@ -869,6 +900,19 @@ function printSummaryTable(summaries: ScreenSummary[]): void {
|
|
|
869
900
|
}
|
|
870
901
|
}
|
|
871
902
|
|
|
903
|
+
/** T6: one checklist block per delivered unit, each box from what its command says now (delivery-checklist.ts). */
|
|
904
|
+
async function printDeliveryChecklist(cwd: string, targets: DeliveryTarget[], accepted?: InRunAcceptance): Promise<void> {
|
|
905
|
+
const units = new Map<string, ChecklistUnit>();
|
|
906
|
+
for (const t of targets) {
|
|
907
|
+
const dir = qaDir(cwd, t);
|
|
908
|
+
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) });
|
|
909
|
+
}
|
|
910
|
+
const rows: Array<{ label: string; boxes: Awaited<ReturnType<typeof unitChecklist>> }> = [];
|
|
911
|
+
for (const u of units.values()) rows.push({ label: u.label, boxes: await unitChecklist(cwd, u, accepted) });
|
|
912
|
+
log('');
|
|
913
|
+
for (const line of renderChecklist(rows)) log(line);
|
|
914
|
+
}
|
|
915
|
+
|
|
872
916
|
// ----------------------------------------------------------------------------
|
|
873
917
|
// Command registration
|
|
874
918
|
// ----------------------------------------------------------------------------
|
|
@@ -887,10 +931,11 @@ export function registerDeliveryCommand(program: Command): void {
|
|
|
887
931
|
.option('--approve [ids]', 'Approve proposed groups (all, or a comma-separated id list) + stamp fingerprints')
|
|
888
932
|
.option('--preview', 'Render the matrix despite review-required findings (DRAFT watermark)')
|
|
889
933
|
.option('--format <format>', 'Matrix output format: xlsx (default) | csv | both', 'xlsx')
|
|
934
|
+
.option('--accept-in-run', 'Deliver despite gate-overrides/waivers/approvals recorded during the run (decision.in-run) — a human confirms on a terminal')
|
|
890
935
|
.action(async (names: string[], options: {
|
|
891
936
|
skipPreflight?: boolean; continueOnMissing?: boolean; env?: string;
|
|
892
937
|
legacy?: boolean; full?: boolean; check?: boolean; approve?: boolean | string; preview?: boolean;
|
|
893
|
-
format?: string;
|
|
938
|
+
format?: string; acceptInRun?: boolean;
|
|
894
939
|
}) => {
|
|
895
940
|
try {
|
|
896
941
|
// Same effect as running with SUNGEN_ENV=<env> — result-file resolution,
|
|
@@ -967,6 +1012,30 @@ export function registerDeliveryCommand(program: Command): void {
|
|
|
967
1012
|
.reduce<SecretScanResult>((a, r) => ({ hits: [...a.hits, ...r.hits], unscanned: [...a.unscanned, ...r.unscanned] }), { hits: [], unscanned: [] });
|
|
968
1013
|
for (const line of formatSecretScan(secretScan)) log(line);
|
|
969
1014
|
|
|
1015
|
+
// OES-11.3–11.5: decisions that do not verify, rejected overrides, a stale audit and in-run
|
|
1016
|
+
// decisions stop the delivery before anything is written (approval only stamps the map).
|
|
1017
|
+
let decisions: DeliveryDecisionGate | undefined;
|
|
1018
|
+
// --approve only stamps a matrix map. With --legacy / --full it would skip this gate and
|
|
1019
|
+
// fall through to the export, so the combination is refused before anything is written.
|
|
1020
|
+
if (options.approve !== undefined && (options.legacy || options.full)) {
|
|
1021
|
+
console.error(`${COLOR.red}--approve applies to the matrix deliverable only${COLOR.reset} — it cannot be combined with --legacy / --full`);
|
|
1022
|
+
process.exit(1);
|
|
1023
|
+
}
|
|
1024
|
+
if (options.approve === undefined) {
|
|
1025
|
+
const gate = await runDeliveryDecisionStep({
|
|
1026
|
+
projectRoot: cwd, acceptInRun: !!options.acceptInRun, io: processIO(), log,
|
|
1027
|
+
// --preview / --check soften only the matrix export; --legacy has no draft mode, so it always needs one.
|
|
1028
|
+
requireTrustedAudit: !!(options.legacy || options.full) || (!options.preview && !options.check),
|
|
1029
|
+
refs: toExport.map((t) => ({ label: t.isFlow ? `flow/${t.featureBaseName}` : t.featureBaseName, unitName: t.screen, unitDir: qaDir(cwd, t), resultsPath: resolveResultsPath(cwd, t) })),
|
|
1030
|
+
argv: ['sungen', 'delivery', ...(names ?? []), ...(options.env ? ['--env', options.env] : []), ...(options.legacy || options.full ? ['--legacy'] : [])],
|
|
1031
|
+
});
|
|
1032
|
+
if (!gate) {
|
|
1033
|
+
await printDeliveryChecklist(cwd, toExport);
|
|
1034
|
+
process.exit(1);
|
|
1035
|
+
}
|
|
1036
|
+
decisions = gate;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
970
1039
|
// 3. Export
|
|
971
1040
|
const legacy = options.legacy || options.full;
|
|
972
1041
|
if (!legacy) {
|
|
@@ -981,9 +1050,9 @@ export function registerDeliveryCommand(program: Command): void {
|
|
|
981
1050
|
// Same contract as the export path: an all-@exploration feature has no
|
|
982
1051
|
// deliverable variants, so there is no map to approve — skip, not an error.
|
|
983
1052
|
{
|
|
984
|
-
const
|
|
985
|
-
if (
|
|
986
|
-
&&
|
|
1053
|
+
const scenarios = parseFeatureMetadata(paths.featureFile).scenarios.filter((s) => !isHookScenario(s));
|
|
1054
|
+
if (scenarios.length > 0
|
|
1055
|
+
&& scenarios.every((s) => s.tags.some((t) => /^@exploration\b/i.test(t)))) {
|
|
987
1056
|
log(`${COLOR.gray}${paths.label}: nothing to approve — all scenario(s) are @exploration probes.${COLOR.reset}`);
|
|
988
1057
|
continue;
|
|
989
1058
|
}
|
|
@@ -1012,13 +1081,15 @@ export function registerDeliveryCommand(program: Command): void {
|
|
|
1012
1081
|
for (const target of toExport) {
|
|
1013
1082
|
const s = await exportMatrixTarget(cwd, target, {
|
|
1014
1083
|
check: options.check, preview: options.preview, format: format as MatrixFormat,
|
|
1015
|
-
}, env);
|
|
1084
|
+
}, env, decisions);
|
|
1016
1085
|
if (s === 'skipped') continue; // all-@exploration feature — neither exported nor a failure
|
|
1017
1086
|
if (s) matrixSummaries.push(s);
|
|
1018
1087
|
else notExported.push(target.isFlow ? `flow/${target.featureBaseName}` : target.featureBaseName);
|
|
1019
1088
|
}
|
|
1020
1089
|
if (matrixSummaries.length > 0 && !options.check) printMatrixSummaryTable(matrixSummaries);
|
|
1090
|
+
for (const line of decisions?.summaryLines() ?? []) log(line);
|
|
1021
1091
|
printSkipSummary(skipped, notExported);
|
|
1092
|
+
await printDeliveryChecklist(cwd, toExport, decisions?.acceptedInRun);
|
|
1022
1093
|
// A named target that produced nothing is a failure. A sweep is a failure
|
|
1023
1094
|
// only when it produced nothing at all — units still waiting for a map or
|
|
1024
1095
|
// an approval are the normal state of a live project. Preflight skips are
|
|
@@ -1041,6 +1112,7 @@ export function registerDeliveryCommand(program: Command): void {
|
|
|
1041
1112
|
// 4. Summary
|
|
1042
1113
|
printSummaryTable(summaries);
|
|
1043
1114
|
printSkipSummary(skipped, []);
|
|
1115
|
+
await printDeliveryChecklist(cwd, toExport, decisions?.acceptedInRun);
|
|
1044
1116
|
// Same rule as the matrix path: every attempted target in an explicit scope
|
|
1045
1117
|
// must have produced a file; a sweep only fails when nothing was written.
|
|
1046
1118
|
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, signoff, 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, 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('--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)')
|
|
17
25
|
.option('--signoff', 'Sign off the review queue — the single human gate (allowed only when every other obligation is satisfied/waived)')
|
|
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
|
? signoff(process.cwd(), name, options.by)
|
|
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) {
|