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,255 @@
1
+ 'use strict';
2
+
3
+ function parseNumber(value, fallback) {
4
+ const parsed = Number(value);
5
+ return Number.isFinite(parsed) ? parsed : fallback;
6
+ }
7
+
8
+ function parseBoolean(value, fallback = false) {
9
+ if (value === undefined || value === null) {
10
+ return fallback;
11
+ }
12
+ const normalized = `${value}`.trim().toLowerCase();
13
+ if (!normalized) {
14
+ return fallback;
15
+ }
16
+ if (['1', 'true', 'yes', 'y', 'on'].includes(normalized)) {
17
+ return true;
18
+ }
19
+ if (['0', 'false', 'no', 'n', 'off'].includes(normalized)) {
20
+ return false;
21
+ }
22
+ return fallback;
23
+ }
24
+
25
+ function normalizeRisk(value) {
26
+ const normalized = `${value || 'unknown'}`.trim().toLowerCase();
27
+ if (['low', 'medium', 'high', 'unknown'].includes(normalized)) {
28
+ return normalized;
29
+ }
30
+ return 'unknown';
31
+ }
32
+
33
+ function countConsecutive(items, predicate) {
34
+ let count = 0;
35
+ for (const item of items) {
36
+ if (!predicate(item)) {
37
+ break;
38
+ }
39
+ count += 1;
40
+ }
41
+ return count;
42
+ }
43
+
44
+ function resolveReleaseDriftThresholds(env = process.env) {
45
+ return {
46
+ failStreakMin: Math.max(
47
+ 1,
48
+ Math.floor(parseNumber(env.RELEASE_DRIFT_FAIL_STREAK_MIN, 2))
49
+ ),
50
+ highRiskShareMinPercent: Math.max(
51
+ 0,
52
+ Math.min(100, parseNumber(env.RELEASE_DRIFT_HIGH_RISK_SHARE_MIN_PERCENT, 60))
53
+ ),
54
+ highRiskShareDeltaMinPercent: Math.max(
55
+ 0,
56
+ Math.min(100, parseNumber(env.RELEASE_DRIFT_HIGH_RISK_SHARE_DELTA_MIN_PERCENT, 25))
57
+ ),
58
+ preflightBlockRateMinPercent: Math.max(
59
+ 0,
60
+ Math.min(100, parseNumber(env.RELEASE_DRIFT_PREFLIGHT_BLOCK_RATE_MIN_PERCENT, 40))
61
+ ),
62
+ hardGateBlockStreakMin: Math.max(
63
+ 1,
64
+ Math.floor(parseNumber(env.RELEASE_DRIFT_HARD_GATE_BLOCK_STREAK_MIN, 2))
65
+ ),
66
+ preflightUnavailableStreakMin: Math.max(
67
+ 1,
68
+ Math.floor(parseNumber(env.RELEASE_DRIFT_PREFLIGHT_UNAVAILABLE_STREAK_MIN, 2))
69
+ ),
70
+ capabilityExpectedUnknownRateMinPercent: Math.max(
71
+ 0,
72
+ Math.min(100, parseNumber(env.RELEASE_DRIFT_CAPABILITY_EXPECTED_UNKNOWN_RATE_MIN_PERCENT, 40))
73
+ ),
74
+ capabilityProvidedUnknownRateMinPercent: Math.max(
75
+ 0,
76
+ Math.min(100, parseNumber(env.RELEASE_DRIFT_CAPABILITY_PROVIDED_UNKNOWN_RATE_MIN_PERCENT, 40))
77
+ )
78
+ };
79
+ }
80
+
81
+ function buildReleaseDriftSignals(payload = {}, options = {}) {
82
+ const entries = Array.isArray(payload && payload.entries) ? payload.entries : [];
83
+ const windowSize = Math.max(1, Math.floor(parseNumber(options.windowSize, 5)));
84
+ const shortWindowSize = Math.max(1, Math.floor(parseNumber(options.shortWindowSize, 3)));
85
+ const longWindowSize = Math.max(shortWindowSize, Math.floor(parseNumber(options.longWindowSize, 5)));
86
+ const defaultThresholds = resolveReleaseDriftThresholds(options.env || process.env);
87
+ const thresholds = options.thresholds && typeof options.thresholds === 'object'
88
+ ? {
89
+ ...defaultThresholds,
90
+ ...options.thresholds
91
+ }
92
+ : defaultThresholds;
93
+
94
+ const recent = entries.slice(0, Math.min(entries.length, windowSize));
95
+ const shortWindow = entries.slice(0, Math.min(entries.length, shortWindowSize));
96
+ const longWindow = entries.slice(0, Math.min(entries.length, longWindowSize));
97
+
98
+ const riskCounts = recent.reduce((acc, item) => {
99
+ const risk = normalizeRisk(item && item.risk_level);
100
+ acc[risk] += 1;
101
+ return acc;
102
+ }, { low: 0, medium: 0, high: 0, unknown: 0 });
103
+
104
+ const recentPass = recent.filter(item => item && item.gate_passed === true).length;
105
+ const recentKnown = recent.filter(item => item && typeof item.gate_passed === 'boolean').length;
106
+ const failedStreak = countConsecutive(recent, item => item && item.gate_passed === false);
107
+ const highRiskShare = recent.length > 0
108
+ ? Number(((riskCounts.high / recent.length) * 100).toFixed(2))
109
+ : 0;
110
+ const shortHighShare = shortWindow.length > 0
111
+ ? shortWindow.filter(item => normalizeRisk(item && item.risk_level) === 'high').length / shortWindow.length
112
+ : 0;
113
+ const longHighShare = longWindow.length > 0
114
+ ? longWindow.filter(item => normalizeRisk(item && item.risk_level) === 'high').length / longWindow.length
115
+ : 0;
116
+ const highRiskDeltaPercent = Number(((shortHighShare - longHighShare) * 100).toFixed(2));
117
+
118
+ const recentPreflightKnown = recent.filter(
119
+ item => item && typeof item.release_gate_preflight_blocked === 'boolean'
120
+ ).length;
121
+ const recentPreflightBlocked = recent.filter(
122
+ item => item && item.release_gate_preflight_blocked === true
123
+ ).length;
124
+ const recentPreflightBlockedRate = recentPreflightKnown > 0
125
+ ? Number(((recentPreflightBlocked / recentPreflightKnown) * 100).toFixed(2))
126
+ : null;
127
+ const hardGateBlockedStreak = countConsecutive(
128
+ recent,
129
+ item => item && item.require_release_gate_preflight === true && item.release_gate_preflight_blocked === true
130
+ );
131
+ const preflightUnavailableStreak = countConsecutive(
132
+ recent,
133
+ item => item && item.release_gate_preflight_available === false
134
+ );
135
+ const recentCapabilityExpectedUnknownKnown = recent.filter(item => (
136
+ item &&
137
+ Number.isFinite(Number(item.capability_expected_unknown_count))
138
+ )).length;
139
+ const recentCapabilityExpectedUnknownPositive = recent.filter(item => (
140
+ item &&
141
+ Number.isFinite(Number(item.capability_expected_unknown_count)) &&
142
+ Number(item.capability_expected_unknown_count) > 0
143
+ )).length;
144
+ const recentCapabilityExpectedUnknownRate = recentCapabilityExpectedUnknownKnown > 0
145
+ ? Number(((recentCapabilityExpectedUnknownPositive / recentCapabilityExpectedUnknownKnown) * 100).toFixed(2))
146
+ : null;
147
+ const recentCapabilityProvidedUnknownKnown = recent.filter(item => (
148
+ item &&
149
+ Number.isFinite(Number(item.capability_provided_unknown_count))
150
+ )).length;
151
+ const recentCapabilityProvidedUnknownPositive = recent.filter(item => (
152
+ item &&
153
+ Number.isFinite(Number(item.capability_provided_unknown_count)) &&
154
+ Number(item.capability_provided_unknown_count) > 0
155
+ )).length;
156
+ const recentCapabilityProvidedUnknownRate = recentCapabilityProvidedUnknownKnown > 0
157
+ ? Number(((recentCapabilityProvidedUnknownPositive / recentCapabilityProvidedUnknownKnown) * 100).toFixed(2))
158
+ : null;
159
+
160
+ const alerts = [];
161
+ if (failedStreak >= thresholds.failStreakMin) {
162
+ alerts.push(`consecutive gate failures: ${failedStreak} (threshold=${thresholds.failStreakMin})`);
163
+ }
164
+ if (highRiskShare >= thresholds.highRiskShareMinPercent) {
165
+ alerts.push(
166
+ `high-risk share in latest ${windowSize} is ${highRiskShare}% `
167
+ + `(threshold=${thresholds.highRiskShareMinPercent}%)`
168
+ );
169
+ }
170
+ if (
171
+ shortWindow.length >= 2 &&
172
+ longWindow.length >= 3 &&
173
+ highRiskDeltaPercent >= thresholds.highRiskShareDeltaMinPercent
174
+ ) {
175
+ alerts.push(
176
+ `high-risk share increased from ${(longHighShare * 100).toFixed(2)}% to ${(shortHighShare * 100).toFixed(2)}% `
177
+ + `(threshold=${thresholds.highRiskShareDeltaMinPercent}%)`
178
+ );
179
+ }
180
+ if (
181
+ recentPreflightBlockedRate !== null &&
182
+ recentPreflightBlockedRate >= thresholds.preflightBlockRateMinPercent
183
+ ) {
184
+ alerts.push(
185
+ `release preflight blocked rate in latest ${windowSize} is ${recentPreflightBlockedRate}% `
186
+ + `(threshold=${thresholds.preflightBlockRateMinPercent}%, known=${recentPreflightKnown})`
187
+ );
188
+ }
189
+ if (hardGateBlockedStreak >= thresholds.hardGateBlockStreakMin) {
190
+ alerts.push(
191
+ `hard-gate preflight blocked streak is ${hardGateBlockedStreak} `
192
+ + `(threshold=${thresholds.hardGateBlockStreakMin})`
193
+ );
194
+ }
195
+ if (preflightUnavailableStreak >= thresholds.preflightUnavailableStreakMin) {
196
+ alerts.push(
197
+ `release preflight unavailable streak is ${preflightUnavailableStreak} `
198
+ + `(threshold=${thresholds.preflightUnavailableStreakMin})`
199
+ );
200
+ }
201
+ if (
202
+ recentCapabilityExpectedUnknownRate !== null &&
203
+ recentCapabilityExpectedUnknownRate >= thresholds.capabilityExpectedUnknownRateMinPercent
204
+ ) {
205
+ alerts.push(
206
+ `capability expected unknown positive rate in latest ${windowSize} is ${recentCapabilityExpectedUnknownRate}% `
207
+ + `(threshold=${thresholds.capabilityExpectedUnknownRateMinPercent}%, known=${recentCapabilityExpectedUnknownKnown})`
208
+ );
209
+ }
210
+ if (
211
+ recentCapabilityProvidedUnknownRate !== null &&
212
+ recentCapabilityProvidedUnknownRate >= thresholds.capabilityProvidedUnknownRateMinPercent
213
+ ) {
214
+ alerts.push(
215
+ `capability provided unknown positive rate in latest ${windowSize} is ${recentCapabilityProvidedUnknownRate}% `
216
+ + `(threshold=${thresholds.capabilityProvidedUnknownRateMinPercent}%, known=${recentCapabilityProvidedUnknownKnown})`
217
+ );
218
+ }
219
+
220
+ return {
221
+ entries,
222
+ recent,
223
+ recentPass,
224
+ recentKnown,
225
+ riskCounts,
226
+ failedStreak,
227
+ highRiskShare,
228
+ highRiskDeltaPercent,
229
+ recentPreflightKnown,
230
+ recentPreflightBlocked,
231
+ recentPreflightBlockedRate,
232
+ hardGateBlockedStreak,
233
+ preflightUnavailableStreak,
234
+ recentCapabilityExpectedUnknownKnown,
235
+ recentCapabilityExpectedUnknownPositive,
236
+ recentCapabilityExpectedUnknownRate,
237
+ recentCapabilityProvidedUnknownKnown,
238
+ recentCapabilityProvidedUnknownPositive,
239
+ recentCapabilityProvidedUnknownRate,
240
+ alerts,
241
+ thresholds,
242
+ windows: {
243
+ recent: recent.length,
244
+ short: shortWindow.length,
245
+ long: longWindow.length
246
+ }
247
+ };
248
+ }
249
+
250
+ module.exports = {
251
+ buildReleaseDriftSignals,
252
+ parseBoolean,
253
+ parseNumber,
254
+ resolveReleaseDriftThresholds
255
+ };
@@ -0,0 +1,132 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ function appendSummary(summaryPath, lines = []) {
7
+ if (!summaryPath) {
8
+ return;
9
+ }
10
+ fs.appendFileSync(summaryPath, `${lines.join('\n')}\n\n`, 'utf8');
11
+ }
12
+
13
+ function safeReadJson(file) {
14
+ try {
15
+ if (!file || !fs.existsSync(file)) {
16
+ return { ok: false, error: `missing file: ${file || 'n/a'}` };
17
+ }
18
+ const payload = JSON.parse(fs.readFileSync(file, 'utf8'));
19
+ return { ok: true, payload };
20
+ } catch (error) {
21
+ return { ok: false, error: `parse error: ${error.message}` };
22
+ }
23
+ }
24
+
25
+ function normalizeArray(value) {
26
+ return Array.isArray(value) ? value : [];
27
+ }
28
+
29
+ function exportReleaseGovernanceSnapshot(options = {}) {
30
+ const env = options.env && typeof options.env === 'object'
31
+ ? options.env
32
+ : process.env;
33
+ const now = typeof options.now === 'function'
34
+ ? options.now
35
+ : () => new Date().toISOString();
36
+
37
+ const summaryFile = `${env.RELEASE_EVIDENCE_SUMMARY_FILE || ''}`.trim();
38
+ const outputJson = `${env.RELEASE_GOVERNANCE_SNAPSHOT_JSON || '.sce/reports/release-evidence/governance-snapshot.json'}`.trim();
39
+ const outputMarkdown = `${env.RELEASE_GOVERNANCE_SNAPSHOT_MD || '.sce/reports/release-evidence/governance-snapshot.md'}`.trim();
40
+ const releaseTag = `${env.RELEASE_TAG || ''}`.trim();
41
+ const summaryPath = env.GITHUB_STEP_SUMMARY;
42
+
43
+ const summaryResult = safeReadJson(summaryFile);
44
+ const payload = summaryResult.ok && summaryResult.payload && typeof summaryResult.payload === 'object'
45
+ ? summaryResult.payload
46
+ : {};
47
+ const governanceSnapshot = payload.governance_snapshot && typeof payload.governance_snapshot === 'object'
48
+ ? payload.governance_snapshot
49
+ : null;
50
+ const available = governanceSnapshot !== null;
51
+ const concerns = normalizeArray(governanceSnapshot && governanceSnapshot.health && governanceSnapshot.health.concerns);
52
+ const recommendations = normalizeArray(governanceSnapshot && governanceSnapshot.health && governanceSnapshot.health.recommendations);
53
+ const risk = `${governanceSnapshot && governanceSnapshot.health && governanceSnapshot.health.risk || 'unknown'}`.trim().toLowerCase();
54
+
55
+ const exportPayload = {
56
+ mode: 'release-governance-snapshot',
57
+ generated_at: now(),
58
+ tag: releaseTag || null,
59
+ summary_file: summaryFile || null,
60
+ available,
61
+ warning: summaryResult.ok ? null : summaryResult.error,
62
+ governance_snapshot: governanceSnapshot
63
+ };
64
+
65
+ fs.mkdirSync(path.dirname(outputJson), { recursive: true });
66
+ fs.writeFileSync(outputJson, `${JSON.stringify(exportPayload, null, 2)}\n`, 'utf8');
67
+
68
+ const markdownLines = [
69
+ '# Release Governance Snapshot',
70
+ '',
71
+ `- Tag: ${releaseTag || 'n/a'}`,
72
+ `- Generated At: ${exportPayload.generated_at}`,
73
+ `- Summary File: ${summaryFile || 'n/a'}`,
74
+ `- Available: ${available ? 'yes' : 'no'}`
75
+ ];
76
+
77
+ if (!available) {
78
+ markdownLines.push(`- Warning: ${exportPayload.warning || 'governance snapshot unavailable'}`);
79
+ } else {
80
+ markdownLines.push(`- Risk: ${risk}`);
81
+ markdownLines.push(`- Concerns: ${concerns.length}`);
82
+ markdownLines.push(`- Recommendations: ${recommendations.length}`);
83
+ if (concerns.length > 0) {
84
+ markdownLines.push('', '## Concerns');
85
+ concerns.forEach(item => markdownLines.push(`- ${item}`));
86
+ }
87
+ if (recommendations.length > 0) {
88
+ markdownLines.push('', '## Recommendations');
89
+ recommendations.forEach(item => markdownLines.push(`- ${item}`));
90
+ }
91
+ }
92
+
93
+ fs.mkdirSync(path.dirname(outputMarkdown), { recursive: true });
94
+ fs.writeFileSync(outputMarkdown, `${markdownLines.join('\n')}\n`, 'utf8');
95
+
96
+ console.log(`[release-governance-snapshot] summary=${summaryFile || 'n/a'} available=${available}`);
97
+ console.log(`[release-governance-snapshot] json=${outputJson}`);
98
+ console.log(`[release-governance-snapshot] markdown=${outputMarkdown}`);
99
+
100
+ appendSummary(summaryPath, [
101
+ '## Release Governance Snapshot',
102
+ '',
103
+ `- summary: ${summaryFile || 'n/a'}`,
104
+ `- available: ${available}`,
105
+ `- json: ${outputJson}`,
106
+ `- markdown: ${outputMarkdown}`,
107
+ ...(available
108
+ ? [
109
+ `- risk: ${risk}`,
110
+ `- concerns: ${concerns.length}`,
111
+ `- recommendations: ${recommendations.length}`
112
+ ]
113
+ : [`- warning: ${exportPayload.warning || 'governance snapshot unavailable'}`])
114
+ ]);
115
+
116
+ return {
117
+ exit_code: 0,
118
+ available,
119
+ warning: exportPayload.warning,
120
+ json_file: outputJson,
121
+ markdown_file: outputMarkdown
122
+ };
123
+ }
124
+
125
+ if (require.main === module) {
126
+ const result = exportReleaseGovernanceSnapshot();
127
+ process.exit(result.exit_code);
128
+ }
129
+
130
+ module.exports = {
131
+ exportReleaseGovernanceSnapshot
132
+ };