scene-capability-engine 3.6.32 → 3.6.36

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 (83) hide show
  1. package/CHANGELOG.md +86 -1
  2. package/README.md +119 -122
  3. package/README.zh.md +123 -121
  4. package/bin/scene-capability-engine.js +11 -0
  5. package/docs/README.md +21 -32
  6. package/docs/auto-refactor-index.md +384 -0
  7. package/docs/command-reference.md +94 -2
  8. package/docs/magicball-adaptation-task-checklist-v1.md +385 -0
  9. package/docs/magicball-app-bundle-sqlite-and-command-draft.md +539 -0
  10. package/docs/magicball-capability-iteration-api.md +2 -0
  11. package/docs/magicball-capability-iteration-ui.md +2 -0
  12. package/docs/magicball-capability-library.md +2 -0
  13. package/docs/magicball-cli-invocation-examples.md +336 -0
  14. package/docs/magicball-frontend-state-and-command-mapping.md +244 -0
  15. package/docs/magicball-integration-doc-index.md +137 -0
  16. package/docs/magicball-integration-issue-tracker.md +218 -0
  17. package/docs/magicball-mode-home-and-ontology-empty-state-playbook.md +249 -0
  18. package/docs/magicball-sce-adaptation-guide.md +203 -0
  19. package/docs/magicball-three-mode-alignment-plan.md +551 -0
  20. package/docs/magicball-ui-surface-checklist.md +126 -0
  21. package/docs/magicball-write-auth-adaptation-guide.md +328 -0
  22. package/docs/refactor-completion-roadmap.md +116 -0
  23. package/docs/zh/README.md +27 -30
  24. package/docs/zh/refactor-completion-roadmap.md +116 -0
  25. package/lib/app/registry-config.js +73 -0
  26. package/lib/app/registry-sync-service.js +228 -0
  27. package/lib/auto/archive-schema-service.js +276 -0
  28. package/lib/auto/archive-summary.js +60 -0
  29. package/lib/auto/batch-goal-input-service.js +543 -0
  30. package/lib/auto/batch-output.js +201 -0
  31. package/lib/auto/batch-summary-storage-service.js +110 -0
  32. package/lib/auto/close-loop-batch-service.js +116 -0
  33. package/lib/auto/close-loop-controller-service.js +287 -0
  34. package/lib/auto/close-loop-program-service.js +283 -0
  35. package/lib/auto/close-loop-recovery-service.js +191 -0
  36. package/lib/auto/close-loop-session-storage-service.js +50 -0
  37. package/lib/auto/controller-lock-service.js +55 -0
  38. package/lib/auto/controller-output.js +32 -0
  39. package/lib/auto/controller-queue-service.js +127 -0
  40. package/lib/auto/controller-session-storage-service.js +105 -0
  41. package/lib/auto/governance-advisory-service.js +208 -0
  42. package/lib/auto/governance-close-loop-service.js +411 -0
  43. package/lib/auto/governance-maintenance-presenter.js +162 -0
  44. package/lib/auto/governance-maintenance-service.js +112 -0
  45. package/lib/auto/governance-session-presenter.js +70 -0
  46. package/lib/auto/governance-session-storage-service.js +198 -0
  47. package/lib/auto/governance-signals.js +139 -0
  48. package/lib/auto/governance-stats-presenter.js +337 -0
  49. package/lib/auto/governance-stats-service.js +115 -0
  50. package/lib/auto/governance-summary.js +703 -0
  51. package/lib/auto/handoff-capability-matrix-service.js +281 -0
  52. package/lib/auto/handoff-evidence-review-service.js +251 -0
  53. package/lib/auto/handoff-release-evidence-service.js +190 -0
  54. package/lib/auto/handoff-release-gate-history-loaders-service.js +502 -0
  55. package/lib/auto/handoff-release-gate-history-service.js +257 -0
  56. package/lib/auto/handoff-reporting-service.js +1407 -0
  57. package/lib/auto/handoff-run-service.js +486 -0
  58. package/lib/auto/handoff-snapshots-service.js +645 -0
  59. package/lib/auto/observability-service.js +132 -0
  60. package/lib/auto/output-writer.js +34 -0
  61. package/lib/auto/program-auto-remediation-service.js +130 -0
  62. package/lib/auto/program-diagnostics.js +138 -0
  63. package/lib/auto/program-governance-helpers.js +306 -0
  64. package/lib/auto/program-governance-loop-service.js +413 -0
  65. package/lib/auto/program-output.js +106 -0
  66. package/lib/auto/program-summary.js +183 -0
  67. package/lib/auto/recovery-memory-service.js +684 -0
  68. package/lib/auto/recovery-selection-service.js +52 -0
  69. package/lib/auto/retention-policy.js +98 -0
  70. package/lib/auto/session-persistence-service.js +106 -0
  71. package/lib/auto/session-presenter.js +105 -0
  72. package/lib/auto/session-prune-service.js +190 -0
  73. package/lib/auto/session-query-service.js +249 -0
  74. package/lib/auto/spec-protection.js +141 -0
  75. package/lib/commands/app.js +911 -0
  76. package/lib/commands/assurance.js +212 -0
  77. package/lib/commands/auto.js +1091 -11063
  78. package/lib/commands/mode.js +321 -0
  79. package/lib/commands/ontology.js +415 -0
  80. package/lib/commands/pm.js +422 -0
  81. package/lib/ontology/seed-profiles.js +160 -0
  82. package/lib/state/sce-state-store.js +3369 -1200
  83. package/package.json +1 -1
@@ -0,0 +1,486 @@
1
+ const path = require('path');
2
+
3
+ async function runAutoHandoff(projectPath, options = {}, dependencies = {}) {
4
+ const {
5
+ AUTO_HANDOFF_RELEASE_EVIDENCE_FILE,
6
+ buildAutoHandoffRunSessionId,
7
+ buildAutoHandoffRunPolicy,
8
+ beginAutoHandoffRunPhase,
9
+ buildAutoHandoffPlan,
10
+ evaluateHandoffOntologyValidation,
11
+ buildAutoHandoffTemplateDiff,
12
+ buildAutoHandoffReleaseGatePreflight,
13
+ loadGovernanceReleaseGateSignals,
14
+ completeAutoHandoffRunPhase,
15
+ evaluateAutoHandoffOntologyGateReasons,
16
+ evaluateAutoHandoffReleaseGatePreflightGateReasons,
17
+ failAutoHandoffRunPhase,
18
+ buildAutoHandoffMoquiBaselineSnapshot,
19
+ buildAutoHandoffMoquiBaselinePhaseDetails,
20
+ evaluateAutoHandoffMoquiBaselineGateReasons,
21
+ buildAutoHandoffScenePackageBatchSnapshot,
22
+ buildAutoHandoffScenePackageBatchPhaseDetails,
23
+ evaluateAutoHandoffScenePackageBatchGateReasons,
24
+ buildAutoHandoffCapabilityCoverageSnapshot,
25
+ evaluateAutoHandoffCapabilityCoverageGateReasons,
26
+ evaluateAutoHandoffCapabilityLexiconGateReasons,
27
+ buildAutoHandoffQueueFromContinueSource,
28
+ buildAutoHandoffQueue,
29
+ writeAutoHandoffQueueFile,
30
+ skipAutoHandoffRunPhase,
31
+ buildAutoHandoffExecutionBatches,
32
+ buildAutoHandoffSpecStatus,
33
+ evaluateAutoHandoffRunGates,
34
+ executeAutoHandoffExecutionBatches,
35
+ buildAutoObservabilitySnapshot,
36
+ extractAutoObservabilityWeeklyOpsStopTelemetry,
37
+ buildProgramKpiSnapshot,
38
+ buildAutoHandoffRegression,
39
+ maybeWriteAutoHandoffMoquiRemediationQueue,
40
+ buildAutoHandoffRunFailureSummary,
41
+ buildAutoHandoffRunRecommendations,
42
+ writeAutoHandoffRunReport,
43
+ mergeAutoHandoffRunIntoReleaseEvidence
44
+ } = dependencies;
45
+
46
+ const startedAtMs = Date.now();
47
+ const result = {
48
+ mode: 'auto-handoff-run',
49
+ status: 'running',
50
+ generated_at: new Date().toISOString(),
51
+ session_id: buildAutoHandoffRunSessionId(),
52
+ manifest_path: null,
53
+ source_project: null,
54
+ policy: buildAutoHandoffRunPolicy(options),
55
+ dry_run: Boolean(options.dryRun),
56
+ phases: [],
57
+ handoff: null,
58
+ template_diff: null,
59
+ queue: null,
60
+ continued_from: null,
61
+ dependency_execution: null,
62
+ batch_summary: null,
63
+ observability_snapshot: null,
64
+ spec_status: null,
65
+ ontology_validation: null,
66
+ moqui_baseline: null,
67
+ scene_package_batch: null,
68
+ moqui_capability_coverage: null,
69
+ release_gate_preflight: null,
70
+ remediation_queue: null,
71
+ gates: null,
72
+ regression: null,
73
+ release_evidence: null,
74
+ failure_summary: null,
75
+ recommendations: [],
76
+ warnings: [],
77
+ error: null
78
+ };
79
+
80
+ try {
81
+ const precheckPhase = beginAutoHandoffRunPhase(result, 'precheck', 'Plan and precheck');
82
+ let plan = null;
83
+ try {
84
+ plan = await buildAutoHandoffPlan(projectPath, {
85
+ manifest: options.manifest,
86
+ strict: options.strict,
87
+ strictWarnings: options.strictWarnings
88
+ });
89
+ result.manifest_path = plan.manifest_path;
90
+ result.source_project = plan.source_project || null;
91
+ result.handoff = plan.handoff;
92
+ result.ontology_validation = evaluateHandoffOntologyValidation(
93
+ plan && plan.handoff ? plan.handoff.ontology_validation : null
94
+ );
95
+ result.template_diff = await buildAutoHandoffTemplateDiff(projectPath, { manifest: options.manifest });
96
+ result.release_gate_preflight = buildAutoHandoffReleaseGatePreflight(
97
+ await loadGovernanceReleaseGateSignals(projectPath)
98
+ );
99
+ if (result.release_gate_preflight.parse_error) {
100
+ result.warnings.push(
101
+ `release gate preflight parse failed: ${result.release_gate_preflight.parse_error}`
102
+ );
103
+ }
104
+ if (result.release_gate_preflight.blocked === true) {
105
+ const reasonText = result.release_gate_preflight.reasons.length > 0
106
+ ? result.release_gate_preflight.reasons.join('; ')
107
+ : 'release gate blocked';
108
+ result.warnings.push(`release gate preflight is blocked: ${reasonText}`);
109
+ }
110
+ completeAutoHandoffRunPhase(precheckPhase, {
111
+ validation: plan.validation,
112
+ phase_count: Array.isArray(plan.phases) ? plan.phases.length : 0,
113
+ template_compatibility: result.template_diff.compatibility,
114
+ release_gate_preflight: {
115
+ available: result.release_gate_preflight.available,
116
+ blocked: result.release_gate_preflight.blocked,
117
+ latest_tag: result.release_gate_preflight.latest_tag,
118
+ latest_gate_passed: result.release_gate_preflight.latest_gate_passed,
119
+ latest_weekly_ops_runtime_block_rate_percent:
120
+ result.release_gate_preflight.latest_weekly_ops_runtime_block_rate_percent,
121
+ latest_weekly_ops_runtime_ui_mode_violation_total:
122
+ result.release_gate_preflight.latest_weekly_ops_runtime_ui_mode_violation_total,
123
+ latest_weekly_ops_runtime_ui_mode_violation_rate_percent:
124
+ result.release_gate_preflight.latest_weekly_ops_runtime_ui_mode_violation_rate_percent,
125
+ weekly_ops_runtime_block_rate_max_percent:
126
+ result.release_gate_preflight.weekly_ops_runtime_block_rate_max_percent,
127
+ weekly_ops_runtime_ui_mode_violation_total:
128
+ result.release_gate_preflight.weekly_ops_runtime_ui_mode_violation_total,
129
+ weekly_ops_runtime_ui_mode_violation_run_rate_percent:
130
+ result.release_gate_preflight.weekly_ops_runtime_ui_mode_violation_run_rate_percent,
131
+ weekly_ops_runtime_ui_mode_violation_rate_max_percent:
132
+ result.release_gate_preflight.weekly_ops_runtime_ui_mode_violation_rate_max_percent
133
+ }
134
+ });
135
+ const ontologyGateReasons = evaluateAutoHandoffOntologyGateReasons(
136
+ result.policy,
137
+ result.ontology_validation
138
+ );
139
+ if (ontologyGateReasons.length > 0) {
140
+ throw new Error(`handoff ontology validation gate failed: ${ontologyGateReasons.join('; ')}`);
141
+ }
142
+ const releaseGatePreflightReasons = evaluateAutoHandoffReleaseGatePreflightGateReasons(
143
+ result.policy,
144
+ result.release_gate_preflight
145
+ );
146
+ if (releaseGatePreflightReasons.length > 0) {
147
+ throw new Error(`handoff release gate preflight failed: ${releaseGatePreflightReasons.join('; ')}`);
148
+ }
149
+ } catch (error) {
150
+ failAutoHandoffRunPhase(precheckPhase, error);
151
+ throw error;
152
+ }
153
+
154
+ const baselinePhase = beginAutoHandoffRunPhase(result, 'moqui-baseline', 'Moqui template baseline scorecard');
155
+ try {
156
+ result.moqui_baseline = await buildAutoHandoffMoquiBaselineSnapshot(projectPath);
157
+ completeAutoHandoffRunPhase(
158
+ baselinePhase,
159
+ buildAutoHandoffMoquiBaselinePhaseDetails(result.moqui_baseline)
160
+ );
161
+ if (result.moqui_baseline && result.moqui_baseline.status === 'error') {
162
+ result.warnings.push(`moqui baseline generation failed: ${result.moqui_baseline.error || 'unknown error'}`);
163
+ }
164
+ const moquiBaselineGateReasons = evaluateAutoHandoffMoquiBaselineGateReasons(
165
+ result.policy,
166
+ result.moqui_baseline
167
+ );
168
+ if (moquiBaselineGateReasons.length > 0) {
169
+ throw new Error(`handoff moqui baseline gate failed: ${moquiBaselineGateReasons.join('; ')}`);
170
+ }
171
+ } catch (baselineError) {
172
+ failAutoHandoffRunPhase(baselinePhase, baselineError);
173
+ if (!result.moqui_baseline) {
174
+ result.moqui_baseline = {
175
+ status: 'error',
176
+ generated: false,
177
+ error: baselineError && baselineError.message ? baselineError.message : `${baselineError}`
178
+ };
179
+ }
180
+ throw baselineError;
181
+ }
182
+
183
+ const sceneBatchPhase = beginAutoHandoffRunPhase(
184
+ result,
185
+ 'scene-package-batch',
186
+ 'Scene package publish-batch dry-run gate'
187
+ );
188
+ try {
189
+ result.scene_package_batch = await buildAutoHandoffScenePackageBatchSnapshot(
190
+ projectPath,
191
+ result.manifest_path
192
+ );
193
+ completeAutoHandoffRunPhase(
194
+ sceneBatchPhase,
195
+ buildAutoHandoffScenePackageBatchPhaseDetails(result.scene_package_batch)
196
+ );
197
+ if (result.scene_package_batch && result.scene_package_batch.status === 'error') {
198
+ result.warnings.push(
199
+ `scene package publish-batch dry-run failed: ${result.scene_package_batch.error || 'unknown error'}`
200
+ );
201
+ }
202
+ const sceneBatchGateReasons = evaluateAutoHandoffScenePackageBatchGateReasons(
203
+ result.policy,
204
+ result.scene_package_batch
205
+ );
206
+ if (sceneBatchGateReasons.length > 0) {
207
+ throw new Error(`handoff scene package batch gate failed: ${sceneBatchGateReasons.join('; ')}`);
208
+ }
209
+ } catch (sceneBatchError) {
210
+ failAutoHandoffRunPhase(sceneBatchPhase, sceneBatchError);
211
+ if (!result.scene_package_batch) {
212
+ result.scene_package_batch = {
213
+ status: 'error',
214
+ generated: false,
215
+ error: sceneBatchError && sceneBatchError.message ? sceneBatchError.message : `${sceneBatchError}`
216
+ };
217
+ }
218
+ throw sceneBatchError;
219
+ }
220
+
221
+ const capabilityCoveragePhase = beginAutoHandoffRunPhase(
222
+ result,
223
+ 'moqui-capability-coverage',
224
+ 'Moqui capability coverage matrix'
225
+ );
226
+ try {
227
+ result.moqui_capability_coverage = await buildAutoHandoffCapabilityCoverageSnapshot(
228
+ projectPath,
229
+ result.handoff,
230
+ result.policy
231
+ );
232
+ completeAutoHandoffRunPhase(capabilityCoveragePhase, {
233
+ status: result.moqui_capability_coverage.status || 'unknown',
234
+ coverage_percent: Number.isFinite(
235
+ Number(
236
+ result.moqui_capability_coverage &&
237
+ result.moqui_capability_coverage.summary
238
+ ? result.moqui_capability_coverage.summary.coverage_percent
239
+ : null
240
+ )
241
+ )
242
+ ? Number(result.moqui_capability_coverage.summary.coverage_percent)
243
+ : null,
244
+ passed: Boolean(
245
+ result.moqui_capability_coverage &&
246
+ result.moqui_capability_coverage.summary &&
247
+ result.moqui_capability_coverage.summary.passed === true
248
+ )
249
+ });
250
+ const capabilityCoverageGateReasons = evaluateAutoHandoffCapabilityCoverageGateReasons(
251
+ result.policy,
252
+ result.moqui_capability_coverage
253
+ );
254
+ if (capabilityCoverageGateReasons.length > 0) {
255
+ throw new Error(`handoff capability coverage gate failed: ${capabilityCoverageGateReasons.join('; ')}`);
256
+ }
257
+ const capabilityLexiconGateReasons = evaluateAutoHandoffCapabilityLexiconGateReasons(
258
+ result.policy,
259
+ result.moqui_capability_coverage
260
+ );
261
+ if (capabilityLexiconGateReasons.length > 0) {
262
+ throw new Error(`handoff capability lexicon gate failed: ${capabilityLexiconGateReasons.join('; ')}`);
263
+ }
264
+ } catch (capabilityCoverageError) {
265
+ failAutoHandoffRunPhase(capabilityCoveragePhase, capabilityCoverageError);
266
+ if (!result.moqui_capability_coverage) {
267
+ result.moqui_capability_coverage = {
268
+ status: 'error',
269
+ generated: false,
270
+ error: capabilityCoverageError && capabilityCoverageError.message
271
+ ? capabilityCoverageError.message
272
+ : `${capabilityCoverageError}`
273
+ };
274
+ }
275
+ throw capabilityCoverageError;
276
+ }
277
+
278
+ const queuePhase = beginAutoHandoffRunPhase(result, 'queue', 'Queue generation');
279
+ let queue = null;
280
+ try {
281
+ if (options.continueFrom) {
282
+ queue = await buildAutoHandoffQueueFromContinueSource(projectPath, plan, options);
283
+ } else {
284
+ queue = await buildAutoHandoffQueue(projectPath, {
285
+ manifest: options.manifest,
286
+ out: options.queueOut,
287
+ append: options.append,
288
+ includeKnownGaps: options.includeKnownGaps,
289
+ dryRun: options.dryRun
290
+ });
291
+ }
292
+ if (!queue.dry_run) {
293
+ await writeAutoHandoffQueueFile(projectPath, queue, {
294
+ out: options.queueOut,
295
+ append: options.append
296
+ });
297
+ }
298
+ result.queue = {
299
+ goal_count: queue.goal_count,
300
+ include_known_gaps: queue.include_known_gaps,
301
+ output_file: queue.output_file || null,
302
+ dependency_batching: result.policy.dependency_batching,
303
+ resumed_from: queue.resumed_from || null
304
+ };
305
+ result.continued_from = queue.resumed_from || null;
306
+ completeAutoHandoffRunPhase(queuePhase, {
307
+ goal_count: queue.goal_count,
308
+ output_file: queue.output_file || null,
309
+ resumed_from: queue.resumed_from
310
+ ? {
311
+ session_id: queue.resumed_from.session_id,
312
+ strategy: queue.resumed_from.strategy
313
+ }
314
+ : null
315
+ });
316
+ } catch (error) {
317
+ failAutoHandoffRunPhase(queuePhase, error);
318
+ throw error;
319
+ }
320
+
321
+ const continuationBaselineSummary = queue && queue.resume_context && queue.resume_context.previous_batch_summary
322
+ ? queue.resume_context.previous_batch_summary
323
+ : null;
324
+
325
+ if (result.dry_run) {
326
+ skipAutoHandoffRunPhase(result, 'execution', 'Autonomous close-loop-batch', 'dry-run');
327
+ skipAutoHandoffRunPhase(result, 'observability', 'Observability snapshot', 'dry-run');
328
+ result.dependency_execution = buildAutoHandoffExecutionBatches(
329
+ result.handoff,
330
+ Array.isArray(queue && queue.goals) ? queue.goals : [],
331
+ result.policy.dependency_batching
332
+ );
333
+ result.spec_status = buildAutoHandoffSpecStatus(
334
+ result.handoff && Array.isArray(result.handoff.specs) ? result.handoff.specs : [],
335
+ null,
336
+ continuationBaselineSummary
337
+ );
338
+ result.gates = evaluateAutoHandoffRunGates({
339
+ policy: result.policy,
340
+ dryRun: true,
341
+ specStatus: result.spec_status,
342
+ ontology: result.ontology_validation,
343
+ moquiBaseline: result.moqui_baseline,
344
+ scenePackageBatch: result.scene_package_batch,
345
+ capabilityCoverage: result.moqui_capability_coverage,
346
+ programKpi: {
347
+ risk_level: 'low'
348
+ }
349
+ });
350
+ result.status = 'dry-run';
351
+ return result;
352
+ }
353
+
354
+ const executionPhase = beginAutoHandoffRunPhase(result, 'execution', 'Autonomous close-loop-batch');
355
+ let executionResult = null;
356
+ try {
357
+ executionResult = await executeAutoHandoffExecutionBatches(projectPath, result.handoff, queue, {
358
+ queueOut: options.queueOut,
359
+ continueOnError: options.continueOnError,
360
+ batchAutonomous: options.batchAutonomous,
361
+ batchParallel: options.batchParallel,
362
+ batchAgentBudget: options.batchAgentBudget,
363
+ batchRetryRounds: options.batchRetryRounds,
364
+ batchRetryUntilComplete: options.batchRetryUntilComplete,
365
+ batchRetryMaxRounds: options.batchRetryMaxRounds,
366
+ dependencyBatching: result.policy.dependency_batching
367
+ });
368
+ result.dependency_execution = executionResult.execution_plan;
369
+ result.batch_summary = executionResult.summary;
370
+ result.spec_status = buildAutoHandoffSpecStatus(
371
+ result.handoff && Array.isArray(result.handoff.specs) ? result.handoff.specs : [],
372
+ result.batch_summary,
373
+ continuationBaselineSummary
374
+ );
375
+ completeAutoHandoffRunPhase(executionPhase, {
376
+ status: result.batch_summary.status,
377
+ processed_goals: result.batch_summary.processed_goals,
378
+ failed_goals: result.batch_summary.failed_goals,
379
+ execution_batches: Array.isArray(executionResult.execution_batches)
380
+ ? executionResult.execution_batches.length
381
+ : 0
382
+ });
383
+ } catch (error) {
384
+ failAutoHandoffRunPhase(executionPhase, error);
385
+ throw error;
386
+ }
387
+
388
+ const observabilityPhase = beginAutoHandoffRunPhase(result, 'observability', 'Observability snapshot');
389
+ try {
390
+ result.observability_snapshot = await buildAutoObservabilitySnapshot(projectPath, options);
391
+ const observabilityWeeklyOps = extractAutoObservabilityWeeklyOpsStopTelemetry(result.observability_snapshot);
392
+ completeAutoHandoffRunPhase(observabilityPhase, {
393
+ risk_level: result.observability_snapshot && result.observability_snapshot.highlights
394
+ ? result.observability_snapshot.highlights.governance_risk_level
395
+ : null,
396
+ weekly_ops_stop_sessions: Number(
397
+ observabilityWeeklyOps && observabilityWeeklyOps.sessions
398
+ ) || 0,
399
+ weekly_ops_high_pressure_sessions: Number(
400
+ observabilityWeeklyOps && observabilityWeeklyOps.high_pressure_sessions
401
+ ) || 0,
402
+ weekly_ops_config_warning_positive_sessions: Number(
403
+ observabilityWeeklyOps && observabilityWeeklyOps.config_warning_positive_sessions
404
+ ) || 0,
405
+ weekly_ops_auth_tier_pressure_sessions: Number(
406
+ observabilityWeeklyOps && observabilityWeeklyOps.auth_tier_pressure_sessions
407
+ ) || 0,
408
+ weekly_ops_dialogue_authorization_pressure_sessions: Number(
409
+ observabilityWeeklyOps && observabilityWeeklyOps.dialogue_authorization_pressure_sessions
410
+ ) || 0,
411
+ weekly_ops_runtime_block_rate_high_sessions: Number(
412
+ observabilityWeeklyOps && observabilityWeeklyOps.runtime_block_rate_high_sessions
413
+ ) || 0,
414
+ weekly_ops_runtime_ui_mode_violation_high_sessions: Number(
415
+ observabilityWeeklyOps && observabilityWeeklyOps.runtime_ui_mode_violation_high_sessions
416
+ ) || 0,
417
+ weekly_ops_runtime_ui_mode_violation_total_sum: Number(
418
+ observabilityWeeklyOps && observabilityWeeklyOps.runtime_ui_mode_violation_total_sum
419
+ ) || 0
420
+ });
421
+ } catch (error) {
422
+ failAutoHandoffRunPhase(observabilityPhase, error);
423
+ throw error;
424
+ }
425
+
426
+ result.gates = evaluateAutoHandoffRunGates({
427
+ policy: result.policy,
428
+ dryRun: false,
429
+ specStatus: result.spec_status,
430
+ ontology: result.ontology_validation,
431
+ moquiBaseline: result.moqui_baseline,
432
+ scenePackageBatch: result.scene_package_batch,
433
+ capabilityCoverage: result.moqui_capability_coverage,
434
+ programKpi: buildProgramKpiSnapshot(result.batch_summary || {})
435
+ });
436
+ if (!result.gates.passed) {
437
+ throw new Error(`handoff run gate failed: ${result.gates.reasons.join('; ')}`);
438
+ }
439
+ result.status = 'completed';
440
+ } catch (error) {
441
+ result.status = 'failed';
442
+ result.error = error && error.message ? error.message : `${error}`;
443
+ } finally {
444
+ result.completed_at = new Date().toISOString();
445
+ result.elapsed_ms = Math.max(0, Date.now() - startedAtMs);
446
+ result.regression = await buildAutoHandoffRegression(projectPath, result);
447
+ result.remediation_queue = await maybeWriteAutoHandoffMoquiRemediationQueue(projectPath, result);
448
+ result.failure_summary = buildAutoHandoffRunFailureSummary(result);
449
+ result.recommendations = buildAutoHandoffRunRecommendations(projectPath, result);
450
+ await writeAutoHandoffRunReport(projectPath, result, options.out);
451
+ if (result.dry_run) {
452
+ result.release_evidence = {
453
+ mode: 'auto-handoff-release-evidence',
454
+ merged: false,
455
+ skipped: true,
456
+ reason: 'dry-run',
457
+ file: path.join(projectPath, AUTO_HANDOFF_RELEASE_EVIDENCE_FILE)
458
+ };
459
+ } else {
460
+ try {
461
+ result.release_evidence = await mergeAutoHandoffRunIntoReleaseEvidence(projectPath, result, result.output_file);
462
+ } catch (mergeError) {
463
+ const message = mergeError && mergeError.message ? mergeError.message : `${mergeError}`;
464
+ result.release_evidence = {
465
+ mode: 'auto-handoff-release-evidence',
466
+ merged: false,
467
+ file: path.join(projectPath, AUTO_HANDOFF_RELEASE_EVIDENCE_FILE),
468
+ error: message
469
+ };
470
+ result.warnings.push(`release evidence merge failed: ${message}`);
471
+ }
472
+ }
473
+ try {
474
+ await writeAutoHandoffRunReport(projectPath, result, options.out);
475
+ } catch (refreshError) {
476
+ const message = refreshError && refreshError.message ? refreshError.message : `${refreshError}`;
477
+ result.warnings.push(`handoff run report refresh failed: ${message}`);
478
+ }
479
+ }
480
+
481
+ return result;
482
+ }
483
+
484
+ module.exports = {
485
+ runAutoHandoff
486
+ };