@sun-asterisk/sungen 3.2.34 → 3.3.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/basis/anchor-grammar.d.ts +32 -0
- package/dist/basis/anchor-grammar.d.ts.map +1 -0
- package/dist/basis/anchor-grammar.js +82 -0
- package/dist/basis/anchor-grammar.js.map +1 -0
- package/dist/basis/anchor-hash.d.ts +6 -0
- package/dist/basis/anchor-hash.d.ts.map +1 -0
- package/dist/basis/anchor-hash.js +28 -0
- package/dist/basis/anchor-hash.js.map +1 -0
- package/dist/basis/bm51-tables.d.ts +20 -0
- package/dist/basis/bm51-tables.d.ts.map +1 -0
- package/dist/basis/bm51-tables.js +71 -0
- package/dist/basis/bm51-tables.js.map +1 -0
- package/dist/basis/extract-spec-anchors.d.ts +39 -0
- package/dist/basis/extract-spec-anchors.d.ts.map +1 -0
- package/dist/basis/extract-spec-anchors.js +81 -0
- package/dist/basis/extract-spec-anchors.js.map +1 -0
- package/dist/basis/migration-sentinel.d.ts +47 -0
- package/dist/basis/migration-sentinel.d.ts.map +1 -0
- package/dist/basis/migration-sentinel.js +219 -0
- package/dist/basis/migration-sentinel.js.map +1 -0
- package/dist/basis/spec-frontmatter.d.ts +18 -0
- package/dist/basis/spec-frontmatter.d.ts.map +1 -0
- package/dist/basis/spec-frontmatter.js +55 -0
- package/dist/basis/spec-frontmatter.js.map +1 -0
- package/dist/basis/spec-sections.d.ts +18 -0
- package/dist/basis/spec-sections.d.ts.map +1 -0
- package/dist/basis/spec-sections.js +27 -0
- package/dist/basis/spec-sections.js.map +1 -0
- package/dist/basis/test-basis-schema.d.ts +28 -0
- package/dist/basis/test-basis-schema.d.ts.map +1 -0
- package/dist/basis/test-basis-schema.js +141 -0
- package/dist/basis/test-basis-schema.js.map +1 -0
- package/dist/capabilities/discover.d.ts +4 -0
- package/dist/capabilities/discover.d.ts.map +1 -1
- package/dist/capabilities/discover.js +16 -2
- package/dist/capabilities/discover.js.map +1 -1
- package/dist/capabilities/registry.d.ts +15 -0
- package/dist/capabilities/registry.d.ts.map +1 -1
- package/dist/capabilities/registry.js.map +1 -1
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/audit.js +10 -5
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/capability.d.ts.map +1 -1
- package/dist/cli/commands/capability.js +6 -2
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/cli/commands/contract-derive-command.d.ts +11 -0
- package/dist/cli/commands/contract-derive-command.d.ts.map +1 -0
- package/dist/cli/commands/contract-derive-command.js +99 -0
- package/dist/cli/commands/contract-derive-command.js.map +1 -0
- package/dist/cli/commands/contract.d.ts +17 -0
- package/dist/cli/commands/contract.d.ts.map +1 -0
- package/dist/cli/commands/contract.js +162 -0
- package/dist/cli/commands/contract.js.map +1 -0
- package/dist/cli/commands/defect.d.ts +7 -0
- package/dist/cli/commands/defect.d.ts.map +1 -0
- package/dist/cli/commands/defect.js +68 -0
- package/dist/cli/commands/defect.js.map +1 -0
- package/dist/cli/commands/delivery.d.ts.map +1 -1
- package/dist/cli/commands/delivery.js +96 -12
- package/dist/cli/commands/delivery.js.map +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +3 -1
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/journey.d.ts.map +1 -1
- package/dist/cli/commands/journey.js +43 -15
- package/dist/cli/commands/journey.js.map +1 -1
- package/dist/cli/commands/next.d.ts +8 -0
- package/dist/cli/commands/next.d.ts.map +1 -1
- package/dist/cli/commands/next.js +68 -8
- package/dist/cli/commands/next.js.map +1 -1
- package/dist/cli/commands/triage.d.ts +7 -0
- package/dist/cli/commands/triage.d.ts.map +1 -0
- package/dist/cli/commands/triage.js +98 -0
- package/dist/cli/commands/triage.js.map +1 -0
- package/dist/cli/commands/update.d.ts +11 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +31 -6
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/index.js +24 -33
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/project-sungen-invocation.d.ts +7 -0
- package/dist/cli/project-sungen-invocation.d.ts.map +1 -0
- package/dist/cli/project-sungen-invocation.js +76 -0
- package/dist/cli/project-sungen-invocation.js.map +1 -0
- package/dist/contract/approve-contract.d.ts +31 -0
- package/dist/contract/approve-contract.d.ts.map +1 -0
- package/dist/contract/approve-contract.js +87 -0
- package/dist/contract/approve-contract.js.map +1 -0
- package/dist/contract/assertion-matcher-vocabulary.d.ts +24 -0
- package/dist/contract/assertion-matcher-vocabulary.d.ts.map +1 -0
- package/dist/contract/assertion-matcher-vocabulary.js +100 -0
- package/dist/contract/assertion-matcher-vocabulary.js.map +1 -0
- package/dist/contract/build-contract-verdict.d.ts +32 -0
- package/dist/contract/build-contract-verdict.d.ts.map +1 -0
- package/dist/contract/build-contract-verdict.js +123 -0
- package/dist/contract/build-contract-verdict.js.map +1 -0
- package/dist/contract/build-trace-conformance.d.ts +18 -0
- package/dist/contract/build-trace-conformance.d.ts.map +1 -0
- package/dist/contract/build-trace-conformance.js +153 -0
- package/dist/contract/build-trace-conformance.js.map +1 -0
- package/dist/contract/classify-contract-change.d.ts +23 -0
- package/dist/contract/classify-contract-change.d.ts.map +1 -0
- package/dist/contract/classify-contract-change.js +98 -0
- package/dist/contract/classify-contract-change.js.map +1 -0
- package/dist/contract/classify-contract-unit.d.ts +18 -0
- package/dist/contract/classify-contract-unit.d.ts.map +1 -0
- package/dist/contract/classify-contract-unit.js +49 -0
- package/dist/contract/classify-contract-unit.js.map +1 -0
- package/dist/contract/classify-trace-conformance.d.ts +32 -0
- package/dist/contract/classify-trace-conformance.d.ts.map +1 -0
- package/dist/contract/classify-trace-conformance.js +117 -0
- package/dist/contract/classify-trace-conformance.js.map +1 -0
- package/dist/contract/contract-git.d.ts +24 -0
- package/dist/contract/contract-git.d.ts.map +1 -0
- package/dist/contract/contract-git.js +144 -0
- package/dist/contract/contract-git.js.map +1 -0
- package/dist/contract/contract-hash.d.ts +7 -0
- package/dist/contract/contract-hash.d.ts.map +1 -0
- package/dist/contract/contract-hash.js +38 -0
- package/dist/contract/contract-hash.js.map +1 -0
- package/dist/contract/contract-report-file.d.ts +4 -0
- package/dist/contract/contract-report-file.d.ts.map +1 -0
- package/dist/contract/contract-report-file.js +60 -0
- package/dist/contract/contract-report-file.js.map +1 -0
- package/dist/contract/contract-schema.d.ts +71 -0
- package/dist/contract/contract-schema.d.ts.map +1 -0
- package/dist/contract/contract-schema.js +102 -0
- package/dist/contract/contract-schema.js.map +1 -0
- package/dist/contract/contract-units.d.ts +12 -0
- package/dist/contract/contract-units.d.ts.map +1 -0
- package/dist/contract/contract-units.js +96 -0
- package/dist/contract/contract-units.js.map +1 -0
- package/dist/contract/contracts-lock-file.d.ts +24 -0
- package/dist/contract/contracts-lock-file.d.ts.map +1 -0
- package/dist/contract/contracts-lock-file.js +140 -0
- package/dist/contract/contracts-lock-file.js.map +1 -0
- package/dist/contract/data-normalize.d.ts +10 -0
- package/dist/contract/data-normalize.d.ts.map +1 -0
- package/dist/contract/data-normalize.js +110 -0
- package/dist/contract/data-normalize.js.map +1 -0
- package/dist/contract/derive-free-feature.d.ts +38 -0
- package/dist/contract/derive-free-feature.d.ts.map +1 -0
- package/dist/contract/derive-free-feature.js +154 -0
- package/dist/contract/derive-free-feature.js.map +1 -0
- package/dist/contract/field-semantic-redaction.d.ts +21 -0
- package/dist/contract/field-semantic-redaction.d.ts.map +1 -0
- package/dist/contract/field-semantic-redaction.js +118 -0
- package/dist/contract/field-semantic-redaction.js.map +1 -0
- package/dist/contract/free-feature-blocks.d.ts +10 -0
- package/dist/contract/free-feature-blocks.d.ts.map +1 -0
- package/dist/contract/free-feature-blocks.js +94 -0
- package/dist/contract/free-feature-blocks.js.map +1 -0
- package/dist/contract/lock-secret-guard.d.ts +22 -0
- package/dist/contract/lock-secret-guard.d.ts.map +1 -0
- package/dist/contract/lock-secret-guard.js +134 -0
- package/dist/contract/lock-secret-guard.js.map +1 -0
- package/dist/contract/lock-vs-git-head.d.ts +26 -0
- package/dist/contract/lock-vs-git-head.d.ts.map +1 -0
- package/dist/contract/lock-vs-git-head.js +28 -0
- package/dist/contract/lock-vs-git-head.js.map +1 -0
- package/dist/contract/normalize-contract-step.d.ts +21 -0
- package/dist/contract/normalize-contract-step.d.ts.map +1 -0
- package/dist/contract/normalize-contract-step.js +70 -0
- package/dist/contract/normalize-contract-step.js.map +1 -0
- package/dist/contract/normalize-feature-steps.d.ts +7 -0
- package/dist/contract/normalize-feature-steps.d.ts.map +1 -0
- package/dist/contract/normalize-feature-steps.js +127 -0
- package/dist/contract/normalize-feature-steps.js.map +1 -0
- package/dist/contract/oracle-strength.d.ts +12 -0
- package/dist/contract/oracle-strength.d.ts.map +1 -0
- package/dist/contract/oracle-strength.js +88 -0
- package/dist/contract/oracle-strength.js.map +1 -0
- package/dist/contract/project-contract-blockers.d.ts +10 -0
- package/dist/contract/project-contract-blockers.d.ts.map +1 -0
- package/dist/contract/project-contract-blockers.js +73 -0
- package/dist/contract/project-contract-blockers.js.map +1 -0
- package/dist/contract/record-contract-approval.d.ts +21 -0
- package/dist/contract/record-contract-approval.d.ts.map +1 -0
- package/dist/contract/record-contract-approval.js +98 -0
- package/dist/contract/record-contract-approval.js.map +1 -0
- package/dist/contract/render-free-gherkin.d.ts +40 -0
- package/dist/contract/render-free-gherkin.d.ts.map +1 -0
- package/dist/contract/render-free-gherkin.js +141 -0
- package/dist/contract/render-free-gherkin.js.map +1 -0
- package/dist/contract/render-trace-sentence.d.ts +20 -0
- package/dist/contract/render-trace-sentence.d.ts.map +1 -0
- package/dist/contract/render-trace-sentence.js +109 -0
- package/dist/contract/render-trace-sentence.js.map +1 -0
- package/dist/contract/render-trace-target.d.ts +14 -0
- package/dist/contract/render-trace-target.d.ts.map +1 -0
- package/dist/contract/render-trace-target.js +70 -0
- package/dist/contract/render-trace-target.js.map +1 -0
- package/dist/contract/resolve-unit-trace-identities.d.ts +8 -0
- package/dist/contract/resolve-unit-trace-identities.d.ts.map +1 -0
- package/dist/contract/resolve-unit-trace-identities.js +78 -0
- package/dist/contract/resolve-unit-trace-identities.js.map +1 -0
- package/dist/contract/trace/collect-trace-evidence.d.ts +33 -0
- package/dist/contract/trace/collect-trace-evidence.d.ts.map +1 -0
- package/dist/contract/trace/collect-trace-evidence.js +161 -0
- package/dist/contract/trace/collect-trace-evidence.js.map +1 -0
- package/dist/contract/trace/identity-cache.d.ts +19 -0
- package/dist/contract/trace/identity-cache.d.ts.map +1 -0
- package/dist/contract/trace/identity-cache.js +104 -0
- package/dist/contract/trace/identity-cache.js.map +1 -0
- package/dist/contract/trace/select-final-attempt.d.ts +27 -0
- package/dist/contract/trace/select-final-attempt.d.ts.map +1 -0
- package/dist/contract/trace/select-final-attempt.js +116 -0
- package/dist/contract/trace/select-final-attempt.js.map +1 -0
- package/dist/contract/trace/snapshot-html-renderer.d.ts +31 -0
- package/dist/contract/trace/snapshot-html-renderer.d.ts.map +1 -0
- package/dist/contract/trace/snapshot-html-renderer.js +172 -0
- package/dist/contract/trace/snapshot-html-renderer.js.map +1 -0
- package/dist/contract/trace/snapshot-resolver.d.ts +21 -0
- package/dist/contract/trace/snapshot-resolver.d.ts.map +1 -0
- package/dist/contract/trace/snapshot-resolver.js +65 -0
- package/dist/contract/trace/snapshot-resolver.js.map +1 -0
- package/dist/contract/trace/snapshot-store.d.ts +66 -0
- package/dist/contract/trace/snapshot-store.d.ts.map +1 -0
- package/dist/contract/trace/snapshot-store.js +173 -0
- package/dist/contract/trace/snapshot-store.js.map +1 -0
- package/dist/contract/trace/target-identity.d.ts +74 -0
- package/dist/contract/trace/target-identity.d.ts.map +1 -0
- package/dist/contract/trace/target-identity.js +68 -0
- package/dist/contract/trace/target-identity.js.map +1 -0
- package/dist/contract/trace/test-step-join.d.ts +65 -0
- package/dist/contract/trace/test-step-join.d.ts.map +1 -0
- package/dist/contract/trace/test-step-join.js +80 -0
- package/dist/contract/trace/test-step-join.js.map +1 -0
- package/dist/contract/trace/trace-binding.d.ts +21 -0
- package/dist/contract/trace/trace-binding.d.ts.map +1 -0
- package/dist/contract/trace/trace-binding.js +88 -0
- package/dist/contract/trace/trace-binding.js.map +1 -0
- package/dist/contract/trace/trace-file-reader.d.ts +41 -0
- package/dist/contract/trace/trace-file-reader.d.ts.map +1 -0
- package/dist/contract/trace/trace-file-reader.js +161 -0
- package/dist/contract/trace/trace-file-reader.js.map +1 -0
- package/dist/contract/trace/trace-fingerprint.d.ts +22 -0
- package/dist/contract/trace/trace-fingerprint.d.ts.map +1 -0
- package/dist/contract/trace/trace-fingerprint.js +96 -0
- package/dist/contract/trace/trace-fingerprint.js.map +1 -0
- package/dist/contract/trace/trace-identity-resolution.d.ts +26 -0
- package/dist/contract/trace/trace-identity-resolution.d.ts.map +1 -0
- package/dist/contract/trace/trace-identity-resolution.js +84 -0
- package/dist/contract/trace/trace-identity-resolution.js.map +1 -0
- package/dist/contract/trace/trace-run-record.d.ts +30 -0
- package/dist/contract/trace/trace-run-record.d.ts.map +1 -0
- package/dist/contract/trace/trace-run-record.js +121 -0
- package/dist/contract/trace/trace-run-record.js.map +1 -0
- package/dist/contract/trace/trace-steps.d.ts +19 -0
- package/dist/contract/trace/trace-steps.d.ts.map +1 -0
- package/dist/contract/trace/trace-steps.js +79 -0
- package/dist/contract/trace/trace-steps.js.map +1 -0
- package/dist/contract/trace/trace-zip-limits.d.ts +45 -0
- package/dist/contract/trace/trace-zip-limits.d.ts.map +1 -0
- package/dist/contract/trace/trace-zip-limits.js +52 -0
- package/dist/contract/trace/trace-zip-limits.js.map +1 -0
- package/dist/contract/trace/trace-zip-reader.d.ts +10 -0
- package/dist/contract/trace/trace-zip-reader.d.ts.map +1 -0
- package/dist/contract/trace/trace-zip-reader.js +186 -0
- package/dist/contract/trace/trace-zip-reader.js.map +1 -0
- package/dist/contract/verify-approval-decisions.d.ts +5 -0
- package/dist/contract/verify-approval-decisions.d.ts.map +1 -0
- package/dist/contract/verify-approval-decisions.js +104 -0
- package/dist/contract/verify-approval-decisions.js.map +1 -0
- package/dist/decisions/append-decision.d.ts +12 -0
- package/dist/decisions/append-decision.d.ts.map +1 -0
- package/dist/decisions/append-decision.js +73 -0
- package/dist/decisions/append-decision.js.map +1 -0
- package/dist/decisions/confirmed-decision-commands.d.ts +41 -0
- package/dist/decisions/confirmed-decision-commands.d.ts.map +1 -0
- package/dist/decisions/confirmed-decision-commands.js +190 -0
- package/dist/decisions/confirmed-decision-commands.js.map +1 -0
- package/dist/decisions/decision-file.d.ts +31 -0
- package/dist/decisions/decision-file.d.ts.map +1 -0
- package/dist/decisions/decision-file.js +139 -0
- package/dist/decisions/decision-file.js.map +1 -0
- package/dist/decisions/decision-identity.d.ts +12 -0
- package/dist/decisions/decision-identity.d.ts.map +1 -0
- package/dist/decisions/decision-identity.js +78 -0
- package/dist/decisions/decision-identity.js.map +1 -0
- package/dist/decisions/decision-integrity-check.d.ts +12 -0
- package/dist/decisions/decision-integrity-check.d.ts.map +1 -0
- package/dist/decisions/decision-integrity-check.js +102 -0
- package/dist/decisions/decision-integrity-check.js.map +1 -0
- package/dist/decisions/decision-schema.d.ts +42 -0
- package/dist/decisions/decision-schema.d.ts.map +1 -0
- package/dist/decisions/decision-schema.js +75 -0
- package/dist/decisions/decision-schema.js.map +1 -0
- package/dist/decisions/decision-source.d.ts +2 -0
- package/dist/decisions/decision-source.d.ts.map +1 -0
- package/dist/decisions/decision-source.js +18 -0
- package/dist/decisions/decision-source.js.map +1 -0
- package/dist/decisions/exclusive-file-create.d.ts +3 -0
- package/dist/decisions/exclusive-file-create.d.ts.map +1 -0
- package/dist/decisions/exclusive-file-create.js +84 -0
- package/dist/decisions/exclusive-file-create.js.map +1 -0
- package/dist/decisions/git-head-trust.d.ts +7 -0
- package/dist/decisions/git-head-trust.d.ts.map +1 -0
- package/dist/decisions/git-head-trust.js +76 -0
- package/dist/decisions/git-head-trust.js.map +1 -0
- package/dist/decisions/human-confirmation.d.ts +35 -0
- package/dist/decisions/human-confirmation.d.ts.map +1 -0
- package/dist/decisions/human-confirmation.js +161 -0
- package/dist/decisions/human-confirmation.js.map +1 -0
- package/dist/decisions/legacy-waiver-migration.d.ts +31 -0
- package/dist/decisions/legacy-waiver-migration.d.ts.map +1 -0
- package/dist/decisions/legacy-waiver-migration.js +170 -0
- package/dist/decisions/legacy-waiver-migration.js.map +1 -0
- package/dist/decisions/read-decisions.d.ts +19 -0
- package/dist/decisions/read-decisions.d.ts.map +1 -0
- package/dist/decisions/read-decisions.js +90 -0
- package/dist/decisions/read-decisions.js.map +1 -0
- package/dist/decisions/viewpoint-baseline-adapter.d.ts +7 -0
- package/dist/decisions/viewpoint-baseline-adapter.d.ts.map +1 -0
- package/dist/decisions/viewpoint-baseline-adapter.js +109 -0
- package/dist/decisions/viewpoint-baseline-adapter.js.map +1 -0
- package/dist/decisions/waiver-decisions.d.ts +24 -0
- package/dist/decisions/waiver-decisions.d.ts.map +1 -0
- package/dist/decisions/waiver-decisions.js +46 -0
- package/dist/decisions/waiver-decisions.js.map +1 -0
- package/dist/exporters/csv-exporter.d.ts +4 -0
- package/dist/exporters/csv-exporter.d.ts.map +1 -1
- package/dist/exporters/csv-exporter.js +1 -1
- package/dist/exporters/csv-exporter.js.map +1 -1
- package/dist/exporters/feature-parser.d.ts +8 -0
- package/dist/exporters/feature-parser.d.ts.map +1 -1
- package/dist/exporters/feature-parser.js +12 -0
- package/dist/exporters/feature-parser.js.map +1 -1
- package/dist/exporters/matrix/build.d.ts +3 -0
- package/dist/exporters/matrix/build.d.ts.map +1 -1
- package/dist/exporters/matrix/build.js +59 -19
- package/dist/exporters/matrix/build.js.map +1 -1
- package/dist/exporters/matrix/carry-manual-results.d.ts +19 -0
- package/dist/exporters/matrix/carry-manual-results.d.ts.map +1 -1
- package/dist/exporters/matrix/carry-manual-results.js +76 -6
- package/dist/exporters/matrix/carry-manual-results.js.map +1 -1
- package/dist/exporters/matrix/export.d.ts +8 -2
- package/dist/exporters/matrix/export.d.ts.map +1 -1
- package/dist/exporters/matrix/export.js +16 -3
- package/dist/exporters/matrix/export.js.map +1 -1
- package/dist/exporters/matrix/gates.d.ts +6 -1
- package/dist/exporters/matrix/gates.d.ts.map +1 -1
- package/dist/exporters/matrix/gates.js +57 -128
- package/dist/exporters/matrix/gates.js.map +1 -1
- package/dist/exporters/matrix/render-csv.d.ts.map +1 -1
- package/dist/exporters/matrix/render-csv.js +4 -1
- package/dist/exporters/matrix/render-csv.js.map +1 -1
- package/dist/exporters/matrix/render-gate-overrides-sheet.d.ts +13 -0
- package/dist/exporters/matrix/render-gate-overrides-sheet.d.ts.map +1 -0
- package/dist/exporters/matrix/render-gate-overrides-sheet.js +44 -0
- package/dist/exporters/matrix/render-gate-overrides-sheet.js.map +1 -0
- package/dist/exporters/matrix/render-xlsx.d.ts +1 -0
- package/dist/exporters/matrix/render-xlsx.d.ts.map +1 -1
- package/dist/exporters/matrix/render-xlsx.js +6 -0
- package/dist/exporters/matrix/render-xlsx.js.map +1 -1
- package/dist/exporters/matrix/types.d.ts +9 -1
- package/dist/exporters/matrix/types.d.ts.map +1 -1
- package/dist/exporters/matrix/types.js.map +1 -1
- package/dist/exporters/matrix/xlsx-cells.js +1 -1
- package/dist/exporters/matrix/xlsx-cells.js.map +1 -1
- package/dist/exporters/playwright-report-parser.d.ts.map +1 -1
- package/dist/exporters/playwright-report-parser.js +1 -0
- package/dist/exporters/playwright-report-parser.js.map +1 -1
- package/dist/exporters/scenario-merger.d.ts.map +1 -1
- package/dist/exporters/scenario-merger.js +2 -0
- package/dist/exporters/scenario-merger.js.map +1 -1
- package/dist/exporters/types.d.ts +5 -0
- package/dist/exporters/types.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +13 -0
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/graph/evaluate-graph.d.ts +23 -0
- package/dist/graph/evaluate-graph.d.ts.map +1 -0
- package/dist/graph/evaluate-graph.js +52 -0
- package/dist/graph/evaluate-graph.js.map +1 -0
- package/dist/graph/locate-finding.d.ts +20 -0
- package/dist/graph/locate-finding.d.ts.map +1 -0
- package/dist/graph/locate-finding.js +137 -0
- package/dist/graph/locate-finding.js.map +1 -0
- package/dist/graph/node-decl.d.ts +66 -0
- package/dist/graph/node-decl.d.ts.map +1 -0
- package/dist/graph/node-decl.js +8 -0
- package/dist/graph/node-decl.js.map +1 -0
- package/dist/graph/nodes/core-node-catalog.d.ts +7 -0
- package/dist/graph/nodes/core-node-catalog.d.ts.map +1 -0
- package/dist/graph/nodes/core-node-catalog.js +13 -0
- package/dist/graph/nodes/core-node-catalog.js.map +1 -0
- package/dist/graph/nodes/test-case-contract-nodes.d.ts +21 -0
- package/dist/graph/nodes/test-case-contract-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/test-case-contract-nodes.js +59 -0
- package/dist/graph/nodes/test-case-contract-nodes.js.map +1 -0
- package/dist/graph/nodes/test-case-nodes.d.ts +26 -0
- package/dist/graph/nodes/test-case-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/test-case-nodes.js +66 -0
- package/dist/graph/nodes/test-case-nodes.js.map +1 -0
- package/dist/graph/nodes/unit-audit-nodes.d.ts +18 -0
- package/dist/graph/nodes/unit-audit-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/unit-audit-nodes.js +95 -0
- package/dist/graph/nodes/unit-audit-nodes.js.map +1 -0
- package/dist/graph/nodes/unit-contract-node.d.ts +21 -0
- package/dist/graph/nodes/unit-contract-node.d.ts.map +1 -0
- package/dist/graph/nodes/unit-contract-node.js +88 -0
- package/dist/graph/nodes/unit-contract-node.js.map +1 -0
- package/dist/graph/nodes/unit-design-nodes.d.ts +14 -0
- package/dist/graph/nodes/unit-design-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/unit-design-nodes.js +91 -0
- package/dist/graph/nodes/unit-design-nodes.js.map +1 -0
- package/dist/graph/nodes/unit-execution-nodes.d.ts +16 -0
- package/dist/graph/nodes/unit-execution-nodes.d.ts.map +1 -0
- package/dist/graph/nodes/unit-execution-nodes.js +79 -0
- package/dist/graph/nodes/unit-execution-nodes.js.map +1 -0
- package/dist/graph/test-case-identity.d.ts +13 -0
- package/dist/graph/test-case-identity.d.ts.map +1 -0
- package/dist/graph/test-case-identity.js +106 -0
- package/dist/graph/test-case-identity.js.map +1 -0
- package/dist/graph/test-case-results.d.ts +11 -0
- package/dist/graph/test-case-results.d.ts.map +1 -0
- package/dist/graph/test-case-results.js +137 -0
- package/dist/graph/test-case-results.js.map +1 -0
- package/dist/graph/test-case-satisfied.d.ts +25 -0
- package/dist/graph/test-case-satisfied.d.ts.map +1 -0
- package/dist/graph/test-case-satisfied.js +51 -0
- package/dist/graph/test-case-satisfied.js.map +1 -0
- package/dist/graph/test-case-state-shape.d.ts +67 -0
- package/dist/graph/test-case-state-shape.d.ts.map +1 -0
- package/dist/graph/test-case-state-shape.js +3 -0
- package/dist/graph/test-case-state-shape.js.map +1 -0
- package/dist/graph/test-case-states.d.ts +9 -0
- package/dist/graph/test-case-states.d.ts.map +1 -0
- package/dist/graph/test-case-states.js +116 -0
- package/dist/graph/test-case-states.js.map +1 -0
- package/dist/graph/unit-artifact-probes.d.ts +19 -0
- package/dist/graph/unit-artifact-probes.d.ts.map +1 -0
- package/dist/graph/unit-artifact-probes.js +133 -0
- package/dist/graph/unit-artifact-probes.js.map +1 -0
- package/dist/graph/unit-state-facts.d.ts +43 -0
- package/dist/graph/unit-state-facts.d.ts.map +1 -0
- package/dist/graph/unit-state-facts.js +87 -0
- package/dist/graph/unit-state-facts.js.map +1 -0
- package/dist/harness/audit.d.ts +11 -0
- package/dist/harness/audit.d.ts.map +1 -1
- package/dist/harness/audit.js +34 -9
- package/dist/harness/audit.js.map +1 -1
- package/dist/harness/catalog/gate-rules.yaml +647 -0
- package/dist/harness/counted-assertions.d.ts +2 -0
- package/dist/harness/counted-assertions.d.ts.map +1 -0
- package/dist/harness/counted-assertions.js +38 -0
- package/dist/harness/counted-assertions.js.map +1 -0
- package/dist/harness/defect-draft.d.ts +14 -0
- package/dist/harness/defect-draft.d.ts.map +1 -0
- package/dist/harness/defect-draft.js +143 -0
- package/dist/harness/defect-draft.js.map +1 -0
- package/dist/harness/defects.d.ts +24 -0
- package/dist/harness/defects.d.ts.map +1 -0
- package/dist/harness/defects.js +118 -0
- package/dist/harness/defects.js.map +1 -0
- package/dist/harness/gates/audit-gate-terms.d.ts +41 -0
- package/dist/harness/gates/audit-gate-terms.d.ts.map +1 -0
- package/dist/harness/gates/audit-gate-terms.js +72 -0
- package/dist/harness/gates/audit-gate-terms.js.map +1 -0
- package/dist/harness/gates/audit-gate-verdict.d.ts +31 -0
- package/dist/harness/gates/audit-gate-verdict.d.ts.map +1 -0
- package/dist/harness/gates/audit-gate-verdict.js +101 -0
- package/dist/harness/gates/audit-gate-verdict.js.map +1 -0
- package/dist/harness/gates/audit-input-hash.d.ts +4 -0
- package/dist/harness/gates/audit-input-hash.d.ts.map +1 -0
- package/dist/harness/gates/audit-input-hash.js +96 -0
- package/dist/harness/gates/audit-input-hash.js.map +1 -0
- package/dist/harness/gates/audit-report-verification.d.ts +41 -0
- package/dist/harness/gates/audit-report-verification.d.ts.map +1 -0
- package/dist/harness/gates/audit-report-verification.js +236 -0
- package/dist/harness/gates/audit-report-verification.js.map +1 -0
- package/dist/harness/gates/decisions-hash.d.ts +13 -0
- package/dist/harness/gates/decisions-hash.d.ts.map +1 -0
- package/dist/harness/gates/decisions-hash.js +72 -0
- package/dist/harness/gates/decisions-hash.js.map +1 -0
- package/dist/harness/gates/delivery-checklist.d.ts +21 -0
- package/dist/harness/gates/delivery-checklist.d.ts.map +1 -0
- package/dist/harness/gates/delivery-checklist.js +128 -0
- package/dist/harness/gates/delivery-checklist.js.map +1 -0
- package/dist/harness/gates/delivery-decision-gate.d.ts +33 -0
- package/dist/harness/gates/delivery-decision-gate.d.ts.map +1 -0
- package/dist/harness/gates/delivery-decision-gate.js +116 -0
- package/dist/harness/gates/delivery-decision-gate.js.map +1 -0
- package/dist/harness/gates/delivery-decision-step.d.ts +19 -0
- package/dist/harness/gates/delivery-decision-step.d.ts.map +1 -0
- package/dist/harness/gates/delivery-decision-step.js +86 -0
- package/dist/harness/gates/delivery-decision-step.js.map +1 -0
- package/dist/harness/gates/gate-override-report.d.ts +59 -0
- package/dist/harness/gates/gate-override-report.d.ts.map +1 -0
- package/dist/harness/gates/gate-override-report.js +86 -0
- package/dist/harness/gates/gate-override-report.js.map +1 -0
- package/dist/harness/gates/gate-override-scope.d.ts +18 -0
- package/dist/harness/gates/gate-override-scope.d.ts.map +1 -0
- package/dist/harness/gates/gate-override-scope.js +98 -0
- package/dist/harness/gates/gate-override-scope.js.map +1 -0
- package/dist/harness/gates/gate-override-validation.d.ts +25 -0
- package/dist/harness/gates/gate-override-validation.d.ts.map +1 -0
- package/dist/harness/gates/gate-override-validation.js +81 -0
- package/dist/harness/gates/gate-override-validation.js.map +1 -0
- package/dist/harness/gates/gate-rule-catalog.d.ts +24 -0
- package/dist/harness/gates/gate-rule-catalog.d.ts.map +1 -0
- package/dist/harness/gates/gate-rule-catalog.js +112 -0
- package/dist/harness/gates/gate-rule-catalog.js.map +1 -0
- package/dist/harness/gates/gate-terms.d.ts +33 -0
- package/dist/harness/gates/gate-terms.d.ts.map +1 -0
- package/dist/harness/gates/gate-terms.js +41 -0
- package/dist/harness/gates/gate-terms.js.map +1 -0
- package/dist/harness/gates/in-run-decision-check.d.ts +21 -0
- package/dist/harness/gates/in-run-decision-check.d.ts.map +1 -0
- package/dist/harness/gates/in-run-decision-check.js +138 -0
- package/dist/harness/gates/in-run-decision-check.js.map +1 -0
- package/dist/harness/gates/journey-gate-inputs.d.ts +37 -0
- package/dist/harness/gates/journey-gate-inputs.d.ts.map +1 -0
- package/dist/harness/gates/journey-gate-inputs.js +81 -0
- package/dist/harness/gates/journey-gate-inputs.js.map +1 -0
- package/dist/harness/gates/migrated-waiver-review.d.ts +6 -0
- package/dist/harness/gates/migrated-waiver-review.d.ts.map +1 -0
- package/dist/harness/gates/migrated-waiver-review.js +116 -0
- package/dist/harness/gates/migrated-waiver-review.js.map +1 -0
- package/dist/harness/gates/resolve-rule.d.ts +59 -0
- package/dist/harness/gates/resolve-rule.d.ts.map +1 -0
- package/dist/harness/gates/resolve-rule.js +41 -0
- package/dist/harness/gates/resolve-rule.js.map +1 -0
- package/dist/harness/gates/unit-gate-overrides.d.ts +25 -0
- package/dist/harness/gates/unit-gate-overrides.d.ts.map +1 -0
- package/dist/harness/gates/unit-gate-overrides.js +122 -0
- package/dist/harness/gates/unit-gate-overrides.js.map +1 -0
- package/dist/harness/journey.d.ts +43 -1
- package/dist/harness/journey.d.ts.map +1 -1
- package/dist/harness/journey.js +207 -33
- package/dist/harness/journey.js.map +1 -1
- package/dist/harness/manifest.d.ts +12 -0
- package/dist/harness/manifest.d.ts.map +1 -1
- package/dist/harness/manifest.js +73 -45
- package/dist/harness/manifest.js.map +1 -1
- package/dist/harness/next-step.d.ts +37 -6
- package/dist/harness/next-step.d.ts.map +1 -1
- package/dist/harness/next-step.js +34 -174
- package/dist/harness/next-step.js.map +1 -1
- package/dist/harness/parse.d.ts +25 -0
- package/dist/harness/parse.d.ts.map +1 -1
- package/dist/harness/parse.js +38 -13
- package/dist/harness/parse.js.map +1 -1
- package/dist/harness/provenance.d.ts +29 -0
- package/dist/harness/provenance.d.ts.map +1 -1
- package/dist/harness/provenance.js +109 -9
- package/dist/harness/provenance.js.map +1 -1
- package/dist/harness/script-check.d.ts.map +1 -1
- package/dist/harness/script-check.js +29 -6
- package/dist/harness/script-check.js.map +1 -1
- package/dist/harness/sensors.d.ts +14 -3
- package/dist/harness/sensors.d.ts.map +1 -1
- package/dist/harness/sensors.js +64 -44
- package/dist/harness/sensors.js.map +1 -1
- package/dist/harness/triage-signals.d.ts +20 -0
- package/dist/harness/triage-signals.d.ts.map +1 -0
- package/dist/harness/triage-signals.js +30 -0
- package/dist/harness/triage-signals.js.map +1 -0
- package/dist/harness/triage-unit.d.ts +23 -0
- package/dist/harness/triage-unit.d.ts.map +1 -0
- package/dist/harness/triage-unit.js +142 -0
- package/dist/harness/triage-unit.js.map +1 -0
- package/dist/harness/triage.d.ts +28 -0
- package/dist/harness/triage.d.ts.map +1 -0
- package/dist/harness/triage.js +99 -0
- package/dist/harness/triage.js.map +1 -0
- package/dist/harness/viewpoint-ledger.d.ts.map +1 -1
- package/dist/harness/viewpoint-ledger.js +2 -1
- package/dist/harness/viewpoint-ledger.js.map +1 -1
- package/dist/hooks/bash-write-targets.d.ts +15 -0
- package/dist/hooks/bash-write-targets.d.ts.map +1 -0
- package/dist/hooks/bash-write-targets.js +173 -0
- package/dist/hooks/bash-write-targets.js.map +1 -0
- package/dist/hooks/claude-hook-entry.d.ts +11 -0
- package/dist/hooks/claude-hook-entry.d.ts.map +1 -0
- package/dist/hooks/claude-hook-entry.js +137 -0
- package/dist/hooks/claude-hook-entry.js.map +1 -0
- package/dist/hooks/claude-transcript-turn.d.ts +11 -0
- package/dist/hooks/claude-transcript-turn.d.ts.map +1 -0
- package/dist/hooks/claude-transcript-turn.js +143 -0
- package/dist/hooks/claude-transcript-turn.js.map +1 -0
- package/dist/hooks/guard-delivery-contract-rule.d.ts +10 -0
- package/dist/hooks/guard-delivery-contract-rule.d.ts.map +1 -0
- package/dist/hooks/guard-delivery-contract-rule.js +152 -0
- package/dist/hooks/guard-delivery-contract-rule.js.map +1 -0
- package/dist/hooks/guard-protected-paths.d.ts +9 -0
- package/dist/hooks/guard-protected-paths.d.ts.map +1 -0
- package/dist/hooks/guard-protected-paths.js +107 -0
- package/dist/hooks/guard-protected-paths.js.map +1 -0
- package/dist/hooks/guard-rules.d.ts +37 -0
- package/dist/hooks/guard-rules.d.ts.map +1 -0
- package/dist/hooks/guard-rules.js +61 -0
- package/dist/hooks/guard-rules.js.map +1 -0
- package/dist/hooks/guard-tty-spoof-rule.d.ts +15 -0
- package/dist/hooks/guard-tty-spoof-rule.d.ts.map +1 -0
- package/dist/hooks/guard-tty-spoof-rule.js +21 -0
- package/dist/hooks/guard-tty-spoof-rule.js.map +1 -0
- package/dist/hooks/hand-back-core.d.ts +39 -0
- package/dist/hooks/hand-back-core.d.ts.map +1 -0
- package/dist/hooks/hand-back-core.js +122 -0
- package/dist/hooks/hand-back-core.js.map +1 -0
- package/dist/hooks/hook-cli-command.d.ts +9 -0
- package/dist/hooks/hook-cli-command.d.ts.map +1 -0
- package/dist/hooks/hook-cli-command.js +46 -0
- package/dist/hooks/hook-cli-command.js.map +1 -0
- package/dist/hooks/hook-registry.d.ts +10 -0
- package/dist/hooks/hook-registry.d.ts.map +1 -0
- package/dist/hooks/hook-registry.js +24 -0
- package/dist/hooks/hook-registry.js.map +1 -0
- package/dist/hooks/hook-result-contract.d.ts +50 -0
- package/dist/hooks/hook-result-contract.d.ts.map +1 -0
- package/dist/hooks/hook-result-contract.js +80 -0
- package/dist/hooks/hook-result-contract.js.map +1 -0
- package/dist/hooks/hook-toggles.d.ts +10 -0
- package/dist/hooks/hook-toggles.d.ts.map +1 -0
- package/dist/hooks/hook-toggles.js +107 -0
- package/dist/hooks/hook-toggles.js.map +1 -0
- package/dist/hooks/pre-tool-guard-hook.d.ts +10 -0
- package/dist/hooks/pre-tool-guard-hook.d.ts.map +1 -0
- package/dist/hooks/pre-tool-guard-hook.js +105 -0
- package/dist/hooks/pre-tool-guard-hook.js.map +1 -0
- package/dist/hooks/session-start-unit-state-hook.d.ts +13 -0
- package/dist/hooks/session-start-unit-state-hook.d.ts.map +1 -0
- package/dist/hooks/session-start-unit-state-hook.js +57 -0
- package/dist/hooks/session-start-unit-state-hook.js.map +1 -0
- package/dist/hooks/stop-next-step-hook.d.ts +16 -0
- package/dist/hooks/stop-next-step-hook.d.ts.map +1 -0
- package/dist/hooks/stop-next-step-hook.js +42 -0
- package/dist/hooks/stop-next-step-hook.js.map +1 -0
- package/dist/hooks/sungen-project-root.d.ts +19 -0
- package/dist/hooks/sungen-project-root.d.ts.map +1 -0
- package/dist/hooks/sungen-project-root.js +130 -0
- package/dist/hooks/sungen-project-root.js.map +1 -0
- package/dist/orchestrator/ai-skills/command-partial-includes.d.ts +15 -0
- package/dist/orchestrator/ai-skills/command-partial-includes.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/command-partial-includes.js +106 -0
- package/dist/orchestrator/ai-skills/command-partial-includes.js.map +1 -0
- package/dist/orchestrator/ai-skills/commands.d.ts +5 -1
- package/dist/orchestrator/ai-skills/commands.d.ts.map +1 -1
- package/dist/orchestrator/ai-skills/commands.js +16 -6
- package/dist/orchestrator/ai-skills/commands.js.map +1 -1
- package/dist/orchestrator/ai-skills/golden-skills.test.js +29 -0
- package/dist/orchestrator/ai-skills/golden-skills.test.js.map +1 -1
- package/dist/orchestrator/assets-drift.d.ts +5 -0
- package/dist/orchestrator/assets-drift.d.ts.map +1 -1
- package/dist/orchestrator/assets-drift.js +12 -3
- package/dist/orchestrator/assets-drift.js.map +1 -1
- package/dist/orchestrator/claude-hooks-install.d.ts +27 -0
- package/dist/orchestrator/claude-hooks-install.d.ts.map +1 -0
- package/dist/orchestrator/claude-hooks-install.js +203 -0
- package/dist/orchestrator/claude-hooks-install.js.map +1 -0
- package/dist/orchestrator/lockstep-version.d.ts +15 -5
- package/dist/orchestrator/lockstep-version.d.ts.map +1 -1
- package/dist/orchestrator/lockstep-version.js +30 -17
- package/dist/orchestrator/lockstep-version.js.map +1 -1
- package/dist/orchestrator/project-initializer.d.ts +6 -0
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +24 -0
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/screen-manager.d.ts.map +1 -1
- package/dist/orchestrator/screen-manager.js +4 -2
- package/dist/orchestrator/screen-manager.js.map +1 -1
- package/dist/orchestrator/templates/ai-src/commands/add-api.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/add-flow.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/add-screen.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/create-data-test.md +1 -0
- package/dist/orchestrator/templates/ai-src/commands/create-test.md +14 -16
- package/dist/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/delivery.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/design.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/feedback.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/locale.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/review.md +2 -0
- package/dist/orchestrator/templates/ai-src/commands/run-test.md +14 -10
- package/dist/orchestrator/templates/ai-src/config/claude.md +20 -7
- package/dist/orchestrator/templates/ai-src/config/copilot.md +20 -7
- package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.claude.md +20 -0
- package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.codex.md +20 -0
- package/dist/orchestrator/templates/ai-src/partials/hand-back-rule.copilot.md +20 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-api-coverage-model/SKILL.md +1 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md +3 -3
- package/dist/orchestrator/templates/ai-src/skills/sungen-data-factory/SKILL.md +9 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +2 -0
- package/dist/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +1 -1
- package/dist/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md +2 -0
- package/dist/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
- package/dist/utils/safe-yaml-parse.d.ts +8 -0
- package/dist/utils/safe-yaml-parse.d.ts.map +1 -0
- package/dist/utils/safe-yaml-parse.js +51 -0
- package/dist/utils/safe-yaml-parse.js.map +1 -0
- package/package.json +3 -3
- package/src/basis/anchor-grammar.ts +83 -0
- package/src/basis/anchor-hash.ts +27 -0
- package/src/basis/bm51-tables.ts +65 -0
- package/src/basis/extract-spec-anchors.ts +95 -0
- package/src/basis/migration-sentinel.ts +175 -0
- package/src/basis/spec-frontmatter.ts +68 -0
- package/src/basis/spec-sections.ts +35 -0
- package/src/basis/test-basis-schema.ts +81 -0
- package/src/capabilities/discover.ts +15 -2
- package/src/capabilities/registry.ts +16 -0
- package/src/cli/commands/audit.ts +10 -5
- package/src/cli/commands/capability.ts +4 -2
- package/src/cli/commands/contract-derive-command.ts +61 -0
- package/src/cli/commands/contract.ts +130 -0
- package/src/cli/commands/defect.ts +49 -0
- package/src/cli/commands/delivery.ts +92 -15
- package/src/cli/commands/generate.ts +3 -1
- package/src/cli/commands/journey.ts +41 -16
- package/src/cli/commands/next.ts +64 -10
- package/src/cli/commands/triage.ts +57 -0
- package/src/cli/commands/update.ts +35 -8
- package/src/cli/index.ts +24 -30
- package/src/cli/project-sungen-invocation.ts +39 -0
- package/src/contract/approve-contract.ts +94 -0
- package/src/contract/assertion-matcher-vocabulary.ts +93 -0
- package/src/contract/build-contract-verdict.ts +108 -0
- package/src/contract/build-trace-conformance.ts +100 -0
- package/src/contract/classify-contract-change.ts +92 -0
- package/src/contract/classify-contract-unit.ts +47 -0
- package/src/contract/classify-trace-conformance.ts +116 -0
- package/src/contract/contract-git.ts +106 -0
- package/src/contract/contract-hash.ts +34 -0
- package/src/contract/contract-report-file.ts +25 -0
- package/src/contract/contract-schema.ts +137 -0
- package/src/contract/contract-units.ts +52 -0
- package/src/contract/contracts-lock-file.ts +97 -0
- package/src/contract/data-normalize.ts +66 -0
- package/src/contract/derive-free-feature.ts +120 -0
- package/src/contract/field-semantic-redaction.ts +80 -0
- package/src/contract/free-feature-blocks.ts +56 -0
- package/src/contract/lock-secret-guard.ts +95 -0
- package/src/contract/lock-vs-git-head.ts +38 -0
- package/src/contract/normalize-contract-step.ts +74 -0
- package/src/contract/normalize-feature-steps.ts +93 -0
- package/src/contract/oracle-strength.ts +80 -0
- package/src/contract/project-contract-blockers.ts +36 -0
- package/src/contract/record-contract-approval.ts +70 -0
- package/src/contract/render-free-gherkin.ts +113 -0
- package/src/contract/render-trace-sentence.ts +98 -0
- package/src/contract/render-trace-target.ts +68 -0
- package/src/contract/resolve-unit-trace-identities.ts +35 -0
- package/src/contract/trace/collect-trace-evidence.ts +109 -0
- package/src/contract/trace/identity-cache.ts +61 -0
- package/src/contract/trace/select-final-attempt.ts +70 -0
- package/src/contract/trace/snapshot-html-renderer.ts +136 -0
- package/src/contract/trace/snapshot-resolver.ts +66 -0
- package/src/contract/trace/snapshot-store.ts +151 -0
- package/src/contract/trace/target-identity.ts +104 -0
- package/src/contract/trace/test-step-join.ts +104 -0
- package/src/contract/trace/trace-binding.ts +56 -0
- package/src/contract/trace/trace-file-reader.ts +133 -0
- package/src/contract/trace/trace-fingerprint.ts +68 -0
- package/src/contract/trace/trace-identity-resolution.ts +74 -0
- package/src/contract/trace/trace-run-record.ts +80 -0
- package/src/contract/trace/trace-steps.ts +88 -0
- package/src/contract/trace/trace-zip-limits.ts +77 -0
- package/src/contract/trace/trace-zip-reader.ts +127 -0
- package/src/contract/verify-approval-decisions.ts +60 -0
- package/src/decisions/append-decision.ts +35 -0
- package/src/decisions/confirmed-decision-commands.ts +149 -0
- package/src/decisions/decision-file.ts +93 -0
- package/src/decisions/decision-identity.ts +73 -0
- package/src/decisions/decision-integrity-check.ts +61 -0
- package/src/decisions/decision-schema.ts +76 -0
- package/src/decisions/decision-source.ts +14 -0
- package/src/decisions/exclusive-file-create.ts +42 -0
- package/src/decisions/git-head-trust.ts +32 -0
- package/src/decisions/human-confirmation.ts +119 -0
- package/src/decisions/legacy-waiver-migration.ts +135 -0
- package/src/decisions/read-decisions.ts +61 -0
- package/src/decisions/viewpoint-baseline-adapter.ts +74 -0
- package/src/decisions/waiver-decisions.ts +56 -0
- package/src/exporters/csv-exporter.ts +5 -1
- package/src/exporters/feature-parser.ts +12 -0
- package/src/exporters/matrix/build.ts +62 -18
- package/src/exporters/matrix/carry-manual-results.ts +70 -7
- package/src/exporters/matrix/export.ts +17 -2
- package/src/exporters/matrix/gates.ts +62 -129
- package/src/exporters/matrix/render-csv.ts +4 -1
- package/src/exporters/matrix/render-gate-overrides-sheet.ts +50 -0
- package/src/exporters/matrix/render-xlsx.ts +6 -0
- package/src/exporters/matrix/types.ts +9 -1
- package/src/exporters/matrix/xlsx-cells.ts +1 -1
- package/src/exporters/playwright-report-parser.ts +1 -0
- package/src/exporters/scenario-merger.ts +2 -1
- package/src/exporters/types.ts +5 -0
- package/src/generators/test-generator/code-generator.ts +13 -0
- package/src/graph/evaluate-graph.ts +66 -0
- package/src/graph/locate-finding.ts +93 -0
- package/src/graph/node-decl.ts +72 -0
- package/src/graph/nodes/core-node-catalog.ts +15 -0
- package/src/graph/nodes/test-case-contract-nodes.ts +74 -0
- package/src/graph/nodes/test-case-nodes.ts +68 -0
- package/src/graph/nodes/unit-audit-nodes.ts +95 -0
- package/src/graph/nodes/unit-contract-node.ts +89 -0
- package/src/graph/nodes/unit-design-nodes.ts +89 -0
- package/src/graph/nodes/unit-execution-nodes.ts +77 -0
- package/src/graph/test-case-identity.ts +75 -0
- package/src/graph/test-case-results.ts +90 -0
- package/src/graph/test-case-satisfied.ts +55 -0
- package/src/graph/test-case-state-shape.ts +62 -0
- package/src/graph/test-case-states.ts +84 -0
- package/src/graph/unit-artifact-probes.ts +77 -0
- package/src/graph/unit-state-facts.ts +112 -0
- package/src/harness/audit.ts +46 -11
- package/src/harness/catalog/gate-rules.yaml +647 -0
- package/src/harness/counted-assertions.ts +33 -0
- package/src/harness/defect-draft.ts +115 -0
- package/src/harness/defects.ts +94 -0
- package/src/harness/gates/audit-gate-terms.ts +80 -0
- package/src/harness/gates/audit-gate-verdict.ts +78 -0
- package/src/harness/gates/audit-input-hash.ts +55 -0
- package/src/harness/gates/audit-report-verification.ts +201 -0
- package/src/harness/gates/decisions-hash.ts +42 -0
- package/src/harness/gates/delivery-checklist.ts +120 -0
- package/src/harness/gates/delivery-decision-gate.ts +139 -0
- package/src/harness/gates/delivery-decision-step.ts +89 -0
- package/src/harness/gates/gate-override-report.ts +114 -0
- package/src/harness/gates/gate-override-scope.ts +66 -0
- package/src/harness/gates/gate-override-validation.ts +75 -0
- package/src/harness/gates/gate-rule-catalog.ts +82 -0
- package/src/harness/gates/gate-terms.ts +59 -0
- package/src/harness/gates/in-run-decision-check.ts +99 -0
- package/src/harness/gates/journey-gate-inputs.ts +89 -0
- package/src/harness/gates/migrated-waiver-review.ts +68 -0
- package/src/harness/gates/resolve-rule.ts +94 -0
- package/src/harness/gates/unit-gate-overrides.ts +99 -0
- package/src/harness/journey.ts +215 -38
- package/src/harness/manifest.ts +69 -45
- package/src/harness/next-step.ts +60 -170
- package/src/harness/parse.ts +40 -13
- package/src/harness/provenance.ts +99 -11
- package/src/harness/script-check.ts +27 -6
- package/src/harness/sensors.ts +73 -47
- package/src/harness/triage-signals.ts +46 -0
- package/src/harness/triage-unit.ts +113 -0
- package/src/harness/triage.ts +127 -0
- package/src/harness/viewpoint-ledger.ts +2 -2
- package/src/hooks/bash-write-targets.ts +109 -0
- package/src/hooks/claude-hook-entry.ts +85 -0
- package/src/hooks/claude-transcript-turn.ts +96 -0
- package/src/hooks/guard-delivery-contract-rule.ts +110 -0
- package/src/hooks/guard-protected-paths.ts +71 -0
- package/src/hooks/guard-rules.ts +98 -0
- package/src/hooks/guard-tty-spoof-rule.ts +31 -0
- package/src/hooks/hand-back-core.ts +112 -0
- package/src/hooks/hook-cli-command.ts +17 -0
- package/src/hooks/hook-registry.ts +24 -0
- package/src/hooks/hook-result-contract.ts +114 -0
- package/src/hooks/hook-toggles.ts +66 -0
- package/src/hooks/pre-tool-guard-hook.ts +67 -0
- package/src/hooks/session-start-unit-state-hook.ts +56 -0
- package/src/hooks/stop-next-step-hook.ts +37 -0
- package/src/hooks/sungen-project-root.ts +80 -0
- package/src/orchestrator/ai-skills/command-partial-includes.ts +72 -0
- package/src/orchestrator/ai-skills/commands.ts +22 -8
- package/src/orchestrator/ai-skills/golden-skills.test.ts +23 -0
- package/src/orchestrator/assets-drift.ts +12 -5
- package/src/orchestrator/claude-hooks-install.ts +168 -0
- package/src/orchestrator/lockstep-version.ts +28 -15
- package/src/orchestrator/project-initializer.ts +22 -0
- package/src/orchestrator/screen-manager.ts +3 -1
- package/src/orchestrator/templates/ai-src/commands/add-api.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/add-flow.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/add-screen.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/create-data-test.md +1 -0
- package/src/orchestrator/templates/ai-src/commands/create-test.md +14 -16
- package/src/orchestrator/templates/ai-src/commands/dashboard.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/delivery.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/design.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/feedback.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/locale.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/review.md +2 -0
- package/src/orchestrator/templates/ai-src/commands/run-test.md +14 -10
- package/src/orchestrator/templates/ai-src/config/claude.md +20 -7
- package/src/orchestrator/templates/ai-src/config/copilot.md +20 -7
- package/src/orchestrator/templates/ai-src/partials/hand-back-rule.claude.md +20 -0
- package/src/orchestrator/templates/ai-src/partials/hand-back-rule.codex.md +20 -0
- package/src/orchestrator/templates/ai-src/partials/hand-back-rule.copilot.md +20 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-api-coverage-model/SKILL.md +1 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md +3 -3
- package/src/orchestrator/templates/ai-src/skills/sungen-data-factory/SKILL.md +9 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md +2 -0
- package/src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md +1 -1
- package/src/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md +2 -0
- package/src/orchestrator/templates/claude-hooks/sungen-hook.cjs +64 -0
- package/src/utils/safe-yaml-parse.ts +44 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read the BM-51 screen-spec tables that carry item ids (company standard, DOS-12.0).
|
|
3
|
+
*
|
|
4
|
+
* `reports/mng/specs/_templates/BM-2-901-51-screen-specification-template.md`:
|
|
5
|
+
* §4.1 Item `| ID | Item Name | Item Type | Required | Note |` — bold section row `A`, then `1.0`, `2.0` …
|
|
6
|
+
* §4.2 Validation `| ID | Type | Min | Max | Default | … |` — rows keyed by the composed id `A-2`
|
|
7
|
+
* §4.3 Data Mapping `| ID | Data Source | API ID | … |` — same key
|
|
8
|
+
* §5 Event `| ID | Given (Pre-condition) | … |` — same key, or `-`
|
|
9
|
+
*
|
|
10
|
+
* Tables are recognised by their header (first column `ID` plus the second column's name), not by
|
|
11
|
+
* heading numbers, so a translated heading still reads. Rows keep their 1-based source line.
|
|
12
|
+
*/
|
|
13
|
+
import { composeItemId } from './anchor-grammar';
|
|
14
|
+
|
|
15
|
+
export type Bm51TableKind = 'item' | 'validation' | 'mapping' | 'event';
|
|
16
|
+
|
|
17
|
+
export interface Bm51Row { table: Bm51TableKind; cells: string[]; id: string; line: number }
|
|
18
|
+
export interface Bm51ItemRow extends Bm51Row { section: string | null; itemId: string | null }
|
|
19
|
+
export interface Bm51Tables { items: Bm51ItemRow[]; validations: Bm51Row[]; mappings: Bm51Row[]; events: Bm51Row[] }
|
|
20
|
+
|
|
21
|
+
const SEPARATOR = /^\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)*\|?\s*$/;
|
|
22
|
+
const COMPOSED_ID = /^[A-Z]+-\d+(?:\.\d+)?$/;
|
|
23
|
+
|
|
24
|
+
function splitRow(line: string): string[] {
|
|
25
|
+
const body = line.trim().replace(/^\|/, '').replace(/\|$/, '');
|
|
26
|
+
return body.split(/(?<!\\)\|/).map((c) => c.replace(/\\\|/g, '|').trim());
|
|
27
|
+
}
|
|
28
|
+
const bare = (cell: string): string => cell.replace(/\*\*|__|`/g, '').trim();
|
|
29
|
+
|
|
30
|
+
function kindOf(header: string[]): Bm51TableKind | null {
|
|
31
|
+
if (bare(header[0] ?? '').toUpperCase() !== 'ID') return null;
|
|
32
|
+
const second = bare(header[1] ?? '').toLowerCase();
|
|
33
|
+
if (second === 'item name') return 'item';
|
|
34
|
+
if (second === 'type') return 'validation';
|
|
35
|
+
if (second === 'data source') return 'mapping';
|
|
36
|
+
if (second.startsWith('given')) return 'event';
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** `lines` are the spec's lines; `firstLine` is the 1-based number of `lines[0]`. */
|
|
41
|
+
export function readBm51Tables(lines: string[], firstLine = 1): Bm51Tables {
|
|
42
|
+
const out: Bm51Tables = { items: [], validations: [], mappings: [], events: [] };
|
|
43
|
+
for (let i = 0; i < lines.length - 1; i++) {
|
|
44
|
+
if (!lines[i].trim().startsWith('|') || !SEPARATOR.test(lines[i + 1].trim())) continue;
|
|
45
|
+
const kind = kindOf(splitRow(lines[i]));
|
|
46
|
+
let j = i + 2;
|
|
47
|
+
let section: string | null = null;
|
|
48
|
+
for (; j < lines.length && lines[j].trim().startsWith('|'); j++) {
|
|
49
|
+
if (!kind) continue;
|
|
50
|
+
const cells = splitRow(lines[j]);
|
|
51
|
+
const id = bare(cells[0] ?? '');
|
|
52
|
+
const line = firstLine + j;
|
|
53
|
+
if (kind === 'item') {
|
|
54
|
+
if (/^[A-Z]+$/.test(id)) { section = id; continue; }
|
|
55
|
+
if (!/^\d+(?:\.\d+)?$/.test(id)) continue;
|
|
56
|
+
out.items.push({ table: kind, cells, id, line, section, itemId: composeItemId(section, id) });
|
|
57
|
+
} else if (COMPOSED_ID.test(id)) {
|
|
58
|
+
const row: Bm51Row = { table: kind, cells, id, line };
|
|
59
|
+
(kind === 'validation' ? out.validations : kind === 'mapping' ? out.mappings : out.events).push(row);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
i = j - 1;
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every anchor a `spec.md` offers, with its hash, confidence label and citation (DOS-12.1 – 12.3).
|
|
3
|
+
*
|
|
4
|
+
* section `sec-<slug>` sha1-12 of the section body (the manifest's hash) INFERRED
|
|
5
|
+
* item `<docId>#<itemId>` sha256-12 of the normalized §4.1 row EXTRACTED
|
|
6
|
+
* val `<docId>#<itemId>/val` sha256-12 of the normalized §4.2 row EXTRACTED
|
|
7
|
+
* a duplicate id, or a §4.2 row naming no §4.1 item AMBIGUOUS
|
|
8
|
+
*
|
|
9
|
+
* A §4.3 / §5 row naming no §4.1 item is reported in `orphans` (AMBIGUOUS, not an error). Item
|
|
10
|
+
* anchors need a docId (frontmatter `id`); without one only section anchors exist. Pointers and
|
|
11
|
+
* hashes only — no spec text leaves this function (red-team #14).
|
|
12
|
+
*/
|
|
13
|
+
import { AnchorConfidence, AnchorKind, CitationBase, formatCitation, itemAnchorId, sectionAnchorId } from './anchor-grammar';
|
|
14
|
+
import { HashAlgo, itemRowHash, sectionHash } from './anchor-hash';
|
|
15
|
+
import { readBm51Tables } from './bm51-tables';
|
|
16
|
+
import { normalizeSectionName, readSpecSectionBlocks } from './spec-sections';
|
|
17
|
+
import { readSpecFrontmatter, SpecFrontmatter } from './spec-frontmatter';
|
|
18
|
+
|
|
19
|
+
export interface SourceAnchor {
|
|
20
|
+
id: string;
|
|
21
|
+
kind: AnchorKind;
|
|
22
|
+
confidence: AnchorConfidence;
|
|
23
|
+
hash: string;
|
|
24
|
+
hashAlgo: HashAlgo;
|
|
25
|
+
location: string;
|
|
26
|
+
/** Why the label is AMBIGUOUS. */
|
|
27
|
+
note?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface OrphanReference { table: 'mapping' | 'event'; itemId: string; location: string; confidence: 'AMBIGUOUS' }
|
|
31
|
+
|
|
32
|
+
export interface SpecAnchors {
|
|
33
|
+
frontmatter: SpecFrontmatter;
|
|
34
|
+
anchors: SourceAnchor[];
|
|
35
|
+
orphans: OrphanReference[];
|
|
36
|
+
problems: string[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Mark every anchor whose id occurs more than once as AMBIGUOUS — a human must pick. */
|
|
40
|
+
function flagDuplicates(anchors: SourceAnchor[]): void {
|
|
41
|
+
const count = new Map<string, number>();
|
|
42
|
+
for (const a of anchors) count.set(a.id, (count.get(a.id) ?? 0) + 1);
|
|
43
|
+
for (const a of anchors) {
|
|
44
|
+
if ((count.get(a.id) ?? 0) > 1) { a.confidence = 'AMBIGUOUS'; a.note = 'duplicate id'; }
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function extractSpecAnchors(text: string, citation: CitationBase): SpecAnchors {
|
|
49
|
+
const lines = text.replace(/^/, '').replace(/\r\n?/g, '\n').split('\n');
|
|
50
|
+
const fm = readSpecFrontmatter(text, citation.path);
|
|
51
|
+
const problems = [...fm.problems];
|
|
52
|
+
const cite = (start: number, end: number): string => formatCitation(citation, start, end);
|
|
53
|
+
|
|
54
|
+
const sections: SourceAnchor[] = readSpecSectionBlocks(lines).map((s) => ({
|
|
55
|
+
id: sectionAnchorId(normalizeSectionName(s.name)),
|
|
56
|
+
kind: 'section',
|
|
57
|
+
confidence: 'INFERRED',
|
|
58
|
+
hash: sectionHash(s.body),
|
|
59
|
+
hashAlgo: 'sha1-12',
|
|
60
|
+
location: cite(s.headingIndex + 1, s.headingIndex + 1 + s.body.length),
|
|
61
|
+
}));
|
|
62
|
+
flagDuplicates(sections);
|
|
63
|
+
|
|
64
|
+
const docId = fm.frontmatter.id;
|
|
65
|
+
const tables = readBm51Tables(lines);
|
|
66
|
+
const items: SourceAnchor[] = [];
|
|
67
|
+
const orphans: OrphanReference[] = [];
|
|
68
|
+
if (!docId) {
|
|
69
|
+
if (tables.items.length) problems.push(`${citation.path}: a BM-51 item table is present but the frontmatter has no id; no item anchors`);
|
|
70
|
+
return { frontmatter: fm.frontmatter, anchors: sections, orphans, problems };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
for (const row of tables.items) {
|
|
74
|
+
if (!row.itemId) { problems.push(`${citation.path}:${row.line}: item ${row.id} has no section row above it; skipped`); continue; }
|
|
75
|
+
items.push({ id: itemAnchorId(docId, row.itemId), kind: 'item', confidence: 'EXTRACTED', hash: itemRowHash(row.cells), hashAlgo: 'sha256-12', location: cite(row.line, row.line) });
|
|
76
|
+
}
|
|
77
|
+
flagDuplicates(items);
|
|
78
|
+
const known = new Set(tables.items.map((r) => r.itemId).filter(Boolean));
|
|
79
|
+
|
|
80
|
+
const vals: SourceAnchor[] = tables.validations.map((row) => ({
|
|
81
|
+
id: itemAnchorId(docId, row.id, true),
|
|
82
|
+
kind: 'validation',
|
|
83
|
+
confidence: known.has(row.id) ? 'EXTRACTED' : 'AMBIGUOUS',
|
|
84
|
+
hash: itemRowHash(row.cells),
|
|
85
|
+
hashAlgo: 'sha256-12',
|
|
86
|
+
location: cite(row.line, row.line),
|
|
87
|
+
...(known.has(row.id) ? {} : { note: 'no §4.1 item with this id' }),
|
|
88
|
+
}));
|
|
89
|
+
flagDuplicates(vals);
|
|
90
|
+
|
|
91
|
+
for (const row of [...tables.mappings, ...tables.events]) {
|
|
92
|
+
if (!known.has(row.id)) orphans.push({ table: row.table as 'mapping' | 'event', itemId: row.id, location: cite(row.line, row.line), confidence: 'AMBIGUOUS' });
|
|
93
|
+
}
|
|
94
|
+
return { frontmatter: fm.frontmatter, anchors: [...items, ...vals, ...sections], orphans, problems };
|
|
95
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Write-ahead sentinel for migrations and re-baselines (takumi T6, DOS-13.6).
|
|
3
|
+
*
|
|
4
|
+
* Before a migration writes anything it records `.sungen/migrations/<slug>.pending.json`: every
|
|
5
|
+
* file it will touch plus a copy of each one's current bytes (or "did not exist"). The sentinel is
|
|
6
|
+
* deleted when the migration completes. An error inside the migration rolls the copies back at
|
|
7
|
+
* once; only a process that DIES mid-migration leaves the sentinel behind — and then the next run
|
|
8
|
+
* stops and asks a human for REVERT (restore every copy byte for byte) or KEEP (keep the new
|
|
9
|
+
* files). It never continues silently. (Reference: reports/takumi/docs/system-architecture.md:656-677.)
|
|
10
|
+
*
|
|
11
|
+
* A sentinel carries pid, host and startedAt. While its writer is alive on this host and it is under a
|
|
12
|
+
* minute old, another run is simply migrating: the answer is "retry", not a REVERT/KEEP prompt. Only a
|
|
13
|
+
* dead writer or an old sentinel is an interrupted migration. One slug per unit covers both writers:
|
|
14
|
+
* the waiver import (DOS-13.5) and the manifest upgrade to schema 2 on save (DOS-12.3).
|
|
15
|
+
*/
|
|
16
|
+
import * as fs from 'fs';
|
|
17
|
+
import * as os from 'os';
|
|
18
|
+
import * as path from 'path';
|
|
19
|
+
import { createFileExclusive } from '../decisions/exclusive-file-create';
|
|
20
|
+
|
|
21
|
+
export interface SentinelFile { path: string; existed: boolean; contentBase64?: string }
|
|
22
|
+
export interface PendingMigration {
|
|
23
|
+
schema: 1; unit: string; slug: string; reason: string; startedAt: string; pid?: number; host?: string; files: SentinelFile[];
|
|
24
|
+
}
|
|
25
|
+
export type MigrationChoice = 'REVERT' | 'KEEP';
|
|
26
|
+
export const IN_PROGRESS_WINDOW_MS = 60_000;
|
|
27
|
+
|
|
28
|
+
export function sentinelPath(projectRoot: string, slug: string): string {
|
|
29
|
+
return path.join(projectRoot, '.sungen', 'migrations', `${slug}.pending.json`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class PendingMigrationError extends Error {
|
|
33
|
+
constructor(public readonly unit: string, public readonly slug: string, public readonly file: string, detail: string) {
|
|
34
|
+
super(
|
|
35
|
+
`An interrupted migration left ${file} (${detail}).\n`
|
|
36
|
+
+ ' Nothing continues until a human chooses: REVERT restores every file it lists byte for byte;\n'
|
|
37
|
+
+ ` KEEP keeps the new files. Run in a terminal and answer the prompt: sungen journey --screen ${unit}`,
|
|
38
|
+
);
|
|
39
|
+
this.name = 'PendingMigrationError';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** The sentinel, or null when there is none. An unreadable sentinel still exists: `files` is then empty. */
|
|
44
|
+
export function readPendingMigration(projectRoot: string, slug: string): (PendingMigration & { readable: boolean }) | null {
|
|
45
|
+
const p = sentinelPath(projectRoot, slug);
|
|
46
|
+
if (!fs.existsSync(p)) return null;
|
|
47
|
+
try {
|
|
48
|
+
const raw = JSON.parse(fs.readFileSync(p, 'utf8')) as PendingMigration;
|
|
49
|
+
if (raw && raw.schema === 1 && Array.isArray(raw.files)) return { ...raw, readable: true };
|
|
50
|
+
} catch { /* fall through: a sentinel that cannot be read is still a stop sign */ }
|
|
51
|
+
return { schema: 1, unit: slug, slug, reason: 'unreadable sentinel', startedAt: '?', files: [], readable: false };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export class MigrationInProgressError extends Error {
|
|
55
|
+
constructor(public readonly unit: string, detail: string) {
|
|
56
|
+
super(`Another sungen run is migrating ${unit} right now (${detail}). Retry in a moment — nothing was changed.`);
|
|
57
|
+
this.name = 'MigrationInProgressError';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function pidAlive(pid: unknown): boolean {
|
|
62
|
+
if (typeof pid !== 'number' || !Number.isInteger(pid) || pid <= 0) return false;
|
|
63
|
+
try { process.kill(pid, 0); return true; } catch (e) { return (e as NodeJS.ErrnoException).code === 'EPERM'; }
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** in-progress: under a minute old and written by a process alive on this host (another host cannot be checked). */
|
|
67
|
+
export function pendingMigrationState(p: PendingMigration & { readable: boolean }): 'in-progress' | 'interrupted' {
|
|
68
|
+
if (!p.readable) return 'interrupted';
|
|
69
|
+
const age = Date.now() - Date.parse(p.startedAt);
|
|
70
|
+
if (!(age >= 0 && age < IN_PROGRESS_WINDOW_MS)) return 'interrupted';
|
|
71
|
+
if (p.host !== os.hostname()) return 'in-progress';
|
|
72
|
+
return pidAlive(p.pid) ? 'in-progress' : 'interrupted';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function pendingError(projectRoot: string, slug: string, pending: PendingMigration & { readable: boolean }): Error {
|
|
76
|
+
if (pendingMigrationState(pending) === 'in-progress') {
|
|
77
|
+
const age = Math.round((Date.now() - Date.parse(pending.startedAt)) / 1000);
|
|
78
|
+
return new MigrationInProgressError(pending.unit, `pid ${pending.pid} on ${pending.host}, started ${age}s ago: ${pending.reason}`);
|
|
79
|
+
}
|
|
80
|
+
const rel = path.relative(projectRoot, sentinelPath(projectRoot, slug));
|
|
81
|
+
return new PendingMigrationError(pending.unit, slug, rel, `started ${pending.startedAt}: ${pending.reason}`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Throws MigrationInProgressError (retry) or PendingMigrationError (REVERT/KEEP) when a sentinel exists. */
|
|
85
|
+
export function assertNoPendingMigration(projectRoot: string, slug: string): void {
|
|
86
|
+
const pending = readPendingMigration(projectRoot, slug);
|
|
87
|
+
if (pending) throw pendingError(projectRoot, slug, pending);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** A sentinel path must stay inside the project — it is data read back from disk. */
|
|
91
|
+
function inside(projectRoot: string, rel: string): string {
|
|
92
|
+
const abs = path.resolve(projectRoot, rel);
|
|
93
|
+
const back = path.relative(path.resolve(projectRoot), abs);
|
|
94
|
+
if (path.isAbsolute(rel) || back === '' || back.startsWith('..') || path.isAbsolute(back)) {
|
|
95
|
+
throw new Error(`refusing to restore "${rel}": outside the project`);
|
|
96
|
+
}
|
|
97
|
+
return abs;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Bytes, not text: REVERT must restore a file exactly, whatever its encoding. Tmp + rename = atomic. */
|
|
101
|
+
function writeBytesAtomic(abs: string, bytes: Buffer): void {
|
|
102
|
+
const tmp = `${abs}.tmp-${process.pid}`;
|
|
103
|
+
try {
|
|
104
|
+
fs.writeFileSync(tmp, bytes);
|
|
105
|
+
fs.renameSync(tmp, abs);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
fs.rmSync(tmp, { force: true });
|
|
108
|
+
throw err;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function restore(projectRoot: string, files: SentinelFile[]): string[] {
|
|
113
|
+
const done: string[] = [];
|
|
114
|
+
for (const f of files) {
|
|
115
|
+
const abs = inside(projectRoot, f.path);
|
|
116
|
+
if (f.existed) {
|
|
117
|
+
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
|
118
|
+
writeBytesAtomic(abs, Buffer.from(f.contentBase64 ?? '', 'base64'));
|
|
119
|
+
} else {
|
|
120
|
+
fs.rmSync(abs, { force: true });
|
|
121
|
+
}
|
|
122
|
+
done.push(f.path);
|
|
123
|
+
}
|
|
124
|
+
return done;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Run `write` under a sentinel covering `files` (absolute paths). The sentinel is written atomically
|
|
129
|
+
* before `write` starts and removed after it returns. If `write` throws, the copies are restored and
|
|
130
|
+
* the sentinel removed before the error is rethrown; a failed rollback leaves the sentinel in place.
|
|
131
|
+
*/
|
|
132
|
+
export function withMigrationSentinel<T>(
|
|
133
|
+
projectRoot: string, unit: string, slug: string, reason: string, files: string[], write: () => T,
|
|
134
|
+
): T {
|
|
135
|
+
assertNoPendingMigration(projectRoot, slug);
|
|
136
|
+
const snapshot: SentinelFile[] = files.map((abs) => {
|
|
137
|
+
const rel = path.relative(projectRoot, abs).split(path.sep).join('/');
|
|
138
|
+
inside(projectRoot, rel);
|
|
139
|
+
return fs.existsSync(abs)
|
|
140
|
+
? { path: rel, existed: true, contentBase64: fs.readFileSync(abs).toString('base64') }
|
|
141
|
+
: { path: rel, existed: false };
|
|
142
|
+
});
|
|
143
|
+
const p = sentinelPath(projectRoot, slug);
|
|
144
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
145
|
+
const pending: PendingMigration = {
|
|
146
|
+
schema: 1, unit, slug, reason, startedAt: new Date().toISOString(), pid: process.pid, host: os.hostname(), files: snapshot,
|
|
147
|
+
};
|
|
148
|
+
// Exclusive: a second migration of the same unit racing this one cannot also believe it holds it.
|
|
149
|
+
if (!createFileExclusive(p, `${JSON.stringify(pending, null, 2)}\n`)) {
|
|
150
|
+
const holder = readPendingMigration(projectRoot, slug);
|
|
151
|
+
throw holder ? pendingError(projectRoot, slug, holder) : new MigrationInProgressError(unit, 'it just finished');
|
|
152
|
+
}
|
|
153
|
+
let result: T;
|
|
154
|
+
try {
|
|
155
|
+
result = write();
|
|
156
|
+
} catch (err) {
|
|
157
|
+
restore(projectRoot, snapshot); // throws → the sentinel stays: the next run asks REVERT/KEEP
|
|
158
|
+
fs.rmSync(p, { force: true });
|
|
159
|
+
throw err;
|
|
160
|
+
}
|
|
161
|
+
fs.rmSync(p, { force: true });
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Answer a leftover sentinel. REVERT restores every listed file exactly; KEEP only removes the sentinel. */
|
|
166
|
+
export function resolvePendingMigration(projectRoot: string, slug: string, choice: MigrationChoice): string[] {
|
|
167
|
+
const pending = readPendingMigration(projectRoot, slug);
|
|
168
|
+
if (!pending) return [];
|
|
169
|
+
if (choice === 'REVERT' && !pending.readable) {
|
|
170
|
+
throw new Error(`${sentinelPath(projectRoot, slug)} cannot be read, so there is nothing to restore from — choose KEEP.`);
|
|
171
|
+
}
|
|
172
|
+
const restored = choice === 'REVERT' ? restore(projectRoot, pending.files) : [];
|
|
173
|
+
fs.rmSync(sentinelPath(projectRoot, slug), { force: true });
|
|
174
|
+
return restored;
|
|
175
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional `spec.md` frontmatter (DOS-12.2).
|
|
3
|
+
*
|
|
4
|
+
* `source_mode: linked|authored` (default `authored`), `id` and `version` (both in the BM-51
|
|
5
|
+
* template), and `status`, `superseded_by` when present. `screen_id` is kept as metadata only — it
|
|
6
|
+
* never enters an anchor. No frontmatter = the old behavior, so this never throws: a malformed
|
|
7
|
+
* block is reported as a problem and read as absent.
|
|
8
|
+
*/
|
|
9
|
+
import { safeYamlParse } from '../utils/safe-yaml-parse';
|
|
10
|
+
import { isDocId } from './anchor-grammar';
|
|
11
|
+
|
|
12
|
+
export type SourceMode = 'linked' | 'authored';
|
|
13
|
+
|
|
14
|
+
export interface SpecFrontmatter {
|
|
15
|
+
source_mode: SourceMode;
|
|
16
|
+
id?: string;
|
|
17
|
+
version?: string;
|
|
18
|
+
status?: string;
|
|
19
|
+
superseded_by?: string;
|
|
20
|
+
screen_id?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface FrontmatterRead {
|
|
24
|
+
present: boolean;
|
|
25
|
+
frontmatter: SpecFrontmatter;
|
|
26
|
+
/** 0-based index of the first line after the closing fence (0 when there is no frontmatter). */
|
|
27
|
+
bodyStartIndex: number;
|
|
28
|
+
problems: string[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const scalar = (v: unknown): string | undefined =>
|
|
32
|
+
typeof v === 'string' ? v.trim() || undefined : typeof v === 'number' ? String(v) : undefined;
|
|
33
|
+
|
|
34
|
+
export function readSpecFrontmatter(text: string, source = 'spec.md'): FrontmatterRead {
|
|
35
|
+
const absent: FrontmatterRead = { present: false, frontmatter: { source_mode: 'authored' }, bodyStartIndex: 0, problems: [] };
|
|
36
|
+
const lines = text.replace(/^/, '').replace(/\r\n?/g, '\n').split('\n');
|
|
37
|
+
if (lines[0]?.trim() !== '---') return absent;
|
|
38
|
+
const close = lines.findIndex((l, i) => i > 0 && (l.trim() === '---' || l.trim() === '...'));
|
|
39
|
+
if (close < 0) return { ...absent, problems: [`${source}: frontmatter opened with --- but never closed; read as absent`] };
|
|
40
|
+
|
|
41
|
+
const problems: string[] = [];
|
|
42
|
+
let raw: unknown;
|
|
43
|
+
try {
|
|
44
|
+
raw = safeYamlParse(lines.slice(1, close).join('\n'), `${source} frontmatter`);
|
|
45
|
+
} catch (err) {
|
|
46
|
+
return { ...absent, bodyStartIndex: close + 1, problems: [err instanceof Error ? err.message : String(err)] };
|
|
47
|
+
}
|
|
48
|
+
if (raw === null || raw === undefined) raw = {};
|
|
49
|
+
if (typeof raw !== 'object' || Array.isArray(raw)) {
|
|
50
|
+
return { ...absent, bodyStartIndex: close + 1, problems: [`${source}: frontmatter is not a mapping; read as absent`] };
|
|
51
|
+
}
|
|
52
|
+
const fm = raw as Record<string, unknown>;
|
|
53
|
+
const out: SpecFrontmatter = { source_mode: 'authored' };
|
|
54
|
+
|
|
55
|
+
const mode = scalar(fm.source_mode);
|
|
56
|
+
if (mode === 'linked' || mode === 'authored') out.source_mode = mode;
|
|
57
|
+
else if (mode !== undefined) problems.push(`${source}: source_mode "${mode}" is not linked|authored; using authored`);
|
|
58
|
+
|
|
59
|
+
const id = scalar(fm.id);
|
|
60
|
+
if (id && isDocId(id)) out.id = id;
|
|
61
|
+
else if (id) problems.push(`${source}: id "${id}" is not a document id like SPEC-AUTH-001; item anchors are not derived`);
|
|
62
|
+
|
|
63
|
+
for (const key of ['version', 'status', 'superseded_by', 'screen_id'] as const) {
|
|
64
|
+
const v = scalar(fm[key]);
|
|
65
|
+
if (v) out[key] = v;
|
|
66
|
+
}
|
|
67
|
+
return { present: true, frontmatter: out, bodyStartIndex: close + 1, problems };
|
|
68
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `##` / `###` section split of `spec.md`, shared by the manifest and the anchor reader so a
|
|
3
|
+
* `sec-<slug>` anchor and a manifest section can never disagree about where a section starts or
|
|
4
|
+
* what it hashes. The rules are the manifest's original ones, moved here unchanged (red-team #1):
|
|
5
|
+
* every line is scanned, a `Section:` prefix is stripped, the body is everything up to the next
|
|
6
|
+
* `##`/`###` heading.
|
|
7
|
+
*/
|
|
8
|
+
export interface SpecSectionBlock {
|
|
9
|
+
/** Heading text with any `Section:` prefix stripped (not yet normalized). */
|
|
10
|
+
name: string;
|
|
11
|
+
/** 0-based index of the heading line. */
|
|
12
|
+
headingIndex: number;
|
|
13
|
+
body: string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function readSpecSectionBlocks(lines: string[]): SpecSectionBlock[] {
|
|
17
|
+
const out: SpecSectionBlock[] = [];
|
|
18
|
+
let cur: SpecSectionBlock | null = null;
|
|
19
|
+
for (let i = 0; i < lines.length; i++) {
|
|
20
|
+
const h = lines[i].match(/^#{2,3}\s+(.*)$/);
|
|
21
|
+
if (h) {
|
|
22
|
+
if (cur) out.push(cur);
|
|
23
|
+
cur = { name: h[1].replace(/^Section:\s*/i, '').trim(), headingIndex: i, body: [] };
|
|
24
|
+
} else if (cur) {
|
|
25
|
+
cur.body.push(lines[i]);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (cur) out.push(cur);
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** The manifest's section-name key: tier suffix and markdown marks dropped, lower-case, spaces collapsed. */
|
|
33
|
+
export function normalizeSectionName(s: string): string {
|
|
34
|
+
return s.replace(/\(Tier[^)]*\)/i, '').replace(/[#*-]/g, '').trim().toLowerCase().replace(/\s+/g, ' ');
|
|
35
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-basis schema, validator and reader (DOS-12.4). P0 ships only these; the generator and a
|
|
3
|
+
* `BasisProvider` are P1, and there is no `basis.hand-edited` rule.
|
|
4
|
+
*
|
|
5
|
+
* { schema, source_mode, sources:[{docId, uri, version, hash}], anchors:[{id, kind, hash, location}] }
|
|
6
|
+
*
|
|
7
|
+
* It stores pointers and hashes, NEVER spec text (red-team #14). The validator enforces that
|
|
8
|
+
* structurally rather than by promise: unknown keys, multi-line values and long strings are refused,
|
|
9
|
+
* and every id, hash and citation must parse.
|
|
10
|
+
*/
|
|
11
|
+
import * as fs from 'fs';
|
|
12
|
+
import { safeYamlParse } from '../utils/safe-yaml-parse';
|
|
13
|
+
import { AnchorKind, isDocId, parseAnchorId, parseCitation } from './anchor-grammar';
|
|
14
|
+
import { SourceMode } from './spec-frontmatter';
|
|
15
|
+
|
|
16
|
+
export const TEST_BASIS_SCHEMA = 1;
|
|
17
|
+
|
|
18
|
+
export interface TestBasisSource { docId: string; uri: string; version: string; hash: string }
|
|
19
|
+
export interface TestBasisAnchor { id: string; kind: AnchorKind; hash: string; location: string }
|
|
20
|
+
export interface TestBasis { schema: 1; source_mode: SourceMode; sources: TestBasisSource[]; anchors: TestBasisAnchor[] }
|
|
21
|
+
|
|
22
|
+
const MAX_LEN: Record<string, number> = { docId: 64, uri: 2048, version: 64, hash: 64, id: 256, kind: 16, location: 2048 };
|
|
23
|
+
const isObject = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
24
|
+
|
|
25
|
+
/** A pointer field: a short single-line string. Anything longer or multi-line is text, not a pointer. */
|
|
26
|
+
function pointerErrors(where: string, obj: Record<string, unknown>, keys: string[]): string[] {
|
|
27
|
+
const e: string[] = [];
|
|
28
|
+
for (const k of Object.keys(obj)) if (!keys.includes(k)) e.push(`${where}: unknown key "${k}" (a test-basis holds pointers and hashes, never spec text)`);
|
|
29
|
+
for (const k of keys) {
|
|
30
|
+
const v = obj[k];
|
|
31
|
+
if (typeof v !== 'string' || !v.trim()) e.push(`${where}.${k} must be a non-empty string`);
|
|
32
|
+
else if (/[\r\n]/.test(v) || v.length > MAX_LEN[k]) e.push(`${where}.${k} must be a single line of at most ${MAX_LEN[k]} characters`);
|
|
33
|
+
}
|
|
34
|
+
return e;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function validateTestBasis(raw: unknown): string[] {
|
|
38
|
+
if (!isObject(raw)) return ['test-basis must be a mapping'];
|
|
39
|
+
const e: string[] = [];
|
|
40
|
+
for (const k of Object.keys(raw)) if (!['schema', 'source_mode', 'sources', 'anchors'].includes(k)) e.push(`unknown top-level key "${k}"`);
|
|
41
|
+
if (raw.schema !== TEST_BASIS_SCHEMA) e.push(`schema must be ${TEST_BASIS_SCHEMA}`);
|
|
42
|
+
if (raw.source_mode !== 'linked' && raw.source_mode !== 'authored') e.push('source_mode must be linked|authored');
|
|
43
|
+
|
|
44
|
+
const docIds = new Set<string>();
|
|
45
|
+
if (!Array.isArray(raw.sources)) e.push('sources must be a list');
|
|
46
|
+
else raw.sources.forEach((s, i) => {
|
|
47
|
+
if (!isObject(s)) { e.push(`sources[${i}] must be a mapping`); return; }
|
|
48
|
+
e.push(...pointerErrors(`sources[${i}]`, s, ['docId', 'uri', 'version', 'hash']));
|
|
49
|
+
if (typeof s.docId === 'string' && !isDocId(s.docId)) e.push(`sources[${i}].docId "${s.docId}" is not a document id like SPEC-AUTH-001`);
|
|
50
|
+
if (typeof s.hash === 'string' && !/^[0-9a-f]{12,64}$/.test(s.hash)) e.push(`sources[${i}].hash must be 12-64 lowercase hex`);
|
|
51
|
+
if (typeof s.docId === 'string') docIds.add(s.docId);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const seen = new Set<string>();
|
|
55
|
+
if (!Array.isArray(raw.anchors)) e.push('anchors must be a list');
|
|
56
|
+
else raw.anchors.forEach((a, i) => {
|
|
57
|
+
if (!isObject(a)) { e.push(`anchors[${i}] must be a mapping`); return; }
|
|
58
|
+
e.push(...pointerErrors(`anchors[${i}]`, a, ['id', 'kind', 'hash', 'location']));
|
|
59
|
+
const parsed = typeof a.id === 'string' ? parseAnchorId(a.id) : null;
|
|
60
|
+
if (!parsed) e.push(`anchors[${i}].id "${a.id}" is not an anchor (SPEC-ID#A-2, SPEC-ID#A-2/val, sec-<slug>)`);
|
|
61
|
+
else if (parsed.kind !== a.kind) e.push(`anchors[${i}].kind "${a.kind}" disagrees with its id (${parsed.kind})`);
|
|
62
|
+
if (parsed?.docId && !docIds.has(parsed.docId)) e.push(`anchors[${i}] points into ${parsed.docId}, which is not a listed source`);
|
|
63
|
+
if (typeof a.hash === 'string' && !/^[0-9a-f]{12}$/.test(a.hash)) e.push(`anchors[${i}].hash must be 12 lowercase hex (sha1-12 or sha256-12)`);
|
|
64
|
+
if (typeof a.location === 'string' && !parseCitation(a.location)) e.push(`anchors[${i}].location must be repo@SHA:path#Lx-Ly`);
|
|
65
|
+
if (typeof a.id === 'string') { if (seen.has(a.id)) e.push(`anchors[${i}].id "${a.id}" is listed twice`); seen.add(a.id); }
|
|
66
|
+
});
|
|
67
|
+
return e;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Best-effort reader: no file → no basis (an authored spec); a bad file → problems, never a throw. */
|
|
71
|
+
export function readTestBasis(file: string): { basis?: TestBasis; problems: string[] } {
|
|
72
|
+
if (!fs.existsSync(file)) return { problems: [] };
|
|
73
|
+
let raw: unknown;
|
|
74
|
+
try {
|
|
75
|
+
raw = safeYamlParse(fs.readFileSync(file, 'utf8'), file);
|
|
76
|
+
} catch (err) {
|
|
77
|
+
return { problems: [err instanceof Error ? err.message : String(err)] };
|
|
78
|
+
}
|
|
79
|
+
const problems = validateTestBasis(raw);
|
|
80
|
+
return problems.length ? { problems } : { basis: raw as TestBasis, problems };
|
|
81
|
+
}
|
|
@@ -123,8 +123,11 @@ function versionSkewWarning(name: string, loaded: string | undefined, core: stri
|
|
|
123
123
|
);
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
/** The bundled drivers, by package name (sorted). */
|
|
127
|
+
export const bundledDriverNames = (): string[] => [...BUNDLED_DRIVERS].sort();
|
|
128
|
+
|
|
129
|
+
/** Every installed copy of a driver, from the project and from core, with the requires that found them. */
|
|
130
|
+
function driverCopies(name: string): { copies: DriverCopy[]; requires: Map<string, NodeRequire> } {
|
|
128
131
|
// Look from the user's PROJECT and from core's own location. Opt-in drivers (`sungen capability add
|
|
129
132
|
// db|api`) install into the PROJECT's node_modules — a globally-installed core (`npm i -g`) wouldn't
|
|
130
133
|
// see them via a core-anchored `require`. The bundled @sungen/driver-ui is a core dependency
|
|
@@ -144,7 +147,17 @@ function loadExternalDriver(name: string): void {
|
|
|
144
147
|
requires.set(resolved, req);
|
|
145
148
|
copies.push({ anchor, resolved, version: readDriverVersion(req, name, resolved) });
|
|
146
149
|
}
|
|
150
|
+
return { copies, requires };
|
|
151
|
+
}
|
|
147
152
|
|
|
153
|
+
/** The copy of a driver discovery would load (the same anchors and pick), or undefined when none resolves. */
|
|
154
|
+
export function resolveDriverCopy(name: string): DriverCopy | undefined {
|
|
155
|
+
return pickDriverCopy(driverCopies(name).copies, coreVersion(), BUNDLED_DRIVERS.has(name));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function loadExternalDriver(name: string): void {
|
|
159
|
+
const bundled = BUNDLED_DRIVERS.has(name);
|
|
160
|
+
const { copies, requires } = driverCopies(name);
|
|
148
161
|
const core = coreVersion();
|
|
149
162
|
const chosen = pickDriverCopy(copies, core, bundled);
|
|
150
163
|
if (chosen) {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import type { StepPattern } from '../generators/test-generator/patterns/types';
|
|
15
15
|
import type { Sensor } from './sensor';
|
|
16
16
|
import type { DiscoveryProvider, ContextMapper, RepairProvider } from './context';
|
|
17
|
+
import type { TraceIdentityResolver } from '../contract/trace/target-identity';
|
|
17
18
|
|
|
18
19
|
export interface CapabilityDescriptor {
|
|
19
20
|
/** Stable id: 'ui' | 'db' | 'api' | 'core' | … */
|
|
@@ -70,6 +71,21 @@ export interface CapabilityDescriptor {
|
|
|
70
71
|
*/
|
|
71
72
|
appProfilePresets?: Record<string, unknown>;
|
|
72
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Target-identity resolver for trace-derived contracts: maps a replayed page snapshot + a
|
|
76
|
+
* recorded action to `{role, name, identityConfidence}` using the runtime's own accessibility
|
|
77
|
+
* engine (UI → Playwright `getByRole` / `ariaSnapshot`). Spec: `sungen_capability_spi_spec.md`
|
|
78
|
+
* §4.5, `sungen_durable_orchestration_spec.md` DOS-14.5.
|
|
79
|
+
*
|
|
80
|
+
* Pinned in phase 08 (the phase 07 spike gate passed): core renders each snapshot as inert HTML
|
|
81
|
+
* and asks the resolver for role + name + optional scope per target; a result that is not
|
|
82
|
+
* well-formed is rejected, and anything core already knows forces `low` (missing CSS…). Called
|
|
83
|
+
* only by `sungen contract check --trace` / `contract derive`; the verdict reads the cached
|
|
84
|
+
* answers. There is deliberately no `nodes?` slot: the graph node API is internal to core in P0
|
|
85
|
+
* (OES-10).
|
|
86
|
+
*/
|
|
87
|
+
traceIdentity?: TraceIdentityResolver;
|
|
88
|
+
|
|
73
89
|
// --- Declared for later R-steps; not consumed yet (kept here so the SPI shape is visible). ---
|
|
74
90
|
// adapter?: string; // codegen adapter id (existing adapterRegistry)
|
|
75
91
|
}
|
|
@@ -30,7 +30,7 @@ function render(r: AuditReport): void {
|
|
|
30
30
|
L('');
|
|
31
31
|
L(` Quality score (business-weighted): ${r.score.overall}/10 [Viewpoint Gate: ${r.gateStatus}]`);
|
|
32
32
|
L(` Intent: focus=${r.intent.focus} · depth threshold ${r.depth.threshold.toFixed(2)} (${r.intent.source})`);
|
|
33
|
-
L(` Provenance: sungen ${r.provenance.sungenVersion} · catalog ${r.provenance.catalogHash} (same
|
|
33
|
+
L(` Provenance: sungen ${r.provenance.sungenVersion} · catalog ${r.provenance.catalogHash} · rules ${r.provenance.rulesHash} (same rules on every machine → same score)`);
|
|
34
34
|
// Print the axes the score was ACTUALLY built from — a fixed five-line block omitted a flow's
|
|
35
35
|
// `flowCoverage`, `specFR` and `atomicLedger` while showing `balance`, which a contract flow
|
|
36
36
|
// does not score on.
|
|
@@ -180,7 +180,7 @@ export function registerAuditCommand(program: Command): void {
|
|
|
180
180
|
const dir = findUnitDir(name);
|
|
181
181
|
if (!dir) throw new Error(`Not found: qa/screens/${name}, qa/flows/${name}, or qa/api/${name}`);
|
|
182
182
|
|
|
183
|
-
|
|
183
|
+
let report = runAudit(dir, name);
|
|
184
184
|
|
|
185
185
|
// The baseline is only ever written HERE, never by the measurement itself:
|
|
186
186
|
// a first sighting has nothing to compare against, and any later change is
|
|
@@ -201,9 +201,14 @@ export function registerAuditCommand(program: Command): void {
|
|
|
201
201
|
if (vb.reparsed) acceptViewpointBaseline(process.cwd(), unitId, { hash: vb.hash, ids: vb.ids, fileHash: vb.fileHash });
|
|
202
202
|
if ((vb.status === 'new' && !postHoc) || (options.acceptViewpoint && (vb.status === 'changed' || postHoc))) {
|
|
203
203
|
acceptViewpointBaseline(process.cwd(), unitId, { hash: vb.hash, ids: vb.ids, fileHash: vb.fileHash });
|
|
204
|
-
if (options.acceptViewpoint
|
|
205
|
-
|
|
206
|
-
|
|
204
|
+
if (options.acceptViewpoint) {
|
|
205
|
+
// Measure again against what was just accepted: the report printed and saved below (the
|
|
206
|
+
// one `sungen next` reads) must not be the pre-accept one, still holding the axes (#867).
|
|
207
|
+
report = runAudit(dir, name);
|
|
208
|
+
if (!options.json) {
|
|
209
|
+
console.log(`\n ✓ test-viewpoint.md accepted as the baseline for ${name} (${vb.ids.length} viewpoint id(s)).`);
|
|
210
|
+
console.log(' The report below is measured against it.\n');
|
|
211
|
+
}
|
|
207
212
|
}
|
|
208
213
|
} else if (options.acceptViewpoint && !options.json) {
|
|
209
214
|
// `absent` covers a file with no readable viewpoint id too — say which (#832).
|
|
@@ -209,7 +209,7 @@ export function registerCapabilityCommand(program: Command): void {
|
|
|
209
209
|
// beta channel can lag (e.g. a prerelease first-published-as-latest), pulling a driver
|
|
210
210
|
// whose core dep resolves to the wrong @sun-asterisk/sungen and fails to load.
|
|
211
211
|
const core = coreVersion();
|
|
212
|
-
const target = resolveDriverVersion(meta.package, core); // exact core, else same-line
|
|
212
|
+
const target = resolveDriverVersion(meta.package, core); // exact core, else same-line build of core's channel, else that channel's tag
|
|
213
213
|
const spec = `${meta.package}@${target}`;
|
|
214
214
|
if (target !== core) {
|
|
215
215
|
console.log(`ℹ ${meta.package}@${core} is not published yet — installing ${spec} (closest on the ${core} line).`);
|
|
@@ -265,7 +265,9 @@ export function registerCapabilityCommand(program: Command): void {
|
|
|
265
265
|
else console.log(' – skipped appium-environment/ (already exists)');
|
|
266
266
|
|
|
267
267
|
// Best-effort driver install — non-fatal so capability add still succeeds offline.
|
|
268
|
-
|
|
268
|
+
// --skip-install promises no npm install; the driver + wdio/appium runtime is ~290 MB.
|
|
269
|
+
if (o.skipInstall) console.log(' – skipped mobile driver install (--skip-install) — later: sungen capability add mobile');
|
|
270
|
+
else installMobileDriver(cwd);
|
|
269
271
|
|
|
270
272
|
// --skip-install means "record only" — then provisioning the machine is not wanted either.
|
|
271
273
|
runAppiumEnvironmentSetup(cwd, { skip: !!(o.skipEnvSetup || o.skipInstall) });
|