create-yss-spec 3.4.7 → 3.4.8

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.
Files changed (121) hide show
  1. package/package.json +1 -1
  2. package/template/.agents/skills/.strategic-design-skills-manifest.json +1 -1
  3. package/template/.agents/skills/code-review/references/yss-review-standards.md +22 -0
  4. package/template/.agents/skills/lombok/SKILL.md +1 -1
  5. package/template/.agents/skills/mapstruct/SKILL.md +3 -1
  6. package/template/.agents/skills/yss-application/references/application-layer-guide.md +7 -0
  7. package/template/.agents/skills/yss-backend-spec-review/SKILL.md +38 -0
  8. package/template/.agents/skills/yss-backend-spec-review/references/check-inputs.md +21 -0
  9. package/template/.agents/skills/yss-backend-spec-review/references/remediation-workflow.md +48 -0
  10. package/template/.agents/skills/yss-backend-spec-review/tests/routing.test.mjs +19 -0
  11. package/template/.agents/skills/yss-ddd-scaffold-generator/SKILL.md +5 -3
  12. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/java/architecture-rules-test.java.template +60 -23
  13. package/template/.agents/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +6 -0
  14. package/template/.agents/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
  15. package/template/.agents/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +4 -2
  16. package/template/.agents/skills/yss-ddd-scaffold-generator/references/engineering-baseline.md +7 -1
  17. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +6 -10
  18. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +12 -16
  19. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +36 -87
  20. package/template/.agents/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +4 -3
  21. package/template/.agents/skills/yss-domain/references/domain-layer-guide.md +8 -1
  22. package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  23. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/assets/templates/architecture-rules-test.java.template +66 -0
  24. package/template/.agents/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +4 -2
  25. package/template/.agents/skills/yss-mybatis/SKILL.md +4 -0
  26. package/template/.agents/skills/yss-repository/references/profiles/target-domain-model.md +10 -2
  27. package/template/.agents/skills/yss-web-controller/references/web-adapter-layer-guide.md +8 -0
  28. package/template/.codex/skills/code-review/references/yss-review-standards.md +22 -0
  29. package/template/.codex/skills/lombok/SKILL.md +1 -1
  30. package/template/.codex/skills/mapstruct/SKILL.md +3 -1
  31. package/template/.codex/skills/yss-application/references/application-layer-guide.md +7 -0
  32. package/template/.codex/skills/yss-backend-spec-review/SKILL.md +38 -0
  33. package/template/.codex/skills/yss-backend-spec-review/references/check-inputs.md +21 -0
  34. package/template/.codex/skills/yss-backend-spec-review/references/remediation-workflow.md +48 -0
  35. package/template/.codex/skills/yss-backend-spec-review/tests/routing.test.mjs +19 -0
  36. package/template/.codex/skills/yss-ddd-scaffold-generator/SKILL.md +5 -3
  37. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/java/architecture-rules-test.java.template +60 -23
  38. package/template/.codex/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +6 -0
  39. package/template/.codex/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
  40. package/template/.codex/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +4 -2
  41. package/template/.codex/skills/yss-ddd-scaffold-generator/references/engineering-baseline.md +7 -1
  42. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +6 -10
  43. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +12 -16
  44. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +36 -87
  45. package/template/.codex/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +4 -3
  46. package/template/.codex/skills/yss-domain/references/domain-layer-guide.md +8 -1
  47. package/template/.codex/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  48. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/assets/templates/architecture-rules-test.java.template +66 -0
  49. package/template/.codex/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +4 -2
  50. package/template/.codex/skills/yss-mybatis/SKILL.md +4 -0
  51. package/template/.codex/skills/yss-repository/references/profiles/target-domain-model.md +10 -2
  52. package/template/.codex/skills/yss-web-controller/references/web-adapter-layer-guide.md +8 -0
  53. package/template/.cursor/skills/code-review/references/yss-review-standards.md +22 -0
  54. package/template/.cursor/skills/lombok/SKILL.md +1 -1
  55. package/template/.cursor/skills/mapstruct/SKILL.md +3 -1
  56. package/template/.cursor/skills/yss-application/references/application-layer-guide.md +7 -0
  57. package/template/.cursor/skills/yss-backend-spec-review/SKILL.md +38 -0
  58. package/template/.cursor/skills/yss-backend-spec-review/references/check-inputs.md +21 -0
  59. package/template/.cursor/skills/yss-backend-spec-review/references/remediation-workflow.md +48 -0
  60. package/template/.cursor/skills/yss-backend-spec-review/tests/routing.test.mjs +19 -0
  61. package/template/.cursor/skills/yss-ddd-scaffold-generator/SKILL.md +5 -3
  62. package/template/.cursor/skills/yss-ddd-scaffold-generator/assets/templates/java/architecture-rules-test.java.template +60 -23
  63. package/template/.cursor/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +6 -0
  64. package/template/.cursor/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
  65. package/template/.cursor/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +4 -2
  66. package/template/.cursor/skills/yss-ddd-scaffold-generator/references/engineering-baseline.md +7 -1
  67. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +6 -10
  68. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +12 -16
  69. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +36 -87
  70. package/template/.cursor/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +4 -3
  71. package/template/.cursor/skills/yss-domain/references/domain-layer-guide.md +8 -1
  72. package/template/.cursor/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  73. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/assets/templates/architecture-rules-test.java.template +66 -0
  74. package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +4 -2
  75. package/template/.cursor/skills/yss-mybatis/SKILL.md +4 -0
  76. package/template/.cursor/skills/yss-repository/references/profiles/target-domain-model.md +10 -2
  77. package/template/.cursor/skills/yss-web-controller/references/web-adapter-layer-guide.md +8 -0
  78. package/template/.pi/skills/code-review/references/yss-review-standards.md +22 -0
  79. package/template/.pi/skills/lombok/SKILL.md +1 -1
  80. package/template/.pi/skills/mapstruct/SKILL.md +3 -1
  81. package/template/.pi/skills/yss-application/references/application-layer-guide.md +7 -0
  82. package/template/.pi/skills/yss-backend-spec-review/SKILL.md +38 -0
  83. package/template/.pi/skills/yss-backend-spec-review/references/check-inputs.md +21 -0
  84. package/template/.pi/skills/yss-backend-spec-review/references/remediation-workflow.md +48 -0
  85. package/template/.pi/skills/yss-backend-spec-review/tests/routing.test.mjs +19 -0
  86. package/template/.pi/skills/yss-ddd-scaffold-generator/SKILL.md +5 -3
  87. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/java/architecture-rules-test.java.template +60 -23
  88. package/template/.pi/skills/yss-ddd-scaffold-generator/assets/templates/pom/bootstrap-pom.xml.template +6 -0
  89. package/template/.pi/skills/yss-ddd-scaffold-generator/references/ARCHITECTURE.md +1 -1
  90. package/template/.pi/skills/yss-ddd-scaffold-generator/references/USAGE_EXAMPLES.md +4 -2
  91. package/template/.pi/skills/yss-ddd-scaffold-generator/references/engineering-baseline.md +7 -1
  92. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/first-slice-compatibility.test.mjs +6 -10
  93. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/first-slice-verification.test.mjs +12 -16
  94. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/run_first_slice_verification.mjs +36 -87
  95. package/template/.pi/skills/yss-ddd-scaffold-generator/scripts/run_scaffold_verification.mjs +4 -3
  96. package/template/.pi/skills/yss-domain/references/domain-layer-guide.md +8 -1
  97. package/template/.pi/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  98. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/assets/templates/architecture-rules-test.java.template +66 -0
  99. package/template/.pi/skills/yss-layered-mvc-scaffold-generator/scripts/generate_scaffold.mjs +4 -2
  100. package/template/.pi/skills/yss-mybatis/SKILL.md +4 -0
  101. package/template/.pi/skills/yss-repository/references/profiles/target-domain-model.md +10 -2
  102. package/template/.pi/skills/yss-web-controller/references/web-adapter-layer-guide.md +8 -0
  103. package/template/docs/agents/yss-skill-registry.yaml +13 -0
  104. package/template/docs/engineering/backend-platforms.md +14 -0
  105. package/template/docs/process/schemas/digital-human-task-package.schema.json +657 -100
  106. package/template/docs/process/schemas/slice-implementation-contract-v3.schema.json +41 -0
  107. package/template/scripts/lib/backend-platform-provenance.mjs +1 -1
  108. package/template/scripts/lib/backend-platform-verification.mjs +2 -2
  109. package/template/scripts/lib/backend-platform.mjs +62 -0
  110. package/template/scripts/lib/backend-review.mjs +102 -0
  111. package/template/scripts/lib/first-slice-artifacts.mjs +47 -0
  112. package/template/scripts/lib/first-slice-tests.mjs +24 -0
  113. package/template/scripts/lib/lifecycle-transition.mjs +6 -0
  114. package/template/scripts/lib/maintenance-candidate.mjs +160 -0
  115. package/template/scripts/lib/slice-execution-preflight.mjs +43 -0
  116. package/template/scripts/slice-contract +7 -3
  117. package/template/scripts/verify-backend-platform-matrix +8 -2
  118. package/template/skills-lock.json +28 -16
  119. package/template/yss-public-skills.json +4 -2
  120. package/template.manifest.json +0 -1
  121. package/template.snapshot.json +5 -5
@@ -18,6 +18,7 @@
18
18
 
19
19
  | Capability | Primary skill | Task modes |
20
20
  | --- | --- | --- |
21
+ | `governance.backend-spec-conformance` | `yss-backend-spec-review` | `guidance`, `troubleshooting`, `review-input` |
21
22
  | `writing.lifecycle-document` | `i-have-adhd` | `guidance` |
22
23
  | `architecture.technical-design` | `yss-technical-design` | `guidance`, `integration`, `review-input` |
23
24
  | `architecture.mvc-design` | `yss-technical-design` | `guidance`, `integration`, `review-input` |
@@ -57,6 +58,7 @@
57
58
 
58
59
  | Recipe | Capabilities |
59
60
  | --- | --- |
61
+ | `backend.spec-conformance` | `governance.backend-spec-conformance`, `quality.java-code-style` |
60
62
  | `backend.ddd-domain-behavior` | `layer.domain`, `layer.application`, `quality.java-code-style` |
61
63
  | `backend.ddd-persistence-mybatis` | `layer.persistence`, `framework.mybatis`, `codegen.mapstruct`, `codegen.lombok`, `quality.java-code-style` |
62
64
  | `backend.ddd-http-api` | `layer.web-adapter`, `contract.dto-wire`, `contract.request-validation`, `contract.error-mapping`, `codegen.mapstruct`, `codegen.lombok`, `quality.java-code-style` |
@@ -106,6 +108,9 @@
106
108
 
107
109
  | Skill | Dependency | Type | Condition |
108
110
  | --- | --- | --- | --- |
111
+ | `yss-backend-spec-review` | `alibaba-java-code-style` | `context-required` | — |
112
+ | `yss-backend-spec-review` | `yss-implementation-contract-compiler` | `coordination-only` | — |
113
+ | `yss-backend-spec-review` | `code-review` | `review-only` | — |
109
114
  | `prototype-review` | `i-have-adhd` | `context-conditional` | `lifecycle-document-output` |
110
115
  | `yss-implementation-contract-compiler` | `i-have-adhd` | `context-conditional` | `lifecycle-document-output` |
111
116
  | `yss-openapi-governance` | `i-have-adhd` | `context-conditional` | `lifecycle-document-output` |
@@ -0,0 +1,66 @@
1
+ package {{base_package}}.architecture;
2
+
3
+ import com.tngtech.archunit.core.domain.JavaClass;
4
+ import com.tngtech.archunit.core.domain.JavaClasses;
5
+ import com.tngtech.archunit.core.domain.Dependency;
6
+ import com.tngtech.archunit.core.importer.ImportOption;
7
+ import com.tngtech.archunit.junit.AnalyzeClasses;
8
+ import com.tngtech.archunit.junit.ArchTest;
9
+
10
+ /** 空骨架可无业务类型;首切片由批准合同传入职责包和必须加载的实际类型。 */
11
+ @AnalyzeClasses(packages = "{{base_package}}", importOptions = ImportOption.DoNotIncludeTests.class)
12
+ class LayeredMvcArchitectureTest {
13
+ private static boolean inPackage(JavaClass type, String prefixes) {
14
+ for (String prefix : prefixes.split(",")) {
15
+ if (!prefix.isEmpty() && (type.getPackageName().equals(prefix)
16
+ || type.getPackageName().startsWith(prefix + "."))) return true;
17
+ }
18
+ return false;
19
+ }
20
+
21
+ private static boolean role(JavaClass type, String name, String defaults) {
22
+ return inPackage(type, defaults) || inPackage(type, System.getProperty("yss.arch." + name, ""));
23
+ }
24
+
25
+ private static boolean controller(JavaClass type) {
26
+ return type.isAnnotatedWith("org.springframework.web.bind.annotation.RestController")
27
+ || type.isAnnotatedWith("org.springframework.stereotype.Controller")
28
+ || type.isMetaAnnotatedWith("org.springframework.stereotype.Controller");
29
+ }
30
+
31
+ private static void reject(boolean forbidden, Dependency dependency) {
32
+ if (forbidden) throw new AssertionError(dependency.getDescription());
33
+ }
34
+
35
+ @ArchTest
36
+ static void boundaries(JavaClasses classes) {
37
+ for (JavaClass origin : classes) {
38
+ boolean application = role(origin, "application", "{{base_package}}.service,{{base_package}}.core");
39
+ boolean infrastructure = role(origin, "infrastructure", "{{base_package}}.repository");
40
+ for (Dependency dependency : origin.getDirectDependenciesFromSelf()) {
41
+ JavaClass target = dependency.getTargetClass();
42
+ boolean targetWeb = controller(target) || role(target, "web",
43
+ "{{base_package}}.server,{{base_package}}.rest,{{base_package}}.adapter.web");
44
+ boolean targetInfrastructure = role(target, "infrastructure", "{{base_package}}.repository");
45
+ reject(application && targetWeb, dependency);
46
+ reject(infrastructure && (targetWeb || role(target, "application",
47
+ "{{base_package}}.service,{{base_package}}.core")), dependency);
48
+ reject(controller(origin) && targetInfrastructure, dependency);
49
+ }
50
+ }
51
+ if (Boolean.getBoolean("yss.firstSlice")) {
52
+ if (Boolean.getBoolean("yss.arch.requireController")) {
53
+ boolean foundController = false;
54
+ for (JavaClass type : classes) if (controller(type)) foundController = true;
55
+ if (!foundController) throw new AssertionError("Web slice did not load an actual Controller");
56
+ }
57
+ String required = System.getProperty("yss.arch.requiredTypes", "");
58
+ if (required.isEmpty()) throw new AssertionError("first slice requires contract-bound types");
59
+ for (String name : required.split(",")) {
60
+ boolean found = false;
61
+ for (JavaClass type : classes) if (type.getName().equals(name)) found = true;
62
+ if (!found) throw new AssertionError("architecture scope did not load " + name);
63
+ }
64
+ }
65
+ }
66
+ }
@@ -120,7 +120,7 @@ function parentPom(contract, modules, platform) {
120
120
  <properties><java.version>${v.java_version}</java.version><spring-boot.version>${v.boot_version}</spring-boot.version><maven.compiler.source>${v.java_version}</maven.compiler.source><maven.compiler.target>${v.java_version}</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><yss-components.version>${xml(c.yss_components_version)}</yss-components.version></properties>
121
121
  <modules>${modules.map((module) => `<module>${contract.project_name}-${module}</module>`).join("")}</modules>
122
122
  <dependencyManagement><dependencies>${dependency("org.springframework.boot", "spring-boot-dependencies", v.boot_version, "import").replace("</dependency>", "<type>pom</type></dependency>")}${dependency("com.yss.cloud", "yss-components-bom", "${yss-components.version}", "import").replace("</dependency>", "<type>pom</type></dependency>")}</dependencies></dependencyManagement>
123
- <build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-enforcer-plugin</artifactId><version>${v.enforcer_version}</version><executions><execution><id>enforce-platform</id><goals><goal>enforce</goal></goals><configuration><rules><requireJavaVersion><version>${v.java_range}</version></requireJavaVersion><requireMavenVersion><version>[3.6.3,)</version></requireMavenVersion><dependencyConvergence/></rules></configuration></execution></executions></plugin></plugins><pluginManagement><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${v.boot_version}</version><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>${v.surefire_version}</version></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>${v.compiler_version}</version><configuration><source>${v.java_version}</source><target>${v.java_version}</target><parameters>true</parameters><annotationProcessorPaths><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${v.lombok_version}</version></path><path><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${v.mapstruct_version}</version></path><path><groupId>org.projectlombok</groupId><artifactId>lombok-mapstruct-binding</artifactId><version>0.2.0</version></path></annotationProcessorPaths></configuration></plugin></plugins></pluginManagement></build>
123
+ <build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-enforcer-plugin</artifactId><version>${v.enforcer_version}</version><executions><execution><id>enforce-platform</id><goals><goal>enforce</goal></goals><configuration><rules><requireJavaVersion><version>${v.java_range}</version></requireJavaVersion><requireMavenVersion><version>[3.6.3,)</version></requireMavenVersion><dependencyConvergence/></rules></configuration></execution></executions></plugin></plugins><pluginManagement><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${v.boot_version}</version><executions><execution><goals><goal>repackage</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>${v.surefire_version}</version></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>${v.compiler_version}</version><configuration><source>${v.java_version}</source><target>${v.java_version}</target><parameters>true</parameters><annotationProcessorPaths><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${v.lombok_version}</version></path><path><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${v.mapstruct_version}</version></path><path><groupId>org.projectlombok</groupId><artifactId>lombok-mapstruct-binding</artifactId><version>${v.lombok_mapstruct_binding_version}</version></path></annotationProcessorPaths></configuration></plugin></plugins></pluginManagement></build>
124
124
  </project>`;
125
125
  }
126
126
 
@@ -130,6 +130,7 @@ function modulePom(contract, module, modules, platform) {
130
130
  const dependencies = [];
131
131
  if (module === "server") {
132
132
  dependencies.push(own(applicationModule), dependency("org.springframework.boot", platform.web_starter), dependency("org.springframework.boot", "spring-boot-starter-validation"), dependency("org.springframework.boot", "spring-boot-starter-test", null, "test"), dependency("com.tngtech.archunit", "archunit-junit5", platform.versions.archunit, "test"));
133
+ dependencies.push(dependency("org.projectlombok", "lombok", platform.versions.lombok, "test"));
133
134
  if (platform.web_test_starter !== "spring-boot-starter-test") dependencies.push(dependency("org.springframework.boot", platform.web_test_starter, null, "test"));
134
135
  if (modules.includes("client")) dependencies.push(own("client"));
135
136
  dependencies.push(dependency("com.h2database", "h2", null, "test"), dependency("org.mapstruct", "mapstruct", platform.versions.mapstruct), dependency("com.yss.cloud", "yss-component-dto"));
@@ -263,7 +264,8 @@ export async function generate(options, { skillId = SKILL_ID, architectureProfil
263
264
  await put(projectRoot, `${serverRoot}/src/main/resources/application-scaffold-local.yml`, localDatabaseConfiguration(options.projectName));
264
265
  await put(projectRoot, `${serverRoot}/src/test/resources/application-scaffold-test.yml`, localDatabaseConfiguration(`${options.projectName}_test`));
265
266
  await put(projectRoot, `${serverRoot}/src/test/java/${packagePath}/${applicationClass}Test.java`, `package ${options.basePackage};\n\nimport org.junit.jupiter.api.Test;\nimport org.springframework.boot.test.context.SpringBootTest;\nimport org.springframework.test.context.ActiveProfiles;\n\n@SpringBootTest\n@ActiveProfiles("scaffold-test")\nclass ${applicationClass}Test {\n @Test\n void contextLoads() {\n }\n}`);
266
- await put(projectRoot, `${serverRoot}/src/test/java/${packagePath}/architecture/LayeredMvcArchitectureTest.java`, `package ${options.basePackage}.architecture;\n\nimport static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;\n\nimport com.tngtech.archunit.core.importer.ImportOption;\nimport com.tngtech.archunit.junit.AnalyzeClasses;\nimport com.tngtech.archunit.junit.ArchTest;\nimport com.tngtech.archunit.lang.ArchRule;\n\n@AnalyzeClasses(packages = "${options.basePackage}", importOptions = ImportOption.DoNotIncludeTests.class)\nclass LayeredMvcArchitectureTest {\n @ArchTest\n static final ArchRule repositoryDoesNotDependOnUpperLayers = noClasses().that().resideInAPackage("..repository..").should().dependOnClassesThat().resideInAnyPackage("..service..", "..server..");\n}`);
267
+ const architectureTemplate = await readFile(path.join(SKILL_ROOT, "assets/templates/architecture-rules-test.java.template"), "utf8");
268
+ await put(projectRoot, `${serverRoot}/src/test/java/${packagePath}/architecture/LayeredMvcArchitectureTest.java`, architectureTemplate.replaceAll("{{base_package}}", options.basePackage));
267
269
  await put(projectRoot, `${serverRoot}/src/test/java/${packagePath}/PlatformIntegrationTest.java`, platformSmokeTest(options.basePackage, platform, contract.module_profile.requested_capabilities));
268
270
  const wrapper = path.join(REPOSITORY_ROOT, ".agents/skills/yss-ddd-scaffold-generator/assets/wrapper");
269
271
  await cp(wrapper, projectRoot, { recursive: true });
@@ -55,3 +55,7 @@ description: 用于 YSS MyBatis / MyBatis-Plus 组件能力核验、接入决策
55
55
  ## 平台与源码门禁
56
56
 
57
57
  接入、修改、代码生成或给出精确类名/配置前,读取 [后端组件平台与源码门禁](../yss-skill-source-index-refresh/references/backend-component-platform-compatibility.md),从批准的 `platform_configuration.component_platform_line` 选择 `source-index.boot2-java8.md` 或 `source-index.boot3-java17.md`,并以 `--skill yss-mybatis --platform-line <line> --source-root <matching-root>` 运行统一 freshness 校验。平台线与源码根不匹配、组件 tree 不一致、组件子树 dirty、索引缺少平台信号,或 Manifest / 组件 GAV 缺少 verified 兼容证据时返回 `blocked`;不得回退另一代索引,也不在业务实现中升级、降级或替换 YSS 组件。既有工程只读分诊可继续,但不得据此宣称跨 Boot/JDK 兼容。
58
+
59
+ ## 持久化选择记录
60
+
61
+ 在已有数据合同 / persistence_strategy 中记录:实际 Mapper 基类、组件源码与平台绑定、分页唯一责任者、主键与审计填充,以及命中批量时的 SQL 入口、分批大小和方言证据。`BaseMapper` 与组件扩展基类按所需能力选择,不因命名不同判违规;依赖存在和循环 insert 均不证明批量能力。未命中的能力不强制生成。
@@ -4,9 +4,9 @@
4
4
 
5
5
  ## 前置与所有权
6
6
 
7
- - 写模型必须已有批准的 Domain Gateway;读模型必须已有批准的 Application Query Port。缺失或需要改变签名时返回 `new_impacts`,由 `yss-domain` / `yss-application` 和实现合同编译器处理。
7
+ - 写模型必须已有批准的 Domain Gateway;展示读模型必须已有批准的 Application Query Port。缺失或需要改变签名时返回 `new_impacts`,由 `yss-domain` / `yss-application` 和实现合同编译器处理。
8
8
  - Infrastructure 实现既有端口,拥有 PO、Repository/Mapper、XML、持久化 Convertor、GatewayImpl 和 QueryAdapter;不拥有领域规则、HTTP DTO 或业务事务。
9
- - Domain Gateway 只交换 Aggregate、Domain Model、领域值和标识;分页、列表和读模型走 Application Query Port,`PageQuery` 不进入 Domain。
9
+ - Domain Gateway 只交换 Aggregate、Domain Model、领域值和标识;展示分页、列表和读模型走 Application Query Port,`PageQuery` 不进入 Domain。
10
10
 
11
11
  ## 结构决策
12
12
 
@@ -21,3 +21,11 @@
21
21
  - 经 Domain Gateway 保存后可重新加载语义等价的 Aggregate。
22
22
  - Query Port 覆盖分页 total、空结果、排序/过滤白名单和字段转换。
23
23
  - Mapper/Repository 使用批准数据库 fixture;H2 不能证明生产方言。
24
+
25
+ ## 持久化决策与映射
26
+
27
+ - 在既有 persistence_strategy / 数据合同中明确 Mapper 基类及源码依据、主键、逻辑删除、审计填充、并发版本、敏感字段、分页责任和命中时的批量策略。未命中分页或批量时写明理由,不创建空适配器。
28
+ - 多表聚合按同一 Application 事务保存,重载后比较身份、值对象、集合与业务状态;并发写入按批准策略验证冲突或幂等结果。
29
+ - 机械字段使用 Spring MapStruct Bean;聚合重建可通过显式工厂或自定义映射方法。业务状态校验由领域入口拥有,禁止为了映射而开放破坏不变量的 setter。
30
+ - 创建与更新的 null 语义、枚举未知值和审计字段保留必须有测试;转换器不得静默创造业务默认值或吞掉非法持久化状态。
31
+ - 包名与类型后缀来自批准工程基线;Mapper 与 Repository 的命名不能替代职责、运行时发现和行为验证。
@@ -84,3 +84,11 @@ public interface QualityRuleWebConvertor {
84
84
  - Wire forbidden fields 无法绑定。
85
85
  - OpenAPI 3 注解、YSS Result wrapper、Validation namespace 与平台 Profile 一致。
86
86
  - 执行项目根 `./mvnw test/package`,并保留 HTTP/serialization/exception 证据。
87
+
88
+ ## 非 CRUD 适配
89
+
90
+ 认证、OAuth 回调、Cookie、流式响应及协议端点可以手工实现,不强行套 CRUD metadata;仍消费批准的 wire 合同、Application seam 和平台配置。Controller 不直连 Domain Gateway,也不自行编排登录、撤销或持久化。
91
+
92
+ 协议转换、Cookie/Header 处理归 Web;业务决策归 Application/Domain。异常翻译器可以依赖领域错误类型,不能据此允许 Controller 调用领域端口。MapStruct 处理机械字段映射,协议编码及显式领域工厂适配使用有测试的自定义方法。
93
+
94
+ 生成器推荐 rest 布局;已登记的 adapter.web 等布局通过合同绑定识别。审查按模块、实际 Controller 类型和依赖方向进行,包名偏离不能让检查空匹配通过。
@@ -33,6 +33,7 @@ backend_skill_domains:
33
33
  yss-implementation-contract-compiler: platform-governance-migration
34
34
  yss-skill-source-index-refresh: platform-governance-migration
35
35
  yss-up-springboot3: platform-governance-migration
36
+ yss-backend-spec-review: platform-governance-migration
36
37
  deprecated_skills: []
37
38
  backend_source_index_contract:
38
39
  schema_version: 1
@@ -126,6 +127,7 @@ retirement_contract:
126
127
  deprecated: skill-deprecated
127
128
  retired: skill-retired
128
129
  capabilities:
130
+ - { id: governance.backend-spec-conformance, primary_skill: yss-backend-spec-review, provider: { kind: none }, task_modes: [guidance, troubleshooting, review-input] }
129
131
  - { id: writing.lifecycle-document, primary_skill: i-have-adhd, provider: { kind: none }, task_modes: [guidance] }
130
132
  - { id: architecture.technical-design, primary_skill: yss-technical-design, provider: { kind: none }, task_modes: [guidance, integration, review-input] }
131
133
  - { id: architecture.mvc-design, primary_skill: yss-technical-design, provider: { kind: none }, architecture_family: layered-mvc, task_modes: [guidance, integration, review-input] }
@@ -159,6 +161,7 @@ capabilities:
159
161
  - { id: project-init.mvc-data-analysis, primary_skill: yss-layered-mvc-scaffold-generator, provider: { kind: none }, task_modes: [component-maintenance] }
160
162
  - { id: migration.springboot3, primary_skill: yss-up-springboot3, provider: { kind: none }, task_modes: [guidance, integration, troubleshooting, component-maintenance, review-input] }
161
163
  recipes:
164
+ - { id: backend.spec-conformance, capabilities: [governance.backend-spec-conformance, quality.java-code-style] }
162
165
  - { id: backend.ddd-domain-behavior, architecture_family: domain-driven, capabilities: [layer.domain, layer.application, quality.java-code-style] }
163
166
  - { id: backend.ddd-persistence-mybatis, architecture_family: domain-driven, capabilities: [layer.persistence, framework.mybatis, codegen.mapstruct, codegen.lombok, quality.java-code-style] }
164
167
  - { id: backend.ddd-http-api, architecture_family: domain-driven, capabilities: [layer.web-adapter, contract.dto-wire, contract.request-validation, contract.error-mapping, codegen.mapstruct, codegen.lombok, quality.java-code-style] }
@@ -180,6 +183,10 @@ recipes:
180
183
  - { id: frontend.vue3-scaffold, capabilities: [scaffold.frontend-vue3] }
181
184
  - { id: backend.springboot3-migration, capabilities: [migration.springboot3, quality.java-code-style] }
182
185
  skill_dependencies:
186
+ yss-backend-spec-review:
187
+ - { skill: alibaba-java-code-style, type: context-required }
188
+ - { skill: yss-implementation-contract-compiler, type: coordination-only }
189
+ - { skill: code-review, type: review-only }
183
190
  prototype-review:
184
191
  - { skill: i-have-adhd, type: context-conditional, when: lifecycle-document-output }
185
192
  yss-implementation-contract-compiler:
@@ -689,6 +696,12 @@ skills:
689
696
  instance_default_discoverable: false
690
697
  aliases: []
691
698
  impacts: [backend]
699
+ - id: yss-backend-spec-review
700
+ layer: specialist
701
+ maturity: verified
702
+ instance_default_discoverable: false
703
+ aliases: []
704
+ impacts: [backend, quality]
692
705
  - id: yss-userinfo
693
706
  layer: specialist
694
707
  maturity: supported
@@ -101,3 +101,17 @@ Boot 4 使用对应 MVC / MVC 测试 starter、Jackson 3 默认栈与新的模
101
101
  通用运行时依赖仍由真实依赖树和 Boot BOM 核验。YSS 组件能力的精确构件绑定只读取同一兼容条目内的 `component_capabilities`,不得再从 catalog 顶层列表或平行 `components` 目录推断。
102
102
 
103
103
  Jar 核验拒绝未登记或版本不符的额外库;仅允许 Boot 对应版本的 jarmode 工具以及已选配方中的 provided Lombok 随包出现。原因是 [Boot repackage 默认包含 provided 依赖](https://docs.spring.io/spring-boot/maven-plugin/packaging.html);这些打包例外不能补足必须存在于 compile/runtime 树的 Web、Servlet、JSON 等能力。
104
+
105
+
106
+ ## 双平台专项认证
107
+
108
+ 本轮必选范围为 `spring-boot-2.7-jdk8:2.7.18` 与 `spring-boot-3.5-jdk17:3.5.16`,各覆盖
109
+ `domain-driven`、`layered-mvc`。矩阵输入可指定 `required_combinations`,或重复传
110
+ `--require-combination <profile_id>:<spring_boot_version>:<architecture_family>`。不指定时仍执行完整矩阵。
111
+ 未选择的组合记录 `not-executed`,不计为通过,也不影响专项总状态。专项通过不自动修改清单可选性。
112
+
113
+ 每个组合使用合同选择的平台和显式 `java_homes`,本机默认 Java 不决定项目版本。生成的测试夹具覆盖
114
+ HTTP JSON/Validation 错误响应、MapStruct 编译与字段映射、MyBatis 持久化往返/分页、事务失败回滚。
115
+ 夹具在 test scope 使用 H2、标准 MyBatis RowBounds 和 TransactionTemplate;它不证明生产方言、YSS 自动分页切面、业务 Service 代理事务或特定
116
+ 组件能力。对应能力仍须读取所选平台的源码索引、验证实际组件并绑定独立证据。新增用例必须出现在本次
117
+ Surefire XML 中,空测试、跳过或旧报告不可通过。没有凭据、构件、真实批准合同或组件兼容证据时保持阻断。