create-yss-spec 3.1.3 → 3.2.0

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 (206) hide show
  1. package/README.md +5 -1
  2. package/package.json +1 -1
  3. package/template/.agents/skills/.strategic-design-skills-manifest.json +1 -1
  4. package/template/.agents/skills/yss-domain/SKILL.md +3 -3
  5. package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +2 -2
  6. package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  7. package/template/.agents/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +10 -2
  8. package/template/.agents/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +8 -1
  9. package/template/.agents/skills/yss-mvc-design/SKILL.md +16 -0
  10. package/template/.agents/skills/yss-mvc-design/agents/openai.yaml +4 -0
  11. package/template/.agents/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  12. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +2 -2
  13. package/template/.agents/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
  14. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +14 -9
  15. package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +1 -1
  16. package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +1 -1
  17. package/template/.agents/skills/yss-tactical-design/SKILL.md +2 -2
  18. package/template/.agents/skills/yss-tactical-design/references/output-template.md +2 -0
  19. package/template/.agents/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  20. package/template/.agents/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  21. package/template/.agents/skills/yss-technical-design/SKILL.md +31 -0
  22. package/template/.agents/skills/yss-technical-design/agents/openai.yaml +4 -0
  23. package/template/.agents/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  24. package/template/.agents/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  25. package/template/.agents/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  26. package/template/.agents/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  27. package/template/.agents/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  28. package/template/.agents/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  29. package/template/.agents/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  30. package/template/.claude/skills/yss-domain/SKILL.md +3 -3
  31. package/template/.claude/skills/yss-implementation-contract-compiler/SKILL.md +2 -2
  32. package/template/.claude/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  33. package/template/.claude/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +10 -2
  34. package/template/.claude/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +8 -1
  35. package/template/.claude/skills/yss-mvc-design/SKILL.md +16 -0
  36. package/template/.claude/skills/yss-mvc-design/agents/openai.yaml +4 -0
  37. package/template/.claude/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  38. package/template/.claude/skills/yss-product-lifecycle/SKILL.md +2 -2
  39. package/template/.claude/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
  40. package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +14 -9
  41. package/template/.claude/skills/yss-product-lifecycle/references/orchestration.md +1 -1
  42. package/template/.claude/skills/yss-product-lifecycle/references/state-model.md +1 -1
  43. package/template/.claude/skills/yss-tactical-design/SKILL.md +2 -2
  44. package/template/.claude/skills/yss-tactical-design/references/output-template.md +2 -0
  45. package/template/.claude/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  46. package/template/.claude/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  47. package/template/.claude/skills/yss-technical-design/SKILL.md +31 -0
  48. package/template/.claude/skills/yss-technical-design/agents/openai.yaml +4 -0
  49. package/template/.claude/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  50. package/template/.claude/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  51. package/template/.claude/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  52. package/template/.claude/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  53. package/template/.claude/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  54. package/template/.claude/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  55. package/template/.claude/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  56. package/template/.codex/skills/yss-domain/SKILL.md +3 -3
  57. package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +2 -2
  58. package/template/.codex/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  59. package/template/.codex/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +10 -2
  60. package/template/.codex/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +8 -1
  61. package/template/.codex/skills/yss-mvc-design/SKILL.md +16 -0
  62. package/template/.codex/skills/yss-mvc-design/agents/openai.yaml +4 -0
  63. package/template/.codex/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  64. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +2 -2
  65. package/template/.codex/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
  66. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +14 -9
  67. package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +1 -1
  68. package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +1 -1
  69. package/template/.codex/skills/yss-tactical-design/SKILL.md +2 -2
  70. package/template/.codex/skills/yss-tactical-design/references/output-template.md +2 -0
  71. package/template/.codex/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  72. package/template/.codex/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  73. package/template/.codex/skills/yss-technical-design/SKILL.md +31 -0
  74. package/template/.codex/skills/yss-technical-design/agents/openai.yaml +4 -0
  75. package/template/.codex/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  76. package/template/.codex/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  77. package/template/.codex/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  78. package/template/.codex/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  79. package/template/.codex/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  80. package/template/.codex/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  81. package/template/.codex/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  82. package/template/.cursor/skills/yss-domain/SKILL.md +3 -3
  83. package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +2 -2
  84. package/template/.cursor/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  85. package/template/.cursor/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +10 -2
  86. package/template/.cursor/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +8 -1
  87. package/template/.cursor/skills/yss-mvc-design/SKILL.md +16 -0
  88. package/template/.cursor/skills/yss-mvc-design/agents/openai.yaml +4 -0
  89. package/template/.cursor/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  90. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +2 -2
  91. package/template/.cursor/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
  92. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +14 -9
  93. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +1 -1
  94. package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +1 -1
  95. package/template/.cursor/skills/yss-tactical-design/SKILL.md +2 -2
  96. package/template/.cursor/skills/yss-tactical-design/references/output-template.md +2 -0
  97. package/template/.cursor/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  98. package/template/.cursor/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  99. package/template/.cursor/skills/yss-technical-design/SKILL.md +31 -0
  100. package/template/.cursor/skills/yss-technical-design/agents/openai.yaml +4 -0
  101. package/template/.cursor/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  102. package/template/.cursor/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  103. package/template/.cursor/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  104. package/template/.cursor/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  105. package/template/.cursor/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  106. package/template/.cursor/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  107. package/template/.cursor/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  108. package/template/.pi/skills/yss-domain/SKILL.md +3 -3
  109. package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +2 -2
  110. package/template/.pi/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  111. package/template/.pi/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +10 -2
  112. package/template/.pi/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +8 -1
  113. package/template/.pi/skills/yss-mvc-design/SKILL.md +16 -0
  114. package/template/.pi/skills/yss-mvc-design/agents/openai.yaml +4 -0
  115. package/template/.pi/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  116. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +2 -2
  117. package/template/.pi/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
  118. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +14 -9
  119. package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +1 -1
  120. package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +1 -1
  121. package/template/.pi/skills/yss-tactical-design/SKILL.md +2 -2
  122. package/template/.pi/skills/yss-tactical-design/references/output-template.md +2 -0
  123. package/template/.pi/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  124. package/template/.pi/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  125. package/template/.pi/skills/yss-technical-design/SKILL.md +31 -0
  126. package/template/.pi/skills/yss-technical-design/agents/openai.yaml +4 -0
  127. package/template/.pi/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  128. package/template/.pi/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  129. package/template/.pi/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  130. package/template/.pi/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  131. package/template/.pi/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  132. package/template/.pi/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  133. package/template/.pi/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  134. package/template/.qoder/skills/yss-domain/SKILL.md +3 -3
  135. package/template/.qoder/skills/yss-implementation-contract-compiler/SKILL.md +2 -2
  136. package/template/.qoder/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  137. package/template/.qoder/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +10 -2
  138. package/template/.qoder/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +8 -1
  139. package/template/.qoder/skills/yss-mvc-design/SKILL.md +16 -0
  140. package/template/.qoder/skills/yss-mvc-design/agents/openai.yaml +4 -0
  141. package/template/.qoder/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  142. package/template/.qoder/skills/yss-product-lifecycle/SKILL.md +2 -2
  143. package/template/.qoder/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
  144. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +14 -9
  145. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration.md +1 -1
  146. package/template/.qoder/skills/yss-product-lifecycle/references/state-model.md +1 -1
  147. package/template/.qoder/skills/yss-tactical-design/SKILL.md +2 -2
  148. package/template/.qoder/skills/yss-tactical-design/references/output-template.md +2 -0
  149. package/template/.qoder/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  150. package/template/.qoder/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  151. package/template/.qoder/skills/yss-technical-design/SKILL.md +31 -0
  152. package/template/.qoder/skills/yss-technical-design/agents/openai.yaml +4 -0
  153. package/template/.qoder/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  154. package/template/.qoder/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  155. package/template/.qoder/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  156. package/template/.qoder/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  157. package/template/.qoder/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  158. package/template/.qoder/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  159. package/template/.qoder/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  160. package/template/.trae/skills/yss-domain/SKILL.md +3 -3
  161. package/template/.trae/skills/yss-implementation-contract-compiler/SKILL.md +2 -2
  162. package/template/.trae/skills/yss-implementation-contract-compiler/references/boundaries.md +5 -0
  163. package/template/.trae/skills/yss-implementation-contract-compiler/references/compiler-contract.yaml +10 -2
  164. package/template/.trae/skills/yss-implementation-contract-compiler/references/slice-implementation-contract.md +8 -1
  165. package/template/.trae/skills/yss-mvc-design/SKILL.md +16 -0
  166. package/template/.trae/skills/yss-mvc-design/agents/openai.yaml +4 -0
  167. package/template/.trae/skills/yss-mvc-design/references/mvc-design.schema.json +315 -0
  168. package/template/.trae/skills/yss-product-lifecycle/SKILL.md +2 -2
  169. package/template/.trae/skills/yss-product-lifecycle/references/artifact-dependencies.md +2 -2
  170. package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +14 -9
  171. package/template/.trae/skills/yss-product-lifecycle/references/orchestration.md +1 -1
  172. package/template/.trae/skills/yss-product-lifecycle/references/state-model.md +1 -1
  173. package/template/.trae/skills/yss-tactical-design/SKILL.md +2 -2
  174. package/template/.trae/skills/yss-tactical-design/references/output-template.md +2 -0
  175. package/template/.trae/skills/yss-tactical-design/references/tactical-design-contract.md +3 -1
  176. package/template/.trae/skills/yss-tactical-design/scripts/validate-tactical-design.mjs +3 -2
  177. package/template/.trae/skills/yss-technical-design/SKILL.md +31 -0
  178. package/template/.trae/skills/yss-technical-design/agents/openai.yaml +4 -0
  179. package/template/.trae/skills/yss-technical-design/references/technical-design-common.schema.json +290 -0
  180. package/template/.trae/skills/yss-technical-design/references/technical-design-contract.md +31 -0
  181. package/template/.trae/skills/yss-technical-design/references/technical-design.schema.json +759 -0
  182. package/template/.trae/skills/yss-technical-design/scripts/generate-schema.mjs +20 -0
  183. package/template/.trae/skills/yss-technical-design/scripts/validate-technical-design.mjs +134 -0
  184. package/template/.trae/skills/yss-technical-design/tests/fixtures.mjs +32 -0
  185. package/template/.trae/skills/yss-technical-design/tests/run-scenarios.mjs +82 -0
  186. package/template/CONTEXT.md +2 -1
  187. package/template/docs/agents/digital-human-roles.yaml +2 -2
  188. package/template/docs/agents/yss-skill-registry.yaml +20 -1
  189. package/template/docs/architecture/templates/architecture-review-checklist.md +1 -1
  190. package/template/docs/architecture/templates/system-overview-design-template.md +15 -4
  191. package/template/docs/process/lifecycle-artifact-map.md +2 -0
  192. package/template/docs/process/lifecycle-registry-baseline.json +3 -1
  193. package/template/docs/process/lifecycle-registry.yaml +9 -2
  194. package/template/docs/process/schemas/strategic-design-handoff.schema.json +77 -4
  195. package/template/docs/process/strategic-handoff-package.md +4 -2
  196. package/template/docs/process/template-verification-profiles.yaml +14 -0
  197. package/template/docs/user-guide//346/210/230/346/234/257/350/256/276/350/256/241/345/255/220/351/241/271/347/233/256/347/224/250/346/210/267/346/211/213/345/206/214.md +7 -6
  198. package/template/scripts/fixtures/strategic-handoff/fixture.mjs +3 -2
  199. package/template/scripts/lib/implementation-contract-compiler.mjs +8 -1
  200. package/template/scripts/lib/strategic-handoff-consumption.mjs +4 -4
  201. package/template/scripts/lib/strategic-handoff-design-targets.mjs +15 -0
  202. package/template/scripts/lib/technical-design-boundary.mjs +23 -0
  203. package/template/scripts/sync-strategic-handoff-tools +3 -2
  204. package/template/scripts/verify-strategic-handoff-package-scenarios +7 -1
  205. package/template/skills-lock.json +41 -11
  206. package/template.snapshot.json +4 -4
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, writeFileSync } from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ const load = ref => JSON.parse(readFileSync(new URL(ref, import.meta.url), 'utf8'));
5
+ const schema = load('../references/technical-design-common.schema.json');
6
+ const branches = [
7
+ ['domain-driven', '../../yss-tactical-design/references/tactical-design.schema.json'],
8
+ ['layered-mvc', '../../yss-mvc-design/references/mvc-design.schema.json']
9
+ ];
10
+ schema.$comment = 'Generated by scripts/generate-schema.mjs from common and specialist schemas. Do not hand-edit.';
11
+ schema.allOf = branches.map(([family, ref]) => {
12
+ const branch = load(ref); delete branch.$id; delete branch.$schema;
13
+ return { if: { properties: { architecture: { properties: { family: { const: family } } } } }, then: { properties: { design: branch } } };
14
+ });
15
+ const output = fileURLToPath(new URL('../references/technical-design.schema.json', import.meta.url));
16
+ const bytes = `${JSON.stringify(schema, null, 2)}\n`;
17
+ if (process.argv.includes('--check')) {
18
+ if (readFileSync(output, 'utf8') !== bytes) throw new Error('技术设计 Schema 投影漂移,请运行 generate-schema.mjs');
19
+ } else writeFileSync(output, bytes);
20
+ process.stdout.write('技术设计分支 Schema 已同步\n');
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from 'node:fs';
3
+ import path from 'node:path';
4
+ import { fileURLToPath, pathToFileURL } from 'node:url';
5
+ import { parseArgs } from 'node:util';
6
+ import { assertScaffoldUserDecision } from '../../../../scripts/lib/user-decision.mjs';
7
+ import { validateJsonSchema } from '../../../../scripts/lib/json-schema.mjs';
8
+ import { read, safe, hash, digest, ensure } from '../../../../scripts/lib/strategic-handoff-io.mjs';
9
+ import { validate as validateDdd } from '../../yss-tactical-design/scripts/validate-tactical-design.mjs';
10
+ import { designTargets } from '../../../../scripts/lib/strategic-handoff-design-targets.mjs';
11
+ import { verifyConsumption } from '../../../../scripts/lib/strategic-handoff-consumption.mjs';
12
+
13
+ const schema = fileURLToPath(new URL('../references/technical-design.schema.json', import.meta.url));
14
+ const text = x => typeof x === 'string' && x.trim().length > 0;
15
+ const nonempty = xs => Array.isArray(xs) && xs.length > 0 && xs.every(text);
16
+ export const technicalDigest = data => digest(Object.fromEntries(Object.entries(data).filter(([key]) => key !== 'digest')));
17
+
18
+
19
+ function validateMvc(design) {
20
+ const modules = new Map(design.module_catalog.map(item => [item.module_id, item]));
21
+ const cases = new Map(design.use_case_catalog.map(item => [item.use_case_id, item]));
22
+ const rules = new Set(design.rule_catalog.map(item => item.rule_id));
23
+ const permitted = {
24
+ server: ['service','core','client'], service: ['repository','adapter'], core: ['repository','adapter'],
25
+ repository: [], adapter: ['client','feign-client'], client: [], 'feign-client': ['client']
26
+ };
27
+ for (const module of modules.values()) for (const ref of module.depends_on) {
28
+ ensure(modules.has(ref) && permitted[module.layer].includes(modules.get(ref).layer), `模块依赖越界: ${module.module_id} -> ${ref}`);
29
+ }
30
+ for (const item of cases.values()) {
31
+ ensure(['service','core'].includes(modules.get(item.module_ref)?.layer), `用例必须属于 service/core: ${item.use_case_id}`);
32
+ ensure(item.rule_refs.every(ref => rules.has(ref)), `用例引用未声明规则: ${item.use_case_id}`);
33
+ }
34
+ for (const rule of design.rule_catalog) ensure(rule.use_case_refs.every(ref => cases.has(ref) && cases.get(ref).rule_refs.includes(rule.rule_id)), `规则与用例未双向关联: ${rule.rule_id}`);
35
+ for (const item of design.state_transition_catalog) ensure(cases.has(item.use_case_ref), '状态转换引用未声明用例');
36
+ if (!design.state_transition_catalog.length) ensure(text(design.state_not_applicable_reason), '无状态转换必须说明原因');
37
+ for (const item of design.persistence_mapping) ensure(cases.has(item.use_case_ref) && modules.get(item.repository_ref)?.layer === 'repository', '持久化映射的用例或 Repository 引用无效');
38
+ for (const item of design.integration_catalog) ensure(modules.get(item.adapter_ref)?.layer === 'adapter', '外部集成必须关联 Adapter');
39
+ if (!design.integration_catalog.length) ensure(text(design.integration_not_applicable_reason), '无外部集成必须说明原因');
40
+ }
41
+
42
+ export function verifyArchitecture(data, root) {
43
+ const binding = data.architecture;
44
+ const file = safe(root, binding.decision_ref);
45
+ ensure(hash(readFileSync(file)) === binding.decision_digest, '架构来源摘要漂移');
46
+ const record = read(file);
47
+ if (binding.source_kind === 'scaffold-decision') {
48
+ const decision = record.decisions?.find(item => item.project_id === binding.project_id);
49
+ ensure(record.status === 'current' && record.template === false, '架构选择记录必须为当前正式记录');
50
+ ensure(decision && ['user-confirmed','lifecycle-approved','consumed'].includes(decision.status), '分支设计前必须确认项目架构');
51
+ ensure(decision.confirmed_architecture === binding.family, '技术设计与确认架构不匹配');
52
+ ensure(text(decision.user_confirmation?.confirmation_ref) && text(decision.user_confirmation?.confirmed_by), '缺少真实架构确认引用');
53
+ assertScaffoldUserDecision(decision, { root });
54
+ } else {
55
+ // Registration formats differ by repository; bind the actual registered identity,
56
+ // never infer architecture from a directory or a design's self-declaration.
57
+ const entry = record.repositories?.find(item => item.project_id === binding.project_id) ?? record;
58
+ ensure(entry.project_id === binding.project_id && entry.architecture_identity?.architecture_family === binding.family, '技术设计与既有工程登记架构不匹配');
59
+ ensure(!['stale','blocked'].includes(record.status) && !['stale','blocked'].includes(entry.status), '工程登记已失效');
60
+ }
61
+ }
62
+
63
+ function validateLocalTraceability(data, root, sliceRef) {
64
+ const { ids, seams } = designTargets(data);
65
+ const sources = new Map(data.source_items.map(item => [item.source_id, item]));
66
+ ensure(sources.size === data.source_items.length, '源规则或场景 ID 重复');
67
+ const rows = new Map(data.traceability.map(item => [item.source_id, item]));
68
+ ensure(rows.size === data.traceability.length, '承接记录重复');
69
+ ensure(data.strategic_handoff || sources.size > 0, '无战略包时必须列出需求规则与场景');
70
+ for (const source of sources.values()) ensure(data.inputs.some(item => item.ref === source.source_ref), '源规则或场景未绑定当前输入');
71
+ for (const id of rows.keys()) ensure(sources.has(id), `未知承接来源: ${id}`);
72
+ for (const [id, source] of sources) {
73
+ const row = rows.get(id);
74
+ ensure(row, `缺少规则或场景承接: ${id}`);
75
+ if (row.disposition === 'implemented') {
76
+ ensure(nonempty(row.tactical_refs) && row.tactical_refs.every(ref => ids.has(ref)), `设计落点悬空: ${id}`);
77
+ ensure(nonempty(row.test_seam_refs) && row.test_seam_refs.every(ref => seams.has(ref) && row.tactical_refs.includes(seams.get(ref).subject_ref)), `测试 seam 未关联设计落点: ${id}`);
78
+ if (source.kind === 'scenario' && source.critical) ensure(['success','failure'].every(outcome => row.scenario_tests?.some(test => test.outcome === outcome && row.test_seam_refs.includes(test.seam_ref))), `关键场景缺少成功/失败测试: ${id}`);
79
+ ensure(nonempty(row.evidence_refs), `缺少承接证据: ${id}`);
80
+ } else if (row.disposition === 'not-applicable') {
81
+ ensure(text(row.reason) && nonempty(row.evidence_refs), `不适用缺少依据: ${id}`);
82
+ } else {
83
+ if (row.disposition === 'deferred') for (const key of ['reason','risk','owner','followup_ticket_ref','verification_plan','target_version']) ensure(text(row[key]), `延期缺少 ${key}: ${id}`);
84
+ ensure(sliceRef && row.dependency_status === 'known' && nonempty(row.dependent_slice_refs) && !row.dependent_slice_refs.includes(sliceRef), `未闭合承接阻断当前范围: ${id}`);
85
+ }
86
+ for (const ref of row.evidence_refs || []) safe(root, ref);
87
+ }
88
+ }
89
+
90
+ export async function validateTechnicalDesign(data, { root = process.cwd(), sliceRef, legacyDdd = false } = {}) {
91
+ if (data?.schema_version === 1) {
92
+ ensure(legacyDdd, '旧 v1 合同需要显式 --legacy-ddd,仅按 DDD 兼容读取');
93
+ const errors = validateDdd(data);
94
+ ensure(!errors.length, errors.join('; '));
95
+ if (sliceRef) ensure(data.status === 'approved', '切片只能消费 approved 设计');
96
+ if (data.strategic_handoff || data.strategic_context_import_ref || data.upstream_impact?.source_kind === 'strategic-handoff') {
97
+ const result = await verifyConsumption(data, { root, sliceRef });
98
+ ensure(result.result === 'verified', JSON.stringify(result));
99
+ }
100
+ return { result: 'legacy-ddd-read-only', architecture_family: 'domain-driven', status: data.status };
101
+ }
102
+ validateJsonSchema(data, schema, { label: '技术设计合同' });
103
+ ensure(data.digest === technicalDigest(data), '技术设计合同摘要不匹配');
104
+ ensure(!['stale','blocked','drift','new_impacts'].includes(data.status), '设计状态不可消费');
105
+ if (sliceRef) ensure(data.status === 'approved', '切片只能消费 approved 设计');
106
+ verifyArchitecture(data, root);
107
+ ensure(data.inputs.some(item => item.kind === 'context' && item.ref === 'CONTEXT.md') && data.inputs.some(item => item.kind === 'spec'), '共同输入缺少根 CONTEXT.md 或 Spec');
108
+ for (const input of data.inputs) ensure(hash(readFileSync(safe(root, input.ref))) === input.digest, `输入摘要漂移: ${input.ref}`);
109
+ for (const ref of data.evidence_refs) safe(root, ref);
110
+ if (data.status === 'approved') ensure(data.evidence_refs.length > 0, '已批准设计缺少评审证据');
111
+ if (data.architecture.family === 'domain-driven') {
112
+ const errors = validateDdd(data.design);
113
+ ensure(!errors.length, errors.join('; '));
114
+ ensure(data.design.status === data.status, 'DDD 分支状态与共同合同不一致');
115
+ ensure(data.inputs.some(item => item.kind === 'strategic'), 'DDD 分支缺少战略领域输入');
116
+ ensure(!data.design.strategic_handoff && !data.design.strategic_context_import_ref, '战略绑定只允许在共同合同中维护');
117
+ } else validateMvc(data.design);
118
+ const { ids, seams } = designTargets(data);
119
+ for (const seam of seams.values()) ensure(ids.has(seam.subject_ref), `测试 seam 设计对象悬空: ${seam.seam_id}`);
120
+ validateLocalTraceability(data, root, sliceRef);
121
+ if (data.strategic_handoff) {
122
+ const result = await verifyConsumption(data, { root, sliceRef });
123
+ ensure(result.result === 'verified', JSON.stringify(result));
124
+ }
125
+ return { result: 'ready-for-lifecycle-review', technical_design_id: data.technical_design_id, architecture_family: data.architecture.family, status: data.status, digest: data.digest };
126
+ }
127
+
128
+ async function main() {
129
+ const { values, positionals } = parseArgs({ allowPositionals: true, options: { root: { type: 'string', default: process.cwd() }, slice: { type: 'string' }, 'legacy-ddd': { type: 'boolean', default: false } } });
130
+ ensure(positionals.length === 1, '用法: validate-technical-design.mjs <合同> --root <项目根> [--slice <ID>] [--legacy-ddd]');
131
+ const result = await validateTechnicalDesign(read(path.resolve(positionals[0])), { root: values.root, sliceRef: values.slice, legacyDdd: values['legacy-ddd'] });
132
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
133
+ }
134
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) main().catch(error => { process.stderr.write(`${JSON.stringify({ result: 'blocked', errors: [error.message] })}\n`); process.exitCode = 1; });
@@ -0,0 +1,32 @@
1
+ import { writeFileSync, readFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { hash } from '../../../../scripts/lib/strategic-handoff-io.mjs';
4
+ import { technicalDigest } from '../scripts/validate-technical-design.mjs';
5
+ export function mvcFixture(root) {
6
+ const files = {
7
+ 'CONTEXT.md': '# 业务上下文\n',
8
+ 'spec.md': '# 需求\nrule.valid: 必填材料完整。scenario.submit: 提交成功或校验失败。\n',
9
+ 'registration.json': JSON.stringify({ project_id: 'example', status: 'current', architecture_identity: { architecture_family: 'layered-mvc' } }),
10
+ 'review.md': '设计评审测试证据;不构成真实批准。\n'
11
+ };
12
+ for (const [ref, bytes] of Object.entries(files)) writeFileSync(path.join(root, ref), bytes);
13
+ const data = {
14
+ schema_version: 2, technical_design_id: 'technical-design.example', version: 'v1', status: 'ready-for-human', context_ref: 'CONTEXT.md',
15
+ architecture: { family: 'layered-mvc', project_id: 'example', source_kind: 'existing-registration', decision_ref: 'registration.json', decision_digest: hash(readFileSync(path.join(root, 'registration.json'))) },
16
+ inputs: ['CONTEXT.md','spec.md'].map((ref,index) => ({ kind: index ? 'spec' : 'context', ref, version: 'v1', digest: hash(readFileSync(path.join(root,ref))) })),
17
+ source_items: [{ source_id: 'rule.valid', kind: 'rule', critical: false, source_ref: 'spec.md' }, { source_id: 'scenario.submit', kind: 'scenario', critical: true, source_ref: 'spec.md' }],
18
+ traceability: ['rule.valid','scenario.submit'].map(source_id => ({ source_id, disposition: 'implemented', tactical_refs: ['use-case.submit'], test_seam_refs: ['test-seam.success','test-seam.failure'], evidence_refs: ['spec.md'], dependency_status: 'known', dependent_slice_refs: ['slice.submit'], scenario_tests: [{ outcome: 'success', seam_ref: 'test-seam.success' }, { outcome: 'failure', seam_ref: 'test-seam.failure' }] })),
19
+ design: {
20
+ module_catalog: [{ module_id: 'module.server', layer: 'server', responsibility: 'HTTP 适配', depends_on: ['module.service'] }, { module_id: 'module.service', layer: 'service', responsibility: '提交用例和事务', depends_on: ['module.repository'] }, { module_id: 'module.repository', layer: 'repository', responsibility: '数据持久化', depends_on: [] }],
21
+ use_case_catalog: [{ use_case_id: 'use-case.submit', module_ref: 'module.service', flow: ['校验材料','保存申请'], rule_refs: ['rule.valid'], failure_handling: '材料不完整拒绝提交,写入失败回滚' }],
22
+ rule_catalog: [{ rule_id: 'rule.valid', statement: '材料必须完整', use_case_refs: ['use-case.submit'] }],
23
+ state_transition_catalog: [], state_not_applicable_reason: '本范围只登记申请,无状态流转',
24
+ consistency_policy: { transaction_boundary: '一次提交同一事务', rollback: '写入失败整体回滚', concurrency: '唯一约束拒绝竞争提交', idempotency: '请求键唯一' },
25
+ persistence_mapping: [{ mapping_id: 'mapping.application', use_case_ref: 'use-case.submit', repository_ref: 'module.repository', storage_model: 'application', notes: '请求键唯一' }],
26
+ integration_catalog: [], integration_not_applicable_reason: '无外部集成',
27
+ test_seams: [{ seam_id: 'test-seam.success', kind: 'service', subject_ref: 'use-case.submit', assertion: '完整材料保存成功' }, { seam_id: 'test-seam.failure', kind: 'service', subject_ref: 'use-case.submit', assertion: '缺材料时不写入' }]
28
+ }, evidence_refs: ['review.md']
29
+ };
30
+ data.digest = technicalDigest(data);
31
+ return data;
32
+ }
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+ import assert from 'node:assert/strict';
3
+ import { mkdtempSync, readFileSync, writeFileSync, rmSync } from 'node:fs';
4
+ import { tmpdir } from 'node:os';
5
+ import path from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ import { attachScaffoldDecisionFixture } from '../../../../scripts/fixtures/user-decision/build-fixture.mjs';
8
+ import { mvcFixture } from './fixtures.mjs';
9
+ import { technicalDigest, validateTechnicalDesign } from '../scripts/validate-technical-design.mjs';
10
+ import { hash, read } from '../../../../scripts/lib/strategic-handoff-io.mjs';
11
+ import { enforceTechnicalDesign } from '../../../../scripts/lib/technical-design-boundary.mjs';
12
+ import { compileDefaultImplementationContract, evaluateContractFreshness, loadCompilerContract } from '../../../../scripts/lib/implementation-contract-compiler.mjs';
13
+ import { loadSkillRegistry } from '../../../../scripts/lib/skill-registry.mjs';
14
+ const root = mkdtempSync(path.join(tmpdir(), 'yss-technical-design-'));
15
+ let checks = 0;
16
+ try {
17
+ const mvc = mvcFixture(root);
18
+ const validate = data => validateTechnicalDesign(data, { root });
19
+ assert.equal((await validate(mvc)).architecture_family, 'layered-mvc'); checks++;
20
+ async function rejected(change, pattern) {
21
+ const data = structuredClone(mvc); change(data); data.digest = technicalDigest(data);
22
+ await assert.rejects(() => validate(data), pattern); checks++;
23
+ }
24
+ await rejected(d => { d.architecture.family = 'mixed'; }, /not one of/);
25
+ await rejected(d => { d.architecture.project_id = 'wrong'; }, /登记架构不匹配/);
26
+ await rejected(d => { d.architecture.decision_digest = `sha256:${'0'.repeat(64)}`; }, /来源摘要漂移/);
27
+ await rejected(d => { d.traceability.pop(); }, /缺少规则或场景承接/);
28
+ await rejected(d => { d.traceability[1].scenario_tests.pop(); }, /成功\/失败测试/);
29
+ await rejected(d => { d.traceability[0].tactical_refs = ['aggregate.fake']; }, /设计落点悬空/);
30
+ await rejected(d => { d.design.module_catalog[0].depends_on = ['module.repository']; }, /模块依赖越界/);
31
+ await rejected(d => { d.design.consistency_policy.transaction_boundary = ''; }, /non-empty/);
32
+ await rejected(d => { d.design.aggregate_catalog = []; }, /Additional properties/);
33
+ await rejected(d => { d.design.test_seams[0].subject_ref = 'missing'; }, /设计对象悬空/);
34
+ await rejected(d => { d.status = 'stale'; }, /状态不可消费/);
35
+ await rejected(d => { d.traceability[0].disposition = 'conflict'; }, /未闭合承接/);
36
+ const deferred = structuredClone(mvc); deferred.status = 'approved';
37
+ Object.assign(deferred.traceability[0], { disposition: 'deferred', reason: '下一版', risk: '提交不可用', owner: '维护者', followup_ticket_ref: 'ticket.next', verification_plan: '回归提交', target_version: 'v2' });
38
+ deferred.digest = technicalDigest(deferred);
39
+ await assert.rejects(() => validateTechnicalDesign(deferred, { root, sliceRef: 'slice.submit' }), /未闭合承接/); checks++;
40
+ assert.equal((await validateTechnicalDesign(deferred, { root, sliceRef: 'slice.other' })).architecture_family, 'layered-mvc'); checks++;
41
+ deferred.traceability[0].dependency_status = 'unknown'; deferred.digest = technicalDigest(deferred);
42
+ await assert.rejects(() => validateTechnicalDesign(deferred, { root, sliceRef: 'slice.other' }), /未闭合承接/); checks++;
43
+ writeFileSync(path.join(root, 'spec.md'), 'changed');
44
+ await assert.rejects(() => validate(mvc), /输入摘要漂移/); checks++;
45
+ mvcFixture(root);
46
+ const old = read(fileURLToPath(new URL('../../yss-tactical-design/tests/fixtures/valid-tactical-design.yaml', import.meta.url)));
47
+ await assert.rejects(() => validate(old), /显式 --legacy-ddd/); checks++;
48
+ assert.equal((await validateTechnicalDesign(old, { root, legacyDdd: true })).result, 'legacy-ddd-read-only'); checks++;
49
+ const ddd = structuredClone(mvc); ddd.architecture.family = 'domain-driven';
50
+ writeFileSync(path.join(root, 'registration.json'), JSON.stringify({ project_id: 'example', status: 'current', architecture_identity: { architecture_family: 'domain-driven' } }));
51
+ ddd.architecture.decision_digest = hash(readFileSync(path.join(root, 'registration.json'))); ddd.design = old;
52
+ ddd.inputs.push({ kind: 'strategic', ref: 'spec.md', version: 'v1', digest: hash(readFileSync(path.join(root, 'spec.md'))) });
53
+ for (const row of ddd.traceability) Object.assign(row, { tactical_refs: [old.test_seams[0].subject_ref], test_seam_refs: [old.test_seams[0].seam_id], scenario_tests: ['success','failure'].map(outcome => ({ outcome, seam_ref: old.test_seams[0].seam_id })) });
54
+ ddd.digest = technicalDigest(ddd);
55
+ assert.equal((await validate(ddd)).architecture_family, 'domain-driven'); checks++;
56
+ ddd.design.aggregate_catalog[0].api_exposure = 'public'; ddd.digest = technicalDigest(ddd);
57
+ await assert.rejects(() => validate(ddd), /internal-only/); checks++;
58
+ const scaffold = mvcFixture(root);
59
+ const decision = attachScaffoldDecisionFixture(path.join(root, 'decision-evidence'), { project_id: 'example', status: 'user-confirmed', confirmed_architecture: 'layered-mvc', decision_inputs_digest: `sha256:${'1'.repeat(64)}`, user_confirmation: { confirmation_ref: 'user-message', confirmed_by: 'user' } });
60
+ const record = { status: 'current', template: false, decisions: [decision] };
61
+ const recordFile = path.join(root, 'decision.json');
62
+ writeFileSync(recordFile, JSON.stringify(record));
63
+ scaffold.architecture = { ...scaffold.architecture, source_kind: 'scaffold-decision', decision_ref: 'decision.json', decision_digest: hash(readFileSync(recordFile)) }; scaffold.digest = technicalDigest(scaffold);
64
+ assert.equal((await validate(scaffold)).architecture_family, 'layered-mvc'); checks++;
65
+ record.decisions[0].status = 'awaiting-user-decision'; writeFileSync(recordFile, JSON.stringify(record)); scaffold.architecture.decision_digest = hash(readFileSync(recordFile)); scaffold.digest = technicalDigest(scaffold);
66
+ await assert.rejects(() => validate(scaffold), /分支设计前必须确认/); checks++;
67
+ record.decisions[0].status = 'user-confirmed'; record.decisions[0].user_confirmation.user_decision_ref = 'missing-user-decision.json'; writeFileSync(recordFile, JSON.stringify(record)); scaffold.architecture.decision_digest = hash(readFileSync(recordFile)); scaffold.digest = technicalDigest(scaffold);
68
+ await assert.rejects(() => validate(scaffold), /user-decision/); checks++;
69
+ const current = mvcFixture(root); current.status = 'approved'; current.digest = technicalDigest(current);
70
+ const file = path.join(root, 'design.json'); writeFileSync(file, JSON.stringify(current));
71
+ const technical_design = { ref: 'design.json', version: 'v1', digest: hash(readFileSync(file)) };
72
+ const identity = { architecture_family: 'layered-mvc', architecture_profile: 'layered-mvc-service', generator_skill: 'yss-layered-mvc-scaffold-generator', requested_capabilities: [], resolved_modules: ['server','service','repository'], verification_database: 'h2', production_database: 'not-bound', contract_digest: 'a'.repeat(64) };
73
+ const state = { technical_design, slice_id: 'slice.submit', architecture_identity: identity, conditions: ['backend-technical-design-impact'] };
74
+ enforceTechnicalDesign(state, { root }); checks++;
75
+ assert.throws(() => enforceTechnicalDesign({ ...state, technical_design: undefined }, { root }), /缺少已批准技术设计/); checks++;
76
+ assert.throws(() => enforceTechnicalDesign({ ...state, architecture_identity: { architecture_family: 'domain-driven' } }, { root }), /架构不匹配/); checks++;
77
+ const resolution = compileDefaultImplementationContract({ ...state, root, requiredCapabilities: ['contract.request-validation'], architecture_evidence: { engineering_baseline: identity, repository_registration: identity, manifest: identity } });
78
+ assert.deepEqual(resolution.technical_design, technical_design); assert(!resolution.required_skills.includes('yss-domain')); checks++;
79
+ writeFileSync(path.join(root, 'spec.md'), 'changed again');
80
+ assert.equal(evaluateContractFreshness({ schema_version: 2, resolution }, { registry: loadSkillRegistry(), compilerContract: loadCompilerContract(), root }).freshness, 'stale'); checks++;
81
+ } finally { rmSync(root, { recursive: true, force: true }); }
82
+ process.stdout.write(`技术设计场景通过:${checks} 项(MVC、DDD、兼容、架构、承接、切片与漂移)\n`);
@@ -72,7 +72,8 @@ context_schema_version: 1
72
72
  | 战略交接快照包 | 将批准的战略资产及证据冻结为可离线验证的完整目录或 ZIP,并提供规则和场景的派生索引。 | — | 源规则由战略方维护;包内快照与索引不成为目标仓词汇权威。 |
73
73
  | 后端交付包 | 将后端当前切片的战略基线、冻结接口、批准合同及构建、部署和验证证据绑定为可独立接收的交付快照。 | — | 验包通过不代表真实服务当前可用,也不代表前端已获准实现。 |
74
74
  | 前端联合接收 | 前端对战略交接快照与后端交付包进行版本、词汇、场景、接口和运行条件核验的过程。 | — | 输入就绪允许准备实现计划和合同;写代码仍需批准且当前的 Slice Implementation Contract。 |
75
- | 战术承接记录 | 将源规则和关键场景关联到战术落点、测试 seam、处置结论及依赖切片的结构化记录。 | — | 延期登记不等于依赖切片可实现;冲突回交战略方,未知依赖扩大阻断。 |
75
+ | 技术设计合同 | 按已确认架构统一记录共同输入、规则与场景承接、对应设计及审查证据的合同。 | — | 技术设计由通用入口组织,领域建模与传统分层是可选分支,生命周期负责批准。 |
76
+ | 战术承接记录 | 将源规则和关键场景关联到所选架构的设计落点、测试 seam、处置结论及依赖切片的结构化记录。 | — | 延期登记不等于依赖切片可实现;冲突回交战略方,未知依赖扩大阻断。 |
76
77
  | 流程模板资产 | 可被不同项目复用的文档模板、技能说明、校验脚本、流程规范和目录占位文件。 | — | 不包含某个具体产品的 Spec、设计、OpenAPI 或 Ticket。 |
77
78
  | 模板维护流程 | 用于评估影响、修改权威资产、同步投影、执行压力验证并审查模板演进的工作流。 | — | 面向模板源仓库,不默认生成具体产品的 Spec、原型、OpenAPI 或垂直切片 Ticket。 |
78
79
  | 模板发布门禁 | 模板源发布前必须通过的结构、技能同步、流程语义和压力场景验证集合。 | — | 不等同于只检查文件存在、Markdown 链接或 YAML 语法。 |
@@ -152,8 +152,8 @@ roles:
152
152
  contract_version: 1
153
153
  title: YSS 后端工程师
154
154
  stages: [stage.system-data-engineering, stage.ticket-formalization, stage.vertical-slice-implementation, stage.verification-release-retrospective]
155
- draft_artifact_ids: [artifact.openapi-draft, artifact.data-architecture]
156
- core_skills: [yss-implementation-contract-compiler, yss-tactical-design, yss-domain, yss-application, yss-repository, yss-mybatis, yss-web-controller, yss-dto, mapstruct, lombok, alibaba-java-code-style, yss-exception, yss-validation, tdd, yss-ddd-scaffold-generator, yss-layered-mvc-scaffold-generator]
155
+ draft_artifact_ids: [artifact.openapi-draft, artifact.data-architecture, artifact.technical-design]
156
+ core_skills: [yss-implementation-contract-compiler, yss-technical-design, yss-tactical-design, yss-mvc-design, yss-domain, yss-application, yss-repository, yss-mybatis, yss-web-controller, yss-dto, mapstruct, lombok, alibaba-java-code-style, yss-exception, yss-validation, tdd, yss-ddd-scaffold-generator, yss-layered-mvc-scaffold-generator]
157
157
  forbidden_skills: [yss-ui, yss-ui-business-page-generation, yss-formily, yss-frontend-scaffold-generator, yss-antd-design, yss-antdv-next-design, page-list-module, page-form-module]
158
158
  description: >-
159
159
  Own OpenAPI Draft, data-architecture contributions, and backend tests.
@@ -57,12 +57,14 @@ capability_contract:
57
57
  preserve_all_reasons: true
58
58
  deterministic_order: [recipe-declaration, dependency-topology, skill-id]
59
59
  capabilities:
60
+ - { id: architecture.technical-design, primary_skill: yss-technical-design, task_modes: [guidance, integration, review-input] }
61
+ - { id: architecture.mvc-design, primary_skill: yss-mvc-design, architecture_family: layered-mvc, task_modes: [guidance, integration, review-input] }
60
62
  - { id: layer.mvc-service, primary_skill: yss-application, architecture_family: layered-mvc, task_modes: [guidance, integration, slice-implementation, troubleshooting, review-input] }
61
63
  - { id: layer.mvc-persistence, primary_skill: yss-repository, architecture_family: layered-mvc, task_modes: [guidance, integration, slice-implementation, troubleshooting, review-input] }
62
64
  - { id: layer.mvc-web, primary_skill: yss-web-controller, architecture_family: layered-mvc, task_modes: [guidance, integration, slice-implementation, troubleshooting, review-input] }
63
65
  - { id: governance.implementation-contract, primary_skill: yss-implementation-contract-compiler, task_modes: [contract-compilation, reroute, result-validation] }
64
66
  - { id: maintenance.skill-source-index, primary_skill: yss-skill-source-index-refresh, task_modes: [component-maintenance, source-index-refresh] }
65
- - { id: architecture.tactical-domain, primary_skill: yss-tactical-design, task_modes: [guidance, integration, slice-implementation, review-input] }
67
+ - { id: architecture.tactical-domain, primary_skill: yss-tactical-design, architecture_family: domain-driven, task_modes: [guidance, integration, slice-implementation, review-input] }
66
68
  - { id: layer.domain, primary_skill: yss-domain, task_modes: [guidance, integration, slice-implementation, troubleshooting, review-input] }
67
69
  - { id: layer.application, primary_skill: yss-application, task_modes: [guidance, integration, slice-implementation, troubleshooting, review-input] }
68
70
  - { id: layer.persistence, primary_skill: yss-repository, task_modes: [guidance, integration, slice-implementation, troubleshooting, review-input] }
@@ -121,6 +123,11 @@ skill_dependencies:
121
123
  - { skill: domain-modeling, type: coordination-only }
122
124
  - { skill: yss-tactical-design, type: context-conditional, when: tactical-domain }
123
125
  - { skill: lombok, type: context-conditional, when: pojo }
126
+ yss-technical-design:
127
+ - { skill: yss-tactical-design, type: coordination-only, when: domain-driven }
128
+ - { skill: yss-mvc-design, type: coordination-only, when: layered-mvc }
129
+ yss-mvc-design:
130
+ - { skill: yss-openapi-draft-review, type: review-only, when: api-impact }
124
131
  yss-tactical-design:
125
132
  - { skill: domain-modeling, type: coordination-only }
126
133
  - { skill: yss-openapi-draft-review, type: review-only, when: api-impact }
@@ -479,6 +486,18 @@ skills:
479
486
  instance_default_discoverable: false
480
487
  aliases: []
481
488
  impacts: [backend]
489
+ - id: yss-technical-design
490
+ layer: core
491
+ maturity: draft
492
+ instance_default_discoverable: true
493
+ aliases: []
494
+ impacts: [backend, lifecycle]
495
+ - id: yss-mvc-design
496
+ layer: specialist
497
+ maturity: draft
498
+ instance_default_discoverable: false
499
+ aliases: []
500
+ impacts: [backend, lifecycle]
482
501
  - id: yss-tactical-design
483
502
  layer: specialist
484
503
  maturity: draft
@@ -19,7 +19,7 @@
19
19
 
20
20
  - [ ] 若为小改动,已完成 DDD impact check,并确认不影响统一语言、上下文边界、聚合、API、数据或风险 / 回滚约束。
21
21
  - [ ] Strategic DDD Check 已完成或明确不适用:统一语言、核心/支撑/通用子域、限界上下文、上下文映射和非目标范围清楚。
22
- - [ ] Tactical DDD Check 已完成或明确不适用:聚合根、Entity、Value Object、领域服务、不变量、一致性边界和 Repository / Gateway seam 清楚。
22
+ - [ ] 技术设计使用已确认的 DDD / MVC 架构,规则与关键场景承接完整,合同及输入摘要当前。DDD 审查聚合、不变量、一致性和 Gateway;MVC 审查分层、用例、业务规则、事务和持久化映射。两者均需成功/失败测试 seam;无相关影响须明确理由。
23
23
  - [ ] OpenAPI 契约使用上下文的公开语言,不直接暴露内部聚合、Repository 或持久化表结构。
24
24
  - [ ] 领域行为测试、Application 用例测试、契约测试和必要 E2E 已与 DDD 边界对齐。
25
25
 
@@ -64,10 +64,21 @@ owner: ai
64
64
  |----------|-------------|-------------|-------------|------------------|
65
65
  | | | | | 是 / 否 |
66
66
 
67
- ## 8. Tactical DDD Check(轻量)
67
+ ## 8. 技术设计(按已确认架构)
68
68
 
69
- > 本节嵌入系统概要设计 / 数据架构,不新增独立阶段。只有当聚合边界、状态机、一致性或持久化映射复杂到无法在本节说明时,才升级为 `docs/.scratch/<feature>/architecture/<feature>-tactical-design.md`。
70
- > 战术设计优先引用结构化 `tactical-design` contract(含 `version`、`digest` 和 `evidence.tactical-design-review`);独立文档只承载复杂场景的展开,不成为第二套事实源。
69
+ 引用 `artifact.technical-design` 的版本、digest 和 `evidence.technical-design-review`。`yss-technical-design` 先核对逐项目架构决定;新项目与脚手架共用确认来源,既有项目沿用登记。仅填写适用分支,未命中技术设计影响时记录原因。
70
+
71
+ ### 8.1 传统 MVC
72
+
73
+ | 模块 / 层 | 用例与业务规则 | 状态转换 | 事务 / 并发 / 幂等 | 持久化 / 外部适配 | 测试 seam |
74
+ |---|---|---|---|---|---|
75
+ | | | | | | |
76
+
77
+ 检查规则和关键场景逐条承接、成功/失败测试、分层依赖及事务回滚。MVC 不填写聚合、值对象或 DDD Gateway;详细规则消费 `yss-mvc-design`。
78
+
79
+ ### 8.2 DDD Tactical Check
80
+
81
+ 以下仅用于 domain-driven,由 `yss-tactical-design` 细化。复杂场景可附独立说明,结构化技术设计合同仍是事实源;旧 `artifact.tactical-design` 只读兼容。
71
82
 
72
83
  | 限界上下文 | 聚合根 | 业务不变量 | Entity / Value Object | 一致性边界 | Gateway / Repository | 主要测试 seam |
73
84
  |------------|--------|------------|-----------------------|------------|----------------------|----------------|
@@ -121,7 +132,7 @@ owner: ai
121
132
  - [ ] API 影响记录 / 契约草案 / OpenAPI Draft 的路径、schema、错误结构、分页和契约测试已被架构反审,且可落地或已列出回改项。
122
133
  - [ ] 状态流、失败路径、幂等、并发和回滚策略清楚。
123
134
  - [ ] 数据架构需求已明确;涉及持久化、元模型、版本或血缘时已有数据架构。
124
- - [ ] Tactical DDD Check 已完成,或明确说明本次变更不影响领域模型 / 聚合 / 持久化边界。
135
+ - [ ] 技术设计合同的适用 DDD / MVC 分支已完成、架构确认与承接证据当前;无相关影响有明确理由。
125
136
  - [ ] 已明确的认证、授权、租户隔离、敏感数据或合规行为已写入普通架构约束、契约与验证 seam;未触发时不额外登记。
126
137
  - [ ] 风险与人工审查点已标记。
127
138
  - [ ] 需要 ADR 的决策已列出。
@@ -66,6 +66,7 @@
66
66
  | `artifact.data-architecture` | 数据架构 | `stage.system-data-engineering` | 数据模型、存储或一致性变化。 |
67
67
  | `artifact.engineering-baseline` | 工程基线记录 | `stage.system-data-engineering` | 后端、前端或高风险工程变化。 |
68
68
  | `artifact.architecture-review` | 架构审查记录 | `stage.system-data-engineering` | 高风险或跨边界变化。 |
69
+ | `artifact.technical-design` | 技术设计合同 | `stage.system-data-engineering` | 后端技术设计需要按已确认 DDD 或 MVC 架构明确行为、分层、一致性或数据映射。 |
69
70
  | `artifact.tactical-design` | DDD 战术设计 | `stage.system-data-engineering` | 聚合边界、状态机、一致性或持久化映射复杂到无法在系统概要设计的 Tactical DDD Check 中清楚表达。 |
70
71
  | `artifact.spec-delta` | Spec Delta | `stage.spec-architecture` | 已有冻结 Spec 的高风险行为变化。 |
71
72
  | `artifact.parent-ticket` | 功能父 Ticket | `stage.ticket-formalization` | 每个进入追踪的功能。 |
@@ -82,6 +83,7 @@
82
83
  | `evidence.context-reconciliation` | Context Reconciliation 证据 | 工作单元在批准或流转前对根目录唯一 CONTEXT.md 的稳定术语回写、作用域解析和双摘要核对结果;不新增门禁。 |
83
84
  | `evidence.impact-assessment` | 影响面分析记录 | 受影响仓库、资产、风险与最近可信阶段。 |
84
85
  | `evidence.domain-strategy-review` | 业务边界与规则评审证据 | 业务板块、业务责任区、统一业务词汇、协作与交接关系、关键场景和不可违反规则的结构化评审结果。 |
86
+ | `evidence.technical-design-review` | 技术设计评审证据 | 按已确认 DDD 或 MVC 架构审查规则与场景承接、分层、行为、一致性和测试边界。 |
85
87
  | `evidence.tactical-design-review` | DDD 战术设计评审证据 | 聚合、Entity、Value Object、不变量、状态机、一致性、Gateway 与 API 隔离的结构化评审结果。 |
86
88
  | `evidence.stage-decision-package` | 阶段决策包验证证据 | 阶段决策包的 Schema、引用、语义一致性、影响传播和下游消费验证结果。 |
87
89
  | `evidence.maintenance-intensity-checkpoint` | 模板维护强度 checkpoint | template-source 变更的 L1 / L2 / L3 分级、触发项、最低验证证据、review 模式和升级记录。 |
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema_version": 1,
3
3
  "registry_id": "yss.lifecycle",
4
- "semantic_sha256": "7757565261e3290046cd31d6b4287fc1e5ec8bdf7fae4735b0be8ac882e87b8d",
4
+ "semantic_sha256": "4eadc734957c5112dad60ec9fe4d844ac8790cbe798fbd8177ee60eae6dbe1fa",
5
5
  "published_ids": [
6
6
  "artifact.architecture-review",
7
7
  "artifact.data-architecture",
@@ -29,6 +29,7 @@
29
29
  "artifact.stage-decision-package",
30
30
  "artifact.state-matrix",
31
31
  "artifact.tactical-design",
32
+ "artifact.technical-design",
32
33
  "artifact.vertical-slice-ticket",
33
34
  "evidence.antd-cli-validation",
34
35
  "evidence.approval-record",
@@ -50,6 +51,7 @@
50
51
  "evidence.repository-identity-check",
51
52
  "evidence.stage-decision-package",
52
53
  "evidence.tactical-design-review",
54
+ "evidence.technical-design-review",
53
55
  "evidence.yss-skill-execution-result",
54
56
  "gate.architecture-reviewed",
55
57
  "gate.design-reviewed",
@@ -56,6 +56,9 @@ evidence:
56
56
  description: 子域、限界上下文、统一语言、Context Map、场景和不变量的结构化评审结果。
57
57
  public_name: 业务边界与规则评审证据
58
58
  public_description: 业务板块、业务责任区、统一业务词汇、协作与交接关系、关键场景和不可违反规则的结构化评审结果。
59
+ - id: evidence.technical-design-review
60
+ name: 技术设计评审证据
61
+ description: 按已确认 DDD 或 MVC 架构审查规则与场景承接、分层、行为、一致性和测试边界。
59
62
  - id: evidence.tactical-design-review
60
63
  name: DDD 战术设计评审证据
61
64
  description: 聚合、Entity、Value Object、不变量、状态机、一致性、Gateway 与 API 隔离的结构化评审结果。
@@ -278,6 +281,10 @@ artifacts:
278
281
  name: 架构审查记录
279
282
  stage: stage.system-data-engineering
280
283
  trigger: 高风险或跨边界变化。
284
+ - id: artifact.technical-design
285
+ name: 技术设计合同
286
+ stage: stage.system-data-engineering
287
+ trigger: 后端技术设计需要按已确认 DDD 或 MVC 架构明确行为、分层、一致性或数据映射。
281
288
  - id: artifact.tactical-design
282
289
  name: DDD 战术设计
283
290
  stage: stage.system-data-engineering
@@ -406,8 +413,8 @@ work_units:
406
413
  name: 技术分析与契约冻结
407
414
  scope: project-instance
408
415
  input: Spec、原型、API/数据/工程影响面。
409
- output: OpenAPI、数据架构、Tactical DDD Check、工程基线、架构审查和 Slice 合同草案。
410
- completion: 命中契约已冻结;无 API 影响有可读记录;命中领域影响时战术模型无未解释冲突;工程基线通过。
416
+ output: OpenAPI、数据架构、按确认架构形成的 DDD / MVC 技术设计合同、工程基线、架构审查和 Slice 合同草案。
417
+ completion: 命中契约已冻结;无 API 影响有可读记录;命中技术设计影响时架构已确认、规则与场景承接无未解释冲突;工程基线通过。
411
418
  - id: work-unit.service-project-initialization
412
419
  name: 独立服务项目初始化
413
420
  scope: project-instance
@@ -117,7 +117,10 @@
117
117
  "const": "docs/process/schemas/context-reconciliation.schema.json"
118
118
  },
119
119
  "required_before_skill": {
120
- "const": "yss-tactical-design"
120
+ "enum": [
121
+ "yss-technical-design",
122
+ "yss-tactical-design"
123
+ ]
121
124
  },
122
125
  "status": {
123
126
  "const": "pending"
@@ -137,10 +140,16 @@
137
140
  "const": "downstream-rd-team"
138
141
  },
139
142
  "skill": {
140
- "const": "yss-tactical-design"
143
+ "enum": [
144
+ "yss-technical-design",
145
+ "yss-tactical-design"
146
+ ]
141
147
  },
142
148
  "output": {
143
- "const": "tactical-design-contract"
149
+ "enum": [
150
+ "technical-design-contract",
151
+ "tactical-design-contract"
152
+ ]
144
153
  }
145
154
  }
146
155
  },
@@ -666,5 +675,69 @@
666
675
  }
667
676
  }
668
677
  }
669
- }
678
+ },
679
+ "allOf": [
680
+ {
681
+ "if": {
682
+ "properties": {
683
+ "target": {
684
+ "properties": {
685
+ "skill": {
686
+ "const": "yss-technical-design"
687
+ }
688
+ }
689
+ }
690
+ }
691
+ },
692
+ "then": {
693
+ "properties": {
694
+ "target": {
695
+ "properties": {
696
+ "output": {
697
+ "const": "technical-design-contract"
698
+ }
699
+ }
700
+ },
701
+ "target_context_reconciliation": {
702
+ "properties": {
703
+ "required_before_skill": {
704
+ "const": "yss-technical-design"
705
+ }
706
+ }
707
+ }
708
+ }
709
+ }
710
+ },
711
+ {
712
+ "if": {
713
+ "properties": {
714
+ "target": {
715
+ "properties": {
716
+ "skill": {
717
+ "const": "yss-tactical-design"
718
+ }
719
+ }
720
+ }
721
+ }
722
+ },
723
+ "then": {
724
+ "properties": {
725
+ "target": {
726
+ "properties": {
727
+ "output": {
728
+ "const": "tactical-design-contract"
729
+ }
730
+ }
731
+ },
732
+ "target_context_reconciliation": {
733
+ "properties": {
734
+ "required_before_skill": {
735
+ "const": "yss-tactical-design"
736
+ }
737
+ }
738
+ }
739
+ }
740
+ }
741
+ }
742
+ ]
670
743
  }
@@ -31,7 +31,7 @@ scripts/strategic-handoff import --bundle <目录或ZIP> --target-root <研发
31
31
 
32
32
  导入落盘到 `docs/handoffs/<handoff-id>/<version>/`,包含不可变 `package/`、`import-receipt.json`、`context-reconciliation-draft.json`、`tactical-traceability-draft.json`、`upstream-change-impact.json`。仅写快照与草案,不自动更新根词汇表或批准状态。目标侧确认增量后更新唯一根 `CONTEXT.md`,生成既有 schema 的正式 reconciliation 并校验。
33
33
 
34
- 战术合同的 `strategic_handoff` 绑定 `import_receipt_ref`、`bundle_digest`、`context_reconciliation_ref` 和 `rows`。逐条覆盖全部规则与 `critical: true` 的成功/失败场景;行字段如下:
34
+ Technical Design Contract v2(DDD / MVC 共用)的 `strategic_handoff` 绑定 `import_receipt_ref`、`bundle_digest`、`context_reconciliation_ref` 和 `rows`。逐条覆盖全部规则与 `critical: true` 的成功/失败场景;行字段如下:
35
35
 
36
36
  - `source_id`、源对象 `source_digest`、`disposition`、`dependency_status: known | unknown`、`dependent_slice_refs`。
37
37
  - `implemented`:`tactical_refs`、`test_seam_refs`、`evidence_refs` 必须可解析;关键场景另用 `scenario_tests` 分别绑定 `outcome: success | failure` 与 `seam_ref`。
@@ -42,9 +42,11 @@ scripts/strategic-handoff import --bundle <目录或ZIP> --target-root <研发
42
42
  ```bash
43
43
  scripts/verify-strategic-handoff-consumption --root <研发项目根> <战术合同>
44
44
  scripts/verify-strategic-handoff-consumption --root <研发项目根> --slice <切片ID> <已批准战术合同>
45
- node .agents/skills/yss-tactical-design/scripts/validate-tactical-design.mjs <战术合同> --root <研发项目根>
45
+ node .agents/skills/yss-technical-design/scripts/validate-technical-design.mjs <技术设计合同> --root <研发项目根>
46
46
  ```
47
47
 
48
+ 新交接的 target 使用 `yss-technical-design` / `technical-design-contract`,对账必须在通用入口前完成;旧 `yss-tactical-design` / `tactical-design-contract` 成对只读兼容,不修改已冻结包。`tactical_refs` 在 v2 可指向 `design` 中的 MVC 模块、用例、规则或 DDD 对象,测试 seam 同样在对应分支解析。无战略交接包的 MVC 项目直接消费批准需求,不要求补造战略 DDD。
49
+
48
50
  整体验证有未落实项时返回 blocked;按切片验证可放行有证据证明不依赖这些项的切片。输出 `block_all`、`blocked_slice_refs`、`issues`、实际消费包摘要与战术摘要。通过只证明结构化映射完整和引用可核验,业务语义仍需独立评审;不能代替 Slice Contract 批准。
49
51
 
50
52
  每版完整快照可独立消费,差异区分 added / updated / removed。更新须提升交接版本,内容变化的源资产也须提升其版本。接收新版本后,消费校验比较最新已导入源对象摘要;规则变化按行依赖阻断,未映射的新规则扩大阻断,战略责任边界、方案决策、Spec/视觉/原型源码等变化未重新绑定时整体阻断。`upstream-change-impact.json` 是生命周期处理 stale 的证据输入,不直接改 Tracker 或覆盖战术合同。