create-yss-spec 2.2.3 → 2.2.4
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/README.md +17 -1
- package/package.json +1 -1
- package/src/cli.js +15 -1
- package/src/self-update.js +277 -0
- package/template/.agents/skills/yss-domain/SKILL.md +5 -4
- package/template/.agents/skills/yss-product-lifecycle/SKILL.md +5 -5
- package/template/.agents/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
- package/template/.agents/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +6 -3
- package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +7 -2
- package/template/.agents/skills/yss-router/SKILL.md +4 -2
- package/template/.agents/skills/yss-router/references/router-contract.yaml +18 -3
- package/template/.agents/skills/yss-router/references/slice-implementation-contract.md +58 -1
- package/template/.agents/skills/yss-stage-decision/SKILL.md +50 -0
- package/template/.agents/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
- package/template/.agents/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
- package/template/.agents/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
- package/template/.agents/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
- package/template/.agents/skills/yss-stage-decision/references/validation-rules.md +18 -0
- package/template/.agents/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
- package/template/.agents/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
- package/template/.agents/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
- package/template/.agents/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
- package/template/.agents/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
- package/template/.agents/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
- package/template/.agents/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
- package/template/.agents/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
- package/template/.agents/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
- package/template/.agents/skills/yss-tactical-design/SKILL.md +33 -0
- package/template/.agents/skills/yss-tactical-design/agents/openai.yaml +4 -0
- package/template/.agents/skills/yss-tactical-design/references/output-template.md +28 -0
- package/template/.agents/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
- package/template/.agents/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
- package/template/.agents/skills/yss-tactical-design/references/validation-rules.md +13 -0
- package/template/.agents/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
- package/template/.agents/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
- package/template/.agents/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
- package/template/.agents/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
- package/template/.agents/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
- package/template/.agents/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
- package/template/.agents/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
- package/template/.agents/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
- package/template/.claude/skills/yss-domain/SKILL.md +5 -4
- package/template/.claude/skills/yss-product-lifecycle/SKILL.md +5 -5
- package/template/.claude/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
- package/template/.claude/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
- package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
- package/template/.claude/skills/yss-product-lifecycle/references/orchestration.md +6 -3
- package/template/.claude/skills/yss-product-lifecycle/references/state-model.md +7 -2
- package/template/.claude/skills/yss-router/SKILL.md +4 -2
- package/template/.claude/skills/yss-router/references/router-contract.yaml +18 -3
- package/template/.claude/skills/yss-router/references/slice-implementation-contract.md +58 -1
- package/template/.claude/skills/yss-stage-decision/SKILL.md +50 -0
- package/template/.claude/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
- package/template/.claude/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
- package/template/.claude/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
- package/template/.claude/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
- package/template/.claude/skills/yss-stage-decision/references/validation-rules.md +18 -0
- package/template/.claude/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
- package/template/.claude/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
- package/template/.claude/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
- package/template/.claude/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
- package/template/.claude/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
- package/template/.claude/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
- package/template/.claude/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
- package/template/.claude/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
- package/template/.claude/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
- package/template/.claude/skills/yss-tactical-design/SKILL.md +33 -0
- package/template/.claude/skills/yss-tactical-design/agents/openai.yaml +4 -0
- package/template/.claude/skills/yss-tactical-design/references/output-template.md +28 -0
- package/template/.claude/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
- package/template/.claude/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
- package/template/.claude/skills/yss-tactical-design/references/validation-rules.md +13 -0
- package/template/.claude/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
- package/template/.claude/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
- package/template/.claude/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
- package/template/.claude/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
- package/template/.claude/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
- package/template/.claude/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
- package/template/.claude/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
- package/template/.claude/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
- package/template/.codex/skills/yss-domain/SKILL.md +5 -4
- package/template/.codex/skills/yss-product-lifecycle/SKILL.md +5 -5
- package/template/.codex/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
- package/template/.codex/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +6 -3
- package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +7 -2
- package/template/.codex/skills/yss-router/SKILL.md +4 -2
- package/template/.codex/skills/yss-router/references/router-contract.yaml +18 -3
- package/template/.codex/skills/yss-router/references/slice-implementation-contract.md +58 -1
- package/template/.codex/skills/yss-stage-decision/SKILL.md +50 -0
- package/template/.codex/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
- package/template/.codex/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
- package/template/.codex/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
- package/template/.codex/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
- package/template/.codex/skills/yss-stage-decision/references/validation-rules.md +18 -0
- package/template/.codex/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
- package/template/.codex/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
- package/template/.codex/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
- package/template/.codex/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
- package/template/.codex/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
- package/template/.codex/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
- package/template/.codex/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
- package/template/.codex/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
- package/template/.codex/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
- package/template/.codex/skills/yss-tactical-design/SKILL.md +33 -0
- package/template/.codex/skills/yss-tactical-design/agents/openai.yaml +4 -0
- package/template/.codex/skills/yss-tactical-design/references/output-template.md +28 -0
- package/template/.codex/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
- package/template/.codex/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
- package/template/.codex/skills/yss-tactical-design/references/validation-rules.md +13 -0
- package/template/.codex/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
- package/template/.codex/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
- package/template/.codex/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
- package/template/.codex/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
- package/template/.codex/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
- package/template/.codex/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
- package/template/.codex/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
- package/template/.codex/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
- package/template/.cursor/skills/yss-domain/SKILL.md +5 -4
- package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +5 -5
- package/template/.cursor/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
- package/template/.cursor/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
- package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
- package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +6 -3
- package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +7 -2
- package/template/.cursor/skills/yss-router/SKILL.md +4 -2
- package/template/.cursor/skills/yss-router/references/router-contract.yaml +18 -3
- package/template/.cursor/skills/yss-router/references/slice-implementation-contract.md +58 -1
- package/template/.cursor/skills/yss-stage-decision/SKILL.md +50 -0
- package/template/.cursor/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
- package/template/.cursor/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
- package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
- package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
- package/template/.cursor/skills/yss-stage-decision/references/validation-rules.md +18 -0
- package/template/.cursor/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
- package/template/.cursor/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
- package/template/.cursor/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
- package/template/.cursor/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
- package/template/.cursor/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
- package/template/.cursor/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
- package/template/.cursor/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
- package/template/.cursor/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
- package/template/.cursor/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
- package/template/.cursor/skills/yss-tactical-design/SKILL.md +33 -0
- package/template/.cursor/skills/yss-tactical-design/agents/openai.yaml +4 -0
- package/template/.cursor/skills/yss-tactical-design/references/output-template.md +28 -0
- package/template/.cursor/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
- package/template/.cursor/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
- package/template/.cursor/skills/yss-tactical-design/references/validation-rules.md +13 -0
- package/template/.cursor/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
- package/template/.cursor/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
- package/template/.cursor/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
- package/template/.cursor/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
- package/template/.cursor/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
- package/template/.cursor/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
- package/template/.cursor/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
- package/template/.cursor/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
- package/template/.hermes/skills/yss-domain/SKILL.md +5 -4
- package/template/.hermes/skills/yss-product-lifecycle/SKILL.md +5 -5
- package/template/.hermes/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
- package/template/.hermes/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
- package/template/.hermes/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
- package/template/.hermes/skills/yss-product-lifecycle/references/orchestration.md +6 -3
- package/template/.hermes/skills/yss-product-lifecycle/references/state-model.md +7 -2
- package/template/.hermes/skills/yss-router/SKILL.md +4 -2
- package/template/.hermes/skills/yss-router/references/router-contract.yaml +18 -3
- package/template/.hermes/skills/yss-router/references/slice-implementation-contract.md +58 -1
- package/template/.hermes/skills/yss-stage-decision/SKILL.md +50 -0
- package/template/.hermes/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
- package/template/.hermes/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
- package/template/.hermes/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
- package/template/.hermes/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
- package/template/.hermes/skills/yss-stage-decision/references/validation-rules.md +18 -0
- package/template/.hermes/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
- package/template/.hermes/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
- package/template/.hermes/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
- package/template/.hermes/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
- package/template/.hermes/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
- package/template/.hermes/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
- package/template/.hermes/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
- package/template/.hermes/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
- package/template/.hermes/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
- package/template/.hermes/skills/yss-tactical-design/SKILL.md +33 -0
- package/template/.hermes/skills/yss-tactical-design/agents/openai.yaml +4 -0
- package/template/.hermes/skills/yss-tactical-design/references/output-template.md +28 -0
- package/template/.hermes/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
- package/template/.hermes/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
- package/template/.hermes/skills/yss-tactical-design/references/validation-rules.md +13 -0
- package/template/.hermes/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
- package/template/.hermes/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
- package/template/.hermes/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
- package/template/.hermes/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
- package/template/.hermes/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
- package/template/.hermes/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
- package/template/.hermes/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
- package/template/.hermes/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
- package/template/.pi/skills/yss-domain/SKILL.md +5 -4
- package/template/.pi/skills/yss-product-lifecycle/SKILL.md +5 -5
- package/template/.pi/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
- package/template/.pi/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +6 -3
- package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +7 -2
- package/template/.pi/skills/yss-router/SKILL.md +4 -2
- package/template/.pi/skills/yss-router/references/router-contract.yaml +18 -3
- package/template/.pi/skills/yss-router/references/slice-implementation-contract.md +58 -1
- package/template/.pi/skills/yss-stage-decision/SKILL.md +50 -0
- package/template/.pi/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
- package/template/.pi/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
- package/template/.pi/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
- package/template/.pi/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
- package/template/.pi/skills/yss-stage-decision/references/validation-rules.md +18 -0
- package/template/.pi/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
- package/template/.pi/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
- package/template/.pi/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
- package/template/.pi/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
- package/template/.pi/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
- package/template/.pi/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
- package/template/.pi/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
- package/template/.pi/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
- package/template/.pi/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
- package/template/.pi/skills/yss-tactical-design/SKILL.md +33 -0
- package/template/.pi/skills/yss-tactical-design/agents/openai.yaml +4 -0
- package/template/.pi/skills/yss-tactical-design/references/output-template.md +28 -0
- package/template/.pi/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
- package/template/.pi/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
- package/template/.pi/skills/yss-tactical-design/references/validation-rules.md +13 -0
- package/template/.pi/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
- package/template/.pi/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
- package/template/.pi/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
- package/template/.pi/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
- package/template/.pi/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
- package/template/.pi/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
- package/template/.pi/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
- package/template/.pi/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
- package/template/.qoder/skills/yss-domain/SKILL.md +5 -4
- package/template/.qoder/skills/yss-product-lifecycle/SKILL.md +5 -5
- package/template/.qoder/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
- package/template/.qoder/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
- package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
- package/template/.qoder/skills/yss-product-lifecycle/references/orchestration.md +6 -3
- package/template/.qoder/skills/yss-product-lifecycle/references/state-model.md +7 -2
- package/template/.qoder/skills/yss-router/SKILL.md +4 -2
- package/template/.qoder/skills/yss-router/references/router-contract.yaml +18 -3
- package/template/.qoder/skills/yss-router/references/slice-implementation-contract.md +58 -1
- package/template/.qoder/skills/yss-stage-decision/SKILL.md +50 -0
- package/template/.qoder/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
- package/template/.qoder/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
- package/template/.qoder/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
- package/template/.qoder/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
- package/template/.qoder/skills/yss-stage-decision/references/validation-rules.md +18 -0
- package/template/.qoder/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
- package/template/.qoder/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
- package/template/.qoder/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
- package/template/.qoder/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
- package/template/.qoder/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
- package/template/.qoder/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
- package/template/.qoder/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
- package/template/.qoder/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
- package/template/.qoder/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
- package/template/.qoder/skills/yss-tactical-design/SKILL.md +33 -0
- package/template/.qoder/skills/yss-tactical-design/agents/openai.yaml +4 -0
- package/template/.qoder/skills/yss-tactical-design/references/output-template.md +28 -0
- package/template/.qoder/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
- package/template/.qoder/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
- package/template/.qoder/skills/yss-tactical-design/references/validation-rules.md +13 -0
- package/template/.qoder/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
- package/template/.qoder/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
- package/template/.qoder/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
- package/template/.qoder/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
- package/template/.qoder/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
- package/template/.qoder/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
- package/template/.qoder/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
- package/template/.qoder/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
- package/template/.trae/skills/yss-domain/SKILL.md +5 -4
- package/template/.trae/skills/yss-product-lifecycle/SKILL.md +5 -5
- package/template/.trae/skills/yss-product-lifecycle/references/artifact-dependencies.md +4 -0
- package/template/.trae/skills/yss-product-lifecycle/references/matt-yss-adapter.md +2 -2
- package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +139 -4
- package/template/.trae/skills/yss-product-lifecycle/references/orchestration.md +6 -3
- package/template/.trae/skills/yss-product-lifecycle/references/state-model.md +7 -2
- package/template/.trae/skills/yss-router/SKILL.md +4 -2
- package/template/.trae/skills/yss-router/references/router-contract.yaml +18 -3
- package/template/.trae/skills/yss-router/references/slice-implementation-contract.md +58 -1
- package/template/.trae/skills/yss-stage-decision/SKILL.md +50 -0
- package/template/.trae/skills/yss-stage-decision/references/domain-strategy-contract.md +26 -0
- package/template/.trae/skills/yss-stage-decision/references/domain-strategy.schema.json +128 -0
- package/template/.trae/skills/yss-stage-decision/references/stage-decision-package-contract.md +19 -0
- package/template/.trae/skills/yss-stage-decision/references/stage-decision-package.schema.json +86 -0
- package/template/.trae/skills/yss-stage-decision/references/validation-rules.md +18 -0
- package/template/.trae/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +169 -0
- package/template/.trae/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +100 -0
- package/template/.trae/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml +15 -0
- package/template/.trae/skills/yss-stage-decision/tests/fixtures/invalid-direction.yaml +58 -0
- package/template/.trae/skills/yss-stage-decision/tests/fixtures/invalid-stage-decision-blocker.yaml +44 -0
- package/template/.trae/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml +15 -0
- package/template/.trae/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +49 -0
- package/template/.trae/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +108 -0
- package/template/.trae/skills/yss-stage-decision/tests/run-scenarios.mjs +68 -0
- package/template/.trae/skills/yss-tactical-design/SKILL.md +33 -0
- package/template/.trae/skills/yss-tactical-design/agents/openai.yaml +4 -0
- package/template/.trae/skills/yss-tactical-design/references/output-template.md +28 -0
- package/template/.trae/skills/yss-tactical-design/references/tactical-design-contract.md +41 -0
- package/template/.trae/skills/yss-tactical-design/references/tactical-design.schema.json +31 -0
- package/template/.trae/skills/yss-tactical-design/references/validation-rules.md +13 -0
- package/template/.trae/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +213 -0
- package/template/.trae/skills/yss-tactical-design/tests/fixtures/invalid-api-leaks-aggregate.yaml +21 -0
- package/template/.trae/skills/yss-tactical-design/tests/fixtures/invalid-missing-consistency-policy.yaml +21 -0
- package/template/.trae/skills/yss-tactical-design/tests/fixtures/invalid-missing-invariant.yaml +21 -0
- package/template/.trae/skills/yss-tactical-design/tests/fixtures/invalid-stale-upstream-ref.yaml +21 -0
- package/template/.trae/skills/yss-tactical-design/tests/fixtures/invalid-strategic-as-tactical.yaml +21 -0
- package/template/.trae/skills/yss-tactical-design/tests/fixtures/valid-tactical-design.yaml +80 -0
- package/template/.trae/skills/yss-tactical-design/tests/run-scenarios.mjs +47 -0
- package/template/AGENTS.md +2 -1
- package/template/docs/agents/digital-human-roles.md +2 -2
- package/template/docs/agents/digital-human-roles.yaml +7 -1
- package/template/docs/agents/yss-skill-registry.yaml +12 -0
- package/template/docs/architecture/templates/system-overview-design-template.md +1 -0
- package/template/docs/process/lifecycle-artifact-map.md +8 -0
- package/template/docs/process/lifecycle-registry-baseline.json +11 -1
- package/template/docs/process/lifecycle-registry.yaml +46 -2
- package/template/docs/process/schemas/digital-human-task-package.schema.json +107 -0
- package/template/docs/process/schemas/subagent-task-package.schema.json +6 -0
- package/template/docs/process/subagent-collaboration.md +2 -2
- package/template/docs/templates/subagent-task-package-template.md +39 -1
- package/template/scripts/lib/lifecycle-transition.mjs +259 -0
- package/template/scripts/lib/scenario-checks.mjs +96 -2
- package/template/scripts/lib/task-package.mjs +214 -0
- package/template/scripts/verify-digital-human-task-package +14 -0
- package/template/scripts/verify-digital-human-task-package-scenarios +8 -0
- package/template/scripts/verify-lifecycle-transition-scenarios +105 -0
- package/template/scripts/verify-subagent-task-package +8 -0
- package/template/scripts/verify-subagent-task-package-scenarios +196 -0
- package/template/scripts/verify-template +13 -2
- package/template/skills-lock.json +35 -3
- package/template.snapshot.json +4 -4
|
@@ -25,6 +25,7 @@ slice_contract:
|
|
|
25
25
|
architecture_review:
|
|
26
26
|
data_architecture:
|
|
27
27
|
engineering_baseline:
|
|
28
|
+
tactical_design:
|
|
28
29
|
build_architecture_checklist:
|
|
29
30
|
implementation_repository:
|
|
30
31
|
frontend_repository:
|
|
@@ -70,6 +71,24 @@ slice_contract:
|
|
|
70
71
|
application_boundary:
|
|
71
72
|
transaction_boundary:
|
|
72
73
|
persistence_strategy:
|
|
74
|
+
tactical_design_ref:
|
|
75
|
+
tactical_design_version:
|
|
76
|
+
aggregate_refs: []
|
|
77
|
+
invariant_refs: []
|
|
78
|
+
state_behavior_refs: []
|
|
79
|
+
gateway_boundary_ref:
|
|
80
|
+
domain_test_seams: []
|
|
81
|
+
application_test_seams: []
|
|
82
|
+
tactical_ddd:
|
|
83
|
+
status: not-applicable
|
|
84
|
+
tactical_design_ref:
|
|
85
|
+
tactical_design_version:
|
|
86
|
+
aggregate_refs: []
|
|
87
|
+
invariant_refs: []
|
|
88
|
+
state_behavior_refs: []
|
|
89
|
+
gateway_boundary_ref:
|
|
90
|
+
domain_test_seams: []
|
|
91
|
+
application_test_seams: []
|
|
73
92
|
allowed_write_paths: []
|
|
74
93
|
forbidden_patterns: []
|
|
75
94
|
expected_evidence_files: []
|
|
@@ -87,7 +106,43 @@ slice_contract:
|
|
|
87
106
|
delivery_order: []
|
|
88
107
|
integration_verification: []
|
|
89
108
|
rollback_order: []
|
|
90
|
-
work_units:
|
|
109
|
+
work_units:
|
|
110
|
+
- id: slice-frontend
|
|
111
|
+
role_id: role.frontend-engineer
|
|
112
|
+
runtime_id: runtime.skill-projection
|
|
113
|
+
execution_state: Worker
|
|
114
|
+
workflow_status: not-started
|
|
115
|
+
task_package_ref:
|
|
116
|
+
contract_id: # must equal slice_contract.contract_id
|
|
117
|
+
contract_version: # must equal slice_contract.contract_version
|
|
118
|
+
downstream_consumers: []
|
|
119
|
+
convergence_ref:
|
|
120
|
+
work_unit:
|
|
121
|
+
behavior:
|
|
122
|
+
primary_skill:
|
|
123
|
+
supporting_skills: []
|
|
124
|
+
tdd_mode: behavior-tdd
|
|
125
|
+
allowed_write_paths: []
|
|
126
|
+
expected_evidence: []
|
|
127
|
+
verification_commands: []
|
|
128
|
+
- id: slice-backend
|
|
129
|
+
role_id: role.backend-engineer
|
|
130
|
+
runtime_id: runtime.skill-projection
|
|
131
|
+
execution_state: Worker
|
|
132
|
+
workflow_status: not-started
|
|
133
|
+
task_package_ref:
|
|
134
|
+
contract_id:
|
|
135
|
+
contract_version:
|
|
136
|
+
downstream_consumers: []
|
|
137
|
+
convergence_ref:
|
|
138
|
+
work_unit:
|
|
139
|
+
behavior:
|
|
140
|
+
primary_skill:
|
|
141
|
+
supporting_skills: []
|
|
142
|
+
tdd_mode: behavior-tdd
|
|
143
|
+
allowed_write_paths: []
|
|
144
|
+
expected_evidence: []
|
|
145
|
+
verification_commands: []
|
|
91
146
|
```
|
|
92
147
|
|
|
93
148
|
工作单元:
|
|
@@ -112,3 +167,5 @@ work_unit:
|
|
|
112
167
|
```
|
|
113
168
|
|
|
114
169
|
`controlled_generation` 仅在 `tdd_mode: controlled-generation` 时必填;其他模式标记 `not-applicable`。明确写入需求的权限业务行为仍使用 `behavior-tdd`;API schema 与 database schema 分别触发契约或数据架构回退,不得用一个含糊的 schema 类型决定路线。
|
|
170
|
+
|
|
171
|
+
`work_units` 中的前端、后端和测试任务是切片级子任务,不是新的生命周期阶段。每个子任务必须引用独立任务包;任务包只能消费同一份已批准且版本当前的 Slice Contract。`workflow_status` 追踪执行过程,不能替代生命周期状态;`contract_id` 或 `contract_version` 不一致时必须阻断并回到 Router。
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: yss-stage-decision
|
|
3
|
+
description: 编排 Discovery 到 Spec 入口的阶段决策与 DDD 战略设计;当需求、领域边界、统一语言或下游影响尚未稳定时使用。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# YSS Stage Decision
|
|
7
|
+
|
|
8
|
+
`yss-stage-decision` 是由 `yss-product-lifecycle` 调度的上游决策技能空间,负责把需求、产品、商务输入和 DDD 战略设计结果整理成可审查、可版本化、可被下游消费的阶段决策包。它不替代生命周期主控,也不生成产品代码、原型、OpenAPI 或垂直切片 Ticket。
|
|
9
|
+
|
|
10
|
+
## 适用边界
|
|
11
|
+
|
|
12
|
+
- 适用于 `project-instance` 的 Discovery → Spec 入口。
|
|
13
|
+
- `template-source` 只维护本技能、Schema、验证器和合成 Fixture,不生成具体产品领域资产。
|
|
14
|
+
- DDD 工作单元只做子域、限界上下文、Context Map、统一语言、关键场景、事件、核心领域概念候选和业务不变量。
|
|
15
|
+
- Entity、Aggregate、Repository、Java 类、数据库表和 OpenAPI Freeze 留给下游工作单元。
|
|
16
|
+
|
|
17
|
+
## 执行顺序
|
|
18
|
+
|
|
19
|
+
1. 读取 `yss-project.yaml`、`CONTEXT.md`、既有 Discovery/Spec、ADR 和父 Ticket/checkpoint。
|
|
20
|
+
2. 分离事实、决策、假设、约束和未决项;技术事实走 `research`,市场/竞品事实走 `competitive-intelligence`。
|
|
21
|
+
3. 从业务场景、事件、规则、责任人和失败路径识别子域及限界上下文,不从数据库表或调用链直接反推边界。
|
|
22
|
+
4. 为每个上下文建立本地统一语言;为跨上下文关系记录语义上游/下游、业务决策权、技术传输方向和翻译责任。
|
|
23
|
+
5. 记录核心领域概念候选,不提前锁定 Entity 或 Aggregate。
|
|
24
|
+
6. 生成 `domain_strategy` 和 `stage_decision_package`,绑定版本、digest、证据和下游影响映射。
|
|
25
|
+
7. 运行 Schema、引用、语义一致性和传播验证;发现关键冲突时返回 `blocked`,不得生成 `approved` 包。
|
|
26
|
+
|
|
27
|
+
## 语义方向规则
|
|
28
|
+
|
|
29
|
+
`semantic_upstream` 是拥有业务规则、决策语义或权威模型的一方;`semantic_downstream` 是消费、适配或依赖该语义的一方。二者不等于 HTTP、事件或数据库的技术方向。每条 Context Map 关系必须独立记录 `transport_direction` 和 `translation_responsibility`;同一对上下文可以存在多条相反方向的语义边。
|
|
30
|
+
|
|
31
|
+
## 产物与批准
|
|
32
|
+
|
|
33
|
+
- DDD 资产是事实源,阶段决策包只通过 `domain_strategy_ref` 引用它们。
|
|
34
|
+
- `stage_decision_package` 必须经过 `draft → ready-for-human → approved`;起草者不得自签。
|
|
35
|
+
- 建议门禁为 `gate.domain-strategy-approved` 和 `gate.stage-decision-package-approved`,实际状态由 `yss-product-lifecycle` 维护;阶段包批准引用必须通过 `scripts/verify-approval-record`,不得用不可读路径或聊天确认替代。
|
|
36
|
+
- 下游只能消费批准且版本当前的包;发现语义冲突返回 `drift` / `new_impacts`,不得静默修改上游。
|
|
37
|
+
|
|
38
|
+
## 结果合同
|
|
39
|
+
|
|
40
|
+
返回标准 `Workflow Execution Result`,至少包含 `work_unit`、`workflow_reference`、`result`、`evidence_refs`、`changed_artifacts`、`new_impacts`、`stale_candidates`、`next_route` 和 `blocking_signals`。`blocked` 必须包含冲突、责任人、恢复条件和下一工作单元。
|
|
41
|
+
|
|
42
|
+
## 禁止事项
|
|
43
|
+
|
|
44
|
+
- 不把阶段包当作第二套领域事实源。
|
|
45
|
+
- 不按数据库、微服务、菜单或 HTTP 调用方向自动划分上下文。
|
|
46
|
+
- 不把同名术语强行合并为全局概念。
|
|
47
|
+
- 不在战略设计阶段生成 Entity、Aggregate、Repository、生产代码或 API 契约。
|
|
48
|
+
- 不把模板 Fixture 当作具体项目的业务事实。
|
|
49
|
+
|
|
50
|
+
详细合同、字段和验证规则见 `references/domain-strategy-contract.md`、`references/stage-decision-package-contract.md` 与 `references/validation-rules.md`。机器可读合同分别为 `references/domain-strategy.schema.json` 和 `references/stage-decision-package.schema.json`;对应验证器为 `scripts/validate-domain-strategy.mjs` 与 `scripts/validate-stage-decision-package.mjs`。
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# DDD 战略设计合同
|
|
2
|
+
|
|
3
|
+
## 顶层结构
|
|
4
|
+
|
|
5
|
+
机器可读合同使用 `references/domain-strategy.schema.json`。顶层必须包含:
|
|
6
|
+
|
|
7
|
+
- `schema_version`、`domain_strategy_id`、`domain_version`、`status`;
|
|
8
|
+
- `contexts`、`subdomains`、`relationships`、`scenarios`;
|
|
9
|
+
- `concept_candidates`、`invariants`、`terminology_refs`;
|
|
10
|
+
- `downstream_mapping`、`evidence_refs`、`approval`。
|
|
11
|
+
|
|
12
|
+
## 上下文
|
|
13
|
+
|
|
14
|
+
每个上下文声明 `context_id`、职责边界、非职责、子域分类、模型所有者、关键场景和本地词汇引用。`context_id` 是稳定身份,不得使用代码模块、数据库 schema 或菜单路径替代。
|
|
15
|
+
|
|
16
|
+
## 关系
|
|
17
|
+
|
|
18
|
+
关系必须声明 `relationship_pattern`、`semantic_upstream`、`semantic_downstream`、`business_authority`、`model_change_impact`、`transport_direction` 和 `translation_responsibility`。语义方向与技术方向可以不同;关系模式只能使用合同中列出的 DDD 模式。
|
|
19
|
+
|
|
20
|
+
## 核心概念
|
|
21
|
+
|
|
22
|
+
使用 `domain_concept_candidate` 表达战略阶段的核心概念候选,记录身份特征、生命周期、不变量引用、可能的战术角色和置信度。不得在该合同中把概念直接批准为 Entity 或 Aggregate Root。
|
|
23
|
+
|
|
24
|
+
## 阶段决策包
|
|
25
|
+
|
|
26
|
+
阶段包应通过 `domain_strategy_ref` 引用 DDD 合同的当前版本和 digest,并使用 `domain_to_downstream_mapping` 描述领域变化对 Spec、设计、API、数据、Ticket 和测试 seam 的传播。
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://yss.local/schemas/domain-strategy-v1.json",
|
|
4
|
+
"title": "YSS DDD Strategic Design",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["schema_version", "domain_strategy_id", "domain_version", "status", "contexts", "subdomains", "relationships", "scenarios", "concept_candidates", "invariants", "terminology_refs", "downstream_mapping", "evidence_refs", "approval"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"schema_version": {"const": 1},
|
|
9
|
+
"domain_strategy_id": {"type": "string", "pattern": "^domain-strategy\\.[a-z0-9][a-z0-9-]*$"},
|
|
10
|
+
"domain_version": {"type": "string", "pattern": "^v[0-9]+$"},
|
|
11
|
+
"status": {"enum": ["draft", "ready-for-human", "approved", "stale", "blocked"]},
|
|
12
|
+
"contexts": {"type": "array", "minItems": 1, "items": {"$ref": "#/$defs/context"}},
|
|
13
|
+
"subdomains": {"type": "array", "minItems": 1, "items": {"$ref": "#/$defs/subdomain"}},
|
|
14
|
+
"relationships": {"type": "array", "items": {"$ref": "#/$defs/relationship"}},
|
|
15
|
+
"scenarios": {"type": "array", "minItems": 1, "items": {"$ref": "#/$defs/scenario"}},
|
|
16
|
+
"concept_candidates": {"type": "array", "items": {"$ref": "#/$defs/concept"}},
|
|
17
|
+
"invariants": {"type": "array", "items": {"$ref": "#/$defs/invariant"}},
|
|
18
|
+
"terminology_refs": {"type": "array", "items": {"type": "string", "minLength": 1}},
|
|
19
|
+
"downstream_mapping": {"type": "array", "items": {"$ref": "#/$defs/mapping"}},
|
|
20
|
+
"evidence_refs": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
|
|
21
|
+
"approval": {"$ref": "#/$defs/approval"}
|
|
22
|
+
},
|
|
23
|
+
"$defs": {
|
|
24
|
+
"context": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"required": ["context_id", "name", "responsibilities", "non_responsibilities", "subdomain_type", "owner", "status"],
|
|
27
|
+
"properties": {
|
|
28
|
+
"context_id": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
|
|
29
|
+
"name": {"type": "string", "minLength": 1},
|
|
30
|
+
"responsibilities": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
|
|
31
|
+
"non_responsibilities": {"type": "array", "items": {"type": "string", "minLength": 1}},
|
|
32
|
+
"subdomain_type": {"enum": ["Core Domain", "Supporting Subdomain", "Generic Subdomain"]},
|
|
33
|
+
"owner": {"type": "string", "minLength": 1},
|
|
34
|
+
"status": {"enum": ["candidate", "confirmed", "stale"]}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"subdomain": {
|
|
38
|
+
"type": "object",
|
|
39
|
+
"required": ["subdomain_id", "name", "type", "rationale", "evidence_refs"],
|
|
40
|
+
"properties": {
|
|
41
|
+
"subdomain_id": {"type": "string", "pattern": "^subdomain\\.[a-z0-9][a-z0-9-]*$"},
|
|
42
|
+
"name": {"type": "string", "minLength": 1},
|
|
43
|
+
"type": {"enum": ["Core Domain", "Supporting Subdomain", "Generic Subdomain"]},
|
|
44
|
+
"rationale": {"type": "string", "minLength": 1},
|
|
45
|
+
"evidence_refs": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"relationship": {
|
|
49
|
+
"type": "object",
|
|
50
|
+
"required": ["relationship_id", "from_context", "to_context", "relationship_pattern", "semantic_upstream", "semantic_downstream", "business_authority", "model_change_impact", "transport_direction", "translation_responsibility", "direction_explanation"],
|
|
51
|
+
"properties": {
|
|
52
|
+
"relationship_id": {"type": "string", "pattern": "^relationship\\.[a-z0-9][a-z0-9-]*$"},
|
|
53
|
+
"from_context": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
|
|
54
|
+
"to_context": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
|
|
55
|
+
"relationship_pattern": {"enum": ["Partnership", "Customer/Supplier", "Conformist", "Anti-Corruption Layer", "Open Host Service", "Published Language", "Shared Kernel", "Separate Ways"]},
|
|
56
|
+
"semantic_upstream": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
|
|
57
|
+
"semantic_downstream": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
|
|
58
|
+
"business_authority": {"type": "string", "minLength": 1},
|
|
59
|
+
"model_change_impact": {"type": "string", "minLength": 1},
|
|
60
|
+
"transport_direction": {"type": "string", "minLength": 1},
|
|
61
|
+
"translation_responsibility": {"type": "string", "minLength": 1},
|
|
62
|
+
"direction_explanation": {"type": "string", "minLength": 1}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"scenario": {
|
|
66
|
+
"type": "object",
|
|
67
|
+
"required": ["scenario_id", "actor", "preconditions", "commands", "rules", "events", "failure_results", "responsible_context", "consumers", "status"],
|
|
68
|
+
"properties": {
|
|
69
|
+
"scenario_id": {"type": "string", "pattern": "^scenario\\.[a-z0-9][a-z0-9-]*$"},
|
|
70
|
+
"actor": {"type": "string", "minLength": 1},
|
|
71
|
+
"preconditions": {"type": "array", "items": {"type": "string"}},
|
|
72
|
+
"commands": {"type": "array", "minItems": 1, "items": {"type": "string"}},
|
|
73
|
+
"rules": {"type": "array", "minItems": 1, "items": {"type": "string"}},
|
|
74
|
+
"events": {"type": "array", "items": {"type": "string"}},
|
|
75
|
+
"failure_results": {"type": "array", "minItems": 1, "items": {"type": "string"}},
|
|
76
|
+
"responsible_context": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
|
|
77
|
+
"consumers": {"type": "array", "items": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"}},
|
|
78
|
+
"status": {"enum": ["candidate", "confirmed", "stale"]}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"concept": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"required": ["concept_id", "name", "context_id", "identity_features", "lifecycle", "confidence", "status"],
|
|
84
|
+
"properties": {
|
|
85
|
+
"concept_id": {"type": "string", "pattern": "^domain-concept\\.[a-z0-9][a-z0-9-]*$"},
|
|
86
|
+
"name": {"type": "string", "minLength": 1},
|
|
87
|
+
"context_id": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
|
|
88
|
+
"identity_features": {"type": "array", "minItems": 1, "items": {"type": "string"}},
|
|
89
|
+
"lifecycle": {"type": "array", "minItems": 1, "items": {"type": "string"}},
|
|
90
|
+
"invariant_refs": {"type": "array", "items": {"type": "string"}},
|
|
91
|
+
"possible_tactical_role": {"type": "string"},
|
|
92
|
+
"confidence": {"enum": ["low", "medium", "high"]},
|
|
93
|
+
"status": {"enum": ["candidate", "confirmed", "stale"]}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
"invariant": {
|
|
97
|
+
"type": "object",
|
|
98
|
+
"required": ["invariant_id", "statement", "responsible_context", "scenario_refs", "verification_method"],
|
|
99
|
+
"properties": {
|
|
100
|
+
"invariant_id": {"type": "string", "pattern": "^invariant\\.[a-z0-9][a-z0-9-]*$"},
|
|
101
|
+
"statement": {"type": "string", "minLength": 1},
|
|
102
|
+
"responsible_context": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
|
|
103
|
+
"scenario_refs": {"type": "array", "minItems": 1, "items": {"type": "string"}},
|
|
104
|
+
"verification_method": {"type": "string", "minLength": 1}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"mapping": {
|
|
108
|
+
"type": "object",
|
|
109
|
+
"required": ["domain_change", "impacts", "propagation", "reapproval_condition"],
|
|
110
|
+
"properties": {
|
|
111
|
+
"domain_change": {"type": "string", "minLength": 1},
|
|
112
|
+
"impacts": {"type": "array", "minItems": 1, "items": {"type": "string"}},
|
|
113
|
+
"propagation": {"enum": ["direct", "transitive", "stale"]},
|
|
114
|
+
"reapproval_condition": {"type": "string", "minLength": 1}
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"approval": {
|
|
118
|
+
"type": "object",
|
|
119
|
+
"required": ["approval_ref", "approver", "persisted_ref", "current_version"],
|
|
120
|
+
"properties": {
|
|
121
|
+
"approval_ref": {"type": "string", "minLength": 1},
|
|
122
|
+
"approver": {"type": "string", "minLength": 1},
|
|
123
|
+
"persisted_ref": {"type": "string", "minLength": 1},
|
|
124
|
+
"current_version": {"type": "string", "pattern": "^v[0-9]+$"}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package-contract.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# 阶段决策包合同
|
|
2
|
+
|
|
3
|
+
`stage_decision_package` 是 Discovery、需求/产品/商务决策与 DDD 战略设计之间的冻结入口。它记录“做什么、为什么做、范围是什么、哪些仍未决”,不复制领域模型事实。
|
|
4
|
+
|
|
5
|
+
## 必须包含
|
|
6
|
+
|
|
7
|
+
- 问题陈述、目标用户、MVP、非目标、成功标准和可执行的测试 seam;
|
|
8
|
+
- 已确认决策、假设、约束和未决项;
|
|
9
|
+
- `domain_strategy_ref`:领域战略合同的稳定 ID、版本、digest 和批准状态;
|
|
10
|
+
- UI/API/Data/Backend/Frontend/跨仓/高风险影响面布尔值;
|
|
11
|
+
- 每个下游消费者的传播方式、重新批准条件、证据引用和批准记录。`approval.approval_ref` 必须指向可读取且通过 `scripts/verify-approval-record` 的 `gate.stage-decision-package-approved` 会签记录;`approval.approver` 必须与记录中的 `role_id` 一致。
|
|
12
|
+
|
|
13
|
+
## 未决项规则
|
|
14
|
+
|
|
15
|
+
`blocker` 必须阻断批准;`deferred` 必须同时记录责任人、下一动作和目标版本/发布日期。没有责任人或恢复路径的未决项不得隐藏在备注中。
|
|
16
|
+
|
|
17
|
+
## 下游消费规则
|
|
18
|
+
|
|
19
|
+
只有 `approved` 且引用的领域战略为 `approved`、版本当前的阶段包,才可以进入 Spec synthesis。任何领域战略 digest、版本或影响面变化都使阶段包 `stale`,并要求重新评估。
|
package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package.schema.json
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://yss.local/schemas/stage-decision-package-v1.json",
|
|
4
|
+
"title": "YSS Stage Decision Package",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["schema_version", "stage_decision_id", "package_version", "status", "problem_statement", "target_users", "mvp", "non_goals", "success_criteria", "test_seams", "confirmed_decisions", "assumptions", "constraints", "unresolved_items", "terminology_refs", "domain_strategy_ref", "impact_assessment", "downstream_mapping", "evidence_refs", "approval"],
|
|
7
|
+
"properties": {
|
|
8
|
+
"schema_version": {"const": 1},
|
|
9
|
+
"stage_decision_id": {"type": "string", "pattern": "^stage-decision\\.[a-z0-9][a-z0-9-]*$"},
|
|
10
|
+
"package_version": {"type": "string", "pattern": "^v[0-9]+$"},
|
|
11
|
+
"status": {"enum": ["draft", "ready-for-human", "approved", "stale", "blocked"]},
|
|
12
|
+
"problem_statement": {"type": "string", "minLength": 1},
|
|
13
|
+
"target_users": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
|
|
14
|
+
"mvp": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
|
|
15
|
+
"non_goals": {"type": "array", "items": {"type": "string", "minLength": 1}},
|
|
16
|
+
"success_criteria": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
|
|
17
|
+
"test_seams": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
|
|
18
|
+
"confirmed_decisions": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
|
|
19
|
+
"assumptions": {"type": "array", "items": {"type": "string", "minLength": 1}},
|
|
20
|
+
"constraints": {"type": "array", "items": {"type": "string", "minLength": 1}},
|
|
21
|
+
"unresolved_items": {"type": "array", "items": {"$ref": "#/$defs/unresolved"}},
|
|
22
|
+
"terminology_refs": {"type": "array", "items": {"type": "string", "minLength": 1}},
|
|
23
|
+
"domain_strategy_ref": {"$ref": "#/$defs/domainRef"},
|
|
24
|
+
"impact_assessment": {"$ref": "#/$defs/impact"},
|
|
25
|
+
"downstream_mapping": {"type": "array", "minItems": 1, "items": {"$ref": "#/$defs/mapping"}},
|
|
26
|
+
"evidence_refs": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
|
|
27
|
+
"approval": {"$ref": "#/$defs/approval"}
|
|
28
|
+
},
|
|
29
|
+
"$defs": {
|
|
30
|
+
"unresolved": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"required": ["item", "type", "owner", "next_action", "target_version"],
|
|
33
|
+
"properties": {
|
|
34
|
+
"item": {"type": "string", "minLength": 1},
|
|
35
|
+
"type": {"enum": ["blocker", "deferred"]},
|
|
36
|
+
"owner": {"type": "string", "minLength": 1},
|
|
37
|
+
"next_action": {"type": "string", "minLength": 1},
|
|
38
|
+
"target_version": {"type": "string", "minLength": 1}
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"domainRef": {
|
|
42
|
+
"type": "object",
|
|
43
|
+
"required": ["domain_strategy_id", "domain_version", "digest", "status", "persisted_ref"],
|
|
44
|
+
"properties": {
|
|
45
|
+
"domain_strategy_id": {"type": "string", "pattern": "^domain-strategy\\.[a-z0-9][a-z0-9-]*$"},
|
|
46
|
+
"domain_version": {"type": "string", "pattern": "^v[0-9]+$"},
|
|
47
|
+
"digest": {"type": "string", "minLength": 1},
|
|
48
|
+
"status": {"enum": ["approved", "stale", "blocked"]},
|
|
49
|
+
"persisted_ref": {"type": "string", "minLength": 1}
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"impact": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"required": ["ui", "api", "data", "backend", "frontend", "cross_repo", "high_risk"],
|
|
55
|
+
"properties": {
|
|
56
|
+
"ui": {"type": "boolean"},
|
|
57
|
+
"api": {"type": "boolean"},
|
|
58
|
+
"data": {"type": "boolean"},
|
|
59
|
+
"backend": {"type": "boolean"},
|
|
60
|
+
"frontend": {"type": "boolean"},
|
|
61
|
+
"cross_repo": {"type": "boolean"},
|
|
62
|
+
"high_risk": {"type": "boolean"}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"mapping": {
|
|
66
|
+
"type": "object",
|
|
67
|
+
"required": ["domain_change", "consumer", "propagation", "reapproval_condition"],
|
|
68
|
+
"properties": {
|
|
69
|
+
"domain_change": {"type": "string", "minLength": 1},
|
|
70
|
+
"consumer": {"type": "string", "minLength": 1},
|
|
71
|
+
"propagation": {"enum": ["direct", "transitive", "not-applicable", "stale"]},
|
|
72
|
+
"reapproval_condition": {"type": "string", "minLength": 1}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"approval": {
|
|
76
|
+
"type": "object",
|
|
77
|
+
"required": ["approval_ref", "approver", "persisted_ref", "current_version"],
|
|
78
|
+
"properties": {
|
|
79
|
+
"approval_ref": {"type": "string", "minLength": 1},
|
|
80
|
+
"approver": {"type": "string", "minLength": 1},
|
|
81
|
+
"persisted_ref": {"type": "string", "minLength": 1},
|
|
82
|
+
"current_version": {"type": "string", "pattern": "^v[0-9]+$"}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# 验证规则
|
|
2
|
+
|
|
3
|
+
验证分为结构、引用和语义三层:
|
|
4
|
+
|
|
5
|
+
1. **结构**:Schema 版本、稳定 ID、状态枚举、必填字段、条件字段和证据格式。
|
|
6
|
+
2. **引用**:上下文端点、场景、不变量、术语和下游资产引用必须可解析。
|
|
7
|
+
3. **语义**:禁止关系自环、未知上下文、未批准 Shared Kernel、未解释的语义/技术方向差异、职责重叠、无责任人的不变量和跨上下文直接共享实体。
|
|
8
|
+
|
|
9
|
+
以下情况必须 `blocked`:关键规则所有权未知、关键术语冲突、上下文边界未定、关键失败场景缺失、事件语义无法解释、领域专家确认缺失。
|
|
10
|
+
|
|
11
|
+
以下变化应触发精确传播:
|
|
12
|
+
|
|
13
|
+
- 术语含义变化 → Spec、验收、原型或 API;
|
|
14
|
+
- 上下文边界变化 → 系统架构、OpenAPI、数据和切片;
|
|
15
|
+
- Context Map 关系变化 → 集成契约和模型翻译;
|
|
16
|
+
- 不变量变化 → 测试 seam、实现合同和验证策略。
|
|
17
|
+
|
|
18
|
+
验证器允许“语义方向 ≠ 技术方向”,但要求 `direction_explanation` 和翻译责任非空。
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { parseDocument } from "../../../../scripts/vendor/yaml.mjs";
|
|
5
|
+
import { loadApprovalRecord, resolveApprovalRef, validateApprovalRecordFile } from "../../../../scripts/lib/approval-record.mjs";
|
|
6
|
+
|
|
7
|
+
const required = ["schema_version", "domain_strategy_id", "domain_version", "status", "contexts", "subdomains", "relationships", "scenarios", "concept_candidates", "invariants", "terminology_refs", "downstream_mapping", "evidence_refs", "approval"];
|
|
8
|
+
const idPatterns = {
|
|
9
|
+
context_id: /^[A-Z][A-Za-z0-9]+$/,
|
|
10
|
+
domain_strategy_id: /^domain-strategy\.[a-z0-9][a-z0-9-]*$/,
|
|
11
|
+
subdomain_id: /^subdomain\.[a-z0-9][a-z0-9-]*$/,
|
|
12
|
+
relationship_id: /^relationship\.[a-z0-9][a-z0-9-]*$/,
|
|
13
|
+
scenario_id: /^scenario\.[a-z0-9][a-z0-9-]*$/,
|
|
14
|
+
concept_id: /^domain-concept\.[a-z0-9][a-z0-9-]*$/,
|
|
15
|
+
invariant_id: /^invariant\.[a-z0-9][a-z0-9-]*$/
|
|
16
|
+
};
|
|
17
|
+
const relationshipPatterns = new Set(["Partnership", "Customer/Supplier", "Conformist", "Anti-Corruption Layer", "Open Host Service", "Published Language", "Shared Kernel", "Separate Ways"]);
|
|
18
|
+
|
|
19
|
+
function fail(errors) {
|
|
20
|
+
process.stderr.write(`${JSON.stringify({ result: "blocked", errors }, null, 2)}\n`);
|
|
21
|
+
process.exitCode = 1;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function nonEmpty(value) { return typeof value === "string" && value.trim().length > 0; }
|
|
25
|
+
function list(value) { return Array.isArray(value); }
|
|
26
|
+
function unique(items, label, errors) {
|
|
27
|
+
const seen = new Set();
|
|
28
|
+
for (const item of items) {
|
|
29
|
+
if (seen.has(item)) errors.push(`${label} 重复: ${item}`);
|
|
30
|
+
seen.add(item);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function requireField(object, field, path, errors) {
|
|
34
|
+
if (!(field in object) || object[field] === null || object[field] === undefined) errors.push(`${path}.${field} 缺失`);
|
|
35
|
+
}
|
|
36
|
+
function requireString(object, field, path, errors) {
|
|
37
|
+
requireField(object, field, path, errors);
|
|
38
|
+
if (field in object && !nonEmpty(object[field])) errors.push(`${path}.${field} 必须是非空字符串`);
|
|
39
|
+
}
|
|
40
|
+
function requireArray(object, field, path, errors, min = 0, itemKind = "string") {
|
|
41
|
+
requireField(object, field, path, errors);
|
|
42
|
+
if (field in object && (!list(object[field]) || object[field].length < min)) errors.push(`${path}.${field} 必须是至少 ${min} 项的数组`);
|
|
43
|
+
if (field in object && list(object[field]) && itemKind === "string") object[field].forEach((item, index) => { if (!nonEmpty(item)) errors.push(`${path}.${field}[${index}] 必须是非空字符串`); });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function validate(data) {
|
|
47
|
+
const errors = [];
|
|
48
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) return ["合同必须是对象"];
|
|
49
|
+
for (const field of required) requireField(data, field, "root", errors);
|
|
50
|
+
if (data.schema_version !== 1) errors.push("schema_version 必须为 1");
|
|
51
|
+
if (!idPatterns.domain_strategy_id.test(String(data.domain_strategy_id ?? ""))) errors.push("domain_strategy_id 格式非法");
|
|
52
|
+
if (!/^v[0-9]+$/.test(String(data.domain_version ?? ""))) errors.push("domain_version 必须形如 v1");
|
|
53
|
+
if (!["draft", "ready-for-human", "approved", "stale", "blocked"].includes(data.status)) errors.push("status 非法");
|
|
54
|
+
|
|
55
|
+
requireArray(data, "contexts", "root", errors, 1, "object");
|
|
56
|
+
const contexts = list(data.contexts) ? data.contexts : [];
|
|
57
|
+
const contextIds = contexts.map((item) => item?.context_id).filter(Boolean);
|
|
58
|
+
unique(contextIds, "context_id", errors);
|
|
59
|
+
for (const [index, context] of contexts.entries()) {
|
|
60
|
+
const path = `contexts[${index}]`;
|
|
61
|
+
for (const field of ["context_id", "name", "owner", "status", "subdomain_type"]) requireString(context ?? {}, field, path, errors);
|
|
62
|
+
for (const field of ["responsibilities", "non_responsibilities"]) requireArray(context ?? {}, field, path, errors, field === "responsibilities" ? 1 : 0);
|
|
63
|
+
if (context?.context_id && !idPatterns.context_id.test(context.context_id)) errors.push(`${path}.context_id 格式非法`);
|
|
64
|
+
if (context?.status && !["candidate", "confirmed", "stale"].includes(context.status)) errors.push(`${path}.status 非法`);
|
|
65
|
+
if (context?.subdomain_type && !["Core Domain", "Supporting Subdomain", "Generic Subdomain"].includes(context.subdomain_type)) errors.push(`${path}.subdomain_type 非法`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
requireArray(data, "subdomains", "root", errors, 1, "object");
|
|
69
|
+
const subdomains = list(data.subdomains) ? data.subdomains : [];
|
|
70
|
+
unique(subdomains.map((item) => item?.subdomain_id).filter(Boolean), "subdomain_id", errors);
|
|
71
|
+
for (const [index, item] of subdomains.entries()) {
|
|
72
|
+
const path = `subdomains[${index}]`;
|
|
73
|
+
for (const field of ["subdomain_id", "name", "type", "rationale"]) requireString(item ?? {}, field, path, errors);
|
|
74
|
+
requireArray(item ?? {}, "evidence_refs", path, errors, 1);
|
|
75
|
+
if (item?.subdomain_id && !idPatterns.subdomain_id.test(item.subdomain_id)) errors.push(`${path}.subdomain_id 格式非法`);
|
|
76
|
+
if (item?.type && !["Core Domain", "Supporting Subdomain", "Generic Subdomain"].includes(item.type)) errors.push(`${path}.type 非法`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const relationships = list(data.relationships) ? data.relationships : [];
|
|
80
|
+
unique(relationships.map((item) => item?.relationship_id).filter(Boolean), "relationship_id", errors);
|
|
81
|
+
for (const [index, relationship] of relationships.entries()) {
|
|
82
|
+
const path = `relationships[${index}]`;
|
|
83
|
+
for (const field of ["relationship_id", "from_context", "to_context", "relationship_pattern", "semantic_upstream", "semantic_downstream", "business_authority", "model_change_impact", "transport_direction", "translation_responsibility", "direction_explanation"]) requireString(relationship ?? {}, field, path, errors);
|
|
84
|
+
if (relationship?.relationship_id && !idPatterns.relationship_id.test(relationship.relationship_id)) errors.push(`${path}.relationship_id 格式非法`);
|
|
85
|
+
for (const field of ["from_context", "to_context", "semantic_upstream", "semantic_downstream"]) {
|
|
86
|
+
if (relationship?.[field] && !contextIds.includes(relationship[field])) errors.push(`${path}.${field} 未引用已声明上下文`);
|
|
87
|
+
}
|
|
88
|
+
if (relationship?.from_context === relationship?.to_context) errors.push(`${path} 不允许上下文自环`);
|
|
89
|
+
if (relationship?.semantic_upstream && ![relationship.from_context, relationship.to_context].includes(relationship.semantic_upstream)) errors.push(`${path}.semantic_upstream 必须是关系端点`);
|
|
90
|
+
if (relationship?.semantic_downstream && ![relationship.from_context, relationship.to_context].includes(relationship.semantic_downstream)) errors.push(`${path}.semantic_downstream 必须是关系端点`);
|
|
91
|
+
if (relationship?.relationship_pattern && !relationshipPatterns.has(relationship.relationship_pattern)) errors.push(`${path}.relationship_pattern 非法`);
|
|
92
|
+
if (relationship?.relationship_pattern === "Shared Kernel" && !nonEmpty(relationship.shared_kernel_approval_ref)) errors.push(`${path} Shared Kernel 必须有 shared_kernel_approval_ref`);
|
|
93
|
+
if (relationship?.semantic_upstream && relationship?.semantic_downstream && relationship.semantic_upstream === relationship.semantic_downstream) errors.push(`${path} semantic_upstream 与 semantic_downstream 不能相同`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
requireArray(data, "scenarios", "root", errors, 1, "object");
|
|
97
|
+
const scenarios = list(data.scenarios) ? data.scenarios : [];
|
|
98
|
+
const scenarioIds = scenarios.map((item) => item?.scenario_id).filter(Boolean);
|
|
99
|
+
unique(scenarioIds, "scenario_id", errors);
|
|
100
|
+
for (const [index, scenario] of scenarios.entries()) {
|
|
101
|
+
const path = `scenarios[${index}]`;
|
|
102
|
+
for (const field of ["scenario_id", "actor", "responsible_context", "status"]) requireString(scenario ?? {}, field, path, errors);
|
|
103
|
+
for (const field of ["preconditions", "commands", "rules", "events", "failure_results", "consumers"]) requireArray(scenario ?? {}, field, path, errors, field === "commands" || field === "rules" || field === "failure_results" ? 1 : 0);
|
|
104
|
+
if (scenario?.scenario_id && !idPatterns.scenario_id.test(scenario.scenario_id)) errors.push(`${path}.scenario_id 格式非法`);
|
|
105
|
+
if (scenario?.responsible_context && !contextIds.includes(scenario.responsible_context)) errors.push(`${path}.responsible_context 未声明`);
|
|
106
|
+
for (const consumer of scenario?.consumers ?? []) if (!contextIds.includes(consumer)) errors.push(`${path}.consumers 引用了未声明上下文: ${consumer}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const concepts = list(data.concept_candidates) ? data.concept_candidates : [];
|
|
110
|
+
unique(concepts.map((item) => item?.concept_id).filter(Boolean), "concept_id", errors);
|
|
111
|
+
for (const [index, concept] of concepts.entries()) {
|
|
112
|
+
const path = `concept_candidates[${index}]`;
|
|
113
|
+
for (const field of ["concept_id", "name", "context_id", "confidence", "status"]) requireString(concept ?? {}, field, path, errors);
|
|
114
|
+
for (const field of ["identity_features", "lifecycle"]) requireArray(concept ?? {}, field, path, errors, 1);
|
|
115
|
+
if (concept?.concept_id && !idPatterns.concept_id.test(concept.concept_id)) errors.push(`${path}.concept_id 格式非法`);
|
|
116
|
+
if (concept?.context_id && !contextIds.includes(concept.context_id)) errors.push(`${path}.context_id 未声明`);
|
|
117
|
+
if (concept?.confidence && !["low", "medium", "high"].includes(concept.confidence)) errors.push(`${path}.confidence 非法`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const invariants = list(data.invariants) ? data.invariants : [];
|
|
121
|
+
unique(invariants.map((item) => item?.invariant_id).filter(Boolean), "invariant_id", errors);
|
|
122
|
+
for (const [index, invariant] of invariants.entries()) {
|
|
123
|
+
const path = `invariants[${index}]`;
|
|
124
|
+
for (const field of ["invariant_id", "statement", "responsible_context", "verification_method"]) requireString(invariant ?? {}, field, path, errors);
|
|
125
|
+
requireArray(invariant ?? {}, "scenario_refs", path, errors, 1);
|
|
126
|
+
if (invariant?.invariant_id && !idPatterns.invariant_id.test(invariant.invariant_id)) errors.push(`${path}.invariant_id 格式非法`);
|
|
127
|
+
if (invariant?.responsible_context && !contextIds.includes(invariant.responsible_context)) errors.push(`${path}.responsible_context 未声明`);
|
|
128
|
+
for (const reference of invariant?.scenario_refs ?? []) if (!scenarioIds.includes(reference)) errors.push(`${path}.scenario_refs 引用了未声明场景: ${reference}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
requireArray(data, "terminology_refs", "root", errors, 0);
|
|
132
|
+
requireArray(data, "evidence_refs", "root", errors, 1);
|
|
133
|
+
const mappings = list(data.downstream_mapping) ? data.downstream_mapping : [];
|
|
134
|
+
for (const [index, mapping] of mappings.entries()) {
|
|
135
|
+
const path = `downstream_mapping[${index}]`;
|
|
136
|
+
for (const field of ["domain_change", "propagation", "reapproval_condition"]) requireString(mapping ?? {}, field, path, errors);
|
|
137
|
+
requireArray(mapping ?? {}, "impacts", path, errors, 1);
|
|
138
|
+
if (mapping?.propagation && !["direct", "transitive", "stale"].includes(mapping.propagation)) errors.push(`${path}.propagation 非法`);
|
|
139
|
+
}
|
|
140
|
+
const approval = data.approval ?? {};
|
|
141
|
+
for (const field of ["approval_ref", "approver", "persisted_ref", "current_version"]) requireString(approval, field, "approval", errors);
|
|
142
|
+
if (data.status === "approved") {
|
|
143
|
+
if (contexts.some((context) => context.status !== "confirmed")) errors.push("approved 合同要求所有上下文 status=confirmed");
|
|
144
|
+
if (approval.current_version !== data.domain_version) errors.push("approval.current_version 必须等于 domain_version");
|
|
145
|
+
try {
|
|
146
|
+
const approvalPath = resolveApprovalRef(approval.approval_ref);
|
|
147
|
+
validateApprovalRecordFile(approvalPath, { requireApproved: true });
|
|
148
|
+
const record = loadApprovalRecord(approvalPath);
|
|
149
|
+
if (record.gate_id !== "gate.domain-strategy-approved") errors.push("approval.approval_ref 的 gate_id 必须为 gate.domain-strategy-approved");
|
|
150
|
+
if (record.role_id !== approval.approver) errors.push("approval.approver 必须与会签记录 role_id 一致");
|
|
151
|
+
} catch (error) { errors.push(`approval.approval_ref 会签记录无效: ${error.message}`); }
|
|
152
|
+
}
|
|
153
|
+
return errors;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const file = process.argv[2];
|
|
157
|
+
if (!file) fail(["用法: validate-domain-strategy.mjs <contract.yaml>"]);
|
|
158
|
+
else {
|
|
159
|
+
try {
|
|
160
|
+
const source = await readFile(file, "utf8");
|
|
161
|
+
const document = parseDocument(source, { maxAliasCount: 0, uniqueKeys: true });
|
|
162
|
+
if (document.errors.length) fail([document.errors[0].message]);
|
|
163
|
+
else {
|
|
164
|
+
const errors = validate(document.toJS({ maxAliasCount: 0 }));
|
|
165
|
+
if (errors.length) fail(errors);
|
|
166
|
+
else process.stdout.write(JSON.stringify({ result: "completed", contract: file }, null, 2) + "\n");
|
|
167
|
+
}
|
|
168
|
+
} catch (error) { fail([error.message]); }
|
|
169
|
+
}
|