create-yss-spec 2.1.3 → 2.1.5
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 +1 -1
- package/package.json +1 -1
- package/template/.agents/skills/code-review/SKILL.md +38 -10
- package/template/.agents/skills/high-fidelity-html-prototype/SKILL.md +16 -12
- package/template/.agents/skills/product-design-prototype/SKILL.md +6 -2
- package/template/.agents/skills/prototype-review/SKILL.md +6 -2
- package/template/.agents/skills/wireframe-prototype/SKILL.md +5 -1
- package/template/.agents/skills/yss-api-integration/SKILL.md +25 -7
- package/template/.agents/skills/yss-ddd-scaffold-generator/SKILL.md +3 -17
- package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +0 -30
- package/template/.agents/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +1 -1
- package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.py +1 -21
- package/template/.agents/skills/yss-design-system/SKILL.md +6 -5
- package/template/.agents/skills/yss-frontend-scaffold-generator/SKILL.md +12 -6
- package/template/.agents/skills/yss-openapi-draft-review/SKILL.md +13 -17
- package/template/.agents/skills/yss-openapi-governance/SKILL.md +89 -114
- package/template/.agents/skills/yss-openapi-governance/agents/openai.yaml +2 -2
- package/template/.agents/skills/yss-product-lifecycle/SKILL.md +13 -7
- package/template/.agents/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
- package/template/.agents/skills/yss-product-lifecycle/references/matt-yss-adapter.md +8 -2
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +77 -30
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +7 -2
- package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +8 -0
- package/template/.agents/skills/yss-prototype-stage/SKILL.md +40 -0
- package/template/.agents/skills/yss-router/SKILL.md +2 -2
- package/template/.agents/skills/yss-router/references/router-contract.yaml +9 -8
- package/template/.agents/skills/yss-router/references/slice-implementation-contract.md +4 -1
- package/template/.agents/skills/yss-router/references/yss-skill-execution-result.md +2 -1
- package/template/.claude/skills/code-review/SKILL.md +38 -10
- package/template/.claude/skills/high-fidelity-html-prototype/SKILL.md +16 -12
- package/template/.claude/skills/product-design-prototype/SKILL.md +6 -2
- package/template/.claude/skills/prototype-review/SKILL.md +6 -2
- package/template/.claude/skills/wireframe-prototype/SKILL.md +5 -1
- package/template/.claude/skills/yss-api-integration/SKILL.md +25 -7
- package/template/.claude/skills/yss-ddd-scaffold-generator/SKILL.md +3 -17
- package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +0 -30
- package/template/.claude/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +1 -1
- package/template/.claude/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.py +1 -21
- package/template/.claude/skills/yss-design-system/SKILL.md +6 -5
- package/template/.claude/skills/yss-frontend-scaffold-generator/SKILL.md +12 -6
- package/template/.claude/skills/yss-openapi-draft-review/SKILL.md +13 -17
- package/template/.claude/skills/yss-openapi-governance/SKILL.md +89 -114
- package/template/.claude/skills/yss-openapi-governance/agents/openai.yaml +2 -2
- package/template/.claude/skills/yss-product-lifecycle/SKILL.md +13 -7
- package/template/.claude/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
- package/template/.claude/skills/yss-product-lifecycle/references/matt-yss-adapter.md +8 -2
- package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +77 -30
- package/template/.claude/skills/yss-product-lifecycle/references/orchestration.md +7 -2
- package/template/.claude/skills/yss-product-lifecycle/references/state-model.md +8 -0
- package/template/.claude/skills/yss-prototype-stage/SKILL.md +40 -0
- package/template/.claude/skills/yss-router/SKILL.md +2 -2
- package/template/.claude/skills/yss-router/references/router-contract.yaml +9 -8
- package/template/.claude/skills/yss-router/references/slice-implementation-contract.md +4 -1
- package/template/.claude/skills/yss-router/references/yss-skill-execution-result.md +2 -1
- package/template/.codex/skills/code-review/SKILL.md +38 -10
- package/template/.codex/skills/high-fidelity-html-prototype/SKILL.md +16 -12
- package/template/.codex/skills/product-design-prototype/SKILL.md +6 -2
- package/template/.codex/skills/prototype-review/SKILL.md +6 -2
- package/template/.codex/skills/wireframe-prototype/SKILL.md +5 -1
- package/template/.codex/skills/yss-api-integration/SKILL.md +25 -7
- package/template/.codex/skills/yss-ddd-scaffold-generator/SKILL.md +3 -17
- package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +0 -30
- package/template/.codex/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +1 -1
- package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.py +1 -21
- package/template/.codex/skills/yss-design-system/SKILL.md +6 -5
- package/template/.codex/skills/yss-frontend-scaffold-generator/SKILL.md +12 -6
- package/template/.codex/skills/yss-openapi-draft-review/SKILL.md +13 -17
- package/template/.codex/skills/yss-openapi-governance/SKILL.md +89 -114
- package/template/.codex/skills/yss-openapi-governance/agents/openai.yaml +2 -2
- package/template/.codex/skills/yss-product-lifecycle/SKILL.md +13 -7
- package/template/.codex/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
- package/template/.codex/skills/yss-product-lifecycle/references/matt-yss-adapter.md +8 -2
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +77 -30
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +7 -2
- package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +8 -0
- package/template/.codex/skills/yss-prototype-stage/SKILL.md +40 -0
- package/template/.codex/skills/yss-router/SKILL.md +2 -2
- package/template/.codex/skills/yss-router/references/router-contract.yaml +9 -8
- package/template/.codex/skills/yss-router/references/slice-implementation-contract.md +4 -1
- package/template/.codex/skills/yss-router/references/yss-skill-execution-result.md +2 -1
- package/template/.hermes/skills/code-review/SKILL.md +38 -10
- package/template/.hermes/skills/high-fidelity-html-prototype/SKILL.md +16 -12
- package/template/.hermes/skills/product-design-prototype/SKILL.md +6 -2
- package/template/.hermes/skills/prototype-review/SKILL.md +6 -2
- package/template/.hermes/skills/wireframe-prototype/SKILL.md +5 -1
- package/template/.hermes/skills/yss-api-integration/SKILL.md +25 -7
- package/template/.hermes/skills/yss-ddd-scaffold-generator/SKILL.md +3 -17
- package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +0 -30
- package/template/.hermes/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +1 -1
- package/template/.hermes/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.py +1 -21
- package/template/.hermes/skills/yss-design-system/SKILL.md +6 -5
- package/template/.hermes/skills/yss-frontend-scaffold-generator/SKILL.md +12 -6
- package/template/.hermes/skills/yss-openapi-draft-review/SKILL.md +13 -17
- package/template/.hermes/skills/yss-openapi-governance/SKILL.md +89 -114
- package/template/.hermes/skills/yss-openapi-governance/agents/openai.yaml +2 -2
- package/template/.hermes/skills/yss-product-lifecycle/SKILL.md +13 -7
- package/template/.hermes/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
- package/template/.hermes/skills/yss-product-lifecycle/references/matt-yss-adapter.md +8 -2
- package/template/.hermes/skills/yss-product-lifecycle/references/orchestration-contract.yaml +77 -30
- package/template/.hermes/skills/yss-product-lifecycle/references/orchestration.md +7 -2
- package/template/.hermes/skills/yss-product-lifecycle/references/state-model.md +8 -0
- package/template/.hermes/skills/yss-prototype-stage/SKILL.md +40 -0
- package/template/.hermes/skills/yss-router/SKILL.md +2 -2
- package/template/.hermes/skills/yss-router/references/router-contract.yaml +9 -8
- package/template/.hermes/skills/yss-router/references/slice-implementation-contract.md +4 -1
- package/template/.hermes/skills/yss-router/references/yss-skill-execution-result.md +2 -1
- package/template/.pi/skills/code-review/SKILL.md +38 -10
- package/template/.pi/skills/high-fidelity-html-prototype/SKILL.md +16 -12
- package/template/.pi/skills/product-design-prototype/SKILL.md +6 -2
- package/template/.pi/skills/prototype-review/SKILL.md +6 -2
- package/template/.pi/skills/wireframe-prototype/SKILL.md +5 -1
- package/template/.pi/skills/yss-api-integration/SKILL.md +25 -7
- package/template/.pi/skills/yss-ddd-scaffold-generator/SKILL.md +3 -17
- package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +0 -30
- package/template/.pi/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +1 -1
- package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.py +1 -21
- package/template/.pi/skills/yss-design-system/SKILL.md +6 -5
- package/template/.pi/skills/yss-frontend-scaffold-generator/SKILL.md +12 -6
- package/template/.pi/skills/yss-openapi-draft-review/SKILL.md +13 -17
- package/template/.pi/skills/yss-openapi-governance/SKILL.md +89 -114
- package/template/.pi/skills/yss-openapi-governance/agents/openai.yaml +2 -2
- package/template/.pi/skills/yss-product-lifecycle/SKILL.md +13 -7
- package/template/.pi/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
- package/template/.pi/skills/yss-product-lifecycle/references/matt-yss-adapter.md +8 -2
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +77 -30
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +7 -2
- package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +8 -0
- package/template/.pi/skills/yss-prototype-stage/SKILL.md +40 -0
- package/template/.pi/skills/yss-router/SKILL.md +2 -2
- package/template/.pi/skills/yss-router/references/router-contract.yaml +9 -8
- package/template/.pi/skills/yss-router/references/slice-implementation-contract.md +4 -1
- package/template/.pi/skills/yss-router/references/yss-skill-execution-result.md +2 -1
- package/template/.qoder/skills/code-review/SKILL.md +38 -10
- package/template/.qoder/skills/high-fidelity-html-prototype/SKILL.md +16 -12
- package/template/.qoder/skills/product-design-prototype/SKILL.md +6 -2
- package/template/.qoder/skills/prototype-review/SKILL.md +6 -2
- package/template/.qoder/skills/wireframe-prototype/SKILL.md +5 -1
- package/template/.qoder/skills/yss-api-integration/SKILL.md +25 -7
- package/template/.qoder/skills/yss-ddd-scaffold-generator/SKILL.md +3 -17
- package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +0 -30
- package/template/.qoder/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +1 -1
- package/template/.qoder/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.py +1 -21
- package/template/.qoder/skills/yss-design-system/SKILL.md +6 -5
- package/template/.qoder/skills/yss-frontend-scaffold-generator/SKILL.md +12 -6
- package/template/.qoder/skills/yss-openapi-draft-review/SKILL.md +13 -17
- package/template/.qoder/skills/yss-openapi-governance/SKILL.md +89 -114
- package/template/.qoder/skills/yss-openapi-governance/agents/openai.yaml +2 -2
- package/template/.qoder/skills/yss-product-lifecycle/SKILL.md +13 -7
- package/template/.qoder/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
- package/template/.qoder/skills/yss-product-lifecycle/references/matt-yss-adapter.md +8 -2
- package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +77 -30
- package/template/.qoder/skills/yss-product-lifecycle/references/orchestration.md +7 -2
- package/template/.qoder/skills/yss-product-lifecycle/references/state-model.md +8 -0
- package/template/.qoder/skills/yss-prototype-stage/SKILL.md +40 -0
- package/template/.qoder/skills/yss-router/SKILL.md +2 -2
- package/template/.qoder/skills/yss-router/references/router-contract.yaml +9 -8
- package/template/.qoder/skills/yss-router/references/slice-implementation-contract.md +4 -1
- package/template/.qoder/skills/yss-router/references/yss-skill-execution-result.md +2 -1
- package/template/.trae/skills/code-review/SKILL.md +38 -10
- package/template/.trae/skills/high-fidelity-html-prototype/SKILL.md +16 -12
- package/template/.trae/skills/product-design-prototype/SKILL.md +6 -2
- package/template/.trae/skills/prototype-review/SKILL.md +6 -2
- package/template/.trae/skills/wireframe-prototype/SKILL.md +5 -1
- package/template/.trae/skills/yss-api-integration/SKILL.md +25 -7
- package/template/.trae/skills/yss-ddd-scaffold-generator/SKILL.md +3 -17
- package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +0 -30
- package/template/.trae/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md +1 -1
- package/template/.trae/skills/yss-ddd-scaffold-generator/scripts/generate_scaffold.py +1 -21
- package/template/.trae/skills/yss-design-system/SKILL.md +6 -5
- package/template/.trae/skills/yss-frontend-scaffold-generator/SKILL.md +12 -6
- package/template/.trae/skills/yss-openapi-draft-review/SKILL.md +13 -17
- package/template/.trae/skills/yss-openapi-governance/SKILL.md +89 -114
- package/template/.trae/skills/yss-openapi-governance/agents/openai.yaml +2 -2
- package/template/.trae/skills/yss-product-lifecycle/SKILL.md +13 -7
- package/template/.trae/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
- package/template/.trae/skills/yss-product-lifecycle/references/matt-yss-adapter.md +8 -2
- package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +77 -30
- package/template/.trae/skills/yss-product-lifecycle/references/orchestration.md +7 -2
- package/template/.trae/skills/yss-product-lifecycle/references/state-model.md +8 -0
- package/template/.trae/skills/yss-prototype-stage/SKILL.md +40 -0
- package/template/.trae/skills/yss-router/SKILL.md +2 -2
- package/template/.trae/skills/yss-router/references/router-contract.yaml +9 -8
- package/template/.trae/skills/yss-router/references/slice-implementation-contract.md +4 -1
- package/template/.trae/skills/yss-router/references/yss-skill-execution-result.md +2 -1
- package/template/AGENTS.md +7 -5
- package/template/CONTEXT.md +15 -1
- package/template/README.md +2 -1
- package/template/__yss_dotfile__.gitignore +4 -0
- package/template/docs/adr/0001-product-design-prototype-entrypoint.md +1 -1
- package/template/docs/adr/0003-machine-readable-lifecycle-registry.md +5 -0
- package/template/docs/adr/0004-split-lifecycle-and-router-registry-domains.md +5 -0
- package/template/docs/adr/0005-cross-repository-ecosystem-release-manifest.md +5 -0
- package/template/docs/adr/0006-stable-lifecycle-ids-and-generated-structure.md +5 -0
- package/template/docs/adr/0007-separate-skill-routing-registry-from-integrity-lock.md +5 -0
- package/template/docs/agents/issue-tracker.md +1 -0
- package/template/docs/api/templates/openapi-draft-review-checklist.md +8 -6
- package/template/docs/api/templates/openapi-freeze-record-template.md +8 -2
- package/template/docs/api/templates/openapi-json-export-record-template.md +60 -0
- package/template/docs/architecture/templates/architecture-review-checklist.md +6 -19
- package/template/docs/architecture/templates/functional-architecture-template.md +4 -4
- package/template/docs/architecture/templates/system-overview-design-template.md +10 -5
- package/template/docs/architecture/templates/tech-design-template.md +4 -11
- package/template/docs/design/README.md +4 -2
- package/template/docs/design/design.md +4 -0
- package/template/docs/design/templates/interaction-spec-template.md +3 -3
- package/template/docs/design/templates/prototype-confirmation-template.md +9 -6
- package/template/docs/design/templates/prototype-evidence-template.yaml +46 -0
- package/template/docs/design/templates/prototype-review-checklist.md +4 -4
- package/template/docs/discovery/templates/discovery-template.md +0 -1
- package/template/docs/implementation/create-yss-spec-repository-mode-contract.md +2 -2
- package/template/docs/process/harness-process-tailoring.md +2 -0
- package/template/docs/process/harness-work-unit-map.md +14 -10
- package/template/docs/process/lifecycle-artifact-map.md +84 -39
- package/template/docs/process/lifecycle-registry-baseline.json +70 -0
- package/template/docs/process/lifecycle-registry.yaml +289 -0
- package/template/docs/process/schemas/lifecycle-registry.schema.json +35 -0
- package/template/docs/reviews/lifecycle-registry-phase0-1-red-green-2026-08-17.md +61 -0
- package/template/docs/reviews/matt-yss-p0-ticket-review-git-red-green-2026-08-17.md +91 -0
- package/template/docs/reviews/openapi-skill-primary-source-research-2026-08-16.md +76 -0
- package/template/docs/reviews/openapi-yaml-first-independent-review-2026-08-16.md +121 -0
- package/template/docs/reviews/openapi-yaml-first-pressure-scenarios-2026-08-16.md +191 -0
- package/template/docs/reviews/openapi-yaml-first-red-green-2026-08-16.md +76 -0
- package/template/docs/reviews/openapi-yaml-json-output-independent-review-2026-08-16.md +30 -0
- package/template/docs/reviews/openapi-yaml-json-output-scope-red-green-2026-08-16.md +154 -0
- package/template/docs/reviews/research-create-yss-spec-refresh-2026-08-16.md +164 -0
- package/template/docs/reviews/security-permission-lifecycle-simplification-red-green-2026-08-16.md +43 -0
- package/template/docs/reviews/template-release-review-remediation-red-green-2026-08-17.md +41 -0
- package/template/docs/templates/agent-brief-template.md +2 -2
- package/template/docs/templates/build-architecture-checklist-template.md +3 -4
- package/template/docs/templates/implementation-repo-registry-template.md +0 -2
- package/template/docs/templates/implementation-routing-template.md +6 -6
- package/template/docs/templates/openapi-spec-template.yaml +0 -6
- package/template/docs/templates/review-report-template.md +2 -1
- package/template/docs/templates/spec-delta-template.md +1 -1
- package/template/docs/templates/spec-template.md +0 -1
- package/template/docs/templates/vertical-slice-ticket-template.md +2 -2
- package/template/docs/user-guide//344/272/247/345/223/201/347/224/237/345/221/275/345/221/250/346/234/237/345/267/245/344/275/234/346/265/201.md +6 -6
- package/template/docs/user-guide//344/272/247/345/223/201/347/240/224/345/217/221/345/205/250/347/224/237/345/221/275/345/221/250/346/234/237/346/234/200/344/275/263/345/256/236/350/267/265.md +3 -3
- package/template/docs/user-guide//345/244/226/351/203/250/345/221/275/344/273/244/350/241/214/345/267/245/345/205/267/345/256/236/350/267/265/346/214/207/345/215/227.md +1 -1
- package/template/docs/user-guide//347/224/237/345/221/275/345/221/250/346/234/237/346/234/200/344/275/263/345/256/236/350/267/265.md +1 -1
- package/template/scripts/generate-lifecycle-artifacts +26 -0
- package/template/scripts/lifecycle-registry.rb +194 -0
- package/template/scripts/sync-skills +1 -0
- package/template/scripts/test-export-yss-skills.rb +10 -6
- package/template/scripts/test-lifecycle-registry.rb +74 -0
- package/template/scripts/update-skill-lock +1 -0
- package/template/scripts/verify-governance-release +39 -0
- package/template/scripts/verify-lifecycle-registry +67 -0
- package/template/scripts/verify-lifecycle-scenarios +193 -23
- package/template/scripts/verify-matt-yss-integration-scenarios +297 -1
- package/template/scripts/verify-openapi-json-handoff-scenarios +270 -0
- package/template/scripts/verify-openapi-yaml-first-scenarios +120 -0
- package/template/scripts/verify-prototype-backend-scaffold-scenarios +26 -4
- package/template/scripts/verify-template +27 -3
- package/template/scripts/verify-yss-router-scenarios +51 -14
- package/template/skills-lock.json +25 -25
- package/template/wiki/raw/skills-lock.json +0 -15
- package/template/wiki/wiki/OpenAPI/345/245/221/347/272/246.md +1 -1
- package/template/wiki/wiki/YSS/345/267/245/347/250/213/346/212/200/350/203/275/344/275/223/347/263/273.md +1 -1
- package/template/yss-public-skills.json +5 -5
- package/template.snapshot.json +4 -4
- package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/config/smart-doc.json.template +0 -17
- package/template/.agents/skills/yss-openapi/SKILL.md +0 -116
- package/template/.agents/skills/yss-openapi/agents/openai.yaml +0 -4
- package/template/.agents/skills/yss-openapi/img.png +0 -0
- package/template/.agents/skills/yss-openapi/img_1.png +0 -0
- package/template/.claude/skills/yss-ddd-scaffold-generator/assets/templates/config/smart-doc.json.template +0 -17
- package/template/.claude/skills/yss-openapi/SKILL.md +0 -116
- package/template/.claude/skills/yss-openapi/agents/openai.yaml +0 -4
- package/template/.claude/skills/yss-openapi/img.png +0 -0
- package/template/.claude/skills/yss-openapi/img_1.png +0 -0
- package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/config/smart-doc.json.template +0 -17
- package/template/.codex/skills/yss-openapi/SKILL.md +0 -116
- package/template/.codex/skills/yss-openapi/agents/openai.yaml +0 -4
- package/template/.codex/skills/yss-openapi/img.png +0 -0
- package/template/.codex/skills/yss-openapi/img_1.png +0 -0
- package/template/.hermes/skills/yss-ddd-scaffold-generator/assets/templates/config/smart-doc.json.template +0 -17
- package/template/.hermes/skills/yss-openapi/SKILL.md +0 -116
- package/template/.hermes/skills/yss-openapi/agents/openai.yaml +0 -4
- package/template/.hermes/skills/yss-openapi/img.png +0 -0
- package/template/.hermes/skills/yss-openapi/img_1.png +0 -0
- package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/config/smart-doc.json.template +0 -17
- package/template/.pi/skills/yss-openapi/SKILL.md +0 -116
- package/template/.pi/skills/yss-openapi/agents/openai.yaml +0 -4
- package/template/.pi/skills/yss-openapi/img.png +0 -0
- package/template/.pi/skills/yss-openapi/img_1.png +0 -0
- package/template/.qoder/skills/yss-ddd-scaffold-generator/assets/templates/config/smart-doc.json.template +0 -17
- package/template/.qoder/skills/yss-openapi/SKILL.md +0 -116
- package/template/.qoder/skills/yss-openapi/agents/openai.yaml +0 -4
- package/template/.qoder/skills/yss-openapi/img.png +0 -0
- package/template/.qoder/skills/yss-openapi/img_1.png +0 -0
- package/template/.trae/skills/yss-ddd-scaffold-generator/assets/templates/config/smart-doc.json.template +0 -17
- package/template/.trae/skills/yss-openapi/SKILL.md +0 -116
- package/template/.trae/skills/yss-openapi/agents/openai.yaml +0 -4
- package/template/.trae/skills/yss-openapi/img.png +0 -0
- package/template/.trae/skills/yss-openapi/img_1.png +0 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "pathname"
|
|
5
|
+
require "json"
|
|
6
|
+
require "digest"
|
|
7
|
+
require "yaml"
|
|
8
|
+
|
|
9
|
+
module LifecycleRegistry
|
|
10
|
+
ROOT = Pathname.new(__dir__).join("..").realpath
|
|
11
|
+
DEFAULT_REGISTRY = ROOT.join("docs/process/lifecycle-registry.yaml")
|
|
12
|
+
DEFAULT_BASELINE = ROOT.join("docs/process/lifecycle-registry-baseline.json")
|
|
13
|
+
ID_PATTERN = /\A(stage|gate|artifact|work-unit|evidence)\.[a-z0-9][a-z0-9-]*\z/
|
|
14
|
+
|
|
15
|
+
module_function
|
|
16
|
+
|
|
17
|
+
def load_registry(path = DEFAULT_REGISTRY)
|
|
18
|
+
YAML.safe_load(Pathname.new(path).read, permitted_classes: [], aliases: false)
|
|
19
|
+
rescue Psych::Exception => error
|
|
20
|
+
raise ArgumentError, "无法解析生命周期注册表: #{error.message}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def validate!(registry, baseline: DEFAULT_BASELINE)
|
|
24
|
+
required_top_level = %w[schema_version registry_id status id_policy stages gates artifacts work_units evidence]
|
|
25
|
+
missing = required_top_level - registry.keys
|
|
26
|
+
raise ArgumentError, "生命周期注册表缺少字段: #{missing.join(', ')}" unless missing.empty?
|
|
27
|
+
raise ArgumentError, "仅支持 lifecycle registry schema_version: 1" unless registry["schema_version"] == 1
|
|
28
|
+
raise ArgumentError, "registry_id 必须为 yss.lifecycle" unless registry["registry_id"] == "yss.lifecycle"
|
|
29
|
+
raise ArgumentError, "status 必须为 shadow 或 active" unless %w[shadow active].include?(registry["status"])
|
|
30
|
+
|
|
31
|
+
policy = registry.fetch("id_policy")
|
|
32
|
+
%w[pattern published_ids_immutable baseline deprecated_ids].each do |key|
|
|
33
|
+
raise ArgumentError, "id_policy 缺少字段: #{key}" unless policy.key?(key)
|
|
34
|
+
end
|
|
35
|
+
raise ArgumentError, "published_ids_immutable 必须为 true" unless policy["published_ids_immutable"] == true
|
|
36
|
+
raise ArgumentError, "id_policy.pattern 不符合固定命名空间" unless policy["pattern"] == "^(stage|gate|artifact|work-unit|evidence)\\.[a-z0-9][a-z0-9-]*$"
|
|
37
|
+
raise ArgumentError, "id_policy.baseline 必须指向发布基线" unless policy["baseline"] == "docs/process/lifecycle-registry-baseline.json"
|
|
38
|
+
raise ArgumentError, "deprecated_ids 必须是数组" unless policy["deprecated_ids"].is_a?(Array)
|
|
39
|
+
|
|
40
|
+
ids = {}
|
|
41
|
+
%w[stages gates artifacts work_units evidence].each do |collection|
|
|
42
|
+
records = registry.fetch(collection)
|
|
43
|
+
raise ArgumentError, "#{collection} 必须是非空数组" unless records.is_a?(Array) && !records.empty?
|
|
44
|
+
records.each do |record|
|
|
45
|
+
id = record["id"]
|
|
46
|
+
raise ArgumentError, "#{collection} 中存在无效 ID: #{id.inspect}" unless id.is_a?(String) && id.match?(ID_PATTERN)
|
|
47
|
+
raise ArgumentError, "生命周期 ID 重复: #{id}" if ids.key?(id)
|
|
48
|
+
expected_prefix = collection == "work_units" ? "work-unit." : collection.delete_suffix("s") + "."
|
|
49
|
+
raise ArgumentError, "#{id} 与 #{collection} 类型不匹配" unless id.start_with?(expected_prefix)
|
|
50
|
+
raise ArgumentError, "#{id} 缺少名称" unless record["name"].is_a?(String) && !record["name"].empty?
|
|
51
|
+
ids[id] = collection
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
registry.fetch("gates").each do |gate|
|
|
56
|
+
require_reference!(ids, gate.fetch("stage"), "#{gate["id"]}.stage")
|
|
57
|
+
unless ids[gate.fetch("stage")] == "stages"
|
|
58
|
+
raise ArgumentError, "#{gate["id"]}.stage 必须引用 stage.*"
|
|
59
|
+
end
|
|
60
|
+
evidence = gate.fetch("evidence")
|
|
61
|
+
raise ArgumentError, "#{gate["id"]}.evidence 必须是非空数组" unless evidence.is_a?(Array) && !evidence.empty?
|
|
62
|
+
evidence.each do |reference|
|
|
63
|
+
require_reference!(ids, reference, "#{gate["id"]}.evidence")
|
|
64
|
+
raise ArgumentError, "#{gate["id"]}.evidence 必须引用 evidence.*" unless ids[reference] == "evidence"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
registry.fetch("artifacts").each do |artifact|
|
|
69
|
+
require_reference!(ids, artifact.fetch("stage"), "#{artifact["id"]}.stage")
|
|
70
|
+
raise ArgumentError, "#{artifact["id"]}.stage 必须引用 stage.*" unless ids[artifact.fetch("stage")] == "stages"
|
|
71
|
+
end
|
|
72
|
+
validate_baseline!(registry, ids, Pathname.new(baseline)) if baseline
|
|
73
|
+
registry
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def require_reference!(ids, reference, field)
|
|
77
|
+
raise ArgumentError, "#{field} 引用了不存在的引用: #{reference}" unless ids.key?(reference)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def semantic_projection(registry)
|
|
81
|
+
%w[stages gates artifacts work_units evidence].flat_map do |collection|
|
|
82
|
+
registry.fetch(collection).map do |record|
|
|
83
|
+
{
|
|
84
|
+
"kind" => collection,
|
|
85
|
+
"record" => canonicalize(record)
|
|
86
|
+
}
|
|
87
|
+
end
|
|
88
|
+
end.sort_by { |entry| entry.fetch("record").fetch("id") }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def canonicalize(value)
|
|
92
|
+
case value
|
|
93
|
+
when Hash
|
|
94
|
+
value.keys.sort.to_h { |key| [key, canonicalize(value.fetch(key))] }
|
|
95
|
+
when Array
|
|
96
|
+
value.map { |item| canonicalize(item) }
|
|
97
|
+
else
|
|
98
|
+
value
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def semantic_digest(registry)
|
|
103
|
+
Digest::SHA256.hexdigest(JSON.generate(semantic_projection(registry)))
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def validate_baseline!(registry, ids, baseline_path)
|
|
107
|
+
raise ArgumentError, "缺少生命周期已发布基线: #{baseline_path.relative_path_from(ROOT)}" unless baseline_path.file?
|
|
108
|
+
baseline = JSON.parse(baseline_path.read)
|
|
109
|
+
unless baseline["schema_version"] == 1 && baseline["registry_id"] == registry["registry_id"]
|
|
110
|
+
raise ArgumentError, "生命周期已发布基线版本或 registry_id 不匹配"
|
|
111
|
+
end
|
|
112
|
+
published_ids = baseline["published_ids"]
|
|
113
|
+
raise ArgumentError, "生命周期已发布基线缺少 published_ids" unless published_ids.is_a?(Array) && published_ids.uniq == published_ids
|
|
114
|
+
published_ids.each do |id|
|
|
115
|
+
raise ArgumentError, "生命周期已发布基线包含无效 ID: #{id.inspect}" unless id.is_a?(String) && id.match?(ID_PATTERN)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
active_ids = ids.keys.sort
|
|
119
|
+
deprecated_ids = registry.fetch("id_policy").fetch("deprecated_ids")
|
|
120
|
+
unless deprecated_ids.uniq == deprecated_ids && deprecated_ids.all? { |id| published_ids.include?(id) } && (deprecated_ids & active_ids).empty?
|
|
121
|
+
raise ArgumentError, "deprecated_ids 必须唯一、来自已发布 ID,且不得仍为活跃对象"
|
|
122
|
+
end
|
|
123
|
+
expected_active_ids = (published_ids - deprecated_ids).sort
|
|
124
|
+
raise ArgumentError, "生命周期活跃 ID 与已发布基线不一致;新增、移除或弃用必须先更新发布基线" unless active_ids == expected_active_ids
|
|
125
|
+
raise ArgumentError, "生命周期稳定 ID 的语义快照已变化;不得复用已发布 ID" unless baseline["semantic_sha256"] == semantic_digest(registry)
|
|
126
|
+
rescue JSON::ParserError => error
|
|
127
|
+
raise ArgumentError, "无法解析生命周期已发布基线: #{error.message}"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def render_lifecycle_structure(registry)
|
|
131
|
+
lines = []
|
|
132
|
+
lines << "<!-- lifecycle-registry:structure:start -->"
|
|
133
|
+
lines << "> 此结构区由 `docs/process/lifecycle-registry.yaml` 生成。当前为 `#{registry.fetch("status")}` 模式:它校验结构和派生文档,不改变运行时状态 schema 或人工批准语义。"
|
|
134
|
+
lines << ""
|
|
135
|
+
lines << "## 1. 主阶段"
|
|
136
|
+
lines << ""
|
|
137
|
+
lines << "| 稳定 ID | 阶段 | 目标 | 退出标准 |"
|
|
138
|
+
lines << "|---|---|---|---|"
|
|
139
|
+
registry.fetch("stages").each { |stage| lines << "| `#{stage["id"]}` | #{stage["name"]} | #{stage["goal"]} | #{stage["exit_criteria"]} |" }
|
|
140
|
+
lines << ""
|
|
141
|
+
lines << "## 2. 生命周期对象"
|
|
142
|
+
lines << ""
|
|
143
|
+
lines << "门禁是需要裁决的审查点;产物、工作单元和证据不是门禁的同义词。未命中条件的门禁记录 `not-applicable` 及原因,不生成空文档。"
|
|
144
|
+
lines << ""
|
|
145
|
+
lines << "### 2.1 条件门禁"
|
|
146
|
+
lines << ""
|
|
147
|
+
lines << "| 稳定 ID | 门禁 | 所属阶段 | 触发条件 | 必须留下的证据 |"
|
|
148
|
+
lines << "|---|---|---|---|---|"
|
|
149
|
+
registry.fetch("gates").each do |gate|
|
|
150
|
+
evidence = gate.fetch("evidence").map { |id| "`#{id}`" }.join("、")
|
|
151
|
+
lines << "| `#{gate["id"]}` | #{gate["name"]} | `#{gate["stage"]}` | #{gate["trigger"]} | #{evidence} |"
|
|
152
|
+
end
|
|
153
|
+
lines << ""
|
|
154
|
+
lines << "### 2.2 生命周期产物"
|
|
155
|
+
lines << ""
|
|
156
|
+
lines << "| 稳定 ID | 产物 | 所属阶段 | 触发条件 |"
|
|
157
|
+
lines << "|---|---|---|---|"
|
|
158
|
+
registry.fetch("artifacts").each { |artifact| lines << "| `#{artifact["id"]}` | #{artifact["name"]} | `#{artifact["stage"]}` | #{artifact["trigger"]} |" }
|
|
159
|
+
lines << ""
|
|
160
|
+
lines << "### 2.3 执行证据"
|
|
161
|
+
lines << ""
|
|
162
|
+
lines << "| 稳定 ID | 证据 | 说明 |"
|
|
163
|
+
lines << "|---|---|---|"
|
|
164
|
+
registry.fetch("evidence").each { |evidence| lines << "| `#{evidence["id"]}` | #{evidence["name"]} | #{evidence["description"]} |" }
|
|
165
|
+
lines << "<!-- lifecycle-registry:structure:end -->"
|
|
166
|
+
lines.join("\n") + "\n"
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def render_work_units(registry)
|
|
170
|
+
lines = []
|
|
171
|
+
lines << "<!-- lifecycle-registry:work-units:start -->"
|
|
172
|
+
lines << "> 此表由 `docs/process/lifecycle-registry.yaml` 生成;它只描述 `template-source` 的 Harness 工作单元。"
|
|
173
|
+
lines << ""
|
|
174
|
+
lines << "| 稳定 ID | 工作单元 | 输入 | 输出 | 完成条件 |"
|
|
175
|
+
lines << "|---|---|---|---|---|"
|
|
176
|
+
registry.fetch("work_units").each do |unit|
|
|
177
|
+
lines << "| `#{unit["id"]}` | #{unit["name"]} | #{unit["input"]} | #{unit["output"]} | #{unit["completion"]} |"
|
|
178
|
+
end
|
|
179
|
+
lines << "<!-- lifecycle-registry:work-units:end -->"
|
|
180
|
+
lines.join("\n") + "\n"
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def replace_region!(path, start_marker, end_marker, replacement, check: false)
|
|
184
|
+
body = path.read
|
|
185
|
+
expression = /#{Regexp.escape(start_marker)}.*?#{Regexp.escape(end_marker)}\n?/m
|
|
186
|
+
raise ArgumentError, "派生文档缺少生成区: #{path.relative_path_from(ROOT)}" unless body.match?(expression)
|
|
187
|
+
expected = body.sub(expression, replacement)
|
|
188
|
+
if check
|
|
189
|
+
raise ArgumentError, "派生文档与注册表漂移: #{path.relative_path_from(ROOT)};运行 scripts/generate-lifecycle-artifacts --write" unless expected == body
|
|
190
|
+
else
|
|
191
|
+
path.write(expected)
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
@@ -18,6 +18,7 @@ REMOVED_SKILLS = %w[
|
|
|
18
18
|
yss-quality
|
|
19
19
|
yss-sql-condition
|
|
20
20
|
yss-sql-tpl
|
|
21
|
+
yss-openapi
|
|
21
22
|
].freeze
|
|
22
23
|
|
|
23
24
|
class ExportYssSkillsTest < Minitest::Test
|
|
@@ -31,19 +32,21 @@ class ExportYssSkillsTest < Minitest::Test
|
|
|
31
32
|
stdout, stderr, result = run_export(output)
|
|
32
33
|
|
|
33
34
|
assert result.success?, "#{stdout}\n#{stderr}"
|
|
34
|
-
assert_equal
|
|
35
|
+
assert_equal 45, Dir.glob(output.join("skills", "*").to_s).count { |path| File.directory?(path) }
|
|
35
36
|
|
|
36
37
|
manifest = JSON.parse(output.join(".yss-export-manifest.json").read)
|
|
37
|
-
assert_equal
|
|
38
|
-
assert_operator manifest.fetch("generated_files_sha256").length, :>,
|
|
38
|
+
assert_equal 45, manifest.fetch("skills").length
|
|
39
|
+
assert_operator manifest.fetch("generated_files_sha256").length, :>, 45
|
|
40
|
+
assert output.join("skills", "yss-prototype-stage", "SKILL.md").file?, "prototype stage contract was not exported"
|
|
39
41
|
REMOVED_SKILLS.each do |skill_name|
|
|
40
42
|
refute output.join("skills", skill_name).exist?, "removed skill was exported: #{skill_name}"
|
|
41
43
|
end
|
|
42
44
|
|
|
43
45
|
page = JSON.parse(output.join("skills.sh.json").read)
|
|
44
46
|
grouped = page.fetch("groupings").flat_map { |group| group.fetch("skills") }
|
|
45
|
-
assert_equal
|
|
46
|
-
assert_equal
|
|
47
|
+
assert_equal 45, grouped.uniq.length
|
|
48
|
+
assert_equal 45, grouped.length
|
|
49
|
+
assert_includes grouped, "yss-prototype-stage"
|
|
47
50
|
|
|
48
51
|
exported_text = Dir.glob(output.join("skills", "**", "*").to_s)
|
|
49
52
|
.select { |path| File.file?(path) }
|
|
@@ -51,7 +54,8 @@ class ExportYssSkillsTest < Minitest::Test
|
|
|
51
54
|
.select(&:valid_encoding?)
|
|
52
55
|
.join("\n")
|
|
53
56
|
REMOVED_SKILLS.each do |skill_name|
|
|
54
|
-
|
|
57
|
+
pattern = Regexp.new("(?<![a-z0-9-])#{Regexp.escape(skill_name)}(?![a-z0-9-])")
|
|
58
|
+
refute_match(pattern, exported_text, "removed skill is still referenced: #{skill_name}")
|
|
55
59
|
end
|
|
56
60
|
|
|
57
61
|
formily_examples = output.join("skills", "yss-formily", "references", "examples.md").read
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "minitest/autorun"
|
|
5
|
+
require "open3"
|
|
6
|
+
require "pathname"
|
|
7
|
+
require "tmpdir"
|
|
8
|
+
require "yaml"
|
|
9
|
+
|
|
10
|
+
ROOT = Pathname.new(__dir__).join("..").realpath
|
|
11
|
+
|
|
12
|
+
class LifecycleRegistryTest < Minitest::Test
|
|
13
|
+
def run_command(*command)
|
|
14
|
+
output, status = Open3.capture2e(*command, chdir: ROOT)
|
|
15
|
+
[output, status]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_registry_verifier_and_generated_views_are_current
|
|
19
|
+
output, status = run_command("scripts/verify-lifecycle-registry")
|
|
20
|
+
assert status.success?, output
|
|
21
|
+
|
|
22
|
+
output, status = run_command("scripts/generate-lifecycle-artifacts", "--check")
|
|
23
|
+
assert status.success?, output
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_verifier_rejects_unknown_cross_reference
|
|
27
|
+
Dir.mktmpdir("yss-lifecycle-registry") do |directory|
|
|
28
|
+
registry_path = Pathname.new(directory).join("broken.yaml")
|
|
29
|
+
registry = YAML.safe_load(ROOT.join("docs/process/lifecycle-registry.yaml").read, aliases: false)
|
|
30
|
+
registry.fetch("gates").first.fetch("evidence") << "evidence.unknown"
|
|
31
|
+
registry_path.write(YAML.dump(registry))
|
|
32
|
+
|
|
33
|
+
output, status = run_command("scripts/verify-lifecycle-registry", "--registry", registry_path.to_s)
|
|
34
|
+
refute status.success?, output
|
|
35
|
+
assert_includes output, "不存在的引用"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_verifier_executes_json_schema_and_stable_id_baseline
|
|
40
|
+
Dir.mktmpdir("yss-lifecycle-registry") do |directory|
|
|
41
|
+
schema_broken = Pathname.new(directory).join("schema-broken.yaml")
|
|
42
|
+
semantic_broken = Pathname.new(directory).join("semantic-broken.yaml")
|
|
43
|
+
registry = YAML.safe_load(ROOT.join("docs/process/lifecycle-registry.yaml").read, aliases: false)
|
|
44
|
+
|
|
45
|
+
registry.fetch("stages").first.delete("goal")
|
|
46
|
+
schema_broken.write(YAML.dump(registry))
|
|
47
|
+
output, status = run_command("scripts/verify-lifecycle-registry", "--registry", schema_broken.to_s)
|
|
48
|
+
refute status.success?, output
|
|
49
|
+
assert_includes output, "JSON Schema 校验失败"
|
|
50
|
+
|
|
51
|
+
registry = YAML.safe_load(ROOT.join("docs/process/lifecycle-registry.yaml").read, aliases: false)
|
|
52
|
+
registry.fetch("gates").first["trigger"] = "被静默改变的语义。"
|
|
53
|
+
semantic_broken.write(YAML.dump(registry))
|
|
54
|
+
output, status = run_command("scripts/verify-lifecycle-registry", "--registry", semantic_broken.to_s)
|
|
55
|
+
refute status.success?, output
|
|
56
|
+
assert_includes output, "语义快照已变化"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_policy_documents_do_not_reintroduce_stale_counts
|
|
61
|
+
forbidden_count = /\d+\s*个(?:主阶段|门禁|工作单元|职责点)/
|
|
62
|
+
assert_match forbidden_count, "必须按 8 个主阶段推进"
|
|
63
|
+
|
|
64
|
+
[
|
|
65
|
+
"AGENTS.md",
|
|
66
|
+
"README.md",
|
|
67
|
+
"docs/user-guide/产品生命周期工作流.md",
|
|
68
|
+
".agents/skills/yss-product-lifecycle/SKILL.md"
|
|
69
|
+
].each do |relative_path|
|
|
70
|
+
body = ROOT.join(relative_path).read
|
|
71
|
+
refute_match(forbidden_count, body, relative_path)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "json"
|
|
5
|
+
require "pathname"
|
|
6
|
+
require "yaml"
|
|
7
|
+
|
|
8
|
+
ROOT = Pathname.new(__dir__).join("..").realpath
|
|
9
|
+
failures = []
|
|
10
|
+
|
|
11
|
+
{
|
|
12
|
+
"docs/architecture/templates/system-overview-design-template.md" => "已明确的认证、授权、租户隔离、敏感数据或合规行为",
|
|
13
|
+
"docs/architecture/templates/tech-design-template.md" => "已明确的认证、授权、租户隔离、敏感数据或合规行为"
|
|
14
|
+
}.each do |relative_path, marker|
|
|
15
|
+
body = ROOT.join(relative_path).read
|
|
16
|
+
failures << "#{relative_path} 缺少条件性安全/权限架构承载" unless body.include?(marker)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
{
|
|
20
|
+
"docs/adr/0003-machine-readable-lifecycle-registry.md" => "状态:部分实施(Phase 1)",
|
|
21
|
+
"docs/adr/0004-split-lifecycle-and-router-registry-domains.md" => "状态:proposed",
|
|
22
|
+
"docs/adr/0005-cross-repository-ecosystem-release-manifest.md" => "状态:proposed",
|
|
23
|
+
"docs/adr/0006-stable-lifecycle-ids-and-generated-structure.md" => "状态:部分实施(Phase 1)",
|
|
24
|
+
"docs/adr/0007-separate-skill-routing-registry-from-integrity-lock.md" => "状态:proposed"
|
|
25
|
+
}.each do |relative_path, marker|
|
|
26
|
+
body = ROOT.join(relative_path).read
|
|
27
|
+
failures << "#{relative_path} 未声明当前实现状态" unless body.include?(marker)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
scenario_verifier = ROOT.join("scripts/verify-lifecycle-scenarios").read
|
|
31
|
+
failures << "生命周期场景未校验稳定 ID 映射" unless scenario_verifier.include?("ROUTE_REGISTRY_IDS")
|
|
32
|
+
|
|
33
|
+
unless failures.empty?
|
|
34
|
+
warn failures.join("\n")
|
|
35
|
+
exit 1
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
warn failures.join("\n") unless failures.empty?
|
|
39
|
+
exit(failures.empty? ? 0 : 1)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "json"
|
|
5
|
+
require "open3"
|
|
6
|
+
require "optparse"
|
|
7
|
+
require_relative "lifecycle-registry"
|
|
8
|
+
|
|
9
|
+
options = { registry: LifecycleRegistry::DEFAULT_REGISTRY }
|
|
10
|
+
OptionParser.new do |parser|
|
|
11
|
+
parser.on("--registry PATH", "使用指定注册表") { |path| options[:registry] = Pathname.new(path) }
|
|
12
|
+
end.parse!
|
|
13
|
+
|
|
14
|
+
begin
|
|
15
|
+
schema_path = LifecycleRegistry::ROOT.join("docs/process/schemas/lifecycle-registry.schema.json")
|
|
16
|
+
schema = JSON.parse(schema_path.read)
|
|
17
|
+
raise ArgumentError, "生命周期注册表 JSON Schema 缺少 schema_version 约束" unless schema.dig("properties", "schema_version", "const") == 1
|
|
18
|
+
json_schema_program = <<~'PYTHON'
|
|
19
|
+
import json
|
|
20
|
+
import sys
|
|
21
|
+
from jsonschema import Draft202012Validator
|
|
22
|
+
|
|
23
|
+
with open(sys.argv[1], encoding="utf-8") as schema_file:
|
|
24
|
+
schema = json.load(schema_file)
|
|
25
|
+
registry = json.load(sys.stdin)
|
|
26
|
+
errors = sorted(Draft202012Validator(schema).iter_errors(registry), key=lambda error: list(error.absolute_path))
|
|
27
|
+
if errors:
|
|
28
|
+
for error in errors:
|
|
29
|
+
location = ".".join(str(part) for part in error.absolute_path) or "<root>"
|
|
30
|
+
print(f"{location}: {error.message}", file=sys.stderr)
|
|
31
|
+
sys.exit(1)
|
|
32
|
+
PYTHON
|
|
33
|
+
registry_json = JSON.generate(LifecycleRegistry.load_registry(options[:registry]))
|
|
34
|
+
output, status = Open3.capture2e("python3", "-c", json_schema_program, schema_path.to_s, stdin_data: registry_json)
|
|
35
|
+
raise ArgumentError, "JSON Schema 校验失败: #{output}" unless status.success?
|
|
36
|
+
registry = LifecycleRegistry.validate!(LifecycleRegistry.load_registry(options[:registry]))
|
|
37
|
+
|
|
38
|
+
if options[:registry] == LifecycleRegistry::DEFAULT_REGISTRY
|
|
39
|
+
command = [LifecycleRegistry::ROOT.join("scripts/generate-lifecycle-artifacts").to_s, "--check"]
|
|
40
|
+
output, status = Open3.capture2e(*command, chdir: LifecycleRegistry::ROOT)
|
|
41
|
+
raise ArgumentError, output unless status.success?
|
|
42
|
+
|
|
43
|
+
tracked_sources = %w[docs/process/lifecycle-registry.yaml docs/process/lifecycle-registry-baseline.json docs/process/schemas/lifecycle-registry.schema.json]
|
|
44
|
+
tracked_sources.each do |relative_path|
|
|
45
|
+
_output, ignored = Open3.capture2e("git", "check-ignore", "-q", relative_path, chdir: LifecycleRegistry::ROOT)
|
|
46
|
+
raise ArgumentError, "权威注册表资产不得被 Git 忽略: #{relative_path}" if ignored.success?
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
stale_count_paths = %w[AGENTS.md README.md docs/user-guide/产品生命周期工作流.md .agents/skills/yss-product-lifecycle/SKILL.md docs/process/lifecycle-artifact-map.md docs/process/harness-work-unit-map.md]
|
|
50
|
+
stale_count_paths.each do |relative_path|
|
|
51
|
+
body = LifecycleRegistry::ROOT.join(relative_path).read
|
|
52
|
+
if body.match?(/\d+\s*个(?:主阶段|门禁|工作单元|职责点)/)
|
|
53
|
+
raise ArgumentError, "#{relative_path} 不得手工声明生命周期对象数量;请引用 lifecycle-registry.yaml"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
public_skills = JSON.parse(LifecycleRegistry::ROOT.join("yss-public-skills.json").read)
|
|
58
|
+
groups = public_skills.fetch("groupings").to_h { |group| [group.fetch("title"), group.fetch("skills")] }
|
|
59
|
+
raise ArgumentError, "yss-web-controller 必须在后端分组" unless groups.fetch("后端").include?("yss-web-controller")
|
|
60
|
+
raise ArgumentError, "yss-web-controller 不得在前端分组" if groups.fetch("前端").include?("yss-web-controller")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
puts "生命周期注册表验证通过(#{registry.fetch("status")})"
|
|
64
|
+
rescue ArgumentError, KeyError, JSON::ParserError => error
|
|
65
|
+
warn "生命周期注册表验证失败: #{error.message}"
|
|
66
|
+
exit 1
|
|
67
|
+
end
|