create-yss-spec 3.3.4 → 3.3.7

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 (171) hide show
  1. package/README.md +2 -2
  2. package/package.json +1 -1
  3. package/src/template/instance-runtime.js +8 -2
  4. package/src/validation/snapshot.js +7 -0
  5. package/template/.agents/skills/.strategic-design-skills-manifest.json +7 -5
  6. package/template/.agents/skills/archify/SKILL.md +1 -1
  7. package/template/.agents/skills/code-review/SKILL.md +6 -0
  8. package/template/.agents/skills/i-have-adhd/LICENSE +21 -0
  9. package/template/.agents/skills/i-have-adhd/SKILL.md +26 -0
  10. package/template/.agents/skills/i-have-adhd/agents/openai.yaml +6 -0
  11. package/template/.agents/skills/i-have-adhd/references/yss-adaptation.md +21 -0
  12. package/template/.agents/skills/i-have-adhd/tests/verify-integration.mjs +63 -0
  13. package/template/.agents/skills/prototype-review/SKILL.md +2 -0
  14. package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +6 -0
  15. package/template/.agents/skills/yss-implementation-contract-compiler/references/boundaries.md +10 -0
  16. package/template/.agents/skills/yss-openapi-governance/SKILL.md +6 -0
  17. package/template/.agents/skills/yss-product-lifecycle/SKILL.md +3 -1
  18. package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +12 -0
  19. package/template/.agents/skills/yss-prototype-stage/SKILL.md +6 -0
  20. package/template/.agents/skills/yss-research/SKILL.md +6 -0
  21. package/template/.agents/skills/yss-stage-decision/SKILL.md +19 -4
  22. package/template/.agents/skills/yss-stage-decision/references/domain-strategy-contract.md +4 -3
  23. package/template/.agents/skills/yss-stage-decision/references/domain-strategy-v2.schema.json +8 -0
  24. package/template/.agents/skills/yss-stage-decision/references/domain-strategy-v3.schema.json +8 -0
  25. package/template/.agents/skills/yss-stage-decision/references/domain-strategy.schema.json +75 -5
  26. package/template/.agents/skills/yss-stage-decision/references/stage-decision-package-contract.md +4 -4
  27. package/template/.agents/skills/yss-stage-decision/references/stage-decision-package-v2.schema.json +8 -0
  28. package/template/.agents/skills/yss-stage-decision/references/stage-decision-package-v3.schema.json +8 -0
  29. package/template/.agents/skills/yss-stage-decision/references/stage-decision-package.schema.json +59 -9
  30. package/template/.agents/skills/yss-stage-decision/references/validation-rules.md +2 -2
  31. package/template/.agents/skills/yss-stage-decision/scripts/migrate-contract-v3.mjs +143 -0
  32. package/template/.agents/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +46 -4
  33. package/template/.agents/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +48 -4
  34. package/template/.agents/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +42 -13
  35. package/template/.agents/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +37 -5
  36. package/template/.agents/skills/yss-stage-decision/tests/run-scenarios.mjs +116 -23
  37. package/template/.agents/skills/yss-technical-design/SKILL.md +6 -0
  38. package/template/.codex/skills/archify/SKILL.md +1 -1
  39. package/template/.codex/skills/code-review/SKILL.md +6 -0
  40. package/template/.codex/skills/i-have-adhd/LICENSE +21 -0
  41. package/template/.codex/skills/i-have-adhd/SKILL.md +26 -0
  42. package/template/.codex/skills/i-have-adhd/agents/openai.yaml +6 -0
  43. package/template/.codex/skills/i-have-adhd/references/yss-adaptation.md +21 -0
  44. package/template/.codex/skills/i-have-adhd/tests/verify-integration.mjs +63 -0
  45. package/template/.codex/skills/prototype-review/SKILL.md +2 -0
  46. package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +6 -0
  47. package/template/.codex/skills/yss-implementation-contract-compiler/references/boundaries.md +10 -0
  48. package/template/.codex/skills/yss-openapi-governance/SKILL.md +6 -0
  49. package/template/.codex/skills/yss-product-lifecycle/SKILL.md +3 -1
  50. package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +12 -0
  51. package/template/.codex/skills/yss-prototype-stage/SKILL.md +6 -0
  52. package/template/.codex/skills/yss-research/SKILL.md +6 -0
  53. package/template/.codex/skills/yss-stage-decision/SKILL.md +19 -4
  54. package/template/.codex/skills/yss-stage-decision/references/domain-strategy-contract.md +4 -3
  55. package/template/.codex/skills/yss-stage-decision/references/domain-strategy-v2.schema.json +8 -0
  56. package/template/.codex/skills/yss-stage-decision/references/domain-strategy-v3.schema.json +8 -0
  57. package/template/.codex/skills/yss-stage-decision/references/domain-strategy.schema.json +75 -5
  58. package/template/.codex/skills/yss-stage-decision/references/stage-decision-package-contract.md +4 -4
  59. package/template/.codex/skills/yss-stage-decision/references/stage-decision-package-v2.schema.json +8 -0
  60. package/template/.codex/skills/yss-stage-decision/references/stage-decision-package-v3.schema.json +8 -0
  61. package/template/.codex/skills/yss-stage-decision/references/stage-decision-package.schema.json +59 -9
  62. package/template/.codex/skills/yss-stage-decision/references/validation-rules.md +2 -2
  63. package/template/.codex/skills/yss-stage-decision/scripts/migrate-contract-v3.mjs +143 -0
  64. package/template/.codex/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +46 -4
  65. package/template/.codex/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +48 -4
  66. package/template/.codex/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +42 -13
  67. package/template/.codex/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +37 -5
  68. package/template/.codex/skills/yss-stage-decision/tests/run-scenarios.mjs +116 -23
  69. package/template/.codex/skills/yss-technical-design/SKILL.md +6 -0
  70. package/template/.cursor/skills/archify/SKILL.md +1 -1
  71. package/template/.cursor/skills/code-review/SKILL.md +6 -0
  72. package/template/.cursor/skills/i-have-adhd/LICENSE +21 -0
  73. package/template/.cursor/skills/i-have-adhd/SKILL.md +26 -0
  74. package/template/.cursor/skills/i-have-adhd/agents/openai.yaml +6 -0
  75. package/template/.cursor/skills/i-have-adhd/references/yss-adaptation.md +21 -0
  76. package/template/.cursor/skills/i-have-adhd/tests/verify-integration.mjs +63 -0
  77. package/template/.cursor/skills/prototype-review/SKILL.md +2 -0
  78. package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +6 -0
  79. package/template/.cursor/skills/yss-implementation-contract-compiler/references/boundaries.md +10 -0
  80. package/template/.cursor/skills/yss-openapi-governance/SKILL.md +6 -0
  81. package/template/.cursor/skills/yss-product-lifecycle/SKILL.md +3 -1
  82. package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +12 -0
  83. package/template/.cursor/skills/yss-prototype-stage/SKILL.md +6 -0
  84. package/template/.cursor/skills/yss-research/SKILL.md +6 -0
  85. package/template/.cursor/skills/yss-stage-decision/SKILL.md +19 -4
  86. package/template/.cursor/skills/yss-stage-decision/references/domain-strategy-contract.md +4 -3
  87. package/template/.cursor/skills/yss-stage-decision/references/domain-strategy-v2.schema.json +8 -0
  88. package/template/.cursor/skills/yss-stage-decision/references/domain-strategy-v3.schema.json +8 -0
  89. package/template/.cursor/skills/yss-stage-decision/references/domain-strategy.schema.json +75 -5
  90. package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package-contract.md +4 -4
  91. package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package-v2.schema.json +8 -0
  92. package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package-v3.schema.json +8 -0
  93. package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package.schema.json +59 -9
  94. package/template/.cursor/skills/yss-stage-decision/references/validation-rules.md +2 -2
  95. package/template/.cursor/skills/yss-stage-decision/scripts/migrate-contract-v3.mjs +143 -0
  96. package/template/.cursor/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +46 -4
  97. package/template/.cursor/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +48 -4
  98. package/template/.cursor/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +42 -13
  99. package/template/.cursor/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +37 -5
  100. package/template/.cursor/skills/yss-stage-decision/tests/run-scenarios.mjs +116 -23
  101. package/template/.cursor/skills/yss-technical-design/SKILL.md +6 -0
  102. package/template/.pi/skills/archify/SKILL.md +1 -1
  103. package/template/.pi/skills/code-review/SKILL.md +6 -0
  104. package/template/.pi/skills/i-have-adhd/LICENSE +21 -0
  105. package/template/.pi/skills/i-have-adhd/SKILL.md +26 -0
  106. package/template/.pi/skills/i-have-adhd/agents/openai.yaml +6 -0
  107. package/template/.pi/skills/i-have-adhd/references/yss-adaptation.md +21 -0
  108. package/template/.pi/skills/i-have-adhd/tests/verify-integration.mjs +63 -0
  109. package/template/.pi/skills/prototype-review/SKILL.md +2 -0
  110. package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +6 -0
  111. package/template/.pi/skills/yss-implementation-contract-compiler/references/boundaries.md +10 -0
  112. package/template/.pi/skills/yss-openapi-governance/SKILL.md +6 -0
  113. package/template/.pi/skills/yss-product-lifecycle/SKILL.md +3 -1
  114. package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +12 -0
  115. package/template/.pi/skills/yss-prototype-stage/SKILL.md +6 -0
  116. package/template/.pi/skills/yss-research/SKILL.md +6 -0
  117. package/template/.pi/skills/yss-stage-decision/SKILL.md +19 -4
  118. package/template/.pi/skills/yss-stage-decision/references/domain-strategy-contract.md +4 -3
  119. package/template/.pi/skills/yss-stage-decision/references/domain-strategy-v2.schema.json +8 -0
  120. package/template/.pi/skills/yss-stage-decision/references/domain-strategy-v3.schema.json +8 -0
  121. package/template/.pi/skills/yss-stage-decision/references/domain-strategy.schema.json +75 -5
  122. package/template/.pi/skills/yss-stage-decision/references/stage-decision-package-contract.md +4 -4
  123. package/template/.pi/skills/yss-stage-decision/references/stage-decision-package-v2.schema.json +8 -0
  124. package/template/.pi/skills/yss-stage-decision/references/stage-decision-package-v3.schema.json +8 -0
  125. package/template/.pi/skills/yss-stage-decision/references/stage-decision-package.schema.json +59 -9
  126. package/template/.pi/skills/yss-stage-decision/references/validation-rules.md +2 -2
  127. package/template/.pi/skills/yss-stage-decision/scripts/migrate-contract-v3.mjs +143 -0
  128. package/template/.pi/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +46 -4
  129. package/template/.pi/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +48 -4
  130. package/template/.pi/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +42 -13
  131. package/template/.pi/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +37 -5
  132. package/template/.pi/skills/yss-stage-decision/tests/run-scenarios.mjs +116 -23
  133. package/template/.pi/skills/yss-technical-design/SKILL.md +6 -0
  134. package/template/docs/agents/yss-skill-registry.yaml +22 -0
  135. package/template/docs/plan/templates/plan-template.md +8 -4
  136. package/template/docs/process/document-writing.md +77 -0
  137. package/template/docs/process/frontend-backend-delivery.md +7 -4
  138. package/template/docs/process/schemas/backend-delivery.schema.json +4 -0
  139. package/template/docs/process/schemas/frontend-delivery-acceptance-v1.schema.json +200 -0
  140. package/template/docs/process/schemas/frontend-delivery-acceptance.schema.json +37 -3
  141. package/template/docs/process/schemas/frontend-strategic-preflight.schema.json +32 -0
  142. package/template/docs/process/schemas/lifecycle-checkpoint.schema.json +2 -1
  143. package/template/docs/process/schemas/strategic-consumer-feedback.schema.json +40 -0
  144. package/template/docs/process/schemas/strategic-design-handoff-v3.schema.json +743 -0
  145. package/template/docs/process/schemas/strategic-design-handoff-v4.schema.json +712 -0
  146. package/template/docs/process/schemas/strategic-feedback-adjudication.schema.json +42 -0
  147. package/template/docs/process/schemas/strategic-handoff-domain-strategy-v3.schema.json +216 -0
  148. package/template/docs/process/schemas/strategic-handoff-import-receipt.schema.json +39 -0
  149. package/template/docs/process/schemas/strategic-handoff-stage-decision-package-v3.schema.json +148 -0
  150. package/template/docs/process/strategic-handoff-package.md +37 -4
  151. package/template/docs/process/templates/lifecycle-checkpoint-template.yaml +1 -0
  152. package/template/docs/process/templates/stage-checkpoint-template.md +1 -0
  153. package/template/docs/templates/examples/lifecycle-writing-examples.md +138 -0
  154. package/template/docs/templates/spec-template.md +16 -3
  155. package/template/docs/templates/vertical-slice-ticket-template.md +8 -4
  156. package/template/scripts/lib/approval-record.mjs +2 -1
  157. package/template/scripts/lib/backend-delivery.mjs +15 -3
  158. package/template/scripts/lib/frontend-delivery-boundary.mjs +20 -4
  159. package/template/scripts/lib/frontend-delivery.mjs +66 -2
  160. package/template/scripts/lib/profile-skill-sync.mjs +336 -0
  161. package/template/scripts/lib/strategic-feedback.mjs +33 -0
  162. package/template/scripts/lib/strategic-handoff-consumption.mjs +5 -0
  163. package/template/scripts/lib/strategic-handoff-io.mjs +1 -0
  164. package/template/scripts/lib/strategic-handoff.mjs +101 -10
  165. package/template/scripts/lib/user-decision-reuse.mjs +38 -0
  166. package/template/scripts/strategic-feedback +10 -0
  167. package/template/scripts/sync-profile-skills +43 -0
  168. package/template/scripts/verify-frontend-strategic-preflight +12 -0
  169. package/template/skills-lock.json +38 -20
  170. package/template.manifest.json +1 -0
  171. package/template.snapshot.json +6 -5
@@ -1,16 +1,41 @@
1
- schema_version: 2
1
+ schema_version: 3
2
2
  stage_decision_id: stage-decision.supplier-admission
3
- package_version: v2
3
+ package_version: v3
4
4
  status: approved
5
5
  problem_statement: 合规准入决定分散,采购无法稳定判断当前有效资格。
6
6
  target_users: [采购专员、合规专员]
7
7
  mvp: [提交供应商申请、合规准入决定、采购侧有效性校验]
8
8
  non_goals: [供应商结算、采购付款、通用工作流平台]
9
- success_criteria: [新采购订单 100% 校验当前有效准入决定]
10
- test_seams: [supplier-application-submit, admission-validity-check]
11
- confirmed_decisions: [ComplianceReview 拥有准入规则语义,ProcurementExecution 只消费决定]
12
- assumptions: [供应商已有唯一 subject_ref]
13
- constraints: [保留现有采购订单流程]
9
+ success_criteria:
10
+ - id: success-criterion.current-admission
11
+ statement: 新采购订单 100% 校验当前有效准入决定。
12
+ source_refs: [rule.current-admission-required]
13
+ evidence_refs: [evidence.discovery.compliance]
14
+ status: confirmed
15
+ test_seams:
16
+ - id: test-seam.admission-validity-check
17
+ statement: admission-validity-check
18
+ source_refs: [scenario.admission-expires, invariant.current-admission-required]
19
+ evidence_refs: [evidence.discovery.compliance]
20
+ status: confirmed
21
+ confirmed_decisions:
22
+ - id: decision.compliance-owns-admission-rules
23
+ statement: ComplianceReview 拥有准入规则语义,ProcurementExecution 只消费决定。
24
+ source_refs: [rule.current-admission-required]
25
+ evidence_refs: [evidence.domain-strategy-review.supplier]
26
+ status: confirmed
27
+ assumptions:
28
+ - id: assumption.unique-subject-ref
29
+ statement: 供应商已有唯一 subject_ref。
30
+ source_refs: [scenario.supplier-submits]
31
+ evidence_refs: [evidence.discovery.supplier]
32
+ status: confirmed
33
+ constraints:
34
+ - id: constraint.preserve-procurement-flow
35
+ statement: 保留现有采购订单流程。
36
+ source_refs: [scenario.admission-expires]
37
+ evidence_refs: [evidence.discovery.compliance]
38
+ status: confirmed
14
39
  unresolved_items:
15
40
  - item: 供应商历史资料迁移范围
16
41
  type: deferred
@@ -25,7 +50,7 @@ context_snapshot:
25
50
  term_refs: [Global/Supplier, ComplianceReview/AdmissionDecision]
26
51
  domain_strategy_ref:
27
52
  domain_strategy_id: domain-strategy.supplier-admission
28
- domain_version: v2
53
+ domain_version: v3
29
54
  digest: <domain-strategy-digest>
30
55
  status: approved
31
56
  persisted_ref: domain-strategy.yaml
@@ -38,17 +63,21 @@ impact_assessment:
38
63
  cross_repo: false
39
64
  high_risk: false
40
65
  downstream_mapping:
41
- - domain_change: admission-decision-validity
42
- consumer: spec-synthesis
66
+ - mapping_id: mapping.backend-admission-validity
67
+ source_refs: [rule.current-admission-required, invariant.current-admission-required]
68
+ consumer_capability: backend-technical-design
43
69
  propagation: direct
44
70
  reapproval_condition: 领域策略版本或有效性规则变化
45
- - domain_change: admission-decision-validity
46
- consumer: ticket-decomposition
71
+ evidence_refs: [evidence.domain-strategy-review.supplier]
72
+ - mapping_id: mapping.frontend-admission-validity
73
+ source_refs: [scenario.admission-expires]
74
+ consumer_capability: frontend-engineering-design
47
75
  propagation: transitive
48
76
  reapproval_condition: Spec 基线变更
77
+ evidence_refs: [evidence.domain-strategy-review.supplier]
49
78
  evidence_refs: [evidence.discovery.supplier, evidence.domain-strategy-review.supplier]
50
79
  approval:
51
80
  approval_ref: .agents/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml
52
81
  approver: role.product-manager
53
82
  persisted_ref: docs/.scratch/supplier/stage-decision/stage-decision-package-v1.yaml
54
- current_version: v2
83
+ current_version: v3
@@ -1,7 +1,19 @@
1
- schema_version: 2
1
+ schema_version: 3
2
2
  domain_strategy_id: domain-strategy.supplier-admission
3
- domain_version: v2
3
+ domain_version: v3
4
4
  status: approved
5
+ traceability_version: 1
6
+ rule_catalog:
7
+ - rule_id: rule.application-material-complete
8
+ statement: 申请材料必须完整
9
+ responsible_context: SupplierManagement
10
+ status: confirmed
11
+ evidence_refs: [evidence.discovery.supplier]
12
+ - rule_id: rule.current-admission-required
13
+ statement: 新采购订单必须引用当前有效的准入决定。
14
+ responsible_context: ComplianceReview
15
+ status: confirmed
16
+ evidence_refs: [evidence.discovery.compliance]
5
17
  contexts:
6
18
  - context_id: SupplierManagement
7
19
  name: 供应商管理
@@ -64,6 +76,10 @@ scenarios:
64
76
  preconditions: [供应商资料可编辑]
65
77
  commands: [SubmitSupplierApplication]
66
78
  rules: [申请材料必须完整]
79
+ rule_refs: [rule.application-material-complete]
80
+ critical: true
81
+ success_results: [完整申请进入合规审查]
82
+ evidence_refs: [evidence.discovery.supplier]
67
83
  events: [SupplierApplicationSubmitted]
68
84
  failure_results: [材料不完整时拒绝提交]
69
85
  responsible_context: SupplierManagement
@@ -73,7 +89,11 @@ scenarios:
73
89
  actor: compliance-officer
74
90
  preconditions: [批准决定存在]
75
91
  commands: [EvaluateAdmissionValidity]
76
- rules: [过期决定不得支持新采购订单]
92
+ rules: [新采购订单必须引用当前有效的准入决定。]
93
+ rule_refs: [rule.current-admission-required]
94
+ critical: true
95
+ success_results: [过期准入决定不能支持新采购订单]
96
+ evidence_refs: [evidence.discovery.compliance]
77
97
  events: [SupplierAdmissionExpired]
78
98
  failure_results: [采购下单时资格校验失败]
79
99
  responsible_context: ComplianceReview
@@ -94,6 +114,8 @@ invariants:
94
114
  responsible_context: ComplianceReview
95
115
  scenario_refs: [scenario.admission-expires]
96
116
  verification_method: 领域场景测试和事件版本校验
117
+ rule_ref: rule.current-admission-required
118
+ evidence_refs: [evidence.discovery.compliance]
97
119
  context_snapshot:
98
120
  context_ref: CONTEXT.md
99
121
  context_schema_version: 1
@@ -101,13 +123,23 @@ context_snapshot:
101
123
  referenced_terms_digest: <referenced-terms-digest>
102
124
  term_refs: [Global/Supplier, ComplianceReview/AdmissionDecision]
103
125
  downstream_mapping:
104
- - domain_change: admission-decision-validity
126
+ - mapping_id: mapping.backend-admission-validity
127
+ source_refs: [rule.current-admission-required, invariant.current-admission-required]
128
+ consumer_capability: backend-technical-design
105
129
  impacts: [spec, openapi, procurement-acceptance-tests]
106
130
  propagation: stale
107
131
  reapproval_condition: ComplianceReview 决定和有效期重新批准
132
+ evidence_refs: [evidence.discovery.compliance]
133
+ - mapping_id: mapping.frontend-admission-validity
134
+ source_refs: [scenario.admission-expires]
135
+ consumer_capability: frontend-engineering-design
136
+ impacts: [ui, frontend]
137
+ propagation: direct
138
+ reapproval_condition: 场景结果或视觉基线变化
139
+ evidence_refs: [evidence.discovery.compliance]
108
140
  evidence_refs: [evidence.discovery.supplier, evidence.discovery.compliance]
109
141
  approval:
110
142
  approval_ref: .agents/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml
111
143
  approver: role.product-manager
112
144
  persisted_ref: docs/.scratch/supplier/domain/domain-strategy-v1.yaml
113
- current_version: v2
145
+ current_version: v3
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { buildDecisionFixture } from "../../../../scripts/fixtures/user-decision/build-fixture.mjs";
3
2
  import { createHash } from "node:crypto";
4
3
  import { spawnSync } from "node:child_process";
5
4
  import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
@@ -14,6 +13,7 @@ const validator = join(testsRoot, "..", "scripts", "validate-domain-strategy.mjs
14
13
  const packageValidator = join(testsRoot, "..", "scripts", "validate-stage-decision-package.mjs");
15
14
  const contextValidator = join(projectRoot, "scripts", "verify-context-contract");
16
15
  const migrationTool = join(testsRoot, "..", "scripts", "migrate-context-references.mjs");
16
+ const v3MigrationTool = join(testsRoot, "..", "scripts", "migrate-contract-v3.mjs");
17
17
  const validTemplate = join(testsRoot, "fixtures", "valid-supplier-domain.yaml");
18
18
  const validPackageTemplate = join(testsRoot, "fixtures", "valid-stage-decision-package.yaml");
19
19
 
@@ -29,6 +29,58 @@ function digestYaml(source) {
29
29
  return `sha256:${createHash("sha256").update(JSON.stringify(canonical(document.toJS({ maxAliasCount: 0 })))).digest("hex")}`;
30
30
  }
31
31
 
32
+ function parseYaml(source) {
33
+ const document = parseDocument(source, { maxAliasCount: 0, uniqueKeys: true });
34
+ if (document.errors.length) throw new Error(document.errors[0].message);
35
+ return document.toJS({ maxAliasCount: 0 });
36
+ }
37
+
38
+ function toV2Domain(source) {
39
+ const value = structuredClone(parseYaml(source));
40
+ value.schema_version = 2;
41
+ value.domain_version = "v2";
42
+ delete value.traceability_version;
43
+ delete value.rule_catalog;
44
+ for (const scenario of value.scenarios) {
45
+ delete scenario.rule_refs;
46
+ delete scenario.critical;
47
+ delete scenario.success_results;
48
+ delete scenario.evidence_refs;
49
+ }
50
+ for (const invariant of value.invariants) {
51
+ delete invariant.rule_ref;
52
+ delete invariant.evidence_refs;
53
+ }
54
+ value.downstream_mapping = [{
55
+ domain_change: "admission-decision-validity",
56
+ impacts: ["spec", "openapi", "procurement-acceptance-tests"],
57
+ propagation: "stale",
58
+ reapproval_condition: "ComplianceReview 决定和有效期重新批准"
59
+ }];
60
+ value.approval.current_version = "v2";
61
+ return value;
62
+ }
63
+
64
+ function toV2Stage(source, domainDigest) {
65
+ const value = structuredClone(parseYaml(source));
66
+ value.schema_version = 2;
67
+ value.package_version = "v2";
68
+ for (const field of ["success_criteria", "test_seams", "confirmed_decisions", "assumptions", "constraints"]) {
69
+ value[field] = value[field].map((item) => item.statement);
70
+ }
71
+ value.domain_strategy_ref.domain_version = "v2";
72
+ value.domain_strategy_ref.digest = domainDigest;
73
+ value.domain_strategy_ref.persisted_ref = "domain-strategy-v2.yaml";
74
+ value.downstream_mapping = [{
75
+ domain_change: "admission-decision-validity",
76
+ consumer: "spec-synthesis",
77
+ propagation: "direct",
78
+ reapproval_condition: "领域策略版本或有效性规则变化"
79
+ }];
80
+ value.approval.current_version = "v2";
81
+ return value;
82
+ }
83
+
32
84
  function run(command, file, contextRoot) {
33
85
  return spawnSync(process.execPath, [command, file, "--root", contextRoot], { cwd: projectRoot, encoding: "utf8" });
34
86
  }
@@ -56,34 +108,59 @@ context_schema_version: 1
56
108
  | 准入决定 | 合规审查形成的准入结论。 | AdmissionDecision | ComplianceReview | 避免:\`审批结果\` |
57
109
  `;
58
110
 
59
- const temporaryRoot = await mkdtemp(join(tmpdir(), "yss-stage-decision-v2-"));
111
+ const temporaryRoot = await mkdtemp(join(tmpdir(), "yss-stage-decision-v3-"));
60
112
  try {
61
113
  await writeFile(join(temporaryRoot, "CONTEXT.md"), contextSource);
62
114
  const contextResult = spawnSync(process.execPath, [contextValidator, "--root", temporaryRoot, "--allowed-context", "SupplierManagement", "--allowed-context", "ComplianceReview", "--allowed-context", "ProcurementExecution", "--term-ref", "Global/Supplier", "--term-ref", "ComplianceReview/AdmissionDecision", "--json"], { cwd: projectRoot, encoding: "utf8" });
63
115
  if (contextResult.status !== 0) throw new Error(`context fixture should pass: ${contextResult.stderr}`);
64
116
  const context = JSON.parse(contextResult.stdout);
65
117
 
66
- const domainApprovalRef = join(temporaryRoot, "domain-approval.json");
67
118
  const domainSource = (await readFile(validTemplate, "utf8"))
68
- .replace(".agents/skills/yss-stage-decision/tests/fixtures/domain-strategy-approval.yaml", domainApprovalRef)
69
119
  .replace("<document-digest>", context.document_digest)
70
120
  .replace("<referenced-terms-digest>", context.referenced_terms_digest);
71
121
  const domainFile = join(temporaryRoot, "domain-strategy.yaml");
72
122
  await writeFile(domainFile, domainSource);
73
- const domainDecision = buildDecisionFixture(join(temporaryRoot, "domain-decision"), { boundary: "check.domain-strategy-approved", subjectRef: domainFile });
74
- const domainApproval = parseDocument(await readFile(join(testsRoot, "fixtures/domain-strategy-approval.yaml"), "utf8")).toJS();
75
- await writeFile(domainApprovalRef, JSON.stringify({ ...domainApproval, subject_ref: domainFile, approval_scope: domainDecision.requirement.scope, user_decision_ref: domainDecision.ref }));
76
123
  const pass = run(validator, domainFile, temporaryRoot);
77
- if (pass.status !== 0) throw new Error(`valid v2 fixture should pass: ${pass.stderr}`);
124
+ if (pass.status !== 0) throw new Error(`valid v3 fixture should pass: ${pass.stderr}`);
125
+
126
+ const v2Domain = toV2Domain(domainSource);
127
+ const v2DomainSource = JSON.stringify(v2Domain, null, 2);
128
+ const v2DomainFile = join(temporaryRoot, "domain-strategy-v2.yaml");
129
+ await writeFile(v2DomainFile, v2DomainSource);
130
+ const v2Pass = run(validator, v2DomainFile, temporaryRoot);
131
+ if (v2Pass.status !== 0) throw new Error(`read-only v2 fixture should pass: ${v2Pass.stderr}`);
132
+
133
+ const migratedDomainV3 = spawnSync(process.execPath, [v3MigrationTool, v2DomainFile, "--kind", "domain-strategy", "--root", temporaryRoot], { cwd: projectRoot, encoding: "utf8" });
134
+ if (migratedDomainV3.status !== 0) throw new Error(`v2 domain strategy should migrate: ${migratedDomainV3.stderr}`);
135
+ const migratedDomainV3Value = JSON.parse(migratedDomainV3.stdout);
136
+ if (migratedDomainV3Value.schema_version !== 3 || migratedDomainV3Value.status !== "draft" || migratedDomainV3Value.approval.approval_ref !== "migration-required") throw new Error("domain v2 -> v3 migration must reset approval and status");
137
+
138
+ const duplicateRule = join(temporaryRoot, "duplicate-rule.yaml");
139
+ const duplicateRuleValue = parseYaml(domainSource);
140
+ duplicateRuleValue.rule_catalog.push(structuredClone(duplicateRuleValue.rule_catalog[0]));
141
+ await writeFile(duplicateRule, JSON.stringify(duplicateRuleValue, null, 2));
142
+ expectBlocked(run(validator, duplicateRule, temporaryRoot), /rule_id.*重复|重复.*rule_id/, "duplicate v3 rule id");
143
+
144
+ const danglingRule = join(temporaryRoot, "dangling-rule.yaml");
145
+ const danglingRuleValue = parseYaml(domainSource);
146
+ danglingRuleValue.scenarios[0].rule_refs = ["rule.missing"];
147
+ await writeFile(danglingRule, JSON.stringify(danglingRuleValue, null, 2));
148
+ expectBlocked(run(validator, danglingRule, temporaryRoot), /rule_refs.*未声明|悬空/, "dangling v3 rule ref");
149
+
150
+ const missingEvidence = join(temporaryRoot, "missing-rule-evidence.yaml");
151
+ const missingEvidenceValue = parseYaml(domainSource);
152
+ missingEvidenceValue.rule_catalog[0].evidence_refs = [];
153
+ await writeFile(missingEvidence, JSON.stringify(missingEvidenceValue, null, 2));
154
+ expectBlocked(run(validator, missingEvidence, temporaryRoot), /evidence_refs/, "missing v3 evidence");
78
155
 
79
156
  const legacyFile = join(temporaryRoot, "legacy-domain.yaml");
80
- await writeFile(legacyFile, domainSource.replace("schema_version: 2", "schema_version: 1"));
157
+ await writeFile(legacyFile, JSON.stringify({ ...v2Domain, schema_version: 1 }, null, 2));
81
158
  expectBlocked(run(validator, legacyFile, temporaryRoot), /migration-required/, "legacy domain contract");
82
159
 
83
160
  const migratableLegacy = join(temporaryRoot, "migratable-legacy-domain.yaml");
84
- const migratableLegacySource = domainSource
85
- .replace("schema_version: 2", "schema_version: 1")
86
- .replace(/context_snapshot:\n[\s\S]*?\ndownstream_mapping:/, "terminology_refs: [CONTEXT.md#Supplier, contexts/ComplianceReview/CONTEXT.md#AdmissionDecision]\ndownstream_mapping:");
161
+ const migratableLegacyValue = { ...structuredClone(v2Domain), schema_version: 1, terminology_refs: ["CONTEXT.md#Supplier", "contexts/ComplianceReview/CONTEXT.md#AdmissionDecision"] };
162
+ delete migratableLegacyValue.context_snapshot;
163
+ const migratableLegacySource = JSON.stringify(migratableLegacyValue, null, 2);
87
164
  await writeFile(migratableLegacy, migratableLegacySource);
88
165
  const migrated = spawnSync(process.execPath, [migrationTool, migratableLegacy, "--root", temporaryRoot], { cwd: projectRoot, encoding: "utf8" });
89
166
  if (migrated.status !== 0) throw new Error(`migratable v1 contract should migrate: ${migrated.stderr}`);
@@ -91,7 +168,7 @@ try {
91
168
  if (migratedValue.schema_version !== 2 || migratedValue.terminology_refs !== undefined || migratedValue.context_snapshot.context_ref !== "CONTEXT.md" || migratedValue.context_snapshot.term_refs.join(",") !== "ComplianceReview/AdmissionDecision,Global/Supplier") throw new Error("migrated context snapshot is incomplete");
92
169
 
93
170
  const ambiguousLegacy = join(temporaryRoot, "ambiguous-legacy-domain.yaml");
94
- await writeFile(ambiguousLegacy, migratableLegacySource.replace("CONTEXT.md#Supplier, contexts/ComplianceReview/CONTEXT.md#AdmissionDecision", "contexts/ComplianceReview/CONTEXT.md"));
171
+ await writeFile(ambiguousLegacy, JSON.stringify({ ...migratableLegacyValue, terminology_refs: ["contexts/ComplianceReview/CONTEXT.md"] }, null, 2));
95
172
  const ambiguousMigration = spawnSync(process.execPath, [migrationTool, ambiguousLegacy, "--root", temporaryRoot], { cwd: projectRoot, encoding: "utf8" });
96
173
  expectBlocked(ambiguousMigration, /migration-required.*无法唯一定位|无法唯一定位.*migration-required/, "ambiguous legacy reference");
97
174
 
@@ -115,32 +192,48 @@ try {
115
192
  await writeFile(unknownContext, domainSource.replace("to_context: ComplianceReview", "to_context: UnknownContext"));
116
193
  expectBlocked(run(validator, unknownContext, temporaryRoot), /未引用已声明上下文|未在领域战略中登记/, "unknown context");
117
194
 
118
- const packageApprovalRef = join(temporaryRoot, "package-approval.json");
119
195
  const packageSource = (await readFile(validPackageTemplate, "utf8"))
120
- .replace(".agents/skills/yss-stage-decision/tests/fixtures/stage-decision-approval.yaml", packageApprovalRef)
121
196
  .replace("<document-digest>", context.document_digest)
122
197
  .replace("<referenced-terms-digest>", context.referenced_terms_digest)
123
198
  .replace("<domain-strategy-digest>", digestYaml(domainSource));
124
199
  const packageFile = join(temporaryRoot, "stage-decision.yaml");
125
200
  await writeFile(packageFile, packageSource);
126
- const packageDecision = buildDecisionFixture(join(temporaryRoot, "package-decision"), { boundary: "check.stage-decision-package-approved", subjectRef: packageFile });
127
- const packageApproval = parseDocument(await readFile(join(testsRoot, "fixtures/stage-decision-approval.yaml"), "utf8")).toJS();
128
- await writeFile(packageApprovalRef, JSON.stringify({ ...packageApproval, subject_ref: packageFile, approval_scope: packageDecision.requirement.scope, user_decision_ref: packageDecision.ref }));
129
201
  const packagePass = run(packageValidator, packageFile, temporaryRoot);
130
- if (packagePass.status !== 0) throw new Error(`valid v2 stage decision package should pass: ${packagePass.stderr}`);
202
+ if (packagePass.status !== 0) throw new Error(`valid v3 stage decision package should pass: ${packagePass.stderr}`);
203
+
204
+ const v2Stage = toV2Stage(packageSource, digestYaml(v2DomainSource));
205
+ const v2StageFile = join(temporaryRoot, "stage-decision-v2.yaml");
206
+ await writeFile(v2StageFile, JSON.stringify(v2Stage, null, 2));
207
+ const v2StagePass = run(packageValidator, v2StageFile, temporaryRoot);
208
+ if (v2StagePass.status !== 0) throw new Error(`read-only v2 stage decision package should pass: ${v2StagePass.stderr}`);
209
+
210
+ const migratedV3 = spawnSync(process.execPath, [v3MigrationTool, v2StageFile, "--kind", "stage-decision", "--root", temporaryRoot], { cwd: projectRoot, encoding: "utf8" });
211
+ if (migratedV3.status !== 0) throw new Error(`v2 stage decision should migrate: ${migratedV3.stderr}`);
212
+ const migratedV3Value = JSON.parse(migratedV3.stdout);
213
+ if (migratedV3Value.schema_version !== 3 || migratedV3Value.status !== "draft" || migratedV3Value.approval.approval_ref !== "migration-required") throw new Error("v2 -> v3 migration must reset approval and status");
214
+
215
+ const wrongSourceRef = join(temporaryRoot, "stage-decision-wrong-source-ref.yaml");
216
+ const wrongSourceRefValue = parseYaml(packageSource);
217
+ wrongSourceRefValue.success_criteria[0].source_refs = ["rule.missing"];
218
+ await writeFile(wrongSourceRef, JSON.stringify(wrongSourceRefValue, null, 2));
219
+ expectBlocked(run(packageValidator, wrongSourceRef, temporaryRoot), /source_refs.*未在领域战略中声明|悬空/, "stage decision dangling source ref");
131
220
 
132
221
  const packageLegacy = join(temporaryRoot, "legacy-stage-decision.yaml");
133
- await writeFile(packageLegacy, packageSource.replace("schema_version: 2", "schema_version: 1"));
222
+ await writeFile(packageLegacy, JSON.stringify({ ...v2Stage, schema_version: 1 }, null, 2));
134
223
  expectBlocked(run(packageValidator, packageLegacy, temporaryRoot), /migration-required/, "legacy stage decision contract");
135
224
 
136
225
  const packageBlocker = join(temporaryRoot, "stage-decision-blocker.yaml");
137
- await writeFile(packageBlocker, packageSource.replace("type: deferred", "type: blocker"));
226
+ const blockerValue = parseYaml(packageSource);
227
+ blockerValue.unresolved_items[0].type = "blocker";
228
+ await writeFile(packageBlocker, JSON.stringify(blockerValue, null, 2));
138
229
  expectBlocked(run(packageValidator, packageBlocker, temporaryRoot), /blocker/, "blocker package");
139
230
 
140
231
  const packageWrongArray = join(temporaryRoot, "stage-decision-wrong-array.yaml");
141
- await writeFile(packageWrongArray, packageSource.replace("target_users: [采购专员、合规专员]", "target_users: [42]"));
232
+ const wrongArrayValue = parseYaml(packageSource);
233
+ wrongArrayValue.target_users = [42];
234
+ await writeFile(packageWrongArray, JSON.stringify(wrongArrayValue, null, 2));
142
235
  expectBlocked(run(packageValidator, packageWrongArray, temporaryRoot), /target_users\[0\]/, "package non-string array item");
143
236
  } finally {
144
237
  await rm(temporaryRoot, { recursive: true, force: true });
145
238
  }
146
- process.stdout.write("业务边界与规则设计 v2 场景验证通过\n");
239
+ process.stdout.write("业务边界与规则设计 v2/v3 场景验证通过\n");
@@ -7,6 +7,12 @@ description: 在 YSS 技术分析中统一承接需求与战略输入,按已
7
7
 
8
8
  由 `yss-product-lifecycle` 调度,负责 `work-unit.technical-analysis` 的技术设计,不另起生命周期、不生成生产代码。生命周期维护批准和状态;`yss-implementation-contract-compiler` 消费批准且当前的设计,起草实现合同。
9
9
 
10
+ 文档输出时按 `lifecycle-document-output` 条件调用 `i-have-adhd`,读取 `docs/process/document-writing.md`;作用域仅限当前产物,派发时传递条件及引用。
11
+
12
+ ## 文档写作
13
+
14
+ 起草或修订技术设计解释正文前,读取 `docs/process/document-writing.md` 的共用写法及工程契约指引,并在分支派发中传递该引用;结构化合同保持原 schema 和验证要求。
15
+
10
16
  ## 输入与架构选择
11
17
 
12
18
  先读根 `CONTEXT.md`、已批准且当前的 Spec、业务规则、关键场景、适用的 API 契约、ADR 和工程约束。没有 API 或其他专项影响时记录有依据的不适用,不生成占位设计。
@@ -16,7 +16,7 @@ Create a self-contained, interactive HTML diagram from a small typed JSON specif
16
16
 
17
17
  When the current repository contains `yss-project.yaml`, these rules override the upstream update and delivery commands below:
18
18
 
19
- - Treat Archify as a conditional specialist. Use it only when the user or the current YSS contract explicitly requires an architecture, workflow, sequence, data-flow, lifecycle, or Mermaid-beautification artifact. A diagram is derived evidence; it never replaces Spec, ADR, OpenAPI, Tactical Design Contract, Slice Implementation Contract, review, or approval evidence.
19
+ - Treat Archify as a conditional specialist. Use it only when the user or the current YSS contract explicitly requires an architecture, workflow, sequence, data-flow, lifecycle, or Mermaid-beautification artifact. A diagram is derived evidence; it never replaces the active profile's architecture contract (such as backend Tactical Design or Frontend Engineering Design), Spec, ADR, OpenAPI, Slice Implementation Contract, review, or approval evidence.
20
20
  - Do not run `scripts/check-update.mjs`. YSS pins the upstream revision in `skills-lock.json`; upgrades happen only through the repository's skill-maintenance workflow.
21
21
  - Validate with the upstream `validate` command, but deliver through the repository-safe wrapper from the repository root:
22
22
 
@@ -13,6 +13,12 @@ Standards and Spec run as **parallel sub-agents** so they don't pollute each oth
13
13
 
14
14
  If `docs/agents/issue-tracker.md` is missing, tell the user to run `/setup-matt-pocock-skills`; do not invoke another user-invoked skill yourself.
15
15
 
16
+ 文档输出时按 `lifecycle-document-output` 条件调用 `i-have-adhd`,读取 `docs/process/document-writing.md`;作用域仅限当前产物,派发时传递条件及引用。
17
+
18
+ ## 文档写作
19
+
20
+ 撰写审查报告时,读取 `docs/process/document-writing.md` 的共用写法及审查指引;保留各审查轴的 findings、严重性、定位、证据及原裁决,不因压缩表达合并或降级。
21
+
16
22
  ## Process
17
23
 
18
24
  ### 1. Pin the fixed point and candidate
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ayoub Ghriss
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,26 @@
1
+ ---
2
+ name: i-have-adhd
3
+ description: 在研发文档起草、修订、审查报告和交接表达时,按 YSS 中文规范组织具体、完整、可执行的输出;仅作用于当前文档工作。
4
+ license: MIT
5
+ ---
6
+
7
+ # i-have-adhd · YSS 适配
8
+
9
+ 为当前产物应用 `docs/process/document-writing.md`;该文是中文写法的唯一权威来源。需要例子时读取 `docs/templates/examples/lifecycle-writing-examples.md`。本技能是原资产所有者的配套技能,不持有业务决定、批准或生命周期状态。
10
+
11
+ ## 触发与作用域
12
+
13
+ 调用者在当前工作包含研究结论、Plan、Spec、设计说明、契约解释正文、Ticket、审查、交接、发布或复盘时,设置条件 `lifecycle-document-output` 并加载本技能。进度与会签表达也属于文档输出;纯代码修改、命令执行和后续无关会话不激活此条件。
14
+
15
+ 每次调用只覆盖输入指定的文档或报告。工作结束即结束本次作用域;用户后续要求正常表达或不使用本技能时遵从当前要求,不继承先前启用状态。不假设读者具有任何诊断。
16
+
17
+ ## 执行
18
+
19
+ 1. 接收产物类型、读者、允许改动范围和可读权威输入;先读共用规范,再读取对应阶段指引。字段、版本或规则来源不明确时保留缺口并回交原所有者,不补造业务决定。
20
+ 2. 先写当前问题、结论或交付行为,再提供依据和必要细节;按顺序动作、规则比较和因果说明选择编号、表格或段落。删除无信息的修饰和重复,不设置字数或规则数量上限。
21
+ 3. 对照输入核查主体、条件、例外、量词、范围、数值、证据、未决项、责任、时点和依赖。保持原 API 标识、schema、冻结行为、状态及批准证据;发现冲突时交回所有者,不以润色名义修复事实。
22
+ 4. 返回调整后的正文及必要的缺口说明,由原工作单元执行现有验证。明确区分已验证结果、估算和未知原因;未执行测试不写通过,多项实质阻塞全部保留。已授权工作由原执行者继续,不把可完成的操作转交用户。
23
+
24
+ 研究仍使用原研究证据合同;代码审查保留原轴、严重性、定位和结论;契约保持机器结构。共用规范不可读时停止受影响的文档改写并报告缺失引用,不妨碍独立的已授权工作。
25
+
26
+ 来源、固定版本和适配差异见 [YSS 适配说明](references/yss-adaptation.md)。只安装项目技能,不安装上游全局插件、hook 或会话持久模式。
@@ -0,0 +1,6 @@
1
+ interface:
2
+ display_name: "i-have-adhd · YSS 文档配套"
3
+ short_description: "按当前研发文档任务应用中文写作规范,保持规则与证据完整"
4
+ default_prompt: "使用 i-have-adhd 配套技能改善当前研发文档表达,保留所有业务规则、证据、未决项和原批准状态。"
5
+ policy:
6
+ allow_implicit_invocation: true
@@ -0,0 +1,21 @@
1
+ # i-have-adhd 的 YSS 适配
2
+
3
+ 上游:`ayghri/i-have-adhd`;固定 revision:`7b9069b39972e269e61bd95c2f66ebb90cac6a02`;许可证见技能目录 `LICENSE`。
4
+
5
+ 原始文件来自 [固定版本目录](https://github.com/ayghri/i-have-adhd/tree/7b9069b39972e269e61bd95c2f66ebb90cac6a02/skills/i-have-adhd)。未经改写的来源基线保存在模板维护证据中;`upstream-files.json` 记录逐文件 SHA-256,`skills-lock.json` 记录上游目录哈希和当前技能目录哈希。基线不进入实例默认加载面。
6
+
7
+ | 上游行为 | YSS 适配 |
8
+ |---|---|
9
+ | 用户显式调用、会话持续 | 原技能名保留;文档工作按 `lifecycle-document-output` 条件调用,任务结束即失效 |
10
+ | 对读者作 ADHD 假设 | 面向所有文档读者,不引入诊断假设 |
11
+ | 行动前置、步骤编号、删除套话 | 消费中文写作规范,按产物类型决定信息顺序和格式 |
12
+ | 展示进度、下一步和具体时间 | 报告实际变化和全部必要阻塞;时间有依据才估算,不把工作推给用户 |
13
+ | 压缩可见列表 | 完整性优先,不设规则数量上限 |
14
+ | 原因与修复直接陈述 | 区分已知现象、待验证原因和实际验证结果 |
15
+ | 平台专属 agent 配置 | 不安装上游 Gemini 持久提示;项目 OpenAI 配置只描述当前文档配套用途 |
16
+
17
+ 生命周期仍拥有门禁、状态、批准和资产;本技能没有独立授权、审批或分支流程。正文规则只在 `docs/process/document-writing.md` 维护;本文件只解释来源差异。
18
+
19
+ 注册表将本技能声明为模型可调用、实例默认可发现的通用工作流 core 技能(仍只作为文档配套);调用者以条件依赖加载。上游 `disable-model-invocation: true` 在适配版移除;作用域由本技能触发条件限定,不延续上游会话开关。
20
+
21
+ 验证只证明来源、路由、投影和合同符合预期。中文文档质量需通过真实生成评估,不以结构检查或作者自检代替盲评效果。
@@ -0,0 +1,63 @@
1
+ // Structural and real dependency-resolution checks; not a model-output quality evaluation.
2
+ import assert from 'node:assert/strict';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import {pathToFileURL} from 'node:url';
6
+
7
+ const root=path.resolve(process.argv[2] || '.');
8
+ const read=ref=>fs.readFileSync(path.join(root,ref),'utf8');
9
+ const {parse}=await import(pathToFileURL(path.join(root,'scripts/vendor/yaml.mjs')));
10
+ const registry=parse(read('docs/agents/yss-skill-registry.yaml'));
11
+ const skill=registry.skills.find(x=>x.id==='i-have-adhd');
12
+ assert.equal(skill.instance_default_discoverable,true);
13
+ assert.equal(registry.invocation_contract.overrides['i-have-adhd'].invocation_mode,'model');
14
+ assert.ok(registry.invocation_contract.overrides['i-have-adhd'].exclusion_conditions.includes('unrelated-conversation'));
15
+ assert.ok(registry.invocation_contract.overrides['i-have-adhd'].exclusion_conditions.includes('user-disabled'));
16
+ const entry=read('.agents/skills/i-have-adhd/SKILL.md');
17
+ assert.ok(!entry.includes('disable-model-invocation: true'));
18
+ assert.equal(parse(read('.agents/skills/i-have-adhd/agents/openai.yaml')).policy.allow_implicit_invocation,true);
19
+ const lock=JSON.parse(read('skills-lock.json'));
20
+ const locked=lock.skills.shared['i-have-adhd'];
21
+ assert.equal(locked.source,'ayghri/i-have-adhd');
22
+ assert.equal(locked.sourceRevision,'7b9069b39972e269e61bd95c2f66ebb90cac6a02');
23
+ assert.notEqual(locked.upstreamHash,locked.effectiveHash);
24
+ const {treeHash}=await import(pathToFileURL(path.join(root,'scripts/lib/skill-supply-chain.mjs')));
25
+ assert.equal(treeHash(path.join(root,'.agents/skills/i-have-adhd')),locked.effectiveHash);
26
+ for (const target of locked.targets) {
27
+ const skillPath=target.endsWith('/i-have-adhd')?target:path.join(target,'i-have-adhd');
28
+ assert.equal(treeHash(path.join(root,skillPath)),locked.effectiveHash,`projection ${target}`);
29
+ }
30
+ for(const ref of ['docs/process/document-writing.md','docs/templates/examples/lifecycle-writing-examples.md']) {
31
+ assert.ok(read(ref).length);
32
+ assert.ok(!read(ref).includes('.template-source/'));
33
+ }
34
+ const callers=Object.entries(registry.skill_dependencies).filter(([,deps])=>deps.some(d=>d.skill==='i-have-adhd'));
35
+ assert.ok(callers.length>0);
36
+ for(const [owner,deps] of callers) {
37
+ const edge=deps.find(d=>d.skill==='i-have-adhd');
38
+ assert.equal(edge.type,'context-conditional');
39
+ assert.equal(edge.when,'lifecycle-document-output');
40
+ assert.ok(read(`.agents/skills/${owner}/SKILL.md`).includes('`i-have-adhd`'));
41
+ }
42
+ const orchestrator=registry.skills.find(x=>['yss-product-lifecycle','yss-strategic-design','harness-orchestrator'].includes(x.id)).id;
43
+ const contract=parse(read(`.agents/skills/${orchestrator}/references/orchestration-contract.yaml`));
44
+ assert.equal(contract.document_writing.supporting_skill,'i-have-adhd');
45
+ assert.equal(contract.document_writing.condition,'lifecycle-document-output');
46
+ assert.equal(contract.document_writing.scope,'current-document-work-only');
47
+ assert.equal(contract.document_writing.gate_and_status_semantics,'unchanged');
48
+
49
+ // Compile using the actual repository resolver, with and without the condition and again without it.
50
+ const compiler=path.join(root,'scripts/lib/implementation-contract-compiler.mjs');
51
+ if(fs.existsSync(compiler)) {
52
+ const api=await import(pathToFileURL(compiler));
53
+ const capability=registry.capabilities.find(c=>c.id==='governance.implementation-contract');
54
+ assert.ok(capability);
55
+ const run=conditions=>api.compileImplementationContract({registry,compilerContract:api.loadCompilerContract(),requiredCapabilities:[capability.id],conditions,root});
56
+ const off=run([]),on=run(['lifecycle-document-output']),next=run([]);
57
+ assert.ok(!off.required_skills.includes('i-have-adhd'));
58
+ assert.ok(on.required_skills.includes('i-have-adhd'));
59
+ assert.ok(!next.required_skills.includes('i-have-adhd'));
60
+ assert.equal(on.status,'draft');
61
+ console.log('PASS: actual resolver excludes code-only, includes document output, does not persist condition or approve the contract.');
62
+ } else console.log('N/A: this strategic-only template has no implementation compiler; conditional route verified in registry and orchestration contract.');
63
+ console.log(`PASS: source, license metadata, ${locked.targets.length} projections, ${callers.length} callers, scope and readable writing inputs. Model output quality not measured.`);
@@ -7,6 +7,8 @@ description: Use when independently reviewing low-fidelity UI, interaction specs
7
7
 
8
8
  Use this skill as the independent low-fidelity review in `yss-prototype-stage`. The review is fail-closed: if the design cannot drive calibrated requirements, API, frontend acceptance, and slices, send it back to product design. `yss-product-lifecycle` alone records the resulting `check.prototype-reviewed` decision.
9
9
 
10
+ 文档输出时按 `lifecycle-document-output` 条件调用 `i-have-adhd`,读取 `docs/process/document-writing.md`;作用域仅限当前产物,派发时传递条件及引用。
11
+
10
12
  ## Trigger Boundary
11
13
 
12
14
  Run this independent gate only when UI changes affect a primary user flow, navigation, permissions, exception/recovery states, state transitions, or OpenAPI implications. For copy edits, token/color/spacing adjustments, and isolated visual fixes with no behavior, state, permission, navigation, or API impact, record `not-applicable` with the impact assessment; do not create prototype-review artifacts.
@@ -7,6 +7,12 @@ description: Use when a YSS vertical slice is entering implementation, spans mul
7
7
 
8
8
  阶段 7 的实现合同编译器。它把已批准的生命周期资产、垂直切片、capability 和窄 Recipe 编译为 `Slice Implementation Contract` v2 草案;不批准合同、不写业务代码、不设置 `ready-for-agent`。
9
9
 
10
+ 文档输出时按 `lifecycle-document-output` 条件调用 `i-have-adhd`,读取 `docs/process/document-writing.md`;作用域仅限当前产物,派发时传递条件及引用。
11
+
12
+ ## 文档写作
13
+
14
+ 撰写实现合同的解释正文和切片交接说明前,读取 `docs/process/document-writing.md` 的共用写法及工程契约 / Ticket 指引;不改变结构化合同、批准状态或就绪条件。
15
+
10
16
  ## 输入
11
17
 
12
18
  先读取 Spec、切片 Ticket、需求冻结、适用的原型确认、OpenAPI Freeze/no-impact、系统/数据架构、Design Review、Build Architecture Checklist、实现仓库和验证命令。输入缺失、未批准或 `stale` 时输出 `blocked`,交回 `yss-product-lifecycle`。
@@ -18,6 +18,7 @@
18
18
 
19
19
  | Capability | Primary skill | Task modes |
20
20
  | --- | --- | --- |
21
+ | `writing.lifecycle-document` | `i-have-adhd` | `guidance` |
21
22
  | `architecture.technical-design` | `yss-technical-design` | `guidance`, `integration`, `review-input` |
22
23
  | `architecture.mvc-design` | `yss-mvc-design` | `guidance`, `integration`, `review-input` |
23
24
  | `layer.mvc-service` | `yss-application` | `guidance`, `integration`, `slice-implementation`, `troubleshooting`, `review-input` |
@@ -105,8 +106,16 @@
105
106
 
106
107
  | Skill | Dependency | Type | Condition |
107
108
  | --- | --- | --- | --- |
109
+ | `prototype-review` | `i-have-adhd` | `context-conditional` | `lifecycle-document-output` |
110
+ | `yss-implementation-contract-compiler` | `i-have-adhd` | `context-conditional` | `lifecycle-document-output` |
111
+ | `yss-openapi-governance` | `i-have-adhd` | `context-conditional` | `lifecycle-document-output` |
112
+ | `yss-stage-decision` | `i-have-adhd` | `context-conditional` | `lifecycle-document-output` |
113
+ | `yss-research` | `i-have-adhd` | `context-conditional` | `lifecycle-document-output` |
114
+ | `yss-product-lifecycle` | `i-have-adhd` | `context-conditional` | `lifecycle-document-output` |
115
+ | `code-review` | `i-have-adhd` | `context-conditional` | `lifecycle-document-output` |
108
116
  | `code-review` | `yss-repository` | `context-conditional` | `backend-persistence-impact` |
109
117
  | `code-review` | `yss-mybatis` | `context-conditional` | `backend-persistence-impact` |
118
+ | `yss-prototype-stage` | `i-have-adhd` | `context-conditional` | `lifecycle-document-output` |
110
119
  | `yss-prototype-stage` | `prototype-review` | `review-only` | — |
111
120
  | `yss-prototype-stage` | `yss-design-system` | `coordination-only` | — |
112
121
  | `yss-prototype-stage` | `yss-antdv-next-design` | `context-conditional` | `h2-vue-antdv-next-default` |
@@ -118,6 +127,7 @@
118
127
  | `yss-domain` | `domain-modeling` | `coordination-only` | — |
119
128
  | `yss-domain` | `yss-tactical-design` | `context-conditional` | `tactical-domain` |
120
129
  | `yss-domain` | `lombok` | `context-conditional` | `pojo` |
130
+ | `yss-technical-design` | `i-have-adhd` | `context-conditional` | `lifecycle-document-output` |
121
131
  | `yss-technical-design` | `yss-tactical-design` | `coordination-only` | `domain-driven` |
122
132
  | `yss-technical-design` | `yss-mvc-design` | `coordination-only` | `layered-mvc` |
123
133
  | `yss-mvc-design` | `yss-openapi-draft-review` | `review-only` | `api-impact` |
@@ -15,6 +15,12 @@ Spec / 设计输入 → OpenAPI YAML Draft → 审查与 Freeze → JSON 派生
15
15
 
16
16
  YSS DTO 的可复用 HTTP/JSON 映射由 `.agents/skills/yss-dto/references/openapi-wire-profile.yaml` 单一维护。它描述公开 wire shape,不是 Java 字段或 getter 清单;本 skill 必须消费 profile,不能在治理文档、feature YAML 和 JSON 中各自发明 `SingleResult`、`PageResult` 或 `PageQuery` 字段表。
17
17
 
18
+ 文档输出时按 `lifecycle-document-output` 条件调用 `i-have-adhd`,读取 `docs/process/document-writing.md`;作用域仅限当前产物,派发时传递条件及引用。
19
+
20
+ ## 文档写作
21
+
22
+ 编写接口说明和契约评审交接正文前,读取 `docs/process/document-writing.md` 的共用写法及工程契约指引;协议标识、schema、冻结状态和验证记录按原合同保存。
23
+
18
24
  ## 边界与职责
19
25
 
20
26
  使用 `yss-openapi-governance`: