scene-capability-engine 3.6.45 → 3.6.47

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 (72) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +1 -0
  3. package/README.zh.md +1 -0
  4. package/docs/agent-runtime/symbol-evidence.schema.json +1 -1
  5. package/docs/command-reference.md +8 -0
  6. package/docs/interactive-customization/dialogue-governance-policy-baseline.json +4 -1
  7. package/docs/interactive-customization/embedded-assistant-authorization-dialogue-rules.md +5 -0
  8. package/docs/releases/README.md +2 -0
  9. package/docs/releases/v3.6.46.md +23 -0
  10. package/docs/releases/v3.6.47.md +23 -0
  11. package/docs/sce-business-mode-map.md +2 -1
  12. package/docs/sce-capability-matrix-e2e-example.md +2 -1
  13. package/docs/security-governance-default-baseline.md +2 -0
  14. package/docs/starter-kit/README.md +3 -0
  15. package/docs/zh/releases/README.md +2 -0
  16. package/docs/zh/releases/v3.6.46.md +23 -0
  17. package/docs/zh/releases/v3.6.47.md +23 -0
  18. package/lib/workspace/takeover-baseline.js +293 -1
  19. package/package.json +6 -2
  20. package/scripts/auto-strategy-router.js +231 -0
  21. package/scripts/capability-mapping-report.js +339 -0
  22. package/scripts/check-branding-consistency.js +140 -0
  23. package/scripts/check-sce-tracking.js +54 -0
  24. package/scripts/check-skip-allowlist.js +94 -0
  25. package/scripts/clarification-first-audit.js +322 -0
  26. package/scripts/errorbook-registry-health-gate.js +172 -0
  27. package/scripts/errorbook-release-gate.js +132 -0
  28. package/scripts/failure-attribution-repair.js +317 -0
  29. package/scripts/git-managed-gate.js +464 -0
  30. package/scripts/interactive-approval-event-projection.js +400 -0
  31. package/scripts/interactive-approval-workflow.js +829 -0
  32. package/scripts/interactive-authorization-tier-evaluate.js +413 -0
  33. package/scripts/interactive-change-plan-gate.js +225 -0
  34. package/scripts/interactive-context-bridge.js +617 -0
  35. package/scripts/interactive-customization-loop.js +1690 -0
  36. package/scripts/interactive-dialogue-governance.js +873 -0
  37. package/scripts/interactive-feedback-log.js +253 -0
  38. package/scripts/interactive-flow-smoke.js +238 -0
  39. package/scripts/interactive-flow.js +1059 -0
  40. package/scripts/interactive-governance-report.js +1112 -0
  41. package/scripts/interactive-intent-build.js +707 -0
  42. package/scripts/interactive-loop-smoke.js +215 -0
  43. package/scripts/interactive-moqui-adapter.js +304 -0
  44. package/scripts/interactive-plan-build.js +426 -0
  45. package/scripts/interactive-runtime-policy-evaluate.js +495 -0
  46. package/scripts/interactive-work-order-build.js +552 -0
  47. package/scripts/matrix-regression-gate.js +167 -0
  48. package/scripts/moqui-core-regression-suite.js +397 -0
  49. package/scripts/moqui-lexicon-audit.js +651 -0
  50. package/scripts/moqui-matrix-remediation-phased-runner.js +865 -0
  51. package/scripts/moqui-matrix-remediation-queue.js +852 -0
  52. package/scripts/moqui-metadata-extract.js +1340 -0
  53. package/scripts/moqui-rebuild-gate.js +167 -0
  54. package/scripts/moqui-release-summary.js +729 -0
  55. package/scripts/moqui-standard-rebuild.js +1370 -0
  56. package/scripts/moqui-template-baseline-report.js +682 -0
  57. package/scripts/npm-package-runtime-asset-check.js +221 -0
  58. package/scripts/problem-closure-gate.js +441 -0
  59. package/scripts/release-asset-integrity-check.js +216 -0
  60. package/scripts/release-asset-nonempty-normalize.js +166 -0
  61. package/scripts/release-drift-evaluate.js +223 -0
  62. package/scripts/release-drift-signals.js +255 -0
  63. package/scripts/release-governance-snapshot-export.js +132 -0
  64. package/scripts/release-ops-weekly-summary.js +934 -0
  65. package/scripts/release-risk-remediation-bundle.js +315 -0
  66. package/scripts/release-weekly-ops-gate.js +423 -0
  67. package/scripts/state-migration-reconciliation-gate.js +110 -0
  68. package/scripts/state-storage-tiering-audit.js +337 -0
  69. package/scripts/steering-content-audit.js +393 -0
  70. package/scripts/symbol-evidence-locate.js +370 -0
  71. package/template/.sce/README.md +1 -0
  72. package/template/.sce/steering/CORE_PRINCIPLES.md +25 -0
@@ -0,0 +1,400 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const path = require('path');
5
+ const fs = require('fs-extra');
6
+ const { getSceStateStore } = require('../lib/state/sce-state-store');
7
+
8
+ const DEFAULT_INPUT = '.sce/reports/interactive-approval-events.jsonl';
9
+
10
+ function parseArgs(argv = []) {
11
+ const options = {
12
+ action: null,
13
+ projectPath: process.cwd(),
14
+ input: DEFAULT_INPUT,
15
+ readSource: 'auto',
16
+ actor: null,
17
+ workflowId: null,
18
+ eventType: null,
19
+ approvalAction: null,
20
+ blocked: null,
21
+ limit: 20,
22
+ json: false,
23
+ failOnDrift: false,
24
+ failOnParseError: false
25
+ };
26
+
27
+ for (let index = 0; index < argv.length; index += 1) {
28
+ const token = argv[index];
29
+ const next = argv[index + 1];
30
+ if (token === '--action' && next) {
31
+ options.action = `${next}`.trim().toLowerCase();
32
+ index += 1;
33
+ continue;
34
+ }
35
+ if ((token === '--project-path' || token === '--workspace') && next) {
36
+ options.projectPath = path.resolve(next);
37
+ index += 1;
38
+ continue;
39
+ }
40
+ if ((token === '--input' || token === '--audit-file') && next) {
41
+ options.input = next;
42
+ index += 1;
43
+ continue;
44
+ }
45
+ if (token === '--read-source' && next) {
46
+ options.readSource = `${next}`.trim().toLowerCase();
47
+ index += 1;
48
+ continue;
49
+ }
50
+ if (token === '--actor' && next) {
51
+ options.actor = next;
52
+ index += 1;
53
+ continue;
54
+ }
55
+ if ((token === '--workflow-id' || token === '--workflow') && next) {
56
+ options.workflowId = next;
57
+ index += 1;
58
+ continue;
59
+ }
60
+ if (token === '--event-type' && next) {
61
+ options.eventType = next;
62
+ index += 1;
63
+ continue;
64
+ }
65
+ if ((token === '--approval-action' || token === '--action-filter') && next) {
66
+ options.approvalAction = next;
67
+ index += 1;
68
+ continue;
69
+ }
70
+ if (token === '--blocked') {
71
+ options.blocked = true;
72
+ continue;
73
+ }
74
+ if (token === '--not-blocked') {
75
+ options.blocked = false;
76
+ continue;
77
+ }
78
+ if (token === '--limit' && next) {
79
+ options.limit = Number.parseInt(next, 10);
80
+ index += 1;
81
+ continue;
82
+ }
83
+ if (token === '--json') {
84
+ options.json = true;
85
+ continue;
86
+ }
87
+ if (token === '--fail-on-drift') {
88
+ options.failOnDrift = true;
89
+ continue;
90
+ }
91
+ if (token === '--fail-on-parse-error') {
92
+ options.failOnParseError = true;
93
+ }
94
+ }
95
+
96
+ if (!['rebuild', 'doctor', 'query'].includes(options.action)) {
97
+ throw new Error('--action must be one of: rebuild, doctor, query');
98
+ }
99
+ if (!['auto', 'file', 'projection'].includes(options.readSource)) {
100
+ throw new Error('--read-source must be one of: auto, file, projection');
101
+ }
102
+ if (!Number.isFinite(options.limit) || options.limit < 0) {
103
+ throw new Error('--limit must be a non-negative integer');
104
+ }
105
+
106
+ return options;
107
+ }
108
+
109
+ function normalizeString(value) {
110
+ return typeof value === 'string' ? value.trim() : '';
111
+ }
112
+
113
+ function resolveInputPath(projectPath, input) {
114
+ return path.isAbsolute(input) ? input : path.resolve(projectPath, input);
115
+ }
116
+
117
+ function relativeProjectPath(projectPath, absolutePath) {
118
+ return path.relative(projectPath, absolutePath).replace(/\\/g, '/');
119
+ }
120
+
121
+ async function readApprovalAuditFile(projectPath, input) {
122
+ const auditPath = resolveInputPath(projectPath, input);
123
+ const relativePath = relativeProjectPath(projectPath, auditPath) || path.basename(auditPath);
124
+ if (!await fs.pathExists(auditPath)) {
125
+ return {
126
+ auditPath,
127
+ relativePath,
128
+ exists: false,
129
+ events: [],
130
+ parseErrors: [],
131
+ lineCount: 0
132
+ };
133
+ }
134
+
135
+ const content = await fs.readFile(auditPath, 'utf8');
136
+ const lines = content.split(/\r?\n/);
137
+ const events = [];
138
+ const parseErrors = [];
139
+ for (let index = 0; index < lines.length; index += 1) {
140
+ const line = lines[index].trim();
141
+ if (!line) {
142
+ continue;
143
+ }
144
+ try {
145
+ const raw = JSON.parse(line);
146
+ events.push({
147
+ ...raw,
148
+ audit_file: relativePath,
149
+ line_no: index + 1
150
+ });
151
+ } catch (error) {
152
+ parseErrors.push({
153
+ line_no: index + 1,
154
+ message: error.message
155
+ });
156
+ }
157
+ }
158
+
159
+ return {
160
+ auditPath,
161
+ relativePath,
162
+ exists: true,
163
+ events,
164
+ parseErrors,
165
+ lineCount: lines.filter((line) => line.trim().length > 0).length
166
+ };
167
+ }
168
+
169
+ function filterApprovalEvents(events = [], options = {}) {
170
+ let rows = Array.isArray(events) ? events.slice() : [];
171
+ const actor = normalizeString(options.actor);
172
+ const workflowId = normalizeString(options.workflowId || options.workflow_id);
173
+ const eventType = normalizeString(options.eventType || options.event_type);
174
+ const approvalAction = normalizeString(options.approvalAction || options.approval_action || options.action);
175
+ const blocked = options.blocked;
176
+
177
+ if (actor) {
178
+ rows = rows.filter((item) => normalizeString(item.actor) === actor);
179
+ }
180
+ if (workflowId) {
181
+ rows = rows.filter((item) => normalizeString(item.workflow_id) === workflowId);
182
+ }
183
+ if (eventType) {
184
+ rows = rows.filter((item) => normalizeString(item.event_type) === eventType);
185
+ }
186
+ if (approvalAction) {
187
+ rows = rows.filter((item) => normalizeString(item.action) === approvalAction);
188
+ }
189
+ if (blocked === true || blocked === false) {
190
+ rows = rows.filter((item) => Boolean(item.blocked) === blocked);
191
+ }
192
+
193
+ rows.sort((left, right) => {
194
+ const leftTs = Date.parse(left.event_timestamp || left.timestamp || '') || 0;
195
+ const rightTs = Date.parse(right.event_timestamp || right.timestamp || '') || 0;
196
+ return rightTs - leftTs;
197
+ });
198
+ return rows;
199
+ }
200
+
201
+ async function rebuildInteractiveApprovalProjection(options = {}, dependencies = {}) {
202
+ const projectPath = path.resolve(options.projectPath || process.cwd());
203
+ const stateStore = dependencies.stateStore || getSceStateStore(projectPath, {
204
+ fileSystem: dependencies.fileSystem || fs,
205
+ env: dependencies.env || process.env
206
+ });
207
+ const audit = await readApprovalAuditFile(projectPath, options.input || DEFAULT_INPUT);
208
+
209
+ await stateStore.clearInteractiveApprovalEventProjection({
210
+ auditFile: audit.relativePath
211
+ });
212
+ const writeResult = await stateStore.upsertInteractiveApprovalEventProjection(audit.events, {
213
+ source: 'jsonl.interactive-approval-events',
214
+ auditFile: audit.relativePath
215
+ });
216
+ const projectionRows = await stateStore.listInteractiveApprovalEventProjection({
217
+ auditFile: audit.relativePath,
218
+ limit: 0
219
+ });
220
+
221
+ return {
222
+ mode: 'interactive-approval-event-projection',
223
+ action: 'rebuild',
224
+ success: audit.parseErrors.length === 0,
225
+ passed: audit.parseErrors.length === 0,
226
+ project_path: projectPath,
227
+ audit_file: audit.relativePath,
228
+ source_event_count: audit.events.length,
229
+ projection_event_count: Array.isArray(projectionRows) ? projectionRows.length : 0,
230
+ parse_error_count: audit.parseErrors.length,
231
+ parse_errors: audit.parseErrors,
232
+ write_result: writeResult || null
233
+ };
234
+ }
235
+
236
+ async function doctorInteractiveApprovalProjection(options = {}, dependencies = {}) {
237
+ const projectPath = path.resolve(options.projectPath || process.cwd());
238
+ const stateStore = dependencies.stateStore || getSceStateStore(projectPath, {
239
+ fileSystem: dependencies.fileSystem || fs,
240
+ env: dependencies.env || process.env
241
+ });
242
+ const audit = await readApprovalAuditFile(projectPath, options.input || DEFAULT_INPUT);
243
+ const projectionRows = await stateStore.listInteractiveApprovalEventProjection({
244
+ auditFile: audit.relativePath,
245
+ limit: 0
246
+ });
247
+ const projectionCount = Array.isArray(projectionRows) ? projectionRows.length : 0;
248
+
249
+ let status = 'aligned';
250
+ if (audit.parseErrors.length > 0) {
251
+ status = 'parse-error';
252
+ } else if (!audit.exists && projectionCount === 0) {
253
+ status = 'empty';
254
+ } else if (!audit.exists && projectionCount > 0) {
255
+ status = 'projection-only';
256
+ } else if (audit.events.length === 0 && projectionCount === 0) {
257
+ status = 'empty';
258
+ } else if (projectionCount === 0 && audit.events.length > 0) {
259
+ status = 'projection-missing';
260
+ } else if (projectionCount < audit.events.length) {
261
+ status = 'pending-projection';
262
+ } else if (projectionCount > audit.events.length) {
263
+ status = 'projection-ahead';
264
+ }
265
+
266
+ const latestSourceEvent = audit.events.length > 0 ? filterApprovalEvents(audit.events, { limit: 1 })[0] : null;
267
+ const latestProjectionEvent = projectionCount > 0 ? projectionRows[0] : null;
268
+
269
+ const blocking = [];
270
+ const alerts = [];
271
+ if (status === 'parse-error') {
272
+ blocking.push('parse-error');
273
+ }
274
+ if (status === 'projection-ahead') {
275
+ blocking.push('projection-ahead');
276
+ }
277
+ if (status === 'projection-only') {
278
+ blocking.push('projection-only');
279
+ }
280
+ if (status === 'projection-missing' || status === 'pending-projection') {
281
+ alerts.push(status);
282
+ }
283
+
284
+ const passed = blocking.length === 0
285
+ && (!options.failOnDrift || alerts.length === 0)
286
+ && (!options.failOnParseError || audit.parseErrors.length === 0);
287
+
288
+ return {
289
+ mode: 'interactive-approval-event-projection',
290
+ action: 'doctor',
291
+ success: passed,
292
+ passed,
293
+ project_path: projectPath,
294
+ audit_file: audit.relativePath,
295
+ status,
296
+ source_event_count: audit.events.length,
297
+ projection_event_count: projectionCount,
298
+ parse_error_count: audit.parseErrors.length,
299
+ parse_errors: audit.parseErrors,
300
+ latest_source_event_id: latestSourceEvent ? latestSourceEvent.event_id || null : null,
301
+ latest_projection_event_id: latestProjectionEvent ? latestProjectionEvent.event_id || null : null,
302
+ blocking,
303
+ alerts
304
+ };
305
+ }
306
+
307
+ async function queryInteractiveApprovalProjection(options = {}, dependencies = {}) {
308
+ const projectPath = path.resolve(options.projectPath || process.cwd());
309
+ const stateStore = dependencies.stateStore || getSceStateStore(projectPath, {
310
+ fileSystem: dependencies.fileSystem || fs,
311
+ env: dependencies.env || process.env
312
+ });
313
+ const audit = await readApprovalAuditFile(projectPath, options.input || DEFAULT_INPUT);
314
+
315
+ let readSource = options.readSource || 'auto';
316
+ let rows = [];
317
+ if (readSource === 'projection' || readSource === 'auto') {
318
+ const projectionRows = await stateStore.listInteractiveApprovalEventProjection({
319
+ auditFile: audit.relativePath,
320
+ actor: options.actor,
321
+ workflowId: options.workflowId,
322
+ eventType: options.eventType,
323
+ action: options.approvalAction,
324
+ blocked: options.blocked,
325
+ limit: options.limit
326
+ });
327
+ if (readSource === 'projection') {
328
+ rows = Array.isArray(projectionRows) ? projectionRows : [];
329
+ } else if (Array.isArray(projectionRows) && projectionRows.length > 0) {
330
+ readSource = 'projection';
331
+ rows = projectionRows;
332
+ } else {
333
+ readSource = 'file';
334
+ }
335
+ }
336
+
337
+ if (readSource === 'file') {
338
+ rows = filterApprovalEvents(audit.events, {
339
+ actor: options.actor,
340
+ workflowId: options.workflowId,
341
+ eventType: options.eventType,
342
+ approvalAction: options.approvalAction,
343
+ blocked: options.blocked
344
+ }).slice(0, options.limit > 0 ? options.limit : undefined);
345
+ }
346
+
347
+ return {
348
+ mode: 'interactive-approval-event-projection',
349
+ action: 'query',
350
+ success: true,
351
+ passed: true,
352
+ project_path: projectPath,
353
+ audit_file: audit.relativePath,
354
+ read_source: readSource,
355
+ result_count: rows.length,
356
+ results: rows
357
+ };
358
+ }
359
+
360
+ async function run(options = {}, dependencies = {}) {
361
+ if (options.action === 'rebuild') {
362
+ return rebuildInteractiveApprovalProjection(options, dependencies);
363
+ }
364
+ if (options.action === 'doctor') {
365
+ return doctorInteractiveApprovalProjection(options, dependencies);
366
+ }
367
+ return queryInteractiveApprovalProjection(options, dependencies);
368
+ }
369
+
370
+ async function main() {
371
+ const options = parseArgs(process.argv.slice(2));
372
+ const result = await run(options);
373
+ if (options.json) {
374
+ console.log(JSON.stringify(result, null, 2));
375
+ } else if (options.action === 'query') {
376
+ console.log(`[interactive-approval-event-projection] read_source=${result.read_source} result_count=${result.result_count}`);
377
+ } else {
378
+ console.log(`[interactive-approval-event-projection] action=${options.action} status=${result.passed ? 'passed' : 'failed'}`);
379
+ }
380
+ if (!result.passed) {
381
+ process.exitCode = 2;
382
+ }
383
+ }
384
+
385
+ if (require.main === module) {
386
+ main().catch((error) => {
387
+ console.error(error && error.message ? error.message : `${error}`);
388
+ process.exitCode = 1;
389
+ });
390
+ }
391
+
392
+ module.exports = {
393
+ DEFAULT_INPUT,
394
+ doctorInteractiveApprovalProjection,
395
+ parseArgs,
396
+ queryInteractiveApprovalProjection,
397
+ readApprovalAuditFile,
398
+ rebuildInteractiveApprovalProjection,
399
+ run
400
+ };