scene-capability-engine 3.6.44 → 3.6.46

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 (61) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/bin/scene-capability-engine.js +36 -2
  3. package/docs/command-reference.md +5 -0
  4. package/docs/releases/README.md +2 -0
  5. package/docs/releases/v3.6.45.md +18 -0
  6. package/docs/releases/v3.6.46.md +23 -0
  7. package/docs/zh/releases/README.md +2 -0
  8. package/docs/zh/releases/v3.6.45.md +18 -0
  9. package/docs/zh/releases/v3.6.46.md +23 -0
  10. package/lib/workspace/collab-governance-audit.js +575 -0
  11. package/package.json +4 -2
  12. package/scripts/auto-strategy-router.js +231 -0
  13. package/scripts/capability-mapping-report.js +339 -0
  14. package/scripts/check-branding-consistency.js +140 -0
  15. package/scripts/check-sce-tracking.js +54 -0
  16. package/scripts/check-skip-allowlist.js +94 -0
  17. package/scripts/errorbook-registry-health-gate.js +172 -0
  18. package/scripts/errorbook-release-gate.js +132 -0
  19. package/scripts/failure-attribution-repair.js +317 -0
  20. package/scripts/git-managed-gate.js +464 -0
  21. package/scripts/interactive-approval-event-projection.js +400 -0
  22. package/scripts/interactive-approval-workflow.js +829 -0
  23. package/scripts/interactive-authorization-tier-evaluate.js +413 -0
  24. package/scripts/interactive-change-plan-gate.js +225 -0
  25. package/scripts/interactive-context-bridge.js +617 -0
  26. package/scripts/interactive-customization-loop.js +1690 -0
  27. package/scripts/interactive-dialogue-governance.js +842 -0
  28. package/scripts/interactive-feedback-log.js +253 -0
  29. package/scripts/interactive-flow-smoke.js +238 -0
  30. package/scripts/interactive-flow.js +1059 -0
  31. package/scripts/interactive-governance-report.js +1112 -0
  32. package/scripts/interactive-intent-build.js +707 -0
  33. package/scripts/interactive-loop-smoke.js +215 -0
  34. package/scripts/interactive-moqui-adapter.js +304 -0
  35. package/scripts/interactive-plan-build.js +426 -0
  36. package/scripts/interactive-runtime-policy-evaluate.js +495 -0
  37. package/scripts/interactive-work-order-build.js +552 -0
  38. package/scripts/matrix-regression-gate.js +167 -0
  39. package/scripts/moqui-core-regression-suite.js +397 -0
  40. package/scripts/moqui-lexicon-audit.js +651 -0
  41. package/scripts/moqui-matrix-remediation-phased-runner.js +865 -0
  42. package/scripts/moqui-matrix-remediation-queue.js +852 -0
  43. package/scripts/moqui-metadata-extract.js +1340 -0
  44. package/scripts/moqui-rebuild-gate.js +167 -0
  45. package/scripts/moqui-release-summary.js +729 -0
  46. package/scripts/moqui-standard-rebuild.js +1370 -0
  47. package/scripts/moqui-template-baseline-report.js +682 -0
  48. package/scripts/npm-package-runtime-asset-check.js +221 -0
  49. package/scripts/problem-closure-gate.js +441 -0
  50. package/scripts/release-asset-integrity-check.js +216 -0
  51. package/scripts/release-asset-nonempty-normalize.js +166 -0
  52. package/scripts/release-drift-evaluate.js +223 -0
  53. package/scripts/release-drift-signals.js +255 -0
  54. package/scripts/release-governance-snapshot-export.js +132 -0
  55. package/scripts/release-ops-weekly-summary.js +934 -0
  56. package/scripts/release-risk-remediation-bundle.js +315 -0
  57. package/scripts/release-weekly-ops-gate.js +423 -0
  58. package/scripts/state-migration-reconciliation-gate.js +110 -0
  59. package/scripts/state-storage-tiering-audit.js +337 -0
  60. package/scripts/steering-content-audit.js +393 -0
  61. package/scripts/symbol-evidence-locate.js +366 -0
@@ -0,0 +1,317 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+
7
+ const DEFAULT_TAXONOMY_FILE = 'docs/agent-runtime/failure-taxonomy-baseline.json';
8
+
9
+ function parseArgs(argv = []) {
10
+ const options = {
11
+ error: '',
12
+ errorFile: '',
13
+ taxonomyFile: DEFAULT_TAXONOMY_FILE,
14
+ testFailures: 0,
15
+ attemptedPasses: 0,
16
+ maxRepairPasses: 1,
17
+ tests: [],
18
+ json: false
19
+ };
20
+
21
+ for (let index = 0; index < argv.length; index += 1) {
22
+ const token = argv[index];
23
+ const next = argv[index + 1];
24
+ if (token === '--error' && next) {
25
+ options.error = next;
26
+ index += 1;
27
+ continue;
28
+ }
29
+ if (token === '--error-file' && next) {
30
+ options.errorFile = next;
31
+ index += 1;
32
+ continue;
33
+ }
34
+ if (token === '--taxonomy-file' && next) {
35
+ options.taxonomyFile = next;
36
+ index += 1;
37
+ continue;
38
+ }
39
+ if (token === '--test-failures' && next) {
40
+ options.testFailures = Number(next);
41
+ index += 1;
42
+ continue;
43
+ }
44
+ if (token === '--attempted-passes' && next) {
45
+ options.attemptedPasses = Number(next);
46
+ index += 1;
47
+ continue;
48
+ }
49
+ if (token === '--max-repair-passes' && next) {
50
+ options.maxRepairPasses = Number(next);
51
+ index += 1;
52
+ continue;
53
+ }
54
+ if (token === '--tests' && next) {
55
+ options.tests = next
56
+ .split(',')
57
+ .map((item) => item.trim())
58
+ .filter(Boolean);
59
+ index += 1;
60
+ continue;
61
+ }
62
+ if (token === '--json') {
63
+ options.json = true;
64
+ continue;
65
+ }
66
+ if (token === '--help' || token === '-h') {
67
+ printHelpAndExit(0);
68
+ }
69
+ }
70
+
71
+ if (!Number.isFinite(options.testFailures) || options.testFailures < 0) {
72
+ throw new Error('--test-failures must be a non-negative number.');
73
+ }
74
+ if (!Number.isFinite(options.attemptedPasses) || options.attemptedPasses < 0) {
75
+ throw new Error('--attempted-passes must be a non-negative number.');
76
+ }
77
+ if (!Number.isFinite(options.maxRepairPasses) || options.maxRepairPasses < 0) {
78
+ throw new Error('--max-repair-passes must be a non-negative number.');
79
+ }
80
+
81
+ return options;
82
+ }
83
+
84
+ function printHelpAndExit(code) {
85
+ const lines = [
86
+ 'Usage: node scripts/failure-attribution-repair.js [options]',
87
+ '',
88
+ 'Options:',
89
+ ' --error <text> Failure text to classify',
90
+ ' --error-file <path> Read failure text from file',
91
+ ` --taxonomy-file <path> Failure taxonomy JSON path (default: ${DEFAULT_TAXONOMY_FILE})`,
92
+ ' --test-failures <n> Number of failing tests (default: 0)',
93
+ ' --attempted-passes <n> Repair passes already consumed (default: 0)',
94
+ ' --max-repair-passes <n> Max repair passes (default: 1)',
95
+ ' --tests <csv> Targeted test commands for re-run',
96
+ ' --json Print JSON payload',
97
+ ' -h, --help Show this help'
98
+ ];
99
+ console.log(lines.join('\n'));
100
+ process.exit(code);
101
+ }
102
+
103
+ function loadTextError(options) {
104
+ if (typeof options.error === 'string' && options.error.trim()) {
105
+ return options.error.trim();
106
+ }
107
+ if (typeof options.errorFile === 'string' && options.errorFile.trim()) {
108
+ const resolvedFile = path.resolve(process.cwd(), options.errorFile);
109
+ if (!fs.existsSync(resolvedFile)) {
110
+ throw new Error(`error file not found: ${options.errorFile}`);
111
+ }
112
+ const content = fs.readFileSync(resolvedFile, 'utf8').trim();
113
+ if (content) {
114
+ return content;
115
+ }
116
+ }
117
+ return '';
118
+ }
119
+
120
+ function loadTaxonomy(taxonomyFile) {
121
+ const resolved = path.resolve(process.cwd(), taxonomyFile);
122
+ if (!fs.existsSync(resolved)) {
123
+ throw new Error(`taxonomy file not found: ${taxonomyFile}`);
124
+ }
125
+ const payload = JSON.parse(fs.readFileSync(resolved, 'utf8'));
126
+ const categories = Array.isArray(payload.categories) ? payload.categories : [];
127
+ return {
128
+ version: payload.version || 'unknown',
129
+ default_category: payload.default_category || 'unknown',
130
+ categories
131
+ };
132
+ }
133
+
134
+ function normalizePattern(pattern) {
135
+ return `${pattern || ''}`.trim().toLowerCase();
136
+ }
137
+
138
+ function classifyFailure(errorText, taxonomy) {
139
+ const message = `${errorText || ''}`.toLowerCase();
140
+ let bestMatch = null;
141
+
142
+ for (const category of taxonomy.categories) {
143
+ const patterns = Array.isArray(category.patterns) ? category.patterns : [];
144
+ const matchedPatterns = patterns
145
+ .map(normalizePattern)
146
+ .filter((pattern) => pattern && message.includes(pattern));
147
+ if (matchedPatterns.length === 0) {
148
+ continue;
149
+ }
150
+ const score = matchedPatterns.length;
151
+ if (!bestMatch || score > bestMatch.score) {
152
+ bestMatch = {
153
+ category,
154
+ matchedPatterns,
155
+ score
156
+ };
157
+ }
158
+ }
159
+
160
+ if (!bestMatch) {
161
+ const fallback = taxonomy.categories.find((category) => category.id === taxonomy.default_category)
162
+ || taxonomy.categories.find((category) => category.id === 'unknown')
163
+ || {
164
+ id: taxonomy.default_category || 'unknown',
165
+ repairable: false,
166
+ default_actions: ['collect diagnostics']
167
+ };
168
+ return {
169
+ category: fallback.id || 'unknown',
170
+ confidence: 'low',
171
+ repairable: fallback.repairable === true,
172
+ matched_patterns: [],
173
+ default_actions: Array.isArray(fallback.default_actions) ? fallback.default_actions : []
174
+ };
175
+ }
176
+
177
+ const confidence = bestMatch.matchedPatterns.length >= 2 ? 'high' : 'medium';
178
+ return {
179
+ category: bestMatch.category.id || taxonomy.default_category || 'unknown',
180
+ confidence,
181
+ repairable: bestMatch.category.repairable === true,
182
+ matched_patterns: bestMatch.matchedPatterns,
183
+ default_actions: Array.isArray(bestMatch.category.default_actions)
184
+ ? bestMatch.category.default_actions
185
+ : []
186
+ };
187
+ }
188
+
189
+ function buildRepairPlan({ attribution, testFailures, attemptedPasses, maxRepairPasses, tests }) {
190
+ const remainingPasses = Math.max(0, Math.floor(maxRepairPasses) - Math.floor(attemptedPasses));
191
+ const canRepair = attribution.repairable === true && remainingPasses > 0;
192
+
193
+ if (!canRepair) {
194
+ const reason = attribution.repairable !== true
195
+ ? `category '${attribution.category}' is non-repairable in bounded mode`
196
+ : `repair pass budget exhausted (${attemptedPasses}/${maxRepairPasses})`;
197
+ return {
198
+ decision: 'stop',
199
+ reason,
200
+ actions: [
201
+ 'emit failure summary and stop automatic retries',
202
+ 'escalate to manual review or authorization flow'
203
+ ],
204
+ retest: {
205
+ required: false,
206
+ commands: []
207
+ },
208
+ terminal_summary: {
209
+ status: 'stopped',
210
+ stop_reason: reason,
211
+ attempted_passes: attemptedPasses,
212
+ max_repair_passes: maxRepairPasses
213
+ }
214
+ };
215
+ }
216
+
217
+ const actionSet = new Set(attribution.default_actions || []);
218
+ actionSet.add('apply one minimal scoped patch');
219
+ const retestCommands = Array.isArray(tests) && tests.length > 0
220
+ ? tests
221
+ : (
222
+ testFailures > 0
223
+ ? ['run failing test subset']
224
+ : ['run targeted verification tests']
225
+ );
226
+ actionSet.add('re-run targeted tests after repair pass');
227
+
228
+ return {
229
+ decision: 'run_repair_pass',
230
+ reason: `category '${attribution.category}' is repairable with remaining budget`,
231
+ actions: [...actionSet],
232
+ retest: {
233
+ required: true,
234
+ commands: retestCommands
235
+ },
236
+ terminal_summary: {
237
+ status: 'repair-scheduled',
238
+ stop_reason: null,
239
+ attempted_passes: attemptedPasses,
240
+ max_repair_passes: maxRepairPasses,
241
+ remaining_after_this_pass: Math.max(0, remainingPasses - 1)
242
+ }
243
+ };
244
+ }
245
+
246
+ function buildReport(options, errorText, taxonomy, attribution, repairPlan) {
247
+ return {
248
+ mode: 'failure-attribution-repair',
249
+ generated_at: new Date().toISOString(),
250
+ input: {
251
+ error: errorText,
252
+ test_failures: options.testFailures,
253
+ attempted_passes: options.attemptedPasses,
254
+ max_repair_passes: options.maxRepairPasses,
255
+ tests: options.tests
256
+ },
257
+ taxonomy: {
258
+ version: taxonomy.version,
259
+ default_category: taxonomy.default_category
260
+ },
261
+ attribution,
262
+ repair_policy: {
263
+ bounded: true,
264
+ attempted_passes: options.attemptedPasses,
265
+ max_repair_passes: options.maxRepairPasses
266
+ },
267
+ repair_pass: {
268
+ decision: repairPlan.decision,
269
+ reason: repairPlan.reason,
270
+ actions: repairPlan.actions
271
+ },
272
+ retest_plan: repairPlan.retest,
273
+ terminal_summary: repairPlan.terminal_summary
274
+ };
275
+ }
276
+
277
+ function main() {
278
+ const options = parseArgs(process.argv.slice(2));
279
+ const errorText = loadTextError(options);
280
+ const taxonomy = loadTaxonomy(options.taxonomyFile);
281
+ const attribution = classifyFailure(errorText, taxonomy);
282
+ const repairPlan = buildRepairPlan({
283
+ attribution,
284
+ testFailures: options.testFailures,
285
+ attemptedPasses: options.attemptedPasses,
286
+ maxRepairPasses: options.maxRepairPasses,
287
+ tests: options.tests
288
+ });
289
+ const payload = buildReport(options, errorText, taxonomy, attribution, repairPlan);
290
+
291
+ if (options.json) {
292
+ process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
293
+ } else {
294
+ process.stdout.write(`failure category=${payload.attribution.category}\n`);
295
+ process.stdout.write(`repair decision=${payload.repair_pass.decision}\n`);
296
+ process.stdout.write(`terminal status=${payload.terminal_summary.status}\n`);
297
+ }
298
+ }
299
+
300
+ if (require.main === module) {
301
+ try {
302
+ main();
303
+ } catch (error) {
304
+ console.error(`failure-attribution-repair failed: ${error.message}`);
305
+ process.exit(1);
306
+ }
307
+ }
308
+
309
+ module.exports = {
310
+ DEFAULT_TAXONOMY_FILE,
311
+ parseArgs,
312
+ loadTextError,
313
+ loadTaxonomy,
314
+ classifyFailure,
315
+ buildRepairPlan,
316
+ buildReport
317
+ };