create-yss-spec 3.4.3 → 3.4.4
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.
- package/README.md +1 -1
- package/package.json +1 -1
- package/template/.agents/skills/.strategic-design-skills-manifest.json +3 -3
- package/template/.agents/skills/yss-ddd-scaffold-generator/SKILL.md +2 -2
- package/template/.agents/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
- package/template/.agents/skills/yss-layered-mvc-scaffold-generator/SKILL.md +1 -1
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration-contract.yaml +22 -5
- package/template/.agents/skills/yss-product-lifecycle/references/orchestration.md +2 -2
- package/template/.agents/skills/yss-product-lifecycle/references/state-model.md +1 -1
- package/template/.agents/skills/yss-product-lifecycle/references/user-decisions.md +1 -1
- package/template/.agents/skills/yss-stage-decision/SKILL.md +1 -1
- package/template/.agents/skills/yss-stage-decision/references/domain-strategy-contract.md +2 -0
- package/template/.agents/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
- package/template/.agents/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +3 -3
- package/template/.agents/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +3 -3
- package/template/.agents/skills/yss-stage-decision/tests/run-scenarios.mjs +33 -0
- package/template/.agents/skills/yss-tactical-design/SKILL.md +1 -1
- package/template/.agents/skills/yss-technical-design/SKILL.md +1 -1
- package/template/.agents/skills/yss-technical-design/references/technical-design-contract.md +1 -1
- package/template/.agents/skills/yss-technical-design/tests/run-scenarios.mjs +1 -1
- package/template/.codex/skills/yss-ddd-scaffold-generator/SKILL.md +2 -2
- package/template/.codex/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
- package/template/.codex/skills/yss-layered-mvc-scaffold-generator/SKILL.md +1 -1
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration-contract.yaml +22 -5
- package/template/.codex/skills/yss-product-lifecycle/references/orchestration.md +2 -2
- package/template/.codex/skills/yss-product-lifecycle/references/state-model.md +1 -1
- package/template/.codex/skills/yss-product-lifecycle/references/user-decisions.md +1 -1
- package/template/.codex/skills/yss-stage-decision/SKILL.md +1 -1
- package/template/.codex/skills/yss-stage-decision/references/domain-strategy-contract.md +2 -0
- package/template/.codex/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
- package/template/.codex/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +3 -3
- package/template/.codex/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +3 -3
- package/template/.codex/skills/yss-stage-decision/tests/run-scenarios.mjs +33 -0
- package/template/.codex/skills/yss-tactical-design/SKILL.md +1 -1
- package/template/.codex/skills/yss-technical-design/SKILL.md +1 -1
- package/template/.codex/skills/yss-technical-design/references/technical-design-contract.md +1 -1
- package/template/.codex/skills/yss-technical-design/tests/run-scenarios.mjs +1 -1
- package/template/.cursor/skills/yss-ddd-scaffold-generator/SKILL.md +2 -2
- package/template/.cursor/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
- package/template/.cursor/skills/yss-layered-mvc-scaffold-generator/SKILL.md +1 -1
- package/template/.cursor/skills/yss-product-lifecycle/references/orchestration-contract.yaml +22 -5
- package/template/.cursor/skills/yss-product-lifecycle/references/orchestration.md +2 -2
- package/template/.cursor/skills/yss-product-lifecycle/references/state-model.md +1 -1
- package/template/.cursor/skills/yss-product-lifecycle/references/user-decisions.md +1 -1
- package/template/.cursor/skills/yss-stage-decision/SKILL.md +1 -1
- package/template/.cursor/skills/yss-stage-decision/references/domain-strategy-contract.md +2 -0
- package/template/.cursor/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
- package/template/.cursor/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +3 -3
- package/template/.cursor/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +3 -3
- package/template/.cursor/skills/yss-stage-decision/tests/run-scenarios.mjs +33 -0
- package/template/.cursor/skills/yss-tactical-design/SKILL.md +1 -1
- package/template/.cursor/skills/yss-technical-design/SKILL.md +1 -1
- package/template/.cursor/skills/yss-technical-design/references/technical-design-contract.md +1 -1
- package/template/.cursor/skills/yss-technical-design/tests/run-scenarios.mjs +1 -1
- package/template/.pi/skills/yss-ddd-scaffold-generator/SKILL.md +2 -2
- package/template/.pi/skills/yss-implementation-contract-compiler/SKILL.md +1 -1
- package/template/.pi/skills/yss-layered-mvc-scaffold-generator/SKILL.md +1 -1
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration-contract.yaml +22 -5
- package/template/.pi/skills/yss-product-lifecycle/references/orchestration.md +2 -2
- package/template/.pi/skills/yss-product-lifecycle/references/state-model.md +1 -1
- package/template/.pi/skills/yss-product-lifecycle/references/user-decisions.md +1 -1
- package/template/.pi/skills/yss-stage-decision/SKILL.md +1 -1
- package/template/.pi/skills/yss-stage-decision/references/domain-strategy-contract.md +2 -0
- package/template/.pi/skills/yss-stage-decision/references/stage-decision-package-contract.md +1 -1
- package/template/.pi/skills/yss-stage-decision/scripts/validate-domain-strategy.mjs +3 -3
- package/template/.pi/skills/yss-stage-decision/scripts/validate-stage-decision-package.mjs +3 -3
- package/template/.pi/skills/yss-stage-decision/tests/run-scenarios.mjs +33 -0
- package/template/.pi/skills/yss-tactical-design/SKILL.md +1 -1
- package/template/.pi/skills/yss-technical-design/SKILL.md +1 -1
- package/template/.pi/skills/yss-technical-design/references/technical-design-contract.md +1 -1
- package/template/.pi/skills/yss-technical-design/tests/run-scenarios.mjs +1 -1
- package/template/docs/agents/digital-human-roles.yaml +5 -1
- package/template/docs/architecture/templates/engineering-baseline-review-template.md +6 -6
- package/template/docs/engineering/backend-platforms.md +1 -1
- package/template/docs/process/existing-ui-baseline.md +1 -1
- package/template/docs/process/lifecycle-artifact-map.md +3 -2
- package/template/docs/process/lifecycle-registry-baseline.json +2 -1
- package/template/docs/process/lifecycle-registry.yaml +13 -4
- package/template/docs/process/schemas/digital-human-task-package.schema.json +1 -0
- package/template/docs/process/schemas/lifecycle-checkpoint.schema.json +4 -0
- package/template/docs/process/schemas/review-bundle.schema.json +42 -0
- package/template/docs/process/strategic-handoff-package.md +5 -11
- package/template/docs/templates/build-architecture-checklist-template.md +2 -2
- package/template/docs/templates/implementation-routing-template.md +4 -4
- package/template/docs/templates/review-bundle-template.yaml +26 -0
- package/template/scripts/lib/approval-record.mjs +25 -6
- package/template/scripts/lib/strategic-handoff-io.mjs +7 -0
- package/template/scripts/lib/strategic-handoff.mjs +21 -7
- package/template/scripts/lib/user-decision.mjs +13 -2
- package/template/skills-lock.json +13 -13
- package/template.snapshot.json +3 -3
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
schema_version: 1
|
|
2
|
+
kind: review-bundle
|
|
3
|
+
bundle_id: review-bundle.plan
|
|
4
|
+
task_id: replace-with-plan-review-task-id
|
|
5
|
+
work_unit_id: work-unit.plan-requirements
|
|
6
|
+
review_session_id: replace-with-stable-review-session-id
|
|
7
|
+
role_id: role.product-manager
|
|
8
|
+
runtime_id: runtime.generic
|
|
9
|
+
principal_ref: replace-with-reviewer-instance
|
|
10
|
+
reviews:
|
|
11
|
+
- schema_version: 1
|
|
12
|
+
gate_id: check.domain-strategy-approved
|
|
13
|
+
decision: approved
|
|
14
|
+
actor_kind: digital-human
|
|
15
|
+
role_id: role.product-manager
|
|
16
|
+
runtime_id: runtime.generic
|
|
17
|
+
principal_ref: replace-with-reviewer-instance
|
|
18
|
+
drafter_role_id: role.requirements-manager
|
|
19
|
+
drafter_principal_ref: replace-with-drafter-instance
|
|
20
|
+
subject_ref: docs/.scratch/<feature>/domain/domain-strategy-v1.yaml
|
|
21
|
+
subject_digest: replace-with-64-char-sha256
|
|
22
|
+
approval_scope:
|
|
23
|
+
- replace-with-feature-id
|
|
24
|
+
evidence_refs:
|
|
25
|
+
- replace-with-current-review-evidence
|
|
26
|
+
notes: 本模板只用于起草。只保留实际命中的 check;同一 bundle 的所有结论必须来自同一复核任务、会话和实例。
|
|
@@ -42,12 +42,32 @@ export function loadApprovalRecord(filePath, gateId) {
|
|
|
42
42
|
return selectApprovalRecord(yamlFromFile(filePath, "会签记录"), gateId);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
function reviewBundleRows(bundle) {
|
|
46
|
+
if (bundle?.schema_version !== 1 || bundle.kind !== "review-bundle") fail("组合审查身份无效");
|
|
47
|
+
for (const field of ["bundle_id", "task_id", "work_unit_id", "review_session_id", "role_id", "runtime_id", "principal_ref"]) requireString(bundle[field], field);
|
|
48
|
+
if (!/^review-bundle\.[a-z0-9][a-z0-9-]*$/.test(bundle.bundle_id)) fail("组合审查 bundle_id 格式非法");
|
|
49
|
+
if (!/^work-unit\.[a-z0-9][a-z0-9-]*$/.test(bundle.work_unit_id)) fail("组合审查 work_unit_id 格式非法");
|
|
50
|
+
if (!Array.isArray(bundle.reviews) || !bundle.reviews.length) fail("组合审查不能为空");
|
|
51
|
+
if (new Set(bundle.reviews.map(row => row?.gate_id)).size !== bundle.reviews.length) fail("组合审查 gate_id 重复");
|
|
52
|
+
for (const row of bundle.reviews) {
|
|
53
|
+
if (!row || typeof row !== "object" || Array.isArray(row)) fail("组合审查结论必须是对象");
|
|
54
|
+
if (row.role_id !== bundle.role_id || row.runtime_id !== bundle.runtime_id || row.principal_ref !== bundle.principal_ref) fail("组合审查必须来自同一复核角色、运行时和实例");
|
|
55
|
+
if (row.review_session_id != null && row.review_session_id !== bundle.review_session_id) fail("组合审查 review_session_id 不一致");
|
|
56
|
+
}
|
|
57
|
+
return bundle.reviews;
|
|
58
|
+
}
|
|
59
|
+
|
|
45
60
|
export function selectApprovalRecord(record, gateId) {
|
|
46
61
|
if (record.kind !== 'review-bundle') return record;
|
|
47
|
-
|
|
48
|
-
const selected = record.reviews.filter(x => x.gate_id === gateId);
|
|
62
|
+
const selected = reviewBundleRows(record).filter(x => x.gate_id === gateId);
|
|
49
63
|
if (selected.length !== 1) fail('组合审查缺少当前检查的明确结论');
|
|
50
|
-
return
|
|
64
|
+
return {
|
|
65
|
+
...selected[0],
|
|
66
|
+
review_bundle_id: record.bundle_id,
|
|
67
|
+
review_task_id: record.task_id,
|
|
68
|
+
review_work_unit_id: record.work_unit_id,
|
|
69
|
+
review_session_id: record.review_session_id
|
|
70
|
+
};
|
|
51
71
|
}
|
|
52
72
|
|
|
53
73
|
export function resolveApprovalRef(approvalRef, fromFile = ROOT) {
|
|
@@ -114,7 +134,7 @@ export function validateApprovalRecord(record, { rolesDoc, requireApproved = fal
|
|
|
114
134
|
}
|
|
115
135
|
|
|
116
136
|
function assertRecordUserDecision(record, registry, options) {
|
|
117
|
-
if (!registry.user_decision_policy.gates.includes(record.gate_id)
|
|
137
|
+
if (!registry.user_decision_policy.gates.includes(record.gate_id)) return;
|
|
118
138
|
const result = assertApprovalUserDecision(record, registry, options);
|
|
119
139
|
if (record.actor_kind === "biological-human" && result.validated.some((item) => item.principal_ref !== record.principal_ref)) fail("user-decision-responder-mismatch: 生物人会签者与原始回复者不一致");
|
|
120
140
|
}
|
|
@@ -122,8 +142,7 @@ function assertRecordUserDecision(record, registry, options) {
|
|
|
122
142
|
export function validateApprovalRecordFile(filePath, options = {}) {
|
|
123
143
|
const record = yamlFromFile(filePath, "会签记录");
|
|
124
144
|
if (record.kind === 'review-bundle') {
|
|
125
|
-
|
|
126
|
-
return record.reviews.map(item => {
|
|
145
|
+
return reviewBundleRows(record).map(item => {
|
|
127
146
|
const row = loadApprovalRecord(filePath, item.gate_id);
|
|
128
147
|
if (options.requireApproved) {
|
|
129
148
|
if (!row.drafter_principal_ref || row.drafter_principal_ref === row.principal_ref) fail('组合审查必须保留独立身份');
|
|
@@ -78,6 +78,13 @@ export function sourceApprovalPolicy(source) {
|
|
|
78
78
|
roles.user_decision_policy ||= {gates:[]};
|
|
79
79
|
ensure(!(roles.user_decision_policy.required_capabilities || []).some(id => id !== 'strategic-decision-reuse-v1'), '接收工具不支持源用户决定策略,请升级工具后验包');
|
|
80
80
|
const policy=roles.gate_policy;
|
|
81
|
+
// Dedicated receivers may predate check_reviews. Mirror source check-review
|
|
82
|
+
// rules into their existing digital review lookup without changing source bytes.
|
|
83
|
+
for(const rule of policy.check_reviews || []) {
|
|
84
|
+
if(!(policy.digital_human_review||[]).some(x=>x.gate===rule.gate) && !(policy.dual_digital_human||[]).some(x=>x.gate===rule.gate)) {
|
|
85
|
+
policy.digital_human_review ||= [];policy.digital_human_review.push({gate:rule.gate,drafter:rule.drafter,countersigners:[...rule.countersigners]});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
81
88
|
for(const gate of policy.product_digital_human_with_biological_veto || []) {
|
|
82
89
|
if(!(policy.biological_human||[]).includes(gate) && !(policy.digital_human_review||[]).some(x=>x.gate===gate) && !(policy.dual_digital_human||[]).some(x=>x.gate===gate)) {
|
|
83
90
|
policy.digital_human_review ||= [];policy.digital_human_review.push({gate,countersigners:['role.product-manager']});
|
|
@@ -20,6 +20,19 @@ const SOURCE_SCHEMAS = new Map([
|
|
|
20
20
|
]);
|
|
21
21
|
const CAPABILITIES=['backend-technical-design','frontend-engineering-design','delivery-coordination'];
|
|
22
22
|
|
|
23
|
+
function sourceApprovalRecord(document, gateId) {
|
|
24
|
+
if(document?.kind!=='review-bundle')return document;
|
|
25
|
+
for(const field of ['bundle_id','task_id','work_unit_id','review_session_id','role_id','runtime_id','principal_ref'])ensure(nonempty(document[field]),`组合审查缺少 ${field}`);
|
|
26
|
+
ensure(Array.isArray(document.reviews)&&document.reviews.length,'组合审查不能为空');
|
|
27
|
+
ensure(new Set(document.reviews.map(row=>row?.gate_id)).size===document.reviews.length,'组合审查 gate_id 重复');
|
|
28
|
+
const rows=document.reviews.filter(row=>row.gate_id===gateId);
|
|
29
|
+
ensure(rows.length===1,`组合审查缺少当前结论: ${gateId}`);
|
|
30
|
+
const row=rows[0];
|
|
31
|
+
ensure(row.role_id===document.role_id&&row.runtime_id===document.runtime_id&&row.principal_ref===document.principal_ref,'组合审查必须来自同一复核角色、运行时和实例');
|
|
32
|
+
ensure(!row.review_session_id||row.review_session_id===document.review_session_id,'组合审查 review_session_id 不一致');
|
|
33
|
+
return {...row,review_bundle_id:document.bundle_id,review_task_id:document.task_id,review_work_unit_id:document.work_unit_id,review_session_id:document.review_session_id};
|
|
34
|
+
}
|
|
35
|
+
|
|
23
36
|
function deliveryReadme(handoff) {
|
|
24
37
|
const sources=Object.entries(handoff.source).sort(([a],[b])=>a.localeCompare(b)).map(([key,value])=>`- \`${key}\`: \`${value.persisted_ref}\` (${value.version}, ${value.digest})`);
|
|
25
38
|
const routes=handoff.consumer_routes.map(route=>`- \`${route.capability}\`: \`${route.activation}\` (${route.route_id})`);
|
|
@@ -171,13 +184,14 @@ export async function inspectSource(root, handoffRef) {
|
|
|
171
184
|
const indexes=extractTraceability(strategy);
|
|
172
185
|
const sourceRoles=read(safe(root,'docs/agents/digital-human-roles.yaml'));
|
|
173
186
|
const roles=sourceApprovalPolicy(sourceRoles);
|
|
174
|
-
for (const [artifact, version] of [[strategy,strategy.domain_version],[stage,stage.package_version]]) {
|
|
175
|
-
if(artifact.approval) { const record=read(safe(root,artifact.approval.approval_ref));await sourceApproval(record,roles,root);ensure(artifact.approval.current_version===version,'资产内置批准版本过期'); }
|
|
187
|
+
for (const [artifact, version, gateId] of [[strategy,strategy.domain_version,'check.domain-strategy-approved'],[stage,stage.package_version,'check.stage-decision-package-approved']]) {
|
|
188
|
+
if(artifact.approval) { const record=sourceApprovalRecord(read(safe(root,artifact.approval.approval_ref)),gateId);await sourceApproval(record,roles,root);ensure(artifact.approval.current_version===version,'资产内置批准版本过期'); }
|
|
176
189
|
}
|
|
177
190
|
// Source packages retain their published approval vocabulary. Never promote old approvals into current checkpoint gates.
|
|
178
191
|
const currentPlan = (roles.gate_policy.dual_digital_human || []).some(rule => rule.gate === 'gate.plan-approved');
|
|
179
|
-
const
|
|
180
|
-
const
|
|
192
|
+
const explicitlyReviewed=(gate)=>(roles.gate_policy.digital_human_review||[]).some(rule=>rule.gate===gate)||(roles.gate_policy.dual_digital_human||[]).some(rule=>rule.gate===gate)||(roles.gate_policy.biological_human||[]).includes(gate);
|
|
193
|
+
const terminalGate=currentPlan||explicitlyReviewed('gate.strategic-design-handoff-approved')?'gate.strategic-design-handoff-approved':'gate.stage-decision-package-approved';
|
|
194
|
+
const expectedGates={domain_strategy_ref:currentPlan?'gate.plan-approved':'gate.domain-strategy-approved',stage_decision_package_ref:currentPlan?'gate.plan-approved':'gate.stage-decision-package-approved',spec_ref:'gate.spec-baseline-approved',prototype_ref:currentPlan?'gate.product-design-approved':'gate.user-confirmation',visual_baseline_ref:currentPlan?'gate.product-design-approved':'gate.user-confirmation',business_ticket_set_ref:currentPlan?'gate.plan-approved':terminalGate,handoff:terminalGate};
|
|
181
195
|
expectedGates.existing_ui_baseline_ref=expectedGates.prototype_ref;
|
|
182
196
|
const bindings={...handoff.source,handoff:{id:handoff.handoff_id,version:handoff.handoff_version,persisted_ref:handoffRef,status:'approved'}};
|
|
183
197
|
for(const [key,ref] of Object.entries(bindings)) {
|
|
@@ -194,14 +208,14 @@ export async function inspectSource(root, handoffRef) {
|
|
|
194
208
|
}
|
|
195
209
|
} else actual=bytesDigest(readFileSync(safe(root,ref.persisted_ref)),approval.digest_kind);
|
|
196
210
|
if(key!=='handoff')ensure(ref.digest===actual,`源资产摘要过期: ${key}`);
|
|
197
|
-
const record=read(safe(root,approval.record_ref));
|
|
211
|
+
const record=sourceApprovalRecord(read(safe(root,approval.record_ref)),approval.gate_id);
|
|
198
212
|
if(key==='existing_ui_baseline_ref')ensure(record.subject_ref===`${ref.persisted_ref}/${ref.manifest_ref}`,'既有 UI 用户决定必须以当前 manifest 为批准主体');
|
|
199
213
|
await sourceApproval(record,roles,root);
|
|
200
214
|
ensure(record.gate_id===approval.gate_id,`批准门禁不匹配: ${key}`);
|
|
201
215
|
ensure((record.artifact_bindings || []).some(x=>x.id===(ref.id||ref.baseline_id) && x.version===ref.version && x.digest===actual),`批准记录未绑定当前资产: ${key}`);
|
|
202
216
|
}
|
|
203
217
|
if (roles.user_decision_policy.required_capabilities?.includes('strategic-decision-reuse-v1')) {
|
|
204
|
-
const record=read(safe(root,config.approvals.handoff.record_ref));
|
|
218
|
+
const record=sourceApprovalRecord(read(safe(root,config.approvals.handoff.record_ref)),config.approvals.handoff.gate_id);
|
|
205
219
|
const scope=read(safe(root,record.subject_ref));
|
|
206
220
|
ensure(scope.kind==='strategic-delivery-scope' && scope.schema_version===1, '交接必须绑定独立的交付范围清单');
|
|
207
221
|
const {package_export,status,...delivery}=handoff;
|
|
@@ -209,7 +223,7 @@ export async function inspectSource(root, handoffRef) {
|
|
|
209
223
|
ensure(scope.assets?.some(asset=>asset.ref===scope.delivery_ref && asset.digest===hash(readFileSync(safe(root,scope.delivery_ref)))), '交接内容快照缺少批准覆盖');
|
|
210
224
|
for (const [key,ref] of Object.entries(handoff.source)) {
|
|
211
225
|
const file=['visual_baseline_ref','existing_ui_baseline_ref'].includes(key)?`${ref.persisted_ref}/${ref.manifest_ref}`:ref.persisted_ref;
|
|
212
|
-
const decisionBoundaries=
|
|
226
|
+
const decisionBoundaries=[expectedGates[key]];
|
|
213
227
|
ensure(scope.assets?.some(asset=>asset.ref===file && asset.version===ref.version && decisionBoundaries.includes(asset.boundary) && asset.digest===hash(readFileSync(safe(root,file)))), `交付范围清单遗漏当前资产: ${key}`);
|
|
214
228
|
}
|
|
215
229
|
}
|
|
@@ -7,6 +7,7 @@ import { ROOT } from "./lifecycle-registry.mjs";
|
|
|
7
7
|
import { loadDigitalHumanRoles } from "./digital-human-roles.mjs";
|
|
8
8
|
import { validateJsonSchema } from "./json-schema.mjs";
|
|
9
9
|
import { assertDecisionContinuation } from './decision-continuation.mjs';
|
|
10
|
+
import { platformProfile } from './backend-platform.mjs';
|
|
10
11
|
|
|
11
12
|
export function decisionError(code, detail) {
|
|
12
13
|
const error = new TypeError(`${code}: ${detail}`);
|
|
@@ -205,11 +206,21 @@ export function assertImplementationDecision(state, options = {}) {
|
|
|
205
206
|
|
|
206
207
|
export function scaffoldDecisionSnapshot(decision) {
|
|
207
208
|
const { user_confirmation, status, decision_inputs_digest, ...inputs } = decision;
|
|
208
|
-
|
|
209
|
+
const profile = platformProfile(decision.platform_profile, undefined, decision.platform_configuration?.spring_boot_version);
|
|
210
|
+
return {
|
|
211
|
+
...inputs,
|
|
212
|
+
platform_selection: {
|
|
213
|
+
profile_id: profile.id,
|
|
214
|
+
spring_boot_version: profile.spring_boot_version,
|
|
215
|
+
java_version: profile.java_version,
|
|
216
|
+
},
|
|
217
|
+
};
|
|
209
218
|
}
|
|
210
219
|
export function assertScaffoldUserDecision(decision, options = {}) {
|
|
211
220
|
const confirmation = decision.user_confirmation || {};
|
|
212
|
-
const
|
|
221
|
+
const profile = platformProfile(decision.platform_profile, undefined, decision.platform_configuration?.spring_boot_version);
|
|
222
|
+
const platformScope = `${profile.id}@${profile.spring_boot_version}/java${profile.java_version}`;
|
|
223
|
+
const requirement = { boundary: "gate.backend-architecture-platform-approved", subject_ref: confirmation.decision_subject_ref, scope: [decision.project_id, decision.confirmed_architecture, platformScope, decision.decision_inputs_digest], user_decision_ref: confirmation.user_decision_ref };
|
|
213
224
|
assertUserDecisionRequirement(requirement, options);
|
|
214
225
|
const io = decisionIO(options);
|
|
215
226
|
if (decisionDigest(io.document(requirement.subject_ref)) !== decisionDigest(scaffoldDecisionSnapshot(decision))) decisionError("user-decision-stale", "脚手架输入与用户所见快照不一致");
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"revision": "c4d958f18cc947cb91cbe1bd48783fa4601cc18f"
|
|
19
19
|
},
|
|
20
20
|
"iloveZzz/yss-harness-design-agent": {
|
|
21
|
-
"revision": "
|
|
21
|
+
"revision": "e9a28b4cb0d3003a730b0113bb4dad59665e38b5"
|
|
22
22
|
},
|
|
23
23
|
"ayghri/i-have-adhd": {
|
|
24
24
|
"revision": "7b9069b39972e269e61bd95c2f66ebb90cac6a02"
|
|
@@ -481,7 +481,7 @@
|
|
|
481
481
|
"sourceType": "git-submodule",
|
|
482
482
|
"skillPath": ".agents/skills/prototype-review/SKILL.md",
|
|
483
483
|
"effectiveHash": "df6f131bef0f52a96d307d98ab42d74888a9b72c5508911b5622913b334e8eab",
|
|
484
|
-
"sourceRevision": "
|
|
484
|
+
"sourceRevision": "e9a28b4cb0d3003a730b0113bb4dad59665e38b5",
|
|
485
485
|
"upstreamHash": "9206df8b6c555c1af1351e425c5ec99ec2a40263c6861607f1418b9c520873ab",
|
|
486
486
|
"adaptationRef": "docs/agents/strategic-design-skills-integration.md",
|
|
487
487
|
"targets": [
|
|
@@ -753,7 +753,7 @@
|
|
|
753
753
|
"source": "project",
|
|
754
754
|
"sourceType": "local",
|
|
755
755
|
"skillPath": ".agents/skills/yss-ddd-scaffold-generator/SKILL.md",
|
|
756
|
-
"effectiveHash": "
|
|
756
|
+
"effectiveHash": "08417fab2d809080470c8ec085330084a7ddeac5c1b385f40fc8491c461749e8",
|
|
757
757
|
"targets": [
|
|
758
758
|
".agents/skills",
|
|
759
759
|
".codex/skills",
|
|
@@ -766,7 +766,7 @@
|
|
|
766
766
|
"sourceType": "git-submodule",
|
|
767
767
|
"skillPath": ".agents/skills/yss-design-system/SKILL.md",
|
|
768
768
|
"effectiveHash": "c5c023813042472030cecca187c222257151dd5554655a6bdcdd757bc2a516c7",
|
|
769
|
-
"sourceRevision": "
|
|
769
|
+
"sourceRevision": "e9a28b4cb0d3003a730b0113bb4dad59665e38b5",
|
|
770
770
|
"upstreamHash": "c917ecf40a67c52f0fa7894fbdfbf827cc1ed6aff1037be2911377387fede1a0",
|
|
771
771
|
"adaptationRef": "docs/agents/strategic-design-skills-integration.md",
|
|
772
772
|
"targets": [
|
|
@@ -891,7 +891,7 @@
|
|
|
891
891
|
"source": "project",
|
|
892
892
|
"sourceType": "local",
|
|
893
893
|
"skillPath": ".agents/skills/yss-implementation-contract-compiler/SKILL.md",
|
|
894
|
-
"effectiveHash": "
|
|
894
|
+
"effectiveHash": "624b3d948a95bf27282e938d386308e74d0c8448ebd3321a31a3f298a6ccafba",
|
|
895
895
|
"targets": [
|
|
896
896
|
".agents/skills",
|
|
897
897
|
".codex/skills",
|
|
@@ -903,7 +903,7 @@
|
|
|
903
903
|
"source": "project",
|
|
904
904
|
"sourceType": "local",
|
|
905
905
|
"skillPath": ".agents/skills/yss-layered-mvc-scaffold-generator/SKILL.md",
|
|
906
|
-
"effectiveHash": "
|
|
906
|
+
"effectiveHash": "ab0f73e2a820572cbc5206a2a5b608c180876b2909d871d978608073211be0cd",
|
|
907
907
|
"targets": [
|
|
908
908
|
".agents/skills",
|
|
909
909
|
".codex/skills",
|
|
@@ -975,7 +975,7 @@
|
|
|
975
975
|
"source": "project",
|
|
976
976
|
"sourceType": "local",
|
|
977
977
|
"skillPath": ".agents/skills/yss-product-lifecycle/SKILL.md",
|
|
978
|
-
"effectiveHash": "
|
|
978
|
+
"effectiveHash": "c4709ad26b58b1f740484f056fd79820b4b42833e001a2ff37fb7ebea40ba745",
|
|
979
979
|
"targets": [
|
|
980
980
|
".agents/skills",
|
|
981
981
|
".codex/skills",
|
|
@@ -988,7 +988,7 @@
|
|
|
988
988
|
"sourceType": "git-submodule",
|
|
989
989
|
"skillPath": ".agents/skills/yss-prototype-stage/SKILL.md",
|
|
990
990
|
"effectiveHash": "cbe197cdf9e4c7e073ea1892dbcfd03778552cd361d6f3e7e16107a89c20677d",
|
|
991
|
-
"sourceRevision": "
|
|
991
|
+
"sourceRevision": "e9a28b4cb0d3003a730b0113bb4dad59665e38b5",
|
|
992
992
|
"upstreamHash": "8256a1edfeb203f4de27d190210b0ba5593f8f74e0f3655b62b146daff2105a8",
|
|
993
993
|
"adaptationRef": "docs/agents/strategic-design-skills-integration.md",
|
|
994
994
|
"targets": [
|
|
@@ -1065,9 +1065,9 @@
|
|
|
1065
1065
|
"source": "iloveZzz/yss-harness-design-agent",
|
|
1066
1066
|
"sourceType": "git-submodule",
|
|
1067
1067
|
"skillPath": ".agents/skills/yss-stage-decision/SKILL.md",
|
|
1068
|
-
"effectiveHash": "
|
|
1069
|
-
"sourceRevision": "
|
|
1070
|
-
"upstreamHash": "
|
|
1068
|
+
"effectiveHash": "4c2cfefe9ed99283ec55e029136b64885280935e8e2a9f66d0425b3f1e8217a9",
|
|
1069
|
+
"sourceRevision": "e9a28b4cb0d3003a730b0113bb4dad59665e38b5",
|
|
1070
|
+
"upstreamHash": "46a9be287963eff0e71f8106b5d31311e43aabbd1117d7bc3d2d8666a0a99474",
|
|
1071
1071
|
"adaptationRef": "docs/agents/strategic-design-skills-integration.md",
|
|
1072
1072
|
"targets": [
|
|
1073
1073
|
".agents/skills",
|
|
@@ -1080,7 +1080,7 @@
|
|
|
1080
1080
|
"source": "project",
|
|
1081
1081
|
"sourceType": "local",
|
|
1082
1082
|
"skillPath": ".agents/skills/yss-tactical-design/SKILL.md",
|
|
1083
|
-
"effectiveHash": "
|
|
1083
|
+
"effectiveHash": "894ecd416a4b9e91d354f85e623ea3e2eb7d2af75407a848134112e2a756d0e0",
|
|
1084
1084
|
"targets": [
|
|
1085
1085
|
".agents/skills",
|
|
1086
1086
|
".codex/skills",
|
|
@@ -1092,7 +1092,7 @@
|
|
|
1092
1092
|
"source": "project",
|
|
1093
1093
|
"sourceType": "local",
|
|
1094
1094
|
"skillPath": ".agents/skills/yss-technical-design/SKILL.md",
|
|
1095
|
-
"effectiveHash": "
|
|
1095
|
+
"effectiveHash": "d1b91d1e3485ba3bf39cd30a746b512dfce12f9db132a8b3345719cbb45b0cb6",
|
|
1096
1096
|
"targets": [
|
|
1097
1097
|
".agents/skills",
|
|
1098
1098
|
".codex/skills",
|
package/template.snapshot.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"templateSource": "github:iloveZzz/yss-spec-project-template",
|
|
5
5
|
"templateRepository": "https://github.com/iloveZzz/yss-spec-project-template.git",
|
|
6
6
|
"requestedRef": "working-tree",
|
|
7
|
-
"templateCommit": "
|
|
7
|
+
"templateCommit": "582b6e62b54eab7a02fbe85aa2954aec5770f65f",
|
|
8
8
|
"sourceState": "working-tree",
|
|
9
9
|
"manifestHash": "191240f4716de5f93cf1b30ea917a9a14dfd4a29b12dd2ba569c6271fa46009e",
|
|
10
10
|
"encodedPaths": {
|
|
@@ -17,6 +17,6 @@
|
|
|
17
17
|
".gitignore": "__yss_dotfile__.gitignore",
|
|
18
18
|
".pi/skills/yss-frontend-scaffold-generator/assets/data-quality-v1/.gitignore": ".pi/skills/yss-frontend-scaffold-generator/assets/data-quality-v1/__yss_dotfile__.gitignore"
|
|
19
19
|
},
|
|
20
|
-
"snapshotHash": "
|
|
21
|
-
"generatedAt": "2026-09-
|
|
20
|
+
"snapshotHash": "f0a4b41e55f53b3d3ace6f0104d1347e6b757ff6b635dbaae1bed3ce882fb4fd",
|
|
21
|
+
"generatedAt": "2026-09-18T03:43:12.395Z"
|
|
22
22
|
}
|