create-yss-spec 3.4.7 → 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 +20 -0
- 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/lombok/SKILL.md +1 -1
- package/template/.agents/skills/mapstruct/SKILL.md +3 -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-application/references/application-layer-guide.md +7 -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 +44 -0
- package/template/.agents/skills/yss-backend-spec-review/references/check-inputs.md +21 -0
- package/template/.agents/skills/yss-backend-spec-review/references/remediation-workflow.md +48 -0
- package/template/.agents/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
- package/template/.agents/skills/yss-backend-spec-review/tests/routing.test.mjs +19 -0
- package/template/.agents/skills/yss-ddd-scaffold-generator/SKILL.md +7 -34
- package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/java/architecture-rules-test.java.template +60 -23
- package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +6 -0
- package/template/.agents/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
- package/template/.agents/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +4 -2
- package/template/.agents/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
- package/template/.agents/skills/yss-ddd-scaffold-generator/references/engineering-baseline.md +7 -1
- package/template/.agents/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
- package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +6 -10
- package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +12 -16
- package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +36 -87
- package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +4 -3
- 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 +10 -3
- 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/boundaries.md +5 -0
- 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-layered-mvc-scaffold-generator/assets/templates/architecture-rules-test.java.template +66 -0
- package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +4 -2
- package/template/.agents/skills/yss-mybatis/SKILL.md +14 -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/references/profiles/target-domain-model.md +10 -2
- 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/yss-web-controller/references/web-adapter-layer-guide.md +8 -0
- 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 +20 -0
- 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/lombok/SKILL.md +1 -1
- package/template/.codex/skills/mapstruct/SKILL.md +3 -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-application/references/application-layer-guide.md +7 -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 +44 -0
- package/template/.codex/skills/yss-backend-spec-review/references/check-inputs.md +21 -0
- package/template/.codex/skills/yss-backend-spec-review/references/remediation-workflow.md +48 -0
- package/template/.codex/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
- package/template/.codex/skills/yss-backend-spec-review/tests/routing.test.mjs +19 -0
- package/template/.codex/skills/yss-ddd-scaffold-generator/SKILL.md +7 -34
- package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/java/architecture-rules-test.java.template +60 -23
- package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +6 -0
- package/template/.codex/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
- package/template/.codex/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +4 -2
- package/template/.codex/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
- package/template/.codex/skills/yss-ddd-scaffold-generator/references/engineering-baseline.md +7 -1
- package/template/.codex/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
- package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +6 -10
- package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +12 -16
- package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +36 -87
- package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +4 -3
- 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 +10 -3
- 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/boundaries.md +5 -0
- 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-layered-mvc-scaffold-generator/assets/templates/architecture-rules-test.java.template +66 -0
- package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +4 -2
- package/template/.codex/skills/yss-mybatis/SKILL.md +14 -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/references/profiles/target-domain-model.md +10 -2
- 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/yss-web-controller/references/web-adapter-layer-guide.md +8 -0
- 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 +20 -0
- 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/lombok/SKILL.md +1 -1
- package/template/.cursor/skills/mapstruct/SKILL.md +3 -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-application/references/application-layer-guide.md +7 -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 +44 -0
- package/template/.cursor/skills/yss-backend-spec-review/references/check-inputs.md +21 -0
- package/template/.cursor/skills/yss-backend-spec-review/references/remediation-workflow.md +48 -0
- package/template/.cursor/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
- package/template/.cursor/skills/yss-backend-spec-review/tests/routing.test.mjs +19 -0
- package/template/.cursor/skills/yss-ddd-scaffold-generator/SKILL.md +7 -34
- package/template/.cursor/skills/yss-ddd-scaffold-generator/assets/templates/java/architecture-rules-test.java.template +60 -23
- package/template/.cursor/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +6 -0
- package/template/.cursor/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
- package/template/.cursor/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +4 -2
- package/template/.cursor/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
- package/template/.cursor/skills/yss-ddd-scaffold-generator/references/engineering-baseline.md +7 -1
- package/template/.cursor/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
- package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +6 -10
- package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +12 -16
- package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +36 -87
- package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +4 -3
- 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 +10 -3
- 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/boundaries.md +5 -0
- 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-layered-mvc-scaffold-generator/assets/templates/architecture-rules-test.java.template +66 -0
- package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +4 -2
- package/template/.cursor/skills/yss-mybatis/SKILL.md +14 -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/references/profiles/target-domain-model.md +10 -2
- 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/yss-web-controller/references/web-adapter-layer-guide.md +8 -0
- 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 +20 -0
- 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/lombok/SKILL.md +1 -1
- package/template/.pi/skills/mapstruct/SKILL.md +3 -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-application/references/application-layer-guide.md +7 -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 +44 -0
- package/template/.pi/skills/yss-backend-spec-review/references/check-inputs.md +21 -0
- package/template/.pi/skills/yss-backend-spec-review/references/remediation-workflow.md +48 -0
- package/template/.pi/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
- package/template/.pi/skills/yss-backend-spec-review/tests/routing.test.mjs +19 -0
- package/template/.pi/skills/yss-ddd-scaffold-generator/SKILL.md +7 -34
- package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/java/architecture-rules-test.java.template +60 -23
- package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +6 -0
- package/template/.pi/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
- package/template/.pi/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +4 -2
- package/template/.pi/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
- package/template/.pi/skills/yss-ddd-scaffold-generator/references/engineering-baseline.md +7 -1
- package/template/.pi/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
- package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +6 -10
- package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +12 -16
- package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +36 -87
- package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +4 -3
- 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 +10 -3
- 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/boundaries.md +5 -0
- 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-layered-mvc-scaffold-generator/assets/templates/architecture-rules-test.java.template +66 -0
- package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +4 -2
- package/template/.pi/skills/yss-mybatis/SKILL.md +14 -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/references/profiles/target-domain-model.md +10 -2
- 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/yss-web-controller/references/web-adapter-layer-guide.md +8 -0
- package/template/.pi/skills/ytable-usage/SKILL.md +2 -2
- package/template/docs/agents/yss-skill-registry.yaml +13 -0
- package/template/docs/engineering/backend-platforms.md +14 -0
- package/template/docs/process/schemas/digital-human-task-package.schema.json +713 -100
- package/template/docs/process/schemas/slice-implementation-contract-v3.schema.json +41 -0
- package/template/scripts/backend-standards-coverage +26 -0
- package/template/scripts/lib/backend-platform-provenance.mjs +1 -1
- package/template/scripts/lib/backend-platform-verification.mjs +2 -2
- package/template/scripts/lib/backend-platform.mjs +62 -0
- package/template/scripts/lib/backend-review.mjs +140 -0
- package/template/scripts/lib/backend-standards-coverage.mjs +237 -0
- package/template/scripts/lib/first-slice-artifacts.mjs +47 -0
- package/template/scripts/lib/first-slice-tests.mjs +24 -0
- package/template/scripts/lib/lifecycle-transition.mjs +9 -0
- package/template/scripts/lib/maintenance-candidate.mjs +160 -0
- package/template/scripts/lib/profile-skill-sync.mjs +46 -5
- package/template/scripts/lib/slice-execution-preflight.mjs +43 -0
- package/template/scripts/slice-contract +7 -3
- package/template/scripts/verify-backend-platform-matrix +8 -2
- package/template/skills-lock.json +77 -63
- package/template/yss-public-skills.json +4 -2
- package/template.manifest.json +0 -1
- package/template.snapshot.json +5 -5
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
/** Declarations bind responsibilities to compiled types, not naming conventions. */
|
|
5
|
+
export function inspectFirstSliceArtifacts(contract, projectRoot) {
|
|
6
|
+
const declaration = contract.backend?.first_slice;
|
|
7
|
+
const failures = [], properties = { 'yss.firstSlice': 'true' };
|
|
8
|
+
if (!declaration || !Array.isArray(declaration.artifacts) || !declaration.artifacts.length) {
|
|
9
|
+
return { failures: ['backend.first_slice.artifacts-required'], properties };
|
|
10
|
+
}
|
|
11
|
+
const roles = new Map(), types = [], seen = new Set();
|
|
12
|
+
const root = fs.realpathSync(projectRoot);
|
|
13
|
+
for (const item of declaration.artifacts) {
|
|
14
|
+
const label = item?.type || item?.path || 'unknown';
|
|
15
|
+
try {
|
|
16
|
+
if (!['domain','application','infrastructure','web','test'].includes(item.role)) throw Error('invalid-role');
|
|
17
|
+
if (!/^[a-zA-Z_$][\w$]*(\.[a-zA-Z_$][\w$]*)+$/.test(item.type || '')) throw Error('qualified-type-required');
|
|
18
|
+
if (seen.has(item.type)) throw Error('duplicate-type');
|
|
19
|
+
seen.add(item.type);
|
|
20
|
+
if (!item.path || path.isAbsolute(item.path) || item.path.split(/[\\/]/).includes('..')) throw Error('relative-path-required');
|
|
21
|
+
const file = fs.realpathSync(path.resolve(root, item.path));
|
|
22
|
+
if (!file.startsWith(`${root}${path.sep}`)) throw Error('path-escape');
|
|
23
|
+
const source = fs.readFileSync(file, 'utf8');
|
|
24
|
+
const pkg = source.match(/^\s*package\s+([\w.]+)\s*;/m)?.[1];
|
|
25
|
+
const name = item.type.slice(item.type.lastIndexOf('.') + 1);
|
|
26
|
+
if (`${pkg}.${name}` !== item.type || !new RegExp(`\\b(class|interface|enum|record)\\s+${name}\\b`).test(source)) throw Error('declared-type-mismatch');
|
|
27
|
+
if (item.role === 'test') {
|
|
28
|
+
if (!item.path.includes('/src/test/java/')) throw Error('test-source-required');
|
|
29
|
+
} else {
|
|
30
|
+
if (!item.path.includes('/src/main/java/')) throw Error('main-source-required');
|
|
31
|
+
types.push(item.type);
|
|
32
|
+
const packages = roles.get(item.role) || new Set(); packages.add(pkg); roles.set(item.role, packages);
|
|
33
|
+
}
|
|
34
|
+
} catch (error) { failures.push(`${label}:${error.message}`); }
|
|
35
|
+
}
|
|
36
|
+
const aliases = { service: 'application', core: 'application', repository: 'infrastructure', server: 'web' };
|
|
37
|
+
for (const layer of contract.backend.affected_layers || []) {
|
|
38
|
+
const role = aliases[layer] || layer;
|
|
39
|
+
if (['domain','application','infrastructure','web'].includes(role) && !roles.has(role)) failures.push(`affected-role-empty:${role}`);
|
|
40
|
+
}
|
|
41
|
+
if (!declaration.artifacts.some(item => item.role === 'test')) failures.push('behavior-test-binding-required');
|
|
42
|
+
if ((contract.backend.affected_layers || []).some(layer => ['web','server'].includes(layer))) properties['yss.arch.requireController'] = 'true';
|
|
43
|
+
if (!types.length) failures.push('business-type-required');
|
|
44
|
+
properties['yss.arch.requiredTypes'] = types.join(',');
|
|
45
|
+
for (const [role, packages] of roles) properties[`yss.arch.${role}`] = [...packages].join(',');
|
|
46
|
+
return { failures, properties };
|
|
47
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { parseXmlDocument } from '../vendor/xml.mjs';
|
|
5
|
+
const array = value => value === undefined ? [] : Array.isArray(value) ? value : [value];
|
|
6
|
+
|
|
7
|
+
export function verifyFirstSliceTests(contract, projectRoot, startedAt, architectureType) {
|
|
8
|
+
const declarations = contract.backend.first_slice.artifacts.filter(item => item.role === 'test');
|
|
9
|
+
const required = [...declarations.map(item => ({ type: item.type, module: item.path.split('/src/test/java/')[0] })), architectureType];
|
|
10
|
+
const evidence = [], failures = [];
|
|
11
|
+
for (const item of required) {
|
|
12
|
+
try {
|
|
13
|
+
const candidates = ['surefire-reports','failsafe-reports'].map(folder => path.join(projectRoot,item.module,'target',folder,`TEST-${item.type}.xml`));
|
|
14
|
+
const ref = candidates.find(file => fs.existsSync(file) && fs.statSync(file).mtimeMs >= startedAt);
|
|
15
|
+
if (!ref) throw Error('fresh execution report missing');
|
|
16
|
+
const bytes = fs.readFileSync(ref), suite = parseXmlDocument(bytes.toString()).testsuite;
|
|
17
|
+
const cases = array(suite?.testcase);
|
|
18
|
+
if (!cases.length || cases.some(c => ['failure','error','skipped'].some(key => Object.hasOwn(c,key)))) throw Error('test not executed successfully');
|
|
19
|
+
if (cases.some(c => c['@_classname'] !== item.type)) throw Error('test class does not match contract');
|
|
20
|
+
evidence.push({type:item.type,ref,sha256:createHash('sha256').update(bytes).digest('hex'),test_count:cases.length});
|
|
21
|
+
} catch(error) { failures.push(`${item.type}:${error.message}`); }
|
|
22
|
+
}
|
|
23
|
+
return { status: failures.length ? 'failed' : 'passed', evidence, failures };
|
|
24
|
+
}
|
|
@@ -9,6 +9,7 @@ import { validatePlanSpecEntry } from "./plan-spec-entry.mjs";
|
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { validateApiContractDecision } from "./api-contract-decision.mjs";
|
|
11
11
|
import { loadApprovalRecord, validateApprovalRecord } from "./approval-record.mjs";
|
|
12
|
+
import { validateBackendReview } from "./backend-review.mjs";
|
|
12
13
|
import { ROOT } from "./lifecycle-registry.mjs";
|
|
13
14
|
|
|
14
15
|
const IMPLEMENTATION_WORK_UNIT = "work-unit.slice-implementation";
|
|
@@ -248,6 +249,14 @@ function validateTicketReference(ref, trackerKind) {
|
|
|
248
249
|
* by `validateWorkflowExecutionResult` before this function is called.
|
|
249
250
|
*/
|
|
250
251
|
export function validateNextRoute(currentWorkUnit, nextRoute, decisionState, options = {}) {
|
|
252
|
+
if (currentWorkUnit === "work-unit.code-review" && nextRoute === "work-unit.release-and-retrospective") {
|
|
253
|
+
try {
|
|
254
|
+
if (decisionState?.review_input?.scope_kind !== "change") throw new Error("只读基线审计不能关闭实现审查");
|
|
255
|
+
validateBackendReview(decisionState, { root: options.root || ROOT });
|
|
256
|
+
}
|
|
257
|
+
catch (error) { return blockedResult(["backend-review-incomplete"], [error.message]); }
|
|
258
|
+
}
|
|
259
|
+
|
|
251
260
|
|
|
252
261
|
if (["work-unit.technical-analysis", TICKET_DECOMPOSITION_WORK_UNIT, IMPLEMENTATION_WORK_UNIT, "work-unit.frontend-implementation-verification"].includes(nextRoute)) {
|
|
253
262
|
try { enforceFrontendDelivery(decisionState, { root: options.root, phase: nextRoute === IMPLEMENTATION_WORK_UNIT ? "implementation" : "inputs" }); }
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, readlinkSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { parseDocument, stringify } from "../vendor/yaml.mjs";
|
|
6
|
+
|
|
7
|
+
const MAGIC = Buffer.from("YSS-WORKTREE-CANDIDATE-V1\0", "ascii");
|
|
8
|
+
const MAX_BUFFER = 512 * 1024 * 1024;
|
|
9
|
+
const MAINTENANCE_EVIDENCE_ROOT = ".template-source/evidence/maintenance";
|
|
10
|
+
const CANDIDATE_FILES = ["candidate-manifest.yaml", "candidate.bin", "tracked.diff"];
|
|
11
|
+
|
|
12
|
+
function fail(message) { throw new TypeError(message); }
|
|
13
|
+
function ensure(condition, message) { if (!condition) fail(message); }
|
|
14
|
+
function git(args, root, encoding = "utf8") {
|
|
15
|
+
const result = spawnSync("git", args, { cwd: root, encoding, maxBuffer: MAX_BUFFER });
|
|
16
|
+
if (result.status !== 0) fail((typeof result.stderr === "string" ? result.stderr : result.stderr?.toString()).trim() || `git ${args.join(" ")} 执行失败`);
|
|
17
|
+
return result.stdout;
|
|
18
|
+
}
|
|
19
|
+
function uint64(value) { const buffer = Buffer.alloc(8); buffer.writeBigUInt64BE(BigInt(value)); return buffer; }
|
|
20
|
+
function uint32(value) { const buffer = Buffer.alloc(4); buffer.writeUInt32BE(value >>> 0); return buffer; }
|
|
21
|
+
function splitNull(buffer) {
|
|
22
|
+
const result = [];
|
|
23
|
+
let start = 0;
|
|
24
|
+
for (let index = 0; index < buffer.length; index += 1) if (buffer[index] === 0) { if (index > start) result.push(buffer.subarray(start, index)); start = index + 1; }
|
|
25
|
+
if (start < buffer.length) result.push(buffer.subarray(start));
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
function normalizeRelative(value, label) {
|
|
29
|
+
ensure(typeof value === "string" && value.trim(), `${label} 不能为空`);
|
|
30
|
+
const normalized = value.replaceAll("\\", "/").replace(/^\.\//, "").replace(/\/$/, "");
|
|
31
|
+
ensure(normalized && !path.posix.isAbsolute(normalized) && path.posix.normalize(normalized) === normalized && normalized !== ".." && !normalized.startsWith("../"), `${label} 必须是规范的仓库内相对路径`);
|
|
32
|
+
return normalized;
|
|
33
|
+
}
|
|
34
|
+
function isMaintenanceEvidencePath(value) {
|
|
35
|
+
return value === MAINTENANCE_EVIDENCE_ROOT || value.startsWith(`${MAINTENANCE_EVIDENCE_ROOT}/`);
|
|
36
|
+
}
|
|
37
|
+
function readLength(buffer, offset, bytes, label) {
|
|
38
|
+
ensure(offset + bytes <= buffer.length, `packed candidate 缺少 ${label}`);
|
|
39
|
+
const value = bytes === 8 ? buffer.readBigUInt64BE(offset) : BigInt(buffer.readUInt32BE(offset));
|
|
40
|
+
ensure(value <= BigInt(Number.MAX_SAFE_INTEGER), `packed candidate ${label} 过大`);
|
|
41
|
+
return { value: Number(value), offset: offset + bytes };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function captureMaintenanceCandidate({ root, outputDir, baseRef = "HEAD", excludePaths = [] }) {
|
|
45
|
+
const repositoryRoot = path.resolve(root);
|
|
46
|
+
const outputPath = path.resolve(repositoryRoot, outputDir);
|
|
47
|
+
const outputRelative = normalizeRelative(path.relative(repositoryRoot, outputPath).replaceAll(path.sep, "/"), "outputDir");
|
|
48
|
+
ensure(isMaintenanceEvidencePath(outputRelative), `outputDir 必须位于 ${MAINTENANCE_EVIDENCE_ROOT}`);
|
|
49
|
+
ensure(!existsSync(outputPath), "outputDir 必须不存在,禁止复用可能含残留文件的候选目录");
|
|
50
|
+
ensure(Array.isArray(excludePaths), "excludePaths 必须是数组");
|
|
51
|
+
const explicitExclusions = excludePaths.map((value) => normalizeRelative(value, "excludePaths"));
|
|
52
|
+
for (const exclusion of explicitExclusions) ensure(isMaintenanceEvidencePath(exclusion), `excludePaths 只允许 ${MAINTENANCE_EVIDENCE_ROOT} 下的维护证据`);
|
|
53
|
+
const exclusions = [...new Set([outputRelative, ...explicitExclusions])];
|
|
54
|
+
const mergeBase = git(["merge-base", baseRef, "HEAD"], repositoryRoot).trim();
|
|
55
|
+
const trackedDiff = git(["diff", "--no-ext-diff", "--binary", "--full-index", mergeBase], repositoryRoot, null);
|
|
56
|
+
const rawPaths = splitNull(git(["ls-files", "-z", "--others", "--exclude-standard"], repositoryRoot, null))
|
|
57
|
+
.filter((rawPath) => {
|
|
58
|
+
const value = rawPath.toString();
|
|
59
|
+
return !exclusions.some((exclusion) => value === exclusion || value.startsWith(`${exclusion}/`));
|
|
60
|
+
})
|
|
61
|
+
.sort(Buffer.compare);
|
|
62
|
+
ensure(trackedDiff.length > 0 || rawPaths.length > 0, "维护候选不能为空");
|
|
63
|
+
|
|
64
|
+
const parts = [MAGIC, Buffer.from([0x54]), uint64(trackedDiff.length), trackedDiff];
|
|
65
|
+
const untrackedFiles = [];
|
|
66
|
+
const untrackedPathBytes = [];
|
|
67
|
+
for (const rawPath of rawPaths) {
|
|
68
|
+
ensure(!rawPath.includes(0) && rawPath.length > 0, "untracked path 无效");
|
|
69
|
+
const relative = rawPath.toString();
|
|
70
|
+
const absolute = path.resolve(repositoryRoot, relative);
|
|
71
|
+
ensure(!path.relative(repositoryRoot, absolute).startsWith(".."), `untracked path 越界: ${relative}`);
|
|
72
|
+
const stat = lstatSync(absolute);
|
|
73
|
+
let kind;
|
|
74
|
+
let content;
|
|
75
|
+
if (stat.isFile()) { kind = 0x52; content = readFileSync(absolute); }
|
|
76
|
+
else if (stat.isSymbolicLink()) { kind = 0x4c; content = readlinkSync(absolute, { encoding: "buffer" }); }
|
|
77
|
+
else fail(`候选包含不支持的 untracked 类型: ${relative}`);
|
|
78
|
+
parts.push(Buffer.from([0x55]), uint64(rawPath.length), rawPath, uint32(stat.mode), Buffer.from([kind]), uint64(content.length), content);
|
|
79
|
+
untrackedFiles.push(relative);
|
|
80
|
+
untrackedPathBytes.push(rawPath.toString("base64"));
|
|
81
|
+
}
|
|
82
|
+
const stream = Buffer.concat(parts);
|
|
83
|
+
const digest = createHash("sha256").update(stream).digest("hex");
|
|
84
|
+
const streamRef = `${outputRelative}/candidate.bin`;
|
|
85
|
+
const diffRef = `${outputRelative}/tracked.diff`;
|
|
86
|
+
const manifestRef = `${outputRelative}/candidate-manifest.yaml`;
|
|
87
|
+
const manifest = {
|
|
88
|
+
schema_version: 1,
|
|
89
|
+
candidate_kind: "yss-worktree-candidate-v1",
|
|
90
|
+
storage: "packed-stream",
|
|
91
|
+
review_mode: "worktree",
|
|
92
|
+
review_base_ref: baseRef,
|
|
93
|
+
merge_base: mergeBase,
|
|
94
|
+
implementation_candidate_ref: "working-tree",
|
|
95
|
+
candidate_snapshot_ref: manifestRef,
|
|
96
|
+
candidate_digest: digest,
|
|
97
|
+
tracked_diff_command: `git diff --no-ext-diff --binary --full-index ${mergeBase}`,
|
|
98
|
+
untracked_inventory_command: "git ls-files -z --others --exclude-standard",
|
|
99
|
+
untracked_diff_command: "packed in candidate.bin",
|
|
100
|
+
untracked_files: untrackedFiles,
|
|
101
|
+
untracked_path_bytes: untrackedPathBytes,
|
|
102
|
+
excluded_paths: exclusions,
|
|
103
|
+
snapshot_stream_ref: streamRef,
|
|
104
|
+
tracked_diff_ref: diffRef,
|
|
105
|
+
commit_list_command: `git log ${baseRef}..HEAD --oneline`
|
|
106
|
+
};
|
|
107
|
+
const outputParent = path.dirname(outputPath);
|
|
108
|
+
mkdirSync(outputParent, { recursive: true });
|
|
109
|
+
const stagingPath = mkdtempSync(path.join(outputParent, ".candidate-staging-"));
|
|
110
|
+
try {
|
|
111
|
+
writeFileSync(path.join(stagingPath, "candidate.bin"), stream);
|
|
112
|
+
writeFileSync(path.join(stagingPath, "tracked.diff"), trackedDiff);
|
|
113
|
+
writeFileSync(path.join(stagingPath, "candidate-manifest.yaml"), stringify(manifest, { lineWidth: 0 }));
|
|
114
|
+
renameSync(stagingPath, outputPath);
|
|
115
|
+
} finally {
|
|
116
|
+
if (existsSync(stagingPath)) rmSync(stagingPath, { recursive: true, force: true });
|
|
117
|
+
}
|
|
118
|
+
return { candidate_digest: digest, manifest, manifest_ref: manifestRef, files: [manifestRef, streamRef, diffRef] };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function inspectMaintenanceCandidate({ manifestPath }) {
|
|
122
|
+
const absoluteManifest = path.resolve(manifestPath);
|
|
123
|
+
const document = parseDocument(readFileSync(absoluteManifest, "utf8"), { uniqueKeys: true });
|
|
124
|
+
ensure(document.errors.length === 0, document.errors[0]?.message || "candidate manifest 无法解析");
|
|
125
|
+
const manifest = document.toJS({ maxAliasCount: 0 });
|
|
126
|
+
ensure(manifest.storage === "packed-stream", "只支持 packed-stream candidate");
|
|
127
|
+
const candidateDir = path.dirname(absoluteManifest);
|
|
128
|
+
ensure(JSON.stringify(readdirSync(candidateDir).sort()) === JSON.stringify([...CANDIDATE_FILES].sort()), `packed candidate 目录必须恰好包含 ${CANDIDATE_FILES.join("、")}`);
|
|
129
|
+
const root = path.resolve(path.dirname(absoluteManifest), ...Array(manifest.candidate_snapshot_ref.split("/").length - 1).fill(".."));
|
|
130
|
+
ensure(path.resolve(root, manifest.candidate_snapshot_ref) === absoluteManifest, "candidate_snapshot_ref 未绑定当前 manifest");
|
|
131
|
+
const streamPath = path.resolve(root, manifest.snapshot_stream_ref);
|
|
132
|
+
const diffPath = path.resolve(root, manifest.tracked_diff_ref);
|
|
133
|
+
ensure(streamPath === path.join(candidateDir, "candidate.bin") && diffPath === path.join(candidateDir, "tracked.diff"), "packed candidate 引用必须绑定同目录规范文件");
|
|
134
|
+
const stream = readFileSync(streamPath);
|
|
135
|
+
ensure(createHash("sha256").update(stream).digest("hex") === manifest.candidate_digest.replace(/^sha256:/, ""), "candidate_digest 与 packed stream 不一致");
|
|
136
|
+
ensure(stream.subarray(0, MAGIC.length).equals(MAGIC), "packed stream magic 无效");
|
|
137
|
+
let offset = MAGIC.length;
|
|
138
|
+
ensure(stream[offset] === 0x54, "packed stream 缺少 tracked record");
|
|
139
|
+
offset += 1;
|
|
140
|
+
let length = readLength(stream, offset, 8, "tracked length");
|
|
141
|
+
offset = length.offset;
|
|
142
|
+
const trackedDiff = stream.subarray(offset, offset + length.value);
|
|
143
|
+
offset += length.value;
|
|
144
|
+
ensure(readFileSync(diffPath).equals(trackedDiff), "tracked.diff 与 packed stream 不一致");
|
|
145
|
+
const entries = [];
|
|
146
|
+
while (offset < stream.length) {
|
|
147
|
+
ensure(stream[offset] === 0x55, "packed stream record kind 无效");
|
|
148
|
+
offset += 1;
|
|
149
|
+
length = readLength(stream, offset, 8, "path length"); offset = length.offset;
|
|
150
|
+
const rawPath = stream.subarray(offset, offset + length.value); offset += length.value;
|
|
151
|
+
length = readLength(stream, offset, 4, "mode"); offset = length.offset;
|
|
152
|
+
const mode = length.value;
|
|
153
|
+
const kind = stream[offset]; offset += 1;
|
|
154
|
+
length = readLength(stream, offset, 8, "content length"); offset = length.offset;
|
|
155
|
+
const content = stream.subarray(offset, offset + length.value); offset += length.value;
|
|
156
|
+
entries.push({ path: rawPath.toString(), path_bytes: rawPath.toString("base64"), mode, kind: kind === 0x52 ? "regular" : "symlink", content });
|
|
157
|
+
}
|
|
158
|
+
ensure(JSON.stringify(entries.map((entry) => entry.path_bytes)) === JSON.stringify(manifest.untracked_path_bytes), "manifest inventory 与 packed stream 不一致");
|
|
159
|
+
return { manifest, trackedDiff, entries };
|
|
160
|
+
}
|
|
@@ -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: "目标含未提交改动" });
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { readSliceContract } from './slice-contract.mjs';
|
|
2
|
+
import { createApprovedExecutionContext } from './approved-execution-context.mjs';
|
|
3
|
+
import { evaluateContractFreshness, loadCompilerContract } from './implementation-contract-compiler.mjs';
|
|
4
|
+
import { loadSkillRegistry } from './skill-registry.mjs';
|
|
5
|
+
|
|
6
|
+
/** Readability, structure and execution approval are different levels of evidence. */
|
|
7
|
+
export function inspectSliceContract(ref, { root = process.cwd(), approval_ref, work_unit_id } = {}) {
|
|
8
|
+
const loaded = readSliceContract(ref, { root });
|
|
9
|
+
const { contract, binding } = loaded;
|
|
10
|
+
const checks = { readable: 'passed', structure: 'passed', approval: 'not-checked', freshness: 'not-checked' };
|
|
11
|
+
const blockers = [];
|
|
12
|
+
if (loaded.raw.schema_version === 2) {
|
|
13
|
+
for (const [section, fields] of Object.entries(loadCompilerContract().slice_contract_required)) {
|
|
14
|
+
const target = section === 'root' ? contract : contract[section];
|
|
15
|
+
for (const field of fields) if (!target || !Object.hasOwn(target, field)) blockers.push(`missing:${section}.${field}`);
|
|
16
|
+
}
|
|
17
|
+
for (const section of ['common', 'resolution', 'backend']) {
|
|
18
|
+
if (!Array.isArray(contract[section]?.required_skills)) blockers.push(`invalid:${section}.required_skills`);
|
|
19
|
+
}
|
|
20
|
+
if (!Array.isArray(contract.work_units) || !contract.work_units.length) blockers.push('slice-contract-work-units-missing');
|
|
21
|
+
for (const unit of contract.work_units || []) {
|
|
22
|
+
if (unit.contract_id !== contract.contract_id) blockers.push(`work-unit-contract-id-mismatch:${unit.id}`);
|
|
23
|
+
if (unit.contract_version !== contract.contract_version) blockers.push(`work-unit-contract-version-mismatch:${unit.id}`);
|
|
24
|
+
if (!unit.work_unit?.primary_skill) blockers.push(`work-unit-primary-skill-missing:${unit.id}`);
|
|
25
|
+
}
|
|
26
|
+
if (blockers.length) checks.structure = 'failed';
|
|
27
|
+
}
|
|
28
|
+
if (approval_ref && !blockers.length) {
|
|
29
|
+
try {
|
|
30
|
+
const approved_slice = { ...binding, approval_ref };
|
|
31
|
+
const context = createApprovedExecutionContext(approved_slice, { root, contract, work_unit_id });
|
|
32
|
+
checks.approval = 'passed';
|
|
33
|
+
const current = evaluateContractFreshness(contract, { root, registry: loadSkillRegistry(), compilerContract: loadCompilerContract(), approved_slice, work_unit_id }, context);
|
|
34
|
+
checks.freshness = current.freshness === 'current' ? 'passed' : 'failed';
|
|
35
|
+
blockers.push(...current.reasons);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
checks.approval = 'failed';
|
|
38
|
+
blockers.push(error.code || error.message);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return { ...loaded, report: { read_only: true, ...binding, checks, approval_validity: checks.approval,
|
|
42
|
+
execution_allowed: !!approval_ref && !blockers.length && checks.freshness === 'passed', blockers } };
|
|
43
|
+
}
|
|
@@ -4,13 +4,14 @@ import path from 'node:path';
|
|
|
4
4
|
import { prepareSliceImplementationContract, migrateSliceContractV2, persistSliceDraft } from './lib/slice-contract-preparation.mjs';
|
|
5
5
|
import { renderSliceContractView, diffSliceContracts } from './lib/slice-contract-views.mjs';
|
|
6
6
|
import { parseSliceYaml, readSliceContract } from './lib/slice-contract.mjs';
|
|
7
|
+
import { inspectSliceContract } from './lib/slice-execution-preflight.mjs';
|
|
7
8
|
|
|
8
9
|
try {
|
|
9
10
|
const args=process.argv.slice(2),mode=args.shift(),options={},positional=[];
|
|
10
11
|
for(let i=0;i<args.length;i++) {
|
|
11
12
|
if(args[i]==='--json'){options.json=true;continue;}
|
|
12
13
|
if(args[i].startsWith('--')) {
|
|
13
|
-
const key=args[i].slice(2);if(!['root','input','output','unit','before-root'].includes(key)||!args[i+1])throw new Error(`未知或缺值参数 ${args[i]}`);
|
|
14
|
+
const key=args[i].slice(2);if(!['root','input','output','unit','before-root','approval-ref'].includes(key)||!args[i+1])throw new Error(`未知或缺值参数 ${args[i]}`);
|
|
14
15
|
options[key]=args[++i];
|
|
15
16
|
}else positional.push(args[i]);
|
|
16
17
|
}
|
|
@@ -24,7 +25,10 @@ try {
|
|
|
24
25
|
if(result.report.blockers.length)process.exitCode=1;
|
|
25
26
|
}else if(mode==='view')result=renderSliceContractView(positional[0],{root,unit_id:options.unit});
|
|
26
27
|
else if(mode==='diff')result=diffSliceContracts(positional[0],positional[1],{root,beforeRoot:options['before-root']?path.resolve(options['before-root']):root});
|
|
27
|
-
else if(mode==='verify')
|
|
28
|
-
|
|
28
|
+
else if(mode==='verify') {
|
|
29
|
+
result=inspectSliceContract(positional[0],{root,approval_ref:options['approval-ref'],work_unit_id:options.unit}).report;
|
|
30
|
+
if(result.blockers.length)process.exitCode=1;
|
|
31
|
+
}
|
|
32
|
+
else throw new Error('用法: scripts/slice-contract prepare <ticket> --input <补充.yaml> --output <新合同.yaml> | migrate <v2.yaml> --input <补充.yaml> --output <新合同.yaml> | view <合同.yaml> [--unit <id>] | diff <旧合同> <新合同> | verify <合同> [--root <项目根>] [--approval-ref <批准记录>] [--unit <工作单元>]');
|
|
29
33
|
process.stdout.write(options.json||!result.markdown?`${JSON.stringify(result,null,2)}\n`:`${result.markdown}\n`);
|
|
30
34
|
}catch(error){process.stderr.write(`${error.message}\n`);process.exitCode=1;}
|
|
@@ -10,7 +10,7 @@ import { ScaffoldGenerator, parseArgs as dddArgs } from "../.agents/skills/yss-d
|
|
|
10
10
|
import { generate, validateContract as validateMvcContract, parseArgs as mvcArgs } from "../.agents/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs";
|
|
11
11
|
import { run } from "../.agents/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs";
|
|
12
12
|
|
|
13
|
-
const { values } = parseArgs({ options: { "evidence-dir": { type: "string" }, inputs: { type: "string" }, resume: { type: "boolean", default: false } }, strict: true });
|
|
13
|
+
const { values } = parseArgs({ options: { "evidence-dir": { type: "string" }, inputs: { type: "string" }, resume: { type: "boolean", default: false }, "require-combination": { type: "string", multiple: true } }, strict: true });
|
|
14
14
|
if (!values["evidence-dir"]) throw new Error("--evidence-dir is required; optional --inputs points to real approved contracts and candidate catalog");
|
|
15
15
|
const evidence = path.resolve(values["evidence-dir"]);
|
|
16
16
|
await mkdir(evidence, { recursive: true });
|
|
@@ -24,9 +24,15 @@ for (const item of input.combinations ?? []) {
|
|
|
24
24
|
if (keys.has(key) || !catalog.profiles.some(p => p.id === item.profile_id && p.spring_boot_version === item.spring_boot_version) || !["domain-driven", "layered-mvc"].includes(item.architecture_family)) throw new Error("duplicate or unknown exact matrix combination");
|
|
25
25
|
keys.add(key);
|
|
26
26
|
}
|
|
27
|
+
const allKeys = loadBackendPlatforms().profiles.flatMap(profile => ["domain-driven", "layered-mvc"].map(family => `${profile.id}:${profile.spring_boot_version}:${family}`));
|
|
28
|
+
const requested = values["require-combination"] || input.required_combinations || allKeys;
|
|
29
|
+
if (!Array.isArray(requested) || !requested.length || new Set(requested).size !== requested.length || requested.some(key => !allKeys.includes(key))) throw new Error("required combinations must be unique exact profile_id:spring_boot_version:architecture_family keys");
|
|
30
|
+
const required = new Set(requested);
|
|
27
31
|
const rows = [];
|
|
28
32
|
for (const profile of loadBackendPlatforms().profiles) for (const family of ["domain-driven", "layered-mvc"]) {
|
|
29
33
|
const row = { profile_id: profile.id, spring_boot_version: profile.spring_boot_version, java_version: profile.java_version, architecture_family: family, status: "blocked", blockers: [], commands: [], executed_at: new Date().toISOString() };
|
|
34
|
+
row.required = required.has(`${profile.id}:${profile.spring_boot_version}:${family}`);
|
|
35
|
+
if (!row.required) { row.status = "not-executed"; row.reason = "outside explicitly requested matrix"; rows.push(row); continue; }
|
|
30
36
|
const configuration = input.combinations?.find(item => item.profile_id === profile.id && item.spring_boot_version === profile.spring_boot_version && item.architecture_family === family);
|
|
31
37
|
for (const key of ["YSS_MAVEN_REPOSITORY_URL", "MAVEN_REPO_USERNAME", "MAVEN_REPO_PASSWORD"]) if (!process.env[key]) row.blockers.push(`missing environment: ${key}`);
|
|
32
38
|
if (!configuration?.contract_ref) row.blockers.push("missing real approved scaffold contract/YSS compatibility coordinates");
|
|
@@ -63,7 +69,7 @@ for (const profile of loadBackendPlatforms().profiles) for (const family of ["do
|
|
|
63
69
|
}
|
|
64
70
|
rows.push(row);
|
|
65
71
|
}
|
|
66
|
-
const report = { schema_version: 1, kind: "backend-platform-matrix", generated_at: new Date().toISOString(), status: rows.every(row => row.status === "passed") ? "passed" : "blocked", combinations: rows };
|
|
72
|
+
const report = { schema_version: 1, kind: "backend-platform-matrix", generated_at: new Date().toISOString(), scope: requested.length === allKeys.length ? "full-matrix" : "required-combinations", required_combinations: requested, certification_policy: "each platform and architecture still requires complete independently validated compatibility evidence", status: rows.filter(row => row.required).every(row => row.status === "passed") ? "passed" : "blocked", combinations: rows };
|
|
67
73
|
await writeFile(path.join(evidence, "platform-matrix.json"), JSON.stringify(report, null, 2));
|
|
68
74
|
process.stdout.write(`${report.status}: ${path.join(evidence, "platform-matrix.json")}\n`);
|
|
69
75
|
if (report.status !== "passed") process.exitCode = 1;
|