create-yss-spec 3.3.6 → 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 (103) 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 +5 -3
  6. package/template/.agents/skills/archify/SKILL.md +1 -1
  7. package/template/.agents/skills/yss-stage-decision/SKILL.md +13 -4
  8. package/template/.agents/skills/yss-stage-decision/references/domain-strategy-contract.md +4 -3
  9. package/template/.agents/skills/yss-stage-decision/references/domain-strategy-v2.schema.json +8 -0
  10. package/template/.agents/skills/yss-stage-decision/references/domain-strategy-v3.schema.json +8 -0
  11. package/template/.agents/skills/yss-stage-decision/references/domain-strategy.schema.json +75 -5
  12. package/template/.agents/skills/yss-stage-decision/references/stage-decision-package-contract.md +4 -4
  13. package/template/.agents/skills/yss-stage-decision/references/stage-decision-package-v2.schema.json +8 -0
  14. package/template/.agents/skills/yss-stage-decision/references/stage-decision-package-v3.schema.json +8 -0
  15. package/template/.agents/skills/yss-stage-decision/references/stage-decision-package.schema.json +59 -9
  16. package/template/.agents/skills/yss-stage-decision/references/validation-rules.md +2 -2
  17. package/template/.agents/skills/yss-stage-decision/scripts/migrate-contract-v3.mjs +143 -0
  18. package/template/.agents/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +46 -4
  19. package/template/.agents/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +48 -4
  20. package/template/.agents/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +42 -13
  21. package/template/.agents/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +37 -5
  22. package/template/.agents/skills/yss-stage-decision/tests/run-scenarios.mjs +116 -23
  23. package/template/.codex/skills/archify/SKILL.md +1 -1
  24. package/template/.codex/skills/yss-stage-decision/SKILL.md +13 -4
  25. package/template/.codex/skills/yss-stage-decision/references/domain-strategy-contract.md +4 -3
  26. package/template/.codex/skills/yss-stage-decision/references/domain-strategy-v2.schema.json +8 -0
  27. package/template/.codex/skills/yss-stage-decision/references/domain-strategy-v3.schema.json +8 -0
  28. package/template/.codex/skills/yss-stage-decision/references/domain-strategy.schema.json +75 -5
  29. package/template/.codex/skills/yss-stage-decision/references/stage-decision-package-contract.md +4 -4
  30. package/template/.codex/skills/yss-stage-decision/references/stage-decision-package-v2.schema.json +8 -0
  31. package/template/.codex/skills/yss-stage-decision/references/stage-decision-package-v3.schema.json +8 -0
  32. package/template/.codex/skills/yss-stage-decision/references/stage-decision-package.schema.json +59 -9
  33. package/template/.codex/skills/yss-stage-decision/references/validation-rules.md +2 -2
  34. package/template/.codex/skills/yss-stage-decision/scripts/migrate-contract-v3.mjs +143 -0
  35. package/template/.codex/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +46 -4
  36. package/template/.codex/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +48 -4
  37. package/template/.codex/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +42 -13
  38. package/template/.codex/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +37 -5
  39. package/template/.codex/skills/yss-stage-decision/tests/run-scenarios.mjs +116 -23
  40. package/template/.cursor/skills/archify/SKILL.md +1 -1
  41. package/template/.cursor/skills/yss-stage-decision/SKILL.md +13 -4
  42. package/template/.cursor/skills/yss-stage-decision/references/domain-strategy-contract.md +4 -3
  43. package/template/.cursor/skills/yss-stage-decision/references/domain-strategy-v2.schema.json +8 -0
  44. package/template/.cursor/skills/yss-stage-decision/references/domain-strategy-v3.schema.json +8 -0
  45. package/template/.cursor/skills/yss-stage-decision/references/domain-strategy.schema.json +75 -5
  46. package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package-contract.md +4 -4
  47. package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package-v2.schema.json +8 -0
  48. package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package-v3.schema.json +8 -0
  49. package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package.schema.json +59 -9
  50. package/template/.cursor/skills/yss-stage-decision/references/validation-rules.md +2 -2
  51. package/template/.cursor/skills/yss-stage-decision/scripts/migrate-contract-v3.mjs +143 -0
  52. package/template/.cursor/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +46 -4
  53. package/template/.cursor/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +48 -4
  54. package/template/.cursor/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +42 -13
  55. package/template/.cursor/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +37 -5
  56. package/template/.cursor/skills/yss-stage-decision/tests/run-scenarios.mjs +116 -23
  57. package/template/.pi/skills/archify/SKILL.md +1 -1
  58. package/template/.pi/skills/yss-stage-decision/SKILL.md +13 -4
  59. package/template/.pi/skills/yss-stage-decision/references/domain-strategy-contract.md +4 -3
  60. package/template/.pi/skills/yss-stage-decision/references/domain-strategy-v2.schema.json +8 -0
  61. package/template/.pi/skills/yss-stage-decision/references/domain-strategy-v3.schema.json +8 -0
  62. package/template/.pi/skills/yss-stage-decision/references/domain-strategy.schema.json +75 -5
  63. package/template/.pi/skills/yss-stage-decision/references/stage-decision-package-contract.md +4 -4
  64. package/template/.pi/skills/yss-stage-decision/references/stage-decision-package-v2.schema.json +8 -0
  65. package/template/.pi/skills/yss-stage-decision/references/stage-decision-package-v3.schema.json +8 -0
  66. package/template/.pi/skills/yss-stage-decision/references/stage-decision-package.schema.json +59 -9
  67. package/template/.pi/skills/yss-stage-decision/references/validation-rules.md +2 -2
  68. package/template/.pi/skills/yss-stage-decision/scripts/migrate-contract-v3.mjs +143 -0
  69. package/template/.pi/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +46 -4
  70. package/template/.pi/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +48 -4
  71. package/template/.pi/skills/yss-stage-decision/tests/fixtures/valid-stage-decision-package.yaml +42 -13
  72. package/template/.pi/skills/yss-stage-decision/tests/fixtures/valid-supplier-domain.yaml +37 -5
  73. package/template/.pi/skills/yss-stage-decision/tests/run-scenarios.mjs +116 -23
  74. package/template/docs/process/frontend-backend-delivery.md +7 -4
  75. package/template/docs/process/schemas/backend-delivery.schema.json +4 -0
  76. package/template/docs/process/schemas/frontend-delivery-acceptance-v1.schema.json +200 -0
  77. package/template/docs/process/schemas/frontend-delivery-acceptance.schema.json +37 -3
  78. package/template/docs/process/schemas/frontend-strategic-preflight.schema.json +32 -0
  79. package/template/docs/process/schemas/lifecycle-checkpoint.schema.json +2 -1
  80. package/template/docs/process/schemas/strategic-consumer-feedback.schema.json +40 -0
  81. package/template/docs/process/schemas/strategic-design-handoff-v3.schema.json +743 -0
  82. package/template/docs/process/schemas/strategic-design-handoff-v4.schema.json +712 -0
  83. package/template/docs/process/schemas/strategic-feedback-adjudication.schema.json +42 -0
  84. package/template/docs/process/schemas/strategic-handoff-domain-strategy-v3.schema.json +216 -0
  85. package/template/docs/process/schemas/strategic-handoff-import-receipt.schema.json +39 -0
  86. package/template/docs/process/schemas/strategic-handoff-stage-decision-package-v3.schema.json +148 -0
  87. package/template/docs/process/strategic-handoff-package.md +37 -4
  88. package/template/docs/process/templates/lifecycle-checkpoint-template.yaml +1 -0
  89. package/template/docs/process/templates/stage-checkpoint-template.md +1 -0
  90. package/template/scripts/lib/approval-record.mjs +2 -1
  91. package/template/scripts/lib/backend-delivery.mjs +15 -3
  92. package/template/scripts/lib/frontend-delivery-boundary.mjs +20 -4
  93. package/template/scripts/lib/frontend-delivery.mjs +66 -2
  94. package/template/scripts/lib/strategic-feedback.mjs +33 -0
  95. package/template/scripts/lib/strategic-handoff-consumption.mjs +5 -0
  96. package/template/scripts/lib/strategic-handoff-io.mjs +1 -0
  97. package/template/scripts/lib/strategic-handoff.mjs +101 -10
  98. package/template/scripts/lib/user-decision-reuse.mjs +38 -0
  99. package/template/scripts/strategic-feedback +10 -0
  100. package/template/scripts/verify-frontend-strategic-preflight +12 -0
  101. package/template/skills-lock.json +10 -10
  102. package/template.manifest.json +1 -0
  103. package/template.snapshot.json +6 -5
@@ -0,0 +1,42 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://yss.local/schemas/strategic-feedback-adjudication-v1.json",
4
+ "title": "YSS Strategic Feedback Adjudication v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schema_version", "adjudication_id", "status", "feedback", "decision", "reason", "owner", "return_work_unit", "target_version", "evidence_refs", "decided_at"],
8
+ "properties": {
9
+ "schema_version": {"const": 1},
10
+ "adjudication_id": {"type": "string", "pattern": "^feedback-adjudication\\.[a-z0-9][a-z0-9-]*$"},
11
+ "status": {"const": "approved"},
12
+ "feedback": {
13
+ "type": "object",
14
+ "additionalProperties": false,
15
+ "required": ["ref", "digest"],
16
+ "properties": {
17
+ "ref": {"type": "string", "minLength": 1},
18
+ "digest": {"type": "string", "pattern": "^sha256:[a-f0-9]{64}$"}
19
+ }
20
+ },
21
+ "decision": {"enum": ["keep", "amend", "defer"]},
22
+ "reason": {"type": "string", "minLength": 1},
23
+ "owner": {"type": "string", "minLength": 1},
24
+ "return_work_unit": {"type": "string", "pattern": "^work-unit\\.[a-z0-9][a-z0-9-]*$"},
25
+ "target_version": {"type": "string", "minLength": 1},
26
+ "risk": {"type": "string", "minLength": 1},
27
+ "verification_plan": {"type": "string", "minLength": 1},
28
+ "approval_ref": {"type": "string", "minLength": 1},
29
+ "evidence_refs": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "minLength": 1}},
30
+ "decided_at": {"type": "string", "format": "date-time"}
31
+ },
32
+ "allOf": [
33
+ {
34
+ "if": {"properties": {"decision": {"enum": ["keep", "amend"]}}, "required": ["decision"]},
35
+ "then": {"required": ["approval_ref"]}
36
+ },
37
+ {
38
+ "if": {"properties": {"decision": {"const": "defer"}}, "required": ["decision"]},
39
+ "then": {"required": ["risk", "verification_plan"]}
40
+ }
41
+ ]
42
+ }
@@ -0,0 +1,216 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://yss.local/schemas/strategic-handoff-domain-strategy-v3.json",
4
+ "title": "YSS 业务边界与规则设计",
5
+ "type": "object",
6
+ "required": ["schema_version", "domain_strategy_id", "domain_version", "status", "contexts", "subdomains", "relationships", "scenarios", "concept_candidates", "invariants", "context_snapshot", "downstream_mapping", "evidence_refs", "approval"],
7
+ "properties": {
8
+ "traceability_version": {"const": 1},
9
+ "rule_catalog": {"type": "array", "items": {"type": "object", "additionalProperties": false, "required": ["rule_id", "statement", "responsible_context", "status"], "properties": {"rule_id": {"type": "string", "pattern": "^rule\\.[a-z0-9][a-z0-9-]*$"}, "statement": {"type": "string", "minLength": 1}, "responsible_context": {"type": "string", "minLength": 1}, "status": {"const": "confirmed"}, "evidence_refs": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "minLength": 1}}}}, "minItems": 1},
10
+ "schema_version": {"const": 3},
11
+ "domain_strategy_id": {"type": "string", "pattern": "^domain-strategy\\.[a-z0-9][a-z0-9-]*$"},
12
+ "domain_version": {"type": "string", "pattern": "^v[0-9]+$"},
13
+ "status": {"enum": ["draft", "ready-for-human", "approved", "stale", "blocked"]},
14
+ "contexts": {"type": "array", "minItems": 1, "items": {"$ref": "#/$defs/context"}},
15
+ "subdomains": {"type": "array", "minItems": 1, "items": {"$ref": "#/$defs/subdomain"}},
16
+ "relationships": {"type": "array", "items": {"$ref": "#/$defs/relationship"}},
17
+ "scenarios": {"type": "array", "minItems": 1, "items": {"$ref": "#/$defs/scenario"}},
18
+ "concept_candidates": {"type": "array", "items": {"$ref": "#/$defs/concept"}},
19
+ "invariants": {"type": "array", "items": {"$ref": "#/$defs/invariant"}},
20
+ "context_snapshot": {"$ref": "#/$defs/contextSnapshot"},
21
+ "downstream_mapping": {"type": "array"},
22
+ "evidence_refs": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
23
+ "approval": {"$ref": "#/$defs/approval"}
24
+ },
25
+ "$defs": {
26
+ "contextSnapshot": {
27
+ "type": "object",
28
+ "additionalProperties": false,
29
+ "required": ["context_ref", "context_schema_version", "document_digest", "referenced_terms_digest", "term_refs"],
30
+ "properties": {
31
+ "context_ref": {"const": "CONTEXT.md"},
32
+ "context_schema_version": {"const": 1},
33
+ "document_digest": {"type": "string", "pattern": "^sha256:[0-9a-f]{64}$"},
34
+ "referenced_terms_digest": {"type": "string", "pattern": "^sha256:[0-9a-f]{64}$"},
35
+ "term_refs": {"type": "array", "items": {"type": "string", "pattern": "^(Global|[A-Z][A-Za-z0-9]+)/[A-Z][A-Za-z0-9]+$"}, "uniqueItems": true}
36
+ }
37
+ },
38
+ "context": {
39
+ "type": "object",
40
+ "required": ["context_id", "name", "responsibilities", "non_responsibilities", "subdomain_type", "owner", "status"],
41
+ "properties": {
42
+ "context_id": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
43
+ "name": {"type": "string", "minLength": 1},
44
+ "responsibilities": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
45
+ "non_responsibilities": {"type": "array", "items": {"type": "string", "minLength": 1}},
46
+ "subdomain_type": {"enum": ["Core Domain", "Supporting Subdomain", "Generic Subdomain"]},
47
+ "owner": {"type": "string", "minLength": 1},
48
+ "status": {"enum": ["candidate", "confirmed", "stale"]}
49
+ }
50
+ },
51
+ "subdomain": {
52
+ "type": "object",
53
+ "required": ["subdomain_id", "name", "type", "rationale", "evidence_refs"],
54
+ "properties": {
55
+ "subdomain_id": {"type": "string", "pattern": "^subdomain\\.[a-z0-9][a-z0-9-]*$"},
56
+ "name": {"type": "string", "minLength": 1},
57
+ "type": {"enum": ["Core Domain", "Supporting Subdomain", "Generic Subdomain"]},
58
+ "rationale": {"type": "string", "minLength": 1},
59
+ "evidence_refs": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}}
60
+ }
61
+ },
62
+ "relationship": {
63
+ "type": "object",
64
+ "required": ["relationship_id", "from_context", "to_context", "relationship_pattern", "semantic_upstream", "semantic_downstream", "business_authority", "model_change_impact", "transport_direction", "translation_responsibility", "direction_explanation"],
65
+ "properties": {
66
+ "relationship_id": {"type": "string", "pattern": "^relationship\\.[a-z0-9][a-z0-9-]*$"},
67
+ "from_context": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
68
+ "to_context": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
69
+ "relationship_pattern": {"enum": ["Partnership", "Customer/Supplier", "Conformist", "Anti-Corruption Layer", "Open Host Service", "Published Language", "Shared Kernel", "Separate Ways"]},
70
+ "semantic_upstream": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
71
+ "semantic_downstream": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
72
+ "business_authority": {"type": "string", "minLength": 1},
73
+ "model_change_impact": {"type": "string", "minLength": 1},
74
+ "transport_direction": {"type": "string", "minLength": 1},
75
+ "translation_responsibility": {"type": "string", "minLength": 1},
76
+ "direction_explanation": {"type": "string", "minLength": 1}
77
+ }
78
+ },
79
+ "scenario": {
80
+ "type": "object",
81
+ "required": ["scenario_id", "actor", "preconditions", "commands", "rules", "events", "failure_results", "responsible_context", "consumers", "status"],
82
+ "properties": {
83
+ "rule_refs": {"type": "array", "items": {"type": "string", "minLength": 1}, "minItems": 1},
84
+ "critical": {"type": "boolean"},
85
+ "success_results": {"type": "array", "items": {"type": "string", "minLength": 1}, "minItems": 1},
86
+ "scenario_id": {"type": "string", "pattern": "^scenario\\.[a-z0-9][a-z0-9-]*$"},
87
+ "actor": {"type": "string", "minLength": 1},
88
+ "preconditions": {"type": "array", "items": {"type": "string"}},
89
+ "commands": {"type": "array", "minItems": 1, "items": {"type": "string"}},
90
+ "rules": {"type": "array", "minItems": 1, "items": {"type": "string"}},
91
+ "events": {"type": "array", "items": {"type": "string"}},
92
+ "failure_results": {"type": "array", "minItems": 1, "items": {"type": "string"}},
93
+ "responsible_context": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
94
+ "consumers": {"type": "array", "items": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"}},
95
+ "status": {"enum": ["candidate", "confirmed", "stale"]}
96
+ }
97
+ },
98
+ "concept": {
99
+ "type": "object",
100
+ "required": ["concept_id", "name", "context_id", "identity_features", "lifecycle", "confidence", "status"],
101
+ "properties": {
102
+ "concept_id": {"type": "string", "pattern": "^domain-concept\\.[a-z0-9][a-z0-9-]*$"},
103
+ "name": {"type": "string", "minLength": 1},
104
+ "context_id": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
105
+ "identity_features": {"type": "array", "minItems": 1, "items": {"type": "string"}},
106
+ "lifecycle": {"type": "array", "minItems": 1, "items": {"type": "string"}},
107
+ "invariant_refs": {"type": "array", "items": {"type": "string"}},
108
+ "possible_tactical_role": {"type": "string"},
109
+ "confidence": {"enum": ["low", "medium", "high"]},
110
+ "status": {"enum": ["candidate", "confirmed", "stale"]}
111
+ }
112
+ },
113
+ "invariant": {
114
+ "type": "object",
115
+ "required": ["invariant_id", "statement", "responsible_context", "scenario_refs", "verification_method"],
116
+ "properties": {
117
+ "rule_ref": {"type": "string", "minLength": 1},
118
+ "invariant_id": {"type": "string", "pattern": "^invariant\\.[a-z0-9][a-z0-9-]*$"},
119
+ "statement": {"type": "string", "minLength": 1},
120
+ "responsible_context": {"type": "string", "pattern": "^[A-Z][A-Za-z0-9]+$"},
121
+ "scenario_refs": {"type": "array", "minItems": 1, "items": {"type": "string"}},
122
+ "verification_method": {"type": "string", "minLength": 1}
123
+ }
124
+ },
125
+ "mapping": {
126
+ "type": "object",
127
+ "required": ["domain_change", "impacts", "propagation", "reapproval_condition"],
128
+ "properties": {
129
+ "domain_change": {"type": "string", "minLength": 1},
130
+ "impacts": {"type": "array", "minItems": 1, "items": {"type": "string"}},
131
+ "propagation": {"enum": ["direct", "transitive", "stale"]},
132
+ "reapproval_condition": {"type": "string", "minLength": 1}
133
+ }
134
+ },
135
+ "mappingV3": {
136
+ "type": "object",
137
+ "additionalProperties": false,
138
+ "required": ["mapping_id", "source_refs", "consumer_capability", "impacts", "propagation", "reapproval_condition", "evidence_refs"],
139
+ "properties": {
140
+ "mapping_id": {"type": "string", "pattern": "^mapping\\.[a-z0-9][a-z0-9-]*$"},
141
+ "source_refs": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "pattern": "^(rule|scenario|invariant)\\.[a-z0-9][a-z0-9-]*$"}},
142
+ "consumer_capability": {"enum": ["backend-technical-design", "frontend-engineering-design", "delivery-coordination"]},
143
+ "impacts": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "minLength": 1}},
144
+ "propagation": {"enum": ["direct", "transitive", "not-applicable", "stale"]},
145
+ "reapproval_condition": {"type": "string", "minLength": 1},
146
+ "evidence_refs": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "minLength": 1}}
147
+ }
148
+ },
149
+ "approval": {
150
+ "type": "object",
151
+ "required": ["approval_ref", "approver", "persisted_ref", "current_version"],
152
+ "properties": {
153
+ "approval_ref": {"type": "string", "minLength": 1},
154
+ "approver": {"type": "string", "minLength": 1},
155
+ "persisted_ref": {"type": "string", "minLength": 1},
156
+ "current_version": {"type": "string", "pattern": "^v[0-9]+$"}
157
+ }
158
+ }
159
+ },
160
+ "allOf": [
161
+ {
162
+ "if": {"properties": {"schema_version": {"const": 3}}, "required": ["schema_version"]},
163
+ "then": {
164
+ "required": ["traceability_version", "rule_catalog"],
165
+ "properties": {
166
+ "traceability_version": {"const": 1},
167
+ "rule_catalog": {
168
+ "items": {
169
+ "required": ["evidence_refs"],
170
+ "properties": {
171
+ "evidence_refs": {
172
+ "type": "array",
173
+ "minItems": 1,
174
+ "uniqueItems": true,
175
+ "items": {"type": "string", "minLength": 1}
176
+ }
177
+ }
178
+ }
179
+ },
180
+ "scenarios": {
181
+ "items": {
182
+ "required": ["rule_refs", "critical", "success_results", "evidence_refs"],
183
+ "properties": {
184
+ "evidence_refs": {
185
+ "type": "array",
186
+ "minItems": 1,
187
+ "uniqueItems": true,
188
+ "items": {"type": "string", "minLength": 1}
189
+ }
190
+ }
191
+ }
192
+ },
193
+ "invariants": {
194
+ "items": {
195
+ "required": ["rule_ref", "evidence_refs"],
196
+ "properties": {
197
+ "evidence_refs": {
198
+ "type": "array",
199
+ "minItems": 1,
200
+ "uniqueItems": true,
201
+ "items": {"type": "string", "minLength": 1}
202
+ }
203
+ }
204
+ }
205
+ },
206
+ "downstream_mapping": {"items": {"$ref": "#/$defs/mappingV3"}}
207
+ }
208
+ },
209
+ "else": {
210
+ "properties": {
211
+ "downstream_mapping": {"items": {"$ref": "#/$defs/mapping"}}
212
+ }
213
+ }
214
+ }
215
+ ]
216
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://yss.local/schemas/strategic-handoff-import-receipt-v2.json",
4
+ "title": "YSS Strategic Handoff Import Receipt v2",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schema_version", "bundle_id", "version", "bundle_digest", "package_ref", "target_context_digest", "target_profile_id", "selected_consumer_capabilities", "routes", "status"],
8
+ "properties": {
9
+ "schema_version": {"const": 2},
10
+ "bundle_id": {"type": "string", "pattern": "^strategic-design-handoff\\.[a-z0-9][a-z0-9-]*$"},
11
+ "version": {"type": "string", "pattern": "^v[1-9][0-9]*$"},
12
+ "bundle_digest": {"type": "string", "pattern": "^sha256:[a-f0-9]{64}$"},
13
+ "package_ref": {"type": "string", "minLength": 1},
14
+ "target_context_digest": {"type": "string", "pattern": "^sha256:[a-f0-9]{64}$"},
15
+ "target_profile_id": {"type": "string", "minLength": 1},
16
+ "selected_consumer_capabilities": {
17
+ "type": "array",
18
+ "minItems": 1,
19
+ "uniqueItems": true,
20
+ "items": {"enum": ["backend-technical-design", "frontend-engineering-design", "delivery-coordination"]}
21
+ },
22
+ "routes": {
23
+ "type": "array",
24
+ "minItems": 1,
25
+ "items": {
26
+ "type": "object",
27
+ "additionalProperties": false,
28
+ "required": ["route_id", "capability", "activation", "artifact_refs"],
29
+ "properties": {
30
+ "route_id": {"type": "string", "pattern": "^route\\.[a-z0-9][a-z0-9-]*$"},
31
+ "capability": {"enum": ["backend-technical-design", "frontend-engineering-design", "delivery-coordination"]},
32
+ "activation": {"enum": ["required", "optional", "not-applicable"]},
33
+ "artifact_refs": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "minLength": 1}}
34
+ }
35
+ }
36
+ },
37
+ "status": {"const": "pending-context-reconciliation"}
38
+ }
39
+ }
@@ -0,0 +1,148 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://yss.local/schemas/strategic-handoff-stage-decision-package-v3.json",
4
+ "title": "YSS Stage Decision Package",
5
+ "type": "object",
6
+ "required": ["schema_version", "stage_decision_id", "package_version", "status", "problem_statement", "target_users", "mvp", "non_goals", "success_criteria", "test_seams", "confirmed_decisions", "assumptions", "constraints", "unresolved_items", "context_snapshot", "domain_strategy_ref", "impact_assessment", "downstream_mapping", "evidence_refs", "approval"],
7
+ "properties": {
8
+ "schema_version": {"const": 3},
9
+ "stage_decision_id": {"type": "string", "pattern": "^stage-decision\\.[a-z0-9][a-z0-9-]*$"},
10
+ "package_version": {"type": "string", "pattern": "^v[0-9]+$"},
11
+ "status": {"enum": ["draft", "ready-for-human", "approved", "stale", "blocked"]},
12
+ "problem_statement": {"type": "string", "minLength": 1},
13
+ "target_users": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
14
+ "mvp": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
15
+ "non_goals": {"type": "array", "items": {"type": "string", "minLength": 1}},
16
+ "success_criteria": {"type": "array", "minItems": 1},
17
+ "test_seams": {"type": "array", "minItems": 1},
18
+ "confirmed_decisions": {"type": "array", "minItems": 1},
19
+ "assumptions": {"type": "array"},
20
+ "constraints": {"type": "array"},
21
+ "unresolved_items": {"type": "array", "items": {"$ref": "#/$defs/unresolved"}},
22
+ "context_snapshot": {"$ref": "#/$defs/contextSnapshot"},
23
+ "domain_strategy_ref": {"$ref": "#/$defs/domainRef"},
24
+ "impact_assessment": {"$ref": "#/$defs/impact"},
25
+ "downstream_mapping": {"type": "array", "minItems": 1},
26
+ "evidence_refs": {"type": "array", "minItems": 1, "items": {"type": "string", "minLength": 1}},
27
+ "approval": {"$ref": "#/$defs/approval"}
28
+ },
29
+ "$defs": {
30
+ "contextSnapshot": {
31
+ "type": "object",
32
+ "additionalProperties": false,
33
+ "required": ["context_ref", "context_schema_version", "document_digest", "referenced_terms_digest", "term_refs"],
34
+ "properties": {
35
+ "context_ref": {"const": "CONTEXT.md"},
36
+ "context_schema_version": {"const": 1},
37
+ "document_digest": {"type": "string", "pattern": "^sha256:[0-9a-f]{64}$"},
38
+ "referenced_terms_digest": {"type": "string", "pattern": "^sha256:[0-9a-f]{64}$"},
39
+ "term_refs": {"type": "array", "items": {"type": "string", "pattern": "^(Global|[A-Z][A-Za-z0-9]+)/[A-Z][A-Za-z0-9]+$"}, "uniqueItems": true}
40
+ }
41
+ },
42
+ "unresolved": {
43
+ "type": "object",
44
+ "required": ["item", "type", "owner", "next_action", "target_version"],
45
+ "properties": {
46
+ "item": {"type": "string", "minLength": 1},
47
+ "type": {"enum": ["blocker", "deferred"]},
48
+ "owner": {"type": "string", "minLength": 1},
49
+ "next_action": {"type": "string", "minLength": 1},
50
+ "target_version": {"type": "string", "minLength": 1}
51
+ }
52
+ },
53
+ "domainRef": {
54
+ "type": "object",
55
+ "required": ["domain_strategy_id", "domain_version", "digest", "status", "persisted_ref"],
56
+ "properties": {
57
+ "domain_strategy_id": {"type": "string", "pattern": "^domain-strategy\\.[a-z0-9][a-z0-9-]*$"},
58
+ "domain_version": {"type": "string", "pattern": "^v[0-9]+$"},
59
+ "digest": {"type": "string", "minLength": 1},
60
+ "status": {"enum": ["approved", "stale", "blocked"]},
61
+ "persisted_ref": {"type": "string", "minLength": 1}
62
+ }
63
+ },
64
+ "impact": {
65
+ "type": "object",
66
+ "required": ["ui", "api", "data", "backend", "frontend", "cross_repo", "high_risk"],
67
+ "properties": {
68
+ "ui": {"type": "boolean"},
69
+ "api": {"type": "boolean"},
70
+ "data": {"type": "boolean"},
71
+ "backend": {"type": "boolean"},
72
+ "frontend": {"type": "boolean"},
73
+ "cross_repo": {"type": "boolean"},
74
+ "high_risk": {"type": "boolean"}
75
+ }
76
+ },
77
+ "mapping": {
78
+ "type": "object",
79
+ "required": ["domain_change", "consumer", "propagation", "reapproval_condition"],
80
+ "properties": {
81
+ "domain_change": {"type": "string", "minLength": 1},
82
+ "consumer": {"type": "string", "minLength": 1},
83
+ "propagation": {"enum": ["direct", "transitive", "not-applicable", "stale"]},
84
+ "reapproval_condition": {"type": "string", "minLength": 1}
85
+ }
86
+ },
87
+ "recordV3": {
88
+ "type": "object",
89
+ "additionalProperties": false,
90
+ "required": ["id", "statement", "evidence_refs"],
91
+ "properties": {
92
+ "id": {"type": "string", "pattern": "^(success-criterion|test-seam|decision|assumption|constraint)\\.[a-z0-9][a-z0-9-]*$"},
93
+ "statement": {"type": "string", "minLength": 1},
94
+ "source_refs": {"type": "array", "uniqueItems": true, "items": {"type": "string", "pattern": "^(rule|scenario|invariant)\\.[a-z0-9][a-z0-9-]*$"}},
95
+ "evidence_refs": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "minLength": 1}},
96
+ "status": {"enum": ["confirmed", "candidate", "stale"]}
97
+ }
98
+ },
99
+ "mappingV3": {
100
+ "type": "object",
101
+ "additionalProperties": false,
102
+ "required": ["mapping_id", "source_refs", "consumer_capability", "propagation", "reapproval_condition", "evidence_refs"],
103
+ "properties": {
104
+ "mapping_id": {"type": "string", "pattern": "^mapping\\.[a-z0-9][a-z0-9-]*$"},
105
+ "source_refs": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "pattern": "^(rule|scenario|invariant)\\.[a-z0-9][a-z0-9-]*$"}},
106
+ "consumer_capability": {"enum": ["backend-technical-design", "frontend-engineering-design", "delivery-coordination"]},
107
+ "propagation": {"enum": ["direct", "transitive", "not-applicable", "stale"]},
108
+ "reapproval_condition": {"type": "string", "minLength": 1},
109
+ "evidence_refs": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "minLength": 1}}
110
+ }
111
+ },
112
+ "approval": {
113
+ "type": "object",
114
+ "required": ["approval_ref", "approver", "persisted_ref", "current_version"],
115
+ "properties": {
116
+ "approval_ref": {"type": "string", "minLength": 1},
117
+ "approver": {"type": "string", "minLength": 1},
118
+ "persisted_ref": {"type": "string", "minLength": 1},
119
+ "current_version": {"type": "string", "pattern": "^v[0-9]+$"}
120
+ }
121
+ }
122
+ },
123
+ "allOf": [
124
+ {
125
+ "if": {"properties": {"schema_version": {"const": 3}}, "required": ["schema_version"]},
126
+ "then": {
127
+ "properties": {
128
+ "success_criteria": {"items": {"$ref": "#/$defs/recordV3"}},
129
+ "test_seams": {"items": {"$ref": "#/$defs/recordV3"}},
130
+ "confirmed_decisions": {"items": {"$ref": "#/$defs/recordV3"}},
131
+ "assumptions": {"items": {"$ref": "#/$defs/recordV3"}},
132
+ "constraints": {"items": {"$ref": "#/$defs/recordV3"}},
133
+ "downstream_mapping": {"items": {"$ref": "#/$defs/mappingV3"}}
134
+ }
135
+ },
136
+ "else": {
137
+ "properties": {
138
+ "success_criteria": {"items": {"type": "string", "minLength": 1}},
139
+ "test_seams": {"items": {"type": "string", "minLength": 1}},
140
+ "confirmed_decisions": {"items": {"type": "string", "minLength": 1}},
141
+ "assumptions": {"items": {"type": "string", "minLength": 1}},
142
+ "constraints": {"items": {"type": "string", "minLength": 1}},
143
+ "downstream_mapping": {"items": {"$ref": "#/$defs/mapping"}}
144
+ }
145
+ }
146
+ }
147
+ ]
148
+ }
@@ -4,9 +4,9 @@
4
4
 
5
5
  ## 源资产准备
6
6
 
7
- 1. 源仓必须为 `project-instance`。业务边界与规则合同保留 schema v2,正式便携导出要求 `traceability_version: 1`。`rule_catalog` 的每行包含稳定 `rule_id`、`statement`、`responsible_context`、`status: confirmed`。不得用行号、文字 hash 或导出顺序生成业务身份。
7
+ 1. 源仓必须为 `project-instance`。新交付使用 Domain Strategy v3 与 Stage Decision Package v3;规则、场景、决定、假设、约束、成功标准、测试 seam 与 downstream mapping 使用稳定 ID 和证据。v2 仅用于历史 Handoff v3 的只读验证;修改或重发须显式迁移、重新批准。不得用行号、文字 hash 或导出顺序生成业务身份。
8
8
  2. 每个场景明确 `critical`、`rule_refs`、`success_results` 和既有 `failure_results`;兼容字段 `rules` 必须与引用规则正文一致。不变量使用 `rule_ref`,并通过 `scenario_refs` 指向确实覆盖该规则的场景。缺身份或关联先回战略方确认、更新并重新批准,导出器不猜测。
9
- 3. Handoff v3 的 `package_export` 使用导出 schema。`approvals` 按 `source` 字段及 `handoff` 绑定批准记录,声明 `record_ref`、`gate_id`、`digest_kind`。沿用源角色表的现有门禁;当前综合模板的战略、阶段决策及交接资产统一绑定 `gate.plan-approved`,Spec 对应 Spec 基线批准,原型和视觉基线对应 `gate.product-design-approved`;历史包及其他源 profile 仍按包内明确登记的源批准规则验证,不自动迁移当前门禁状态。
9
+ 3. 新交付使用 Handoff v4;历史 Handoff v3 继续按冻结 v3 schema 和单目标语义严格验证,不原地升级。校验器先读取 `schema_version` 再选择固定 schema,未知版本输出支持列表并 fail closed。`package_export` 的 `approvals` 按 `source` 字段及 `handoff` 绑定批准记录,声明 `record_ref`、`gate_id`、`digest_kind`。沿用源角色表的现有门禁;当前综合模板的战略、阶段决策及交接资产统一绑定 `gate.plan-approved`,Spec 对应 Spec 基线批准,原型和视觉基线对应 `gate.product-design-approved`;历史包及其他源 profile 仍按包内明确登记的源批准规则验证,不自动迁移当前门禁状态。
10
10
  4. 批准记录除既有会签字段,还要在 `artifact_bindings` 中逐项绑定 `{id, version, digest}`。战略/阶段建议 `canonical-json`;普通文件使用 `sha256-bytes`;视觉基线使用 `visual-baseline`。正文中的 `approved` 和可读取批准路径不能替代当前字节的批准绑定。源角色表要求用户决定记录时,接收端必须支持并核验该策略;旧工具缺少该能力时阻断并要求升级,不能按旧规则放行。
11
11
  5. `additional_files` 明确补充依赖;`reference_map` 将 `evidence.*` 稳定证据引用解析为仓内路径。源资产、批准记录、证据引用、Markdown 本地链接和显式目录共同形成依赖闭包。HTTP 引用保留为引用,不在导出时下载网页。
12
12
  6. `prototype` 指定 `profile`、`preview_root`、`entry_ref`、`verification_ref`、`verification_digest`(验证记录的字节摘要);H2 另须 `source_root`、`lock_ref` 和 `source_digest`(源码目录树摘要,算法同下述预览树)。源码交付目录不含 node_modules / .git;锁文件与源码一同保存。预览目录须资源闭合,可通过本地静态服务离线浏览。源码、锁文件或验证记录变化须更新交接摘要并重新批准。
@@ -27,9 +27,17 @@ scripts/strategic-handoff import --bundle <目录或ZIP> --target-root <研发
27
27
 
28
28
  `manifest.json` 的 `files` 声明所有文件的字节摘要和大小。`bundle_digest` 是删除自身字段后 canonical JSON 的 SHA-256;不把整 ZIP 摘要当逻辑版本摘要。目录与 ZIP 的逻辑摘要相同。源合同的既有语义 digest 另行复核。目录/ZIP 已存在时拒绝覆盖,同身份版本不同内容的导入拒绝;已验过且相同的重复导入返回 `already-imported`。限制为 20,000 文件、512 MiB 展开内容;拒绝 ZIP 路径穿越、重复路径、大小写碰撞和符号链接。
29
29
 
30
+ ## Handoff v4 消费者路由
31
+
32
+ `consumer_routes` 固定表达三种能力,不绑定仓名:`backend-technical-design`、`frontend-engineering-design`、`delivery-coordination`。每条路由记录稳定 `route_id`、`required | optional | not-applicable`、影响引用、入口工作单元、预期输出、依赖和 Context Reconciliation 要求;`optional` / `not-applicable` 必须有原因与证据,不能产生 `ready-for-agent`。
33
+
34
+ - Backend/API/Data 任一影响为真时,backend 路由必须 `required`,入口是 `work-unit.technical-design`;架构只在下游按已批准决定分流 DDD/MVC。
35
+ - Frontend/UI 任一影响为真时,frontend 路由必须 `required`,入口是 `work-unit.frontend-engineering-design`;仅在 backend 路由生效时依赖后端交付。
36
+ - 任一交付路由生效时 coordination 必须 `required`;全部无实现影响时三条路由均为有证据的 `not-applicable`。
37
+
30
38
  ## 下游接收与逐条追溯
31
39
 
32
- 导入落盘到 `docs/handoffs/<handoff-id>/<version>/`,包含不可变 `package/`、`import-receipt.json`、`context-reconciliation-draft.json`、`tactical-traceability-draft.json`、`upstream-change-impact.json`。仅写快照与草案,不自动更新根词汇表或批准状态。目标侧确认增量后更新唯一根 `CONTEXT.md`,生成既有 schema 的正式 reconciliation 并校验。
40
+ 导入落盘到 `docs/handoffs/<handoff-id>/<version>/`。Handoff v3 继续生成 Import Receipt v1 和原固定文件名;Handoff v4 生成 Import Receipt v2,按目标 profile 的消费者能力登记 route、产物引用和状态,并分别生成后端追踪、Frontend Strategic Preflight / 前端追踪、协调状态索引草案。共同生成 route-aware Context Reconciliation 和 upstream impact 草案。仅写快照与草案,不自动更新根词汇表或批准状态。目标侧确认增量后更新唯一根 `CONTEXT.md` 并完成正式 reconciliation。
33
41
 
34
42
  Technical Design Contract v2(DDD / MVC 共用)的 `strategic_handoff` 绑定 `import_receipt_ref`、`bundle_digest`、`context_reconciliation_ref` 和 `rows`。逐条覆盖全部规则与 `critical: true` 的成功/失败场景;行字段如下:
35
43
 
@@ -45,7 +53,18 @@ scripts/verify-strategic-handoff-consumption --root <研发项目根> --slice <
45
53
  node .agents/skills/yss-technical-design/scripts/validate-technical-design.mjs <技术设计合同> --root <研发项目根>
46
54
  ```
47
55
 
48
- 新交接的 target 使用 `yss-technical-design` / `technical-design-contract`,对账必须在通用入口前完成;旧 `yss-tactical-design` / `tactical-design-contract` 成对只读兼容,不修改已冻结包。`tactical_refs` 在 v2 可指向 `design` 中的 MVC 模块、用例、规则或 DDD 对象,测试 seam 同样在对应分支解析。无战略交接包的 MVC 项目直接消费批准需求,不要求补造战略 DDD。
56
+ Handoff v4 后端消费必须绑定 `backend-technical-design` 的 `route_id`,先对账,再由 `yss-technical-design` 依据已批准架构调用 `yss-tactical-design` 或 `yss-mvc-design`。Handoff v3 的 `yss-technical-design` / `yss-tactical-design` 单目标组合只读兼容,不修改已冻结包。`tactical_refs` 在 v2 Technical Design 可指向 MVC 或 DDD 分支对象;无战略交接包的 MVC 项目直接消费批准需求,不补造战略 DDD。
57
+
58
+ 前端先验证 `frontend-strategic-preflight.schema.json`,只允许起草前端工程设计与实现计划,固定返回 `ready_for_agent: false`。最终 Frontend Delivery Acceptance v2 在 Backend/API/Data 有影响时必须绑定真实 Backend Delivery 收据与版本探测;UI-only 时使用与战略路由一致的 `backend-not-applicable`,此时 `operation_ids` 必须为空。无论哪条路径,当前且已批准的 Slice Contract 仍是实现入口。
59
+
60
+ ## 消费者反馈闭环
61
+
62
+ Consumer Feedback v1 与 Feedback Adjudication v1 独立保存在已交付 package 外,分别绑定 bundle ID/version/digest、route、source ID/digest 和 feedback 原始字节 digest。`keep` 允许消费者重新核验后继续;`amend` 保持旧路径 blocked,战略资产升版、重新批准并导出新的 Handoff v4;`defer` 对 blocking 问题继续阻断,非阻断问题只有责任人、风险、验证计划和目标版本齐全时继续。任何范围或风险变化重新应用用户决定失效规则;禁止修改历史 package 或用旧摘要冒充当前裁决。
63
+
64
+ ```bash
65
+ scripts/strategic-feedback verify-feedback --root <消费者项目根> <feedback.json>
66
+ scripts/strategic-feedback verify-adjudication --root <消费者项目根> <adjudication.json>
67
+ ```
49
68
 
50
69
  整体验证有未落实项时返回 blocked;按切片验证可放行有证据证明不依赖这些项的切片。输出 `block_all`、`blocked_slice_refs`、`issues`、实际消费包摘要与战术摘要。通过只证明结构化映射完整和引用可核验,业务语义仍需独立评审;不能代替 Slice Contract 批准。
51
70
 
@@ -54,3 +73,17 @@ node .agents/skills/yss-technical-design/scripts/validate-technical-design.mjs <
54
73
  ## 维护与同步
55
74
 
56
75
  共享脚本和包 schema 以主模板为维护源,通过 `scripts/sync-strategic-handoff-tools` 同步到设计/研发模板;源战略 schema 的离线验证副本由该脚本从 canonical `yss-stage-decision/references` 派生。三仓技能仍只编辑 `.agents/skills`,再生成各 runtime 投影与锁。CLI 快照使用各自同步工具,工作树快照用于集成验证,不代表已发布 commit。
76
+
77
+ ## 当前用户决定与交接复用
78
+
79
+ 源角色策略以 `required_capabilities: [strategic-decision-reuse-v1]` 声明本节语义;不支持该能力的接收器必须拒绝。历史包仍按包内源策略校验,不升级旧批准。
80
+
81
+ 当前会签绑定 `subject_ref`、`approval_scope`、`user_decision_ref`。只有最终战略交接允许用 `decision_reuse_ref` 引用复用证明;原回复的 boundary、资产和范围保持不变。checkpoint 的 `human_review.decision_reuse` 保存 `{target_gate, ref}`,会签必须引用同一证明。数字人审查仍独立完成。
82
+
83
+ 复用证明采用 schema v1,`kind: strategic-decision-reuse-v1`,包含 `target_gate`、`scope_ref`、`scope`、`requirements`。每个 requirement 保留原 `boundary`、`subject_ref`、`scope`、`user_decision_ref`。校验当前原始回复、负责人、撤销、资产摘要和范围,不接受自填布尔值作为覆盖证据。
84
+
85
+ 独立交付范围清单采用 schema v1,`kind: strategic-delivery-scope`,包含 `delivery_ref`、`assets`、`risks`、`conditions`。每项资产包含 `ref`、`version`、原始字节 `digest`、`boundary` 和 `scope`;原决定的 subject 或 basis 必须覆盖该资产,专业边界须一致。风险必须已出现在原决定的 risks 中,授权条件必须已出现在 next_actions 中;无法证明的部分补充确认。
86
+
87
+ `delivery_ref` 是交接正文去除 `package_export`、`status` 后的独立 JSON/YAML 快照;也必须列入 assets 并由既有真实决定明确覆盖;不强制新增交接回复。所有实际 source 资产及视觉基线 manifest 均须逐项覆盖。业务 Ticket 已被 Spec 的当前行为与验收范围明确覆盖时,可引用该 Spec 决定;数字人交接会签仍使用交接门禁,不改写原回复的专业边界。先固定该快照与业务资产,再确认和会签,最后组装包,避免摘要循环。仅重新组装传输包且业务依据和范围不变时复用有效确认。
88
+
89
+ 导出将范围清单、复用证明、原决定及其来源依赖一起收集。离线 verify 重新检查实际交付与批准覆盖;缺文件、摘要变化、范围遗漏、未知能力均阻断,不回写旧包。
@@ -22,6 +22,7 @@ stage_trace:
22
22
  downstream_impacts: []
23
23
  ticket_sync:
24
24
  status: pending
25
+ # 仅登记消费者收据、反馈/裁决和交付验收等权威资产引用,不复制其状态。
25
26
  refs: []
26
27
  verification:
27
28
  commands: []
@@ -33,6 +33,7 @@ stage_trace:
33
33
  downstream_impacts: []
34
34
  ticket_sync:
35
35
  status: <pending|synced|not-applicable>
36
+ # refs 关联消费者收据、反馈/裁决和交付验收等权威资产,不复制其机器状态。
36
37
  refs: []
37
38
  next_work_unit: <stable work-unit id>
38
39
  verification:
@@ -1,3 +1,4 @@
1
+ import { assertApprovalUserDecision } from './user-decision-reuse.mjs';
1
2
  import { existsSync, readFileSync } from "node:fs";
2
3
  import path from "node:path";
3
4
  import { parseDocument } from "../vendor/yaml.mjs";
@@ -101,7 +102,7 @@ export function validateApprovalRecord(record, { rolesDoc, requireApproved = fal
101
102
 
102
103
  function assertRecordUserDecision(record, registry, options) {
103
104
  if (!registry.user_decision_policy.gates.includes(record.gate_id) && countersignRuleForGate(registry.gate_policy, record.gate_id)?.bucket !== "biological_human") return;
104
- const result = assertUserDecisionRequirement({ boundary: record.gate_id, subject_ref: record.subject_ref, scope: record.approval_scope, user_decision_ref: record.user_decision_ref }, { ...options, rolesDoc: registry });
105
+ const result = assertApprovalUserDecision(record, registry, options);
105
106
  if (record.actor_kind === "biological-human" && result.validated.some((item) => item.principal_ref !== record.principal_ref)) fail("user-decision-responder-mismatch: 生物人会签者与原始回复者不一致");
106
107
  }
107
108
 
@@ -6,7 +6,7 @@ import { read, safe, ensure, hash, digest, json, files, write, project, schema,
6
6
 
7
7
  // Evidence binds the deliverable basis, avoiding a circular hash through its own logs.
8
8
  export function backendDeliveryBasis(delivery) {
9
- return digest(Object.fromEntries(['delivery_id','version','strategic_bundle_digest','scope','openapi','slice_contract','build','environment'].map(key=>[key,delivery[key]])));
9
+ return digest(Object.fromEntries(['delivery_id','version','strategic_bundle_digest','strategic_route_id','scope','openapi','slice_contract','build','environment'].filter(key=>delivery[key]!==undefined).map(key=>[key,delivery[key]])));
10
10
  }
11
11
 
12
12
  function boundFile(root, binding) {
@@ -57,6 +57,10 @@ export async function inspectBackendDelivery(root, ref) {
57
57
  verification(root,delivery.verification.deployment,basis,'backend-deployment');
58
58
  return openBundle(safe(root,delivery.strategic_bundle_ref),bundle=>{
59
59
  ensure(bundle.manifest.bundle_digest===delivery.strategic_bundle_digest,'后端交付与战略版本不一致');
60
+ if(bundle.handoff.schema_version===4){
61
+ const route=bundle.handoff.consumer_routes.find(item=>item.capability==='backend-technical-design');
62
+ ensure(route&&route.activation!=='not-applicable'&&delivery.strategic_route_id===route.route_id,'后端交付未绑定当前 backend-technical-design route_id');
63
+ }
60
64
  const sources=new Set([...bundle.indexes.rules.map(x=>x.rule_id),...bundle.indexes.scenarios.map(x=>x.scenario_id)]);
61
65
  ensure(delivery.scope.source_ids.every(id=>sources.has(id)),'后端交付引用未知规则/场景');
62
66
  const scenarios=bundle.indexes.scenarios.filter(x=>delivery.scope.source_ids.includes(x.scenario_id));
@@ -152,14 +156,22 @@ export async function importBackendDelivery({bundle,targetRoot}) {
152
156
  }
153
157
  const strategic=await importBundle({bundle:safe(b.source,b.delivery.strategic_bundle_ref),targetRoot:target});
154
158
  const strategicReceipt=read(safe(target,strategic.receipt_ref));
155
- const trace=read(safe(target,`${path.posix.dirname(strategic.receipt_ref)}/tactical-traceability-draft.json`));
159
+ const strategicBase=path.posix.dirname(strategic.receipt_ref);
160
+ const frontendRoute=strategicReceipt.schema_version===2?strategicReceipt.routes.find(route=>route.capability==='frontend-engineering-design'):null;
161
+ const traceRef=frontendRoute?.artifact_refs.find(item=>item.endsWith('frontend-traceability-draft.json'))||`${strategicBase}/tactical-traceability-draft.json`;
162
+ const trace=read(safe(target,traceRef));
156
163
  mkdirSync(path.dirname(destination),{recursive:true});
157
164
  const staging=mkdtempSync(path.join(path.dirname(destination),'.backend-import-'));
158
165
  try {
159
166
  cpSync(b.root,path.join(staging,'package'),{recursive:true,errorOnExist:true,force:false});
160
167
  const receipt={schema_version:1,delivery_id:b.delivery.delivery_id,version:b.delivery.version,bundle_digest:b.manifest.bundle_digest,package_ref:`${ref}/package`};
161
168
  write(staging,'import-receipt.json',json(receipt));
162
- write(staging,'frontend-acceptance-draft.json',json({schema_version:1,status:'draft',slice_id:b.delivery.scope.slice_id,backend_delivery:{import_receipt_ref:`${ref}/import-receipt.json`,bundle_digest:b.manifest.bundle_digest},strategic_handoff:{import_receipt_ref:strategic.receipt_ref,bundle_digest:strategicReceipt.bundle_digest,context_reconciliation_ref:'',rows:trace.rows.map(({tactical_refs,test_seam_refs,...row})=>({...row,frontend_case_refs:[]}))},frontend_cases:[]}));
169
+ const strategicHandoff={import_receipt_ref:strategic.receipt_ref,bundle_digest:strategicReceipt.bundle_digest,...(trace.route_id?{route_id:trace.route_id}:{}),context_reconciliation_ref:'',rows:trace.rows.map(({tactical_refs,test_seam_refs,...row})=>({...row,frontend_case_refs:[]}))};
170
+ if(strategicReceipt.schema_version===2){
171
+ ensure(frontendRoute,'Handoff v4 Import Receipt 未选择 frontend-engineering-design 能力');
172
+ const preflightRef=frontendRoute.artifact_refs.find(item=>item.endsWith('frontend-strategic-preflight-draft.json'));ensure(preflightRef,'Handoff v4 缺少 Frontend Strategic Preflight 草案');
173
+ write(staging,'frontend-acceptance-draft.json',json({schema_version:2,status:'draft',slice_id:b.delivery.scope.slice_id,strategic_preflight:{ref:preflightRef,digest:hash(readFileSync(safe(target,preflightRef)))},backend_dependency:{mode:'required',route_id:'route.backend'},backend_delivery:{import_receipt_ref:`${ref}/import-receipt.json`,bundle_digest:b.manifest.bundle_digest},strategic_handoff:strategicHandoff,frontend_cases:[]}));
174
+ }else write(staging,'frontend-acceptance-draft.json',json({schema_version:1,status:'draft',slice_id:b.delivery.scope.slice_id,backend_delivery:{import_receipt_ref:`${ref}/import-receipt.json`,bundle_digest:b.manifest.bundle_digest},strategic_handoff:strategicHandoff,frontend_cases:[]}));
163
175
  ensure(!existsSync(destination),'后端包导入并发冲突');renameSync(staging,destination);
164
176
  return {result:'imported-pending-acceptance',receipt_ref:`${ref}/import-receipt.json`,acceptance_ref:`${ref}/frontend-acceptance-draft.json`};
165
177
  } finally { rmSync(staging,{recursive:true,force:true}); }