create-yss-spec 3.4.8 → 3.4.9
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/.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 +1 -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 +1 -1
- package/template/.agents/skills/yss-openapi-governance/SKILL.md +1 -32
- package/template/.agents/skills/yss-openapi-governance/references/governance-output.md +34 -0
- package/template/.agents/skills/yss-product-lifecycle/SKILL.md +1 -1
- package/template/.agents/skills/yss-prototype-stage/SKILL.md +1 -5
- package/template/.agents/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
- 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 +1 -1
- package/template/.agents/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
- package/template/.agents/skills/yss-tactical-design/SKILL.md +1 -3
- package/template/.agents/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
- 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 +1 -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 +1 -1
- package/template/.codex/skills/yss-openapi-governance/SKILL.md +1 -32
- package/template/.codex/skills/yss-openapi-governance/references/governance-output.md +34 -0
- package/template/.codex/skills/yss-product-lifecycle/SKILL.md +1 -1
- package/template/.codex/skills/yss-prototype-stage/SKILL.md +1 -5
- package/template/.codex/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
- 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 +1 -1
- package/template/.codex/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
- package/template/.codex/skills/yss-tactical-design/SKILL.md +1 -3
- package/template/.codex/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
- 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 +1 -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 +1 -1
- package/template/.cursor/skills/yss-openapi-governance/SKILL.md +1 -32
- package/template/.cursor/skills/yss-openapi-governance/references/governance-output.md +34 -0
- package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +1 -1
- package/template/.cursor/skills/yss-prototype-stage/SKILL.md +1 -5
- package/template/.cursor/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
- 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 +1 -1
- package/template/.cursor/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
- package/template/.cursor/skills/yss-tactical-design/SKILL.md +1 -3
- package/template/.cursor/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
- 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 +1 -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 +1 -1
- package/template/.pi/skills/yss-openapi-governance/SKILL.md +1 -32
- package/template/.pi/skills/yss-openapi-governance/references/governance-output.md +34 -0
- package/template/.pi/skills/yss-product-lifecycle/SKILL.md +1 -1
- package/template/.pi/skills/yss-prototype-stage/SKILL.md +1 -5
- package/template/.pi/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
- 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 +1 -1
- package/template/.pi/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
- package/template/.pi/skills/yss-tactical-design/SKILL.md +1 -3
- package/template/.pi/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
- 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/docs/process/schemas/digital-human-task-package.schema.json +60 -4
- package/template/scripts/backend-standards-coverage +26 -0
- package/template/scripts/lib/backend-review.mjs +58 -20
- package/template/scripts/lib/backend-standards-coverage.mjs +237 -0
- package/template/scripts/lib/first-slice-artifacts.mjs +1 -1
- package/template/scripts/lib/lifecycle-transition.mjs +4 -1
- package/template/scripts/lib/profile-skill-sync.mjs +46 -5
- package/template/skills-lock.json +64 -62
- package/template.snapshot.json +4 -4
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { spawnSync } from 'node:child_process';
|
|
5
|
+
import { parseSliceYaml } from './slice-contract.mjs';
|
|
6
|
+
import { treeHash } from './skill-supply-chain.mjs';
|
|
7
|
+
|
|
8
|
+
export const coverageDigest = value => createHash('sha256').update(typeof value === 'string' || Buffer.isBuffer(value) ? value : JSON.stringify(value)).digest('hex');
|
|
9
|
+
const ensure = (ok, message) => { if (!ok) throw Error(`backend-review: ${message}`); };
|
|
10
|
+
const beneath = (file, scope) => scope === '.' || file === scope || file.startsWith(`${scope}/`);
|
|
11
|
+
export const CORE_SKILLS = ['yss-web-controller','yss-dto','yss-domain','yss-application','yss-repository','yss-mybatis'];
|
|
12
|
+
const roleSkills = {web:'yss-web-controller',server:'yss-web-controller',domain:'yss-domain',application:'yss-application',service:'yss-application',core:'yss-application',infrastructure:'yss-repository',persistence:'yss-repository',repository:'yss-repository'};
|
|
13
|
+
export function coverageFile(root, ref) {
|
|
14
|
+
ensure(typeof ref === 'string' && ref && !path.isAbsolute(ref) && !ref.split(/[\\/]/).includes('..'), 'safe relative coverage reference required');
|
|
15
|
+
const resolved = fs.realpathSync(path.resolve(root, ref));
|
|
16
|
+
ensure(resolved.startsWith(`${fs.realpathSync(root)}${path.sep}`), 'coverage reference escapes root');
|
|
17
|
+
return resolved;
|
|
18
|
+
}
|
|
19
|
+
function binding(root, item) {
|
|
20
|
+
ensure(item?.ref && item?.digest, 'coverage basis ref/digest required');
|
|
21
|
+
const bytes = fs.readFileSync(coverageFile(root,item.ref));
|
|
22
|
+
ensure(coverageDigest(bytes) === item.digest.replace(/^sha256:/,''), `coverage basis stale: ${item.ref}`);
|
|
23
|
+
return parseSliceYaml(bytes.toString());
|
|
24
|
+
}
|
|
25
|
+
function files(root, prefix = '') {
|
|
26
|
+
return fs.readdirSync(path.join(root,prefix),{withFileTypes:true}).sort((a,b)=>a.name.localeCompare(b.name,'en')).flatMap(entry => {
|
|
27
|
+
if (['.git','target','node_modules'].includes(entry.name) || (prefix==='.template-source' && entry.name==='evidence')) return [];
|
|
28
|
+
const ref = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
29
|
+
ensure(!entry.isSymbolicLink(), `unresolved source symlink: ${ref}`);
|
|
30
|
+
return entry.isDirectory() ? files(root,ref) : [ref];
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function git(root,args) {
|
|
34
|
+
const r=spawnSync('git',args,{cwd:root,encoding:'utf8',maxBuffer:32*1024*1024});
|
|
35
|
+
ensure(r.status===0,`coverage git ${args[0]} failed`); return r.stdout;
|
|
36
|
+
}
|
|
37
|
+
function stripComments(source) {
|
|
38
|
+
// Exclude literals too: a diagnostic string containing "FooRepository" is not a dependency.
|
|
39
|
+
return source.replace(/"""[\s\S]*?"""|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\/\*[\s\S]*?\*\/|\/\/[^\n]*/g, value => value.replace(/[^\n]/g,' '));
|
|
40
|
+
}
|
|
41
|
+
function uses(from,to) {
|
|
42
|
+
return to.declared.some(name => from.tokens.has(name) && (from.pkg===to.pkg || from.code.includes(`${to.pkg}.${name}`) || from.code.includes(`import ${to.pkg}.*`)));
|
|
43
|
+
}
|
|
44
|
+
function javaType(ref,source) {
|
|
45
|
+
const code=stripComments(source), pkg=code.match(/\bpackage\s+([\w.]+)\s*;/)?.[1];
|
|
46
|
+
const declared=[...code.matchAll(/(?:@\s*interface|\bclass|\binterface|\benum|\brecord)\s+(\w+)/g)].map(m=>m[1]);
|
|
47
|
+
const annotations=[...code.matchAll(/@([\w.]+)/g)].map(m=>m[1].split('.').at(-1));
|
|
48
|
+
const parents=[...code.matchAll(/\b(?:extends|implements)\s+([\w.,<>\s]+?)(?=\{|\bpermits\b)/g)].flatMap(m=>m[1].match(/\b[A-Z]\w*/g)||[]);
|
|
49
|
+
const tokens=new Set(code.match(/\b[A-Z]\w*/g)||[]);
|
|
50
|
+
return {ref,code,pkg,declared,annotations,parents,tokens,http:false,roles:new Set()};
|
|
51
|
+
}
|
|
52
|
+
function readRules(root,skill) {
|
|
53
|
+
ensure(/^[a-z][a-z0-9-]*$/.test(skill),'invalid skill identifier');
|
|
54
|
+
const folder=`.agents/skills/${skill}`;
|
|
55
|
+
ensure(fs.existsSync(path.join(root,folder,'SKILL.md')), `missing applicable skill: ${skill}`);
|
|
56
|
+
const sources=files(path.join(root,folder)).filter(p=>p.endsWith('.md') && !p.includes('source-index'));
|
|
57
|
+
const rules=[],sourceDigests=[];
|
|
58
|
+
for (const name of sources) {
|
|
59
|
+
const ref=`${folder}/${name}`, source=fs.readFileSync(coverageFile(root,ref),'utf8');
|
|
60
|
+
sourceDigests.push({ref,digest:coverageDigest(source)});
|
|
61
|
+
for (const m of source.matchAll(/^<!-- yss-rule (\{[^\n]+\}) -->$/gm)) {
|
|
62
|
+
const rule=JSON.parse(m[1]);
|
|
63
|
+
ensure(/^[a-z][a-z0-9.-]+$/.test(rule.id) && rule.level==='mandatory' && ['always','change','web','wire','domain','application','persistence','mybatis','pagination','batch'].includes(rule.when), `invalid rule declaration: ${ref}`);
|
|
64
|
+
ensure(source.includes(`<a id="${rule.id}"></a>`),`rule anchor missing: ${rule.id}`);
|
|
65
|
+
rules.push({...rule,skill,rule_ref:`${ref}#${rule.id}`,rule_digest:coverageDigest(source)});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Whole-text semantic review is always required, including unstructured auxiliary rules.
|
|
69
|
+
const ref=`${folder}/SKILL.md`;
|
|
70
|
+
rules.push({id:`${skill}.full-text`,when:'always',level:'mandatory',evidence:'semantic-review',skill,rule_ref:ref,rule_digest:coverageDigest(fs.readFileSync(coverageFile(root,ref)))});
|
|
71
|
+
return {rules,sourceDigests};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Read-only derivation: never approves a contract or executes project build commands. */
|
|
75
|
+
export function compileStandardsCoverage({root,projectRoot,contract=null,scope_kind='baseline',baseline_binding=null,comparison_ref=null,actual_skills=[],responsibility_evidence=[]}={}) {
|
|
76
|
+
ensure(['baseline','change'].includes(scope_kind),'scope_kind required');
|
|
77
|
+
root=fs.realpathSync(root);projectRoot=fs.realpathSync(projectRoot);
|
|
78
|
+
const basis=contract?.resolution?.architecture_evidence?.engineering_baseline || baseline_binding;
|
|
79
|
+
const baseline=basis?binding(root,basis):null;
|
|
80
|
+
const identity=contract?.resolution?.architecture_identity || baseline?.architecture_identity;
|
|
81
|
+
const family=identity?.architecture_family;
|
|
82
|
+
const issues=[];
|
|
83
|
+
if (baseline && (baseline.kind!=='existing-engineering-baseline' || baseline.status!=='current') && identity?.source_kind==='existing-registration') issues.push({id:'baseline-not-current',reason:'既有工程基线未标记为当前观测,须先核对登记'});
|
|
84
|
+
if (!['domain-driven','layered-mvc'].includes(family)) issues.push({id:'architecture-unknown',reason:'需要登记架构;只读盘点不能猜测 DDD/MVC'});
|
|
85
|
+
const all=files(projectRoot);
|
|
86
|
+
const roots=baseline?.source?.roots || ['.'];
|
|
87
|
+
ensure(roots.every(r=>r==='.' || (!path.isAbsolute(r)&&!r.split('/').includes('..'))),'invalid registered source roots');
|
|
88
|
+
const selected=all.filter(ref=>roots.some(r=>beneath(ref,r)));
|
|
89
|
+
const outside=all.filter(ref=>!selected.includes(ref)&&ref.endsWith('.java'));
|
|
90
|
+
if (outside.length) issues.push({id:'unregistered-source',reason:outside.join(', ')});
|
|
91
|
+
const inventory=selected.map(ref=>({path:ref,mode:fs.statSync(coverageFile(projectRoot,ref)).mode,digest:coverageDigest(fs.readFileSync(coverageFile(projectRoot,ref)))}));
|
|
92
|
+
const types=selected.filter(ref=>ref.endsWith('.java')).map(ref=>javaType(ref,fs.readFileSync(coverageFile(projectRoot,ref),'utf8')));
|
|
93
|
+
for(const t of types) if(!t.declared.length || /\\u[0-9a-fA-F]{4}/.test(t.code)) issues.push({id:`unparsed:${t.ref}`,reason:'源码类型解析不足,须人工核实或编译态证据'});
|
|
94
|
+
if(!types.some(t=>!t.ref.includes('/test/'))) issues.push({id:'zero-business-types',reason:'未发现业务类型,不能证明存量工程合规'});
|
|
95
|
+
const httpNames=new Set(['RestController','Controller','RequestMapping','GetMapping','PostMapping','PutMapping','DeleteMapping','PatchMapping']);
|
|
96
|
+
let changed=true;
|
|
97
|
+
while(changed){changed=false;for(const t of types) if(!t.http&&(t.annotations.some(a=>httpNames.has(a))||t.parents.some(p=>httpNames.has(p)))){t.http=true;for(const name of t.declared)httpNames.add(name);changed=true;}}
|
|
98
|
+
const localNames=new Set(types.flatMap(t=>t.declared));
|
|
99
|
+
const familiar=new Set([...httpNames,'interface','Override','Deprecated','SuppressWarnings','FunctionalInterface','Serializable','Comparable','Exception','RuntimeException','Service','Repository','Mapper','Entity','TableName','Id','TableId','Autowired','Component','Configuration','Bean','Valid','Validated','NotNull','NotBlank','Size','Min','Max','Pattern','RequestBody','RequestParam','PathVariable','RequestHeader','CookieValue','ResponseBody','ResponseStatus','ExceptionHandler','ControllerAdvice','RestControllerAdvice','Transactional','Data','Getter','Setter','Builder','NoArgsConstructor','AllArgsConstructor','RequiredArgsConstructor','Slf4j','EqualsAndHashCode','ToString','JsonProperty','JsonIgnore','JsonCreator','Test']);
|
|
100
|
+
const resolutions=responsibility_evidence.map(item=>({...binding(root,item),binding:item}));
|
|
101
|
+
const units=baseline?.build_units || [];
|
|
102
|
+
for(const t of types) {
|
|
103
|
+
for(const u of units) for(const [role,refs] of Object.entries(u.role_paths||{})) if(refs.some(ref=>beneath(t.ref,ref))) t.roles.add(role);
|
|
104
|
+
for(const a of contract?.backend?.first_slice?.artifacts||[]) if(a.path===t.ref)t.roles.add(a.role);
|
|
105
|
+
if(t.http)t.roles.add('web');
|
|
106
|
+
if(t.annotations.includes('Service'))t.roles.add('application');
|
|
107
|
+
if(t.annotations.some(a=>['Repository','Entity','TableName'].includes(a))||(t.annotations.includes('Mapper')&&!/org\.mapstruct/.test(t.code))||/\b(?:JdbcTemplate|SqlSession|EntityManager|BaseMapper)\b/.test(t.code))t.roles.add('persistence');
|
|
108
|
+
const unresolved=[...t.annotations,...t.parents].filter(n=>!localNames.has(n)&&!familiar.has(n));
|
|
109
|
+
if((unresolved.length || (!t.roles.size && !/@\s*interface\b/.test(t.code))) && !t.ref.includes('/test/')) {
|
|
110
|
+
const resolution=resolutions.find(r=>r.source_ref===t.ref);
|
|
111
|
+
if(!resolution)t.uncertainty={id:`unresolved-responsibility:${t.ref}`,reason:unresolved.join(', ')||'type has no registered or observed responsibility'};
|
|
112
|
+
else {
|
|
113
|
+
ensure(resolution.source_digest===coverageDigest(fs.readFileSync(coverageFile(projectRoot,t.ref))) && typeof resolution.reason==='string' && resolution.reason.trim() && Array.isArray(resolution.roles) && resolution.roles.length && resolution.roles.every(r=>roleSkills[r]||r==='data'),'responsibility evidence stale or invalid');
|
|
114
|
+
ensure(resolution.evidence_ref && resolution.evidence_digest && coverageDigest(fs.readFileSync(coverageFile(root,resolution.evidence_ref)))===resolution.evidence_digest,'responsibility verification evidence stale');
|
|
115
|
+
resolution.roles.forEach(r=>t.roles.add(r));
|
|
116
|
+
if(resolution.roles.some(r=>['web','server'].includes(r)))t.http=true;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
}
|
|
121
|
+
let active=types, changedPaths=[];
|
|
122
|
+
if(scope_kind==='change') {
|
|
123
|
+
ensure(contract && comparison_ref,'change coverage needs approved contract and comparison_ref');
|
|
124
|
+
ensure(/^[a-f0-9]{40}$/.test(comparison_ref),'comparison_ref must be an immutable commit');
|
|
125
|
+
changedPaths=[...new Set([...git(projectRoot,['diff','--name-only',comparison_ref]).trim().split('\n'),...git(projectRoot,['ls-files','--others','--exclude-standard']).trim().split('\n')].filter(Boolean))];
|
|
126
|
+
const affected=new Set(types.filter(t=>changedPaths.includes(t.ref)));
|
|
127
|
+
// Source inventory is broad; semantic work is restricted to changed types and bidirectional dependency closure.
|
|
128
|
+
let expanding=true;
|
|
129
|
+
while(expanding){expanding=false;for(const t of types)if(!affected.has(t)&&[...affected].some(a=>uses(t,a)||uses(a,t))){affected.add(t);expanding=true;}}
|
|
130
|
+
active=[...affected];
|
|
131
|
+
if(changedPaths.some(p=>selected.includes(p)&&!p.endsWith('.java')&&!p.startsWith('.template-source/'))) active=types; // config/build changes can affect all types
|
|
132
|
+
}
|
|
133
|
+
issues.push(...active.flatMap(t=>t.uncertainty?[t.uncertainty]:[]));
|
|
134
|
+
const tags=new Set(['always',...(scope_kind==='change'?['change']:[])]), reasons=new Map();
|
|
135
|
+
const add=(skill,reason)=>{if(!reasons.has(skill))reasons.set(skill,new Set());reasons.get(skill).add(reason);};
|
|
136
|
+
const declaredSkills=[...(contract?.resolution?.required_skills||[]),...(contract?.common?.required_skills||[]),...(contract?.backend?.required_skills||[])];
|
|
137
|
+
for(const s of [...declaredSkills,...actual_skills])add(s,'contract-or-declared-impact');
|
|
138
|
+
add('alibaba-java-code-style','backend-scope');
|
|
139
|
+
for(const t of active.filter(t=>!t.ref.includes('/test/'))) {
|
|
140
|
+
for(const role of t.roles)if(roleSkills[role])add(roleSkills[role],t.ref);
|
|
141
|
+
if(t.http){tags.add('web');tags.add('wire');add('yss-dto',t.ref);}
|
|
142
|
+
if(/\b(?:PageResult|PageQuery|CommandDTO|QueryDTO|SingleResult|MultiResult)\b/.test(t.code)){tags.add('wire');add('yss-dto',t.ref);}
|
|
143
|
+
if(t.roles.has('domain')&&family==='domain-driven')tags.add('domain');
|
|
144
|
+
if([...t.roles].some(r=>['application','service','core'].includes(r)))tags.add('application');
|
|
145
|
+
if([...t.roles].some(r=>['repository','persistence','infrastructure'].includes(r)))tags.add('persistence');
|
|
146
|
+
if(/\b(?:PageQuery|PageRequest|PageResult|IPage|PageHelper|pageIndex|pageSize)\b/.test(t.code))tags.add('pagination');
|
|
147
|
+
if(/\b(?:insertBatch|saveBatch|updateBatch|executeBatch)\b/.test(t.code))tags.add('batch');
|
|
148
|
+
for(const [regex,skill] of [[/\b(?:Valid|Validated|NotNull|NotBlank|Size)\b/,'yss-validation'],[/\b(?:ExceptionHandler|ControllerAdvice|RestControllerAdvice)\b/,'yss-exception'],[/\borg\.mapstruct\b/,'mapstruct'],[/\blombok\b/,'lombok']])if(regex.test(t.code))add(skill,t.ref);
|
|
149
|
+
}
|
|
150
|
+
for(const layer of contract?.backend?.affected_layers||[]) if(roleSkills[layer])add(roleSkills[layer],`affected-layer:${layer}`);
|
|
151
|
+
const configPaths=(scope_kind==='baseline'?selected:selected.filter(p=>changedPaths.includes(p))).filter(p=>/\.(?:xml|ya?ml|properties|sql|json)$/.test(p));
|
|
152
|
+
const runtimeText=[...active.map(t=>t.code),...configPaths.filter(p=>!p.endsWith('.java')).map(p=>fs.readFileSync(coverageFile(projectRoot,p),'utf8'))].join('\n');
|
|
153
|
+
// Derive component ownership from the existing registry and the locked platform index.
|
|
154
|
+
// These are discovery signals only; they never certify component compatibility.
|
|
155
|
+
const discovery_sources=[];
|
|
156
|
+
const registryRef='docs/agents/yss-skill-registry.yaml';
|
|
157
|
+
if(fs.existsSync(path.join(root,registryRef))) {
|
|
158
|
+
const registryBytes=fs.readFileSync(coverageFile(root,registryRef));
|
|
159
|
+
discovery_sources.push({ref:registryRef,digest:coverageDigest(registryBytes)});
|
|
160
|
+
const registry=parseSliceYaml(registryBytes.toString());
|
|
161
|
+
const line=identity?.platform_configuration?.component_platform_line;
|
|
162
|
+
if(!['boot2-java8','boot3-java17'].includes(line))issues.push({id:'component-discovery-platform-unknown',reason:'组件发现需要已登记的平台源码索引,不跨平台借证据'});
|
|
163
|
+
else for(const skill of [...new Set((registry.capabilities||[]).filter(c=>c.provider?.kind==='yss-component').map(c=>c.primary_skill))].sort()) {
|
|
164
|
+
ensure(/^[a-z][a-z0-9-]*$/.test(skill),'invalid registered component skill');
|
|
165
|
+
const ref=`.agents/skills/${skill}/references/source-index.${line}.md`;
|
|
166
|
+
if(!fs.existsSync(path.join(root,ref))){issues.push({id:`component-index-missing:${skill}`,reason:ref});continue;}
|
|
167
|
+
const source=fs.readFileSync(coverageFile(root,ref),'utf8');
|
|
168
|
+
discovery_sources.push({ref,digest:coverageDigest(source)});
|
|
169
|
+
const symbols=[...source.matchAll(/src\/main\/java\/([\w/$]+)\.java/g)].map(m=>m[1].replaceAll('/','.'));
|
|
170
|
+
const gavs=[...source.matchAll(/GAV `([^:`]+):([^:`]+):[^`]+`/g)];
|
|
171
|
+
const symbolHit=symbols.some(symbol=>runtimeText.includes(symbol) || runtimeText.includes(`import ${symbol.slice(0,symbol.lastIndexOf('.'))}.*`));
|
|
172
|
+
const artifactHit=gavs.some(([,group,artifact])=>runtimeText.includes(`<groupId>${group}</groupId>`) && runtimeText.includes(`<artifactId>${artifact}</artifactId>`));
|
|
173
|
+
if(symbolHit||artifactHit)add(skill,`registered-component-index:${ref}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if(/org\.apache\.ibatis|com\.baomidou|mybatis|<mapper\b/i.test(runtimeText)){tags.add('mybatis');tags.add('persistence');add('yss-mybatis','source-or-build-binding');add('yss-repository','source-or-build-binding');}
|
|
177
|
+
if(/\b(?:JdbcTemplate|EntityManager)\b|spring-boot-starter-data-jpa|<mapper\b/.test(runtimeText)){tags.add('persistence');add('yss-repository','source-or-build-binding');}
|
|
178
|
+
for(const [skill,tag] of [['yss-web-controller','web'],['yss-dto','wire'],['yss-domain','domain'],['yss-application','application'],['yss-repository','persistence'],['yss-mybatis','mybatis']])if(reasons.has(skill))tags.add(tag);
|
|
179
|
+
if(family==='layered-mvc'){tags.delete('domain');if(reasons.has('yss-domain'))issues.push({id:'mvc-domain-conflict',reason:'MVC 不应加载 DDD 专属技能,须回合同核对'});reasons.delete('yss-domain');}
|
|
180
|
+
const observedSkills=[...reasons.keys()].sort();
|
|
181
|
+
if(scope_kind==='change')for(const skill of observedSkills)if(skill!=='alibaba-java-code-style'&&!declaredSkills.includes(skill))issues.push({id:`undeclared-skill:${skill}`,reason:'actual impact exceeds contract; recompile before execution'});
|
|
182
|
+
const constraints=[],rulesSources=[];
|
|
183
|
+
const lock=path.join(root,'skills-lock.json');
|
|
184
|
+
const skillLock=fs.existsSync(lock)?JSON.parse(fs.readFileSync(lock,'utf8')):null;
|
|
185
|
+
if(!skillLock)issues.push({id:'skill-lock-missing',reason:'缺少锁定的 canonical Skill 来源;只读盘点不能声明规范已锁定'});
|
|
186
|
+
const skillTrees={};
|
|
187
|
+
for(const skill of observedSkills) {
|
|
188
|
+
ensure(/^[a-z][a-z0-9-]*$/.test(skill),'invalid skill identifier');
|
|
189
|
+
const skillRoot=path.join(root,'.agents/skills',skill);
|
|
190
|
+
if(fs.existsSync(skillRoot)) {
|
|
191
|
+
skillTrees[skill]=treeHash(skillRoot);
|
|
192
|
+
if(skillLock?.skills?.shared?.[skill]?.effectiveHash!==skillTrees[skill])issues.push({id:`skill-lock-drift:${skill}`,reason:'技能正文、引用或源码索引与锁不一致'});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
for(const skill of observedSkills){const {rules,sourceDigests}=readRules(root,skill);rulesSources.push(...sourceDigests);for(const rule of rules){const applicability=tags.has(rule.when)?'required':(['pagination','batch'].includes(rule.when)?'conditional':'not-applicable');constraints.push({...rule,constraint_id:rule.id,applicability,applicability_basis:applicability==='required'?[...reasons.get(skill)].sort():[`no-observed-${rule.when}; reviewer must reconcile actual behavior`]});}}
|
|
196
|
+
ensure(new Set(constraints.map(r=>r.constraint_id)).size===constraints.length,'duplicate canonical constraint_id');
|
|
197
|
+
const platform=identity?.platform_configuration;
|
|
198
|
+
const catalogRef='docs/engineering/backend-platforms.json';
|
|
199
|
+
const catalogPath=path.join(root,catalogRef);
|
|
200
|
+
let platform_catalog_digest=null;
|
|
201
|
+
if(platform?.profile_id && fs.existsSync(catalogPath)) {
|
|
202
|
+
const bytes=fs.readFileSync(catalogPath);platform_catalog_digest=coverageDigest(bytes);
|
|
203
|
+
const profile=JSON.parse(bytes).profiles.find(p=>p.id===platform.profile_id);
|
|
204
|
+
if(!profile || profile.java_version!==platform.java_version || profile.spring_boot_version!==platform.spring_boot_version || profile.component_platform_line!==platform.component_platform_line)issues.push({id:'platform-identity-mismatch',reason:'登记精确平台与事实源不一致'});
|
|
205
|
+
else if(types.some(t=>new RegExp(`\\bimport\\s+${profile.validation_namespace==='javax'?'jakarta':'javax'}\\.(?:validation|servlet)\\.`).test(t.code)))issues.push({id:'platform-namespace-mismatch',reason:'源码使用了目标平台之外的 Validation/Servlet 命名空间'});
|
|
206
|
+
}
|
|
207
|
+
const findings=[];
|
|
208
|
+
for(const t of active) {
|
|
209
|
+
const dependencies=types.filter(other=>other!==t&&uses(t,other));
|
|
210
|
+
if([...t.roles].some(r=>['infrastructure','repository','persistence'].includes(r)) && dependencies.some(o=>[...o.roles].some(r=>['web','server'].includes(r))))findings.push({constraint_id:'repository.ownership',code_ref:t.ref,disposition:'violation',reason:'持久化层引用 Web 类型'});
|
|
211
|
+
if(t.http && !t.annotations.some(a=>['ControllerAdvice','RestControllerAdvice'].includes(a)) && (dependencies.some(o=>[...o.roles].some(r=>['domain','repository','infrastructure','persistence'].includes(r)))||/\b(?:[A-Z]\w*(?:Gateway|Repository|Mapper)|JdbcTemplate|EntityManager)\b/.test(t.code)))findings.push({constraint_id:'web.use-case',code_ref:t.ref,disposition:'violation',reason:'HTTP 入口直接引用领域/持久化能力'});
|
|
212
|
+
if(t.roles.has('domain')&&family==='domain-driven'&&/\bimport\s+(?:org\.springframework|org\.apache\.ibatis|com\.baomidou|jakarta\.persistence|javax\.persistence)\./.test(t.code))findings.push({constraint_id:'domain.dependencies',code_ref:t.ref,disposition:'violation',reason:'Domain 技术依赖泄漏'});
|
|
213
|
+
}
|
|
214
|
+
return {schema_version:1,scope_kind,architecture_identity:identity||null,basis: basis||null,comparison_ref,source_roots:roots,source_head:git(projectRoot,['rev-parse','HEAD']).trim(),changed_paths:changedPaths.sort(),inventory,reviewed_paths:active.map(t=>t.ref).sort(),skills:observedSkills.map(skill=>({skill,tree_digest:skillTrees[skill],reasons:[...reasons.get(skill)].sort()})),skill_assessments:CORE_SKILLS.map(skill=>({skill,status:observedSkills.includes(skill)?'applicable':'not-applicable',reason:observedSkills.includes(skill)?'observed-or-declared':'no matching registered responsibility or source signal'})),constraints:constraints.sort((a,b)=>a.constraint_id.localeCompare(b.constraint_id)),responsibility_evidence,discovery_sources,platform_catalog_digest,rule_sources:rulesSources.sort((a,b)=>a.ref.localeCompare(b.ref)),skill_lock_digest:fs.existsSync(lock)?coverageDigest(fs.readFileSync(lock)):null,issues,findings,limitations:['源码检查用于发现职责与明确反例,不替代编译态 ArchUnit、HTTP fixture 或 Reviewer 全文语义审查。']};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export function verifyCoverageRows(coverage, rows, {root,projectRoot}={}) {
|
|
218
|
+
ensure(!coverage.issues.length,`coverage unresolved: ${coverage.issues.map(i=>i.id).join(', ')}`);
|
|
219
|
+
ensure(!coverage.findings.length,`Standards violation: ${coverage.findings.map(i=>i.constraint_id).join(', ')}`);
|
|
220
|
+
ensure(Array.isArray(rows),'constraint_results required');
|
|
221
|
+
const standards=rows.filter(r=>r.axis==='Standards');
|
|
222
|
+
ensure(new Set(standards.map(r=>r.constraint_id)).size===standards.length,'duplicate constraint result');
|
|
223
|
+
for(const expected of coverage.constraints) {
|
|
224
|
+
const row=standards.find(r=>r.constraint_id===expected.constraint_id);
|
|
225
|
+
ensure(row,`constraint not reviewed: ${expected.constraint_id}`);
|
|
226
|
+
ensure(row.skill===expected.skill && row.rule_ref===expected.rule_ref && row.rule_digest===expected.rule_digest,'constraint owner/rule mismatch');
|
|
227
|
+
ensure(typeof row.constraint==='string'&&row.constraint.trim()&&Array.isArray(row.applicability_basis)&&coverageDigest(row.applicability_basis)===coverageDigest(expected.applicability_basis),'constraint applicability evidence required');
|
|
228
|
+
ensure(['passed','not-applicable'].includes(row.status),`${expected.constraint_id}: unresolved violation`);
|
|
229
|
+
if(row.status==='not-applicable')ensure(expected.applicability!=='required' && typeof row.reason==='string' && row.reason.trim(),`${expected.constraint_id}: applicable rule cannot be waived`);
|
|
230
|
+
ensure(row.code_ref && row.evidence_ref && row.evidence_digest,'rule/code/evidence required');
|
|
231
|
+
coverageFile(projectRoot,row.code_ref.split(':')[0]);
|
|
232
|
+
ensure(coverageDigest(fs.readFileSync(coverageFile(root,row.evidence_ref)))===row.evidence_digest,'verification evidence stale');
|
|
233
|
+
if(expected.evidence==='semantic-review')ensure(typeof row.review_notes==='string'&&row.review_notes.trim().length>=20,'full-text semantic review needs concrete reasoning');
|
|
234
|
+
}
|
|
235
|
+
const ids=new Set(coverage.constraints.map(r=>r.constraint_id));
|
|
236
|
+
ensure(standards.every(r=>ids.has(r.constraint_id)),'unknown constraint result; update canonical declaration before asserting coverage');
|
|
237
|
+
}
|
|
@@ -33,7 +33,7 @@ export function inspectFirstSliceArtifacts(contract, projectRoot) {
|
|
|
33
33
|
}
|
|
34
34
|
} catch (error) { failures.push(`${label}:${error.message}`); }
|
|
35
35
|
}
|
|
36
|
-
const aliases = { service: 'application', core: '
|
|
36
|
+
const aliases = { service: 'application', core: 'application', repository: 'infrastructure', server: 'web' };
|
|
37
37
|
for (const layer of contract.backend.affected_layers || []) {
|
|
38
38
|
const role = aliases[layer] || layer;
|
|
39
39
|
if (['domain','application','infrastructure','web'].includes(role) && !roles.has(role)) failures.push(`affected-role-empty:${role}`);
|
|
@@ -250,7 +250,10 @@ function validateTicketReference(ref, trackerKind) {
|
|
|
250
250
|
*/
|
|
251
251
|
export function validateNextRoute(currentWorkUnit, nextRoute, decisionState, options = {}) {
|
|
252
252
|
if (currentWorkUnit === "work-unit.code-review" && nextRoute === "work-unit.release-and-retrospective") {
|
|
253
|
-
try {
|
|
253
|
+
try {
|
|
254
|
+
if (decisionState?.review_input?.scope_kind !== "change") throw new Error("只读基线审计不能关闭实现审查");
|
|
255
|
+
validateBackendReview(decisionState, { root: options.root || ROOT });
|
|
256
|
+
}
|
|
254
257
|
catch (error) { return blockedResult(["backend-review-incomplete"], [error.message]); }
|
|
255
258
|
}
|
|
256
259
|
|
|
@@ -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: "目标含未提交改动" });
|