create-yss-spec 3.4.8 → 3.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/template/attach-planner.js +5 -0
- package/src/template/sync-planner.js +5 -0
- package/template/.agents/skills/.strategic-design-skills-manifest.json +5 -5
- package/template/.agents/skills/alibaba-java-code-style/SKILL.md +2 -2
- package/template/.agents/skills/archify/SKILL.md +2 -19
- package/template/.agents/skills/archify/references/geometry-and-routing.md +20 -0
- package/template/.agents/skills/code-review/SKILL.md +3 -33
- package/template/.agents/skills/code-review/references/candidate-capture.md +33 -0
- package/template/.agents/skills/code-review/references/yss-review-standards.md +3 -5
- package/template/.agents/skills/codebase-design/SKILL.md +2 -2
- package/template/.agents/skills/competitive-intelligence/SKILL.md +1 -1
- package/template/.agents/skills/diagnosing-bugs/SKILL.md +6 -2
- package/template/.agents/skills/formily-foundation/SKILL.md +1 -1
- package/template/.agents/skills/formily-step-flow/SKILL.md +3 -2
- package/template/.agents/skills/frontend-commit/SKILL.md +6 -6
- package/template/.agents/skills/grilling/SKILL.md +2 -2
- package/template/.agents/skills/implement/SKILL.md +1 -1
- package/template/.agents/skills/implementation-repo-onboarding/SKILL.md +3 -3
- package/template/.agents/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
- package/template/.agents/skills/improve-codebase-architecture/SKILL.md +10 -6
- package/template/.agents/skills/java-backend-commit/SKILL.md +5 -5
- package/template/.agents/skills/llm-wiki/SKILL.md +1 -1
- package/template/.agents/skills/prototype/SKILL.md +1 -1
- package/template/.agents/skills/prototype-review/SKILL.md +1 -1
- package/template/.agents/skills/resolving-merge-conflicts/SKILL.md +2 -2
- package/template/.agents/skills/tdd/SKILL.md +1 -1
- package/template/.agents/skills/to-questionnaire/SKILL.md +4 -2
- package/template/.agents/skills/to-spec/SKILL.md +3 -3
- package/template/.agents/skills/to-tickets/SKILL.md +7 -7
- package/template/.agents/skills/using-git-worktrees/SKILL.md +13 -11
- package/template/.agents/skills/wait-what/SKILL.md +1 -1
- package/template/.agents/skills/wayfinder/SKILL.md +4 -2
- package/template/.agents/skills/writing-for-agents/SKILL.md +9 -73
- package/template/.agents/skills/writing-for-agents/references/writing-principles.md +76 -0
- package/template/.agents/skills/yss-api-integration/SKILL.md +2 -2
- package/template/.agents/skills/yss-application/SKILL.md +12 -0
- package/template/.agents/skills/yss-audit-log/SKILL.md +3 -1
- package/template/.agents/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
- package/template/.agents/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
- package/template/.agents/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
- package/template/.agents/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
- package/template/.agents/skills/yss-backend-spec-review/SKILL.md +6 -0
- package/template/.agents/skills/yss-backend-spec-review/references/check-inputs.md +2 -2
- package/template/.agents/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
- package/template/.agents/skills/yss-ddd-scaffold-generator/SKILL.md +5 -34
- package/template/.agents/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
- package/template/.agents/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
- package/template/.agents/skills/yss-design-system/SKILL.md +2 -2
- package/template/.agents/skills/yss-domain/SKILL.md +17 -5
- package/template/.agents/skills/yss-domain/references/domain-layer-guide.md +2 -2
- package/template/.agents/skills/yss-domain/references/existing-project.md +5 -0
- package/template/.agents/skills/yss-dto/SKILL.md +13 -10
- package/template/.agents/skills/yss-dto/references/wire-validation-checklist.md +14 -0
- package/template/.agents/skills/yss-exception/SKILL.md +2 -2
- package/template/.agents/skills/yss-formily-schema-generator/SKILL.md +12 -12
- package/template/.agents/skills/yss-hook/SKILL.md +8 -44
- package/template/.agents/skills/yss-hook/references/use-request.md +42 -0
- package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +3 -5
- package/template/.agents/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
- package/template/.agents/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
- package/template/.agents/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
- package/template/.agents/skills/yss-mybatis/SKILL.md +10 -0
- package/template/.agents/skills/yss-openapi-draft-review/SKILL.md +3 -1
- package/template/.agents/skills/yss-openapi-governance/SKILL.md +5 -32
- package/template/.agents/skills/yss-openapi-governance/references/governance-output.md +34 -0
- package/template/.agents/skills/yss-product-lifecycle/SKILL.md +12 -6
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +63 -1
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +2 -2
- package/template/.agents/skills/yss-prototype-stage/SKILL.md +3 -5
- package/template/.agents/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
- package/template/.agents/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +2 -2
- package/template/.agents/skills/yss-repository/SKILL.md +13 -1
- package/template/.agents/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
- package/template/.agents/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
- package/template/.agents/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
- package/template/.agents/skills/yss-stage-decision/SKILL.md +3 -1
- package/template/.agents/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
- package/template/.agents/skills/yss-tactical-design/SKILL.md +3 -3
- package/template/.agents/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
- package/template/.agents/skills/yss-technical-design/SKILL.md +2 -0
- package/template/.agents/skills/yss-technical-design/scripts/engineering-design.mjs +1 -1
- package/template/.agents/skills/yss-technical-design/scripts/validate-technical-design.mjs +11 -8
- package/template/.agents/skills/yss-ui-business-page-generation/SKILL.md +5 -3
- package/template/.agents/skills/yss-validation/SKILL.md +1 -1
- package/template/.agents/skills/yss-web-controller/SKILL.md +16 -7
- package/template/.agents/skills/ytable-usage/SKILL.md +2 -2
- package/template/.codex/skills/alibaba-java-code-style/SKILL.md +2 -2
- package/template/.codex/skills/archify/SKILL.md +2 -19
- package/template/.codex/skills/archify/references/geometry-and-routing.md +20 -0
- package/template/.codex/skills/code-review/SKILL.md +3 -33
- package/template/.codex/skills/code-review/references/candidate-capture.md +33 -0
- package/template/.codex/skills/code-review/references/yss-review-standards.md +3 -5
- package/template/.codex/skills/codebase-design/SKILL.md +2 -2
- package/template/.codex/skills/competitive-intelligence/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/mcp/server.cjs +2 -1
- package/template/.codex/skills/data-analytics/skills/analyze-data-quality/SKILL.md +9 -32
- package/template/.codex/skills/data-analytics/skills/analyze-data-quality/references/quality-checks.md +29 -0
- package/template/.codex/skills/data-analytics/skills/build-dashboard/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/build-report/SKILL.md +4 -4
- package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/SKILL.md +12 -22
- package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/cli.py +5 -10
- package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/scripts/report_to_google_doc/plan.py +47 -49
- package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-doc/tests/test_delivery_plan.py +45 -0
- package/template/.codex/skills/data-analytics/skills/build-report/report-to-google-slides/SKILL.md +4 -5
- package/template/.codex/skills/data-analytics/skills/build-report/report-to-pdf/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/build-report/specifications/mcp-app-report.md +1 -1
- package/template/.codex/skills/data-analytics/skills/design-kpis/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/gather-business-context/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/index/SKILL.md +4 -4
- package/template/.codex/skills/data-analytics/skills/jupyter-notebooks/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/kpi-reporting/SKILL.md +2 -2
- package/template/.codex/skills/data-analytics/skills/market-sizing/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/metric-diagnostics/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/product-business-analysis/SKILL.md +1 -1
- package/template/.codex/skills/data-analytics/skills/spreadsheets/SKILL.md +4 -4
- package/template/.codex/skills/data-analytics/skills/user-context/SKILL.md +16 -14
- package/template/.codex/skills/data-analytics/skills/user-context/plugin-author-config/automation-config.md +1 -1
- package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding-examples.md +1 -1
- package/template/.codex/skills/data-analytics/skills/user-context/references/onboarding.md +7 -7
- package/template/.codex/skills/data-analytics/skills/user-context/references/source-category-runtime.md +7 -7
- package/template/.codex/skills/data-analytics/skills/user-context/scripts/data_analytics_preflight.py +4 -2
- package/template/.codex/skills/data-analytics/skills/user-context/scripts/validate_user_context_preflight.py +5 -5
- package/template/.codex/skills/data-analytics/skills/user-context/tests/test_state_helpers.py +3 -3
- package/template/.codex/skills/data-analytics/skills/validate-data/SKILL.md +7 -71
- package/template/.codex/skills/data-analytics/skills/validate-data/references/validation-methods.md +70 -0
- package/template/.codex/skills/data-analytics/skills/visualize-data/SKILL.md +4 -4
- package/template/.codex/skills/data-analytics/src/analytics-app/App.tsx +1 -1
- package/template/.codex/skills/data-analytics/src/analytics-app-core.md +1 -1
- package/template/.codex/skills/diagnosing-bugs/SKILL.md +6 -2
- package/template/.codex/skills/formily-foundation/SKILL.md +1 -1
- package/template/.codex/skills/formily-step-flow/SKILL.md +3 -2
- package/template/.codex/skills/frontend-commit/SKILL.md +6 -6
- package/template/.codex/skills/grilling/SKILL.md +2 -2
- package/template/.codex/skills/implement/SKILL.md +1 -1
- package/template/.codex/skills/implementation-repo-onboarding/SKILL.md +3 -3
- package/template/.codex/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
- package/template/.codex/skills/improve-codebase-architecture/SKILL.md +10 -6
- package/template/.codex/skills/java-backend-commit/SKILL.md +5 -5
- package/template/.codex/skills/llm-wiki/SKILL.md +1 -1
- package/template/.codex/skills/product-design/references/critical-overrides.md +3 -4
- package/template/.codex/skills/product-design/skills/audit/SKILL.md +1 -1
- package/template/.codex/skills/product-design/skills/design-qa/SKILL.md +1 -1
- package/template/.codex/skills/product-design/skills/get-context/SKILL.md +2 -1
- package/template/.codex/skills/product-design/skills/ideate/SKILL.md +2 -50
- package/template/.codex/skills/product-design/skills/ideate/references/image-prompt-patterns.md +51 -0
- package/template/.codex/skills/product-design/skills/image-to-code/SKILL.md +6 -6
- package/template/.codex/skills/product-design/skills/index/SKILL.md +2 -2
- package/template/.codex/skills/product-design/skills/prototype/SKILL.md +6 -6
- package/template/.codex/skills/product-design/skills/url-to-code/SKILL.md +1 -1
- package/template/.codex/skills/product-design/skills/user-context/SKILL.md +1 -1
- package/template/.codex/skills/prototype/SKILL.md +1 -1
- package/template/.codex/skills/prototype-review/SKILL.md +1 -1
- package/template/.codex/skills/resolving-merge-conflicts/SKILL.md +2 -2
- package/template/.codex/skills/tdd/SKILL.md +1 -1
- package/template/.codex/skills/to-questionnaire/SKILL.md +4 -2
- package/template/.codex/skills/to-spec/SKILL.md +3 -3
- package/template/.codex/skills/to-tickets/SKILL.md +7 -7
- package/template/.codex/skills/using-git-worktrees/SKILL.md +13 -11
- package/template/.codex/skills/wait-what/SKILL.md +1 -1
- package/template/.codex/skills/wayfinder/SKILL.md +4 -2
- package/template/.codex/skills/writing-for-agents/SKILL.md +9 -73
- package/template/.codex/skills/writing-for-agents/references/writing-principles.md +76 -0
- package/template/.codex/skills/yss-api-integration/SKILL.md +2 -2
- package/template/.codex/skills/yss-application/SKILL.md +12 -0
- package/template/.codex/skills/yss-audit-log/SKILL.md +3 -1
- package/template/.codex/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
- package/template/.codex/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
- package/template/.codex/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
- package/template/.codex/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
- package/template/.codex/skills/yss-backend-spec-review/SKILL.md +6 -0
- package/template/.codex/skills/yss-backend-spec-review/references/check-inputs.md +2 -2
- package/template/.codex/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
- package/template/.codex/skills/yss-ddd-scaffold-generator/SKILL.md +5 -34
- package/template/.codex/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
- package/template/.codex/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
- package/template/.codex/skills/yss-design-system/SKILL.md +2 -2
- package/template/.codex/skills/yss-domain/SKILL.md +17 -5
- package/template/.codex/skills/yss-domain/references/domain-layer-guide.md +2 -2
- package/template/.codex/skills/yss-domain/references/existing-project.md +5 -0
- package/template/.codex/skills/yss-dto/SKILL.md +13 -10
- package/template/.codex/skills/yss-dto/references/wire-validation-checklist.md +14 -0
- package/template/.codex/skills/yss-exception/SKILL.md +2 -2
- package/template/.codex/skills/yss-formily-schema-generator/SKILL.md +12 -12
- package/template/.codex/skills/yss-hook/SKILL.md +8 -44
- package/template/.codex/skills/yss-hook/references/use-request.md +42 -0
- package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +3 -5
- package/template/.codex/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
- package/template/.codex/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
- package/template/.codex/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
- package/template/.codex/skills/yss-mybatis/SKILL.md +10 -0
- package/template/.codex/skills/yss-openapi-draft-review/SKILL.md +3 -1
- package/template/.codex/skills/yss-openapi-governance/SKILL.md +5 -32
- package/template/.codex/skills/yss-openapi-governance/references/governance-output.md +34 -0
- package/template/.codex/skills/yss-product-lifecycle/SKILL.md +12 -6
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +63 -1
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +2 -2
- package/template/.codex/skills/yss-prototype-stage/SKILL.md +3 -5
- package/template/.codex/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
- package/template/.codex/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +2 -2
- package/template/.codex/skills/yss-repository/SKILL.md +13 -1
- package/template/.codex/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
- package/template/.codex/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
- package/template/.codex/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
- package/template/.codex/skills/yss-stage-decision/SKILL.md +3 -1
- package/template/.codex/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
- package/template/.codex/skills/yss-tactical-design/SKILL.md +3 -3
- package/template/.codex/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
- package/template/.codex/skills/yss-technical-design/SKILL.md +2 -0
- package/template/.codex/skills/yss-technical-design/scripts/engineering-design.mjs +1 -1
- package/template/.codex/skills/yss-technical-design/scripts/validate-technical-design.mjs +11 -8
- package/template/.codex/skills/yss-ui-business-page-generation/SKILL.md +5 -3
- package/template/.codex/skills/yss-validation/SKILL.md +1 -1
- package/template/.codex/skills/yss-web-controller/SKILL.md +16 -7
- package/template/.codex/skills/ytable-usage/SKILL.md +2 -2
- package/template/.cursor/skills/alibaba-java-code-style/SKILL.md +2 -2
- package/template/.cursor/skills/archify/SKILL.md +2 -19
- package/template/.cursor/skills/archify/references/geometry-and-routing.md +20 -0
- package/template/.cursor/skills/code-review/SKILL.md +3 -33
- package/template/.cursor/skills/code-review/references/candidate-capture.md +33 -0
- package/template/.cursor/skills/code-review/references/yss-review-standards.md +3 -5
- package/template/.cursor/skills/codebase-design/SKILL.md +2 -2
- package/template/.cursor/skills/competitive-intelligence/SKILL.md +1 -1
- package/template/.cursor/skills/diagnosing-bugs/SKILL.md +6 -2
- package/template/.cursor/skills/formily-foundation/SKILL.md +1 -1
- package/template/.cursor/skills/formily-step-flow/SKILL.md +3 -2
- package/template/.cursor/skills/frontend-commit/SKILL.md +6 -6
- package/template/.cursor/skills/grilling/SKILL.md +2 -2
- package/template/.cursor/skills/implement/SKILL.md +1 -1
- package/template/.cursor/skills/implementation-repo-onboarding/SKILL.md +3 -3
- package/template/.cursor/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
- package/template/.cursor/skills/improve-codebase-architecture/SKILL.md +10 -6
- package/template/.cursor/skills/java-backend-commit/SKILL.md +5 -5
- package/template/.cursor/skills/llm-wiki/SKILL.md +1 -1
- package/template/.cursor/skills/prototype/SKILL.md +1 -1
- package/template/.cursor/skills/prototype-review/SKILL.md +1 -1
- package/template/.cursor/skills/resolving-merge-conflicts/SKILL.md +2 -2
- package/template/.cursor/skills/tdd/SKILL.md +1 -1
- package/template/.cursor/skills/to-questionnaire/SKILL.md +4 -2
- package/template/.cursor/skills/to-spec/SKILL.md +3 -3
- package/template/.cursor/skills/to-tickets/SKILL.md +7 -7
- package/template/.cursor/skills/using-git-worktrees/SKILL.md +13 -11
- package/template/.cursor/skills/wait-what/SKILL.md +1 -1
- package/template/.cursor/skills/wayfinder/SKILL.md +4 -2
- package/template/.cursor/skills/writing-for-agents/SKILL.md +9 -73
- package/template/.cursor/skills/writing-for-agents/references/writing-principles.md +76 -0
- package/template/.cursor/skills/yss-api-integration/SKILL.md +2 -2
- package/template/.cursor/skills/yss-application/SKILL.md +12 -0
- package/template/.cursor/skills/yss-audit-log/SKILL.md +3 -1
- package/template/.cursor/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
- package/template/.cursor/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
- package/template/.cursor/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
- package/template/.cursor/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
- package/template/.cursor/skills/yss-backend-spec-review/SKILL.md +6 -0
- package/template/.cursor/skills/yss-backend-spec-review/references/check-inputs.md +2 -2
- package/template/.cursor/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
- package/template/.cursor/skills/yss-ddd-scaffold-generator/SKILL.md +5 -34
- package/template/.cursor/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
- package/template/.cursor/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
- package/template/.cursor/skills/yss-design-system/SKILL.md +2 -2
- package/template/.cursor/skills/yss-domain/SKILL.md +17 -5
- package/template/.cursor/skills/yss-domain/references/domain-layer-guide.md +2 -2
- package/template/.cursor/skills/yss-domain/references/existing-project.md +5 -0
- package/template/.cursor/skills/yss-dto/SKILL.md +13 -10
- package/template/.cursor/skills/yss-dto/references/wire-validation-checklist.md +14 -0
- package/template/.cursor/skills/yss-exception/SKILL.md +2 -2
- package/template/.cursor/skills/yss-formily-schema-generator/SKILL.md +12 -12
- package/template/.cursor/skills/yss-hook/SKILL.md +8 -44
- package/template/.cursor/skills/yss-hook/references/use-request.md +42 -0
- package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +3 -5
- package/template/.cursor/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
- package/template/.cursor/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
- package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
- package/template/.cursor/skills/yss-mybatis/SKILL.md +10 -0
- package/template/.cursor/skills/yss-openapi-draft-review/SKILL.md +3 -1
- package/template/.cursor/skills/yss-openapi-governance/SKILL.md +5 -32
- package/template/.cursor/skills/yss-openapi-governance/references/governance-output.md +34 -0
- package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +12 -6
- package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +63 -1
- package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +2 -2
- package/template/.cursor/skills/yss-prototype-stage/SKILL.md +3 -5
- package/template/.cursor/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
- package/template/.cursor/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +2 -2
- package/template/.cursor/skills/yss-repository/SKILL.md +13 -1
- package/template/.cursor/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
- package/template/.cursor/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
- package/template/.cursor/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
- package/template/.cursor/skills/yss-stage-decision/SKILL.md +3 -1
- package/template/.cursor/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
- package/template/.cursor/skills/yss-tactical-design/SKILL.md +3 -3
- package/template/.cursor/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
- package/template/.cursor/skills/yss-technical-design/SKILL.md +2 -0
- package/template/.cursor/skills/yss-technical-design/scripts/engineering-design.mjs +1 -1
- package/template/.cursor/skills/yss-technical-design/scripts/validate-technical-design.mjs +11 -8
- package/template/.cursor/skills/yss-ui-business-page-generation/SKILL.md +5 -3
- package/template/.cursor/skills/yss-validation/SKILL.md +1 -1
- package/template/.cursor/skills/yss-web-controller/SKILL.md +16 -7
- package/template/.cursor/skills/ytable-usage/SKILL.md +2 -2
- package/template/.pi/skills/alibaba-java-code-style/SKILL.md +2 -2
- package/template/.pi/skills/archify/SKILL.md +2 -19
- package/template/.pi/skills/archify/references/geometry-and-routing.md +20 -0
- package/template/.pi/skills/code-review/SKILL.md +3 -33
- package/template/.pi/skills/code-review/references/candidate-capture.md +33 -0
- package/template/.pi/skills/code-review/references/yss-review-standards.md +3 -5
- package/template/.pi/skills/codebase-design/SKILL.md +2 -2
- package/template/.pi/skills/competitive-intelligence/SKILL.md +1 -1
- package/template/.pi/skills/diagnosing-bugs/SKILL.md +6 -2
- package/template/.pi/skills/formily-foundation/SKILL.md +1 -1
- package/template/.pi/skills/formily-step-flow/SKILL.md +3 -2
- package/template/.pi/skills/frontend-commit/SKILL.md +6 -6
- package/template/.pi/skills/grilling/SKILL.md +2 -2
- package/template/.pi/skills/implement/SKILL.md +1 -1
- package/template/.pi/skills/implementation-repo-onboarding/SKILL.md +3 -3
- package/template/.pi/skills/implementation-repo-onboarding/references/write-scope.md +5 -0
- package/template/.pi/skills/improve-codebase-architecture/SKILL.md +10 -6
- package/template/.pi/skills/java-backend-commit/SKILL.md +5 -5
- package/template/.pi/skills/llm-wiki/SKILL.md +1 -1
- package/template/.pi/skills/prototype/SKILL.md +1 -1
- package/template/.pi/skills/prototype-review/SKILL.md +1 -1
- package/template/.pi/skills/resolving-merge-conflicts/SKILL.md +2 -2
- package/template/.pi/skills/tdd/SKILL.md +1 -1
- package/template/.pi/skills/to-questionnaire/SKILL.md +4 -2
- package/template/.pi/skills/to-spec/SKILL.md +3 -3
- package/template/.pi/skills/to-tickets/SKILL.md +7 -7
- package/template/.pi/skills/using-git-worktrees/SKILL.md +13 -11
- package/template/.pi/skills/wait-what/SKILL.md +1 -1
- package/template/.pi/skills/wayfinder/SKILL.md +4 -2
- package/template/.pi/skills/writing-for-agents/SKILL.md +9 -73
- package/template/.pi/skills/writing-for-agents/references/writing-principles.md +76 -0
- package/template/.pi/skills/yss-api-integration/SKILL.md +2 -2
- package/template/.pi/skills/yss-application/SKILL.md +12 -0
- package/template/.pi/skills/yss-audit-log/SKILL.md +3 -1
- package/template/.pi/skills/yss-audit-log/assets/AuditLogAspect.java +1 -0
- package/template/.pi/skills/yss-audit-log/assets/YssAuditLogPrintSubscriberImpl.java +1 -0
- package/template/.pi/skills/yss-audit-log/assets/YssAuditLogSysManagerSubscriberImpl.java +1 -0
- package/template/.pi/skills/yss-audit-log/assets/YssAuditPublishService.java +1 -0
- package/template/.pi/skills/yss-backend-spec-review/SKILL.md +6 -0
- package/template/.pi/skills/yss-backend-spec-review/references/check-inputs.md +2 -2
- package/template/.pi/skills/yss-backend-spec-review/references/standards-coverage.md +39 -0
- package/template/.pi/skills/yss-ddd-scaffold-generator/SKILL.md +5 -34
- package/template/.pi/skills/yss-ddd-scaffold-generator/references/command-examples.md +32 -0
- package/template/.pi/skills/yss-ddd-scaffold-generator/references/generator-maintenance.md +7 -0
- package/template/.pi/skills/yss-design-system/SKILL.md +2 -2
- package/template/.pi/skills/yss-domain/SKILL.md +17 -5
- package/template/.pi/skills/yss-domain/references/domain-layer-guide.md +2 -2
- package/template/.pi/skills/yss-domain/references/existing-project.md +5 -0
- package/template/.pi/skills/yss-dto/SKILL.md +13 -10
- package/template/.pi/skills/yss-dto/references/wire-validation-checklist.md +14 -0
- package/template/.pi/skills/yss-exception/SKILL.md +2 -2
- package/template/.pi/skills/yss-formily-schema-generator/SKILL.md +12 -12
- package/template/.pi/skills/yss-hook/SKILL.md +8 -44
- package/template/.pi/skills/yss-hook/references/use-request.md +42 -0
- package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +3 -5
- package/template/.pi/skills/yss-implementation-contract-compiler/references/strategic-handoff-routing.md +7 -0
- package/template/.pi/skills/yss-implementation-contract-compiler/references/yss-skill-execution-result.md +5 -1
- package/template/.pi/skills/yss-layered-mvc-scaffold-generator/SKILL.md +2 -2
- package/template/.pi/skills/yss-mybatis/SKILL.md +10 -0
- package/template/.pi/skills/yss-openapi-draft-review/SKILL.md +3 -1
- package/template/.pi/skills/yss-openapi-governance/SKILL.md +5 -32
- package/template/.pi/skills/yss-openapi-governance/references/governance-output.md +34 -0
- package/template/.pi/skills/yss-product-lifecycle/SKILL.md +12 -6
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +63 -1
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +2 -2
- package/template/.pi/skills/yss-prototype-stage/SKILL.md +3 -5
- package/template/.pi/skills/yss-prototype-stage/references/existing-ui-entry.md +7 -0
- package/template/.pi/skills/yss-prototype-stage/scripts/visual-baseline-contract.mjs +2 -2
- package/template/.pi/skills/yss-repository/SKILL.md +13 -1
- package/template/.pi/skills/yss-repository/references/profiles/existing-domain-driven-maven.md +7 -0
- package/template/.pi/skills/yss-repository/references/profiles/existing-layered-mvc-maven.md +7 -0
- package/template/.pi/skills/yss-repository/tests/profile-routing.test.mjs +3 -1
- package/template/.pi/skills/yss-stage-decision/SKILL.md +3 -1
- package/template/.pi/skills/yss-stage-decision/references/strategic-handoff-routing.md +3 -0
- package/template/.pi/skills/yss-tactical-design/SKILL.md +3 -3
- package/template/.pi/skills/yss-tactical-design/references/strategic-handoff-routing.md +5 -0
- package/template/.pi/skills/yss-technical-design/SKILL.md +2 -0
- package/template/.pi/skills/yss-technical-design/scripts/engineering-design.mjs +1 -1
- package/template/.pi/skills/yss-technical-design/scripts/validate-technical-design.mjs +11 -8
- package/template/.pi/skills/yss-ui-business-page-generation/SKILL.md +5 -3
- package/template/.pi/skills/yss-validation/SKILL.md +1 -1
- package/template/.pi/skills/yss-web-controller/SKILL.md +16 -7
- package/template/.pi/skills/ytable-usage/SKILL.md +2 -2
- package/template/AGENTS.md +2 -0
- package/template/CONTEXT.md +2 -1
- package/template/README.md +1 -0
- package/template/docs/agents/issue-tracker.md +7 -0
- package/template/docs/process/contract-reading.md +46 -0
- package/template/docs/process/lifecycle-artifact-map.md +2 -2
- package/template/docs/process/lifecycle-registry-baseline.json +2 -1
- package/template/docs/process/lifecycle-registry.yaml +10 -4
- package/template/docs/process/schemas/api-contract-decision-v2.schema.json +198 -0
- package/template/docs/process/schemas/digital-human-task-package.schema.json +68 -4
- package/template/docs/process/schemas/lifecycle-checkpoint.schema.json +259 -0
- package/template/docs/process/schemas/stage-tracking.schema.json +259 -0
- package/template/docs/process/stage-tracking.md +62 -0
- package/template/docs/process/strategic-handoff-package.md +8 -0
- package/template/docs/user-guide//347/224/250/346/210/267/346/211/213/345/206/214.md +2 -0
- package/template/docs/user-guide//347/224/250/346/210/267/346/211/213/345/206/214/347/264/242/345/274/225.md +1 -0
- package/template/docs/user-guide//351/230/266/346/256/265/346/216/245/345/205/245/344/270/216/344/272/247/347/211/251/345/244/215/347/224/250/344/275/277/347/224/250/346/211/213/345/206/214.md +243 -0
- package/template/scripts/api-contract-decision +16 -0
- package/template/scripts/backend-standards-coverage +26 -0
- package/template/scripts/complete-backend-delivery +17 -0
- package/template/scripts/contract +13 -0
- package/template/scripts/dispatch-slice-task +13 -0
- package/template/scripts/lib/api-contract-decision.mjs +45 -4
- package/template/scripts/lib/approval-record.mjs +1 -1
- package/template/scripts/lib/approved-execution-context.mjs +35 -7
- package/template/scripts/lib/backend-architecture.mjs +2 -2
- package/template/scripts/lib/backend-delivery-terminal.mjs +51 -0
- package/template/scripts/lib/backend-platform-provenance.mjs +1 -1
- package/template/scripts/lib/backend-platform.mjs +1 -1
- package/template/scripts/lib/backend-review.mjs +58 -20
- package/template/scripts/lib/backend-scaffold-prerequisites.mjs +1 -1
- package/template/scripts/lib/backend-standards-coverage.mjs +237 -0
- package/template/scripts/lib/context-contract.mjs +1 -1
- package/template/scripts/lib/context-reconciliation.mjs +1 -1
- package/template/scripts/lib/contract-source.mjs +22 -0
- package/template/scripts/lib/contract-views.mjs +109 -0
- package/template/scripts/lib/delivery-preflight.mjs +3 -2
- package/template/scripts/lib/digital-human-roles.mjs +1 -1
- package/template/scripts/lib/existing-backend-architecture.mjs +4 -3
- package/template/scripts/lib/existing-ui-baseline.mjs +4 -2
- package/template/scripts/lib/first-slice-artifacts.mjs +1 -1
- package/template/scripts/lib/frontend-delivery-boundary.mjs +1 -1
- package/template/scripts/lib/frontend-delivery.mjs +1 -1
- package/template/scripts/lib/harness-execution-scope.mjs +15 -1
- package/template/scripts/lib/implementation-contract-compiler.mjs +4 -4
- package/template/scripts/lib/json-schema.mjs +19 -4
- package/template/scripts/lib/lifecycle-context-query.mjs +5 -1
- package/template/scripts/lib/lifecycle-controls.mjs +1 -1
- package/template/scripts/lib/lifecycle-execution-scope.mjs +92 -0
- package/template/scripts/lib/lifecycle-registry.mjs +2 -1
- package/template/scripts/lib/lifecycle-transition.mjs +25 -4
- package/template/scripts/lib/openapi-draft-validation.mjs +2 -1
- package/template/scripts/lib/profile-skill-sync.mjs +46 -5
- package/template/scripts/lib/skill-registry.mjs +1 -1
- package/template/scripts/lib/slice-contract-preparation.mjs +16 -14
- package/template/scripts/lib/slice-contract-views.mjs +1 -1
- package/template/scripts/lib/slice-contract.mjs +18 -3
- package/template/scripts/lib/slice-execution-preflight.mjs +7 -3
- package/template/scripts/lib/slice-repositories.mjs +1 -1
- package/template/scripts/lib/slice-task-package.mjs +3 -2
- package/template/scripts/lib/stage-tracking-migration.mjs +176 -0
- package/template/scripts/lib/stage-tracking.mjs +184 -0
- package/template/scripts/lib/strategic-handoff-consumption.mjs +5 -4
- package/template/scripts/lib/strategic-handoff-io.mjs +5 -2
- package/template/scripts/lib/strategic-handoff-routing.mjs +31 -0
- package/template/scripts/lib/strategic-handoff.mjs +4 -2
- package/template/scripts/lib/task-package.mjs +2 -0
- package/template/scripts/lib/technical-design-boundary.mjs +4 -2
- package/template/scripts/lib/ui-baseline.mjs +1 -1
- package/template/scripts/lib/user-decision.mjs +1 -1
- package/template/scripts/lib/validation-phase.mjs +72 -0
- package/template/scripts/stage-tracking +25 -0
- package/template/scripts/strategic-consumer-entry +47 -0
- package/template/scripts/verify-context-reconciliation +4 -3
- package/template/scripts/verify-lifecycle-checkpoint +10 -0
- package/template/skills-lock.json +65 -63
- package/template.snapshot.json +4 -4
|
@@ -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
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { existsSync, lstatSync, readFileSync, readdirSync } from
|
|
2
|
+
import { existsSync, lstatSync, readFileSync, readdirSync } from './validation-phase.mjs';
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
|
|
5
5
|
const CONTEXT_FILE = "CONTEXT.md";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from
|
|
1
|
+
import { existsSync, readFileSync } from './validation-phase.mjs';
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { parseDocument } from "../vendor/yaml.mjs";
|
|
4
4
|
import { resolveContextTermRefs, verifyContextSnapshot } from "./context-contract.mjs";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {readFileSync} from './validation-phase.mjs';
|
|
2
|
+
import {safe,hash} from './strategic-handoff-io.mjs';
|
|
3
|
+
import {parseSliceYaml} from './slice-contract.mjs';
|
|
4
|
+
export function contractSourceMetadata(bytes){
|
|
5
|
+
const text=String(bytes),front=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(text);
|
|
6
|
+
if(front)return parseSliceYaml(front[1]);
|
|
7
|
+
return /^\s*[{[]/.test(text)||/^[A-Za-z_][\w-]*:\s/m.test(text)&&!/^#/m.test(text)?parseSliceYaml(text):{};
|
|
8
|
+
}
|
|
9
|
+
/** Reads original bytes; returns derivable facts only. It never selects or approves a source. */
|
|
10
|
+
export function readContractSource(selection,{root=process.cwd(),read=ref=>readFileSync(safe(root,ref))}={}){
|
|
11
|
+
const selected=typeof selection==='string'?{ref:selection}:selection;
|
|
12
|
+
if(!selected?.ref)throw new TypeError('来源选择缺少 ref');
|
|
13
|
+
const bytes=read(selected.ref),digest=hash(bytes),data=contractSourceMetadata(bytes);
|
|
14
|
+
const observed=data.requirement_version??data.version??data.contract_version??data.decision_version;
|
|
15
|
+
const conflicts=[];
|
|
16
|
+
const conflict=(field,before,after)=>conflicts.push({field,source_ref:selected.ref,before,after});
|
|
17
|
+
if(selected.digest&&selected.digest!==digest)conflict('digest',selected.digest,digest);
|
|
18
|
+
if(selected.version!==undefined&&observed!==undefined&&String(selected.version)!==String(observed))conflict('version',selected.version,observed);
|
|
19
|
+
if(conflicts.length){const error=new TypeError(conflicts.map(({field,before,after})=>`${field==='version'?'来源版本冲突':'来源冲突'} ${selected.ref}.${field}: supplied=${before}; observed=${after}; 恢复: 核对双方来源并显式选择当前版本`).join('\n'));Object.assign(error,{code:'SLICE_SOURCE_CONFLICT',...conflicts[0],conflicts});throw error;}
|
|
20
|
+
const version=selected.version??observed;
|
|
21
|
+
return {bytes,data,binding:{ref:selected.ref,digest,...(version!==undefined?{version:String(version)}:{}),...(selected.approval_ref?{approval_ref:selected.approval_ref}:{})}};
|
|
22
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import {readFileSync,withValidationPhase} from './validation-phase.mjs';
|
|
2
|
+
import {safe,hash,schema} from './strategic-handoff-io.mjs';
|
|
3
|
+
import {parseSliceYaml,readSliceContract} from './slice-contract.mjs';
|
|
4
|
+
import {renderSliceContractView,diffSliceContracts} from './slice-contract-views.mjs';
|
|
5
|
+
|
|
6
|
+
// This is a presentation adapter table, never a lifecycle or approval registry.
|
|
7
|
+
export const contractKinds=Object.freeze({
|
|
8
|
+
slice:null,plan:null,spec:null,'product-design':null,'prototype-confirmation':null,'visual-baseline':null,
|
|
9
|
+
'technical-design':'.agents/skills/yss-technical-design/references/technical-design.schema.json',
|
|
10
|
+
'api-decision':'docs/process/schemas/api-contract-decision.schema.json',
|
|
11
|
+
'data-decision':'docs/process/schemas/data-architecture-decision.schema.json',
|
|
12
|
+
scaffold:'docs/process/schemas/project-scaffold-contract.schema.json',
|
|
13
|
+
'scaffold-decision':'docs/process/schemas/scaffold-architecture-decisions.schema.json',
|
|
14
|
+
handoff:null,'backend-delivery':'docs/process/schemas/backend-delivery.schema.json',
|
|
15
|
+
'frontend-acceptance':'docs/process/schemas/frontend-delivery-acceptance.schema.json',approval:null,'user-decision':'docs/process/schemas/user-decision.schema.json',
|
|
16
|
+
'context-reconciliation':'docs/process/schemas/context-reconciliation.schema.json'
|
|
17
|
+
});
|
|
18
|
+
const object=v=>v&&typeof v==='object'&&!Array.isArray(v);
|
|
19
|
+
const stringify=v=>typeof v==='string'?v:JSON.stringify(v,null,2);
|
|
20
|
+
const metadata=/^(schema_version|kind|digest|sha256|subject_digest|.*_digest|.*_sha256|resolution|basis|inputs|sources|artifact_bindings|current_version)$/;
|
|
21
|
+
function display(value){
|
|
22
|
+
if(Array.isArray(value))return value.map(display);
|
|
23
|
+
if(!object(value))return value;
|
|
24
|
+
return Object.fromEntries(Object.entries(value).filter(([key])=>!metadata.test(key)).map(([k,v])=>[k,display(v)]));
|
|
25
|
+
}
|
|
26
|
+
function validateKind(kind){if(!Object.hasOwn(contractKinds,kind))throw new TypeError(`未知合同类型 ${kind};可用:${Object.keys(contractKinds).join(', ')}`);}
|
|
27
|
+
function load(ref,root){
|
|
28
|
+
const bytes=readFileSync(safe(root,ref));
|
|
29
|
+
if(/\.md$/i.test(ref)){
|
|
30
|
+
const text=bytes.toString('utf8'),front=/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(text);
|
|
31
|
+
return{bytes,raw:{...(front?parseSliceYaml(front[1]):{}),正文:front?text.slice(front[0].length):text}};
|
|
32
|
+
}
|
|
33
|
+
const raw=parseSliceYaml(bytes);if(!object(raw))throw new TypeError('合同必须是结构化对象或 Markdown 文档');return{bytes,raw};
|
|
34
|
+
}
|
|
35
|
+
function references(value,root,rows=[],seen=new Set()){
|
|
36
|
+
if(!value||typeof value!=='object')return rows;
|
|
37
|
+
if(object(value)&&typeof value.ref==='string'&&typeof value.digest==='string'){
|
|
38
|
+
const key=`${value.ref}\0${value.digest}`;
|
|
39
|
+
if(!seen.has(key)){seen.add(key);try{rows.push({ref:value.ref,current:hash(readFileSync(safe(root,value.ref)))===value.digest});}catch(error){rows.push({ref:value.ref,current:false,error:error.message});}}
|
|
40
|
+
}
|
|
41
|
+
if(object(value))for(const [key,ref]of Object.entries(value))if(key.endsWith('_ref')&&typeof ref==='string'&&typeof value[key.replace(/_ref$/,'_digest')]==='string')references({ref,digest:value[key.replace(/_ref$/,'_digest')]},root,rows,seen);
|
|
42
|
+
for(const child of Object.values(value))references(child,root,rows,seen);
|
|
43
|
+
return rows;
|
|
44
|
+
}
|
|
45
|
+
function declaredBlockers(value,prefix=''){
|
|
46
|
+
if(!value||typeof value!=='object')return[];
|
|
47
|
+
const rows=[];
|
|
48
|
+
for(const [key,child]of Object.entries(value)){
|
|
49
|
+
const field=prefix?`${prefix}.${key}`:key;
|
|
50
|
+
if(['blockers','blocking_findings','stale_inputs','readiness_blockers'].includes(key)&&Array.isArray(child))for(const item of child)rows.push(`${field}: ${stringify(item)}`);
|
|
51
|
+
else rows.push(...declaredBlockers(child,field));
|
|
52
|
+
}
|
|
53
|
+
return rows;
|
|
54
|
+
}
|
|
55
|
+
function markdown(view){
|
|
56
|
+
const lines=[`# ${view.kind} · ${view.binding.id||view.binding.ref}`,`版本:${view.binding.version||'源资产未声明'};权威文件:${view.binding.ref}`,`摘要:${view.binding.digest}`,`检查:${view.checks.join(';')}。批准有效性未核验;本视图不授予执行权限。`];
|
|
57
|
+
for(const [name,value]of Object.entries(view.content))if(value!==undefined)lines.push(`## ${name}`,stringify(value));
|
|
58
|
+
if(view.blockers.length)lines.push('## 阻断与未决检查',...view.blockers.map(x=>`- ${x}`));
|
|
59
|
+
return lines.join('\n\n')+'\n';
|
|
60
|
+
}
|
|
61
|
+
export function viewContract(ref,options={}){return withValidationPhase({root:options.root,purpose:'contract-view',slice_id:ref,work_unit_id:options.unit_id,readOnly:true},()=>view(ref,options));}
|
|
62
|
+
function view(ref,{root=process.cwd(),kind,profile='review',unit_id}={}){
|
|
63
|
+
validateKind(kind);if(!['review','task','full'].includes(profile))throw new TypeError(`未知阅读档位 ${profile}`);
|
|
64
|
+
let binding,content,checks=['可读取'],blockers=[],sourceChecks=[];
|
|
65
|
+
if(kind==='slice'){
|
|
66
|
+
const loaded=readSliceContract(ref,{root,diagnostic:true});binding=loaded.binding;blockers.push(...declaredBlockers(loaded.raw));
|
|
67
|
+
const legacy=renderSliceContractView(ref,{root,unit_id:profile==='task'?unit_id:undefined});
|
|
68
|
+
checks.push('Slice 结构及绑定来源');
|
|
69
|
+
if(legacy.diagnostic_only){content={诊断:legacy.blockers};blockers=legacy.blockers.map(b=>b.reason);}
|
|
70
|
+
else if(profile==='full')content={权威合同:loaded.raw,完整视图:legacy};
|
|
71
|
+
else if(profile==='review'){
|
|
72
|
+
content={...legacy.summary,验收:legacy.acceptance,实施范围:{工程:loaded.raw.scope?.project_roots||legacy.constraints.project_roots,允许写入:loaded.raw.scope?.allowed_write_paths||legacy.constraints.allowed_write_paths},关键约束:loaded.raw.scope?.forbidden_patterns||legacy.constraints.forbidden_patterns,停止条件:'来源或批准过期、越界、缺证据、验证失败、drift / violation / new_impacts 时停止并回交。'};
|
|
73
|
+
for(const key of ['risks','risk_acceptance','blockers','pending_decisions','constraints'])if(loaded.raw[key])content[key]=loaded.raw[key];
|
|
74
|
+
for(const [label,pattern]of [['风险',/风险/],['关键取舍',/取舍/],['待决定事项',/待|决定/],['变化',/变化|变更/]])if(!Object.keys(content).some(k=>pattern.test(k)))content[label]='来源未说明,审阅时核实。';
|
|
75
|
+
const extensions=loaded.raw.extensions||{};
|
|
76
|
+
for(const [name,extension]of Object.entries(extensions))for(const [key,value]of Object.entries(extension))if(/risk|constraint|decision|block|exception|unknown/.test(key))content[`${name}.${key}`]=value;
|
|
77
|
+
}else{
|
|
78
|
+
if(!unit_id)throw new TypeError('task 视图必须指定 --unit');
|
|
79
|
+
const units=loaded.contract.work_units.filter(u=>u.id===unit_id);if(units.length!==1)throw new TypeError(`工作单元缺失或不唯一: ${unit_id}`);
|
|
80
|
+
content={当前任务:units[0].work_unit||units[0],全局约束:legacy.constraints,专项约束:legacy.extensions,编译约束:loaded.raw.resolution,适用性:loaded.raw.applicability,验收:legacy.acceptance,上游引用:Object.fromEntries(Object.entries(loaded.sources).map(([k,v])=>[k,{ref:v.ref,version:v.version}])),停止条件:'来源或批准过期、越界、缺证据、验证失败、drift / violation / new_impacts 时停止并回交。'};
|
|
81
|
+
const known=new Set(['schema_version','contract_id','contract_version','slice_id','status','basis','scope','applicability','resolution','acceptance','verification','work_units','extensions','ticket_policy']);
|
|
82
|
+
content.其他约束=Object.fromEntries(Object.entries(loaded.raw).filter(([k])=>!known.has(k)));
|
|
83
|
+
}
|
|
84
|
+
}else{
|
|
85
|
+
const {bytes,raw}=load(ref,root);binding={ref,id:raw.contract_id||raw.technical_design_id||raw.decision_id||raw.request?.request_id||raw.handoff_id||raw.baseline_id||raw.spec_id||raw.plan_id||raw.id||null,version:raw.contract_version||raw.decision_version||raw.handoff_version||raw.version||null,digest:hash(bytes)};
|
|
86
|
+
blockers.push(...declaredBlockers(raw));
|
|
87
|
+
let schemaRef=contractKinds[kind];if(kind==='api-decision'&&raw.schema_version===2)schemaRef='docs/process/schemas/api-contract-decision-v2.schema.json';
|
|
88
|
+
if(kind==='frontend-acceptance'&&[1,3].includes(raw.schema_version))schemaRef=`docs/process/schemas/frontend-delivery-acceptance${raw.schema_version===1?'-v1':'-v3'}.schema.json`;
|
|
89
|
+
if(schemaRef)try{schema(raw,schemaRef);checks.push('结构校验');}catch(error){blockers.push(error.message);}
|
|
90
|
+
else checks.push('结构与批准未核验,按资产所有者规则继续');
|
|
91
|
+
sourceChecks=references(raw,root);if(sourceChecks.length)checks.push(`核对 ${sourceChecks.length} 项可识别来源摘要;其余语义由资产所有者核验`);for(const source of sourceChecks)if(!source.current)blockers.push(`来源不可读或过期:${source.ref}`);
|
|
92
|
+
// Unknown business fields remain visible. Only well-known machine metadata is hidden.
|
|
93
|
+
content=profile==='full'?{权威合同:raw,来源核对:sourceChecks}:display(raw);
|
|
94
|
+
if(kind==='api-decision'&&raw.schema_version===2&&raw.draft_review){try{const review=load(raw.draft_review.ref,root).raw;content.实际审查记录=profile==='full'?review:display(review);if(review.result!=='approved'||!Array.isArray(review.blocking_findings)||review.blocking_findings.length)blockers.push('OpenAPI Draft Review 实际记录未批准或有阻断');if(review.draft_ref!==raw.openapi?.ref||review.draft_digest!==raw.openapi?.digest)blockers.push('Draft Review 未绑定当前 OpenAPI');}catch(error){blockers.push(error.message);}}
|
|
95
|
+
if(profile==='task'){
|
|
96
|
+
if(raw.work_units){if(!unit_id)throw new TypeError('含工作单元的合同必须指定 --unit');const matches=raw.work_units.filter(x=>x.id===unit_id);if(matches.length!==1)throw new TypeError(`工作单元缺失或不唯一: ${unit_id}`);content.work_units=matches;}
|
|
97
|
+
content.机器绑定中的约束=Object.fromEntries(['resolution','basis','inputs','sources','artifact_bindings'].filter(k=>raw[k]!==undefined).map(k=>[k,raw[k]]));
|
|
98
|
+
content.约束分类='保留未分类字段;本视图只允许阅读,执行影响由资产所有者核验。';
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const view={read_only:true,execution_allowed:false,kind,profile,binding,checks,approval_validity:'not-checked',content,blockers};view.markdown=markdown(view);return view;
|
|
102
|
+
}
|
|
103
|
+
export function diffContract(beforeRef,afterRef,{root=process.cwd(),beforeRoot=root,kind}={}){
|
|
104
|
+
validateKind(kind);if(kind==='slice')return diffSliceContracts(beforeRef,afterRef,{root,beforeRoot});
|
|
105
|
+
const before=load(beforeRef,beforeRoot),after=load(afterRef,root),changes=[];
|
|
106
|
+
const walk=(a,b,p)=>{if(JSON.stringify(a)===JSON.stringify(b))return;if(object(a)&&object(b)){for(const key of new Set([...Object.keys(a),...Object.keys(b)]))walk(a[key],b[key],p?`${p}.${key}`:key);}else changes.push({path:p,before:a??null,after:b??null,category:metadata.test(p.split('.').at(-1))?'binding-change':'requires-review'});};
|
|
107
|
+
walk(before.raw,after.raw,'');const source_checks=[...references(before.raw,beforeRoot).map(x=>({...x,side:'before'})),...references(after.raw,root).map(x=>({...x,side:'after'}))];
|
|
108
|
+
return{read_only:true,approval_reusable:false,execution_allowed:false,before:{ref:beforeRef,digest:hash(before.bytes)},after:{ref:afterRef,digest:hash(after.bytes)},bytes_changed:!before.bytes.equals(after.bytes),changes,source_checks,decision_impact:'必须按当前差异和授权延续协议核验;无法读取旧来源时影响未知。'};
|
|
109
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { normalizeSliceContract, sourceSliceContract, parseSliceYaml } from './slice-contract.mjs';
|
|
2
2
|
import { assertExistingSliceStructure, createApprovedExecutionContext, verifySliceContractApproval } from './approved-execution-context.mjs';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import { readFileSync, existsSync } from '
|
|
4
|
+
import { readFileSync, existsSync, withValidationPhase } from './validation-phase.mjs';
|
|
5
5
|
import { ROOT, read, parse, safe, hash, digest, ensure, schema, sourceApprovalPolicy } from './strategic-handoff-io.mjs';
|
|
6
6
|
import { parseContextContract } from './context-contract.mjs';
|
|
7
7
|
import { validateApprovalRecord } from './approval-record.mjs';
|
|
@@ -47,7 +47,8 @@ function requireBackendCapability(key) {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
/** Read-only: never executes input commands, starts services, unpacks archives or writes receipts. */
|
|
50
|
-
export async function preflightDelivery(input,{
|
|
50
|
+
export async function preflightDelivery(input,options={}) {return withValidationPhase({root:path.resolve(options.root||process.cwd(),typeof input?.governance_root==='string'?input.governance_root:'.'),purpose:`delivery-${options.stage}`,slice_id:input?.scope?.slice_id,work_unit_id:options.work_unit_id,readOnly:true,signal:options.signal},()=>preflight(input,options));}
|
|
51
|
+
async function preflight(input,{stage,root=process.cwd(),work_unit_id}={}) {
|
|
51
52
|
try { ensure(STAGES.includes(stage),'未知阶段;必须是 prepare|build|export|accept');schema(input,'docs/process/schemas/delivery-preflight-input.schema.json'); }
|
|
52
53
|
catch(error) { return invalidPreflightInput(error.message); }
|
|
53
54
|
root=path.resolve(root,input.governance_root||'.');
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {assertApprovedExecutionContext} from './approved-execution-context.mjs';
|
|
2
2
|
import {createHash} from 'node:crypto';
|
|
3
|
-
import {
|
|
3
|
+
import { realpathSync } from 'node:fs';
|
|
4
|
+
import { readFileSync, lstatSync, readdirSync } from './validation-phase.mjs';
|
|
4
5
|
import path from 'node:path';
|
|
5
6
|
import {execFileSync} from 'node:child_process';
|
|
6
7
|
import {parseDocument} from '../vendor/yaml.mjs';
|
|
@@ -35,7 +36,7 @@ function inspectMaven(root,units){
|
|
|
35
36
|
const script=`import json,sys,xml.etree.ElementTree as ET\nout=[]\nfor p in json.load(sys.stdin):\n r=ET.parse(p).getroot(); ns={'m':'http://maven.apache.org/POM/4.0.0'}; q=lambda s:r.find(s,ns)\n aid=q('m:artifactId'); aid=aid if aid is not None else q('artifactId')\n deps=[e.text.strip() for e in r.findall('m:dependencies/m:dependency/m:artifactId',ns)+r.findall('m:profiles/m:profile/m:dependencies/m:dependency/m:artifactId',ns)+r.findall('dependencies/dependency/artifactId') if e.text]\n modules=[e.text.strip() for e in r.findall('.//m:modules/m:module',ns)+r.findall('.//modules/module') if e.text]\n out.append({'artifact_id':aid.text.strip() if aid is not None else '', 'dependencies':deps, 'modules':modules})\nprint(json.dumps(out))`;
|
|
36
37
|
try{return JSON.parse(execFileSync('python3',['-c',script],{input:JSON.stringify(units.map(u=>file(root,u.pom_ref))),encoding:'utf8',timeout:15000,maxBuffer:2*1024*1024}));}catch(error){requireThat(false,'ARCH_BUILD_INVALID',`无法读取实际 Maven 构建单元: ${error.message}`);}
|
|
37
38
|
}
|
|
38
|
-
export function verifyExistingArchitecture(identity,bindings,{root,registry,execution}={}){
|
|
39
|
+
export function verifyExistingArchitecture(identity,bindings,{root,registry,execution,readOnly=false}={}){
|
|
39
40
|
const profile=validateExistingArchitecture(identity,registry);
|
|
40
41
|
requireThat(text(root),'ARCH_EVIDENCE_REF','需要治理 root');
|
|
41
42
|
const baseline=bound(root,bindings?.engineering_baseline),registration=bound(root,bindings?.repository_registration),manifest=bound(root,bindings?.manifest);
|
|
@@ -132,7 +133,7 @@ export function verifyExistingArchitecture(identity,bindings,{root,registry,exec
|
|
|
132
133
|
}
|
|
133
134
|
if(changes.length){
|
|
134
135
|
requireThat(execution,'ARCH_SOURCE_STALE',`固定源码改变: ${changes.join(', ')}`);
|
|
135
|
-
const permission=assertApprovedExecutionContext(execution,{root,architectureIdentity:identity,architectureEvidence:bindings});
|
|
136
|
+
const permission=assertApprovedExecutionContext(execution,{root,architectureIdentity:identity,architectureEvidence:bindings,readOnly});
|
|
136
137
|
const allowed=permission.allowed_write_paths.map(x=>{if(path.isAbsolute(x)){const rel=path.relative(projectRoot,x).split(path.sep).join('/');return rel==='.'||rel===''?'.':relative(rel);}return x==='.'?'.':relative(x);});
|
|
137
138
|
requireThat(changes.every(ref=>allowed.some(scope=>beneath(ref,scope))&®istration.allowed_write_paths.some(scope=>beneath(ref,scope))),'ARCH_SOURCE_OUT_OF_SCOPE','输出增量超出批准写范围');
|
|
138
139
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { statSync } from 'node:fs';
|
|
2
|
+
import { readFileSync, withValidationPhase, inValidationPhase } from './validation-phase.mjs';
|
|
2
3
|
import { ensure, hash, digest, read, safe, files, schema, treeDigest } from './strategic-handoff-io.mjs';
|
|
3
4
|
|
|
4
5
|
// This is an observation bundle, not a prototype or an approval generator.
|
|
5
|
-
export function validateExistingUiBaseline(data,
|
|
6
|
+
export function validateExistingUiBaseline(data,options={}) {return inValidationPhase()?validate(data,options):withValidationPhase({root:options.bundleRoot,purpose:'existing-ui-baseline',readOnly:true},()=>validate(data,options));}
|
|
7
|
+
function validate(data, { bundleRoot } = {}) {
|
|
6
8
|
const errors=[];
|
|
7
9
|
try {
|
|
8
10
|
schema(data,'docs/process/schemas/existing-ui-baseline.schema.json');
|
|
@@ -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}`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { normalizeSliceContract, sourceSliceContract, parseSliceYaml } from './slice-contract.mjs';
|
|
2
2
|
import { loadDeliveryProfile } from './harness-execution-scope.mjs';
|
|
3
|
-
import { existsSync } from '
|
|
3
|
+
import { existsSync } from './validation-phase.mjs';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { spawnSync } from 'node:child_process';
|
|
6
6
|
import { ROOT, read, safe, ensure, digest } from './strategic-handoff-io.mjs';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { uiBaselineRef, uiBaselineCaseIds, uiBaselineKind, hasConsumerRoutes } from './ui-baseline.mjs';
|
|
2
|
-
import { existsSync, readdirSync, readFileSync } from '
|
|
2
|
+
import { existsSync, readdirSync, readFileSync } from './validation-phase.mjs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { spawnSync } from 'node:child_process';
|
|
5
5
|
import { openBackendDelivery } from './backend-delivery.mjs';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { loadExecutionScope, assertScopeWorkUnit } from './lifecycle-execution-scope.mjs';
|
|
2
|
+
import { existsSync } from './validation-phase.mjs';
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
import { ROOT, read, safe, ensure } from './strategic-handoff-io.mjs';
|
|
4
5
|
|
|
@@ -30,6 +31,12 @@ function activeProfile(root) {
|
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
export function enforceHarnessTaskScope(task,{root=ROOT}={}) {
|
|
34
|
+
const scope=loadExecutionScope(root);
|
|
35
|
+
if(scope) {
|
|
36
|
+
assertScopeWorkUnit(task.contract?.kind==='slice-implementation'?'work-unit.slice-implementation':task.work_unit_id,{root});
|
|
37
|
+
ensure(task.role_id!=='role.frontend-engineer','后端职责不允许派发前端实现');
|
|
38
|
+
ensure(task.allowed_write_paths.every(ref=>!/^apps\/frontend(?:\/|$)/.test(ref)),'禁止写入前端工程');
|
|
39
|
+
}
|
|
33
40
|
const profile=activeProfile(root);
|
|
34
41
|
if (!profile) return;
|
|
35
42
|
ensure(task.contract?.kind!=='template-maintenance','专职产品项目不得派发模板维护任务');
|
|
@@ -41,6 +48,13 @@ export function enforceHarnessTaskScope(task,{root=ROOT}={}) {
|
|
|
41
48
|
}
|
|
42
49
|
|
|
43
50
|
export function enforceHarnessSkillScope(skills,registry,{root=ROOT}={}) {
|
|
51
|
+
if(loadExecutionScope(root)) {
|
|
52
|
+
assertScopeWorkUnit('work-unit.slice-implementation',{root});
|
|
53
|
+
for(const id of skills) {
|
|
54
|
+
const impacts=registry.skills.find(skill=>skill.id===id)?.impacts||[];
|
|
55
|
+
ensure(!impacts.includes('frontend')||impacts.includes('backend')||impacts.includes('lifecycle'),`后端职责禁止编译生产前端技能: ${id}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
44
58
|
const profile=activeProfile(root);
|
|
45
59
|
if (!profile) return;
|
|
46
60
|
const side=profile.profile_id==='harness.frontend-delivery'?'frontend':'backend';
|
|
@@ -5,7 +5,7 @@ import { createApprovedExecutionContext, createApprovedRecompilationContext, ass
|
|
|
5
5
|
import { enforceTechnicalDesign } from './technical-design-boundary.mjs';
|
|
6
6
|
import { enforceHarnessSkillScope } from "./harness-execution-scope.mjs";
|
|
7
7
|
import { createHash } from "node:crypto";
|
|
8
|
-
import { readFileSync } from
|
|
8
|
+
import { readFileSync } from './validation-phase.mjs';
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { parseDocument } from "../vendor/yaml.mjs";
|
|
11
11
|
import { DEFAULT_REGISTRY, loadSkillRegistry, resolveSkillForNewUse } from "./skill-registry.mjs";
|
|
@@ -276,8 +276,8 @@ export function evaluateContractFreshness(contract, { registry, compilerContract
|
|
|
276
276
|
const reasons = [];
|
|
277
277
|
let trustedExecution;
|
|
278
278
|
try {
|
|
279
|
-
trustedExecution=approved_slice?createApprovedExecutionContext(approved_slice,{root,contract:all,work_unit_id}):execution;
|
|
280
|
-
if(trustedExecution)assertApprovedExecutionContext(trustedExecution,{root,contract});
|
|
279
|
+
trustedExecution=approved_slice?createApprovedExecutionContext(approved_slice,{root,contract:all,work_unit_id,readOnly}):execution;
|
|
280
|
+
if(trustedExecution)assertApprovedExecutionContext(trustedExecution,{root,contract,readOnly});
|
|
281
281
|
} catch(error) { reasons.push(error.code||'EXECUTION_APPROVAL_INVALID');trustedExecution=undefined; }
|
|
282
282
|
try { enforceTechnicalDesign({ ...resolution, slice_id: contract.slice_id ?? resolution.slice_id }, { root,execution:trustedExecution,readOnly }); }
|
|
283
283
|
catch { reasons.push("technical-design-stale-or-unavailable"); }
|
|
@@ -289,7 +289,7 @@ export function evaluateContractFreshness(contract, { registry, compilerContract
|
|
|
289
289
|
try { validateArchitectureIdentity(resolution.architecture_identity, registry); }
|
|
290
290
|
catch { reasons.push("architecture-identity-invalid"); }
|
|
291
291
|
if (resolution.architecture_identity.schema_version === 2) {
|
|
292
|
-
try { verifyArchitectureEvidence(resolution.architecture_identity, resolution.architecture_evidence, { root, registry, execution:trustedExecution }); }
|
|
292
|
+
try { verifyArchitectureEvidence(resolution.architecture_identity, resolution.architecture_evidence, { root, registry, execution:trustedExecution, readOnly }); }
|
|
293
293
|
catch (error) { reasons.push(error.code ?? "architecture-evidence-stale-or-unavailable"); }
|
|
294
294
|
}
|
|
295
295
|
if (resolution.architecture_identity_digest !== architectureDigest(resolution.architecture_identity)) reasons.push("architecture-identity-digest-changed");
|