scene-capability-engine 3.3.22 → 3.3.24
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/CHANGELOG.md +54 -0
- package/bin/scene-capability-engine.js +10 -0
- package/docs/adoption-guide.md +8 -0
- package/docs/autonomous-control-guide.md +8 -8
- package/docs/command-reference.md +51 -2
- package/docs/errorbook-registry.md +128 -0
- package/lib/adoption/adoption-strategy.js +2 -0
- package/lib/adoption/backup-manager.js +2 -0
- package/lib/adoption/detection-engine.js +2 -0
- package/lib/adoption/file-classifier.js +3 -1
- package/lib/adoption/smart-orchestrator.js +2 -0
- package/lib/adoption/strategy-selector.js +2 -0
- package/lib/adoption/template-sync.js +2 -0
- package/lib/auto/config-schema.js +7 -7
- package/lib/commands/auto.js +2 -2
- package/lib/commands/errorbook.js +968 -4
- package/lib/commands/spec-bootstrap.js +17 -2
- package/lib/commands/spec-domain.js +217 -0
- package/lib/commands/studio.js +314 -9
- package/lib/spec/domain-modeling.js +439 -0
- package/lib/spec-gate/policy/default-policy.js +1 -0
- package/lib/spec-gate/rules/default-rules.js +8 -0
- package/package.json +3 -2
- package/template/.sce/config/errorbook-registry.json +13 -0
- package/template/.sce/steering/CORE_PRINCIPLES.md +30 -1
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const DOMAIN_MAP_RELATIVE_PATH = path.join('custom', 'problem-domain-map.md');
|
|
5
|
+
const SCENE_SPEC_RELATIVE_PATH = path.join('custom', 'scene-spec.md');
|
|
6
|
+
const DOMAIN_CHAIN_RELATIVE_PATH = path.join('custom', 'problem-domain-chain.json');
|
|
7
|
+
const DOMAIN_CHAIN_API_VERSION = 'sce.problem-domain-chain/v0.1';
|
|
8
|
+
|
|
9
|
+
function normalizeText(value) {
|
|
10
|
+
if (typeof value !== 'string') {
|
|
11
|
+
return '';
|
|
12
|
+
}
|
|
13
|
+
return value.trim();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function resolveSpecPaths(projectPath, specId) {
|
|
17
|
+
const specPath = path.join(projectPath, '.sce', 'specs', specId);
|
|
18
|
+
return {
|
|
19
|
+
specPath,
|
|
20
|
+
domainMapPath: path.join(specPath, DOMAIN_MAP_RELATIVE_PATH),
|
|
21
|
+
sceneSpecPath: path.join(specPath, SCENE_SPEC_RELATIVE_PATH),
|
|
22
|
+
domainChainPath: path.join(specPath, DOMAIN_CHAIN_RELATIVE_PATH)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function buildProblemDomainMindMap(specId, options = {}) {
|
|
27
|
+
const sceneId = normalizeText(options.sceneId) || `scene.${specId.replace(/[^a-zA-Z0-9]+/g, '-').toLowerCase()}`;
|
|
28
|
+
const problemStatement = normalizeText(options.problemStatement) || 'TBD: describe the primary business problem';
|
|
29
|
+
const primaryFlow = normalizeText(options.primaryFlow) || 'TBD: define core user/business flow';
|
|
30
|
+
const verificationPlan = normalizeText(options.verificationPlan) || 'TBD: define validation and rollback criteria';
|
|
31
|
+
|
|
32
|
+
return `# Problem Domain Mind Map
|
|
33
|
+
|
|
34
|
+
> Mandatory artifact: use this map to expand the problem domain before implementation.
|
|
35
|
+
> Policy: after two failed fix rounds, diagnostics must be added before the next patch round.
|
|
36
|
+
|
|
37
|
+
## Root Problem
|
|
38
|
+
|
|
39
|
+
- Scene: \`${sceneId}\`
|
|
40
|
+
- Spec: \`${specId}\`
|
|
41
|
+
- Problem Statement: ${problemStatement}
|
|
42
|
+
- Primary Flow: ${primaryFlow}
|
|
43
|
+
|
|
44
|
+
## Domain Mind Map
|
|
45
|
+
|
|
46
|
+
\`\`\`mermaid
|
|
47
|
+
mindmap
|
|
48
|
+
root((${specId}))
|
|
49
|
+
Problem
|
|
50
|
+
Symptom
|
|
51
|
+
Root Cause Hypothesis
|
|
52
|
+
Constraints
|
|
53
|
+
Ontology
|
|
54
|
+
Entity
|
|
55
|
+
Relation
|
|
56
|
+
Business Rule
|
|
57
|
+
Decision Policy
|
|
58
|
+
Execution Flow
|
|
59
|
+
Stakeholders
|
|
60
|
+
User
|
|
61
|
+
Operator
|
|
62
|
+
Maintainer
|
|
63
|
+
Risk
|
|
64
|
+
Wrong Direction
|
|
65
|
+
Data Integrity
|
|
66
|
+
Security
|
|
67
|
+
Rollback
|
|
68
|
+
Validation
|
|
69
|
+
Test Evidence
|
|
70
|
+
Runtime Signal
|
|
71
|
+
Gate Criteria
|
|
72
|
+
\`\`\`
|
|
73
|
+
|
|
74
|
+
## Layered Exploration Chain
|
|
75
|
+
|
|
76
|
+
1. Clarify symptom scope and affected boundaries.
|
|
77
|
+
2. Enumerate entities, relations, and rule constraints.
|
|
78
|
+
3. Identify decision points and execution paths.
|
|
79
|
+
4. Produce candidate fixes and risk tradeoffs.
|
|
80
|
+
5. Define verification path and measurable acceptance.
|
|
81
|
+
|
|
82
|
+
## Correction Loop
|
|
83
|
+
|
|
84
|
+
- Expected Wrong-Direction Signals:
|
|
85
|
+
- requirement drift
|
|
86
|
+
- ontology mismatch
|
|
87
|
+
- repeated failed remediation
|
|
88
|
+
- Correction Actions:
|
|
89
|
+
- update this map
|
|
90
|
+
- add debug evidence
|
|
91
|
+
- adjust scene-spec contract before coding
|
|
92
|
+
|
|
93
|
+
## Verification Plan
|
|
94
|
+
|
|
95
|
+
- ${verificationPlan}
|
|
96
|
+
`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function buildSceneSpec(specId, options = {}) {
|
|
100
|
+
const sceneId = normalizeText(options.sceneId) || `scene.${specId.replace(/[^a-zA-Z0-9]+/g, '-').toLowerCase()}`;
|
|
101
|
+
const problemStatement = normalizeText(options.problemStatement) || 'TBD';
|
|
102
|
+
const primaryFlow = normalizeText(options.primaryFlow) || 'TBD';
|
|
103
|
+
const verificationPlan = normalizeText(options.verificationPlan) || 'TBD';
|
|
104
|
+
|
|
105
|
+
return `# Scene Spec
|
|
106
|
+
|
|
107
|
+
> Mandatory artifact: scene-oriented contract for implementation and gating.
|
|
108
|
+
|
|
109
|
+
## Scene Definition
|
|
110
|
+
|
|
111
|
+
- Scene ID: \`${sceneId}\`
|
|
112
|
+
- Spec ID: \`${specId}\`
|
|
113
|
+
- Objective: ${problemStatement}
|
|
114
|
+
- Primary Flow: ${primaryFlow}
|
|
115
|
+
|
|
116
|
+
## Scope & Boundaries
|
|
117
|
+
|
|
118
|
+
- In Scope:
|
|
119
|
+
- core scene behavior
|
|
120
|
+
- required integrations
|
|
121
|
+
- Out of Scope:
|
|
122
|
+
- unrelated legacy refactors
|
|
123
|
+
- uncontrolled workaround paths
|
|
124
|
+
|
|
125
|
+
## Ontology Coverage
|
|
126
|
+
|
|
127
|
+
| Layer | Required Mapping |
|
|
128
|
+
| --- | --- |
|
|
129
|
+
| Entity | list key domain entities |
|
|
130
|
+
| Relation | list key relations |
|
|
131
|
+
| Business Rule | list enforceable rules |
|
|
132
|
+
| Decision Policy | list decision points |
|
|
133
|
+
| Execution Flow | list end-to-end action chain |
|
|
134
|
+
|
|
135
|
+
## Decision & Execution Path
|
|
136
|
+
|
|
137
|
+
1. Trigger condition and entry point.
|
|
138
|
+
2. Decision policy branch(es).
|
|
139
|
+
3. Service/tool execution sequence.
|
|
140
|
+
4. Expected outputs and side effects.
|
|
141
|
+
5. Failure path and rollback criteria.
|
|
142
|
+
|
|
143
|
+
## Acceptance & Gate
|
|
144
|
+
|
|
145
|
+
- Functional acceptance: define testable behaviors.
|
|
146
|
+
- Technical acceptance: define gate/test requirements.
|
|
147
|
+
- Verification Plan: ${verificationPlan}
|
|
148
|
+
`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function buildProblemDomainChain(specId, options = {}) {
|
|
152
|
+
const sceneId = normalizeText(options.sceneId) || `scene.${specId.replace(/[^a-zA-Z0-9]+/g, '-').toLowerCase()}`;
|
|
153
|
+
const problemStatement = normalizeText(options.problemStatement) || 'TBD: describe the primary business problem';
|
|
154
|
+
const primaryFlow = normalizeText(options.primaryFlow) || 'TBD: define core user/business flow';
|
|
155
|
+
const verificationPlan = normalizeText(options.verificationPlan) || 'TBD: define validation and rollback criteria';
|
|
156
|
+
const now = new Date().toISOString();
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
api_version: DOMAIN_CHAIN_API_VERSION,
|
|
160
|
+
generated_at: now,
|
|
161
|
+
scene_id: sceneId,
|
|
162
|
+
spec_id: specId,
|
|
163
|
+
problem: {
|
|
164
|
+
statement: problemStatement,
|
|
165
|
+
scope: 'TBD: define boundary and excluded domains',
|
|
166
|
+
symptom: 'TBD: observable symptom and impact'
|
|
167
|
+
},
|
|
168
|
+
ontology: {
|
|
169
|
+
entity: ['TBD: primary entity'],
|
|
170
|
+
relation: ['TBD: key relation'],
|
|
171
|
+
business_rule: ['TBD: enforceable business rule'],
|
|
172
|
+
decision_policy: ['TBD: decision condition and policy'],
|
|
173
|
+
execution_flow: ['TBD: action chain and side effects']
|
|
174
|
+
},
|
|
175
|
+
hypotheses: [
|
|
176
|
+
{
|
|
177
|
+
id: 'H1',
|
|
178
|
+
statement: 'TBD: root-cause hypothesis',
|
|
179
|
+
evidence: ['TBD: evidence or signal'],
|
|
180
|
+
confidence: 'low'
|
|
181
|
+
}
|
|
182
|
+
],
|
|
183
|
+
risks: [
|
|
184
|
+
{
|
|
185
|
+
id: 'R1',
|
|
186
|
+
type: 'wrong-direction',
|
|
187
|
+
statement: 'TBD: direction drift risk',
|
|
188
|
+
mitigation: 'TBD: correction checkpoint'
|
|
189
|
+
}
|
|
190
|
+
],
|
|
191
|
+
decision_execution_path: [
|
|
192
|
+
{
|
|
193
|
+
step: 1,
|
|
194
|
+
action: 'entry',
|
|
195
|
+
decision: 'TBD: trigger condition',
|
|
196
|
+
expected_result: 'TBD: expected output'
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
step: 2,
|
|
200
|
+
action: 'route',
|
|
201
|
+
decision: 'TBD: policy branch',
|
|
202
|
+
expected_result: 'TBD: branch result'
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
step: 3,
|
|
206
|
+
action: 'execute',
|
|
207
|
+
decision: 'TBD: execution rule',
|
|
208
|
+
expected_result: 'TBD: side effect and data change'
|
|
209
|
+
}
|
|
210
|
+
],
|
|
211
|
+
correction_loop: {
|
|
212
|
+
triggers: [
|
|
213
|
+
'gate failure',
|
|
214
|
+
'ontology mismatch',
|
|
215
|
+
'two failed fix rounds'
|
|
216
|
+
],
|
|
217
|
+
actions: [
|
|
218
|
+
'refresh domain map',
|
|
219
|
+
'attach debug evidence',
|
|
220
|
+
'rebuild scene spec contract'
|
|
221
|
+
]
|
|
222
|
+
},
|
|
223
|
+
verification: {
|
|
224
|
+
plan: verificationPlan,
|
|
225
|
+
gates: [
|
|
226
|
+
'spec-gate',
|
|
227
|
+
'tests',
|
|
228
|
+
'release preflight'
|
|
229
|
+
]
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function validateProblemDomainMapContent(content = '') {
|
|
235
|
+
const checks = {
|
|
236
|
+
hasRootProblem: /##\s+Root Problem/i.test(content),
|
|
237
|
+
hasMindMapBlock: /```mermaid[\s\S]*mindmap/i.test(content),
|
|
238
|
+
hasLayeredExplorationChain: /##\s+Layered Exploration Chain/i.test(content),
|
|
239
|
+
hasCorrectionLoop: /##\s+Correction Loop/i.test(content)
|
|
240
|
+
};
|
|
241
|
+
const passed = Object.values(checks).every(Boolean);
|
|
242
|
+
return { passed, checks };
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function validateSceneSpecContent(content = '') {
|
|
246
|
+
const checks = {
|
|
247
|
+
hasSceneDefinition: /##\s+Scene Definition/i.test(content),
|
|
248
|
+
hasOntologyCoverage: /##\s+Ontology Coverage/i.test(content),
|
|
249
|
+
hasDecisionExecutionPath: /##\s+Decision & Execution Path/i.test(content),
|
|
250
|
+
hasAcceptanceGate: /##\s+Acceptance & Gate/i.test(content)
|
|
251
|
+
};
|
|
252
|
+
const passed = Object.values(checks).every(Boolean);
|
|
253
|
+
return { passed, checks };
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function isNonEmptyString(value) {
|
|
257
|
+
return typeof value === 'string' && value.trim().length > 0;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function hasNonEmptyStringArray(value) {
|
|
261
|
+
return Array.isArray(value) && value.some((item) => isNonEmptyString(item));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function validateProblemDomainChainPayload(payload = {}, specId = '') {
|
|
265
|
+
const checks = {
|
|
266
|
+
apiVersion: isNonEmptyString(payload.api_version),
|
|
267
|
+
sceneId: isNonEmptyString(payload.scene_id),
|
|
268
|
+
specId: isNonEmptyString(payload.spec_id) && (!specId || payload.spec_id === specId),
|
|
269
|
+
problemStatement: isNonEmptyString(payload?.problem?.statement),
|
|
270
|
+
ontologyEntity: hasNonEmptyStringArray(payload?.ontology?.entity),
|
|
271
|
+
ontologyRelation: hasNonEmptyStringArray(payload?.ontology?.relation),
|
|
272
|
+
ontologyBusinessRule: hasNonEmptyStringArray(payload?.ontology?.business_rule),
|
|
273
|
+
ontologyDecisionPolicy: hasNonEmptyStringArray(payload?.ontology?.decision_policy),
|
|
274
|
+
ontologyExecutionFlow: hasNonEmptyStringArray(payload?.ontology?.execution_flow),
|
|
275
|
+
hasHypotheses: Array.isArray(payload.hypotheses) && payload.hypotheses.length > 0,
|
|
276
|
+
hasRisks: Array.isArray(payload.risks) && payload.risks.length > 0,
|
|
277
|
+
hasDecisionPath: Array.isArray(payload.decision_execution_path) && payload.decision_execution_path.length >= 3,
|
|
278
|
+
hasCorrectionTriggers: hasNonEmptyStringArray(payload?.correction_loop?.triggers),
|
|
279
|
+
hasCorrectionActions: hasNonEmptyStringArray(payload?.correction_loop?.actions),
|
|
280
|
+
hasVerificationGates: hasNonEmptyStringArray(payload?.verification?.gates)
|
|
281
|
+
};
|
|
282
|
+
return {
|
|
283
|
+
passed: Object.values(checks).every(Boolean),
|
|
284
|
+
checks
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
async function ensureSpecDomainArtifacts(projectPath, specId, options = {}) {
|
|
289
|
+
const fileSystem = options.fileSystem || fs;
|
|
290
|
+
const dryRun = options.dryRun === true;
|
|
291
|
+
const force = options.force === true;
|
|
292
|
+
|
|
293
|
+
const paths = resolveSpecPaths(projectPath, specId);
|
|
294
|
+
const domainMapContent = buildProblemDomainMindMap(specId, options);
|
|
295
|
+
const sceneSpecContent = buildSceneSpec(specId, options);
|
|
296
|
+
const domainChainPayload = buildProblemDomainChain(specId, options);
|
|
297
|
+
|
|
298
|
+
const created = {
|
|
299
|
+
domain_map: false,
|
|
300
|
+
scene_spec: false,
|
|
301
|
+
domain_chain: false
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
if (!dryRun) {
|
|
305
|
+
await fileSystem.ensureDir(path.dirname(paths.domainMapPath));
|
|
306
|
+
|
|
307
|
+
const hasDomainMap = await fileSystem.pathExists(paths.domainMapPath);
|
|
308
|
+
if (force || !hasDomainMap) {
|
|
309
|
+
await fileSystem.writeFile(paths.domainMapPath, domainMapContent, 'utf8');
|
|
310
|
+
created.domain_map = true;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const hasSceneSpec = await fileSystem.pathExists(paths.sceneSpecPath);
|
|
314
|
+
if (force || !hasSceneSpec) {
|
|
315
|
+
await fileSystem.writeFile(paths.sceneSpecPath, sceneSpecContent, 'utf8');
|
|
316
|
+
created.scene_spec = true;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const hasDomainChain = await fileSystem.pathExists(paths.domainChainPath);
|
|
320
|
+
if (force || !hasDomainChain) {
|
|
321
|
+
await fileSystem.writeJson(paths.domainChainPath, domainChainPayload, { spaces: 2 });
|
|
322
|
+
created.domain_chain = true;
|
|
323
|
+
}
|
|
324
|
+
} else {
|
|
325
|
+
created.domain_map = true;
|
|
326
|
+
created.scene_spec = true;
|
|
327
|
+
created.domain_chain = true;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return {
|
|
331
|
+
paths: {
|
|
332
|
+
domain_map: paths.domainMapPath,
|
|
333
|
+
scene_spec: paths.sceneSpecPath,
|
|
334
|
+
domain_chain: paths.domainChainPath
|
|
335
|
+
},
|
|
336
|
+
created,
|
|
337
|
+
preview: {
|
|
338
|
+
domain_map: domainMapContent,
|
|
339
|
+
scene_spec: sceneSpecContent,
|
|
340
|
+
domain_chain: domainChainPayload
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
async function validateSpecDomainArtifacts(projectPath, specId, fileSystem = fs) {
|
|
346
|
+
const paths = resolveSpecPaths(projectPath, specId);
|
|
347
|
+
const warnings = [];
|
|
348
|
+
const details = {
|
|
349
|
+
domain_map: {
|
|
350
|
+
path: paths.domainMapPath,
|
|
351
|
+
exists: false,
|
|
352
|
+
checks: {}
|
|
353
|
+
},
|
|
354
|
+
scene_spec: {
|
|
355
|
+
path: paths.sceneSpecPath,
|
|
356
|
+
exists: false,
|
|
357
|
+
checks: {}
|
|
358
|
+
},
|
|
359
|
+
domain_chain: {
|
|
360
|
+
path: paths.domainChainPath,
|
|
361
|
+
exists: false,
|
|
362
|
+
checks: {}
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
let passedChecks = 0;
|
|
367
|
+
const totalChecks = 3;
|
|
368
|
+
|
|
369
|
+
const hasDomainMap = await fileSystem.pathExists(paths.domainMapPath);
|
|
370
|
+
details.domain_map.exists = hasDomainMap;
|
|
371
|
+
if (!hasDomainMap) {
|
|
372
|
+
warnings.push(`Missing required artifact: ${DOMAIN_MAP_RELATIVE_PATH}`);
|
|
373
|
+
} else {
|
|
374
|
+
const content = await fileSystem.readFile(paths.domainMapPath, 'utf8');
|
|
375
|
+
const evaluation = validateProblemDomainMapContent(content);
|
|
376
|
+
details.domain_map.checks = evaluation.checks;
|
|
377
|
+
if (evaluation.passed) {
|
|
378
|
+
passedChecks += 1;
|
|
379
|
+
} else {
|
|
380
|
+
warnings.push(`Invalid ${DOMAIN_MAP_RELATIVE_PATH}: missing mandatory sections`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const hasSceneSpec = await fileSystem.pathExists(paths.sceneSpecPath);
|
|
385
|
+
details.scene_spec.exists = hasSceneSpec;
|
|
386
|
+
if (!hasSceneSpec) {
|
|
387
|
+
warnings.push(`Missing required artifact: ${SCENE_SPEC_RELATIVE_PATH}`);
|
|
388
|
+
} else {
|
|
389
|
+
const content = await fileSystem.readFile(paths.sceneSpecPath, 'utf8');
|
|
390
|
+
const evaluation = validateSceneSpecContent(content);
|
|
391
|
+
details.scene_spec.checks = evaluation.checks;
|
|
392
|
+
if (evaluation.passed) {
|
|
393
|
+
passedChecks += 1;
|
|
394
|
+
} else {
|
|
395
|
+
warnings.push(`Invalid ${SCENE_SPEC_RELATIVE_PATH}: missing mandatory sections`);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const hasDomainChain = await fileSystem.pathExists(paths.domainChainPath);
|
|
400
|
+
details.domain_chain.exists = hasDomainChain;
|
|
401
|
+
if (!hasDomainChain) {
|
|
402
|
+
warnings.push(`Missing required artifact: ${DOMAIN_CHAIN_RELATIVE_PATH}`);
|
|
403
|
+
} else {
|
|
404
|
+
let payload = null;
|
|
405
|
+
try {
|
|
406
|
+
payload = await fileSystem.readJson(paths.domainChainPath);
|
|
407
|
+
} catch (error) {
|
|
408
|
+
warnings.push(`Invalid ${DOMAIN_CHAIN_RELATIVE_PATH}: malformed JSON (${error.message})`);
|
|
409
|
+
}
|
|
410
|
+
if (payload) {
|
|
411
|
+
const evaluation = validateProblemDomainChainPayload(payload, specId);
|
|
412
|
+
details.domain_chain.checks = evaluation.checks;
|
|
413
|
+
if (evaluation.passed) {
|
|
414
|
+
passedChecks += 1;
|
|
415
|
+
} else {
|
|
416
|
+
warnings.push(`Invalid ${DOMAIN_CHAIN_RELATIVE_PATH}: missing mandatory chain fields`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
return {
|
|
422
|
+
passed: passedChecks === totalChecks,
|
|
423
|
+
ratio: passedChecks / totalChecks,
|
|
424
|
+
details,
|
|
425
|
+
warnings
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
module.exports = {
|
|
430
|
+
DOMAIN_MAP_RELATIVE_PATH,
|
|
431
|
+
SCENE_SPEC_RELATIVE_PATH,
|
|
432
|
+
DOMAIN_CHAIN_RELATIVE_PATH,
|
|
433
|
+
DOMAIN_CHAIN_API_VERSION,
|
|
434
|
+
buildProblemDomainMindMap,
|
|
435
|
+
buildSceneSpec,
|
|
436
|
+
buildProblemDomainChain,
|
|
437
|
+
ensureSpecDomainArtifacts,
|
|
438
|
+
validateSpecDomainArtifacts
|
|
439
|
+
};
|
|
@@ -11,6 +11,7 @@ const DEFAULT_GATE_POLICY = {
|
|
|
11
11
|
mandatory: { enabled: true, weight: 30, hard_fail: true },
|
|
12
12
|
tests: { enabled: true, weight: 25, hard_fail: true },
|
|
13
13
|
docs: { enabled: true, weight: 15, hard_fail: false },
|
|
14
|
+
domain_scene_modeling: { enabled: true, weight: 25, hard_fail: true },
|
|
14
15
|
config_consistency: { enabled: true, weight: 15, hard_fail: false },
|
|
15
16
|
traceability: { enabled: true, weight: 15, hard_fail: false }
|
|
16
17
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const fs = require('fs-extra');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const docsCommand = require('../../commands/docs');
|
|
4
|
+
const { validateSpecDomainArtifacts } = require('../../spec/domain-modeling');
|
|
4
5
|
|
|
5
6
|
function createDefaultRules(projectPath = process.cwd()) {
|
|
6
7
|
return [
|
|
@@ -75,6 +76,13 @@ function createDefaultRules(projectPath = process.cwd()) {
|
|
|
75
76
|
};
|
|
76
77
|
}
|
|
77
78
|
},
|
|
79
|
+
{
|
|
80
|
+
id: 'domain_scene_modeling',
|
|
81
|
+
description: 'Verify mandatory problem-domain mind map and scene-spec artifacts',
|
|
82
|
+
async execute(context) {
|
|
83
|
+
return validateSpecDomainArtifacts(projectPath, context.specId, fs);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
78
86
|
{
|
|
79
87
|
id: 'config_consistency',
|
|
80
88
|
description: 'Verify project-level sce config baseline exists',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scene-capability-engine",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.24",
|
|
4
4
|
"description": "SCE (Scene Capability Engine) - A CLI tool and npm package for spec-driven development with AI coding assistants.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -69,11 +69,12 @@
|
|
|
69
69
|
"report:release-ops-weekly": "node scripts/release-ops-weekly-summary.js --json",
|
|
70
70
|
"gate:release-ops-weekly": "node scripts/release-weekly-ops-gate.js",
|
|
71
71
|
"gate:errorbook-release": "node scripts/errorbook-release-gate.js --fail-on-block",
|
|
72
|
+
"gate:errorbook-registry-health": "node scripts/errorbook-registry-health-gate.js",
|
|
72
73
|
"gate:git-managed": "node scripts/git-managed-gate.js --fail-on-violation",
|
|
73
74
|
"gate:release-asset-integrity": "node scripts/release-asset-integrity-check.js",
|
|
74
75
|
"report:release-risk-remediation": "node scripts/release-risk-remediation-bundle.js --json",
|
|
75
76
|
"report:moqui-core-regression": "node scripts/moqui-core-regression-suite.js --json",
|
|
76
|
-
"prepublishOnly": "npm run test:full && npm run test:skip-audit && npm run test:sce-tracking && npm run test:brand-consistency && npm run gate:git-managed && npm run gate:errorbook-release && npm run report:interactive-governance -- --fail-on-alert",
|
|
77
|
+
"prepublishOnly": "npm run test:full && npm run test:skip-audit && npm run test:sce-tracking && npm run test:brand-consistency && npm run gate:git-managed && npm run gate:errorbook-registry-health && npm run gate:errorbook-release && npm run report:interactive-governance -- --fail-on-alert",
|
|
77
78
|
"publish:manual": "npm publish --access public",
|
|
78
79
|
"install-global": "npm install -g .",
|
|
79
80
|
"uninstall-global": "npm uninstall -g scene-capability-engine"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"enabled": true,
|
|
3
|
+
"search_mode": "remote",
|
|
4
|
+
"cache_file": ".sce/errorbook/registry-cache.json",
|
|
5
|
+
"sources": [
|
|
6
|
+
{
|
|
7
|
+
"name": "central",
|
|
8
|
+
"enabled": true,
|
|
9
|
+
"url": "https://raw.githubusercontent.com/heguangyong/sce-errorbook-registry/main/registry/errorbook-registry.json",
|
|
10
|
+
"index_url": "https://raw.githubusercontent.com/heguangyong/sce-errorbook-registry/main/registry/errorbook-registry.index.json"
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
@@ -72,6 +72,17 @@
|
|
|
72
72
|
|
|
73
73
|
**目标**: 用户说"开始执行 Spec XX",AI 自主完成所有任务交付功能
|
|
74
74
|
|
|
75
|
+
### 4.2 强制默认自主推进(无二次确认)⚡
|
|
76
|
+
|
|
77
|
+
**核心**: 默认执行策略必须是“自主闭环推进”,不是“每步等待确认”
|
|
78
|
+
|
|
79
|
+
**默认行为**:
|
|
80
|
+
1) 接到任务后直接进入:分析 → 修改 → 测试 → 修复 → 提交 → 推送(若已配置远端)
|
|
81
|
+
2) 非阻断性问题(可自行定位/修复)不得暂停等待用户二次确认
|
|
82
|
+
3) 仅在以下情况允许中断并请求用户介入:外部权限缺失、不可恢复致命错误、生产高风险变更、业务目标冲突
|
|
83
|
+
|
|
84
|
+
**强制要求**: 不得以“先等你确认再继续”替代执行;未形成可验证结果前不得提前结束
|
|
85
|
+
|
|
75
86
|
### 5. 上下文管控
|
|
76
87
|
|
|
77
88
|
**主动管控避免 token 耗尽**
|
|
@@ -158,6 +169,8 @@
|
|
|
158
169
|
|
|
159
170
|
**复杂问题定位方法**: 优先使用 debug 日志与可观测信号定位(输入、输出、关键分支、异常栈、上下文参数),先还原执行路径再下结论
|
|
160
171
|
|
|
172
|
+
**两轮失败强制调试规则**: 同一问题连续 2 轮修复仍未达到目标验证(测试/门禁/验收)时,必须切换到 debug 定位模式;先补充结构化 debug 日志与关键观测点,复现并固化失败证据,再进入第 3 轮修复。❌ 禁止在未接入调试证据前继续盲改
|
|
173
|
+
|
|
161
174
|
**修复后清理要求**: 问题修复并验证通过后,必须清理临时 debug 日志、临时埋点、一次性脚本和调试开关;需要长期保留的日志必须转为可配置观测项且默认关闭
|
|
162
175
|
|
|
163
176
|
**允许的临时措施**: 仅在生产止血场景可临时绕行,但必须同时给出根因修复任务、回滚条件和截止时间
|
|
@@ -189,6 +202,22 @@
|
|
|
189
202
|
|
|
190
203
|
**目标**: 保证跨 Agent 连续性、可追溯历史、上下文可控,避免因 Agent session 长短差异导致上下文漂移
|
|
191
204
|
|
|
205
|
+
### 14. 问题域思维导图 + 场景化 Spec 强制原则 🧠
|
|
206
|
+
|
|
207
|
+
**核心**: Spec 推进必须先完成“问题域思维导图”与“场景化 Spec 契约”,再进入实现与修复闭环
|
|
208
|
+
|
|
209
|
+
**硬规则**:
|
|
210
|
+
1) 每个 Spec 必须具备:
|
|
211
|
+
- `.sce/specs/<spec>/custom/problem-domain-map.md`
|
|
212
|
+
- `.sce/specs/<spec>/custom/scene-spec.md`
|
|
213
|
+
- `.sce/specs/<spec>/custom/problem-domain-chain.json`
|
|
214
|
+
2) `problem-domain-map` 必须包含:Root Problem、Mind Map、Layered Exploration Chain、Correction Loop
|
|
215
|
+
3) `scene-spec` 必须包含:Scene Definition、Ontology Coverage、Decision & Execution Path、Acceptance & Gate
|
|
216
|
+
4) `problem-domain-chain.json` 必须包含可机读思维链:problem/ontology/hypotheses/risks/decision_execution_path/correction_loop/verification
|
|
217
|
+
5) 默认门禁强制校验上述结构,缺失即 `no-go`
|
|
218
|
+
|
|
219
|
+
**目标**: 用全局问题域视角 + 场景契约约束,减少方向性错误与盲改,提升纠偏效率
|
|
220
|
+
|
|
192
221
|
---
|
|
193
222
|
|
|
194
|
-
|
|
223
|
+
v21.0 | 2026-03-01 | 强化“强制默认自主推进(无二次确认)”执行基线
|