create-yss-spec 3.4.8 → 3.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/template/attach-planner.js +5 -0
- package/src/template/sync-planner.js +5 -0
- package/template/.agents/skills/.strategic-design-skills-manifest.json +5 -5
- package/template/.agents/skills/alibaba-java-code-style/SKILL.md +2 -2
- package/template/.agents/skills/archify/SKILL.md +2 -19
- package/template/.agents/skills/archify/references/geometry-and-routing.md +20 -0
- package/template/.agents/skills/code-review/SKILL.md +3 -33
- package/template/.agents/skills/code-review/references/candidate-capture.md +33 -0
- package/template/.agents/skills/code-review/references/yss-review-standards.md +3 -5
- package/template/.agents/skills/codebase-design/SKILL.md +2 -2
- package/template/.agents/skills/competitive-intelligence/SKILL.md +1 -1
- package/template/.agents/skills/diagnosing-bugs/SKILL.md +6 -2
- package/template/.agents/skills/formily-foundation/SKILL.md +1 -1
- package/template/.agents/skills/formily-step-flow/SKILL.md +3 -2
- package/template/.agents/skills/frontend-commit/SKILL.md +6 -6
- package/template/.agents/skills/grilling/SKILL.md +2 -2
- package/template/.agents/skills/implement/SKILL.md +1 -1
- package/template/.agents/skills/implementation-repo-onboarding/SKILL.md +3 -3
- package/template/.agents/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
- package/template/.agents/skills/improve-codebase-architecture/SKILL.md +10 -6
- package/template/.agents/skills/java-backend-commit/SKILL.md +5 -5
- package/template/.agents/skills/llm-wiki/SKILL.md +1 -1
- package/template/.agents/skills/prototype/SKILL.md +1 -1
- package/template/.agents/skills/prototype-review/SKILL.md +1 -1
- package/template/.agents/skills/resolving-merge-conflicts/SKILL.md +2 -2
- package/template/.agents/skills/tdd/SKILL.md +1 -1
- package/template/.agents/skills/to-questionnaire/SKILL.md +4 -2
- package/template/.agents/skills/to-spec/SKILL.md +3 -3
- package/template/.agents/skills/to-tickets/SKILL.md +7 -7
- package/template/.agents/skills/using-git-worktrees/SKILL.md +13 -11
- package/template/.agents/skills/wait-what/SKILL.md +1 -1
- package/template/.agents/skills/wayfinder/SKILL.md +4 -2
- package/template/.agents/skills/writing-for-agents/SKILL.md +9 -73
- package/template/.agents/skills/writing-for-agents/references/writing-principles.md +76 -0
- package/template/.agents/skills/yss-api-integration/SKILL.md +2 -2
- package/template/.agents/skills/yss-application/SKILL.md +12 -0
- package/template/.agents/skills/yss-audit-log/SKILL.md +3 -1
- package/template/.agents/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
- package/template/.agents/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
- package/template/.agents/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
- package/template/.agents/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
- package/template/.agents/skills/yss-backend-spec-review/SKILL.md +6 -0
- package/template/.agents/skills/yss-backend-spec-review/references/check-inputs.md +2 -2
- package/template/.agents/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
- package/template/.agents/skills/yss-ddd-scaffold-generator/SKILL.md +5 -34
- package/template/.agents/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
- package/template/.agents/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
- package/template/.agents/skills/yss-design-system/SKILL.md +2 -2
- package/template/.agents/skills/yss-domain/SKILL.md +17 -5
- package/template/.agents/skills/yss-domain/references/domain-layer-guide.md +2 -2
- package/template/.agents/skills/yss-domain/references/existing-project.md +5 -0
- package/template/.agents/skills/yss-dto/SKILL.md +13 -10
- package/template/.agents/skills/yss-dto/references/wire-validation-checklist.md +14 -0
- package/template/.agents/skills/yss-exception/SKILL.md +2 -2
- package/template/.agents/skills/yss-formily-schema-generator/SKILL.md +12 -12
- package/template/.agents/skills/yss-hook/SKILL.md +8 -44
- package/template/.agents/skills/yss-hook/references/use-request.md +42 -0
- package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +3 -5
- package/template/.agents/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
- package/template/.agents/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
- package/template/.agents/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
- package/template/.agents/skills/yss-mybatis/SKILL.md +10 -0
- package/template/.agents/skills/yss-openapi-draft-review/SKILL.md +3 -1
- package/template/.agents/skills/yss-openapi-governance/SKILL.md +5 -32
- package/template/.agents/skills/yss-openapi-governance/references/governance-output.md +34 -0
- package/template/.agents/skills/yss-product-lifecycle/SKILL.md +12 -6
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +63 -1
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +2 -2
- package/template/.agents/skills/yss-prototype-stage/SKILL.md +3 -5
- package/template/.agents/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
- package/template/.agents/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +2 -2
- package/template/.agents/skills/yss-repository/SKILL.md +13 -1
- package/template/.agents/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
- package/template/.agents/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
- package/template/.agents/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
- package/template/.agents/skills/yss-stage-decision/SKILL.md +3 -1
- package/template/.agents/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
- package/template/.agents/skills/yss-tactical-design/SKILL.md +3 -3
- package/template/.agents/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
- package/template/.agents/skills/yss-technical-design/SKILL.md +2 -0
- package/template/.agents/skills/yss-technical-design/scripts/engineering-design.mjs +1 -1
- package/template/.agents/skills/yss-technical-design/scripts/validate-technical-design.mjs +11 -8
- package/template/.agents/skills/yss-ui-business-page-generation/SKILL.md +5 -3
- package/template/.agents/skills/yss-validation/SKILL.md +1 -1
- package/template/.agents/skills/yss-web-controller/SKILL.md +16 -7
- package/template/.agents/skills/ytable-usage/SKILL.md +2 -2
- package/template/.codex/skills/alibaba-java-code-style/SKILL.md +2 -2
- package/template/.codex/skills/archify/SKILL.md +2 -19
- package/template/.codex/skills/archify/references/geometry-and-routing.md +20 -0
- package/template/.codex/skills/code-review/SKILL.md +3 -33
- package/template/.codex/skills/code-review/references/candidate-capture.md +33 -0
- package/template/.codex/skills/code-review/references/yss-review-standards.md +3 -5
- package/template/.codex/skills/codebase-design/SKILL.md +2 -2
- package/template/.codex/skills/competitive-intelligence/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/mcp/server.cjs +2 -1
- package/template/.codex/skills/data-analytics/skills/analyze-data-quality/SKILL.md +9 -32
- package/template/.codex/skills/data-analytics/skills/analyze-data-quality/references/quality-checks.md +29 -0
- package/template/.codex/skills/data-analytics/skills/build-dashboard/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/build-report/SKILL.md +4 -4
- package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/SKILL.md +12 -22
- package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/cli.py +5 -10
- package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/plan.py +47 -49
- package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/tests/test_delivery_plan.py +45 -0
- package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/SKILL.md +4 -5
- package/template/.codex/skills/data-analytics/skills/build-report/report-to-pdf/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/build-report/specifications/mcp-app-report.md +1 -1
- package/template/.codex/skills/data-analytics/skills/design-kpis/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/gather-business-context/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/index/SKILL.md +4 -4
- package/template/.codex/skills/data-analytics/skills/jupyter-notebooks/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/kpi-reporting/SKILL.md +2 -2
- package/template/.codex/skills/data-analytics/skills/market-sizing/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/metric-diagnostics/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/product-business-analysis/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/spreadsheets/SKILL.md +4 -4
- package/template/.codex/skills/data-analytics/skills/user-context/SKILL.md +16 -14
- package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/automation-config.md +1 -1
- package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding-examples.md +1 -1
- package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding.md +7 -7
- package/template/.codex/skills/data-analytics/skills/user-context/references/source-category-runtime.md +7 -7
- package/template/.codex/skills/data-analytics/skills/user-context/scripts/data_analytics_preflight.py +4 -2
- package/template/.codex/skills/data-analytics/skills/user-context/scripts/validate_user_context_preflight.py +5 -5
- package/template/.codex/skills/data-analytics/skills/user-context/tests/test_state_helpers.py +3 -3
- package/template/.codex/skills/data-analytics/skills/validate-data/SKILL.md +7 -71
- package/template/.codex/skills/data-analytics/skills/validate-data/references/validation-methods.md +70 -0
- package/template/.codex/skills/data-analytics/skills/visualize-data/SKILL.md +4 -4
- package/template/.codex/skills/data-analytics/src/analytics-app/App.tsx +1 -1
- package/template/.codex/skills/data-analytics/src/analytics-app-core.md +1 -1
- package/template/.codex/skills/diagnosing-bugs/SKILL.md +6 -2
- package/template/.codex/skills/formily-foundation/SKILL.md +1 -1
- package/template/.codex/skills/formily-step-flow/SKILL.md +3 -2
- package/template/.codex/skills/frontend-commit/SKILL.md +6 -6
- package/template/.codex/skills/grilling/SKILL.md +2 -2
- package/template/.codex/skills/implement/SKILL.md +1 -1
- package/template/.codex/skills/implementation-repo-onboarding/SKILL.md +3 -3
- package/template/.codex/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
- package/template/.codex/skills/improve-codebase-architecture/SKILL.md +10 -6
- package/template/.codex/skills/java-backend-commit/SKILL.md +5 -5
- package/template/.codex/skills/llm-wiki/SKILL.md +1 -1
- package/template/.codex/skills/product-design/references/critical-overrides.md +3 -4
- package/template/.codex/skills/product-design/skills/audit/SKILL.md +1 -1
- package/template/.codex/skills/product-design/skills/design-qa/SKILL.md +1 -1
- package/template/.codex/skills/product-design/skills/get-context/SKILL.md +2 -1
- package/template/.codex/skills/product-design/skills/ideate/SKILL.md +2 -50
- package/template/.codex/skills/product-design/skills/ideate/references/image-prompt-patterns.md +51 -0
- package/template/.codex/skills/product-design/skills/image-to-code/SKILL.md +6 -6
- package/template/.codex/skills/product-design/skills/index/SKILL.md +2 -2
- package/template/.codex/skills/product-design/skills/prototype/SKILL.md +6 -6
- package/template/.codex/skills/product-design/skills/url-to-code/SKILL.md +1 -1
- package/template/.codex/skills/product-design/skills/user-context/SKILL.md +1 -1
- package/template/.codex/skills/prototype/SKILL.md +1 -1
- package/template/.codex/skills/prototype-review/SKILL.md +1 -1
- package/template/.codex/skills/resolving-merge-conflicts/SKILL.md +2 -2
- package/template/.codex/skills/tdd/SKILL.md +1 -1
- package/template/.codex/skills/to-questionnaire/SKILL.md +4 -2
- package/template/.codex/skills/to-spec/SKILL.md +3 -3
- package/template/.codex/skills/to-tickets/SKILL.md +7 -7
- package/template/.codex/skills/using-git-worktrees/SKILL.md +13 -11
- package/template/.codex/skills/wait-what/SKILL.md +1 -1
- package/template/.codex/skills/wayfinder/SKILL.md +4 -2
- package/template/.codex/skills/writing-for-agents/SKILL.md +9 -73
- package/template/.codex/skills/writing-for-agents/references/writing-principles.md +76 -0
- package/template/.codex/skills/yss-api-integration/SKILL.md +2 -2
- package/template/.codex/skills/yss-application/SKILL.md +12 -0
- package/template/.codex/skills/yss-audit-log/SKILL.md +3 -1
- package/template/.codex/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
- package/template/.codex/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
- package/template/.codex/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
- package/template/.codex/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
- package/template/.codex/skills/yss-backend-spec-review/SKILL.md +6 -0
- package/template/.codex/skills/yss-backend-spec-review/references/check-inputs.md +2 -2
- package/template/.codex/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
- package/template/.codex/skills/yss-ddd-scaffold-generator/SKILL.md +5 -34
- package/template/.codex/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
- package/template/.codex/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
- package/template/.codex/skills/yss-design-system/SKILL.md +2 -2
- package/template/.codex/skills/yss-domain/SKILL.md +17 -5
- package/template/.codex/skills/yss-domain/references/domain-layer-guide.md +2 -2
- package/template/.codex/skills/yss-domain/references/existing-project.md +5 -0
- package/template/.codex/skills/yss-dto/SKILL.md +13 -10
- package/template/.codex/skills/yss-dto/references/wire-validation-checklist.md +14 -0
- package/template/.codex/skills/yss-exception/SKILL.md +2 -2
- package/template/.codex/skills/yss-formily-schema-generator/SKILL.md +12 -12
- package/template/.codex/skills/yss-hook/SKILL.md +8 -44
- package/template/.codex/skills/yss-hook/references/use-request.md +42 -0
- package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +3 -5
- package/template/.codex/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
- package/template/.codex/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
- package/template/.codex/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
- package/template/.codex/skills/yss-mybatis/SKILL.md +10 -0
- package/template/.codex/skills/yss-openapi-draft-review/SKILL.md +3 -1
- package/template/.codex/skills/yss-openapi-governance/SKILL.md +5 -32
- package/template/.codex/skills/yss-openapi-governance/references/governance-output.md +34 -0
- package/template/.codex/skills/yss-product-lifecycle/SKILL.md +12 -6
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +63 -1
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +2 -2
- package/template/.codex/skills/yss-prototype-stage/SKILL.md +3 -5
- package/template/.codex/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
- package/template/.codex/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +2 -2
- package/template/.codex/skills/yss-repository/SKILL.md +13 -1
- package/template/.codex/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
- package/template/.codex/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
- package/template/.codex/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
- package/template/.codex/skills/yss-stage-decision/SKILL.md +3 -1
- package/template/.codex/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
- package/template/.codex/skills/yss-tactical-design/SKILL.md +3 -3
- package/template/.codex/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
- package/template/.codex/skills/yss-technical-design/SKILL.md +2 -0
- package/template/.codex/skills/yss-technical-design/scripts/engineering-design.mjs +1 -1
- package/template/.codex/skills/yss-technical-design/scripts/validate-technical-design.mjs +11 -8
- package/template/.codex/skills/yss-ui-business-page-generation/SKILL.md +5 -3
- package/template/.codex/skills/yss-validation/SKILL.md +1 -1
- package/template/.codex/skills/yss-web-controller/SKILL.md +16 -7
- package/template/.codex/skills/ytable-usage/SKILL.md +2 -2
- package/template/.cursor/skills/alibaba-java-code-style/SKILL.md +2 -2
- package/template/.cursor/skills/archify/SKILL.md +2 -19
- package/template/.cursor/skills/archify/references/geometry-and-routing.md +20 -0
- package/template/.cursor/skills/code-review/SKILL.md +3 -33
- package/template/.cursor/skills/code-review/references/candidate-capture.md +33 -0
- package/template/.cursor/skills/code-review/references/yss-review-standards.md +3 -5
- package/template/.cursor/skills/codebase-design/SKILL.md +2 -2
- package/template/.cursor/skills/competitive-intelligence/SKILL.md +1 -1
- package/template/.cursor/skills/diagnosing-bugs/SKILL.md +6 -2
- package/template/.cursor/skills/formily-foundation/SKILL.md +1 -1
- package/template/.cursor/skills/formily-step-flow/SKILL.md +3 -2
- package/template/.cursor/skills/frontend-commit/SKILL.md +6 -6
- package/template/.cursor/skills/grilling/SKILL.md +2 -2
- package/template/.cursor/skills/implement/SKILL.md +1 -1
- package/template/.cursor/skills/implementation-repo-onboarding/SKILL.md +3 -3
- package/template/.cursor/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
- package/template/.cursor/skills/improve-codebase-architecture/SKILL.md +10 -6
- package/template/.cursor/skills/java-backend-commit/SKILL.md +5 -5
- package/template/.cursor/skills/llm-wiki/SKILL.md +1 -1
- package/template/.cursor/skills/prototype/SKILL.md +1 -1
- package/template/.cursor/skills/prototype-review/SKILL.md +1 -1
- package/template/.cursor/skills/resolving-merge-conflicts/SKILL.md +2 -2
- package/template/.cursor/skills/tdd/SKILL.md +1 -1
- package/template/.cursor/skills/to-questionnaire/SKILL.md +4 -2
- package/template/.cursor/skills/to-spec/SKILL.md +3 -3
- package/template/.cursor/skills/to-tickets/SKILL.md +7 -7
- package/template/.cursor/skills/using-git-worktrees/SKILL.md +13 -11
- package/template/.cursor/skills/wait-what/SKILL.md +1 -1
- package/template/.cursor/skills/wayfinder/SKILL.md +4 -2
- package/template/.cursor/skills/writing-for-agents/SKILL.md +9 -73
- package/template/.cursor/skills/writing-for-agents/references/writing-principles.md +76 -0
- package/template/.cursor/skills/yss-api-integration/SKILL.md +2 -2
- package/template/.cursor/skills/yss-application/SKILL.md +12 -0
- package/template/.cursor/skills/yss-audit-log/SKILL.md +3 -1
- package/template/.cursor/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
- package/template/.cursor/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
- package/template/.cursor/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
- package/template/.cursor/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
- package/template/.cursor/skills/yss-backend-spec-review/SKILL.md +6 -0
- package/template/.cursor/skills/yss-backend-spec-review/references/check-inputs.md +2 -2
- package/template/.cursor/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
- package/template/.cursor/skills/yss-ddd-scaffold-generator/SKILL.md +5 -34
- package/template/.cursor/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
- package/template/.cursor/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
- package/template/.cursor/skills/yss-design-system/SKILL.md +2 -2
- package/template/.cursor/skills/yss-domain/SKILL.md +17 -5
- package/template/.cursor/skills/yss-domain/references/domain-layer-guide.md +2 -2
- package/template/.cursor/skills/yss-domain/references/existing-project.md +5 -0
- package/template/.cursor/skills/yss-dto/SKILL.md +13 -10
- package/template/.cursor/skills/yss-dto/references/wire-validation-checklist.md +14 -0
- package/template/.cursor/skills/yss-exception/SKILL.md +2 -2
- package/template/.cursor/skills/yss-formily-schema-generator/SKILL.md +12 -12
- package/template/.cursor/skills/yss-hook/SKILL.md +8 -44
- package/template/.cursor/skills/yss-hook/references/use-request.md +42 -0
- package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +3 -5
- package/template/.cursor/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
- package/template/.cursor/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
- package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
- package/template/.cursor/skills/yss-mybatis/SKILL.md +10 -0
- package/template/.cursor/skills/yss-openapi-draft-review/SKILL.md +3 -1
- package/template/.cursor/skills/yss-openapi-governance/SKILL.md +5 -32
- package/template/.cursor/skills/yss-openapi-governance/references/governance-output.md +34 -0
- package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +12 -6
- package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +63 -1
- package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +2 -2
- package/template/.cursor/skills/yss-prototype-stage/SKILL.md +3 -5
- package/template/.cursor/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
- package/template/.cursor/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +2 -2
- package/template/.cursor/skills/yss-repository/SKILL.md +13 -1
- package/template/.cursor/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
- package/template/.cursor/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
- package/template/.cursor/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
- package/template/.cursor/skills/yss-stage-decision/SKILL.md +3 -1
- package/template/.cursor/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
- package/template/.cursor/skills/yss-tactical-design/SKILL.md +3 -3
- package/template/.cursor/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
- package/template/.cursor/skills/yss-technical-design/SKILL.md +2 -0
- package/template/.cursor/skills/yss-technical-design/scripts/engineering-design.mjs +1 -1
- package/template/.cursor/skills/yss-technical-design/scripts/validate-technical-design.mjs +11 -8
- package/template/.cursor/skills/yss-ui-business-page-generation/SKILL.md +5 -3
- package/template/.cursor/skills/yss-validation/SKILL.md +1 -1
- package/template/.cursor/skills/yss-web-controller/SKILL.md +16 -7
- package/template/.cursor/skills/ytable-usage/SKILL.md +2 -2
- package/template/.pi/skills/alibaba-java-code-style/SKILL.md +2 -2
- package/template/.pi/skills/archify/SKILL.md +2 -19
- package/template/.pi/skills/archify/references/geometry-and-routing.md +20 -0
- package/template/.pi/skills/code-review/SKILL.md +3 -33
- package/template/.pi/skills/code-review/references/candidate-capture.md +33 -0
- package/template/.pi/skills/code-review/references/yss-review-standards.md +3 -5
- package/template/.pi/skills/codebase-design/SKILL.md +2 -2
- package/template/.pi/skills/competitive-intelligence/SKILL.md +1 -1
- package/template/.pi/skills/diagnosing-bugs/SKILL.md +6 -2
- package/template/.pi/skills/formily-foundation/SKILL.md +1 -1
- package/template/.pi/skills/formily-step-flow/SKILL.md +3 -2
- package/template/.pi/skills/frontend-commit/SKILL.md +6 -6
- package/template/.pi/skills/grilling/SKILL.md +2 -2
- package/template/.pi/skills/implement/SKILL.md +1 -1
- package/template/.pi/skills/implementation-repo-onboarding/SKILL.md +3 -3
- package/template/.pi/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
- package/template/.pi/skills/improve-codebase-architecture/SKILL.md +10 -6
- package/template/.pi/skills/java-backend-commit/SKILL.md +5 -5
- package/template/.pi/skills/llm-wiki/SKILL.md +1 -1
- package/template/.pi/skills/prototype/SKILL.md +1 -1
- package/template/.pi/skills/prototype-review/SKILL.md +1 -1
- package/template/.pi/skills/resolving-merge-conflicts/SKILL.md +2 -2
- package/template/.pi/skills/tdd/SKILL.md +1 -1
- package/template/.pi/skills/to-questionnaire/SKILL.md +4 -2
- package/template/.pi/skills/to-spec/SKILL.md +3 -3
- package/template/.pi/skills/to-tickets/SKILL.md +7 -7
- package/template/.pi/skills/using-git-worktrees/SKILL.md +13 -11
- package/template/.pi/skills/wait-what/SKILL.md +1 -1
- package/template/.pi/skills/wayfinder/SKILL.md +4 -2
- package/template/.pi/skills/writing-for-agents/SKILL.md +9 -73
- package/template/.pi/skills/writing-for-agents/references/writing-principles.md +76 -0
- package/template/.pi/skills/yss-api-integration/SKILL.md +2 -2
- package/template/.pi/skills/yss-application/SKILL.md +12 -0
- package/template/.pi/skills/yss-audit-log/SKILL.md +3 -1
- package/template/.pi/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
- package/template/.pi/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
- package/template/.pi/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
- package/template/.pi/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
- package/template/.pi/skills/yss-backend-spec-review/SKILL.md +6 -0
- package/template/.pi/skills/yss-backend-spec-review/references/check-inputs.md +2 -2
- package/template/.pi/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
- package/template/.pi/skills/yss-ddd-scaffold-generator/SKILL.md +5 -34
- package/template/.pi/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
- package/template/.pi/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
- package/template/.pi/skills/yss-design-system/SKILL.md +2 -2
- package/template/.pi/skills/yss-domain/SKILL.md +17 -5
- package/template/.pi/skills/yss-domain/references/domain-layer-guide.md +2 -2
- package/template/.pi/skills/yss-domain/references/existing-project.md +5 -0
- package/template/.pi/skills/yss-dto/SKILL.md +13 -10
- package/template/.pi/skills/yss-dto/references/wire-validation-checklist.md +14 -0
- package/template/.pi/skills/yss-exception/SKILL.md +2 -2
- package/template/.pi/skills/yss-formily-schema-generator/SKILL.md +12 -12
- package/template/.pi/skills/yss-hook/SKILL.md +8 -44
- package/template/.pi/skills/yss-hook/references/use-request.md +42 -0
- package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +3 -5
- package/template/.pi/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
- package/template/.pi/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
- package/template/.pi/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
- package/template/.pi/skills/yss-mybatis/SKILL.md +10 -0
- package/template/.pi/skills/yss-openapi-draft-review/SKILL.md +3 -1
- package/template/.pi/skills/yss-openapi-governance/SKILL.md +5 -32
- package/template/.pi/skills/yss-openapi-governance/references/governance-output.md +34 -0
- package/template/.pi/skills/yss-product-lifecycle/SKILL.md +12 -6
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +63 -1
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +2 -2
- package/template/.pi/skills/yss-prototype-stage/SKILL.md +3 -5
- package/template/.pi/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
- package/template/.pi/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +2 -2
- package/template/.pi/skills/yss-repository/SKILL.md +13 -1
- package/template/.pi/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
- package/template/.pi/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
- package/template/.pi/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
- package/template/.pi/skills/yss-stage-decision/SKILL.md +3 -1
- package/template/.pi/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
- package/template/.pi/skills/yss-tactical-design/SKILL.md +3 -3
- package/template/.pi/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
- package/template/.pi/skills/yss-technical-design/SKILL.md +2 -0
- package/template/.pi/skills/yss-technical-design/scripts/engineering-design.mjs +1 -1
- package/template/.pi/skills/yss-technical-design/scripts/validate-technical-design.mjs +11 -8
- package/template/.pi/skills/yss-ui-business-page-generation/SKILL.md +5 -3
- package/template/.pi/skills/yss-validation/SKILL.md +1 -1
- package/template/.pi/skills/yss-web-controller/SKILL.md +16 -7
- package/template/.pi/skills/ytable-usage/SKILL.md +2 -2
- package/template/AGENTS.md +2 -0
- package/template/CONTEXT.md +2 -1
- package/template/README.md +1 -0
- package/template/docs/agents/issue-tracker.md +7 -0
- package/template/docs/process/contract-reading.md +46 -0
- package/template/docs/process/lifecycle-artifact-map.md +2 -2
- package/template/docs/process/lifecycle-registry-baseline.json +2 -1
- package/template/docs/process/lifecycle-registry.yaml +10 -4
- package/template/docs/process/schemas/api-contract-decision-v2.schema.json +198 -0
- package/template/docs/process/schemas/digital-human-task-package.schema.json +68 -4
- package/template/docs/process/schemas/lifecycle-checkpoint.schema.json +259 -0
- package/template/docs/process/schemas/stage-tracking.schema.json +259 -0
- package/template/docs/process/stage-tracking.md +62 -0
- package/template/docs/process/strategic-handoff-package.md +8 -0
- package/template/docs/user-guide//347/224/250/346/210/267/346/211/213/345/206/214.md +2 -0
- package/template/docs/user-guide//347/224/250/346/210/267/346/211/213/345/206/214/347/264/242/345/274/225.md +1 -0
- package/template/docs/user-guide//351/230/266/346/256/265/346/216/245/345/205/245/344/270/216/344/272/247/347/211/251/345/244/215/347/224/250/344/275/277/347/224/250/346/211/213/345/206/214.md +243 -0
- package/template/scripts/api-contract-decision +16 -0
- package/template/scripts/backend-standards-coverage +26 -0
- package/template/scripts/complete-backend-delivery +17 -0
- package/template/scripts/contract +13 -0
- package/template/scripts/dispatch-slice-task +13 -0
- package/template/scripts/lib/api-contract-decision.mjs +45 -4
- package/template/scripts/lib/approval-record.mjs +1 -1
- package/template/scripts/lib/approved-execution-context.mjs +35 -7
- package/template/scripts/lib/backend-architecture.mjs +2 -2
- package/template/scripts/lib/backend-delivery-terminal.mjs +51 -0
- package/template/scripts/lib/backend-platform-provenance.mjs +1 -1
- package/template/scripts/lib/backend-platform.mjs +1 -1
- package/template/scripts/lib/backend-review.mjs +58 -20
- package/template/scripts/lib/backend-scaffold-prerequisites.mjs +1 -1
- package/template/scripts/lib/backend-standards-coverage.mjs +237 -0
- package/template/scripts/lib/context-contract.mjs +1 -1
- package/template/scripts/lib/context-reconciliation.mjs +1 -1
- package/template/scripts/lib/contract-source.mjs +22 -0
- package/template/scripts/lib/contract-views.mjs +109 -0
- package/template/scripts/lib/delivery-preflight.mjs +3 -2
- package/template/scripts/lib/digital-human-roles.mjs +1 -1
- package/template/scripts/lib/existing-backend-architecture.mjs +4 -3
- package/template/scripts/lib/existing-ui-baseline.mjs +4 -2
- package/template/scripts/lib/first-slice-artifacts.mjs +1 -1
- package/template/scripts/lib/frontend-delivery-boundary.mjs +1 -1
- package/template/scripts/lib/frontend-delivery.mjs +1 -1
- package/template/scripts/lib/harness-execution-scope.mjs +15 -1
- package/template/scripts/lib/implementation-contract-compiler.mjs +4 -4
- package/template/scripts/lib/json-schema.mjs +19 -4
- package/template/scripts/lib/lifecycle-context-query.mjs +5 -1
- package/template/scripts/lib/lifecycle-controls.mjs +1 -1
- package/template/scripts/lib/lifecycle-execution-scope.mjs +92 -0
- package/template/scripts/lib/lifecycle-registry.mjs +2 -1
- package/template/scripts/lib/lifecycle-transition.mjs +25 -4
- package/template/scripts/lib/openapi-draft-validation.mjs +2 -1
- package/template/scripts/lib/profile-skill-sync.mjs +46 -5
- package/template/scripts/lib/skill-registry.mjs +1 -1
- package/template/scripts/lib/slice-contract-preparation.mjs +16 -14
- package/template/scripts/lib/slice-contract-views.mjs +1 -1
- package/template/scripts/lib/slice-contract.mjs +18 -3
- package/template/scripts/lib/slice-execution-preflight.mjs +7 -3
- package/template/scripts/lib/slice-repositories.mjs +1 -1
- package/template/scripts/lib/slice-task-package.mjs +3 -2
- package/template/scripts/lib/stage-tracking-migration.mjs +176 -0
- package/template/scripts/lib/stage-tracking.mjs +184 -0
- package/template/scripts/lib/strategic-handoff-consumption.mjs +5 -4
- package/template/scripts/lib/strategic-handoff-io.mjs +5 -2
- package/template/scripts/lib/strategic-handoff-routing.mjs +31 -0
- package/template/scripts/lib/strategic-handoff.mjs +4 -2
- package/template/scripts/lib/task-package.mjs +2 -0
- package/template/scripts/lib/technical-design-boundary.mjs +4 -2
- package/template/scripts/lib/ui-baseline.mjs +1 -1
- package/template/scripts/lib/user-decision.mjs +1 -1
- package/template/scripts/lib/validation-phase.mjs +72 -0
- package/template/scripts/stage-tracking +25 -0
- package/template/scripts/strategic-consumer-entry +47 -0
- package/template/scripts/verify-context-reconciliation +4 -3
- package/template/scripts/verify-lifecycle-checkpoint +10 -0
- package/template/skills-lock.json +65 -63
- package/template.snapshot.json +4 -4
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { existsSync } from
|
|
1
|
+
import { existsSync, readFileSync, validationCache } from './validation-phase.mjs';
|
|
2
2
|
import { spawnSync } from "node:child_process";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
|
|
5
|
+
const schemaCache=Symbol('schema-results');
|
|
5
6
|
const validator = String.raw`
|
|
6
7
|
import json
|
|
7
8
|
import sys
|
|
@@ -21,8 +22,7 @@ for item in jobs:
|
|
|
21
22
|
try:
|
|
22
23
|
key = (item['schemaPath'], item['formatChecker'])
|
|
23
24
|
if key not in validators:
|
|
24
|
-
|
|
25
|
-
schema = json.load(source)
|
|
25
|
+
schema = json.loads(item['schemaText'])
|
|
26
26
|
validators[key] = Draft202012Validator(schema, format_checker=FormatChecker() if key[1] else None)
|
|
27
27
|
errors = list(validators[key].iter_errors(item['value']))
|
|
28
28
|
if item['errorStyle'] == 'verbose':
|
|
@@ -45,10 +45,11 @@ export function validateJsonSchemas(items, { cwd = process.cwd(), timeoutMs = 30
|
|
|
45
45
|
const effectiveSchema = path.resolve(schemaPath);
|
|
46
46
|
if (!existsSync(effectiveSchema)) throw new TypeError(`缺少 ${label}: ${effectiveSchema}`);
|
|
47
47
|
if (!["compact", "verbose"].includes(errorStyle)) throw new TypeError(`未知 schema errorStyle: ${errorStyle}`);
|
|
48
|
-
return { value, schemaPath: effectiveSchema, formatChecker, errorStyle };
|
|
48
|
+
return { value, schemaPath: effectiveSchema, schemaText: readFileSync(effectiveSchema, 'utf8'), formatChecker, errorStyle };
|
|
49
49
|
});
|
|
50
50
|
// readall waits for EOF even after the complete JSON has arrived. A known UTF-8
|
|
51
51
|
// byte frame lets the validator finish when a transport keeps its write end open.
|
|
52
|
+
const run = jobs => {
|
|
52
53
|
const input = Buffer.from(JSON.stringify(jobs), "utf8");
|
|
53
54
|
const result = spawnSync("python3", ["-c", validator, String(input.length)], { cwd, encoding: "utf8", input, timeout: timeoutMs, maxBuffer: 16 * 1024 * 1024 });
|
|
54
55
|
if (result.error?.code === "ETIMEDOUT") throw new TypeError(`JSON_SCHEMA_TIMEOUT: schema validation exceeded ${timeoutMs}ms`);
|
|
@@ -58,6 +59,20 @@ export function validateJsonSchemas(items, { cwd = process.cwd(), timeoutMs = 30
|
|
|
58
59
|
if (!Array.isArray(results) || results.some(item => !item || typeof item.valid !== "boolean" || typeof item.error !== "string")) throw new TypeError("JSON_SCHEMA_PROTOCOL: validator returned invalid result records");
|
|
59
60
|
if (results.length !== jobs.length) throw new TypeError("schema batch 返回数量不匹配");
|
|
60
61
|
return results;
|
|
62
|
+
};
|
|
63
|
+
// Batch identical jobs once and reuse only deterministic checks within this operation.
|
|
64
|
+
// External references retain the uncached path: their dependency closure is not local here.
|
|
65
|
+
const keys=jobs.map(job=>JSON.stringify([job.schemaPath,job.schemaText,job.value,job.formatChecker,job.errorStyle,path.resolve(cwd),timeoutMs]));
|
|
66
|
+
const pending=new Map(),cached=new Map();
|
|
67
|
+
for(let i=0;i<jobs.length;i++){
|
|
68
|
+
if(/"\$(?:ref|dynamicRef)"\s*:\s*"(?!#)/.test(jobs[i].schemaText)){pending.set(`${i}:${keys[i]}`,{job:jobs[i],indices:[i],cache:false});continue;}
|
|
69
|
+
const existing=validationCache(schemaCache,keys[i]);
|
|
70
|
+
if(existing!==undefined)cached.set(i,existing);
|
|
71
|
+
else {const item=pending.get(keys[i])||{job:jobs[i],indices:[],key:keys[i],cache:true};item.indices.push(i);pending.set(keys[i],item);}
|
|
72
|
+
}
|
|
73
|
+
const entries=[...pending.values()],computed=entries.length?run(entries.map(x=>x.job)):[];
|
|
74
|
+
entries.forEach((entry,index)=>{const result=computed[index];if(entry.cache&&!result.error.includes('Traceback (most recent call last)'))validationCache(schemaCache,entry.key,result);for(const i of entry.indices)cached.set(i,result);});
|
|
75
|
+
return jobs.map((_,i)=>structuredClone(cached.get(i)));
|
|
61
76
|
}
|
|
62
77
|
|
|
63
78
|
export function validateJsonSchema(value, schemaPath, options = {}) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { loadExecutionScope, assertScopeWorkUnit, scopedNextRoutes } from './lifecycle-execution-scope.mjs';
|
|
1
2
|
import { createHash } from "node:crypto";
|
|
2
3
|
import { readFileSync } from "node:fs";
|
|
3
4
|
import path from "node:path";
|
|
@@ -67,6 +68,8 @@ export function queryLifecycleContext({ mode, stageId, workUnitId, include = []
|
|
|
67
68
|
throw new TypeError("至少提供 --mode、--stage、--work-unit 或 --include 之一");
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
const scope = loadExecutionScope();
|
|
72
|
+
if (workUnitId) assertScopeWorkUnit(workUnitId, { readOnly: true });
|
|
70
73
|
const lifecycle = validateRegistry(loadRegistry());
|
|
71
74
|
const orchestration = loadYaml(ORCHESTRATION_CONTRACT_REF, "生命周期编排合同");
|
|
72
75
|
const skillRegistry = loadSkillRegistry();
|
|
@@ -91,7 +94,7 @@ export function queryLifecycleContext({ mode, stageId, workUnitId, include = []
|
|
|
91
94
|
const evidenceIds = new Set([...gates, ...checks].flatMap((gate) => gate.evidence ?? []));
|
|
92
95
|
const selected = Object.fromEntries(normalizedIncludes.map((key) => [key, orchestration[key]]));
|
|
93
96
|
const transition = workUnitId ? {
|
|
94
|
-
next: orchestration.transition_graph?.routes?.[workUnitId] ?? [],
|
|
97
|
+
next: scopedNextRoutes(workUnitId, orchestration.transition_graph?.routes?.[workUnitId] ?? []),
|
|
95
98
|
forbidden_shortcuts: (orchestration.transition_graph?.forbidden_shortcuts ?? [])
|
|
96
99
|
.filter((edge) => edge.from === workUnitId || edge.to === workUnitId),
|
|
97
100
|
} : null;
|
|
@@ -129,6 +132,7 @@ export function queryLifecycleContext({ mode, stageId, workUnitId, include = []
|
|
|
129
132
|
work_unit: workUnit,
|
|
130
133
|
},
|
|
131
134
|
execution: {
|
|
135
|
+
...(scope ? { responsibility_scope: scope } : {}),
|
|
132
136
|
mode: mode ? orchestration.modes[mode] : null,
|
|
133
137
|
selected,
|
|
134
138
|
...(loadPlan ? { plan_checks: lifecycle.stages.find(stage => stage.id === 'stage.plan').spec_entry.required_checks.map(id => ({ id, status: 'pending', evidence_refs: [] })) } : {}),
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from './validation-phase.mjs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { spawnSync } from 'node:child_process';
|
|
4
|
+
import { safe } from './strategic-handoff-io.mjs';
|
|
5
|
+
import { ROOT } from './lifecycle-registry.mjs';
|
|
6
|
+
import { parseDocument } from '../vendor/yaml.mjs';
|
|
7
|
+
|
|
8
|
+
export const SCOPE_REF = '.yss-execution-scope.yaml';
|
|
9
|
+
export const TERMINAL_REF = '.yss-backend-delivery.json';
|
|
10
|
+
const read = (root, ref) => {
|
|
11
|
+
const file = safe(root, ref);
|
|
12
|
+
const doc = parseDocument(readFileSync(file, 'utf8'), { uniqueKeys: true });
|
|
13
|
+
if (doc.errors.length) throw new TypeError(doc.errors[0].message);
|
|
14
|
+
return doc.toJS({ maxAliasCount: 0 });
|
|
15
|
+
};
|
|
16
|
+
const check = (ok, message) => { if (!ok) throw new TypeError(`execution-scope-blocked: ${message}`); };
|
|
17
|
+
|
|
18
|
+
/** The project opt-in selects a policy; callers cannot supply a replacement policy. */
|
|
19
|
+
export function loadExecutionScope(root = ROOT) {
|
|
20
|
+
const marker = path.join(root, '.yss-plugin.json');
|
|
21
|
+
const plugin = existsSync(marker) ? read(root, '.yss-plugin.json') : null;
|
|
22
|
+
const file = path.join(root, SCOPE_REF);
|
|
23
|
+
if (!existsSync(file)) {
|
|
24
|
+
check(!['yss-plan-to-backend', 'yss-backend-delivery'].includes(plugin?.plugin), '插件项目缺少职责范围;迁移后才能继续');
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const config = read(root, SCOPE_REF), identity = read(root, 'yss-project.yaml');
|
|
28
|
+
check(identity.schema_version === 1 && identity.repository_mode === 'project-instance', '职责范围仅适用于项目实例');
|
|
29
|
+
check(config.schema_version === 1 && config.scope_id === 'plan-to-backend'
|
|
30
|
+
&& Object.keys(config).every(key => ['schema_version', 'scope_id'].includes(key)), '未知或被扩大的职责配置');
|
|
31
|
+
if (plugin) check(['yss-plan-to-backend', 'yss-backend-delivery'].includes(plugin.plugin) && plugin.execution_scope === config.scope_id, '插件与项目职责绑定不一致');
|
|
32
|
+
const contract = read(root, '.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml');
|
|
33
|
+
const policy = contract.execution_scopes?.[config.scope_id];
|
|
34
|
+
check(policy?.terminal_work_unit === 'work-unit.backend-delivery' && Array.isArray(policy.allowed_work_units), '匹配版本的主控合同缺少职责策略');
|
|
35
|
+
return { ...policy, scope_id: config.scope_id };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function verifyDeliveryTerminal(root = ROOT) {
|
|
39
|
+
check(existsSync(path.join(root, TERMINAL_REF)), '缺少正式后端交付终点记录');
|
|
40
|
+
const result = spawnSync(process.execPath, [path.join(root, 'scripts/complete-backend-delivery'), 'verify', '--root', root], {
|
|
41
|
+
cwd: root, encoding: 'utf8', input: '', timeout: 120000, maxBuffer: 8 * 1024 * 1024,
|
|
42
|
+
env: { ...process.env, NODE_OPTIONS: '', NODE_PATH: '' },
|
|
43
|
+
});
|
|
44
|
+
check(!result.error && result.status === 0, result.error?.message || result.stderr || '后端交付终点复验失败');
|
|
45
|
+
return JSON.parse(result.stdout);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function assertScopeWorkUnit(workUnit, { root = ROOT, readOnly = false } = {}) {
|
|
49
|
+
const scope = loadExecutionScope(root);
|
|
50
|
+
if (!scope) { check(workUnit !== 'work-unit.backend-delivery', '后端终点需要显式职责范围'); return null; }
|
|
51
|
+
check(scope.allowed_work_units.includes(workUnit), `职责范围不允许 ${workUnit}`);
|
|
52
|
+
if (existsSync(path.join(root, TERMINAL_REF))) {
|
|
53
|
+
verifyDeliveryTerminal(root);
|
|
54
|
+
check(readOnly, '后端交付已完成;不能恢复实现或自动发布');
|
|
55
|
+
}
|
|
56
|
+
return scope;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function scopedNextRoutes(workUnit, routes, { root = ROOT } = {}) {
|
|
60
|
+
const scope = loadExecutionScope(root);
|
|
61
|
+
if (!scope) return routes.filter(id => id !== 'work-unit.backend-delivery');
|
|
62
|
+
assertScopeWorkUnit(workUnit, { root, readOnly: true });
|
|
63
|
+
if (existsSync(path.join(root, TERMINAL_REF))) return [];
|
|
64
|
+
return (scope.route_overrides[workUnit] || routes).filter(id => scope.allowed_work_units.includes(id));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function assertScopeTransition(current, next, state, { root = ROOT } = {}) {
|
|
68
|
+
const scope = loadExecutionScope(root);
|
|
69
|
+
if (!scope) { check(current !== 'work-unit.backend-delivery' && next !== 'work-unit.backend-delivery', '后端终点需要显式职责范围'); return; }
|
|
70
|
+
if (current === scope.terminal_work_unit && next === null) { verifyDeliveryTerminal(root); return; }
|
|
71
|
+
assertScopeWorkUnit(current, { root });
|
|
72
|
+
if (next) assertScopeWorkUnit(next, { root });
|
|
73
|
+
check(next !== null, '不能把中间阶段声明为后端交付完成');
|
|
74
|
+
assertScopeImpacts(state, { root });
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function assertScopeImpacts(state, { root = ROOT } = {}) {
|
|
78
|
+
if (!loadExecutionScope(root)) return;
|
|
79
|
+
check(state?.delivery_impacts?.frontend !== true, '产品 UI 设计保留,生产前端实现必须交给下游');
|
|
80
|
+
if (state?.ui_impact === true) {
|
|
81
|
+
const deferred = state.downstream_frontend;
|
|
82
|
+
check(deferred && ['owner', 'ticket_ref', 'verification_plan', 'target_version'].every(key => typeof deferred[key] === 'string' && deferred[key].trim()), 'UI 产品须明确下游前端责任、Ticket、验证计划和目标版本');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function assertScopeSlice(contract, { root = ROOT } = {}) {
|
|
87
|
+
if (!loadExecutionScope(root)) return;
|
|
88
|
+
check(contract.backend?.status === 'required' && contract.frontend?.status === 'not-applicable', '本职责仅允许后端 Slice;产品 UI 设计不能混作前端实现批准');
|
|
89
|
+
check(!(contract.common?.impacted_areas || []).some(x => ['ui', 'frontend'].includes(x)), 'Slice 仍包含生产前端实现影响');
|
|
90
|
+
const roles = (contract.work_units || []).map(unit => unit.role_id);
|
|
91
|
+
check(!roles.includes('role.frontend-engineer'), '禁止派发前端实现');
|
|
92
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import {
|
|
2
|
+
import { writeFileSync } from 'node:fs';
|
|
3
|
+
import { readFileSync } from './validation-phase.mjs';
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { fileURLToPath } from "node:url";
|
|
5
6
|
import { parseDocument } from "../vendor/yaml.mjs";
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { assertTrackingTransition } from './stage-tracking.mjs';
|
|
2
|
+
import { assertScopeTransition, assertScopeImpacts, assertScopeWorkUnit, scopedNextRoutes } from './lifecycle-execution-scope.mjs';
|
|
1
3
|
// Wire capability marker: profile-local readiness rules are not interchangeable.
|
|
2
4
|
export const SLICE_REPOSITORY_PREPARATION_PROTOCOL = 1;
|
|
3
5
|
import { createHash } from "node:crypto";
|
|
@@ -43,7 +45,8 @@ const NEXT_ROUTES = deepFreeze({
|
|
|
43
45
|
[TICKET_DECOMPOSITION_WORK_UNIT]: [IMPLEMENTATION_WORK_UNIT],
|
|
44
46
|
[IMPLEMENTATION_WORK_UNIT]: ["work-unit.frontend-implementation-verification", "work-unit.code-review"],
|
|
45
47
|
"work-unit.frontend-implementation-verification": ["work-unit.code-review"],
|
|
46
|
-
"work-unit.code-review": ["work-unit.release-and-retrospective", IMPLEMENTATION_WORK_UNIT],
|
|
48
|
+
"work-unit.code-review": ["work-unit.release-and-retrospective", IMPLEMENTATION_WORK_UNIT, "work-unit.backend-delivery"],
|
|
49
|
+
"work-unit.backend-delivery": [],
|
|
47
50
|
"work-unit.release-and-retrospective": [],
|
|
48
51
|
});
|
|
49
52
|
|
|
@@ -249,8 +252,15 @@ function validateTicketReference(ref, trackerKind) {
|
|
|
249
252
|
* by `validateWorkflowExecutionResult` before this function is called.
|
|
250
253
|
*/
|
|
251
254
|
export function validateNextRoute(currentWorkUnit, nextRoute, decisionState, options = {}) {
|
|
252
|
-
|
|
253
|
-
|
|
255
|
+
try { assertTrackingTransition(currentWorkUnit, nextRoute, decisionState, { root: options.root || ROOT }); }
|
|
256
|
+
catch (error) { return blockedResult(['stage-tracking-blocked'], [error.message]); }
|
|
257
|
+
try { assertScopeTransition(currentWorkUnit, nextRoute, decisionState, options); }
|
|
258
|
+
catch (error) { return blockedResult(['execution-scope-blocked'], [error.message]); }
|
|
259
|
+
if (currentWorkUnit === "work-unit.code-review" && ["work-unit.release-and-retrospective", "work-unit.backend-delivery"].includes(nextRoute)) {
|
|
260
|
+
try {
|
|
261
|
+
if (decisionState?.review_input?.scope_kind !== "change") throw new Error("只读基线审计不能关闭实现审查");
|
|
262
|
+
validateBackendReview(decisionState, { root: options.root || ROOT });
|
|
263
|
+
}
|
|
254
264
|
catch (error) { return blockedResult(["backend-review-incomplete"], [error.message]); }
|
|
255
265
|
}
|
|
256
266
|
|
|
@@ -259,7 +269,7 @@ export function validateNextRoute(currentWorkUnit, nextRoute, decisionState, opt
|
|
|
259
269
|
try { enforceFrontendDelivery(decisionState, { root: options.root, phase: nextRoute === IMPLEMENTATION_WORK_UNIT ? "implementation" : "inputs" }); }
|
|
260
270
|
catch (error) { return blockedResult(["frontend-delivery-blocked"], [error.message]); }
|
|
261
271
|
}
|
|
262
|
-
const routes = NEXT_ROUTES[currentWorkUnit];
|
|
272
|
+
const routes = NEXT_ROUTES[currentWorkUnit] && scopedNextRoutes(currentWorkUnit, NEXT_ROUTES[currentWorkUnit], options);
|
|
263
273
|
if (!routes) return blockedResult([BLOCKING_SIGNALS.invalidRoute], ["known_current_work_unit"]);
|
|
264
274
|
if (nextRoute === REPOSITORY_PREPARATION_WORK_UNIT && currentWorkUnit !== "work-unit.technical-analysis") {
|
|
265
275
|
return blockedResult([BLOCKING_SIGNALS.technicalAnalysisRequired], ["work-unit.technical-analysis predecessor"]);
|
|
@@ -296,6 +306,8 @@ export function validateNextRoute(currentWorkUnit, nextRoute, decisionState, opt
|
|
|
296
306
|
* generated and verified scaffold. Unaffected roles need an explicit reason.
|
|
297
307
|
*/
|
|
298
308
|
export function validateImplementationRepositoriesReady(state, { exists = existsSync, read = (ref) => readFileSync(ref, "utf8"), root = ROOT } = {}) {
|
|
309
|
+
try { assertScopeImpacts(state, { root }); }
|
|
310
|
+
catch (error) { return blockedResult(['execution-scope-blocked'], [error.message]); }
|
|
299
311
|
const preparation = state?.implementation_repository_preparation;
|
|
300
312
|
const impacts = state?.delivery_impacts;
|
|
301
313
|
const signals = [];
|
|
@@ -408,6 +420,13 @@ function validateDecisionBoundary(workUnit, state, options) {
|
|
|
408
420
|
* `exists` is injectable so external adapters can resolve their own tracker refs.
|
|
409
421
|
*/
|
|
410
422
|
export function validateTicketFormalization(state, { exists = existsSync, read = (ref) => readFileSync(ref, "utf8"), ...decisionOptions } = {}) {
|
|
423
|
+
if ((state?.tracker_kind ?? "local-markdown") === "local-markdown" && state?.vertical_slice_ticket?.ref && isReadable(state.vertical_slice_ticket.ref, exists)) {
|
|
424
|
+
try {
|
|
425
|
+
const header = read(state.vertical_slice_ticket.ref).match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
426
|
+
const kind = header ? parseDocument(header[1], { uniqueKeys: true }).toJS({ maxAliasCount: 0 })?.kind : null;
|
|
427
|
+
if (kind === "stage-work-item") return blockedResult(["stage-work-item-not-implementable"], ["vertical-slice-ticket required"]);
|
|
428
|
+
} catch { return blockedResult(["ticket-content-unreadable"], ["readable vertical slice content"]); }
|
|
429
|
+
}
|
|
411
430
|
try { enforceFrontendDelivery(state, { root: decisionOptions.root, phase: "implementation" }); }
|
|
412
431
|
catch (error) { return blockedResult(["frontend-delivery-blocked"], [error.message]); }
|
|
413
432
|
const repositoryResult = validateImplementationRepositoriesReady(state, { exists, read, ...decisionOptions });
|
|
@@ -529,6 +548,8 @@ export function validateTicketFormalization(state, { exists = existsSync, read =
|
|
|
529
548
|
* Validate the complete implementation entry seam after ready-for-agent promotion.
|
|
530
549
|
*/
|
|
531
550
|
export function validateImplementationEntry(state, options = {}) {
|
|
551
|
+
try { assertScopeWorkUnit(IMPLEMENTATION_WORK_UNIT, options); assertScopeImpacts(state, options); }
|
|
552
|
+
catch (error) { return blockedResult(['execution-scope-blocked'], [error.message]); }
|
|
532
553
|
const ticketResult = validateTicketFormalization(state, options);
|
|
533
554
|
if (ticketResult.result === "blocked") return ticketResult;
|
|
534
555
|
if (state?.predecessor_work_unit !== TICKET_DECOMPOSITION_WORK_UNIT) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import {
|
|
2
|
+
import { realpathSync } from "node:fs";
|
|
3
|
+
import { existsSync, lstatSync, readFileSync } from "./validation-phase.mjs";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { fileURLToPath } from "node:url";
|
|
5
6
|
import { parseAllDocuments, parseDocument } from "../vendor/yaml.mjs";
|
|
@@ -31,6 +31,8 @@ function files(directory, prefix = "") {
|
|
|
31
31
|
if (!info.isDirectory()) fail(`技能源必须是目录: ${directory}`);
|
|
32
32
|
const result = new Map();
|
|
33
33
|
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
34
|
+
// Match the skill supply-chain inventory: interpreter caches are not source.
|
|
35
|
+
if (entry.name === "__pycache__" || entry.name === ".DS_Store" || /\.(iml|pyc|pyo)$/.test(entry.name)) continue;
|
|
34
36
|
if (entry.isSymbolicLink()) fail(`跨仓同步不接受符号链接: ${path.join(directory, entry.name)}`);
|
|
35
37
|
const absolute = path.join(directory, entry.name);
|
|
36
38
|
const relative = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
@@ -103,6 +105,29 @@ function dirtyMatch(dirty, relative) {
|
|
|
103
105
|
return [...dirty].some((entry) => entry === relative || entry.startsWith(`${relative}/`) || relative.startsWith(`${entry}/`));
|
|
104
106
|
}
|
|
105
107
|
|
|
108
|
+
function checkEntryReferences(profile, profileRoot, definition, changes, issues) {
|
|
109
|
+
const overlay = new Map(changes.filter((item) => item.profile === profile).map((item) => [path.resolve(profileRoot, item.path), item.content]));
|
|
110
|
+
const entries = new Set();
|
|
111
|
+
for (const relative of [".agents/skills", ...(definition.reference_roots ?? [])]) {
|
|
112
|
+
const directory = safe(profileRoot, relative, "reference root");
|
|
113
|
+
for (const name of files(directory).keys()) if (name.endsWith("/SKILL.md")) entries.add(path.join(directory, name));
|
|
114
|
+
}
|
|
115
|
+
for (const [file, content] of overlay) if (content !== null && file.endsWith("/SKILL.md")) entries.add(file);
|
|
116
|
+
for (const file of entries) {
|
|
117
|
+
const content = overlay.has(file) ? overlay.get(file) : readFileSync(file);
|
|
118
|
+
if (content === null) continue;
|
|
119
|
+
const prose = content.toString("utf8").replace(/```[\s\S]*?```/g, "").replace(/`[^`]*`/g, "");
|
|
120
|
+
for (const match of prose.matchAll(/\]\(([^\s)]+)\)/g)) {
|
|
121
|
+
const link = match[1].split("#")[0];
|
|
122
|
+
if (!link || /^[a-z][a-z\d+.-]*:/i.test(link) || link.includes("<")) continue;
|
|
123
|
+
const target = path.resolve(path.dirname(file), link);
|
|
124
|
+
const inside = target.startsWith(`${path.resolve(profileRoot)}${path.sep}`);
|
|
125
|
+
const present = inside && (overlay.has(target) ? overlay.get(target) !== null : existsSync(target));
|
|
126
|
+
if (!present) issues.push({ profile, status: "missing_reference", path: `${definition.target}/${path.relative(profileRoot, file)}`, message: `Skill 引用无法解析: ${link}` });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
106
131
|
function transformedSource(root, profile, item) {
|
|
107
132
|
const source = safe(root, item.source ?? `.agents/skills/${item.id}`, "source");
|
|
108
133
|
const sourceFiles = files(source);
|
|
@@ -262,22 +287,38 @@ export function planProfileSkillSync({ root, config, selectedProfiles, dirtyProv
|
|
|
262
287
|
const targetSkillRoot = safe(profileRoot, ".agents/skills", "profile skill root");
|
|
263
288
|
if (existsSync(targetSkillRoot)) {
|
|
264
289
|
for (const entry of readdirSync(targetSkillRoot, { withFileTypes: true })) {
|
|
265
|
-
if (!entry.isDirectory() ||
|
|
266
|
-
const
|
|
267
|
-
if (
|
|
268
|
-
|
|
290
|
+
if (!entry.isDirectory() || !existsSync(path.join(targetSkillRoot, entry.name, "SKILL.md"))) continue;
|
|
291
|
+
const classification = classified.get(entry.name);
|
|
292
|
+
if (classification === "excluded") {
|
|
293
|
+
issues.push({ profile, skill: entry.name, status: "active_excluded", path: `${definition.target}/.agents/skills/${entry.name}`, message: "活跃 Skill 不能用 excluded 跳过维护;登记 exact、adapted、local_only 或 upstream" });
|
|
294
|
+
} else if (!classification) {
|
|
269
295
|
issues.push({
|
|
270
296
|
profile,
|
|
271
297
|
skill: entry.name,
|
|
272
298
|
status: "unregistered_difference",
|
|
273
299
|
path: `${definition.target}/.agents/skills/${entry.name}`,
|
|
274
|
-
message: "
|
|
300
|
+
message: "实际 Skill 入口未登记同步分类(包括内容相同及 profile 独有入口)",
|
|
275
301
|
});
|
|
276
302
|
}
|
|
277
303
|
}
|
|
278
304
|
}
|
|
279
305
|
|
|
306
|
+
// Platform packages are source directories, unlike generated shared projections.
|
|
307
|
+
// Register them using exact/adapted source and target paths; keep schema v1 readable.
|
|
308
|
+
for (const platformRoot of config.platform_roots ?? []) {
|
|
309
|
+
const directory = safe(profileRoot, platformRoot, "platform root");
|
|
310
|
+
if (!existsSync(directory)) continue;
|
|
311
|
+
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
312
|
+
if (!entry.isDirectory() || existsSync(path.join(targetSkillRoot, entry.name, "SKILL.md"))) continue;
|
|
313
|
+
const relative = `${platformRoot}/${entry.name}`;
|
|
314
|
+
if (![...files(path.join(directory, entry.name)).keys()].some((name) => name === "SKILL.md" || name.endsWith("/SKILL.md"))) continue;
|
|
315
|
+
const owners = [...(definition.exact ?? []), ...(definition.adapted ?? [])].filter((item) => item.target === relative);
|
|
316
|
+
if (owners.length !== 1) issues.push({ profile, skill: entry.name, status: "unregistered_platform_package", path: `${definition.target}/${relative}`, message: "平台技能包必须按完整包路径登记唯一来源" });
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
280
320
|
const changedPaths = [...new Set(changes.filter((item) => item.profile === profile).map((item) => item.path))];
|
|
321
|
+
if (config.verify_entry_references) checkEntryReferences(profile, profileRoot, definition, changes, issues);
|
|
281
322
|
const dirty = dirtyProvider(profileRoot, changedPaths);
|
|
282
323
|
for (const change of changes.filter((item) => item.profile === profile && dirtyMatch(dirty, item.path))) {
|
|
283
324
|
issues.push({ profile, skill: change.skill, status: "adaptation_conflict", path: `${definition.target}/${change.path}`, message: "目标含未提交改动" });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from
|
|
1
|
+
import { existsSync, readFileSync } from './validation-phase.mjs';
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { parseDocument } from "../vendor/yaml.mjs";
|
|
4
4
|
import { nestedSkillPaths, OBSOLETE, PROJECTION_ROOTS, ROOT, unregisteredNestedSkillPaths } from "./skill-supply-chain.mjs";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import {readContractSource,contractSourceMetadata} from './contract-source.mjs';
|
|
1
2
|
import {sliceRepositories} from './slice-repositories.mjs';
|
|
2
3
|
import { sliceCheckApplicability } from './slice-applicability.mjs';
|
|
3
4
|
import path from 'node:path';
|
|
4
|
-
import fs from '
|
|
5
|
+
import fs, {withValidationPhase} from './validation-phase.mjs';
|
|
5
6
|
import { stringify } from '../vendor/yaml.mjs';
|
|
6
7
|
import { safe, hash, digest, write } from './strategic-handoff-io.mjs';
|
|
7
8
|
import { compileDefaultImplementationContract, digestDocument, loadCompilerContract } from './implementation-contract-compiler.mjs';
|
|
@@ -9,11 +10,7 @@ import { normalizeSliceContract, parseSliceYaml, readSliceSources, resolveSliceB
|
|
|
9
10
|
|
|
10
11
|
const object=value=>value && typeof value==='object' && !Array.isArray(value);
|
|
11
12
|
const same=(a,b)=>digest(a)===digest(b);
|
|
12
|
-
|
|
13
|
-
const front=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(text);
|
|
14
|
-
if(front)return parseSliceYaml(front[1]);
|
|
15
|
-
return (/^\s*[{[]/.test(text)||/^[A-Za-z_][\w-]*:\s/m.test(text)&&!/^#/m.test(text))?parseSliceYaml(text):{};
|
|
16
|
-
}
|
|
13
|
+
const metadata=contractSourceMetadata;
|
|
17
14
|
function mergeFacts(left,right,path,report) {
|
|
18
15
|
if(left===undefined)return structuredClone(right);
|
|
19
16
|
if(right===undefined)return structuredClone(left);
|
|
@@ -43,7 +40,15 @@ function lifecycleSources(checkpoint,report) {
|
|
|
43
40
|
return result;
|
|
44
41
|
}
|
|
45
42
|
/** sources select existing assets; refinements contain ONLY new slice facts, never an approved contract. */
|
|
46
|
-
export function prepareSliceImplementationContract(
|
|
43
|
+
export function prepareSliceImplementationContract(options={}) {
|
|
44
|
+
let result;
|
|
45
|
+
try{return withValidationPhase({root:options.root,purpose:'slice-prepare',slice_id:options.ticket_ref,readOnly:true,signal:options.signal},()=>result=prepare(options));}
|
|
46
|
+
catch(error){
|
|
47
|
+
if(!result||!['VALIDATION_INPUT_CHANGED','VALIDATION_CANCELLED'].includes(error.code))throw error;
|
|
48
|
+
result.slice_contract.status='blocked';result.report.blockers.push({code:error.code==='VALIDATION_INPUT_CHANGED'?'SLICE_INPUT_CONFLICT':error.code,field:'slice',source_ref:null,reason:`${error.message.includes('compiler-contract.yaml')?'编译规则来源冲突':'生成期间来源变化'}: ${error.message}`,responsibility:'professional-review',recovery:'重新读取当前来源并准备新草案'});return result;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function prepare({root=process.cwd(),ticket_ref,checkpoint_ref,sources={},refinements={},approved_slice}={}) {
|
|
47
52
|
const started=performance.now();
|
|
48
53
|
const report={read_only:true,blockers:[],sources:{},provenance:[],reason_chains:{},checks:[]};
|
|
49
54
|
const snapshots=new Map();
|
|
@@ -52,6 +57,7 @@ export function prepareSliceImplementationContract({root=process.cwd(),ticket_re
|
|
|
52
57
|
try {
|
|
53
58
|
let ticketText='',ticket={},saved={};
|
|
54
59
|
try {ticketText=read(ticket_ref).toString('utf8');ticket=metadata(ticketText);}catch(error){report.blockers.push({code:'SLICE_SOURCE_UNREADABLE',field:'basis.ticket',source_ref:ticket_ref,reason:error.message});}
|
|
60
|
+
if (ticket.kind === 'stage-work-item' || /\/work-items\//.test(ticket_ref || '')) report.blockers.push({code:'STAGE_WORK_ITEM_NOT_IMPLEMENTABLE',field:'basis.ticket',reason:'stage-work-item 不能作为实现 Ticket'});
|
|
55
61
|
if(checkpoint_ref)try {saved=parseSliceYaml(read(checkpoint_ref));}catch(error){report.blockers.push({code:'SLICE_SOURCE_UNREADABLE',field:'checkpoint',source_ref:checkpoint_ref,reason:error.message});}
|
|
56
62
|
const fromTicket=ticket.slice_implementation || {};
|
|
57
63
|
const facts=mergeFacts(saved.slice_implementation || {},fromTicket,'slice',report);
|
|
@@ -73,13 +79,9 @@ export function prepareSliceImplementationContract({root=process.cwd(),ticket_re
|
|
|
73
79
|
try {
|
|
74
80
|
if(typeof value==='string' && Object.hasOwn(selected,value)) {basis[key]=value;continue;}
|
|
75
81
|
const binding=typeof value==='string'?{ref:value}:value;
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const sourceVersion=data.requirement_version??data.version??data.contract_version;
|
|
80
|
-
if(binding.version!==undefined&&sourceVersion!==undefined&&String(binding.version)!==String(sourceVersion))throw new TypeError(`来源版本冲突: ${key}`);
|
|
81
|
-
const version=binding.version||data.requirement_version||data.version||data.contract_version;
|
|
82
|
-
basis[key]={ref:binding.ref,digest:rawDigest,...(version?{version:String(version)}:{}),...(binding.approval_ref?{approval_ref:binding.approval_ref}:{})};
|
|
82
|
+
const source=readContractSource(binding,{root,read});
|
|
83
|
+
const rawDigest=source.binding.digest;
|
|
84
|
+
basis[key]=source.binding;
|
|
83
85
|
if(seen.has(binding.ref)) {
|
|
84
86
|
const previous=seen.get(binding.ref);
|
|
85
87
|
if(!same(basis[key],basis[previous]))throw new TypeError(`来源绑定冲突: ${key}/${previous}`);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import fs from '
|
|
1
|
+
import fs from './validation-phase.mjs';
|
|
2
2
|
import { safe, hash, digest } from './strategic-handoff-io.mjs';
|
|
3
3
|
import { selectSliceWorkUnit, readSliceContract, readSliceSources, sliceAcceptanceText, parseSliceYaml, sourceSliceContract } from './slice-contract.mjs';
|
|
4
4
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {validateExistingUiBaseline} from './existing-ui-baseline.mjs';
|
|
2
2
|
import {sliceRepositories} from './slice-repositories.mjs';
|
|
3
3
|
import { sliceCheckApplicability } from './slice-applicability.mjs';
|
|
4
|
-
import fs from '
|
|
4
|
+
import fs, {validationMemo} from './validation-phase.mjs';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { parseDocument } from '../vendor/yaml.mjs';
|
|
7
7
|
import { safe, hash, digest, schema } from './strategic-handoff-io.mjs';
|
|
8
8
|
|
|
9
|
+
const parseCache=Symbol('slice-yaml');
|
|
9
10
|
const originals = new WeakMap();
|
|
10
11
|
const sourceSnapshots = new WeakMap();
|
|
11
12
|
const nonempty = value => typeof value === 'string' && value.trim();
|
|
@@ -13,7 +14,8 @@ const unique = values => [...new Set(values)];
|
|
|
13
14
|
const fail = message => { throw new TypeError(`slice-contract-invalid: ${message}`); };
|
|
14
15
|
const requireThat = (ok, message) => { if (!ok) fail(message); };
|
|
15
16
|
export const sourceSliceContract = value => originals.get(value) || value?.slice_contract || value;
|
|
16
|
-
export function parseSliceYaml(bytes) {
|
|
17
|
+
export function parseSliceYaml(bytes) {return validationMemo(parseCache,String(bytes),()=>parseSliceYamlFresh(bytes));}
|
|
18
|
+
function parseSliceYamlFresh(bytes) {
|
|
17
19
|
const doc = parseDocument(String(bytes), { uniqueKeys: true, intAsBigInt: true });
|
|
18
20
|
requireThat(!doc.errors.length, `YAML 无效: ${doc.errors[0]?.message}`);
|
|
19
21
|
const value = doc.toJS({ maxAliasCount: 0 });
|
|
@@ -99,10 +101,23 @@ export function sliceAcceptanceText(contract, sources) {
|
|
|
99
101
|
export function normalizeSliceContract(document, options = {}) {
|
|
100
102
|
const raw = sourceSliceContract(document);
|
|
101
103
|
requireThat(raw && [2,3].includes(raw.schema_version), 'Slice Implementation Contract schema v1 已停止支持;需要 schema v2 或 v3');
|
|
102
|
-
if (raw.schema_version === 2)
|
|
104
|
+
if (raw.schema_version === 2) {
|
|
105
|
+
const ref = raw.lifecycle_refs?.ticket;
|
|
106
|
+
if (ref) {
|
|
107
|
+
requireThat(!/\/work-items\//.test(ref), 'stage-work-item 不能作为实现 Ticket');
|
|
108
|
+
const file = safe(options.root || process.cwd(), ref, { missing: true });
|
|
109
|
+
if (fs.existsSync(file)) {
|
|
110
|
+
const header = fs.readFileSync(file, 'utf8').match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
111
|
+
requireThat(!header || parseSliceYaml(header[1])?.kind !== 'stage-work-item', 'stage-work-item 不能作为实现 Ticket');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return structuredClone(raw);
|
|
115
|
+
}
|
|
103
116
|
schema(raw,'docs/process/schemas/slice-implementation-contract-v3.schema.json');
|
|
104
117
|
const sources=readSliceSources(raw,options), refs=Object.fromEntries(Object.entries(sources).map(([key,item])=>[key,item.ref]));
|
|
105
118
|
requireKeys(refs,['spec','ticket','engineering_baseline','implementation_repository','build_architecture_checklist'],'依据');
|
|
119
|
+
const ticketHeader = sources.ticket.text.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
120
|
+
requireThat(!/\/work-items\//.test(refs.ticket) && (!ticketHeader || parseSliceYaml(ticketHeader[1])?.kind !== 'stage-work-item'), 'stage-work-item 不能作为实现 Ticket');
|
|
106
121
|
if(!raw.applicability.checks)requireKeys(refs,['architecture_review'],'依据');
|
|
107
122
|
else {
|
|
108
123
|
requireKeys(refs,['lifecycle_registry','process_tailoring'],'适用性依据');
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
import { withValidationPhase } from './validation-phase.mjs';
|
|
1
2
|
import { readSliceContract } from './slice-contract.mjs';
|
|
2
3
|
import { createApprovedExecutionContext } from './approved-execution-context.mjs';
|
|
3
4
|
import { evaluateContractFreshness, loadCompilerContract } from './implementation-contract-compiler.mjs';
|
|
4
5
|
import { loadSkillRegistry } from './skill-registry.mjs';
|
|
5
6
|
|
|
6
7
|
/** Readability, structure and execution approval are different levels of evidence. */
|
|
7
|
-
export function inspectSliceContract(ref,
|
|
8
|
+
export function inspectSliceContract(ref, options = {}) {
|
|
9
|
+
return withValidationPhase({root:options.root,purpose:'slice-inspect',slice_id:ref,work_unit_id:options.work_unit_id,readOnly:true,signal:options.signal},()=>inspect(ref,options));
|
|
10
|
+
}
|
|
11
|
+
function inspect(ref, { root = process.cwd(), approval_ref, work_unit_id } = {}) {
|
|
8
12
|
const loaded = readSliceContract(ref, { root });
|
|
9
13
|
const { contract, binding } = loaded;
|
|
10
14
|
const checks = { readable: 'passed', structure: 'passed', approval: 'not-checked', freshness: 'not-checked' };
|
|
@@ -28,9 +32,9 @@ export function inspectSliceContract(ref, { root = process.cwd(), approval_ref,
|
|
|
28
32
|
if (approval_ref && !blockers.length) {
|
|
29
33
|
try {
|
|
30
34
|
const approved_slice = { ...binding, approval_ref };
|
|
31
|
-
const context = createApprovedExecutionContext(approved_slice, { root, contract, work_unit_id });
|
|
35
|
+
const context = createApprovedExecutionContext(approved_slice, { root, contract, work_unit_id, readOnly: true });
|
|
32
36
|
checks.approval = 'passed';
|
|
33
|
-
const current = evaluateContractFreshness(contract, { root, registry: loadSkillRegistry(), compilerContract: loadCompilerContract(), approved_slice, work_unit_id }, context);
|
|
37
|
+
const current = evaluateContractFreshness(contract, { root, registry: loadSkillRegistry(), compilerContract: loadCompilerContract(), approved_slice, work_unit_id, readOnly: true }, context);
|
|
34
38
|
checks.freshness = current.freshness === 'current' ? 'passed' : 'failed';
|
|
35
39
|
blockers.push(...current.reasons);
|
|
36
40
|
} catch (error) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {enforceHarnessTaskScope} from './harness-execution-scope.mjs';
|
|
2
|
-
import { readFileSync } from '
|
|
2
|
+
import { readFileSync, withValidationPhase } from './validation-phase.mjs';
|
|
3
3
|
import { ROOT, hash, safe, digest } from './strategic-handoff-io.mjs';
|
|
4
4
|
import { normalizeSliceContract, withinSlicePath, parseSliceYaml } from './slice-contract.mjs';
|
|
5
5
|
import { createApprovedExecutionContext, assertApprovedExecutionContext } from './approved-execution-context.mjs';
|
|
@@ -14,7 +14,8 @@ function generateTaskPackageDefaults(roleId,overrides,{rolesDoc}={}) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/** Compile dispatch from the approved YAML. Only runtime identity and task ID come from the caller. */
|
|
17
|
-
export function compileSliceTaskPackage(binding,{root
|
|
17
|
+
export function compileSliceTaskPackage(binding,options={}) {return withValidationPhase({root:options.root||ROOT,purpose:'slice-dispatch',slice_id:binding.ref,work_unit_id:options.work_unit_id,readOnly:false,signal:options.signal},()=>compile(binding,options));}
|
|
18
|
+
function compile(binding,{root=ROOT,work_unit_id,task_id,actor_id,runtime_id,execution_state='Worker',rolesDoc,user_decisions}={}) {
|
|
18
19
|
const actualRoles=parseSliceYaml(readFileSync(safe(root,'docs/agents/digital-human-roles.yaml')));
|
|
19
20
|
if(rolesDoc&&digest(rolesDoc)!==digest(actualRoles))fail('调用方不能替换接收端角色能力');
|
|
20
21
|
rolesDoc=actualRoles;
|