scene-capability-engine 3.6.45 → 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.
- package/CHANGELOG.md +11 -0
- package/docs/releases/README.md +1 -0
- package/docs/releases/v3.6.46.md +23 -0
- package/docs/zh/releases/README.md +1 -0
- package/docs/zh/releases/v3.6.46.md +23 -0
- package/package.json +4 -2
- package/scripts/auto-strategy-router.js +231 -0
- package/scripts/capability-mapping-report.js +339 -0
- package/scripts/check-branding-consistency.js +140 -0
- package/scripts/check-sce-tracking.js +54 -0
- package/scripts/check-skip-allowlist.js +94 -0
- package/scripts/errorbook-registry-health-gate.js +172 -0
- package/scripts/errorbook-release-gate.js +132 -0
- package/scripts/failure-attribution-repair.js +317 -0
- package/scripts/git-managed-gate.js +464 -0
- package/scripts/interactive-approval-event-projection.js +400 -0
- package/scripts/interactive-approval-workflow.js +829 -0
- package/scripts/interactive-authorization-tier-evaluate.js +413 -0
- package/scripts/interactive-change-plan-gate.js +225 -0
- package/scripts/interactive-context-bridge.js +617 -0
- package/scripts/interactive-customization-loop.js +1690 -0
- package/scripts/interactive-dialogue-governance.js +842 -0
- package/scripts/interactive-feedback-log.js +253 -0
- package/scripts/interactive-flow-smoke.js +238 -0
- package/scripts/interactive-flow.js +1059 -0
- package/scripts/interactive-governance-report.js +1112 -0
- package/scripts/interactive-intent-build.js +707 -0
- package/scripts/interactive-loop-smoke.js +215 -0
- package/scripts/interactive-moqui-adapter.js +304 -0
- package/scripts/interactive-plan-build.js +426 -0
- package/scripts/interactive-runtime-policy-evaluate.js +495 -0
- package/scripts/interactive-work-order-build.js +552 -0
- package/scripts/matrix-regression-gate.js +167 -0
- package/scripts/moqui-core-regression-suite.js +397 -0
- package/scripts/moqui-lexicon-audit.js +651 -0
- package/scripts/moqui-matrix-remediation-phased-runner.js +865 -0
- package/scripts/moqui-matrix-remediation-queue.js +852 -0
- package/scripts/moqui-metadata-extract.js +1340 -0
- package/scripts/moqui-rebuild-gate.js +167 -0
- package/scripts/moqui-release-summary.js +729 -0
- package/scripts/moqui-standard-rebuild.js +1370 -0
- package/scripts/moqui-template-baseline-report.js +682 -0
- package/scripts/npm-package-runtime-asset-check.js +221 -0
- package/scripts/problem-closure-gate.js +441 -0
- package/scripts/release-asset-integrity-check.js +216 -0
- package/scripts/release-asset-nonempty-normalize.js +166 -0
- package/scripts/release-drift-evaluate.js +223 -0
- package/scripts/release-drift-signals.js +255 -0
- package/scripts/release-governance-snapshot-export.js +132 -0
- package/scripts/release-ops-weekly-summary.js +934 -0
- package/scripts/release-risk-remediation-bundle.js +315 -0
- package/scripts/release-weekly-ops-gate.js +423 -0
- package/scripts/state-migration-reconciliation-gate.js +110 -0
- package/scripts/state-storage-tiering-audit.js +337 -0
- package/scripts/steering-content-audit.js +393 -0
- package/scripts/symbol-evidence-locate.js +366 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const fs = require('fs-extra');
|
|
6
|
+
|
|
7
|
+
const DEFAULT_GATE_REPORT = '.sce/reports/release-evidence/release-gate.json';
|
|
8
|
+
const DEFAULT_OUT = '.sce/reports/release-evidence/release-risk-remediation-bundle.json';
|
|
9
|
+
const DEFAULT_MARKDOWN_OUT = '.sce/reports/release-evidence/release-risk-remediation-bundle.md';
|
|
10
|
+
const DEFAULT_LINES_OUT = '.sce/reports/release-evidence/release-risk-remediation.commands.lines';
|
|
11
|
+
|
|
12
|
+
function parseArgs(argv) {
|
|
13
|
+
const options = {
|
|
14
|
+
gateReport: DEFAULT_GATE_REPORT,
|
|
15
|
+
out: DEFAULT_OUT,
|
|
16
|
+
markdownOut: DEFAULT_MARKDOWN_OUT,
|
|
17
|
+
linesOut: DEFAULT_LINES_OUT,
|
|
18
|
+
json: false
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
22
|
+
const token = argv[i];
|
|
23
|
+
const next = argv[i + 1];
|
|
24
|
+
if (token === '--gate-report' && next) {
|
|
25
|
+
options.gateReport = next;
|
|
26
|
+
i += 1;
|
|
27
|
+
} else if (token === '--out' && next) {
|
|
28
|
+
options.out = next;
|
|
29
|
+
i += 1;
|
|
30
|
+
} else if (token === '--markdown-out' && next) {
|
|
31
|
+
options.markdownOut = next;
|
|
32
|
+
i += 1;
|
|
33
|
+
} else if (token === '--lines-out' && next) {
|
|
34
|
+
options.linesOut = next;
|
|
35
|
+
i += 1;
|
|
36
|
+
} else if (token === '--json') {
|
|
37
|
+
options.json = true;
|
|
38
|
+
} else if (token === '--help' || token === '-h') {
|
|
39
|
+
printHelpAndExit(0);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return options;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function printHelpAndExit(code) {
|
|
47
|
+
const lines = [
|
|
48
|
+
'Usage: node scripts/release-risk-remediation-bundle.js [options]',
|
|
49
|
+
'',
|
|
50
|
+
'Options:',
|
|
51
|
+
` --gate-report <path> release gate report JSON (default: ${DEFAULT_GATE_REPORT})`,
|
|
52
|
+
` --out <path> JSON output path (default: ${DEFAULT_OUT})`,
|
|
53
|
+
` --markdown-out <path> Markdown output path (default: ${DEFAULT_MARKDOWN_OUT})`,
|
|
54
|
+
` --lines-out <path> Command lines output path (default: ${DEFAULT_LINES_OUT})`,
|
|
55
|
+
' --json Print JSON payload',
|
|
56
|
+
' -h, --help Show this help'
|
|
57
|
+
];
|
|
58
|
+
console.log(lines.join('\n'));
|
|
59
|
+
process.exit(code);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function normalizeText(value) {
|
|
63
|
+
return `${value || ''}`.trim();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function uniquePush(target, seen, value) {
|
|
67
|
+
const text = normalizeText(value);
|
|
68
|
+
if (!text || seen.has(text)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
seen.add(text);
|
|
72
|
+
target.push(text);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function safeReadJson(cwd, candidatePath) {
|
|
76
|
+
const absolutePath = path.isAbsolute(candidatePath)
|
|
77
|
+
? candidatePath
|
|
78
|
+
: path.resolve(cwd, candidatePath);
|
|
79
|
+
const relativePath = path.relative(cwd, absolutePath) || '.';
|
|
80
|
+
const exists = await fs.pathExists(absolutePath);
|
|
81
|
+
if (!exists) {
|
|
82
|
+
return {
|
|
83
|
+
path: relativePath,
|
|
84
|
+
exists: false,
|
|
85
|
+
parse_error: null,
|
|
86
|
+
payload: null
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
const payload = await fs.readJson(absolutePath);
|
|
91
|
+
return {
|
|
92
|
+
path: relativePath,
|
|
93
|
+
exists: true,
|
|
94
|
+
parse_error: null,
|
|
95
|
+
payload
|
|
96
|
+
};
|
|
97
|
+
} catch (error) {
|
|
98
|
+
return {
|
|
99
|
+
path: relativePath,
|
|
100
|
+
exists: true,
|
|
101
|
+
parse_error: error.message,
|
|
102
|
+
payload: null
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function buildRemediationPlan(gatePayload) {
|
|
108
|
+
const commands = [];
|
|
109
|
+
const recommendations = [];
|
|
110
|
+
const reasons = [];
|
|
111
|
+
const seenCommands = new Set();
|
|
112
|
+
const seenRecommendations = new Set();
|
|
113
|
+
const seenReasons = new Set();
|
|
114
|
+
const addCommand = (cmd) => uniquePush(commands, seenCommands, cmd);
|
|
115
|
+
const addRecommendation = (text) => uniquePush(recommendations, seenRecommendations, text);
|
|
116
|
+
const addReason = (text) => uniquePush(reasons, seenReasons, text);
|
|
117
|
+
|
|
118
|
+
const weeklyOps = gatePayload && gatePayload.weekly_ops && typeof gatePayload.weekly_ops === 'object'
|
|
119
|
+
? gatePayload.weekly_ops
|
|
120
|
+
: {};
|
|
121
|
+
const weeklySignals = weeklyOps && weeklyOps.signals && typeof weeklyOps.signals === 'object'
|
|
122
|
+
? weeklyOps.signals
|
|
123
|
+
: {};
|
|
124
|
+
const weeklyViolations = Array.isArray(weeklyOps.violations) ? weeklyOps.violations : [];
|
|
125
|
+
const weeklyBlocked = weeklyOps.blocked === true;
|
|
126
|
+
|
|
127
|
+
const drift = gatePayload && gatePayload.drift && typeof gatePayload.drift === 'object'
|
|
128
|
+
? gatePayload.drift
|
|
129
|
+
: {};
|
|
130
|
+
const driftAlerts = Array.isArray(drift.alerts) ? drift.alerts : [];
|
|
131
|
+
const driftBlocked = drift.blocked === true;
|
|
132
|
+
|
|
133
|
+
if (weeklyBlocked || weeklyViolations.length > 0) {
|
|
134
|
+
addReason('weekly-ops-gate');
|
|
135
|
+
weeklyViolations.forEach(item => addReason(item));
|
|
136
|
+
addCommand('node scripts/release-ops-weekly-summary.js --json');
|
|
137
|
+
addCommand('node scripts/release-weekly-ops-gate.js');
|
|
138
|
+
addCommand('npx sce auto handoff evidence --file .sce/reports/release-evidence/handoff-runs.json --json');
|
|
139
|
+
addCommand('npx sce auto handoff regression --session-id latest --json');
|
|
140
|
+
addRecommendation('Resolve weekly risk drivers first (handoff quality, governance breach, matrix regression trend).');
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (weeklySignals && weeklySignals.governance_status === 'alert') {
|
|
144
|
+
addReason('interactive-governance-alert');
|
|
145
|
+
addCommand('node scripts/interactive-governance-report.js --period weekly --fail-on-alert --json');
|
|
146
|
+
addRecommendation('Clear medium/high governance breaches before next release tag.');
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const weeklyDialogueBlockRate = Number(
|
|
150
|
+
weeklySignals && weeklySignals.dialogue_authorization_block_rate_percent
|
|
151
|
+
);
|
|
152
|
+
const weeklyDialogueBlockRateMax = Number(
|
|
153
|
+
weeklyOps && weeklyOps.max_dialogue_authorization_block_rate_percent
|
|
154
|
+
);
|
|
155
|
+
const dialogueRateExceeded = (
|
|
156
|
+
Number.isFinite(weeklyDialogueBlockRate)
|
|
157
|
+
&& Number.isFinite(weeklyDialogueBlockRateMax)
|
|
158
|
+
&& weeklyDialogueBlockRate > weeklyDialogueBlockRateMax
|
|
159
|
+
) || weeklyViolations.some(item => `${item || ''}`.includes('dialogue-authorization block rate'));
|
|
160
|
+
if (dialogueRateExceeded) {
|
|
161
|
+
addReason('dialogue-authorization-block-pressure');
|
|
162
|
+
addCommand('node scripts/interactive-dialogue-governance.js --policy docs/interactive-customization/dialogue-governance-policy-baseline.json --authorization-dialogue-policy docs/interactive-customization/authorization-dialogue-policy-baseline.json --json');
|
|
163
|
+
addRecommendation('Reduce dialogue-authorization block pressure by tuning ui-mode specific authorization dialogue rules for user-app vs ops-console.');
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const weeklyAuthTierBlockRate = Number(
|
|
167
|
+
weeklySignals && weeklySignals.authorization_tier_block_rate_percent
|
|
168
|
+
);
|
|
169
|
+
const weeklyAuthTierBlockRateMax = Number(
|
|
170
|
+
weeklyOps && weeklyOps.max_authorization_tier_block_rate_percent
|
|
171
|
+
);
|
|
172
|
+
const authorizationTierRateExceeded = (
|
|
173
|
+
Number.isFinite(weeklyAuthTierBlockRate)
|
|
174
|
+
&& Number.isFinite(weeklyAuthTierBlockRateMax)
|
|
175
|
+
&& weeklyAuthTierBlockRate > weeklyAuthTierBlockRateMax
|
|
176
|
+
) || weeklyViolations.some(item => `${item || ''}`.includes('authorization-tier block rate'));
|
|
177
|
+
if (authorizationTierRateExceeded) {
|
|
178
|
+
addReason('authorization-tier-block-pressure');
|
|
179
|
+
addCommand('node scripts/interactive-authorization-tier-evaluate.js --policy docs/interactive-customization/authorization-tier-policy-baseline.json --json');
|
|
180
|
+
addRecommendation('Tune authorization-tier profile/environment step-up policy to reduce deny/review pressure while preserving safety constraints.');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (driftAlerts.length > 0 || driftBlocked) {
|
|
184
|
+
addReason('release-drift-alerts');
|
|
185
|
+
driftAlerts.forEach(item => addReason(item));
|
|
186
|
+
addCommand('npx sce auto handoff gate-index --dir .sce/reports/release-evidence --out .sce/reports/release-evidence/release-gate-history.json --json');
|
|
187
|
+
addCommand('node scripts/release-drift-evaluate.js');
|
|
188
|
+
addCommand('node scripts/release-ops-weekly-summary.js --json');
|
|
189
|
+
addRecommendation('Review drift trend before release and remediate consecutive failures/high-risk share spikes.');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (commands.length === 0) {
|
|
193
|
+
addRecommendation('No blocking weekly/drift signal found in gate report.');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const phases = [];
|
|
197
|
+
if (commands.length > 0) {
|
|
198
|
+
phases.push({
|
|
199
|
+
id: 'diagnose',
|
|
200
|
+
commands: commands.slice(0, Math.min(3, commands.length))
|
|
201
|
+
});
|
|
202
|
+
if (commands.length > 3) {
|
|
203
|
+
phases.push({
|
|
204
|
+
id: 'remediate',
|
|
205
|
+
commands: commands.slice(3)
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return {
|
|
211
|
+
reasons,
|
|
212
|
+
recommendations,
|
|
213
|
+
commands,
|
|
214
|
+
phases
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function buildMarkdown(bundle) {
|
|
219
|
+
const lines = [];
|
|
220
|
+
lines.push('# Release Risk Remediation Bundle');
|
|
221
|
+
lines.push('');
|
|
222
|
+
lines.push(`- Generated at: ${bundle.generated_at}`);
|
|
223
|
+
lines.push(`- Gate report: ${bundle.input.gate_report.path}`);
|
|
224
|
+
lines.push(`- Blocking signals: ${bundle.summary.blocking_signal_count}`);
|
|
225
|
+
lines.push('');
|
|
226
|
+
lines.push('## Reasons');
|
|
227
|
+
lines.push('');
|
|
228
|
+
if (bundle.plan.reasons.length === 0) {
|
|
229
|
+
lines.push('- none');
|
|
230
|
+
} else {
|
|
231
|
+
bundle.plan.reasons.forEach(item => lines.push(`- ${item}`));
|
|
232
|
+
}
|
|
233
|
+
lines.push('');
|
|
234
|
+
lines.push('## Commands');
|
|
235
|
+
lines.push('');
|
|
236
|
+
if (bundle.plan.commands.length === 0) {
|
|
237
|
+
lines.push('- none');
|
|
238
|
+
} else {
|
|
239
|
+
bundle.plan.commands.forEach(item => lines.push(`- \`${item}\``));
|
|
240
|
+
}
|
|
241
|
+
lines.push('');
|
|
242
|
+
lines.push('## Recommendations');
|
|
243
|
+
lines.push('');
|
|
244
|
+
bundle.plan.recommendations.forEach(item => lines.push(`- ${item}`));
|
|
245
|
+
return `${lines.join('\n')}\n`;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
async function main() {
|
|
249
|
+
const options = parseArgs(process.argv.slice(2));
|
|
250
|
+
const cwd = process.cwd();
|
|
251
|
+
const gateInput = await safeReadJson(cwd, options.gateReport);
|
|
252
|
+
if (!gateInput.exists) {
|
|
253
|
+
throw new Error(`gate report missing: ${gateInput.path}`);
|
|
254
|
+
}
|
|
255
|
+
if (gateInput.parse_error) {
|
|
256
|
+
throw new Error(`gate report parse error: ${gateInput.parse_error}`);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const plan = buildRemediationPlan(gateInput.payload || {});
|
|
260
|
+
const outPath = path.resolve(cwd, options.out);
|
|
261
|
+
const markdownOutPath = path.resolve(cwd, options.markdownOut);
|
|
262
|
+
const linesOutPath = path.resolve(cwd, options.linesOut);
|
|
263
|
+
const blockingSignalCount = plan.reasons.filter(item =>
|
|
264
|
+
item === 'weekly-ops-gate'
|
|
265
|
+
|| item === 'release-drift-alerts'
|
|
266
|
+
|| item === 'interactive-governance-alert'
|
|
267
|
+
).length;
|
|
268
|
+
|
|
269
|
+
const bundle = {
|
|
270
|
+
mode: 'release-risk-remediation-bundle',
|
|
271
|
+
generated_at: new Date().toISOString(),
|
|
272
|
+
input: {
|
|
273
|
+
gate_report: gateInput
|
|
274
|
+
},
|
|
275
|
+
summary: {
|
|
276
|
+
blocking_signal_count: blockingSignalCount,
|
|
277
|
+
command_count: plan.commands.length,
|
|
278
|
+
recommendation_count: plan.recommendations.length
|
|
279
|
+
},
|
|
280
|
+
plan,
|
|
281
|
+
output: {
|
|
282
|
+
json: path.relative(cwd, outPath) || '.',
|
|
283
|
+
markdown: path.relative(cwd, markdownOutPath) || '.',
|
|
284
|
+
commands_lines: path.relative(cwd, linesOutPath) || '.'
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
await fs.ensureDir(path.dirname(outPath));
|
|
289
|
+
await fs.writeJson(outPath, bundle, { spaces: 2 });
|
|
290
|
+
await fs.ensureDir(path.dirname(markdownOutPath));
|
|
291
|
+
await fs.writeFile(markdownOutPath, buildMarkdown(bundle), 'utf8');
|
|
292
|
+
await fs.ensureDir(path.dirname(linesOutPath));
|
|
293
|
+
await fs.writeFile(linesOutPath, `${plan.commands.join('\n')}\n`, 'utf8');
|
|
294
|
+
|
|
295
|
+
if (options.json) {
|
|
296
|
+
process.stdout.write(`${JSON.stringify(bundle, null, 2)}\n`);
|
|
297
|
+
} else {
|
|
298
|
+
process.stdout.write(`Release remediation bundle generated (${bundle.summary.command_count} commands).\n`);
|
|
299
|
+
process.stdout.write(`- JSON: ${bundle.output.json}\n`);
|
|
300
|
+
process.stdout.write(`- Markdown: ${bundle.output.markdown}\n`);
|
|
301
|
+
process.stdout.write(`- Commands: ${bundle.output.commands_lines}\n`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (require.main === module) {
|
|
306
|
+
main().catch((error) => {
|
|
307
|
+
console.error(`Release remediation bundle failed: ${error.message}`);
|
|
308
|
+
process.exit(1);
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
module.exports = {
|
|
313
|
+
buildRemediationPlan,
|
|
314
|
+
buildMarkdown
|
|
315
|
+
};
|