@sun-asterisk/sungen 3.2.35 → 3.3.0-alpha.10
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/case-triage-hint.d.ts +14 -0
- package/dist/cli/case-triage-hint.d.ts.map +1 -0
- package/dist/cli/case-triage-hint.js +23 -0
- package/dist/cli/case-triage-hint.js.map +1 -0
- package/dist/cli/commands/audit.js +1 -1
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/capability.js +1 -1
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/cli/commands/contract-derive-command.d.ts +12 -0
- package/dist/cli/commands/contract-derive-command.d.ts.map +1 -0
- package/dist/cli/commands/contract-derive-command.js +113 -0
- package/dist/cli/commands/contract-derive-command.js.map +1 -0
- package/dist/cli/commands/contract.d.ts +20 -0
- package/dist/cli/commands/contract.d.ts.map +1 -0
- package/dist/cli/commands/contract.js +195 -0
- package/dist/cli/commands/contract.js.map +1 -0
- package/dist/cli/commands/delivery.d.ts.map +1 -1
- package/dist/cli/commands/delivery.js +109 -19
- package/dist/cli/commands/delivery.js.map +1 -1
- package/dist/cli/commands/gate.d.ts.map +1 -1
- package/dist/cli/commands/gate.js +2 -1
- package/dist/cli/commands/gate.js.map +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +17 -3
- 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 +47 -17
- package/dist/cli/commands/journey.js.map +1 -1
- package/dist/cli/commands/next.d.ts +13 -0
- package/dist/cli/commands/next.d.ts.map +1 -1
- package/dist/cli/commands/next.js +98 -9
- package/dist/cli/commands/next.js.map +1 -1
- package/dist/cli/commands/triage.d.ts +2 -1
- package/dist/cli/commands/triage.d.ts.map +1 -1
- package/dist/cli/commands/triage.js +45 -3
- package/dist/cli/commands/triage.js.map +1 -1
- 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 +37 -8
- 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/json-error-on-exit.d.ts +34 -0
- package/dist/cli/json-error-on-exit.d.ts.map +1 -0
- package/dist/cli/json-error-on-exit.js +63 -0
- package/dist/cli/json-error-on-exit.js.map +1 -0
- package/dist/cli/project-sungen-invocation.d.ts +13 -0
- package/dist/cli/project-sungen-invocation.d.ts.map +1 -0
- package/dist/cli/project-sungen-invocation.js +95 -0
- package/dist/cli/project-sungen-invocation.js.map +1 -0
- package/dist/cli/run-command-hints.d.ts +9 -0
- package/dist/cli/run-command-hints.d.ts.map +1 -0
- package/dist/cli/run-command-hints.js +84 -0
- package/dist/cli/run-command-hints.js.map +1 -0
- package/dist/cli/waiting-for-you-block.d.ts +18 -0
- package/dist/cli/waiting-for-you-block.d.ts.map +1 -0
- package/dist/cli/waiting-for-you-block.js +22 -0
- package/dist/cli/waiting-for-you-block.js.map +1 -0
- package/dist/contract/accept-opaque-steps.d.ts +3 -0
- package/dist/contract/accept-opaque-steps.d.ts.map +1 -0
- package/dist/contract/accept-opaque-steps.js +114 -0
- package/dist/contract/accept-opaque-steps.js.map +1 -0
- package/dist/contract/approve-contract.d.ts +38 -0
- package/dist/contract/approve-contract.d.ts.map +1 -0
- package/dist/contract/approve-contract.js +93 -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 +22 -0
- package/dist/contract/build-trace-conformance.d.ts.map +1 -0
- package/dist/contract/build-trace-conformance.js +151 -0
- package/dist/contract/build-trace-conformance.js.map +1 -0
- package/dist/contract/classify-contract-change.d.ts +24 -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 +47 -0
- package/dist/contract/classify-trace-conformance.d.ts.map +1 -0
- package/dist/contract/classify-trace-conformance.js +164 -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 +92 -0
- package/dist/contract/contract-schema.d.ts.map +1 -0
- package/dist/contract/contract-schema.js +124 -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 +141 -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 +49 -0
- package/dist/contract/derive-free-feature.d.ts.map +1 -0
- package/dist/contract/derive-free-feature.js +183 -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 +75 -0
- package/dist/contract/project-contract-blockers.js.map +1 -0
- package/dist/contract/record-contract-approval.d.ts +36 -0
- package/dist/contract/record-contract-approval.d.ts.map +1 -0
- package/dist/contract/record-contract-approval.js +126 -0
- package/dist/contract/record-contract-approval.js.map +1 -0
- package/dist/contract/render-free-gherkin.d.ts +42 -0
- package/dist/contract/render-free-gherkin.d.ts.map +1 -0
- package/dist/contract/render-free-gherkin.js +147 -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 +20 -0
- package/dist/contract/resolve-unit-trace-identities.d.ts.map +1 -0
- package/dist/contract/resolve-unit-trace-identities.js +62 -0
- package/dist/contract/resolve-unit-trace-identities.js.map +1 -0
- package/dist/contract/trace/collect-trace-evidence.d.ts +44 -0
- package/dist/contract/trace/collect-trace-evidence.d.ts.map +1 -0
- package/dist/contract/trace/collect-trace-evidence.js +219 -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/read-file-once.d.ts +20 -0
- package/dist/contract/trace/read-file-once.d.ts.map +1 -0
- package/dist/contract/trace/read-file-once.js +135 -0
- package/dist/contract/trace/read-file-once.js.map +1 -0
- package/dist/contract/trace/scenario-id-claims.d.ts +11 -0
- package/dist/contract/trace/scenario-id-claims.d.ts.map +1 -0
- package/dist/contract/trace/scenario-id-claims.js +89 -0
- package/dist/contract/trace/scenario-id-claims.js.map +1 -0
- package/dist/contract/trace/select-final-attempt.d.ts +29 -0
- package/dist/contract/trace/select-final-attempt.d.ts.map +1 -0
- package/dist/contract/trace/select-final-attempt.js +119 -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 +22 -0
- package/dist/contract/trace/trace-binding.d.ts.map +1 -0
- package/dist/contract/trace/trace-binding.js +91 -0
- package/dist/contract/trace/trace-binding.js.map +1 -0
- package/dist/contract/trace/trace-file-reader.d.ts +47 -0
- package/dist/contract/trace/trace-file-reader.d.ts.map +1 -0
- package/dist/contract/trace/trace-file-reader.js +137 -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-freshness.d.ts +27 -0
- package/dist/contract/trace/trace-freshness.d.ts.map +1 -0
- package/dist/contract/trace/trace-freshness.js +146 -0
- package/dist/contract/trace/trace-freshness.js.map +1 -0
- package/dist/contract/trace/trace-identity-resolution.d.ts +28 -0
- package/dist/contract/trace/trace-identity-resolution.d.ts.map +1 -0
- package/dist/contract/trace/trace-identity-resolution.js +87 -0
- package/dist/contract/trace/trace-identity-resolution.js.map +1 -0
- package/dist/contract/trace/trace-run-record.d.ts +32 -0
- package/dist/contract/trace/trace-run-record.d.ts.map +1 -0
- package/dist/contract/trace/trace-run-record.js +135 -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 +109 -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 +43 -0
- package/dist/decisions/decision-schema.d.ts.map +1 -0
- package/dist/decisions/decision-schema.js +76 -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 +19 -0
- package/dist/decisions/git-head-trust.d.ts.map +1 -0
- package/dist/decisions/git-head-trust.js +128 -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 +38 -0
- package/dist/decisions/legacy-waiver-migration.d.ts.map +1 -0
- package/dist/decisions/legacy-waiver-migration.js +179 -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 +11 -2
- package/dist/exporters/csv-exporter.d.ts.map +1 -1
- package/dist/exporters/csv-exporter.js +8 -4
- package/dist/exporters/csv-exporter.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 +10 -9
- package/dist/exporters/matrix/build.js.map +1 -1
- package/dist/exporters/matrix/export.d.ts +9 -1
- package/dist/exporters/matrix/export.d.ts.map +1 -1
- package/dist/exporters/matrix/export.js +13 -4
- 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 +3 -0
- 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 +3 -0
- package/dist/exporters/matrix/render-xlsx.js.map +1 -1
- package/dist/exporters/matrix/types.d.ts +4 -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/test-data-resolver.d.ts.map +1 -1
- package/dist/exporters/test-data-resolver.js +2 -12
- package/dist/exporters/test-data-resolver.js.map +1 -1
- package/dist/exporters/xlsx-exporter.d.ts +3 -2
- package/dist/exporters/xlsx-exporter.d.ts.map +1 -1
- package/dist/exporters/xlsx-exporter.js +4 -4
- package/dist/exporters/xlsx-exporter.js.map +1 -1
- package/dist/generators/gherkin-parser/index.d.ts.map +1 -1
- package/dist/generators/gherkin-parser/index.js +0 -1
- package/dist/generators/gherkin-parser/index.js.map +1 -1
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/contain-text-assertion.hbs +1 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/fill-action.hbs +1 -13
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/contain-text-assertion.hbs +1 -9
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +18 -4
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/generators/test-generator/diagnostics.d.ts +3 -9
- package/dist/generators/test-generator/diagnostics.d.ts.map +1 -1
- package/dist/generators/test-generator/diagnostics.js +3 -9
- package/dist/generators/test-generator/diagnostics.js.map +1 -1
- package/dist/generators/test-generator/patterns/types.d.ts +1 -1
- package/dist/generators/test-generator/patterns/types.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.d.ts +0 -8
- package/dist/generators/test-generator/step-mapper.d.ts.map +1 -1
- package/dist/generators/test-generator/step-mapper.js +8 -52
- package/dist/generators/test-generator/step-mapper.js.map +1 -1
- package/dist/generators/test-generator/utils/data-resolver.d.ts +0 -16
- package/dist/generators/test-generator/utils/data-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/data-resolver.js +0 -59
- package/dist/generators/test-generator/utils/data-resolver.js.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.js +2 -10
- package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
- package/dist/graph/board-human-actions.d.ts +5 -0
- package/dist/graph/board-human-actions.d.ts.map +1 -0
- package/dist/graph/board-human-actions.js +83 -0
- package/dist/graph/board-human-actions.js.map +1 -0
- package/dist/graph/evaluate-graph.d.ts +41 -0
- package/dist/graph/evaluate-graph.d.ts.map +1 -0
- package/dist/graph/evaluate-graph.js +77 -0
- package/dist/graph/evaluate-graph.js.map +1 -0
- package/dist/graph/human-action.d.ts +21 -0
- package/dist/graph/human-action.d.ts.map +1 -0
- package/dist/graph/human-action.js +3 -0
- package/dist/graph/human-action.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/manual-triage-decisions.d.ts +19 -0
- package/dist/graph/manual-triage-decisions.d.ts.map +1 -0
- package/dist/graph/manual-triage-decisions.js +53 -0
- package/dist/graph/manual-triage-decisions.js.map +1 -0
- package/dist/graph/node-decl.d.ts +75 -0
- package/dist/graph/node-decl.d.ts.map +1 -0
- package/dist/graph/node-decl.js +11 -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 +72 -0
- package/dist/graph/nodes/test-case-contract-nodes.js.map +1 -0
- package/dist/graph/nodes/test-case-nodes.d.ts +29 -0
- package/dist/graph/nodes/test-case-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/test-case-nodes.js +95 -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 +96 -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 +96 -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 +12 -0
- package/dist/graph/test-case-results.d.ts.map +1 -0
- package/dist/graph/test-case-results.js +161 -0
- package/dist/graph/test-case-results.js.map +1 -0
- package/dist/graph/test-case-satisfied.d.ts +26 -0
- package/dist/graph/test-case-satisfied.d.ts.map +1 -0
- package/dist/graph/test-case-satisfied.js +55 -0
- package/dist/graph/test-case-satisfied.js.map +1 -0
- package/dist/graph/test-case-state-shape.d.ts +73 -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 +135 -0
- package/dist/graph/unit-artifact-probes.js.map +1 -0
- package/dist/graph/unit-results-freshness.d.ts +29 -0
- package/dist/graph/unit-results-freshness.d.ts.map +1 -0
- package/dist/graph/unit-results-freshness.js +213 -0
- package/dist/graph/unit-results-freshness.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 +14 -2
- package/dist/harness/audit.d.ts.map +1 -1
- package/dist/harness/audit.js +20 -21
- package/dist/harness/audit.js.map +1 -1
- package/dist/harness/catalog/gate-rules.yaml +647 -0
- package/dist/harness/defect-draft.d.ts.map +1 -1
- package/dist/harness/defect-draft.js +12 -2
- package/dist/harness/defect-draft.js.map +1 -1
- package/dist/harness/defects.d.ts +14 -0
- package/dist/harness/defects.d.ts.map +1 -1
- package/dist/harness/defects.js +14 -10
- package/dist/harness/defects.js.map +1 -1
- package/dist/harness/flow-check.d.ts +9 -0
- package/dist/harness/flow-check.d.ts.map +1 -1
- package/dist/harness/flow-check.js +11 -0
- package/dist/harness/flow-check.js.map +1 -1
- 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 +102 -0
- package/dist/harness/gates/audit-gate-verdict.js.map +1 -0
- package/dist/harness/gates/audit-input-hash.d.ts +6 -0
- package/dist/harness/gates/audit-input-hash.d.ts.map +1 -0
- package/dist/harness/gates/audit-input-hash.js +124 -0
- package/dist/harness/gates/audit-input-hash.js.map +1 -0
- package/dist/harness/gates/audit-report-verification.d.ts +43 -0
- package/dist/harness/gates/audit-report-verification.d.ts.map +1 -0
- package/dist/harness/gates/audit-report-verification.js +241 -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 +24 -0
- package/dist/harness/gates/delivery-checklist.d.ts.map +1 -0
- package/dist/harness/gates/delivery-checklist.js +161 -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 +166 -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-import-bounds.d.ts +13 -0
- package/dist/harness/gates/migrated-waiver-import-bounds.d.ts.map +1 -0
- package/dist/harness/gates/migrated-waiver-import-bounds.js +141 -0
- package/dist/harness/gates/migrated-waiver-import-bounds.js.map +1 -0
- package/dist/harness/gates/migrated-waiver-review.d.ts +16 -0
- package/dist/harness/gates/migrated-waiver-review.d.ts.map +1 -0
- package/dist/harness/gates/migrated-waiver-review.js +114 -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 +64 -1
- package/dist/harness/journey.d.ts.map +1 -1
- package/dist/harness/journey.js +258 -34
- 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 +71 -43
- package/dist/harness/manifest.js.map +1 -1
- package/dist/harness/next-step.d.ts +58 -4
- package/dist/harness/next-step.d.ts.map +1 -1
- package/dist/harness/next-step.js +55 -204
- package/dist/harness/next-step.js.map +1 -1
- package/dist/harness/parse.d.ts +7 -0
- package/dist/harness/parse.d.ts.map +1 -1
- package/dist/harness/parse.js +18 -2
- 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 +22 -5
- 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 +41 -38
- package/dist/harness/sensors.js.map +1 -1
- package/dist/harness/triage-manual-classification.d.ts +32 -0
- package/dist/harness/triage-manual-classification.d.ts.map +1 -0
- package/dist/harness/triage-manual-classification.js +56 -0
- package/dist/harness/triage-manual-classification.js.map +1 -0
- package/dist/harness/unit-paths.d.ts +8 -0
- package/dist/harness/unit-paths.d.ts.map +1 -1
- package/dist/harness/unit-paths.js +23 -1
- package/dist/harness/unit-paths.js.map +1 -1
- package/dist/hooks/bash-read-only-segment.d.ts +9 -0
- package/dist/hooks/bash-read-only-segment.d.ts.map +1 -0
- package/dist/hooks/bash-read-only-segment.js +168 -0
- package/dist/hooks/bash-read-only-segment.js.map +1 -0
- package/dist/hooks/bash-write-targets.d.ts +25 -0
- package/dist/hooks/bash-write-targets.d.ts.map +1 -0
- package/dist/hooks/bash-write-targets.js +266 -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 +13 -0
- package/dist/hooks/guard-protected-paths.d.ts.map +1 -0
- package/dist/hooks/guard-protected-paths.js +116 -0
- package/dist/hooks/guard-protected-paths.js.map +1 -0
- package/dist/hooks/guard-rules.d.ts +20 -0
- package/dist/hooks/guard-rules.d.ts.map +1 -0
- package/dist/hooks/guard-rules.js +130 -0
- package/dist/hooks/guard-rules.js.map +1 -0
- package/dist/hooks/guard-tty-spoof-rule.d.ts +17 -0
- package/dist/hooks/guard-tty-spoof-rule.d.ts.map +1 -0
- package/dist/hooks/guard-tty-spoof-rule.js +22 -0
- package/dist/hooks/guard-tty-spoof-rule.js.map +1 -0
- package/dist/hooks/hand-back-core.d.ts +42 -0
- package/dist/hooks/hand-back-core.d.ts.map +1 -0
- package/dist/hooks/hand-back-core.js +128 -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 +14 -0
- package/dist/hooks/session-start-unit-state-hook.d.ts.map +1 -0
- package/dist/hooks/session-start-unit-state-hook.js +60 -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 +43 -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/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- 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 +11 -3
- package/dist/orchestrator/ai-skills/commands.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/templates/ai-src/commands/add-api.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/add-flow.md +6 -26
- 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 +17 -16
- package/dist/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/delivery.md +4 -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 +4 -0
- package/dist/orchestrator/templates/ai-src/commands/run-test.md +6 -8
- 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/partials/waiting-for-you.claude.md +11 -0
- package/dist/orchestrator/templates/ai-src/partials/waiting-for-you.codex.md +11 -0
- package/dist/orchestrator/templates/ai-src/partials/waiting-for-you.copilot.md +11 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md +1 -2
- package/dist/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +4 -5
- package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +8 -24
- package/dist/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +3 -4
- package/dist/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
- package/dist/orchestrator/templates/specs-test-data.ts +4 -22
- 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/case-triage-hint.ts +31 -0
- package/src/cli/commands/audit.ts +1 -1
- package/src/cli/commands/capability.ts +1 -1
- package/src/cli/commands/contract-derive-command.ts +72 -0
- package/src/cli/commands/contract.ts +164 -0
- package/src/cli/commands/delivery.ts +106 -19
- package/src/cli/commands/gate.ts +2 -1
- package/src/cli/commands/generate.ts +16 -3
- package/src/cli/commands/journey.ts +45 -18
- package/src/cli/commands/next.ts +92 -11
- package/src/cli/commands/triage.ts +41 -3
- package/src/cli/commands/update.ts +41 -10
- package/src/cli/index.ts +24 -30
- package/src/cli/json-error-on-exit.ts +72 -0
- package/src/cli/project-sungen-invocation.ts +59 -0
- package/src/cli/run-command-hints.ts +47 -0
- package/src/cli/waiting-for-you-block.ts +27 -0
- package/src/contract/accept-opaque-steps.ts +114 -0
- package/src/contract/approve-contract.ts +101 -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 +103 -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 +170 -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 +166 -0
- package/src/contract/contract-units.ts +52 -0
- package/src/contract/contracts-lock-file.ts +98 -0
- package/src/contract/data-normalize.ts +66 -0
- package/src/contract/derive-free-feature.ts +153 -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 +38 -0
- package/src/contract/record-contract-approval.ts +110 -0
- package/src/contract/render-free-gherkin.ts +118 -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 +58 -0
- package/src/contract/trace/collect-trace-evidence.ts +178 -0
- package/src/contract/trace/identity-cache.ts +61 -0
- package/src/contract/trace/read-file-once.ts +95 -0
- package/src/contract/trace/scenario-id-claims.ts +60 -0
- package/src/contract/trace/select-final-attempt.ts +77 -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 +59 -0
- package/src/contract/trace/trace-file-reader.ts +144 -0
- package/src/contract/trace/trace-fingerprint.ts +68 -0
- package/src/contract/trace/trace-freshness.ts +110 -0
- package/src/contract/trace/trace-identity-resolution.ts +77 -0
- package/src/contract/trace/trace-run-record.ts +96 -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 +64 -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 +77 -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 +76 -0
- package/src/decisions/human-confirmation.ts +119 -0
- package/src/decisions/legacy-waiver-migration.ts +146 -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 +12 -4
- package/src/exporters/matrix/build.ts +11 -9
- package/src/exporters/matrix/export.ts +16 -4
- package/src/exporters/matrix/gates.ts +62 -129
- package/src/exporters/matrix/render-csv.ts +3 -0
- package/src/exporters/matrix/render-gate-overrides-sheet.ts +50 -0
- package/src/exporters/matrix/render-xlsx.ts +3 -0
- package/src/exporters/matrix/types.ts +4 -1
- package/src/exporters/matrix/xlsx-cells.ts +1 -1
- package/src/exporters/test-data-resolver.ts +2 -10
- package/src/exporters/xlsx-exporter.ts +5 -4
- package/src/generators/gherkin-parser/index.ts +0 -1
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/contain-text-assertion.hbs +1 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/fill-action.hbs +1 -13
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/contain-text-assertion.hbs +1 -9
- package/src/generators/test-generator/code-generator.ts +17 -4
- package/src/generators/test-generator/diagnostics.ts +3 -9
- package/src/generators/test-generator/patterns/types.ts +0 -2
- package/src/generators/test-generator/step-mapper.ts +9 -56
- package/src/generators/test-generator/utils/data-resolver.ts +0 -53
- package/src/generators/test-generator/utils/selector-resolver.ts +2 -10
- package/src/graph/board-human-actions.ts +80 -0
- package/src/graph/evaluate-graph.ts +97 -0
- package/src/graph/human-action.ts +33 -0
- package/src/graph/locate-finding.ts +93 -0
- package/src/graph/manual-triage-decisions.ts +55 -0
- package/src/graph/node-decl.ts +83 -0
- package/src/graph/nodes/core-node-catalog.ts +15 -0
- package/src/graph/nodes/test-case-contract-nodes.ts +90 -0
- package/src/graph/nodes/test-case-nodes.ts +100 -0
- package/src/graph/nodes/unit-audit-nodes.ts +96 -0
- package/src/graph/nodes/unit-contract-node.ts +100 -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 +111 -0
- package/src/graph/test-case-satisfied.ts +58 -0
- package/src/graph/test-case-state-shape.ts +67 -0
- package/src/graph/test-case-states.ts +84 -0
- package/src/graph/unit-artifact-probes.ts +79 -0
- package/src/graph/unit-results-freshness.ts +165 -0
- package/src/graph/unit-state-facts.ts +112 -0
- package/src/harness/audit.ts +31 -18
- package/src/harness/catalog/gate-rules.yaml +647 -0
- package/src/harness/defect-draft.ts +13 -2
- package/src/harness/defects.ts +22 -9
- package/src/harness/flow-check.ts +11 -0
- package/src/harness/gates/audit-gate-terms.ts +80 -0
- package/src/harness/gates/audit-gate-verdict.ts +79 -0
- package/src/harness/gates/audit-input-hash.ts +79 -0
- package/src/harness/gates/audit-report-verification.ts +206 -0
- package/src/harness/gates/decisions-hash.ts +42 -0
- package/src/harness/gates/delivery-checklist.ts +152 -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 +124 -0
- package/src/harness/gates/journey-gate-inputs.ts +89 -0
- package/src/harness/gates/migrated-waiver-import-bounds.ts +103 -0
- package/src/harness/gates/migrated-waiver-review.ts +121 -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 +287 -39
- package/src/harness/manifest.ts +67 -43
- package/src/harness/next-step.ts +91 -193
- package/src/harness/parse.ts +20 -2
- package/src/harness/provenance.ts +99 -11
- package/src/harness/script-check.ts +20 -5
- package/src/harness/sensors.ts +47 -40
- package/src/harness/triage-manual-classification.ts +76 -0
- package/src/harness/unit-paths.ts +19 -0
- package/src/hooks/bash-read-only-segment.ts +130 -0
- package/src/hooks/bash-write-targets.ts +195 -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 +80 -0
- package/src/hooks/guard-rules.ts +117 -0
- package/src/hooks/guard-tty-spoof-rule.ts +34 -0
- package/src/hooks/hand-back-core.ts +118 -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 +59 -0
- package/src/hooks/stop-next-step-hook.ts +38 -0
- package/src/hooks/sungen-project-root.ts +80 -0
- package/src/index.ts +1 -2
- package/src/orchestrator/ai-skills/command-partial-includes.ts +72 -0
- package/src/orchestrator/ai-skills/commands.ts +17 -5
- 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/templates/ai-src/commands/add-api.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/add-flow.md +6 -26
- 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 +17 -16
- package/src/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/delivery.md +4 -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 +4 -0
- package/src/orchestrator/templates/ai-src/commands/run-test.md +6 -8
- 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/partials/waiting-for-you.claude.md +11 -0
- package/src/orchestrator/templates/ai-src/partials/waiting-for-you.codex.md +11 -0
- package/src/orchestrator/templates/ai-src/partials/waiting-for-you.copilot.md +11 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md +1 -2
- package/src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +4 -5
- package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +8 -24
- package/src/orchestrator/templates/ai-src/skills/sungen-tc-generation/SKILL.md +3 -4
- package/src/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
- package/src/orchestrator/templates/specs-test-data.ts +4 -22
- package/src/utils/safe-yaml-parse.ts +44 -0
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/expanded-assertion.hbs +0 -2
- package/dist/generators/test-generator/adapters/playwright/templates/steps/actions/date-picker-unsupported.hbs +0 -5
- package/dist/generators/test-generator/adapters/playwright/templates/steps/assertions/expanded-assertion.hbs +0 -12
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/expanded-assertion.hbs +0 -2
- package/src/generators/test-generator/adapters/playwright/templates/steps/actions/date-picker-unsupported.hbs +0 -5
- package/src/generators/test-generator/adapters/playwright/templates/steps/assertions/expanded-assertion.hbs +0 -12
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The gate-rule catalog (OES-11.1): `harness/catalog/gate-rules.yaml`, shipped next to the code
|
|
3
|
+
* (`copy-templates` copies it into `dist/harness/catalog/`).
|
|
4
|
+
*
|
|
5
|
+
* The catalog is code-owned data — a malformed one is a build defect, so loading it throws rather
|
|
6
|
+
* than degrading to "no rules" (which would silently stop every gate from blocking).
|
|
7
|
+
*/
|
|
8
|
+
import * as fs from 'fs';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import { parse } from 'yaml';
|
|
11
|
+
|
|
12
|
+
export const GATE_SEVERITIES = ['error', 'review', 'warning', 'info'] as const;
|
|
13
|
+
export type GateSeverity = typeof GATE_SEVERITIES[number];
|
|
14
|
+
export type GateKind = 'hard' | 'soft';
|
|
15
|
+
export const GATE_STAGES = ['spec', 'create', 'generate', 'run', 'deliver'] as const;
|
|
16
|
+
export type GateStage = typeof GATE_STAGES[number];
|
|
17
|
+
|
|
18
|
+
export interface GateRule {
|
|
19
|
+
id: string;
|
|
20
|
+
stage: GateStage;
|
|
21
|
+
severity: GateSeverity;
|
|
22
|
+
kind: GateKind;
|
|
23
|
+
rationale: string;
|
|
24
|
+
fix: string;
|
|
25
|
+
since: string;
|
|
26
|
+
offAllowed: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const CATALOG_FILE = path.join(__dirname, '..', 'catalog', 'gate-rules.yaml');
|
|
30
|
+
const ID_RE = /^[a-z0-9]+(\.[a-z0-9]+(-[a-z0-9]+)*)+$/;
|
|
31
|
+
|
|
32
|
+
/** Parse and validate catalog text. Throws on the first structural defect. */
|
|
33
|
+
export function parseGateRuleCatalog(text: string): Map<string, GateRule> {
|
|
34
|
+
const doc = parse(text) as { rules?: unknown } | null;
|
|
35
|
+
if (!doc || !Array.isArray(doc.rules)) throw new Error('gate-rules.yaml: no `rules:` list');
|
|
36
|
+
const out = new Map<string, GateRule>();
|
|
37
|
+
for (const raw of doc.rules as Array<Record<string, unknown>>) {
|
|
38
|
+
const id = String(raw?.id ?? '');
|
|
39
|
+
const bad = (why: string): never => { throw new Error(`gate-rules.yaml: rule "${id}" ${why}`); };
|
|
40
|
+
if (!ID_RE.test(id)) bad('has no dotted kebab-case id');
|
|
41
|
+
if (out.has(id)) bad('is declared twice');
|
|
42
|
+
if (!GATE_STAGES.includes(raw.stage as GateStage)) bad(`has an unknown stage "${raw.stage}"`);
|
|
43
|
+
if (!GATE_SEVERITIES.includes(raw.severity as GateSeverity)) bad(`has an unknown severity "${raw.severity}"`);
|
|
44
|
+
if (raw.kind !== 'hard' && raw.kind !== 'soft') bad('kind must be hard|soft');
|
|
45
|
+
if (typeof raw.offAllowed !== 'boolean') bad('offAllowed must be a boolean');
|
|
46
|
+
if (raw.kind === 'hard' && raw.offAllowed) bad('is hard, so it can never be switched off');
|
|
47
|
+
out.set(id, {
|
|
48
|
+
id,
|
|
49
|
+
stage: raw.stage as GateStage,
|
|
50
|
+
severity: raw.severity as GateSeverity,
|
|
51
|
+
kind: raw.kind as GateKind,
|
|
52
|
+
rationale: String(raw.rationale ?? ''),
|
|
53
|
+
fix: String(raw.fix ?? ''),
|
|
54
|
+
since: String(raw.since ?? ''),
|
|
55
|
+
offAllowed: raw.offAllowed as boolean,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let cached: ReadonlyMap<string, GateRule> | null = null;
|
|
62
|
+
|
|
63
|
+
/** Every rule, keyed by id (loaded once per process). */
|
|
64
|
+
export function gateRuleCatalog(): ReadonlyMap<string, GateRule> {
|
|
65
|
+
if (!cached) cached = parseGateRuleCatalog(fs.readFileSync(CATALOG_FILE, 'utf8'));
|
|
66
|
+
return cached;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function findGateRule(id: string): GateRule | undefined {
|
|
70
|
+
return gateRuleCatalog().get(id);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** A rule the CODE names. An unknown id is a programming error, never user input — so it throws. */
|
|
74
|
+
export function gateRule(id: string): GateRule {
|
|
75
|
+
const rule = findGateRule(id);
|
|
76
|
+
if (!rule) throw new Error(`gate rule "${id}" is not in harness/catalog/gate-rules.yaml`);
|
|
77
|
+
return rule;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function listRules(): GateRule[] {
|
|
81
|
+
return [...gateRuleCatalog().values()];
|
|
82
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turning a gate CONDITION into an outcome through `resolveRule` — the only shapes a gate site uses,
|
|
3
|
+
* so no site writes a severity literal of its own (OES-11.2).
|
|
4
|
+
*
|
|
5
|
+
* evaluateGateTerms a conjunction (audit gateStatus, script-check status): each term names its
|
|
6
|
+
* rule and whether its condition holds; a violated term blocks only when its
|
|
7
|
+
* resolved severity blocks
|
|
8
|
+
* ruleVerdict a sensor verdict (pass | warn | fail) for one rule
|
|
9
|
+
* sensorSeverityOf a per-finding sensor severity (fail | warn | info), or null when switched off
|
|
10
|
+
*/
|
|
11
|
+
import { GateRules, ResolvedRule } from './resolve-rule';
|
|
12
|
+
|
|
13
|
+
export interface GateTerm {
|
|
14
|
+
rule: string;
|
|
15
|
+
/** The condition the rule wants to see — `true` means the term passes. */
|
|
16
|
+
holds: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface GateTermsOutcome {
|
|
20
|
+
pass: boolean;
|
|
21
|
+
/** Violated rules whose resolved severity blocks. */
|
|
22
|
+
blocking: string[];
|
|
23
|
+
/** Violated rules an override lowered to advisory. */
|
|
24
|
+
relaxed: string[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function evaluateGateTerms(terms: GateTerm[], rules: GateRules): GateTermsOutcome {
|
|
28
|
+
const blocking: string[] = [];
|
|
29
|
+
const relaxed: string[] = [];
|
|
30
|
+
for (const t of terms) {
|
|
31
|
+
if (t.holds) continue;
|
|
32
|
+
const r = rules.resolve(t.rule);
|
|
33
|
+
if (r.blocking) blocking.push(t.rule);
|
|
34
|
+
else if (r.overriddenBy) relaxed.push(t.rule);
|
|
35
|
+
}
|
|
36
|
+
return { pass: blocking.length === 0, blocking, relaxed };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type SensorVerdict = 'pass' | 'warn' | 'fail';
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* A sensor verdict for one rule. `advisoryAnyway` is a reason the miss can never block that is not
|
|
43
|
+
* a severity (the `smoke` focus, or no failing row) — the rule is then not consulted at all.
|
|
44
|
+
*/
|
|
45
|
+
export function ruleVerdict(rules: GateRules, id: string, conditionMet: boolean, advisoryAnyway: boolean): SensorVerdict {
|
|
46
|
+
if (!conditionMet) return 'pass';
|
|
47
|
+
if (advisoryAnyway) return 'warn';
|
|
48
|
+
const r = rules.resolve(id);
|
|
49
|
+
if (r.severity === 'off') return 'pass';
|
|
50
|
+
return r.blocking ? 'fail' : 'warn';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type SensorSeverity = 'fail' | 'warn' | 'info';
|
|
54
|
+
|
|
55
|
+
export function sensorSeverityOf(r: ResolvedRule): SensorSeverity | null {
|
|
56
|
+
if (r.severity === 'off') return null;
|
|
57
|
+
if (r.blocking) return 'fail';
|
|
58
|
+
return r.severity === 'info' ? 'info' : 'warn';
|
|
59
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `decision.in-run` (OES-11.5, red-team #3/#15) — a hard rule: a decision that relaxes or approves
|
|
3
|
+
* something (`gate-override`, `waiver`, `contract-approval`) must have been reviewed BEFORE the run
|
|
4
|
+
* being delivered. It is in-run when
|
|
5
|
+
* - it is not in `git show HEAD:` (never committed, so never reviewed), or
|
|
6
|
+
* - it was committed after the start of that run — judged by its git COMMIT time, not by the
|
|
7
|
+
* `valid_from` it carries, which its author writes and can backdate (review H1).
|
|
8
|
+
* Without git only the second test is possible, on `valid_from`; the caller says so (lower confidence).
|
|
9
|
+
* Without git AND without a run, nothing can be judged — reported, not guessed. A commit time can be
|
|
10
|
+
* forged too (GIT_COMMITTER_DATE); it raises the bar, it is not a signature.
|
|
11
|
+
*
|
|
12
|
+
* A MIGRATED waiver (DOS-13.5) was reviewed when its legacy record was committed — the only record the
|
|
13
|
+
* import trusts — so it is judged by THAT commit (migrated-waiver-review.ts), never by its own decision
|
|
14
|
+
* file: in-run when the record was committed after the run started, or — run start or not (#925) —
|
|
15
|
+
* when it could not have been the import's source: not strictly before the decision file, the unit's
|
|
16
|
+
* import marker or the project's adoption of 3.3 appeared. Holding it to its decision file's commit would make
|
|
17
|
+
* every legacy project's waivers in-run the day they are imported (phase 09). An entry HEAD's legacy
|
|
18
|
+
* file does not vouch for — absent, uncommitted, different, introduced beyond the commits the walk
|
|
19
|
+
* reads (#924) or at a shallow clone's boundary — is judged as any other; in the last two cases an
|
|
20
|
+
* in-run finding says why.
|
|
21
|
+
*
|
|
22
|
+
* A manual triage classification that claims a human typed it (`triage-classification` with
|
|
23
|
+
* `humanConfirmed`, #928) is a claim the entry makes about itself — a script can write one. What backs
|
|
24
|
+
* it is review, so it is in-run while git HEAD does not hold it (and, with no git, always: nothing
|
|
25
|
+
* shows it was reviewed). Judged by HEAD membership only: it is always recorded after the run it
|
|
26
|
+
* judges, so its commit time says nothing. Only a test-defect / environment entry that is not
|
|
27
|
+
* superseded counts — the only kind the reader puts in force on that claim.
|
|
28
|
+
*/
|
|
29
|
+
import * as fs from 'fs';
|
|
30
|
+
import * as path from 'path';
|
|
31
|
+
import { DECISION_FILE_PATH } from '../../decisions/decision-file';
|
|
32
|
+
import { DecisionVisibility } from '../../decisions/decision-schema';
|
|
33
|
+
import { gitOutput } from '../../decisions/git-head-trust';
|
|
34
|
+
import { readDecisions } from '../../decisions/read-decisions';
|
|
35
|
+
import { HUMAN_ONLY_TRIAGE, ManualTriageClass, TRIAGE_DECISION_KIND } from '../../graph/manual-triage-decisions';
|
|
36
|
+
import { migratedWaiverReview } from './migrated-waiver-review';
|
|
37
|
+
|
|
38
|
+
export const IN_RUN_KINDS = ['gate-override', 'waiver', 'contract-approval'] as const;
|
|
39
|
+
export const IN_RUN_RULE = 'decision.in-run';
|
|
40
|
+
|
|
41
|
+
export interface InRunDecision { id: string; kind: string; path: string; visibility: DecisionVisibility; why: string[] }
|
|
42
|
+
|
|
43
|
+
/** Paths (relative to the project, `/`-separated) of decision files in git HEAD; null outside git. */
|
|
44
|
+
export function committedDecisionPaths(projectRoot: string): Set<string> | null {
|
|
45
|
+
if (gitOutput(projectRoot, ['rev-parse', '--is-inside-work-tree'])?.trim() !== 'true') return null;
|
|
46
|
+
const listed = gitOutput(projectRoot, ['ls-tree', '-r', '-z', '--name-only', 'HEAD', '--', 'qa']) ?? ''; // no HEAD yet → nothing committed
|
|
47
|
+
return new Set(listed.split('\0').filter((p) => DECISION_FILE_PATH.test(p)));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** When a committed file was last committed (ISO), or null when git cannot say. */
|
|
51
|
+
function commitTimeOf(projectRoot: string, rel: string): string | null {
|
|
52
|
+
const t = gitOutput(projectRoot, ['log', '-1', '--format=%cI', '--', rel])?.trim();
|
|
53
|
+
return t && !Number.isNaN(Date.parse(t)) ? t : null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** When the delivered run started: Playwright's `stats.startTime`; null when there is no readable run. */
|
|
57
|
+
export function runStartOf(resultsPath: string | null): string | null {
|
|
58
|
+
if (!resultsPath) return null;
|
|
59
|
+
try {
|
|
60
|
+
const json = JSON.parse(fs.readFileSync(resultsPath, 'utf8')) as { stats?: { startTime?: unknown } };
|
|
61
|
+
const t = json?.stats?.startTime;
|
|
62
|
+
return typeof t === 'string' && !Number.isNaN(Date.parse(t)) ? t : null;
|
|
63
|
+
} catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const isInRunKind = (kind: string): boolean => (IN_RUN_KINDS as readonly string[]).includes(kind);
|
|
69
|
+
/**
|
|
70
|
+
* A triage classification claiming a human typed it (#928): reviewed only once git HEAD holds it.
|
|
71
|
+
* Only what the reader (manual-triage-decisions.ts) can put in force: a superseded entry is never read,
|
|
72
|
+
* and a product classification needs no human — its claim backs nothing, so it blocks nothing.
|
|
73
|
+
*/
|
|
74
|
+
const claimsHumanTriage = (e: { kind: string; payload?: Record<string, unknown>; superseded_by?: string }): boolean =>
|
|
75
|
+
e.kind === TRIAGE_DECISION_KIND && !e.superseded_by && e.payload?.humanConfirmed === true
|
|
76
|
+
&& HUMAN_ONLY_TRIAGE.has(e.payload?.class as ManualTriageClass);
|
|
77
|
+
|
|
78
|
+
/** In-run decisions among `scopes`, judged against one run start (null: HEAD membership only) and the committed set. */
|
|
79
|
+
export function inRunDecisions(projectRoot: string, scopes: string[], runStart: string | null, committed: Set<string> | null): InRunDecision[] {
|
|
80
|
+
const out: InRunDecision[] = [];
|
|
81
|
+
const after = (t: string): boolean => !!runStart && Date.parse(t) > Date.parse(runStart);
|
|
82
|
+
const migratedReview = committed ? migratedWaiverReview(projectRoot) : null;
|
|
83
|
+
for (const scope of scopes) {
|
|
84
|
+
for (const e of readDecisions(projectRoot, scope).entries) {
|
|
85
|
+
const rel = path.relative(projectRoot, e.path).split(path.sep).join('/');
|
|
86
|
+
if (claimsHumanTriage(e) && !committed?.has(rel)) {
|
|
87
|
+
out.push({ id: e.id, kind: e.kind, path: rel, visibility: e.visibility, why: [committed
|
|
88
|
+
? 'a classification by hand that claims a human typed it, not in git HEAD (never committed through review)'
|
|
89
|
+
: 'a classification by hand that claims a human typed it, and no git to show it was committed through review'] });
|
|
90
|
+
}
|
|
91
|
+
if (!isInRunKind(e.kind)) continue;
|
|
92
|
+
// A migrated waiver re-confirmed on a terminal is replaced: the new decision is judged on its own.
|
|
93
|
+
if (e.superseded_by && e.source?.where === 'migrated') continue;
|
|
94
|
+
const why: string[] = [];
|
|
95
|
+
const migrated = migratedReview?.reviewOf(scope, e) ?? null;
|
|
96
|
+
if (migrated?.at) {
|
|
97
|
+
if (after(migrated.at)) why.push(`migrated: its legacy record was committed at ${migrated.at}, after the run started ${runStart}`);
|
|
98
|
+
if (migrated.notImported) why.push(migrated.notImported);
|
|
99
|
+
} else if (committed && !committed.has(rel)) {
|
|
100
|
+
why.push('not in git HEAD (never committed through review)');
|
|
101
|
+
} else if (committed && runStart) {
|
|
102
|
+
const at = commitTimeOf(projectRoot, rel);
|
|
103
|
+
if (at ? after(at) : after(e.valid_from)) {
|
|
104
|
+
why.push(at ? `committed at ${at}, after the run started ${runStart}` : `recorded ${e.valid_from} (commit time unavailable), after the run started ${runStart}`);
|
|
105
|
+
}
|
|
106
|
+
} else if (!committed && after(e.valid_from)) {
|
|
107
|
+
why.push(`recorded ${e.valid_from}, after the run started ${runStart}`);
|
|
108
|
+
}
|
|
109
|
+
if (why.length && migrated?.unvouched) why.push(migrated.unvouched);
|
|
110
|
+
if (why.length) out.push({ id: e.id, kind: e.kind, path: rel, visibility: e.visibility, why });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Release decisions (override / waiver / approval) in reach that git HEAD does not hold — what `gate deliver` refuses. */
|
|
117
|
+
export function uncommittedReleaseDecisions(projectRoot: string, scopes: string[]): InRunDecision[] {
|
|
118
|
+
return inRunDecisions(projectRoot, scopes, null, committedDecisionPaths(projectRoot));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Whether any decision of an in-run kind is in reach at all — the no-git notes are printed only then. */
|
|
122
|
+
export function hasInRunKindDecisions(projectRoot: string, scopes: string[]): boolean {
|
|
123
|
+
return scopes.some((s) => readDecisions(projectRoot, s).entries.some((e) => isInRunKind(e.kind)));
|
|
124
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the journey board and `runGate` take from the gate registry (OES-11.2/11.4, phase-03 review).
|
|
3
|
+
*
|
|
4
|
+
* readJourneyAudit the audit report, read through the T3 checks — a stale or untrusted one
|
|
5
|
+
* counts as never audited
|
|
6
|
+
* applyAuditOverrides an OB-* whose rule the AUDIT recorded as overridden is accepted
|
|
7
|
+
* (`overridden`); journey never re-applies an override itself (red-team #12)
|
|
8
|
+
* journeyDecisionFindings the decision files in the unit's reach that do not verify, edits/deletes
|
|
9
|
+
* of committed entries (checkDecisionIntegrity), and rejected overrides — each
|
|
10
|
+
* a finding the board shows and the gate blocks on, never a crash
|
|
11
|
+
*/
|
|
12
|
+
import { checkDecisionIntegrity } from '../../decisions/decision-integrity-check';
|
|
13
|
+
import { resolveUnitCandidates } from '../../cli/resolve-unit';
|
|
14
|
+
import { auditCounts, auditNotCountedReason, AuditVerification, verifyAuditReport } from './audit-report-verification';
|
|
15
|
+
import { GateOverrideReport } from './gate-override-report';
|
|
16
|
+
import { ActiveOverride } from './resolve-rule';
|
|
17
|
+
import { loadUnitGateOverrides, unitScopeOfDir, UnitGateOverrides } from './unit-gate-overrides';
|
|
18
|
+
|
|
19
|
+
export interface JourneyAuditInput {
|
|
20
|
+
audit: Record<string, unknown> | null;
|
|
21
|
+
verification: AuditVerification;
|
|
22
|
+
/** Set when a report exists but does not count (stale / invalid). */
|
|
23
|
+
notCountedReason?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function readJourneyAudit(projectRoot: string, unit: string): JourneyAuditInput {
|
|
27
|
+
const verification = verifyAuditReport(projectRoot, unit);
|
|
28
|
+
if (auditCounts(verification)) return { audit: verification.report, verification };
|
|
29
|
+
return {
|
|
30
|
+
audit: null,
|
|
31
|
+
verification,
|
|
32
|
+
...(verification.state !== 'absent' ? { notCountedReason: auditNotCountedReason(verification, unit) } : {}),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** The audit rule each design obligation stands for. */
|
|
37
|
+
export const OBLIGATION_RULE: Readonly<Record<string, string>> = {
|
|
38
|
+
'OB-spec': 'audit.spec-coverage',
|
|
39
|
+
'OB-coverage': 'audit.viewpoint-coverage',
|
|
40
|
+
'OB-depth': 'audit.assertion-depth',
|
|
41
|
+
'OB-trace': 'audit.taxonomy-mismatch',
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
interface OverridableObligation { id: string; status: string; detail: string; overriddenBy?: string }
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Mark needs-work obligations whose rule the audit recorded as overridden (applied). audit.json is
|
|
48
|
+
* output too: an `applied` entry counts only when the same override (decision id AND rule) is in
|
|
49
|
+
* force for the unit today (review M3); the others are ignored and returned for the board.
|
|
50
|
+
*/
|
|
51
|
+
export function applyAuditOverrides<T extends OverridableObligation>(obligations: T[], audit: Record<string, unknown>, inForce: ActiveOverride[]): GateOverrideReport[] {
|
|
52
|
+
const recorded = (Array.isArray(audit.gateOverrides) ? audit.gateOverrides as GateOverrideReport[] : [])
|
|
53
|
+
.filter((g) => g && g.status === 'applied');
|
|
54
|
+
const real = (g: GateOverrideReport): boolean => inForce.some((o) => o.decisionId === g.decisionId && o.rule === g.rule);
|
|
55
|
+
const applied = recorded.filter(real);
|
|
56
|
+
for (const ob of obligations) {
|
|
57
|
+
const o = applied.find((g) => g.rule === OBLIGATION_RULE[ob.id]);
|
|
58
|
+
if (!o || ob.status !== 'needs-work') continue;
|
|
59
|
+
ob.status = 'overridden';
|
|
60
|
+
ob.overriddenBy = o.decisionId;
|
|
61
|
+
ob.detail = `overridden by ${o.decisionId} (${o.rule} → ${o.severity}) — ${o.reason}. Was: ${ob.detail}`;
|
|
62
|
+
}
|
|
63
|
+
return recorded.filter((g) => !real(g));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function ignoredOverrideText(g: GateOverrideReport): string {
|
|
67
|
+
return `⚠️ audit.json says override ${String(g.decisionId)} (${String(g.rule)}) applied, but it is not in force for this unit — ignored. Re-run the audit; never edit its report.`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface DecisionGateFinding { rule: 'decision.id-reuse' | 'decision.mutated' | 'gate.override-rejected'; path: string; message: string }
|
|
71
|
+
|
|
72
|
+
export function unitOverrides(projectRoot: string, unit: string): UnitGateOverrides {
|
|
73
|
+
const found = resolveUnitCandidates(unit, projectRoot);
|
|
74
|
+
return loadUnitGateOverrides(projectRoot, found.length === 1 ? unitScopeOfDir(projectRoot, found[0].dir) : null);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Integrity of every decision in the unit's reach (project + unit dirs) plus its rejected overrides. */
|
|
78
|
+
export function journeyDecisionFindings(projectRoot: string, overrides: UnitGateOverrides): DecisionGateFinding[] {
|
|
79
|
+
const reach = ['qa/decisions/', ...(overrides.unitScope ? [`qa/${overrides.unitScope}/decisions/`] : [])];
|
|
80
|
+
const integrity: DecisionGateFinding[] = checkDecisionIntegrity(projectRoot)
|
|
81
|
+
.filter((f) => reach.some((r) => f.path.startsWith(r)))
|
|
82
|
+
.map((f) => ({ rule: f.rule, path: f.path, message: f.message }));
|
|
83
|
+
const rejected: DecisionGateFinding[] = overrides.rejected.map((r) => ({ rule: 'gate.override-rejected', path: r.path, message: `${r.decisionId}: ${r.reason}` }));
|
|
84
|
+
return [...integrity, ...rejected];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function decisionFindingText(f: DecisionGateFinding): string {
|
|
88
|
+
return `⛔ ${f.rule}: ${f.path} — ${f.message}. Hard rule: restore the file from git, or record a superseding decision on a terminal.`;
|
|
89
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Could a migrated waiver's legacy record have been the source of the import that wrote it? (#925)
|
|
3
|
+
*
|
|
4
|
+
* The one-time import (legacy-waiver-migration.ts) reads a record git HEAD ALREADY holds, and only
|
|
5
|
+
* before 3.3 takes over. So a genuine record was committed strictly before each of:
|
|
6
|
+
* 1. the decision file's first appearance — its first commit, else its creation on disk;
|
|
7
|
+
* 2. the unit's import marker `.sungen/migrations/<slug>.waivers-imported.json` — the commit that
|
|
8
|
+
* added the one HEAD holds (an agent can delete or recreate the file, not that commit), else its
|
|
9
|
+
* creation on disk; once it exists the import never reads that unit's legacy file again;
|
|
10
|
+
* 3. the project's adoption of 3.3 — the first commit that added any 3.3-only file: an import marker
|
|
11
|
+
* or other `.sungen/migrations/` file, a decision file (`qa/**\/decisions/*.yaml`) or a contract lock
|
|
12
|
+
* (`qa/**\/contracts.lock.yaml`). Only the 3.3 CLI writes them, and only committed ones count: a
|
|
13
|
+
* legacy waiver is one written before the project's first reviewed 3.3 change. Mixed versions pay
|
|
14
|
+
* for it: a waiver a pre-3.3 CLI writes after that commit must be re-confirmed on a terminal.
|
|
15
|
+
* A record failing any bound claims a migration that never happened: the decision is in-run.
|
|
16
|
+
*
|
|
17
|
+
* What stays open (the limit of any time-based check, as for ordinary decisions): a record forged and
|
|
18
|
+
* committed before the project's first 3.3 commit — indistinguishable from a real legacy waiver, as on
|
|
19
|
+
* a project adopting 3.3 for the very first time — and commit times forged with GIT_COMMITTER_DATE.
|
|
20
|
+
*/
|
|
21
|
+
import * as fs from 'fs';
|
|
22
|
+
import * as path from 'path';
|
|
23
|
+
import { committedText, gitOutput } from '../../decisions/git-head-trust';
|
|
24
|
+
import { formatCommand } from '../../decisions/human-confirmation';
|
|
25
|
+
import { importMarkerPath } from '../../decisions/legacy-waiver-migration';
|
|
26
|
+
import type { ReadDecision } from '../../decisions/read-decisions';
|
|
27
|
+
|
|
28
|
+
/** Files only the 3.3 CLI writes, as pathspecs relative to the project. */
|
|
29
|
+
const ADOPTION_PATHSPECS = ['.sungen/migrations', ':(glob)qa/**/decisions/*.yaml', ':(glob)qa/**/contracts.lock.yaml'];
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* What a human does about a migrated waiver its legacy record cannot vouch for: record it anew on a
|
|
33
|
+
* terminal (a `cli` decision that supersedes it — the superseded one is no longer judged), or accept it
|
|
34
|
+
* for one delivery.
|
|
35
|
+
*/
|
|
36
|
+
export const migratedWaiverRemedy = (scope: string, ob: string): string =>
|
|
37
|
+
`re-confirm it on a terminal: ${formatCommand(['sungen', 'journey', '--screen', scope.split('/').pop() ?? scope, '--waive', ob, '--reason', '…'])}, `
|
|
38
|
+
+ 'then commit the new decision; or accept it once with `sungen delivery --accept-in-run`';
|
|
39
|
+
|
|
40
|
+
const validMs = (iso: string | undefined): number | null => (iso && !Number.isNaN(Date.parse(iso)) ? Date.parse(iso) : null);
|
|
41
|
+
const createdMs = (abs: string): number | null => {
|
|
42
|
+
try { const s = fs.statSync(abs); return s.birthtimeMs || s.mtimeMs; } catch { return null; }
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** One run's bounds: each decision's first appearance, each unit's marker and the project's adoption, read once. */
|
|
46
|
+
export function migratedWaiverImportBounds(projectRoot: string) {
|
|
47
|
+
const relOf = (abs: string): string => path.relative(projectRoot, abs).split(path.sep).join('/');
|
|
48
|
+
const firstSeen = new Map<string, number>();
|
|
49
|
+
const markers = new Map<string, number | null>();
|
|
50
|
+
let adoption: number | null | undefined;
|
|
51
|
+
|
|
52
|
+
/** When a decision file first appeared: its first commit, else its creation (or last change) on disk. */
|
|
53
|
+
const decisionMs = (e: ReadDecision): number => {
|
|
54
|
+
if (!firstSeen.has(e.path)) {
|
|
55
|
+
const added = gitOutput(projectRoot, ['log', '--diff-filter=A', '--format=%cI', '--', relOf(e.path)])?.trim().split('\n').filter(Boolean).pop();
|
|
56
|
+
firstSeen.set(e.path, validMs(added) ?? createdMs(e.path) ?? Number.NEGATIVE_INFINITY);
|
|
57
|
+
}
|
|
58
|
+
return firstSeen.get(e.path)!;
|
|
59
|
+
};
|
|
60
|
+
const markerMs = (slug: string): number | null => {
|
|
61
|
+
if (!markers.has(slug)) {
|
|
62
|
+
const abs = importMarkerPath(projectRoot, slug);
|
|
63
|
+
const added = committedText(projectRoot, abs) !== null
|
|
64
|
+
? validMs(gitOutput(projectRoot, ['log', '-1', '--diff-filter=A', '--format=%cI', '--', relOf(abs)])?.trim()) : null;
|
|
65
|
+
markers.set(slug, added ?? createdMs(abs));
|
|
66
|
+
}
|
|
67
|
+
return markers.get(slug)!;
|
|
68
|
+
};
|
|
69
|
+
const adoptionMs = (): number | null => {
|
|
70
|
+
if (adoption === undefined) {
|
|
71
|
+
const added = (gitOutput(projectRoot, ['log', '--diff-filter=A', '--format=%cI', '--', ...ADOPTION_PATHSPECS]) ?? '')
|
|
72
|
+
.split('\n').map((l) => validMs(l.trim())).filter((t): t is number => t !== null);
|
|
73
|
+
adoption = added.length ? Math.min(...added) : null;
|
|
74
|
+
}
|
|
75
|
+
return adoption;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/** The first bound a record committed at `legacy` (ms) crosses, or undefined. */
|
|
79
|
+
const boundCrossed = (slug: string, e: ReadDecision, legacy: number): string | undefined => {
|
|
80
|
+
const decision = decisionMs(e);
|
|
81
|
+
if (legacy > decision) return 'after this decision first appeared';
|
|
82
|
+
if (legacy === decision) return 'when this decision first appeared, not before it — an import only reads a record already committed';
|
|
83
|
+
const marker = markerMs(slug);
|
|
84
|
+
if (marker !== null && legacy >= marker) {
|
|
85
|
+
return `after this unit's waivers were imported (${relOf(importMarkerPath(projectRoot, slug))}, ${new Date(marker).toISOString()}) `
|
|
86
|
+
+ '— from then on the import never reads the legacy file';
|
|
87
|
+
}
|
|
88
|
+
const adopted = adoptionMs();
|
|
89
|
+
if (adopted !== null && legacy >= adopted) {
|
|
90
|
+
return `after this project adopted sungen 3.3 (${new Date(adopted).toISOString()}: the first commit adding a .sungen/migrations/ file, `
|
|
91
|
+
+ 'a decision or a contract lock) — a legacy waiver is one written before that';
|
|
92
|
+
}
|
|
93
|
+
return undefined;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
/** Why a record committed at `at` (state file of `slug`) cannot have been the source of `e`'s import; undefined when it can. */
|
|
98
|
+
notImported(slug: string, e: ReadDecision, at: string): string | undefined {
|
|
99
|
+
const why = boundCrossed(slug, e, Date.parse(at));
|
|
100
|
+
return why && `migrated: its legacy record was committed at ${at}, ${why}; ${migratedWaiverRemedy(e.scope, String(e.payload?.obligation))}`;
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* When a MIGRATED waiver was reviewed (DOS-13.5, phase 09) — for `decision.in-run`.
|
|
3
|
+
*
|
|
4
|
+
* The import (legacy-waiver-migration.ts) trusts a legacy waiver only when git HEAD's
|
|
5
|
+
* `.sungen/journey/<slug>.state.json` holds that exact record; its review was the commit that put the
|
|
6
|
+
* record there. So a migrated decision is judged by THAT commit, not by its own file:
|
|
7
|
+
*
|
|
8
|
+
* vouched HEAD's state file holds the record (same reason, `at`, auditHashAtWaive) — reviewedAt is
|
|
9
|
+
* the commit time of the oldest commit in the unbroken run, back from HEAD, that holds it
|
|
10
|
+
* imported the record could have been the import's source (#925) — always checked, run start or not:
|
|
11
|
+
* committed strictly before the decision file, the unit's import marker and the project's
|
|
12
|
+
* adoption of 3.3 first appeared (migrated-waiver-import-bounds.ts). Failing one, the decision
|
|
13
|
+
* claims a migration that never happened → in-run, even at `gate --phase deliver`, which has
|
|
14
|
+
* no run start.
|
|
15
|
+
* with a run start also in-run when reviewedAt is after it (the same test as any committed decision)
|
|
16
|
+
* Anything else — no git, no such record in HEAD, a record that differs — is not vouched for: the
|
|
17
|
+
* decision is judged as any other (`not in git HEAD`, or its own commit time). Only a rewritten history
|
|
18
|
+
* (a squash or rebase that folds the record's commit into the import's) can fail a genuine import; the
|
|
19
|
+
* finding says which bound it crossed.
|
|
20
|
+
*
|
|
21
|
+
* Nor is a record whose introducing commit is out of reach — judged as any other, with `unvouched`
|
|
22
|
+
* saying why, never vouched for by a later commit taken for its introduction: the walk reads at most
|
|
23
|
+
* MAX_COMMITS commits of a state file and the record is held by the commit before them too (#924), or
|
|
24
|
+
* the record reaches a shallow clone's boundary commit. One review reads each state file's history
|
|
25
|
+
* once (one `git log`, one `git cat-file --batch`), however many waivers share it.
|
|
26
|
+
*/
|
|
27
|
+
import { gitFileTexts, gitOutput, isShallowRepository } from '../../decisions/git-head-trust';
|
|
28
|
+
import type { ReadDecision } from '../../decisions/read-decisions';
|
|
29
|
+
import { asLegacyWaiver, isLegacyWaiver, sameWaiver } from '../../decisions/waiver-decisions';
|
|
30
|
+
import { reportSlug } from '../unit-paths';
|
|
31
|
+
import { migratedWaiverImportBounds, migratedWaiverRemedy } from './migrated-waiver-import-bounds';
|
|
32
|
+
|
|
33
|
+
/** Commits of one state file the walk reads at most. */
|
|
34
|
+
const MAX_COMMITS = 200;
|
|
35
|
+
|
|
36
|
+
type State = { waivers?: Record<string, unknown> } | null;
|
|
37
|
+
/** A state file in git: HEAD's version and its newest MAX_COMMITS + 1 commits (newest first; `root`: no parent shown). */
|
|
38
|
+
interface StateHistory { rel: string; head: State; commits: Array<{ at: string; state: State; root: boolean }> }
|
|
39
|
+
|
|
40
|
+
/** A migrated waiver HEAD's legacy file holds: when it was reviewed, or why that cannot be said. */
|
|
41
|
+
export interface MigratedReview {
|
|
42
|
+
/** When its legacy record was committed; null when that commit is out of reach (see `unvouched`). */
|
|
43
|
+
at: string | null;
|
|
44
|
+
/** Set with `at`: why the record cannot have been the import's source — the decision is in-run. */
|
|
45
|
+
notImported?: string;
|
|
46
|
+
/** Set when `at` is null: why the record vouches for nothing — the decision is judged as any other. */
|
|
47
|
+
unvouched?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const parse = (text: string | null): State => {
|
|
51
|
+
if (text === null) return null;
|
|
52
|
+
try { return JSON.parse(text.replace(/^/, '')); } catch { return null; }
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
function holds(state: State, e: ReadDecision, ob: string): boolean {
|
|
56
|
+
const w = state?.waivers?.[ob];
|
|
57
|
+
return isLegacyWaiver(w) && w.at === e.valid_from && sameWaiver(w, asLegacyWaiver(e));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function readHistory(projectRoot: string, rel: string): StateHistory {
|
|
61
|
+
const log = (gitOutput(projectRoot, ['log', `--max-count=${MAX_COMMITS + 1}`, '--format=%H %cI %P', '--', rel]) ?? '')
|
|
62
|
+
.split('\n').filter(Boolean).map((line) => line.trim().split(' '));
|
|
63
|
+
const texts = gitFileTexts(projectRoot, [`HEAD:./${rel}`, ...log.map(([sha]) => `${sha}:./${rel}`)]);
|
|
64
|
+
return {
|
|
65
|
+
rel,
|
|
66
|
+
head: parse(texts?.[0] ?? null),
|
|
67
|
+
commits: log.map(([, at, ...parents], i) => ({ at, state: parse(texts?.[i + 1] ?? null), root: parents.length === 0 })),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The commit time of the oldest commit, in the unbroken run back from HEAD, whose state file holds the
|
|
73
|
+
* record. The walk reads MAX_COMMITS commits; the next one only says whether the last of them introduced it.
|
|
74
|
+
* In a shallow clone a commit with no parent shown is the boundary: every file seems to appear there, so a
|
|
75
|
+
* record reaching it has no known commit time.
|
|
76
|
+
*/
|
|
77
|
+
function introducedAt(h: StateHistory, e: ReadDecision, ob: string, scope: string, shallow: () => boolean): MigratedReview | null {
|
|
78
|
+
let run = 0;
|
|
79
|
+
while (run < h.commits.length && holds(h.commits[run].state, e, ob)) run++;
|
|
80
|
+
const unvouched = (why: string): MigratedReview => ({ at: null, unvouched: `migrated, but its legacy record cannot vouch for it: ${why}` });
|
|
81
|
+
if (run > MAX_COMMITS) {
|
|
82
|
+
return unvouched(`${h.rel} changed in more than ${MAX_COMMITS} commits, and the commit that introduced the record is older than all of them`);
|
|
83
|
+
}
|
|
84
|
+
const oldest = run ? h.commits[run - 1] : null;
|
|
85
|
+
if (oldest?.root && shallow()) {
|
|
86
|
+
return unvouched(`the git history is shallow, so the record's real commit time is unknown — fetch the full history `
|
|
87
|
+
+ `(\`git fetch --unshallow\`; \`fetch-depth: 0\` in CI), or ${migratedWaiverRemedy(scope, ob)}`);
|
|
88
|
+
}
|
|
89
|
+
return oldest && !Number.isNaN(Date.parse(oldest.at)) ? { at: oldest.at } : null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** One run's reads for migrated waivers: each state file's history, decision's first commit and import marker, read once. */
|
|
93
|
+
export function migratedWaiverReview(projectRoot: string) {
|
|
94
|
+
const histories = new Map<string, StateHistory>();
|
|
95
|
+
const bounds = migratedWaiverImportBounds(projectRoot);
|
|
96
|
+
let isShallow: boolean | undefined;
|
|
97
|
+
const shallow = (): boolean => (isShallow ??= isShallowRepository(projectRoot));
|
|
98
|
+
const historyOf = (rel: string): StateHistory => {
|
|
99
|
+
if (!histories.has(rel)) histories.set(rel, readHistory(projectRoot, rel));
|
|
100
|
+
return histories.get(rel)!;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
/** How a migrated waiver was reviewed; null when it is not one HEAD's legacy file holds (judged as any other). */
|
|
105
|
+
reviewOf(scope: string, e: ReadDecision): MigratedReview | null {
|
|
106
|
+
const ob = e.payload?.obligation;
|
|
107
|
+
if (e.kind !== 'waiver' || e.source?.where !== 'migrated' || typeof ob !== 'string') return null;
|
|
108
|
+
// The journey keys its state by the unit name it was given: `<name>`, or the catalog id for api units.
|
|
109
|
+
const slugs = new Set([scope.split('/').pop() ?? '', reportSlug(scope.replace(/^(screens|flows)\//, ''))]);
|
|
110
|
+
let unvouched: MigratedReview | null = null;
|
|
111
|
+
for (const slug of slugs) {
|
|
112
|
+
const h = historyOf(`.sungen/journey/${slug}.state.json`);
|
|
113
|
+
if (!holds(h.head, e, ob)) continue;
|
|
114
|
+
const review = introducedAt(h, e, ob, scope, shallow);
|
|
115
|
+
if (review?.at) return { at: review.at, notImported: bounds.notImported(slug, e, review.at) };
|
|
116
|
+
unvouched = unvouched ?? review;
|
|
117
|
+
}
|
|
118
|
+
return unvouched;
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
}
|