create-yss-spec 2.1.4 → 2.1.5

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 (89) hide show
  1. package/package.json +1 -1
  2. package/template/.agents/skills/high-fidelity-html-prototype/SKILL.md +16 -12
  3. package/template/.agents/skills/product-design-prototype/SKILL.md +6 -2
  4. package/template/.agents/skills/prototype-review/SKILL.md +6 -2
  5. package/template/.agents/skills/wireframe-prototype/SKILL.md +5 -1
  6. package/template/.agents/skills/yss-design-system/SKILL.md +5 -4
  7. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +2 -2
  8. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +2 -2
  9. package/template/.agents/skills/yss-prototype-stage/SKILL.md +40 -0
  10. package/template/.agents/skills/yss-router/references/router-contract.yaml +5 -2
  11. package/template/.agents/skills/yss-router/references/slice-implementation-contract.md +3 -0
  12. package/template/.claude/skills/high-fidelity-html-prototype/SKILL.md +16 -12
  13. package/template/.claude/skills/product-design-prototype/SKILL.md +6 -2
  14. package/template/.claude/skills/prototype-review/SKILL.md +6 -2
  15. package/template/.claude/skills/wireframe-prototype/SKILL.md +5 -1
  16. package/template/.claude/skills/yss-design-system/SKILL.md +5 -4
  17. package/template/.claude/skills/yss-product-lifecycle/SKILL.md +2 -2
  18. package/template/.claude/skills/yss-product-lifecycle/references/orchestration-contract.yaml +2 -2
  19. package/template/.claude/skills/yss-prototype-stage/SKILL.md +40 -0
  20. package/template/.claude/skills/yss-router/references/router-contract.yaml +5 -2
  21. package/template/.claude/skills/yss-router/references/slice-implementation-contract.md +3 -0
  22. package/template/.codex/skills/high-fidelity-html-prototype/SKILL.md +16 -12
  23. package/template/.codex/skills/product-design-prototype/SKILL.md +6 -2
  24. package/template/.codex/skills/prototype-review/SKILL.md +6 -2
  25. package/template/.codex/skills/wireframe-prototype/SKILL.md +5 -1
  26. package/template/.codex/skills/yss-design-system/SKILL.md +5 -4
  27. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +2 -2
  28. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +2 -2
  29. package/template/.codex/skills/yss-prototype-stage/SKILL.md +40 -0
  30. package/template/.codex/skills/yss-router/references/router-contract.yaml +5 -2
  31. package/template/.codex/skills/yss-router/references/slice-implementation-contract.md +3 -0
  32. package/template/.hermes/skills/high-fidelity-html-prototype/SKILL.md +16 -12
  33. package/template/.hermes/skills/product-design-prototype/SKILL.md +6 -2
  34. package/template/.hermes/skills/prototype-review/SKILL.md +6 -2
  35. package/template/.hermes/skills/wireframe-prototype/SKILL.md +5 -1
  36. package/template/.hermes/skills/yss-design-system/SKILL.md +5 -4
  37. package/template/.hermes/skills/yss-product-lifecycle/SKILL.md +2 -2
  38. package/template/.hermes/skills/yss-product-lifecycle/references/orchestration-contract.yaml +2 -2
  39. package/template/.hermes/skills/yss-prototype-stage/SKILL.md +40 -0
  40. package/template/.hermes/skills/yss-router/references/router-contract.yaml +5 -2
  41. package/template/.hermes/skills/yss-router/references/slice-implementation-contract.md +3 -0
  42. package/template/.pi/skills/high-fidelity-html-prototype/SKILL.md +16 -12
  43. package/template/.pi/skills/product-design-prototype/SKILL.md +6 -2
  44. package/template/.pi/skills/prototype-review/SKILL.md +6 -2
  45. package/template/.pi/skills/wireframe-prototype/SKILL.md +5 -1
  46. package/template/.pi/skills/yss-design-system/SKILL.md +5 -4
  47. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +2 -2
  48. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +2 -2
  49. package/template/.pi/skills/yss-prototype-stage/SKILL.md +40 -0
  50. package/template/.pi/skills/yss-router/references/router-contract.yaml +5 -2
  51. package/template/.pi/skills/yss-router/references/slice-implementation-contract.md +3 -0
  52. package/template/.qoder/skills/high-fidelity-html-prototype/SKILL.md +16 -12
  53. package/template/.qoder/skills/product-design-prototype/SKILL.md +6 -2
  54. package/template/.qoder/skills/prototype-review/SKILL.md +6 -2
  55. package/template/.qoder/skills/wireframe-prototype/SKILL.md +5 -1
  56. package/template/.qoder/skills/yss-design-system/SKILL.md +5 -4
  57. package/template/.qoder/skills/yss-product-lifecycle/SKILL.md +2 -2
  58. package/template/.qoder/skills/yss-product-lifecycle/references/orchestration-contract.yaml +2 -2
  59. package/template/.qoder/skills/yss-prototype-stage/SKILL.md +40 -0
  60. package/template/.qoder/skills/yss-router/references/router-contract.yaml +5 -2
  61. package/template/.qoder/skills/yss-router/references/slice-implementation-contract.md +3 -0
  62. package/template/.trae/skills/high-fidelity-html-prototype/SKILL.md +16 -12
  63. package/template/.trae/skills/product-design-prototype/SKILL.md +6 -2
  64. package/template/.trae/skills/prototype-review/SKILL.md +6 -2
  65. package/template/.trae/skills/wireframe-prototype/SKILL.md +5 -1
  66. package/template/.trae/skills/yss-design-system/SKILL.md +5 -4
  67. package/template/.trae/skills/yss-product-lifecycle/SKILL.md +2 -2
  68. package/template/.trae/skills/yss-product-lifecycle/references/orchestration-contract.yaml +2 -2
  69. package/template/.trae/skills/yss-prototype-stage/SKILL.md +40 -0
  70. package/template/.trae/skills/yss-router/references/router-contract.yaml +5 -2
  71. package/template/.trae/skills/yss-router/references/slice-implementation-contract.md +3 -0
  72. package/template/AGENTS.md +1 -1
  73. package/template/docs/adr/0001-product-design-prototype-entrypoint.md +1 -1
  74. package/template/docs/design/README.md +4 -2
  75. package/template/docs/design/design.md +4 -0
  76. package/template/docs/design/templates/interaction-spec-template.md +3 -3
  77. package/template/docs/design/templates/prototype-confirmation-template.md +9 -6
  78. package/template/docs/design/templates/prototype-evidence-template.yaml +46 -0
  79. package/template/docs/design/templates/prototype-review-checklist.md +4 -4
  80. package/template/docs/process/lifecycle-artifact-map.md +10 -1
  81. package/template/docs/process/lifecycle-registry-baseline.json +10 -1
  82. package/template/docs/process/lifecycle-registry.yaml +35 -1
  83. package/template/scripts/test-export-yss-skills.rb +7 -5
  84. package/template/scripts/verify-lifecycle-scenarios +80 -7
  85. package/template/scripts/verify-prototype-backend-scaffold-scenarios +26 -4
  86. package/template/scripts/verify-yss-router-scenarios +9 -0
  87. package/template/skills-lock.json +22 -7
  88. package/template/yss-public-skills.json +2 -0
  89. package/template.snapshot.json +4 -4
@@ -57,6 +57,18 @@ evidence:
57
57
  - id: evidence.design-review-result
58
58
  name: 设计审查结果
59
59
  description: API、架构或产品设计审查意见及处理结果。
60
+ - id: evidence.prototype-review-result
61
+ name: 原型评审结果
62
+ description: 低保真页面、流程、状态与 API 反推的独立评审结论和阻断项。
63
+ - id: evidence.antd-cli-validation
64
+ name: Ant Design CLI 校验证据
65
+ description: 设计语言、组件、demo、token、semantic 与 lint 的实际 CLI/目标版本和可读输出引用。
66
+ - id: evidence.browser-prototype-verification
67
+ name: 浏览器原型验证证据
68
+ description: 高保真原型的非空渲染、主流程、异常状态、视口和控制台验证记录。
69
+ - id: evidence.prototype-confirmation
70
+ name: 原型用户确认记录
71
+ description: 高保真原型、验证清单和进入下游阶段范围的人工确认结论。
60
72
  - id: evidence.openapi-draft-review
61
73
  name: OpenAPI Draft 审查记录
62
74
  description: P0、错误、分页、幂等和契约测试审查记录。
@@ -84,11 +96,21 @@ gates:
84
96
  stage: stage.spec-architecture
85
97
  trigger: 新功能、行为变化或范围扩大进入 Spec 基线。
86
98
  evidence: [evidence.approval-record]
99
+ - id: gate.prototype-reviewed
100
+ name: 原型评审
101
+ stage: stage.product-design
102
+ trigger: 命中产品设计影响,且低保真页面、流程、状态或 API 反推需要独立评审。
103
+ evidence: [evidence.prototype-review-result]
104
+ - id: gate.prototype-verified
105
+ name: 高保真原型验证
106
+ stage: stage.product-design
107
+ trigger: 需要高保真 HTML 原型进行视觉与交互校准。
108
+ evidence: [evidence.antd-cli-validation, evidence.browser-prototype-verification]
87
109
  - id: gate.user-confirmation
88
110
  name: 用户确认
89
111
  stage: stage.product-design
90
112
  trigger: 产品设计影响尚未被人工确认。
91
- evidence: [evidence.approval-record]
113
+ evidence: [evidence.prototype-confirmation]
92
114
  - id: gate.openapi-draft-reviewed
93
115
  name: OpenAPI Draft Review
94
116
  stage: stage.system-data-engineering
@@ -151,6 +173,10 @@ artifacts:
151
173
  name: 功能架构
152
174
  stage: stage.spec-architecture
153
175
  trigger: 新模块或跨边界变化。
176
+ - id: artifact.interaction-spec
177
+ name: 交互说明
178
+ stage: stage.product-design
179
+ trigger: 命中产品设计影响。
154
180
  - id: artifact.low-fidelity-prototype
155
181
  name: 低保真原型
156
182
  stage: stage.product-design
@@ -163,6 +189,14 @@ artifacts:
163
189
  name: 高保真 HTML 原型
164
190
  stage: stage.product-design
165
191
  trigger: 需要视觉与交互校准。
192
+ - id: artifact.prototype-review
193
+ name: 原型评审记录
194
+ stage: stage.product-design
195
+ trigger: 命中 gate.prototype-reviewed。
196
+ - id: artifact.prototype-confirmation
197
+ name: 原型确认记录
198
+ stage: stage.product-design
199
+ trigger: 命中 gate.user-confirmation。
166
200
  - id: artifact.openapi-draft
167
201
  name: OpenAPI Draft
168
202
  stage: stage.system-data-engineering
@@ -32,19 +32,21 @@ class ExportYssSkillsTest < Minitest::Test
32
32
  stdout, stderr, result = run_export(output)
33
33
 
34
34
  assert result.success?, "#{stdout}\n#{stderr}"
35
- assert_equal 44, Dir.glob(output.join("skills", "*").to_s).count { |path| File.directory?(path) }
35
+ assert_equal 45, Dir.glob(output.join("skills", "*").to_s).count { |path| File.directory?(path) }
36
36
 
37
37
  manifest = JSON.parse(output.join(".yss-export-manifest.json").read)
38
- assert_equal 44, manifest.fetch("skills").length
39
- assert_operator manifest.fetch("generated_files_sha256").length, :>, 44
38
+ assert_equal 45, manifest.fetch("skills").length
39
+ assert_operator manifest.fetch("generated_files_sha256").length, :>, 45
40
+ assert output.join("skills", "yss-prototype-stage", "SKILL.md").file?, "prototype stage contract was not exported"
40
41
  REMOVED_SKILLS.each do |skill_name|
41
42
  refute output.join("skills", skill_name).exist?, "removed skill was exported: #{skill_name}"
42
43
  end
43
44
 
44
45
  page = JSON.parse(output.join("skills.sh.json").read)
45
46
  grouped = page.fetch("groupings").flat_map { |group| group.fetch("skills") }
46
- assert_equal 44, grouped.uniq.length
47
- assert_equal 44, grouped.length
47
+ assert_equal 45, grouped.uniq.length
48
+ assert_equal 45, grouped.length
49
+ assert_includes grouped, "yss-prototype-stage"
48
50
 
49
51
  exported_text = Dir.glob(output.join("skills", "**", "*").to_s)
50
52
  .select { |path| File.file?(path) }
@@ -25,9 +25,12 @@ ROUTE_REGISTRY_IDS = {
25
25
  "spec" => "artifact.spec",
26
26
  "product-overview" => "artifact.product-overview",
27
27
  "functional-architecture" => "artifact.functional-architecture",
28
+ "interaction-spec" => "artifact.interaction-spec",
28
29
  "low-fidelity-prototype" => "artifact.low-fidelity-prototype",
29
30
  "state-matrix" => "artifact.state-matrix",
31
+ "prototype-review" => "gate.prototype-reviewed",
30
32
  "high-fidelity-html-prototype" => "artifact.high-fidelity-html-prototype",
33
+ "prototype-verification" => "gate.prototype-verified",
31
34
  "user-confirmation" => "gate.user-confirmation",
32
35
  "openapi-draft" => "artifact.openapi-draft",
33
36
  "draft-review" => "gate.openapi-draft-reviewed",
@@ -63,9 +66,12 @@ def route(facts)
63
66
 
64
67
  if facts.fetch(:ui_impact)
65
68
  gates.concat(%w[
69
+ interaction-spec
66
70
  low-fidelity-prototype
67
71
  state-matrix
72
+ prototype-review
68
73
  high-fidelity-html-prototype
74
+ prototype-verification
69
75
  user-confirmation
70
76
  ])
71
77
  end
@@ -91,7 +97,7 @@ scenarios = [
91
97
  data_impact: false, existing_frozen_baseline: true
92
98
  },
93
99
  required: %w[impact-assessment tracker-sync fresh-verification],
94
- forbidden: %w[spec product-overview spec-delta high-fidelity-html-prototype]
100
+ forbidden: %w[spec product-overview spec-delta interaction-spec high-fidelity-html-prototype prototype-review prototype-verification]
95
101
  },
96
102
  {
97
103
  name: "纯后端新功能",
@@ -101,7 +107,7 @@ scenarios = [
101
107
  data_impact: false, existing_frozen_baseline: false
102
108
  },
103
109
  required: %w[spec product-overview functional-architecture openapi-draft engineering-baseline parent-ticket vertical-slice-tickets],
104
- forbidden: %w[low-fidelity-prototype state-matrix high-fidelity-html-prototype user-confirmation spec-delta]
110
+ forbidden: %w[interaction-spec low-fidelity-prototype state-matrix prototype-review high-fidelity-html-prototype prototype-verification user-confirmation spec-delta]
105
111
  },
106
112
  {
107
113
  name: "普通 API 功能无需专项输入",
@@ -111,7 +117,7 @@ scenarios = [
111
117
  data_impact: false, existing_frozen_baseline: false
112
118
  },
113
119
  required: %w[spec product-overview functional-architecture openapi-draft draft-review openapi-freeze engineering-baseline parent-ticket vertical-slice-tickets],
114
- forbidden: %w[low-fidelity-prototype state-matrix high-fidelity-html-prototype user-confirmation spec-delta]
120
+ forbidden: %w[interaction-spec low-fidelity-prototype state-matrix prototype-review high-fidelity-html-prototype prototype-verification user-confirmation spec-delta]
115
121
  },
116
122
  {
117
123
  name: "有 UI 的新功能",
@@ -120,7 +126,7 @@ scenarios = [
120
126
  ui_impact: true, api_impact: true, backend_impact: true,
121
127
  data_impact: false, existing_frozen_baseline: false
122
128
  },
123
- required: %w[spec product-overview low-fidelity-prototype state-matrix high-fidelity-html-prototype user-confirmation openapi-freeze vertical-slice-tickets],
129
+ required: %w[spec product-overview interaction-spec low-fidelity-prototype state-matrix prototype-review high-fidelity-html-prototype prototype-verification user-confirmation openapi-freeze vertical-slice-tickets],
124
130
  forbidden: %w[spec-delta]
125
131
  },
126
132
  {
@@ -131,7 +137,7 @@ scenarios = [
131
137
  data_impact: true, existing_frozen_baseline: true
132
138
  },
133
139
  required: %w[spec product-overview spec-delta openapi-draft data-architecture architecture-review vertical-slice-tickets],
134
- forbidden: %w[high-fidelity-html-prototype]
140
+ forbidden: %w[interaction-spec prototype-review high-fidelity-html-prototype prototype-verification]
135
141
  },
136
142
  {
137
143
  name: "模板源流程修订",
@@ -162,6 +168,32 @@ route_keys.each do |route_key|
162
168
  failures << "生命周期场景 route key 映射到不存在的稳定 ID: #{route_key} -> #{registry_id}" if registry_id && !REGISTRY_IDS.include?(registry_id)
163
169
  end
164
170
 
171
+ prototype_registry_requirements = {
172
+ "gate.prototype-reviewed" => ["evidence.prototype-review-result"],
173
+ "gate.prototype-verified" => ["evidence.antd-cli-validation", "evidence.browser-prototype-verification"],
174
+ "gate.user-confirmation" => ["evidence.prototype-confirmation"]
175
+ }.freeze
176
+ prototype_registry_requirements.each do |gate_id, required_evidence|
177
+ gate = REGISTRY.fetch("gates").find { |record| record.fetch("id") == gate_id }
178
+ failures << "原型阶段缺少生命周期门禁: #{gate_id}" unless gate
179
+ next unless gate
180
+
181
+ missing_evidence = required_evidence - gate.fetch("evidence", [])
182
+ failures << "#{gate_id} 缺少证据: #{missing_evidence.join(', ')}" unless missing_evidence.empty?
183
+ end
184
+
185
+ %w[
186
+ artifact.interaction-spec
187
+ artifact.prototype-review
188
+ artifact.prototype-confirmation
189
+ evidence.prototype-review-result
190
+ evidence.antd-cli-validation
191
+ evidence.browser-prototype-verification
192
+ evidence.prototype-confirmation
193
+ ].each do |stable_id|
194
+ failures << "原型阶段缺少生命周期对象: #{stable_id}" unless REGISTRY_IDS.include?(stable_id)
195
+ end
196
+
165
197
  semantic_markers = {
166
198
  "AGENTS.md" => [
167
199
  "生命周期注册表中的条件门禁全部按影响面强制",
@@ -334,6 +366,47 @@ unless prototype_review.include?("isolated visual fixes") && prototype_review.in
334
366
  failures << "prototype-review 未排除无行为影响的局部视觉改动"
335
367
  end
336
368
 
369
+ yss_design_system = ROOT.join(".agents/skills/yss-design-system/SKILL.md").read
370
+ failures << "yss-design-system 未将 product-design:index 声明为原型主入口" unless yss_design_system.include?("product-design:index")
371
+ failures << "yss-design-system 未路由统一原型阶段契约" unless yss_design_system.include?("yss-prototype-stage")
372
+
373
+ %w[product-design-prototype wireframe-prototype high-fidelity-html-prototype].each do |skill_name|
374
+ body = ROOT.join(".agents/skills/#{skill_name}/SKILL.md").read
375
+ failures << "#{skill_name} 未降为兼容入口" unless body.include?("兼容入口") && body.include?("yss-prototype-stage")
376
+ end
377
+
378
+ high_fidelity = ROOT.join(".agents/skills/high-fidelity-html-prototype/SKILL.md").read
379
+ failures << "高保真原型仍固定 AntD CLI 版本" if high_fidelity.include?("@ant-design/cli@6.5.0")
380
+ failures << "高保真原型仍以 npm view 代替受控 AntD CLI 证据" if high_fidelity.include?("npm view antd version")
381
+
382
+ confirmation_template = ROOT.join("docs/design/templates/prototype-confirmation-template.md").read
383
+ failures << "原型确认模板仍固定 AntD 版本" if confirmation_template.include?("--version 6.0.0")
384
+ failures << "原型确认模板未引用统一证据清单" unless confirmation_template.include?("prototype-evidence.yaml")
385
+
386
+ evidence_template_path = ROOT.join("docs/design/templates/prototype-evidence-template.yaml")
387
+ failures << "缺少机器可读的原型证据模板" unless evidence_template_path.file?
388
+ if evidence_template_path.file?
389
+ evidence_template = evidence_template_path.read
390
+ %w[design_baseline antd browser_verification review user_confirmation].each do |field|
391
+ failures << "原型证据模板缺少 #{field}" unless evidence_template.include?("#{field}:")
392
+ end
393
+ end
394
+
395
+ prototype_stage_path = ROOT.join(".agents/skills/yss-prototype-stage/SKILL.md")
396
+ failures << "缺少跨 Agent 原型阶段契约" unless prototype_stage_path.file?
397
+ if prototype_stage_path.file?
398
+ prototype_stage = prototype_stage_path.read
399
+ %w[product-design:index antd design.md project_design browser_verification].each do |marker|
400
+ failures << "统一原型阶段契约缺少 #{marker}" unless prototype_stage.include?(marker)
401
+ end
402
+ end
403
+
404
+ design_baseline = ROOT.join("docs/design/design.md").read
405
+ failures << "项目设计基线未声明上游 design.md 与项目 token 的优先级" unless design_baseline.include?("上游默认") && design_baseline.include?("项目覆盖")
406
+
407
+ adr = ROOT.join("docs/adr/0001-product-design-prototype-entrypoint.md").read
408
+ failures << "ADR 仍引用不存在的原型流程文档" if adr.include?("docs/process/product-prototype-workflow.md")
409
+
337
410
  openapi_review = ROOT.join(".agents/skills/yss-openapi-draft-review/SKILL.md").read
338
411
  %w[Automated semantic unchanged].each do |marker|
339
412
  failures << "OpenAPI Draft Review 缺少自动/语义边界: #{marker}" unless openapi_review.include?(marker)
@@ -431,14 +504,14 @@ failures << "Matt prototype 分支模式错误" unless matt_prototype["branch_pa
431
504
  failures << "Matt prototype 不能作为生产交付物" unless matt_prototype["production_delivery"] == false
432
505
  failures << "Matt prototype 错误替代 YSS 高保真原型" unless matt_prototype["replaces_yss_high_fidelity"] == false
433
506
  yss_prototype = prototype_modes.fetch("yss_high_fidelity", {})
434
- %w[prototype_review antd_cli_verification user_confirmation].each do |field|
507
+ %w[prototype_review antd_cli_verification browser_verification prototype_evidence user_confirmation].each do |field|
435
508
  failures << "YSS 高保真 prototype 缺少 #{field} 门禁" unless yss_prototype.fetch("required", []).include?(field)
436
509
  end
437
510
  failures << "YSS 高保真 prototype 错误替代 Matt prototype" unless yss_prototype["replaces_matt_logic"] == false
438
511
 
439
512
  prototype_mode_requirements = {
440
513
  "matt_logic" => %w[prototype_mode prototype_branch source_handoff prototype_asset_or_run conclusion updated_authoritative_asset remaining_questions return_handoff],
441
- "yss_high_fidelity" => %w[prototype_mode prototype_review antd_cli_verification user_confirmation]
514
+ "yss_high_fidelity" => %w[prototype_mode prototype_review antd_cli_verification browser_verification prototype_evidence user_confirmation]
442
515
  }.freeze
443
516
  prototype_mode_requirements.each do |mode, required_fields|
444
517
  evidence = required_fields.to_h { |field| [field, true] }.merge("prototype_mode" => mode)
@@ -16,8 +16,16 @@ end
16
16
  def route_after_prototype(facts)
17
17
  return {"status" => "not-applicable", "steps" => []} unless facts.fetch(:backend_impact)
18
18
 
19
- if facts.fetch(:ui_impact) && !facts.fetch(:prototype_confirmation)
20
- return {"status" => "blocked", "reason" => "prototype-confirmation-required", "steps" => []}
19
+ if facts.fetch(:ui_impact)
20
+ {
21
+ prototype_review: "prototype-review-required",
22
+ prototype_verification: "prototype-verification-required",
23
+ antd_cli_verification: "antd-cli-verification-required",
24
+ browser_verification: "browser-verification-required",
25
+ prototype_confirmation: "prototype-confirmation-required"
26
+ }.each do |fact, reason|
27
+ return {"status" => "blocked", "reason" => reason, "steps" => []} unless facts.fetch(fact, false)
28
+ end
21
29
  end
22
30
 
23
31
  steps = ["engineering-baseline"]
@@ -74,7 +82,9 @@ if backend_scaffold.is_a?(Hash)
74
82
  %w[approval_ref approver persisted_ref current_version].each do |required|
75
83
  failures << "脚手架合同审批记录缺少 #{required}" unless scaffold_schema.dig("approval", "required").to_a.include?(required)
76
84
  end
77
- failures << "backend_scaffold 必须声明 prototype_confirmation 后置顺序" unless backend_scaffold.dig("sequence", "after").include?("prototype_confirmation")
85
+ %w[prototype_review prototype_verification antd_cli_verification browser_verification prototype_confirmation].each do |required|
86
+ failures << "backend_scaffold 必须声明 #{required} 后置顺序" unless backend_scaffold.dig("sequence", "after").include?(required)
87
+ end
78
88
  failures << "backend_scaffold 必须先于业务代码生成" unless backend_scaffold.dig("sequence", "before").include?("business_code_generation")
79
89
  failures << "required 脚手架必须使用 yss-ddd-scaffold-generator" unless backend_scaffold["generator_skill"] == "yss-ddd-scaffold-generator"
80
90
  failures << "脚手架生成必须使用 controlled-generation" unless backend_scaffold["tdd_mode"] == "controlled-generation"
@@ -146,7 +156,9 @@ if router_scaffold_schema.is_a?(Hash)
146
156
  end
147
157
 
148
158
  complete_facts = {
149
- backend_impact: true, ui_impact: true, prototype_confirmation: true, scaffold_status: "required", scaffold_contract_approved: true
159
+ backend_impact: true, ui_impact: true, prototype_review: true, prototype_verification: true,
160
+ antd_cli_verification: true, browser_verification: true, prototype_confirmation: true,
161
+ scaffold_status: "required", scaffold_contract_approved: true
150
162
  }
151
163
  complete_route = route_after_prototype(complete_facts)
152
164
  expected_steps = %w[engineering-baseline yss-router-scaffold-contract lifecycle-approve-scaffold-contract yss-ddd-scaffold-generator yss-backend-scaffold-parent yss-router-contract-recompile]
@@ -155,6 +167,16 @@ failures << "原型完成后的后端路由顺序不完整" unless complete_rout
155
167
  blocked_route = route_after_prototype(complete_facts.merge(prototype_confirmation: false))
156
168
  failures << "原型未确认时错误允许后端脚手架" unless blocked_route["status"] == "blocked" && blocked_route["reason"] == "prototype-confirmation-required"
157
169
 
170
+ {
171
+ prototype_review: "prototype-review-required",
172
+ prototype_verification: "prototype-verification-required",
173
+ antd_cli_verification: "antd-cli-verification-required",
174
+ browser_verification: "browser-verification-required"
175
+ }.each do |missing_fact, reason|
176
+ blocked = route_after_prototype(complete_facts.merge(missing_fact => false))
177
+ failures << "#{missing_fact} 缺失时错误允许后端脚手架" unless blocked["status"] == "blocked" && blocked["reason"] == reason
178
+ end
179
+
158
180
  missing_scaffold_contract = route_after_prototype(complete_facts.merge(scaffold_contract_approved: false))
159
181
  failures << "脚手架受控生成缺少批准合同仍被允许" unless missing_scaffold_contract["status"] == "blocked" && missing_scaffold_contract["reason"] == "scaffold-contract-required"
160
182
 
@@ -77,11 +77,20 @@ api_ready = CONTRACT.dig("readiness", "api_impact").to_h { |key| [key, true] }
77
77
  all_ui = common_ready.merge(ui_ready).merge(api_ready)
78
78
  failures << "Approved UI inputs were blocked" unless readiness_missing(CONTRACT, %w[ui_impact api_impact], all_ui).empty?
79
79
 
80
+ %w[prototype_review prototype_verification antd_cli_evidence browser_verification_evidence prototype_confirmation].each do |field|
81
+ failures << "Router UI readiness 缺少 #{field}" unless CONTRACT.dig("readiness", "ui_impact").include?(field)
82
+ end
83
+
80
84
  ui_without_confirmation = all_ui.merge("prototype_confirmation" => false)
81
85
  unless readiness_missing(CONTRACT, %w[ui_impact api_impact], ui_without_confirmation).include?("prototype_confirmation")
82
86
  failures << "UI implementation was not blocked without prototype confirmation"
83
87
  end
84
88
 
89
+ ui_without_browser_evidence = all_ui.merge("browser_verification_evidence" => false)
90
+ unless readiness_missing(CONTRACT, %w[ui_impact api_impact], ui_without_browser_evidence).include?("browser_verification_evidence")
91
+ failures << "UI implementation was not blocked without browser verification evidence"
92
+ end
93
+
85
94
  data_ready = common_ready.merge(CONTRACT.dig("readiness", "data_impact").to_h { |key| [key, true] })
86
95
  data_missing = data_ready.merge("data_architecture" => false)
87
96
  unless readiness_missing(CONTRACT, %w[data_impact], data_missing).include?("data_architecture")
@@ -328,7 +328,7 @@
328
328
  "source": "project",
329
329
  "sourceType": "local",
330
330
  "skillPath": ".agents/skills/high-fidelity-html-prototype/SKILL.md",
331
- "effectiveHash": "e6de720a81d38e75a96ee30b3b8443ff1df0fd94f99a2dc512dee2348c7ab6be",
331
+ "effectiveHash": "9cde0608db48293eb0c0784a4283a41ba582aabdc2ef9f77dc1606492d333eda",
332
332
  "targets": [
333
333
  ".agents/skills",
334
334
  ".claude/skills",
@@ -469,7 +469,7 @@
469
469
  "source": "project",
470
470
  "sourceType": "local",
471
471
  "skillPath": ".agents/skills/product-design-prototype/SKILL.md",
472
- "effectiveHash": "ca8a5c4dbd8b75ebf6febcf1887d6b51bf7daa953b505694dac01fd59aef2f1a",
472
+ "effectiveHash": "cd8f600b5fde968244186e365e6533c1b6edbd8e3726d3d2d3e38b8056457d7f",
473
473
  "targets": [
474
474
  ".agents/skills",
475
475
  ".claude/skills",
@@ -500,7 +500,7 @@
500
500
  "source": "project",
501
501
  "sourceType": "local",
502
502
  "skillPath": ".agents/skills/prototype-review/SKILL.md",
503
- "effectiveHash": "3c5973fab1fabafe32d852e63629e0bf13cc38769728fe2037595525a8dfa9e5",
503
+ "effectiveHash": "5502cd1617734eaf50b6aaa26ced6d5dfe60b5ef552ea81cdfb7150a9d3008d0",
504
504
  "targets": [
505
505
  ".agents/skills",
506
506
  ".claude/skills",
@@ -784,7 +784,7 @@
784
784
  "source": "project",
785
785
  "sourceType": "local",
786
786
  "skillPath": ".agents/skills/wireframe-prototype/SKILL.md",
787
- "effectiveHash": "aa1d29a77ad5104ca67cf796ddfeaeccc3b3ea669697557b55c283f42c6cdc11",
787
+ "effectiveHash": "200e1a34cc4de1f6a9f6a8e31e66c123568e804183d6661ee0c164086f88a88e",
788
788
  "targets": [
789
789
  ".agents/skills",
790
790
  ".claude/skills",
@@ -1044,7 +1044,7 @@
1044
1044
  "source": "project",
1045
1045
  "sourceType": "local",
1046
1046
  "skillPath": ".agents/skills/yss-design-system/SKILL.md",
1047
- "effectiveHash": "b8bde50efcd0226b7bbdfd830e738a3cdb4d74d135e1b2af8715057d1557a9b0",
1047
+ "effectiveHash": "0cf7028c716b33c6a4b376f8bc6d17708854c0e6b9c460fc60cfa3865be63ce5",
1048
1048
  "targets": [
1049
1049
  ".agents/skills",
1050
1050
  ".claude/skills",
@@ -1314,7 +1314,22 @@
1314
1314
  "source": "project",
1315
1315
  "sourceType": "local",
1316
1316
  "skillPath": ".agents/skills/yss-product-lifecycle/SKILL.md",
1317
- "effectiveHash": "b048cd8d1c9ab5d4d3f10e5c0a391b983a05f0c6075a710e086b093607f7f391",
1317
+ "effectiveHash": "1bdf5769a237d6a95bec19dc2ce5790ae052b164c79c9520373bacf9c7b28d0e",
1318
+ "targets": [
1319
+ ".agents/skills",
1320
+ ".claude/skills",
1321
+ ".codex/skills",
1322
+ ".hermes/skills",
1323
+ ".pi/skills",
1324
+ ".qoder/skills",
1325
+ ".trae/skills"
1326
+ ]
1327
+ },
1328
+ "yss-prototype-stage": {
1329
+ "source": "project",
1330
+ "sourceType": "local",
1331
+ "skillPath": ".agents/skills/yss-prototype-stage/SKILL.md",
1332
+ "effectiveHash": "38d4bb83e7a3bf104c11d99e4a8cad9f2094fb29da51f32b0e9a66ebcbe16d03",
1318
1333
  "targets": [
1319
1334
  ".agents/skills",
1320
1335
  ".claude/skills",
@@ -1359,7 +1374,7 @@
1359
1374
  "source": "project",
1360
1375
  "sourceType": "local",
1361
1376
  "skillPath": ".agents/skills/yss-router/SKILL.md",
1362
- "effectiveHash": "14e111cbc36e0be6aee67358f580f20b917bf213ea5994acaa0f7f32340e9567",
1377
+ "effectiveHash": "315788ec2c1fcca6f577fa3f83bf0e848404031c5691fd2ba8058ba25fcd0c14",
1363
1378
  "targets": [
1364
1379
  ".agents/skills",
1365
1380
  ".claude/skills",
@@ -32,6 +32,7 @@
32
32
  "yss-openapi-governance",
33
33
  "yss-page-module-development",
34
34
  "yss-product-lifecycle",
35
+ "yss-prototype-stage",
35
36
  "yss-repository",
36
37
  "yss-resilience4j",
37
38
  "yss-router",
@@ -88,6 +89,7 @@
88
89
  "yss-frontend-scaffold-generator",
89
90
  "yss-hook",
90
91
  "yss-page-module-development",
92
+ "yss-prototype-stage",
91
93
  "yss-ui",
92
94
  "yss-use-table-height",
93
95
  "yss-use-tree-height"
@@ -3,8 +3,8 @@
3
3
  "templateName": "yss-spec-project-template",
4
4
  "templateSource": "github:iloveZzz/yss-spec-project-template",
5
5
  "templateRepository": "https://github.com/iloveZzz/yss-spec-project-template.git",
6
- "requestedRef": "b6e005a538daae46309daaf9ade7ce8dc6bb93a7",
7
- "templateCommit": "b6e005a538daae46309daaf9ade7ce8dc6bb93a7",
6
+ "requestedRef": "4c2208e2de255f60a8d1a9eee87ac7ff5a8d4b83",
7
+ "templateCommit": "4c2208e2de255f60a8d1a9eee87ac7ff5a8d4b83",
8
8
  "encodedPaths": {
9
9
  ".agents/skills/beautiful-article/assets/scaffold-template/.npmrc": ".agents/skills/beautiful-article/assets/scaffold-template/__yss_dotfile__.npmrc",
10
10
  ".agents/skills/drawio-academic-skills/.gitignore": ".agents/skills/drawio-academic-skills/__yss_dotfile__.gitignore",
@@ -32,6 +32,6 @@
32
32
  ".trae/skills/drawio-academic-skills/.gitignore": ".trae/skills/drawio-academic-skills/__yss_dotfile__.gitignore",
33
33
  ".trae/skills/excalidraw-diagram-generator/scripts/.gitignore": ".trae/skills/excalidraw-diagram-generator/scripts/__yss_dotfile__.gitignore"
34
34
  },
35
- "snapshotHash": "067f8feda878be6e69e94e7248e34afa3c099234ad7009da0c49aefc03265366",
36
- "generatedAt": "2026-08-16T18:16:16.070Z"
35
+ "snapshotHash": "cd2aacc6f0905ab75bf5a8556ab7062d14b45a40d68557fc0c6296cf844369aa",
36
+ "generatedAt": "2026-08-17T05:59:06.142Z"
37
37
  }