create-yss-spec 2.2.7 → 2.2.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 (130) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/template/.agents/skills/maintaining-skills/SKILL.md +1 -1
  4. package/template/.agents/skills/yss-antd-design/references/evidence.md +4 -0
  5. package/template/.agents/skills/yss-design-system/SKILL.md +3 -1
  6. package/template/.agents/skills/yss-page-module-development/SKILL.md +1 -1
  7. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +1 -1
  8. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +4 -0
  9. package/template/.agents/skills/yss-prototype-stage/SKILL.md +11 -6
  10. package/template/.agents/skills/yss-prototype-stage/references/product-design-adapter.md +54 -0
  11. package/template/.agents/skills/yss-prototype-stage/scripts/prototype-contract.mjs +207 -0
  12. package/template/.agents/skills/yss-prototype-stage/tests/run-scenarios.mjs +154 -0
  13. package/template/.agents/skills/yss-router/references/boundaries.md +1 -1
  14. package/template/.agents/skills/yss-ui/references/antdv-compatibility.md +1 -1
  15. package/template/.claude/skills/maintaining-skills/SKILL.md +1 -1
  16. package/template/.claude/skills/yss-antd-design/references/evidence.md +4 -0
  17. package/template/.claude/skills/yss-design-system/SKILL.md +3 -1
  18. package/template/.claude/skills/yss-page-module-development/SKILL.md +1 -1
  19. package/template/.claude/skills/yss-product-lifecycle/SKILL.md +1 -1
  20. package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +4 -0
  21. package/template/.claude/skills/yss-prototype-stage/SKILL.md +11 -6
  22. package/template/.claude/skills/yss-prototype-stage/references/product-design-adapter.md +54 -0
  23. package/template/.claude/skills/yss-prototype-stage/scripts/prototype-contract.mjs +207 -0
  24. package/template/.claude/skills/yss-prototype-stage/tests/run-scenarios.mjs +154 -0
  25. package/template/.claude/skills/yss-router/references/boundaries.md +1 -1
  26. package/template/.claude/skills/yss-ui/references/antdv-compatibility.md +1 -1
  27. package/template/.codex/skills/maintaining-skills/SKILL.md +1 -1
  28. package/template/.codex/skills/yss-antd-design/references/evidence.md +4 -0
  29. package/template/.codex/skills/yss-design-system/SKILL.md +3 -1
  30. package/template/.codex/skills/yss-page-module-development/SKILL.md +1 -1
  31. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +1 -1
  32. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +4 -0
  33. package/template/.codex/skills/yss-prototype-stage/SKILL.md +11 -6
  34. package/template/.codex/skills/yss-prototype-stage/references/product-design-adapter.md +54 -0
  35. package/template/.codex/skills/yss-prototype-stage/scripts/prototype-contract.mjs +207 -0
  36. package/template/.codex/skills/yss-prototype-stage/tests/run-scenarios.mjs +154 -0
  37. package/template/.codex/skills/yss-router/references/boundaries.md +1 -1
  38. package/template/.codex/skills/yss-ui/references/antdv-compatibility.md +1 -1
  39. package/template/.cursor/skills/maintaining-skills/SKILL.md +1 -1
  40. package/template/.cursor/skills/yss-antd-design/references/evidence.md +4 -0
  41. package/template/.cursor/skills/yss-design-system/SKILL.md +3 -1
  42. package/template/.cursor/skills/yss-page-module-development/SKILL.md +1 -1
  43. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +1 -1
  44. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +4 -0
  45. package/template/.cursor/skills/yss-prototype-stage/SKILL.md +11 -6
  46. package/template/.cursor/skills/yss-prototype-stage/references/product-design-adapter.md +54 -0
  47. package/template/.cursor/skills/yss-prototype-stage/scripts/prototype-contract.mjs +207 -0
  48. package/template/.cursor/skills/yss-prototype-stage/tests/run-scenarios.mjs +154 -0
  49. package/template/.cursor/skills/yss-router/references/boundaries.md +1 -1
  50. package/template/.cursor/skills/yss-ui/references/antdv-compatibility.md +1 -1
  51. package/template/.hermes/skills/maintaining-skills/SKILL.md +1 -1
  52. package/template/.hermes/skills/yss-antd-design/references/evidence.md +4 -0
  53. package/template/.hermes/skills/yss-design-system/SKILL.md +3 -1
  54. package/template/.hermes/skills/yss-page-module-development/SKILL.md +1 -1
  55. package/template/.hermes/skills/yss-product-lifecycle/SKILL.md +1 -1
  56. package/template/.hermes/skills/yss-product-lifecycle/references/orchestration-contract.yaml +4 -0
  57. package/template/.hermes/skills/yss-prototype-stage/SKILL.md +11 -6
  58. package/template/.hermes/skills/yss-prototype-stage/references/product-design-adapter.md +54 -0
  59. package/template/.hermes/skills/yss-prototype-stage/scripts/prototype-contract.mjs +207 -0
  60. package/template/.hermes/skills/yss-prototype-stage/tests/run-scenarios.mjs +154 -0
  61. package/template/.hermes/skills/yss-router/references/boundaries.md +1 -1
  62. package/template/.hermes/skills/yss-ui/references/antdv-compatibility.md +1 -1
  63. package/template/.pi/skills/maintaining-skills/SKILL.md +1 -1
  64. package/template/.pi/skills/yss-antd-design/references/evidence.md +4 -0
  65. package/template/.pi/skills/yss-design-system/SKILL.md +3 -1
  66. package/template/.pi/skills/yss-page-module-development/SKILL.md +1 -1
  67. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +1 -1
  68. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +4 -0
  69. package/template/.pi/skills/yss-prototype-stage/SKILL.md +11 -6
  70. package/template/.pi/skills/yss-prototype-stage/references/product-design-adapter.md +54 -0
  71. package/template/.pi/skills/yss-prototype-stage/scripts/prototype-contract.mjs +207 -0
  72. package/template/.pi/skills/yss-prototype-stage/tests/run-scenarios.mjs +154 -0
  73. package/template/.pi/skills/yss-router/references/boundaries.md +1 -1
  74. package/template/.pi/skills/yss-ui/references/antdv-compatibility.md +1 -1
  75. package/template/.qoder/skills/maintaining-skills/SKILL.md +1 -1
  76. package/template/.qoder/skills/yss-antd-design/references/evidence.md +4 -0
  77. package/template/.qoder/skills/yss-design-system/SKILL.md +3 -1
  78. package/template/.qoder/skills/yss-page-module-development/SKILL.md +1 -1
  79. package/template/.qoder/skills/yss-product-lifecycle/SKILL.md +1 -1
  80. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +4 -0
  81. package/template/.qoder/skills/yss-prototype-stage/SKILL.md +11 -6
  82. package/template/.qoder/skills/yss-prototype-stage/references/product-design-adapter.md +54 -0
  83. package/template/.qoder/skills/yss-prototype-stage/scripts/prototype-contract.mjs +207 -0
  84. package/template/.qoder/skills/yss-prototype-stage/tests/run-scenarios.mjs +154 -0
  85. package/template/.qoder/skills/yss-router/references/boundaries.md +1 -1
  86. package/template/.qoder/skills/yss-ui/references/antdv-compatibility.md +1 -1
  87. package/template/.trae/skills/maintaining-skills/SKILL.md +1 -1
  88. package/template/.trae/skills/yss-antd-design/references/evidence.md +4 -0
  89. package/template/.trae/skills/yss-design-system/SKILL.md +3 -1
  90. package/template/.trae/skills/yss-page-module-development/SKILL.md +1 -1
  91. package/template/.trae/skills/yss-product-lifecycle/SKILL.md +1 -1
  92. package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +4 -0
  93. package/template/.trae/skills/yss-prototype-stage/SKILL.md +11 -6
  94. package/template/.trae/skills/yss-prototype-stage/references/product-design-adapter.md +54 -0
  95. package/template/.trae/skills/yss-prototype-stage/scripts/prototype-contract.mjs +207 -0
  96. package/template/.trae/skills/yss-prototype-stage/tests/run-scenarios.mjs +154 -0
  97. package/template/.trae/skills/yss-router/references/boundaries.md +1 -1
  98. package/template/.trae/skills/yss-ui/references/antdv-compatibility.md +1 -1
  99. package/template/AGENTS.md +4 -4
  100. package/template/README.md +10 -11
  101. package/template/__yss_dotfile__.gitignore +1 -0
  102. package/template/docs/agents/skills-maintenance.md +2 -2
  103. package/template/docs/api/templates/openapi-draft-review-checklist.md +2 -2
  104. package/template/docs/design/README.md +2 -2
  105. package/template/docs/design/design.md +48 -9
  106. package/template/docs/design/templates/interaction-spec-template.md +2 -2
  107. package/template/docs/design/templates/prototype-confirmation-template.md +1 -1
  108. package/template/docs/design/templates/prototype-evidence-template.yaml +52 -10
  109. package/template/docs/process/harness-process-tailoring.md +5 -5
  110. package/template/docs/process/template-engineering-overview.md +2 -2
  111. package/template/docs/process/template-verification-profiles.yaml +8 -1
  112. package/template/docs/process/templates/maintenance-checkpoint-template.yaml +3 -12
  113. package/template/docs/templates/requirement-freeze-template.md +1 -1
  114. package/template/docs/user-guide//347/224/250/346/210/267/346/211/213/345/206/214.md +961 -0
  115. package/template/scripts/lib/maintenance-intensity.mjs +24 -10
  116. package/template/scripts/lib/skill-governance.mjs +19 -0
  117. package/template/scripts/node-verify-lifecycle-registry.mjs +1 -1
  118. package/template/scripts/verify-template-verification-scenarios +5 -0
  119. package/template/scripts/verify-yss-prototype-contract-scenarios +2 -0
  120. package/template/skills-lock.json +8 -8
  121. package/template.snapshot.json +4 -4
  122. package/template/docs/user-guide/templates//347/224/250/346/210/267/346/211/213/345/206/214/346/250/241/346/235/277.md +0 -53
  123. package/template/docs/user-guide//344/272/247/345/223/201/347/224/237/345/221/275/345/221/250/346/234/237/345/267/245/344/275/234/346/265/201.md +0 -223
  124. package/template/docs/user-guide//344/272/247/345/223/201/347/240/224/345/217/221/345/205/250/347/224/237/345/221/275/345/221/250/346/234/237/346/234/200/344/275/263/345/256/236/350/267/265.md +0 -1115
  125. package/template/docs/user-guide//345/244/226/351/203/250/345/221/275/344/273/244/350/241/214/345/267/245/345/205/267/345/256/236/350/267/265/346/214/207/345/215/227.md +0 -117
  126. package/template/docs/user-guide//347/224/237/345/221/275/345/221/250/346/234/237/346/234/200/344/275/263/345/256/236/350/267/265.md +0 -584
  127. package/template/docs/user-guide//347/224/250/346/210/267/346/211/213/345/206/214/347/264/242/345/274/225.md +0 -31
  128. package/template/docs/user-guide//350/247/204/346/240/274/344/270/216/344/273/273/345/212/241/350/277/201/347/247/273/346/214/207/345/215/227.md +0 -44
  129. package/template/docs/user-guide//351/234/200/346/261/202/346/276/204/346/270/205/346/214/207/345/215/227.md +0 -230
  130. package/template/docs/user-guide//351/234/200/346/261/202/346/276/204/346/270/205/346/234/200/344/275/263/345/256/236/350/267/265.md +0 -275
@@ -0,0 +1,54 @@
1
+ # YSS Product Design Adapter
2
+
3
+ 本合同把 Codex Product Design 的通用 React/Vite 产出接入 YSS 原型阶段。它不修改上游 Product Design skill,也不把 React API 带入 Vue 生产实现。
4
+
5
+ ## 双轨版本
6
+
7
+ - `design_standard: ant-design-v6`:高保真原型的主题、视觉语义、标准组件和 CLI 事实。
8
+ - `runtime_component_library: ant-design-vue-4.x`:生产 Vue/YSS 组件 API;精确版本只从实现仓 lockfile 读取。
9
+ - 标准原型组件存在 Ant Design 实现时,React 原型必须精确锁定与 CLI 查询一致的 `antd@6.x`。YSS 专有布局可用适配 CSS,但仍消费项目 Token。
10
+ - 禁止把 React hook、props、JSX、静态 API 或事件模型作为 Vue/YSS 实现合同。
11
+
12
+ ## 产出前适配
13
+
14
+ 1. 目标目录固定为 `docs/.scratch/<feature>/design/prototypes/`。
15
+ 2. Product Design 完成 `get-context`、三方案 `ideate` 和用户视觉选择后,进入 `image-to-code` 的 local preflight,只执行官方 bootstrap 创建空 starter;在安装依赖或编写 UI 前立即运行 adapter:
16
+
17
+ ```bash
18
+ node .agents/skills/yss-prototype-stage/scripts/prototype-contract.mjs prepare \
19
+ --project-root <project-root> \
20
+ --root <project-root>/docs/.scratch/<feature>/design/prototypes \
21
+ --feature <feature> \
22
+ --target-antd-version <exact-6.x-version> \
23
+ --pnpm-version <actual-pnpm-version>
24
+ ```
25
+
26
+ 3. adapter 只做机械动作:精确写入 `antd` 版本、登记 pnpm、生成 `src/yss-theme.js` 和 `yss-prototype-adapter.json`。随后由 Product Design 将入口包在 `ConfigProvider theme={yssTheme}` 中,并优先使用标准 `antd` 组件。
27
+ 4. 执行 `pnpm install`、`pnpm build`,保留 `pnpm-lock.yaml`、源码入口、构建入口、实际命令与退出码。禁止用 npm lockfile 代替受控例外记录。
28
+ 5. 校验项目:
29
+
30
+ ```bash
31
+ node .agents/skills/yss-prototype-stage/scripts/prototype-contract.mjs validate-project \
32
+ --root <project-root>/docs/.scratch/<feature>/design/prototypes \
33
+ --target-antd-version <exact-6.x-version>
34
+ ```
35
+
36
+ ## 视觉与实现映射
37
+
38
+ 每个关键组件在 `visual_semantic_mapping` 中记录四层映射:Ant Design v6 semantic role、项目 Token、React 原型组件、生产 YSS/Ant Design Vue 目标。映射的是视觉角色、状态和验收行为,不是 React API 表面形状。
39
+
40
+ 至少覆盖主操作、表单输入、表格/列表、反馈、弹层和导航中本功能实际出现的类型。每项记录 `default/hover/active/disabled/loading/error` 等适用状态,并把 `react_only_api_not_copied` 设为 `true` 后才能通过。
41
+
42
+ ## 视口、QA 与无障碍
43
+
44
+ - 默认视觉目标和同状态 QA 使用 desktop `1440x900`、mobile `390x844`;按影响追加 tablet/laptop/wide,不机械要求九个视口。
45
+ - Design QA 报告固定到 `docs/.scratch/<feature>/verification/design-qa.md`,不得写仓库根共享文件。
46
+ - 项目品牌 Seed `#3371ff` 保持不变;普通文本、按钮及状态组合不满足 WCAG 2.2 AA 时,通过组件 Token 调整实际填充或文字色,并保存对比度证据。
47
+ - 验证至少包含键盘、焦点、语义标签/Dialog、200% zoom、reduced motion、目标尺寸和自动化扫描;工具不可用时记录人工替代与未覆盖缺口,不得空填 passed。
48
+
49
+ ## 交互档位
50
+
51
+ - `reviewable-flow`(默认):合同内主路径和关键状态可操作;非范围控件禁用或明确标注,不伪装完整功能。
52
+ - `full-prototype`:brief 明确要求的全部可见范围控件可操作。
53
+
54
+ 不得使用含义冲突的 `static` / `mostly-static` 作为 YSS 交付状态。
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync } from "node:fs";
3
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import process from "node:process";
6
+ import { fileURLToPath, pathToFileURL } from "node:url";
7
+ import { parseDocument } from "../../../../scripts/vendor/yaml.mjs";
8
+
9
+ const nonEmpty = (value) => typeof value === "string" && value.trim().length > 0;
10
+ const object = (value) => value && typeof value === "object" && !Array.isArray(value);
11
+ const semver = /^6\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?$/;
12
+ const pnpmSemver = /^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?$/;
13
+
14
+ function required(data, field, parent, errors) {
15
+ if (!object(data) || data[field] === undefined || data[field] === null) errors.push(`${parent}.${field} 缺失`);
16
+ }
17
+
18
+ function requiredString(data, field, parent, errors) {
19
+ required(data, field, parent, errors);
20
+ if (object(data) && data[field] !== undefined && !nonEmpty(data[field])) errors.push(`${parent}.${field} 必须是非空字符串`);
21
+ }
22
+
23
+ function requiredPassed(data, field, parent, errors) {
24
+ requiredString(data, field, parent, errors);
25
+ if (object(data) && nonEmpty(data[field]) && !["passed", "approved"].includes(data[field])) errors.push(`${parent}.${field} 必须为 passed/approved`);
26
+ }
27
+
28
+ export function validatePrototypeEvidence(data, { allowTemplate = false, allowLegacy = false } = {}) {
29
+ const errors = [];
30
+ const warnings = [];
31
+ if (!object(data)) return { errors: ["原型证据必须是对象"], warnings };
32
+ if (data.schema_version === 1) {
33
+ if (!allowLegacy) errors.push("schema_version 1 是旧证据;完成 gate.prototype-verified 前必须迁移到 2,或只读时显式 --allow-legacy");
34
+ else warnings.push("legacy prototype evidence schema v1");
35
+ return { errors, warnings };
36
+ }
37
+ if (data.schema_version !== 2) errors.push("schema_version 必须为 2");
38
+ for (const field of ["feature", "prototype_ref", "prototype_stack", "design_baseline", "visual_semantic_mapping", "antd", "browser_verification", "design_qa", "accessibility_verification", "review", "user_confirmation", "blockers"]) required(data, field, "root", errors);
39
+
40
+ const templateValue = (value) => allowTemplate && nonEmpty(value) && /<[^>]+>/.test(value);
41
+ const stack = data.prototype_stack;
42
+ if (object(stack)) {
43
+ for (const field of ["framework", "package_manager", "package_manifest_ref", "lockfile_ref", "source_entry_ref", "build_entry_ref", "build_command", "build_result", "actual_antd_version"]) requiredString(stack, field, "prototype_stack", errors);
44
+ if (stack.framework !== "react") errors.push("prototype_stack.framework 必须为 react");
45
+ if (stack.package_manager !== "pnpm") errors.push("prototype_stack.package_manager 必须为 pnpm");
46
+ if (nonEmpty(stack.lockfile_ref) && !stack.lockfile_ref.endsWith("pnpm-lock.yaml")) errors.push("prototype_stack.lockfile_ref 必须指向 pnpm-lock.yaml");
47
+ if (!templateValue(stack.actual_antd_version) && nonEmpty(stack.actual_antd_version) && !semver.test(stack.actual_antd_version)) errors.push("prototype_stack.actual_antd_version 必须是明确的 antd 6.x semver");
48
+ if (!allowTemplate) requiredPassed(stack, "build_result", "prototype_stack", errors);
49
+ }
50
+
51
+ const baseline = data.design_baseline;
52
+ if (object(baseline)) {
53
+ for (const field of ["design_standard", "project_design_ref", "project_token_refs", "theme_adapter_ref", "project_override_reviewed"]) required(baseline, field, "design_baseline", errors);
54
+ if (baseline.design_standard !== "ant-design-v6") errors.push("design_baseline.design_standard 必须为 ant-design-v6");
55
+ if (!Array.isArray(baseline.project_token_refs) || baseline.project_token_refs.length === 0) errors.push("design_baseline.project_token_refs 必须是非空数组");
56
+ if (!allowTemplate && baseline.project_override_reviewed !== true) errors.push("design_baseline.project_override_reviewed 必须为 true");
57
+ }
58
+
59
+ const mapping = data.visual_semantic_mapping;
60
+ if (object(mapping)) {
61
+ if (mapping.runtime_component_library !== "ant-design-vue-4.x") errors.push("visual_semantic_mapping.runtime_component_library 必须为 ant-design-vue-4.x");
62
+ if (mapping.runtime_version_source !== "implementation-lockfile") errors.push("visual_semantic_mapping.runtime_version_source 必须为 implementation-lockfile");
63
+ if (!Array.isArray(mapping.components) || mapping.components.length === 0) errors.push("visual_semantic_mapping.components 必须是非空数组");
64
+ for (const [index, component] of (mapping.components ?? []).entries()) {
65
+ const parent = `visual_semantic_mapping.components[${index}]`;
66
+ for (const field of ["semantic_role", "antd_v6_component", "project_token_refs", "yss_or_antdv_target", "state_mapping", "react_only_api_not_copied", "verification_ref"]) required(component, field, parent, errors);
67
+ if (!Array.isArray(component?.project_token_refs) || component.project_token_refs.length === 0) errors.push(`${parent}.project_token_refs 必须是非空数组`);
68
+ if (!Array.isArray(component?.state_mapping) || component.state_mapping.length === 0) errors.push(`${parent}.state_mapping 必须是非空数组`);
69
+ if (!allowTemplate && component?.react_only_api_not_copied !== true) errors.push(`${parent}.React-only API 未确认隔离`);
70
+ }
71
+ }
72
+
73
+ if (object(data.antd)) {
74
+ requiredString(data.antd, "target_antd_version", "antd", errors);
75
+ if (object(stack) && nonEmpty(data.antd.target_antd_version) && nonEmpty(stack.actual_antd_version) && !templateValue(data.antd.target_antd_version) && data.antd.target_antd_version !== stack.actual_antd_version) errors.push("antd.target_antd_version 必须与 prototype_stack.actual_antd_version 一致");
76
+ }
77
+ if (object(data.design_qa)) {
78
+ requiredString(data.design_qa, "report_ref", "design_qa", errors);
79
+ requiredString(data.design_qa, "result", "design_qa", errors);
80
+ if (nonEmpty(data.design_qa.report_ref) && !/^docs\/\.scratch\/[^/]+\/verification\/design-qa\.md$/.test(data.design_qa.report_ref) && !templateValue(data.design_qa.report_ref)) errors.push("design_qa.report_ref 必须是 feature 级 verification/design-qa.md");
81
+ if (!allowTemplate) requiredPassed(data.design_qa, "result", "design_qa", errors);
82
+ }
83
+ const accessibility = data.accessibility_verification;
84
+ if (object(accessibility)) {
85
+ for (const field of ["contrast_results_ref", "keyboard_navigation_result", "focus_visible_and_order_result", "semantic_label_dialog_result", "zoom_200_result", "reduced_motion_result", "target_size_result", "automated_scan"]) required(accessibility, field, "accessibility_verification", errors);
86
+ requiredString(accessibility, "contrast_results_ref", "accessibility_verification", errors);
87
+ if (!allowTemplate) for (const field of ["keyboard_navigation_result", "focus_visible_and_order_result", "semantic_label_dialog_result", "zoom_200_result", "reduced_motion_result", "target_size_result"]) requiredPassed(accessibility, field, "accessibility_verification", errors);
88
+ if (object(accessibility.automated_scan)) for (const field of ["tool", "version", "result", "ref"]) requiredString(accessibility.automated_scan, field, "accessibility_verification.automated_scan", errors);
89
+ }
90
+ if (!Array.isArray(data.blockers)) errors.push("root.blockers 必须是数组");
91
+ if (!allowTemplate && Array.isArray(data.blockers) && data.blockers.length > 0) errors.push("存在 blockers,不能通过原型验证");
92
+ return { errors, warnings };
93
+ }
94
+
95
+ function safePrototypeRoot(projectRoot, root, feature) {
96
+ const resolvedProject = path.resolve(projectRoot);
97
+ const resolvedRoot = path.resolve(root);
98
+ const expected = path.resolve(resolvedProject, "docs/.scratch", feature, "design/prototypes");
99
+ if (resolvedRoot !== expected) throw new TypeError(`原型目录必须精确匹配 ${expected}`);
100
+ if (!resolvedRoot.startsWith(`${resolvedProject}${path.sep}`)) throw new TypeError("原型目录越出项目根");
101
+ return { resolvedProject, resolvedRoot };
102
+ }
103
+
104
+ export async function preparePrototype({ projectRoot, root, feature, targetAntdVersion, pnpmVersion }) {
105
+ if (!/^[a-z0-9][a-z0-9-]*$/.test(feature ?? "")) throw new TypeError("feature 必须是小写 kebab-case");
106
+ if (!semver.test(targetAntdVersion ?? "")) throw new TypeError("targetAntdVersion 必须是明确的 antd 6.x semver");
107
+ if (!pnpmSemver.test(pnpmVersion ?? "")) throw new TypeError("pnpmVersion 必须是明确 semver");
108
+ const { resolvedProject, resolvedRoot } = safePrototypeRoot(projectRoot, root, feature);
109
+ const packagePath = path.join(resolvedRoot, "package.json");
110
+ if (!existsSync(packagePath)) throw new TypeError(`缺少 Product Design starter package.json: ${packagePath}`);
111
+ const pkg = JSON.parse(await readFile(packagePath, "utf8"));
112
+ pkg.packageManager = `pnpm@${pnpmVersion}`;
113
+ pkg.dependencies = { ...(pkg.dependencies ?? {}), "@ant-design/icons": "^6.0.0", antd: targetAntdVersion };
114
+ await writeFile(packagePath, `${JSON.stringify(pkg, null, 2)}\n`);
115
+
116
+ const themeSourcePath = path.join(resolvedProject, "docs/design/tokens/theme.json");
117
+ if (!existsSync(themeSourcePath)) throw new TypeError(`缺少项目主题: ${themeSourcePath}`);
118
+ const themeSource = JSON.parse(await readFile(themeSourcePath, "utf8"));
119
+ const generated = [
120
+ 'import { theme } from "antd";',
121
+ "",
122
+ `const source = ${JSON.stringify(themeSource, null, 2)};`,
123
+ 'const layoutKeys = new Set(["layoutHeaderHeight", "layoutSiderBackground", "layoutBodyBackground"]);',
124
+ "export const yssLayoutTokens = Object.fromEntries(Object.entries(source.token ?? {}).filter(([key]) => layoutKeys.has(key)));",
125
+ "export const yssTheme = {",
126
+ " algorithm: [theme.defaultAlgorithm, theme.compactAlgorithm],",
127
+ " token: Object.fromEntries(Object.entries(source.token ?? {}).filter(([key]) => !layoutKeys.has(key)))",
128
+ "};",
129
+ ""
130
+ ].join("\n");
131
+ await mkdir(path.join(resolvedRoot, "src"), { recursive: true });
132
+ await writeFile(path.join(resolvedRoot, "src/yss-theme.js"), generated);
133
+ const manifest = {
134
+ schema_version: 1,
135
+ feature,
136
+ design_standard: "ant-design-v6",
137
+ target_antd_version: targetAntdVersion,
138
+ prototype_framework: "react",
139
+ package_manager: `pnpm@${pnpmVersion}`,
140
+ theme_source: "docs/design/tokens/theme.json",
141
+ theme_adapter: `docs/.scratch/${feature}/design/prototypes/src/yss-theme.js`,
142
+ production_runtime: { framework: "vue-3", component_library: "ant-design-vue-4.x", version_source: "implementation-lockfile" },
143
+ next_commands: ["pnpm install", "pnpm build"]
144
+ };
145
+ await writeFile(path.join(resolvedRoot, "yss-prototype-adapter.json"), `${JSON.stringify(manifest, null, 2)}\n`);
146
+ return manifest;
147
+ }
148
+
149
+ export async function validatePrototypeProject({ root, targetAntdVersion }) {
150
+ const errors = [];
151
+ const packagePath = path.join(root, "package.json");
152
+ if (!existsSync(packagePath)) return { errors: ["缺少 package.json"] };
153
+ const pkg = JSON.parse(await readFile(packagePath, "utf8"));
154
+ if (pkg.dependencies?.antd !== targetAntdVersion) errors.push(`package.json 必须精确锁定 antd ${targetAntdVersion}`);
155
+ if (!String(pkg.packageManager ?? "").startsWith("pnpm@")) errors.push("package.json 必须记录实际 pnpm packageManager");
156
+ if (!existsSync(path.join(root, "pnpm-lock.yaml"))) errors.push("缺少 pnpm-lock.yaml");
157
+ if (!existsSync(path.join(root, "src/yss-theme.js"))) errors.push("缺少 src/yss-theme.js");
158
+ const sourceFiles = ["src/App.jsx", "src/App.tsx", "src/main.jsx", "src/main.tsx"].filter((file) => existsSync(path.join(root, file)));
159
+ const source = (await Promise.all(sourceFiles.map((file) => readFile(path.join(root, file), "utf8")))).join("\n");
160
+ if (!/ConfigProvider/.test(source) || !/yssTheme/.test(source)) errors.push("原型入口必须通过 ConfigProvider 消费 yssTheme");
161
+ if (!existsSync(path.join(root, "yss-prototype-adapter.json"))) errors.push("缺少 yss-prototype-adapter.json");
162
+ return { errors };
163
+ }
164
+
165
+ function args(argv) {
166
+ const result = { _: [] };
167
+ for (let index = 0; index < argv.length; index += 1) {
168
+ const item = argv[index];
169
+ if (!item.startsWith("--")) { result._.push(item); continue; }
170
+ const key = item.slice(2);
171
+ const value = argv[index + 1];
172
+ if (!value || value.startsWith("--")) result[key] = true;
173
+ else { result[key] = value; index += 1; }
174
+ }
175
+ return result;
176
+ }
177
+
178
+ async function loadYaml(file) {
179
+ const document = parseDocument(await readFile(file, "utf8"), { uniqueKeys: true });
180
+ if (document.errors.length > 0) throw new TypeError(document.errors[0].message);
181
+ return document.toJS({ maxAliasCount: 0 });
182
+ }
183
+
184
+ async function main(argv) {
185
+ const parsed = args(argv);
186
+ const command = parsed._[0];
187
+ if (command === "prepare") {
188
+ const result = await preparePrototype({ projectRoot: parsed["project-root"], root: parsed.root, feature: parsed.feature, targetAntdVersion: parsed["target-antd-version"], pnpmVersion: parsed["pnpm-version"] });
189
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
190
+ return;
191
+ }
192
+ if (command === "validate-project") {
193
+ const result = await validatePrototypeProject({ root: parsed.root, targetAntdVersion: parsed["target-antd-version"] });
194
+ if (result.errors.length > 0) throw new TypeError(result.errors.join("\n"));
195
+ process.stdout.write("prototype project contract passed\n");
196
+ return;
197
+ }
198
+ if (command === "validate-evidence") {
199
+ const result = validatePrototypeEvidence(await loadYaml(parsed._[1]), { allowTemplate: Boolean(parsed["allow-template"]), allowLegacy: Boolean(parsed["allow-legacy"]) });
200
+ if (result.errors.length > 0) throw new TypeError(result.errors.join("\n"));
201
+ process.stdout.write(`prototype evidence passed${result.warnings.length ? ` with warnings: ${result.warnings.join(", ")}` : ""}\n`);
202
+ return;
203
+ }
204
+ throw new TypeError("usage: prototype-contract.mjs prepare|validate-project|validate-evidence ...");
205
+ }
206
+
207
+ if (import.meta.url === pathToFileURL(process.argv[1]).href) main(process.argv.slice(2)).catch((error) => { process.stderr.write(`${error.message}\n`); process.exitCode = 1; });
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env node
2
+ import assert from "node:assert/strict";
3
+ import { mkdtemp, mkdir, readFile, writeFile } from "node:fs/promises";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import {
7
+ preparePrototype,
8
+ validatePrototypeEvidence,
9
+ validatePrototypeProject
10
+ } from "../scripts/prototype-contract.mjs";
11
+
12
+ const tempRoot = await mkdtemp(path.join(os.tmpdir(), "yss-prototype-contract-"));
13
+ const projectRoot = path.join(tempRoot, "project");
14
+ const feature = "order-review";
15
+ const prototypeRoot = path.join(projectRoot, "docs/.scratch", feature, "design/prototypes");
16
+ await mkdir(path.join(prototypeRoot, "src"), { recursive: true });
17
+ await mkdir(path.join(projectRoot, "docs/design/tokens"), { recursive: true });
18
+ await writeFile(path.join(prototypeRoot, "package.json"), JSON.stringify({
19
+ name: "order-review-prototype",
20
+ private: true,
21
+ type: "module",
22
+ scripts: { build: "vite build" },
23
+ dependencies: { react: "19.2.0", "react-dom": "19.2.0", vite: "6.4.2" }
24
+ }, null, 2));
25
+ await writeFile(path.join(projectRoot, "docs/design/tokens/theme.json"), JSON.stringify({
26
+ algorithm: "default",
27
+ token: {
28
+ colorPrimary: "#3371ff",
29
+ borderRadius: 6,
30
+ controlHeight: 32,
31
+ layoutHeaderHeight: 64
32
+ }
33
+ }, null, 2));
34
+
35
+ const before = await validatePrototypeProject({ root: prototypeRoot, targetAntdVersion: "6.6.2" });
36
+ assert(before.errors.some((message) => message.includes("antd")), "RED: starter without antd must fail");
37
+ assert(before.errors.some((message) => message.includes("pnpm-lock.yaml")), "RED: missing pnpm lockfile must fail");
38
+
39
+ await preparePrototype({ projectRoot, root: prototypeRoot, feature, targetAntdVersion: "6.6.2", pnpmVersion: "10.15.0" });
40
+ const pkg = JSON.parse(await readFile(path.join(prototypeRoot, "package.json"), "utf8"));
41
+ assert.equal(pkg.dependencies.antd, "6.6.2");
42
+ assert.equal(pkg.packageManager, "pnpm@10.15.0");
43
+ assert.match(await readFile(path.join(prototypeRoot, "src/yss-theme.js"), "utf8"), /compactAlgorithm/);
44
+
45
+ await writeFile(path.join(prototypeRoot, "pnpm-lock.yaml"), "lockfileVersion: '9.0'\n");
46
+ await writeFile(path.join(prototypeRoot, "src/App.jsx"), [
47
+ 'import { ConfigProvider, Button } from "antd";',
48
+ 'import { yssTheme } from "./yss-theme.js";',
49
+ 'export function App() { return <ConfigProvider theme={yssTheme}><Button type="primary">提交</Button></ConfigProvider>; }'
50
+ ].join("\n"));
51
+ const after = await validatePrototypeProject({ root: prototypeRoot, targetAntdVersion: "6.6.2" });
52
+ assert.deepEqual(after.errors, []);
53
+
54
+ const wrongTarget = await validatePrototypeProject({ root: prototypeRoot, targetAntdVersion: "6.6.1" });
55
+ assert(wrongTarget.errors.some((message) => message.includes("精确锁定 antd 6.6.1")), "target 与实际 antd 版本不一致必须失败");
56
+
57
+ const npmPackage = structuredClone(pkg);
58
+ npmPackage.packageManager = "npm@11.0.0";
59
+ await writeFile(path.join(prototypeRoot, "package.json"), JSON.stringify(npmPackage, null, 2));
60
+ const npmProject = await validatePrototypeProject({ root: prototypeRoot, targetAntdVersion: "6.6.2" });
61
+ assert(npmProject.errors.some((message) => message.includes("packageManager")), "原型包管理器漂移到 npm 必须失败");
62
+ await writeFile(path.join(prototypeRoot, "package.json"), JSON.stringify(pkg, null, 2));
63
+
64
+ await assert.rejects(
65
+ preparePrototype({
66
+ projectRoot,
67
+ root: path.join(projectRoot, "prototypes", feature),
68
+ feature,
69
+ targetAntdVersion: "6.6.2",
70
+ pnpmVersion: "10.15.0"
71
+ }),
72
+ /docs\/.scratch/,
73
+ "非标准原型目录必须被拒绝"
74
+ );
75
+
76
+ const validEvidence = {
77
+ schema_version: 2,
78
+ feature,
79
+ prototype_ref: `docs/.scratch/${feature}/design/prototypes/index.html`,
80
+ prototype_stack: {
81
+ framework: "react",
82
+ package_manager: "pnpm",
83
+ package_manifest_ref: `docs/.scratch/${feature}/design/prototypes/package.json`,
84
+ lockfile_ref: `docs/.scratch/${feature}/design/prototypes/pnpm-lock.yaml`,
85
+ source_entry_ref: `docs/.scratch/${feature}/design/prototypes/src/App.jsx`,
86
+ build_entry_ref: `docs/.scratch/${feature}/design/prototypes/dist/index.html`,
87
+ build_command: "pnpm build",
88
+ build_result: "passed",
89
+ actual_antd_version: "6.6.2"
90
+ },
91
+ design_baseline: {
92
+ design_standard: "ant-design-v6",
93
+ project_design_ref: "docs/design/design.md",
94
+ project_token_refs: ["docs/design/tokens/theme.json"],
95
+ theme_adapter_ref: `docs/.scratch/${feature}/design/prototypes/src/yss-theme.js`,
96
+ project_override_reviewed: true
97
+ },
98
+ visual_semantic_mapping: {
99
+ runtime_component_library: "ant-design-vue-4.x",
100
+ runtime_version_source: "implementation-lockfile",
101
+ components: [{
102
+ semantic_role: "primary-action",
103
+ antd_v6_component: "Button",
104
+ project_token_refs: ["colorPrimary"],
105
+ yss_or_antdv_target: "YButton",
106
+ state_mapping: ["default", "hover", "active", "disabled", "loading"],
107
+ react_only_api_not_copied: true,
108
+ verification_ref: "verification/button-states.png"
109
+ }]
110
+ },
111
+ antd: { target_antd_version: "6.6.2", queries: { design_md: "verification/antd-design.json", components: [] } },
112
+ browser_verification: { rendered_nonblank: true, viewports: [], main_flow_result: "passed", failure_permission_or_conflict_result: "passed", console_error_ref: "verification/console.txt" },
113
+ design_qa: { report_ref: `docs/.scratch/${feature}/verification/design-qa.md`, result: "passed" },
114
+ accessibility_verification: {
115
+ contrast_results_ref: "verification/contrast.json",
116
+ keyboard_navigation_result: "passed",
117
+ focus_visible_and_order_result: "passed",
118
+ semantic_label_dialog_result: "passed",
119
+ zoom_200_result: "passed",
120
+ reduced_motion_result: "passed",
121
+ target_size_result: "passed",
122
+ automated_scan: { tool: "axe", version: "4", result: "passed", ref: "verification/axe.json" }
123
+ },
124
+ review: { prototype_review_ref: "design/review.md", result: "approved" },
125
+ user_confirmation: { confirmation_ref: "design/confirmation.md", result: "approved" },
126
+ blockers: []
127
+ };
128
+ assert.deepEqual(validatePrototypeEvidence(validEvidence).errors, []);
129
+
130
+ const missingMapping = structuredClone(validEvidence);
131
+ delete missingMapping.visual_semantic_mapping;
132
+ assert(validatePrototypeEvidence(missingMapping).errors.some((message) => message.includes("visual_semantic_mapping")));
133
+
134
+ const copiedReactApi = structuredClone(validEvidence);
135
+ copiedReactApi.visual_semantic_mapping.components[0].react_only_api_not_copied = false;
136
+ assert(validatePrototypeEvidence(copiedReactApi).errors.some((message) => message.includes("React-only")));
137
+
138
+ const inaccessible = structuredClone(validEvidence);
139
+ inaccessible.accessibility_verification.contrast_results_ref = "";
140
+ assert(validatePrototypeEvidence(inaccessible).errors.some((message) => message.includes("contrast_results_ref")));
141
+
142
+ const wrongQaRoot = structuredClone(validEvidence);
143
+ wrongQaRoot.design_qa.report_ref = "docs/design/design-qa.md";
144
+ assert(validatePrototypeEvidence(wrongQaRoot).errors.some((message) => message.includes("design_qa.report_ref")));
145
+
146
+ const versionMismatch = structuredClone(validEvidence);
147
+ versionMismatch.antd.target_antd_version = "6.6.1";
148
+ assert(validatePrototypeEvidence(versionMismatch).errors.some((message) => message.includes("target_antd_version")));
149
+
150
+ const unresolvedBlocker = structuredClone(validEvidence);
151
+ unresolvedBlocker.blockers = ["缺少权限失败态"];
152
+ assert(validatePrototypeEvidence(unresolvedBlocker).errors.some((message) => message.includes("blockers")));
153
+
154
+ process.stdout.write("YSS prototype contract scenarios passed\n");
@@ -15,7 +15,7 @@ Use this reference when multiple YSS skills seem applicable.
15
15
  - `yss-use-table-height`: Only table available-height calculation and required container/pagination/toolbar wiring.
16
16
  - `yss-use-tree-height`: Only tree available-height calculation, search offset, and virtual scrolling wiring.
17
17
 
18
- Default for a new page: first verify the approved product design, state matrix, Ant Design v6 high-fidelity HTML prototype, AntD CLI evidence, and user confirmation; then start with `yss-page-module-development` and add the narrow skills that match the page controls.
18
+ Default for a new page: first verify the approved product design, state matrix, Ant Design v6 theme/visual-standard high-fidelity HTML prototype, schema v2 semantic mapping/browser/accessibility evidence, and user confirmation; then use the implementation lockfile to map into YSS UI + Ant Design Vue 4.x, start with `yss-page-module-development`, and add the narrow skills that match the page controls.
19
19
 
20
20
  中文说明:新建页面默认从页面模块技能开始,只有遇到具体组件、Hook、API、Formily 细节时再加载专项技能。
21
21
 
@@ -32,7 +32,7 @@ pnpm why vue @yss-ui/components @yss-ui/hooks ant-design-vue vxe-table
32
32
 
33
33
  ## Ant Design v6 边界
34
34
 
35
- Ant Design v6 可以作为产品原型的视觉和 token 语义参考;Vue 生产实现使用 Ant Design Vue 4.x。禁止复制 React hooks、JSX、组件 props、theme algorithm API 或事件模型到 Vue 代码。
35
+ Ant Design v6 是产品原型默认的主题样式、视觉和 token 语义标准;Vue 生产实现使用 Ant Design Vue 4.x。版本号不同本身不是冲突。生产映射必须消费原型证据中的 `visual_semantic_mapping`,并用实现仓 lockfile/类型验证 YSS 或 AntDV 目标;禁止复制 React hooks、JSX、组件 props、theme algorithm API 或事件模型到 Vue 代码。
36
36
 
37
37
  ## 兼容性证据
38
38
 
@@ -39,7 +39,7 @@ README、用户指南、根目录 `CLAUDE.md` 和其他说明文档只引用或
39
39
 
40
40
  按“影响面 → 单一事实来源 → 投影 / 派生资产 → 分级证据”维护。强度分级、最低证据和 checkpoint 合同见 `docs/process/harness-process-tailoring.md`。
41
41
 
42
- - 创建、修改或退役 skill 时使用 `maintaining-skills`,并先按 `docs/process/harness-process-tailoring.md` 判定 L1 / L2 / L3;只有 L3 必须保留完整基线失败、压力场景、修订后验证和正式独立审查证据。
42
+ - 创建、修改或退役 skill 时使用 `maintaining-skills`,并先按 `docs/process/harness-process-tailoring.md` 判定 L1 / L2 / L3;L3 日常记录维护者自检与 fresh verification,正式发布前执行完整模板门禁。
43
43
  - `.agents/skills` 是跨 Agent 共享技能的权威内容;`.claude/skills`、`.codex/skills`、`.cursor/skills`、`.hermes/skills`、`.pi/skills`、`.qoder/skills`、`.trae/skills` 中的共享技能是生成投影,禁止分别手工修改。Cursor 的契约运行时入口是 `.cursor/skills`;不得把 canonical `.agents/skills` 与某个平台投影当作同权双入口。
44
44
  - 模板维护默认以 `scripts/verify-template-fast` 完成 `implementation-ready`;显式晋级审查时用 `scripts/verify-template-candidate`,首次冻结前和最终发布前仍必须执行完整 `scripts/verify-template`。后者是不可裁剪的模板发布阻断门禁。模板与外部 `create-yss-spec` 的跨仓库契约未完成集成验证时,不得声称可发布。
45
45
 
@@ -54,7 +54,7 @@ README、用户指南、根目录 `CLAUDE.md` 和其他说明文档只引用或
54
54
  | 入口分诊 `stage.entry-triage` | `work-unit.entry-triage` | `yss-product-lifecycle` | 仓库身份、影响面、最近可信阶段;`gate.repository-identity-valid` |
55
55
  | Discovery `stage.discovery` | `work-unit.discovery-opportunity`、`work-unit.discovery-requirements`、`work-unit.domain-strategy-design`、`work-unit.stage-decision` | `yss-product-lifecycle`;按事实 / 领域影响使用 `competitive-intelligence`、`research`、`grilling`、`domain-modeling`、`yss-stage-decision` | Discovery、用户/MVP/非目标/成功标准、测试 seam;必要时 DDD 战略设计与阶段决策包;`gate.domain-strategy-approved`、`gate.stage-decision-package-approved` |
56
56
  | Spec / 功能架构 `stage.spec-architecture` | `work-unit.spec-synthesis` | `yss-product-lifecycle`;`to-spec` 仅为显式兼容入口 | Spec、产品总体设计、功能架构;必要时 Spec Delta;`gate.spec-baseline-approved` |
57
- | 产品设计 `stage.product-design` | `work-unit.prototype-design` | `yss-design-system` → `prototype-review` → `yss-prototype-stage` → `yss-antd-design` → Codex `product-design:index`;前端落地改用 `yss-ui` | 交互说明、低 / 高保真原型、状态矩阵;`gate.prototype-reviewed`、`gate.prototype-verified`、`gate.user-confirmation` |
57
+ | 产品设计 `stage.product-design` | `work-unit.prototype-design` | `yss-prototype-stage` 为主合同,内部依次消费 `yss-design-system`、低保真、独立 `prototype-review`、`yss-antd-design` pre-build facts、Codex `product-design:index` focused workflow、post-build/浏览器/无障碍验证;前端落地改用 `yss-ui` | 交互说明、低 / 高保真原型、状态矩阵;`gate.prototype-reviewed`、`gate.prototype-verified`、`gate.user-confirmation` |
58
58
  | 系统 / 数据架构与工程契约 `stage.system-data-engineering` | `work-unit.technical-analysis` | `yss-router`;按影响使用 `yss-openapi-governance`、`yss-openapi-draft-review`、`codebase-design`、`implementation-repo-onboarding`、`yss-tactical-design` | OpenAPI Draft / Freeze、数据架构、工程基线、架构审查;无 API 影响记录;必要时 Tactical DDD Check;`gate.openapi-draft-reviewed`、`gate.design-reviewed`、`gate.openapi-frozen`、`gate.engineering-baseline-accepted`、`gate.architecture-reviewed` |
59
59
  | Ticket 正式化 `stage.ticket-formalization` | `work-unit.ticket-decomposition` | `yss-product-lifecycle` + `yss-router`;`to-tickets` 仅为显式兼容入口 | 功能父 Ticket、垂直切片、Slice Implementation Contract;切片初始 `ready-for-human`;`gate.slice-contract-approved`、`gate.slice-ready-for-agent` |
60
60
  | 垂直切片实现 `stage.vertical-slice-implementation` | `work-unit.slice-implementation` | `yss-router` + `tdd`;UI 影响追加 `yss-ui`、`yss-page-module-development` 及条件专项 skill;`implement` 仅为显式兼容入口 | 前后端代码、TDD、YSS Skill Execution Result;仅允许 `ready-for-agent` 且合同当前 |
@@ -96,7 +96,7 @@ README、用户指南、根目录 `CLAUDE.md` 和其他说明文档只引用或
96
96
  |---|---|
97
97
  | 技术事实、标准、第三方 API 或框架行为影响决策 | `research` 或等价的一手资料记录 |
98
98
  | 竞品、市场或用户口碑事实 | `competitive-intelligence` |
99
- | UI 设计、原型、组件或主题 | `yss-design-system` → `prototype-review` → `yss-prototype-stage`;原型事实用 `yss-antd-design`,Codex 再路由 `product-design:index`,其他 Agent 交付等价合同资产。前端代码落地改用 `yss-ui`,不要继续调用 `yss-antd-design` |
99
+ | UI 设计、原型、组件或主题 | `yss-prototype-stage` 持有阶段合同:`yss-design-system` → 低保真 → 独立 `prototype-review` → `yss-antd-design` pre-build facts → Codex `product-design:index` focused workflow → post-build/浏览器/无障碍验证;其他 Agent 交付等价合同资产。前端代码落地改用 `yss-ui`,不要继续调用 `yss-antd-design` |
100
100
  | Bug、测试失败或性能回退 | `diagnosing-bugs` 建立可复现反馈,再用 `tdd` |
101
101
  | merge / rebase 冲突 | `resolving-merge-conflicts` |
102
102
  | 架构治理、难测模块或深模块设计 | `codebase-design`;`improve-codebase-architecture` 仅作为用户显式兼容入口 |
@@ -114,7 +114,7 @@ README、用户指南、根目录 `CLAUDE.md` 和其他说明文档只引用或
114
114
 
115
115
  ## 10. 独立审查、验证和追踪
116
116
 
117
- - 实现者不能承担命中的独立审查(含数字人)。模板维护按 L1 / L2 / L3 分别使用 self-check / 人工 checkpoint、聚焦独立审查、正式独立审查;模板发布、代码切片和高风险变更仍必须由其他 Agent 或独立审查者完成。产品切片与模板维护共用同一 finding 闭环:`violation` 由实现者在原合同路径修复后重新捕获并全轴复审;`drift` / `new_impacts` 使合同 `stale` 并回 Router。审查者不得写实现。命中后的 mandatory 不得豁免;未命中才 `not-applicable`。
117
+ - 实现者不能承担命中的独立审查(含数字人)。模板维护的 L3 日常路径使用维护者自检;L2 仍按需使用聚焦独立审查,正式发布仍执行完整模板门禁。模板发布、代码切片和高风险变更仍必须满足各自独立审查要求。产品切片与模板维护共用同一 finding 闭环:`violation` 由实现者在原合同路径修复后重新捕获并全轴复审;`drift` / `new_impacts` 使合同 `stale` 并回 Router。审查者不得写实现。命中后的 mandatory 不得豁免;未命中才 `not-applicable`。
118
118
  - 任何“完成 / 可合并 / 可发布”结论必须基于 fresh verification,不接受“之前跑过”或实现者自述。
119
119
  - 会签门禁按 `docs/agents/digital-human-roles.yaml` 的 `gate_policy` 关闭,会签文件经 `scripts/verify-approval-record` 核验;`gate.release-ready`、对外商务承诺和运行时外部副作用仍须生物人。
120
120
  - 在会签暂停、handoff、进入实现、合并或发布边界集中同步范围、验证证据、风险、会签点、Ticket 状态和下一步;阻塞、责任人变化或资产单独批准时立即同步。
@@ -42,17 +42,17 @@
42
42
 
43
43
  1. 先读取 `yss-project.yaml`,按 `repository_mode` 选择模板维护或产品研发生命周期。
44
44
  2. 必读入口为 `AGENTS.md` 与 `CONTEXT.md`;流程事实分别以生命周期映射和裁剪指南为准。
45
- 3. `template-source` 修改流程、技能或模板后,执行 `scripts/sync-skills`、`scripts/update-skill-lock` 和 `scripts/verify-template`。
46
- 4. `project-instance` 先做影响面分诊;进入 Spec 基线时使用 `grill-with-docs`、`to-spec`,契约冻结后再用 `to-tickets` 拆分垂直切片 Ticket。
45
+ 3. `template-source` 修改后先按 `maintenance-intensity.yaml` 判定 L1 / L2 / L3,默认用 `scripts/verify-template-fast` 达到 `implementation-ready`;L3 日常采用维护者自检,正式发布前执行完整门禁;只有共享 skill 变更才运行 `scripts/sync-skills` 和 `scripts/update-skill-lock`。
46
+ 4. `project-instance` 默认从 `yss-product-lifecycle` 的 `route` 模式开始,再由原生 `work-unit.*` 推进 Discovery、Spec、产品设计、工程契约和 Ticket 正式化;`grill-with-docs`、`to-spec`、`to-tickets`、`implement` 仅作为用户显式调用的兼容入口。
47
47
  5. 实现仓库接入、YSS 路由、独立审查、fresh verification 和 Git checkpoint 以 `AGENTS.md` 的硬门禁为准。
48
48
 
49
49
  YSS skills 的公开发布投影维护在 [iloveZzz/yss-spec-dev-skills](https://github.com/iloveZzz/yss-spec-dev-skills),发布清单和导出命令见 [skills 维护说明](./docs/agents/skills-maintenance.md)。
50
50
 
51
51
  ## 模板初始化 CLI
52
52
 
53
- `create-yss-spec` 的目标维护位置是独立 GitHub 仓库 [iloveZzz/create-yss-spec](https://github.com/iloveZzz/create-yss-spec)。本仓库不再包含 CLI 源码、测试、发布配置或开发过程记录,只保留面向模板使用者的实践指南:
53
+ `create-yss-spec` 的目标维护位置是独立 GitHub 仓库 [iloveZzz/create-yss-spec](https://github.com/iloveZzz/create-yss-spec)。本仓库不再包含 CLI 源码、测试、发布配置或开发过程记录。CLI 的使用方法已经合并到统一用户手册:
54
54
 
55
- - [create-yss-spec 外部 CLI 实践指南](./docs/user-guide/外部命令行工具实践指南.md)
55
+ - [YSS 用户手册:创建、接管和更新项目](./docs/user-guide/用户手册.md#创建接管和更新项目)
56
56
 
57
57
  推荐入口:
58
58
 
@@ -80,13 +80,13 @@ main@6acc160e4e0cd062dbbbd7a1b26ae92855edf07e
80
80
 
81
81
  主研发流程使用 `skills/engineering`;`skills-lock.json` 同时记录本次安装的关联 `productivity`、`in-progress`、`deprecated`、`misc` 和 `personal` skill 路径。
82
82
 
83
- ## 轻量校验
83
+ ## 模板校验
84
84
 
85
85
  ```bash
86
- scripts/verify-template
86
+ scripts/verify-template-fast
87
87
  ```
88
88
 
89
- 该脚本检查:
89
+ 快速入口按 Git 影响面执行相关检查,未映射路径或核心校验资产变化时 fail-safe 升级。它与 candidate / 发布 profile 共同检查:
90
90
 
91
91
  - `yss-project.yaml`、权威流程资产和模板是否完整。
92
92
  - 共享技能投影及 `skills-lock.json` 的完整树哈希是否一致。
@@ -96,14 +96,14 @@ scripts/verify-template
96
96
  - 示例 OpenAPI YAML 是否可解析。
97
97
  - Git diff 是否存在空白错误。
98
98
 
99
+ 显式准备审查候选时执行 `scripts/verify-template-candidate`;首次正式冻结前和最终发布前执行不可裁剪的 `scripts/verify-template`。
100
+
99
101
  ## 关键文档
100
102
 
101
103
  | 文档 | 内容 |
102
104
  |------|------|
103
105
  | [AGENTS.md](./AGENTS.md) | 全局 AI 指令 + 工程基线入口 + Agent 协作 |
104
- | [docs/user-guide/用户手册索引.md](./docs/user-guide/用户手册索引.md) | 模板使用说明 |
105
- | [docs/user-guide/产品生命周期工作流.md](./docs/user-guide/产品生命周期工作流.md) | 产品全生命周期使用手册 |
106
- | [docs/user-guide/图示生成器使用指南.md](./docs/user-guide/图示生成器使用指南.md) | Excalidraw 可视化辅助 skill 使用手册 |
106
+ | [docs/user-guide/用户手册.md](./docs/user-guide/用户手册.md) | 从首次只读检查到需求、开发、审查、发布和 CLI 操作的统一用户手册 |
107
107
  | [docs/process/PDCA-SCRUM.md](./docs/process/PDCA-SCRUM.md) | PDCA × Scrum × AI |
108
108
  | [docs/process/MATT-POCOCK-ENGINEERING-SKILLS.md](./docs/process/MATT-POCOCK-ENGINEERING-SKILLS.md) | Matt Pocock Engineering Skills 集成与使用 |
109
109
  | [docs/process/lifecycle-registry.yaml](./docs/process/lifecycle-registry.yaml) | 生命周期结构事实源:主阶段、门禁、产物、工作单元、证据与稳定 ID |
@@ -113,7 +113,6 @@ scripts/verify-template
113
113
  | [docs/process/implementation-repo-integration.md](./docs/process/implementation-repo-integration.md) | 外部前端 / 后端实现仓库接入与跨仓库切片绑定 |
114
114
  | [docs/agents/README.md](./docs/agents/README.md) | Agent 协作文档目录说明 |
115
115
  | [docs/agents/skills-maintenance.md](./docs/agents/skills-maintenance.md) | Agent skills 安装与维护 |
116
- | [docs/user-guide/规格与任务迁移指南.md](./docs/user-guide/规格与任务迁移指南.md) | 旧规格与任务入口迁移指南 |
117
116
  | [docs/discovery/IDEATION.md](./docs/discovery/IDEATION.md) | 机会构想方法 |
118
117
  | [docs/architecture/README.md](./docs/architecture/README.md) | 架构设计 + 审查清单 |
119
118
  | [docs/testing/README.md](./docs/testing/README.md) | 测试策略 |
@@ -37,6 +37,7 @@ htmlcov/
37
37
  Excalidraw
38
38
  .obsidian
39
39
  .ua
40
+ output
40
41
  docs/process/presentations/
41
42
  docs/process/yss-product-lifecycle-team-guide.md
42
43
  docs/graphify-out
@@ -36,7 +36,7 @@
36
36
 
37
37
  1. 在临时目录读取或下载锁定来源,不直接覆盖工作区。
38
38
  2. 只在 `.agents/skills/<skill-name>/` 修改共享技能;平台专属技能只在所属 root 修改。
39
- 3. 创建、修改或退役 skill 时使用 `maintaining-skills`,并先按 `docs/process/harness-process-tailoring.md` 判定验证与审查强度:L1 执行相关检查,L2 记录最小反例和 fresh verification,L3 记录完整 RED 基线、压力场景、GREEN 结果和 REFACTOR 检查。未定义分级的外部仓库按实际风险执行结构校验和针对性行为验证,不强制为每次普通修改构造失败基线。
39
+ 3. 创建、修改或退役 skill 时使用 `maintaining-skills`,并先按 `docs/process/harness-process-tailoring.md` 判定验证与审查强度:L1 执行相关检查,L2 记录最小反例、fresh verification 和聚焦审查,L3 记录维护者自检与 fresh verification;正式发布前统一执行完整模板门禁。未定义分级的外部仓库按实际风险执行结构校验和针对性行为验证。
40
40
  4. 生成共享投影并更新锁文件:
41
41
 
42
42
  ```bash
@@ -78,7 +78,7 @@ scripts/update-skill-lock --check
78
78
  scripts/verify-upstream-skill-source --source-root <matt-skills-checkout>
79
79
  ```
80
80
 
81
- 前者检查所有共享投影是否指向或匹配权威内容,后者检查 `skills-lock.json` 是否与当前完整目录树一致。过时技能不会保留兼容别名;旧版项目按 `docs/user-guide/规格与任务迁移指南.md` 一次性迁移。
81
+ 前者检查所有共享投影是否指向或匹配权威内容,后者检查 `skills-lock.json` 是否与当前完整目录树一致。过时技能不会保留兼容别名;旧 skill 名称和入口按 [`docs/agents/skill-migrations.md`](./skill-migrations.md) 一次性迁移,项目文件升级由 `create-yss-spec attach` / `sync` 处理。
82
82
 
83
83
  ## skills.sh 公开发布
84
84
 
@@ -16,7 +16,7 @@
16
16
  | 原型 / 线框图 | | |
17
17
  | 状态矩阵 | `docs/.scratch/<feature>/design/<feature>-state-matrix.md` | |
18
18
  | 原型评审结论 | `docs/.scratch/<feature>/design/<feature>-prototype-review.md` | |
19
- | 高保真 HTML 原型 | `docs/.scratch/<feature>/design/prototypes/index.html` | 有 UI 时必需;必须使用 Ant Design v6,并通过 `product-design:index` 路由产出或记录例外原因 |
19
+ | 高保真 HTML 原型 | `docs/.scratch/<feature>/design/prototypes/index.html` | 有 UI 时必需;主题/视觉标准必须为 Ant Design v6,并通过 YSS Product Design adapter + `product-design:index` 路由产出或记录例外原因;生产 API 为 YSS UI + Ant Design Vue 4.x |
20
20
  | AntD CLI 校验证据 | `docs/.scratch/<feature>/design/<feature>-prototype-confirmation.md` 或评审记录 | 有 UI 时必需;记录 design.md / info / demo / token / semantic 查询 |
21
21
  | 用户确认记录 | `docs/.scratch/<feature>/design/<feature>-prototype-confirmation.md` | 有 UI 时必需;未确认前不得进入 OpenAPI Draft 评审 |
22
22
  | YSS 工程基线 | `.codex/skills/yss-ddd-scaffold-generator/references/yss-backend-scaffold-parent/SKILL.md` | |
@@ -37,7 +37,7 @@
37
37
  | YAML 权威性 | 单一 OAS 3.1 document;未混入生命周期 frontmatter / 根字段;`operationId` 稳定 | | |
38
38
  | P0 覆盖 | 每个 P0 需求有 endpoint/schema/error/test 或明确非目标 | | |
39
39
  | 产品总体设计完整 | Draft 已依据 Spec 和产品总体设计 / 功能架构;缺产品总体设计时返回上游补齐 | | |
40
- | 交互输入完整 | 有 UI 时,Draft 已同时依据交互说明、原型/线框、状态矩阵、prototype-review、Ant Design v6 高保真 HTML 原型、AntD CLI 校验证据和用户确认记录;无 UI 时需说明页面 / 交互资产不适用原因 | | |
40
+ | 交互输入完整 | 有 UI 时,Draft 已同时依据交互说明、原型/线框、状态矩阵、prototype-review、Ant Design v6 主题/视觉标准高保真 HTML 原型、schema v2 AntD/语义映射/浏览器/无障碍证据和用户确认记录;无 UI 时需说明页面 / 交互资产不适用原因 | | |
41
41
  | DDD 契约边界 | Endpoint/schema 归属的限界上下文清楚;术语与 `CONTEXT.md` 和功能架构一致;契约不直接暴露内部聚合、Repository 或持久化表结构 | | |
42
42
  | 页面动作覆盖 | 每个按钮 / 抽屉 / 弹窗动作有 endpoint/non-goal、`actionKey` 和错误码;Spec 明确认认证 / 授权变化时同时映射该行为 | | |
43
43
  | 对象生命周期 | manage/maintain/configure/create/update/archive/retry/cancel/publish/export/create-draft 语义闭环 | | |
@@ -20,7 +20,7 @@
20
20
  - 表单、表格、弹窗、抽屉、步骤流等交互说明。
21
21
  - loading、empty、error、readonly、disabled、no-permission、conflict 等状态矩阵。
22
22
  - 页面字段、筛选条件、操作按钮和权限规则。
23
- - 低保真原型评审通过后的 Ant Design v6 高保真可交互 HTML 原型,默认路径为 `docs/.scratch/<feature>/design/prototypes/index.html`;该产物可由系统 / Agent 自动生成,不要求用户手工提供,产出前必须使用 `yss-antd-design` 查询设计语言、组件 API、demo、token 和 semantic 信息,产出后必须记录 AntD v6 校验证据并获得用户确认。前端代码落地改用 `yss-ui`。
23
+ - 低保真原型评审通过后的 Ant Design v6 主题/视觉标准高保真可交互 HTML 原型,默认路径为 `docs/.scratch/<feature>/design/prototypes/index.html`;标准 React 原型组件精确锁定与 CLI 一致的 `antd@6.x`,通过 YSS Product Design adapter 消费项目 token、pnpm、同视口 QA 和无障碍证据。生产组件/API 仍是 Vue 3 + YSS UI + 实现仓 lockfile 的 Ant Design Vue 4.x。产出后必须记录 schema v2 原型证据并获得用户确认。
24
24
 
25
25
  这些资产用于反推 API 影响、契约草案、OpenAPI 请求 / 响应字段、错误结构、分页筛选、权限状态和前端验收标准。
26
26
 
@@ -36,7 +36,7 @@
36
36
  推荐技能:
37
37
 
38
38
  - `yss-design-system`:项目设计系统与 Ant Design 企业级 UI 风格基线;页面设计、原型评审、UI 实现和主题 token 落地时默认先引用。Codex `$design-qa` 的 token / 字体对照读该技能的 `references/design-qa-theme.md`,以项目覆盖为准,不改上游 `design-qa` 插件。
39
- - `yss-prototype-stage`:跨 Agent 的原型阶段合同,固定资产、证据、设计优先级与生命周期回流;Codex 的主路由为 `product-design:index`。
39
+ - `yss-prototype-stage`:跨 Agent 的原型阶段主合同,固定资产、证据、设计优先级与生命周期回流;其 `references/product-design-adapter.md` 把 Codex `product-design:index` 通用产出接入 YSS 双轨版本、项目主题和证据合同。
40
40
  - `product-design:index`:Codex 产品原型产出的主路由;根据输入是否有 URL、截图、Figma、代码目标或视觉方向,进入 `$get-context`、`$ideate`、`$prototype`、`$image-to-code`、`$url-to-code`、`$share` 或 `$design-qa` 等 focused skill。
41
41
  - Product Design focused skills:基于 Spec 初稿和产品总体设计 / 功能架构,产出低保真 / 高保真页面、原型、交互设计资产和可分享原型;高保真 HTML 原型默认由该路由链路产出。
42
42
  - `yss-antd-design`:仅用于原型设计构建的 Ant Design v6 事实技能;生成或修改高保真 HTML 原型前后必须留下 CLI 校验证据。前端代码落地改用 `yss-ui`。