scene-capability-engine 3.6.64 → 3.6.67

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 (125) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +17 -6
  3. package/README.zh.md +18 -6
  4. package/bin/scene-capability-engine.js +4 -0
  5. package/docs/README.md +2 -2
  6. package/docs/command-reference.md +385 -8
  7. package/docs/document-governance.md +3 -2
  8. package/docs/integration-modes.md +62 -478
  9. package/docs/integration-philosophy.md +56 -263
  10. package/docs/magicball-cli-invocation-examples.md +1 -0
  11. package/docs/magicball-project-portfolio-contract.md +125 -4
  12. package/docs/project-management/README.md +14 -0
  13. package/docs/project-management/assurance/backup.md +3 -0
  14. package/docs/project-management/assurance/config.md +3 -0
  15. package/docs/project-management/assurance/evidence/README.md +3 -0
  16. package/docs/project-management/assurance/incidents/README.md +3 -0
  17. package/docs/project-management/assurance/logs.md +3 -0
  18. package/docs/project-management/assurance/overview.md +3 -0
  19. package/docs/project-management/assurance/recovery/README.md +3 -0
  20. package/docs/project-management/assurance/resource.md +3 -0
  21. package/docs/project-management/assurance/runbooks/README.md +3 -0
  22. package/docs/project-management/delivery/acceptance/README.md +3 -0
  23. package/docs/project-management/delivery/acceptance/evidence/README.md +3 -0
  24. package/docs/project-management/delivery/acceptance/exceptions/README.md +3 -0
  25. package/docs/project-management/delivery/acceptance/reports/README.md +3 -0
  26. package/docs/project-management/delivery/documents/changes.md +3 -0
  27. package/docs/project-management/delivery/documents/issues.md +3 -0
  28. package/docs/project-management/delivery/documents/overview.md +3 -0
  29. package/docs/project-management/delivery/documents/planning.md +3 -0
  30. package/docs/project-management/delivery/documents/requirements.md +3 -0
  31. package/docs/project-management/delivery/documents/tracking.md +3 -0
  32. package/docs/project-management/delivery/handoffs/README.md +3 -0
  33. package/docs/project-management/delivery/handoffs/evidence/README.md +3 -0
  34. package/docs/project-management/delivery/handoffs/records/README.md +3 -0
  35. package/docs/project-management/delivery/overview.md +10 -0
  36. package/docs/project-management/delivery/releases/README.md +3 -0
  37. package/docs/project-management/delivery/releases/baselines/README.md +3 -0
  38. package/docs/project-management/delivery/releases/evidence/README.md +3 -0
  39. package/docs/project-management/delivery/tables/changes.md +3 -0
  40. package/docs/project-management/delivery/tables/issues.md +3 -0
  41. package/docs/project-management/delivery/tables/planning.md +3 -0
  42. package/docs/project-management/delivery/tables/requirements.md +3 -0
  43. package/docs/project-management/delivery/tables/tracking.md +3 -0
  44. package/docs/project-management/environment/agent-discovery.md +3 -0
  45. package/docs/project-management/environment/development.md +3 -0
  46. package/docs/project-management/environment/overview.md +10 -0
  47. package/docs/project-management/environment/testing.md +3 -0
  48. package/docs/project-management/environment/version-alignment.md +3 -0
  49. package/docs/quick-start-with-ai-tools.md +68 -308
  50. package/docs/releases/README.md +3 -0
  51. package/docs/releases/v3.6.65.md +25 -0
  52. package/docs/releases/v3.6.66.md +23 -0
  53. package/docs/releases/v3.6.67.md +23 -0
  54. package/docs/steering-governance.md +64 -2
  55. package/docs/zh/README.md +2 -2
  56. package/docs/zh/releases/README.md +3 -0
  57. package/docs/zh/releases/v3.6.65.md +25 -0
  58. package/docs/zh/releases/v3.6.66.md +23 -0
  59. package/docs/zh/releases/v3.6.67.md +23 -0
  60. package/lib/commands/adopt.js +24 -0
  61. package/lib/commands/native.js +158 -0
  62. package/lib/commands/project.js +96 -0
  63. package/lib/commands/semantic.js +1459 -0
  64. package/lib/commands/session.js +74 -3
  65. package/lib/commands/spec-bootstrap.js +10 -1
  66. package/lib/commands/spec-gate.js +10 -1
  67. package/lib/commands/spec-pipeline.js +10 -1
  68. package/lib/commands/studio.js +405 -30
  69. package/lib/commands/task.js +141 -7
  70. package/lib/governance/supreme-principles.js +530 -0
  71. package/lib/problem/problem-evaluator.js +4 -0
  72. package/lib/project/candidate-inspection-service.js +24 -1
  73. package/lib/project/portfolio-projection-service.js +315 -5
  74. package/lib/project/project-channel-output.js +94 -0
  75. package/lib/project/project-channel-projection.js +181 -0
  76. package/lib/project/root-onboarding-service.js +107 -7
  77. package/lib/project/semantic-shared-source-projection.js +150 -0
  78. package/lib/project/supervision-action-model.js +277 -0
  79. package/lib/project/supervision-projection-service.js +305 -5
  80. package/lib/project/target-resolution-service.js +70 -5
  81. package/lib/project/visibility-policy.js +93 -0
  82. package/lib/runtime/multi-spec-scene-session.js +8 -1
  83. package/lib/runtime/project-channel-context-store.js +387 -0
  84. package/lib/runtime/project-channel-context.js +406 -0
  85. package/lib/runtime/scene-session-binding.js +46 -0
  86. package/lib/runtime/session-store.js +186 -0
  87. package/lib/runtime/steering-contract.js +7 -1
  88. package/lib/semantic/archive-report.js +283 -0
  89. package/lib/semantic/archive-routing.js +67 -0
  90. package/lib/semantic/backflow-report.js +245 -0
  91. package/lib/semantic/capability-contract.js +30 -0
  92. package/lib/semantic/delta-export.js +145 -0
  93. package/lib/semantic/interaction-observer.js +254 -0
  94. package/lib/semantic/kernel-loader.js +881 -0
  95. package/lib/semantic/native-runtime.js +359 -0
  96. package/lib/semantic/progress-ledger.js +433 -0
  97. package/lib/semantic/replay-evaluator.js +382 -0
  98. package/lib/semantic/shared-publication.js +592 -0
  99. package/lib/semantic/shared-source-config.js +183 -0
  100. package/lib/semantic/shared-source-connect.js +139 -0
  101. package/lib/semantic/shared-source-discovery.js +98 -0
  102. package/lib/semantic/shared-sync-export.js +413 -0
  103. package/lib/semantic/shared-sync-intake.js +592 -0
  104. package/lib/semantic/shared-sync-merge.js +547 -0
  105. package/lib/semantic/shared-sync-release.js +463 -0
  106. package/lib/semantic/supreme-intent-report.js +300 -0
  107. package/lib/state/sce-state-store.js +1360 -0
  108. package/lib/steering/context-sync-manager.js +276 -25
  109. package/lib/studio/spec-intake-governor.js +39 -3
  110. package/lib/studio/task-envelope.js +35 -2
  111. package/lib/workspace/takeover-baseline.js +342 -83
  112. package/package.json +7 -2
  113. package/scripts/agent-governance-baseline-audit.js +395 -0
  114. package/scripts/clarification-first-audit.js +9 -9
  115. package/scripts/deprecated-entry-audit.js +240 -0
  116. package/scripts/release-doc-version-audit.js +24 -0
  117. package/scripts/release-posture-report.js +262 -0
  118. package/template/.sce/README.md +62 -228
  119. package/template/.sce/config/semantic-shared-sources.json +5 -0
  120. package/template/.sce/config/supreme-principles-policy.json +105 -0
  121. package/template/.sce/config/takeover-baseline.json +7 -0
  122. package/template/.sce/steering/CORE_PRINCIPLES.md +23 -63
  123. package/template/.sce/steering/CURRENT_CONTEXT.md +4 -0
  124. package/template/.sce/steering/RULES_GUIDE.md +17 -9
  125. package/template/README.md +32 -96
@@ -0,0 +1,277 @@
1
+ function normalizeString(value) {
2
+ if (typeof value !== 'string') {
3
+ return '';
4
+ }
5
+ return value.trim();
6
+ }
7
+
8
+ const SEVERITY_ORDER = {
9
+ none: 0,
10
+ low: 1,
11
+ medium: 2,
12
+ high: 3,
13
+ critical: 4
14
+ };
15
+
16
+ function quoteCliArg(value) {
17
+ const normalized = normalizeString(value);
18
+ if (!normalized) {
19
+ return '';
20
+ }
21
+ if (/^[A-Za-z0-9._:/=-]+$/.test(normalized)) {
22
+ return normalized;
23
+ }
24
+ return `"${normalized.replace(/(["\\$`])/g, '\\$1')}"`;
25
+ }
26
+
27
+ function appendCommandOption(parts, flag, value) {
28
+ const normalized = normalizeString(value);
29
+ if (!normalized) {
30
+ return;
31
+ }
32
+ parts.push(flag, quoteCliArg(normalized));
33
+ }
34
+
35
+ function joinCommand(parts) {
36
+ return parts.filter(Boolean).join(' ');
37
+ }
38
+
39
+ function buildProjectSupervisionCommand(projectId, channelId) {
40
+ const parts = ['sce', 'project', 'supervision', 'show'];
41
+ appendCommandOption(parts, '--project', projectId);
42
+ appendCommandOption(parts, '--channel', channelId);
43
+ parts.push('--json');
44
+ return joinCommand(parts);
45
+ }
46
+
47
+ function buildGovernanceReportCommand(projectId, item = {}) {
48
+ const parts = ['sce', 'semantic', 'governance-report'];
49
+ appendCommandOption(parts, '--project-id', projectId);
50
+ appendCommandOption(parts, '--channel-id', item.channelId);
51
+ appendCommandOption(parts, '--scene', item.sceneId);
52
+ appendCommandOption(parts, '--spec', item.specId);
53
+ parts.push('--json');
54
+ return joinCommand(parts);
55
+ }
56
+
57
+ function buildBackflowReportCommand(projectId, item = {}) {
58
+ const parts = ['sce', 'semantic', 'backflow-report'];
59
+ appendCommandOption(parts, '--project-id', projectId);
60
+ appendCommandOption(parts, '--spec', item.specId);
61
+ parts.push('--json');
62
+ return joinCommand(parts);
63
+ }
64
+
65
+ function buildArchiveReportCommand(projectId, item = {}) {
66
+ const parts = ['sce', 'semantic', 'archive-report'];
67
+ appendCommandOption(parts, '--project-id', projectId);
68
+ appendCommandOption(parts, '--spec', item.specId);
69
+ appendCommandOption(parts, '--session-id', item.sessionId);
70
+ parts.push('--json');
71
+ return joinCommand(parts);
72
+ }
73
+
74
+ function buildConnectSharedSourceCommand(item = {}) {
75
+ const suggested = normalizeString(item.suggestedConnectCommand);
76
+ if (suggested) {
77
+ return suggested;
78
+ }
79
+ const parts = ['sce', 'semantic', 'connect-shared-source'];
80
+ appendCommandOption(parts, '--input-file', item.descriptorFile);
81
+ parts.push('--json');
82
+ return joinCommand(parts);
83
+ }
84
+
85
+ function buildStudioResumeCommand(item = {}) {
86
+ const parts = ['sce', 'studio', 'resume'];
87
+ appendCommandOption(parts, '--job', item.eventId);
88
+ parts.push('--json');
89
+ return joinCommand(parts);
90
+ }
91
+
92
+ function buildHandoffEvidenceCommand(item = {}) {
93
+ const parts = ['sce', 'auto', 'handoff', 'evidence'];
94
+ appendCommandOption(parts, '--session-id', item.requestId);
95
+ parts.push('--json');
96
+ return joinCommand(parts);
97
+ }
98
+
99
+ function buildMergeSharedCommand(item = {}) {
100
+ const parts = ['sce', 'semantic', 'merge-shared'];
101
+ appendCommandOption(parts, '--spec', item.specId);
102
+ parts.push('--json');
103
+ return joinCommand(parts);
104
+ }
105
+
106
+ function buildPublishSharedRegistryCommand(item = {}) {
107
+ const parts = ['sce', 'semantic', 'publish-shared-registry'];
108
+ appendCommandOption(parts, '--spec', item.specId);
109
+ parts.push('--json');
110
+ return joinCommand(parts);
111
+ }
112
+
113
+ function resolveBlockingScope(item = {}) {
114
+ if (normalizeString(item.specId)) {
115
+ return 'spec';
116
+ }
117
+ if (normalizeString(item.sceneId)) {
118
+ return 'scene';
119
+ }
120
+ if (normalizeString(item.channelId)) {
121
+ return 'channel';
122
+ }
123
+ return 'project';
124
+ }
125
+
126
+ function annotateSupervisionItem(item = {}, context = {}) {
127
+ const projectId = normalizeString(context.projectId);
128
+ const state = normalizeString(item.state);
129
+ const kind = normalizeString(item.kind);
130
+ const blockingScope = resolveBlockingScope(item);
131
+ let severity = 'none';
132
+ let recommendedAction = null;
133
+ let recommendedCommand = null;
134
+
135
+ if (kind === 'blocked') {
136
+ severity = 'critical';
137
+ recommendedAction = 'resume_blocked_studio_job';
138
+ recommendedCommand = buildStudioResumeCommand(item);
139
+ } else if (kind === 'handoff') {
140
+ severity = 'low';
141
+ recommendedAction = 'review_handoff_readiness';
142
+ recommendedCommand = buildHandoffEvidenceCommand(item);
143
+ } else if (kind === 'risk') {
144
+ severity = 'medium';
145
+ recommendedAction = 'refresh_stale_spec_governance';
146
+ recommendedCommand = buildProjectSupervisionCommand(projectId, item.channelId);
147
+ } else if (kind === 'info' && state === 'pending-connect') {
148
+ severity = 'medium';
149
+ recommendedAction = 'connect_shared_source';
150
+ recommendedCommand = buildConnectSharedSourceCommand(item);
151
+ } else if (kind === 'governance') {
152
+ severity = state === 'refuse-hotspot' ? 'high' : 'medium';
153
+ recommendedAction = state === 'refuse-hotspot'
154
+ ? 'reduce_refuse_hotspot'
155
+ : 'reduce_rewrite_hotspot';
156
+ recommendedCommand = buildGovernanceReportCommand(projectId, item);
157
+ } else if (kind === 'backflow') {
158
+ if (state === 'central-release-blocked') {
159
+ severity = 'critical';
160
+ recommendedAction = 'unblock_central_release';
161
+ recommendedCommand = normalizeString(item.specId)
162
+ ? buildPublishSharedRegistryCommand(item)
163
+ : buildBackflowReportCommand(projectId, item);
164
+ } else if (state === 'central-merge-blocked') {
165
+ severity = 'high';
166
+ recommendedAction = 'unblock_central_merge';
167
+ recommendedCommand = normalizeString(item.specId)
168
+ ? buildMergeSharedCommand(item)
169
+ : buildBackflowReportCommand(projectId, item);
170
+ } else if (state === 'local-publish-blocked') {
171
+ severity = 'high';
172
+ recommendedAction = 'resolve_local_publish_blocker';
173
+ recommendedCommand = buildBackflowReportCommand(projectId, item);
174
+ }
175
+ } else if (kind === 'archive') {
176
+ if (state === 'archive-routing-missing') {
177
+ severity = 'critical';
178
+ recommendedAction = 'normalize_archive_routing';
179
+ recommendedCommand = buildArchiveReportCommand(projectId, item);
180
+ } else if (
181
+ Number(item.publishBlockedCount || 0) > 0
182
+ || Number(item.publishPendingCount || 0) > 0
183
+ ) {
184
+ severity = 'medium';
185
+ recommendedAction = 'clear_archive_publication_backlog';
186
+ recommendedCommand = buildArchiveReportCommand(projectId, item);
187
+ } else {
188
+ severity = 'low';
189
+ recommendedAction = 'review_archive_accumulation';
190
+ recommendedCommand = buildArchiveReportCommand(projectId, item);
191
+ }
192
+ }
193
+
194
+ return {
195
+ ...item,
196
+ severity,
197
+ blocking_scope: blockingScope,
198
+ recommended_action: recommendedAction,
199
+ recommended_command: recommendedCommand,
200
+ actionable: Boolean(recommendedAction && recommendedCommand)
201
+ };
202
+ }
203
+
204
+ function compareSupervisionItems(left = {}, right = {}) {
205
+ const severityDelta = (SEVERITY_ORDER[right.severity] || 0) - (SEVERITY_ORDER[left.severity] || 0);
206
+ if (severityDelta !== 0) {
207
+ return severityDelta;
208
+ }
209
+ const updatedAtDelta = `${right.updatedAt || ''}`.localeCompare(`${left.updatedAt || ''}`);
210
+ if (updatedAtDelta !== 0) {
211
+ return updatedAtDelta;
212
+ }
213
+ return `${left.id || ''}`.localeCompare(`${right.id || ''}`);
214
+ }
215
+
216
+ function summarizeActionQueue(actionQueue = []) {
217
+ const summary = {
218
+ highestSeverity: actionQueue[0] ? actionQueue[0].severity : 'none',
219
+ actionableCount: actionQueue.length,
220
+ criticalCount: 0,
221
+ highCount: 0,
222
+ mediumCount: 0,
223
+ lowCount: 0
224
+ };
225
+
226
+ for (const item of actionQueue) {
227
+ if (item.severity === 'critical') {
228
+ summary.criticalCount += 1;
229
+ } else if (item.severity === 'high') {
230
+ summary.highCount += 1;
231
+ } else if (item.severity === 'medium') {
232
+ summary.mediumCount += 1;
233
+ } else if (item.severity === 'low') {
234
+ summary.lowCount += 1;
235
+ }
236
+ }
237
+
238
+ if (actionQueue[0] && normalizeString(actionQueue[0].recommended_command)) {
239
+ summary.primaryRecommendedCommand = actionQueue[0].recommended_command;
240
+ }
241
+
242
+ return summary;
243
+ }
244
+
245
+ function buildSupervisionActionQueue(items = [], context = {}) {
246
+ const annotatedItems = items.map((item) => annotateSupervisionItem(item, context));
247
+ const actionQueue = annotatedItems
248
+ .filter((item) => item.actionable)
249
+ .sort(compareSupervisionItems)
250
+ .map((item, index) => ({
251
+ rank: index + 1,
252
+ id: item.id,
253
+ kind: item.kind,
254
+ state: item.state,
255
+ summary: item.summary,
256
+ updatedAt: item.updatedAt,
257
+ severity: item.severity,
258
+ blocking_scope: item.blocking_scope,
259
+ recommended_action: item.recommended_action,
260
+ recommended_command: item.recommended_command,
261
+ ...(normalizeString(item.channelId) ? { channelId: item.channelId } : {}),
262
+ ...(normalizeString(item.sceneId) ? { sceneId: item.sceneId } : {}),
263
+ ...(normalizeString(item.specId) ? { specId: item.specId } : {})
264
+ }));
265
+
266
+ return {
267
+ items: annotatedItems,
268
+ actionQueue,
269
+ summary: summarizeActionQueue(actionQueue)
270
+ };
271
+ }
272
+
273
+ module.exports = {
274
+ SEVERITY_ORDER,
275
+ annotateSupervisionItem,
276
+ buildSupervisionActionQueue
277
+ };
@@ -4,6 +4,13 @@ const fs = require('fs-extra');
4
4
  const TaskClaimer = require('../task/task-claimer');
5
5
  const { SessionStore } = require('../runtime/session-store');
6
6
  const { buildProjectPortfolioProjection } = require('./portfolio-projection-service');
7
+ const { buildProjectChannelProjection } = require('./project-channel-projection');
8
+ const { buildProjectChannelOutputFromProjection } = require('./project-channel-output');
9
+ const { buildSemanticSharedSourceProjection } = require('./semantic-shared-source-projection');
10
+ const { buildSupervisionActionQueue } = require('./supervision-action-model');
11
+ const { buildSupremeIntentGovernanceReport } = require('../semantic/supreme-intent-report');
12
+ const { buildSemanticBackflowReport } = require('../semantic/backflow-report');
13
+ const { buildSemanticArchiveReport } = require('../semantic/archive-report');
7
14
 
8
15
  const SPEC_GOVERNANCE_SCENE_INDEX = path.join('.sce', 'spec-governance', 'scene-index.json');
9
16
  const STUDIO_REPORT_DIR = path.join('.sce', 'reports', 'studio');
@@ -245,6 +252,159 @@ async function buildBlockedItems(projectRoot, fileSystem = fs) {
245
252
  return items;
246
253
  }
247
254
 
255
+ async function buildSemanticSharedSourceInfoItems(projectRoot, fileSystem = fs) {
256
+ const projection = await buildSemanticSharedSourceProjection(projectRoot, {
257
+ fileSystem
258
+ });
259
+ const items = [];
260
+ for (const item of projection.items.filter((entry) => entry.approved && !entry.connected)) {
261
+ items.push({
262
+ id: `info:semantic-shared-source:${item.source_name}:${item.descriptor_file}`,
263
+ kind: 'info',
264
+ state: 'pending-connect',
265
+ reasonCode: 'project.semantic_shared_source_connect_recommended',
266
+ ...(normalizeString(item.spec_id) ? { specId: normalizeString(item.spec_id) } : {}),
267
+ descriptorFile: item.descriptor_file,
268
+ sourceName: item.source_name,
269
+ suggestedConnectCommand: item.suggested_connect_command,
270
+ ...(safeIsoAt(item.updated_at) ? { updatedAt: safeIsoAt(item.updated_at) } : {}),
271
+ summary: `Approved semantic shared source ${item.source_name} is available but not connected.`
272
+ });
273
+ }
274
+ return {
275
+ projection,
276
+ items
277
+ };
278
+ }
279
+
280
+ function buildSupremeIntentGovernanceItems(report = {}) {
281
+ const hotspots = Array.isArray(report.top_scope_hotspots) ? report.top_scope_hotspots : [];
282
+ return hotspots
283
+ .filter((item) => Number(item.governed_count || 0) > 0)
284
+ .slice(0, 3)
285
+ .map((item) => ({
286
+ id: `governance:${item.project_id || 'project'}:${item.channel_id || 'channel'}:${item.spec_id || 'spec'}`,
287
+ kind: 'governance',
288
+ state: item.refuse > 0 ? 'refuse-hotspot' : 'rewrite-hotspot',
289
+ reasonCode: 'project.supreme_intent_governance_hotspot',
290
+ ...(normalizeString(item.channel_id) ? { channelId: normalizeString(item.channel_id) } : {}),
291
+ ...(normalizeString(item.scene_id) ? { sceneId: normalizeString(item.scene_id) } : {}),
292
+ ...(normalizeString(item.spec_id) ? { specId: normalizeString(item.spec_id) } : {}),
293
+ governedCount: item.governed_count,
294
+ rewriteCount: Number(item.rewrite || 0),
295
+ refuseCount: Number(item.refuse || 0),
296
+ clarifyCount: Number(item.clarify || 0),
297
+ narrowCount: Number(item.narrow || 0),
298
+ updatedAt: safeIsoAt(item.latest_at) || new Date().toISOString(),
299
+ summary: `Governance hotspot on ${item.channel_id || 'project'} / ${item.spec_id || item.scene_id || 'unbound'} with ${item.governed_count} governed assessments.`
300
+ }));
301
+ }
302
+
303
+ function buildSemanticBackflowItems(report = {}) {
304
+ const items = [];
305
+ const localBlockedItems = Array.isArray(report?.local?.recent_blocked_items)
306
+ ? report.local.recent_blocked_items.slice(0, 3)
307
+ : [];
308
+ for (const item of localBlockedItems) {
309
+ items.push({
310
+ id: `backflow:local:${item.lesson_id || item.capability_id || item.spec_id || 'unknown'}`,
311
+ kind: 'backflow',
312
+ state: 'local-publish-blocked',
313
+ reasonCode: 'project.semantic_backflow_local_publish_blocked',
314
+ ...(normalizeString(item.channel_id) ? { channelId: normalizeString(item.channel_id) } : {}),
315
+ ...(normalizeString(item.scene_id) ? { sceneId: normalizeString(item.scene_id) } : {}),
316
+ ...(normalizeString(item.spec_id) ? { specId: normalizeString(item.spec_id) } : {}),
317
+ ...(normalizeString(item.lesson_id) ? { lessonId: normalizeString(item.lesson_id) } : {}),
318
+ ...(normalizeString(item.capability_id) ? { capabilityId: normalizeString(item.capability_id) } : {}),
319
+ blockedReason: normalizeString(item.blocked_reason) || 'unknown',
320
+ governancePenaltyScore: Number(item.governance_penalty_score || 0),
321
+ governanceRefuseCount: Number(item.governance_refuse_count || 0),
322
+ governanceExecutionBlockedCount: Number(item.governance_execution_blocked_count || 0),
323
+ updatedAt: safeIsoAt(item.blocked_at) || new Date().toISOString(),
324
+ summary: `Local semantic publication is blocked for ${item.spec_id || item.scene_id || 'project scope'} (${normalizeString(item.blocked_reason) || 'unknown'}).`
325
+ });
326
+ }
327
+
328
+ const mergeReceipts = Array.isArray(report?.central_merge?.receipts)
329
+ ? report.central_merge.receipts
330
+ : [];
331
+ for (const receipt of mergeReceipts.filter((entry) => Number(entry?.totals?.blocked || 0) > 0).slice(0, 3)) {
332
+ const blockedReasons = (Array.isArray(receipt.blocked) ? receipt.blocked : [])
333
+ .map((entry) => normalizeString(entry && entry.reason))
334
+ .filter(Boolean);
335
+ items.push({
336
+ id: `backflow:merge:${receipt.spec_id || 'unknown'}:${receipt.generated_at || 'latest'}`,
337
+ kind: 'backflow',
338
+ state: 'central-merge-blocked',
339
+ reasonCode: 'project.semantic_backflow_central_merge_blocked',
340
+ ...(normalizeString(receipt.spec_id) ? { specId: normalizeString(receipt.spec_id) } : {}),
341
+ blockedCount: Number(receipt?.totals?.blocked || 0),
342
+ blockedReasons,
343
+ updatedAt: safeIsoAt(receipt.generated_at) || new Date().toISOString(),
344
+ summary: `Central merge is blocked for ${receipt.spec_id || 'unknown spec'} with ${Number(receipt?.totals?.blocked || 0)} blocked entr${Number(receipt?.totals?.blocked || 0) === 1 ? 'y' : 'ies'}.`
345
+ });
346
+ }
347
+
348
+ const releaseReceipts = Array.isArray(report?.central_release?.receipts)
349
+ ? report.central_release.receipts
350
+ : [];
351
+ for (const receipt of releaseReceipts.filter((entry) => Number(entry?.totals?.blocked || 0) > 0).slice(0, 3)) {
352
+ const blockedReasons = (Array.isArray(receipt.blocked) ? receipt.blocked : [])
353
+ .map((entry) => normalizeString(entry && entry.reason))
354
+ .filter(Boolean);
355
+ items.push({
356
+ id: `backflow:release:${receipt.spec_id || 'unknown'}:${receipt.generated_at || 'latest'}`,
357
+ kind: 'backflow',
358
+ state: 'central-release-blocked',
359
+ reasonCode: 'project.semantic_backflow_central_release_blocked',
360
+ ...(normalizeString(receipt.spec_id) ? { specId: normalizeString(receipt.spec_id) } : {}),
361
+ blockedCount: Number(receipt?.totals?.blocked || 0),
362
+ blockedReasons,
363
+ updatedAt: safeIsoAt(receipt.generated_at) || new Date().toISOString(),
364
+ summary: `Approved-central release is blocked for ${receipt.spec_id || 'unknown spec'} with ${Number(receipt?.totals?.blocked || 0)} blocked entr${Number(receipt?.totals?.blocked || 0) === 1 ? 'y' : 'ies'}.`
365
+ });
366
+ }
367
+
368
+ return items;
369
+ }
370
+
371
+ function buildSemanticArchiveItems(report = {}) {
372
+ const items = [];
373
+ const libraries = Array.isArray(report.by_library) ? report.by_library : [];
374
+ for (const item of libraries.filter((entry) => (Number(entry.lesson_count || 0) + Number(entry.ledger_count || 0)) > 0).slice(0, 3)) {
375
+ items.push({
376
+ id: `archive:${item.target_library || 'unknown'}`,
377
+ kind: 'archive',
378
+ state: item.published_shared_count > 0 ? 'shared-accumulating' : 'local-accumulating',
379
+ reasonCode: 'project.semantic_archive_library_accumulating',
380
+ targetLibrary: normalizeString(item.target_library) || null,
381
+ archiveClass: normalizeString(item.archive_class) || null,
382
+ reuseScope: normalizeString(item.reuse_scope) || null,
383
+ lessonCount: Number(item.lesson_count || 0),
384
+ ledgerCount: Number(item.ledger_count || 0),
385
+ publishPendingCount: Number(item.publish_pending_count || 0),
386
+ publishedSharedCount: Number(item.published_shared_count || 0),
387
+ publishBlockedCount: Number(item.publish_blocked_count || 0),
388
+ updatedAt: safeIsoAt((report.recent_items || []).find((entry) => normalizeString(entry.target_library) === normalizeString(item.target_library))?.updated_at) || new Date().toISOString(),
389
+ summary: `${item.target_library || 'unknown'} is accumulating ${Number(item.lesson_count || 0)} lesson(s) and ${Number(item.ledger_count || 0)} ledger row(s).`
390
+ });
391
+ }
392
+
393
+ if (Number(report?.totals?.missing_archive_count || 0) > 0) {
394
+ items.push({
395
+ id: 'archive:missing-routing',
396
+ kind: 'archive',
397
+ state: 'archive-routing-missing',
398
+ reasonCode: 'project.semantic_archive_routing_missing',
399
+ missingArchiveCount: Number(report.totals.missing_archive_count || 0),
400
+ updatedAt: safeIsoAt(report.generated_at) || new Date().toISOString(),
401
+ summary: `${Number(report.totals.missing_archive_count || 0)} archive item(s) are missing normalized routing metadata.`
402
+ });
403
+ }
404
+
405
+ return items;
406
+ }
407
+
248
408
  async function resolveVisibleProject(projectId, dependencies = {}) {
249
409
  const portfolio = await buildProjectPortfolioProjection({}, dependencies);
250
410
  const record = (portfolio.projects || []).find((item) => item.projectId === projectId) || null;
@@ -256,6 +416,7 @@ async function resolveVisibleProject(projectId, dependencies = {}) {
256
416
 
257
417
  async function buildProjectSupervisionProjection(options = {}, dependencies = {}) {
258
418
  const projectId = normalizeString(options.project);
419
+ const requestedChannelId = normalizeString(options.channel);
259
420
  if (!projectId) {
260
421
  throw new Error('--project is required');
261
422
  }
@@ -276,9 +437,16 @@ async function buildProjectSupervisionProjection(options = {}, dependencies = {}
276
437
  summary: {
277
438
  blockedCount: 0,
278
439
  handoffCount: 0,
279
- riskCount: 0
440
+ riskCount: 0,
441
+ highestSeverity: 'none',
442
+ actionableCount: 0,
443
+ criticalCount: 0,
444
+ highCount: 0,
445
+ mediumCount: 0,
446
+ lowCount: 0
280
447
  },
281
448
  items: [],
449
+ actionQueue: [],
282
450
  partial: true,
283
451
  partialReasons: ['project_inaccessible']
284
452
  };
@@ -295,32 +463,164 @@ async function buildProjectSupervisionProjection(options = {}, dependencies = {}
295
463
  const riskItems = await buildRiskItems(projectRoot, fileSystem);
296
464
  const handoffItems = await buildHandoffItems(projectRoot, fileSystem);
297
465
  const blockedItems = await buildBlockedItems(projectRoot, fileSystem);
466
+ const semanticSharedSourceInfo = await buildSemanticSharedSourceInfoItems(projectRoot, fileSystem);
467
+ const semanticArchive = await buildSemanticArchiveReport({
468
+ project_id: projectId,
469
+ limit: 200,
470
+ recent_limit: 10
471
+ }, {
472
+ ...dependencies,
473
+ projectPath: projectRoot,
474
+ fileSystem
475
+ });
476
+ const semanticBackflow = await buildSemanticBackflowReport({
477
+ project_id: projectId,
478
+ limit: 200,
479
+ recent_limit: 10
480
+ }, {
481
+ ...dependencies,
482
+ projectPath: projectRoot,
483
+ fileSystem
484
+ });
485
+ const supremeIntentGovernance = await buildSupremeIntentGovernanceReport({
486
+ project_id: projectId,
487
+ ...(requestedChannelId ? { channel_id: requestedChannelId } : {}),
488
+ limit: 200,
489
+ hotspot_limit: 3,
490
+ recent_limit: 5
491
+ }, {
492
+ ...dependencies,
493
+ projectPath: projectRoot,
494
+ fileSystem
495
+ });
496
+ const projectChannelProjection = await buildProjectChannelProjection(projectRoot, {
497
+ preferredProjectIds: [record.projectChannelContext && record.projectChannelContext.contextProjectId, projectId, record.workspaceId],
498
+ channelId: requestedChannelId
499
+ }, {
500
+ fileSystem
501
+ });
502
+ const infoItems = semanticSharedSourceInfo.items;
503
+ const governanceItems = buildSupremeIntentGovernanceItems(supremeIntentGovernance);
504
+ const archiveItems = buildSemanticArchiveItems(semanticArchive);
505
+ const backflowItems = buildSemanticBackflowItems(semanticBackflow);
298
506
  const taskSummary = await collectSpecTaskSummary(projectRoot, fileSystem, taskClaimer);
299
- const items = [
507
+ const rawItems = [
300
508
  ...blockedItems,
301
509
  ...handoffItems,
302
510
  ...riskItems,
303
- ...activeItems
511
+ ...activeItems,
512
+ ...archiveItems,
513
+ ...backflowItems,
514
+ ...governanceItems,
515
+ ...infoItems
304
516
  ].sort((left, right) => `${right.updatedAt || ''}`.localeCompare(`${left.updatedAt || ''}`));
517
+ const actionProjection = buildSupervisionActionQueue(rawItems, { projectId });
518
+ const items = actionProjection.items;
305
519
  const latestEventAt = collectLatestTimestamp(items);
306
520
  const generatedAt = new Date().toISOString();
521
+ const summary = semanticSharedSourceInfo.projection.summary;
522
+ const partialReasons = Array.isArray(record.partialReasons) ? [...record.partialReasons] : [];
523
+ if (semanticSharedSourceInfo.projection.partial) {
524
+ partialReasons.push(...semanticSharedSourceInfo.projection.partialReasons);
525
+ }
526
+ if (projectChannelProjection.partial) {
527
+ partialReasons.push(...projectChannelProjection.partialReasons);
528
+ }
529
+ const resolvedChannel = projectChannelProjection.resolvedChannel;
307
530
 
308
531
  return {
309
532
  generatedAt,
310
533
  projectId,
534
+ ...(requestedChannelId ? { requestedChannelId } : {}),
311
535
  cursor: createCursor(projectId, latestEventAt || generatedAt, items.length),
312
536
  summary: {
313
537
  blockedCount: blockedItems.length,
314
538
  handoffCount: handoffItems.length,
315
539
  riskCount: riskItems.length,
540
+ infoCount: infoItems.length,
541
+ governanceHotspotCount: governanceItems.length,
542
+ archiveItemCount: archiveItems.length,
543
+ backflowItemCount: backflowItems.length,
316
544
  activeSceneCount: activeItems.length,
317
545
  activeSpecCount: taskSummary.activeSpecCount,
318
546
  activeTaskCount: taskSummary.activeTaskCount,
547
+ supremeIntentAssessmentCount: supremeIntentGovernance.totals.total,
548
+ supremeIntentGovernedCount: supremeIntentGovernance.totals.governed,
549
+ supremeIntentRewriteCount: supremeIntentGovernance.totals.rewrite,
550
+ supremeIntentRefuseCount: supremeIntentGovernance.totals.refuse,
551
+ supremeIntentGovernedRatePercent: supremeIntentGovernance.totals.governed_action_rate_percent,
552
+ archiveLibraryCount: semanticArchive.totals.library_count,
553
+ archiveMissingCount: semanticArchive.totals.missing_archive_count,
554
+ archiveExperienceLessonCount: Number(semanticArchive.by_library.find((item) => normalizeString(item.target_library) === 'experience-library')?.lesson_count || 0),
555
+ archiveOntologyCapabilityLessonCount: Number(semanticArchive.by_library.find((item) => normalizeString(item.target_library) === 'ontology-capability-library')?.lesson_count || 0),
556
+ archiveApplicationLessonCount: Number(semanticArchive.by_library.find((item) => normalizeString(item.target_library) === 'application-library')?.lesson_count || 0),
557
+ backflowLocalBlockedCount: semanticBackflow.totals.local_publish_blocked,
558
+ backflowCentralMergeBlockedCount: semanticBackflow.totals.central_merge_blocked,
559
+ backflowCentralReleaseBlockedCount: semanticBackflow.totals.central_release_blocked,
560
+ backflowBlockedSpecCount: semanticBackflow.totals.blocked_spec_count,
561
+ semanticSharedSourceApprovedCount: summary.approvedDescriptors,
562
+ semanticSharedSourceBlockedCount: summary.blockedDescriptors,
563
+ semanticSharedSourceConfiguredCount: summary.configuredSources,
564
+ semanticSharedSourceConnectedCount: summary.connectedApprovedDescriptors,
565
+ semanticSharedSourcePendingConnectCount: summary.pendingApprovedDescriptors,
566
+ projectChannelCount: projectChannelProjection.summary.channelCount,
567
+ highestSeverity: actionProjection.summary.highestSeverity,
568
+ actionableCount: actionProjection.summary.actionableCount,
569
+ criticalCount: actionProjection.summary.criticalCount,
570
+ highCount: actionProjection.summary.highCount,
571
+ mediumCount: actionProjection.summary.mediumCount,
572
+ lowCount: actionProjection.summary.lowCount,
573
+ ...(actionProjection.summary.primaryRecommendedCommand
574
+ ? { primaryRecommendedCommand: actionProjection.summary.primaryRecommendedCommand }
575
+ : {}),
576
+ ...(projectChannelProjection.summary.focusedChannelId
577
+ ? { focusedChannelId: projectChannelProjection.summary.focusedChannelId }
578
+ : {}),
319
579
  ...(latestEventAt ? { latestEventAt } : {})
320
580
  },
581
+ projectChannelContext: {
582
+ available: projectChannelProjection.summary.available,
583
+ contextProjectId: projectChannelProjection.summary.contextProjectId,
584
+ canonicalProjectIdMatched: projectChannelProjection.summary.canonicalProjectIdMatched,
585
+ focusedChannelId: projectChannelProjection.summary.focusedChannelId,
586
+ storageMode: projectChannelProjection.summary.storageMode,
587
+ channels: projectChannelProjection.channels
588
+ },
589
+ ...(resolvedChannel
590
+ ? {
591
+ projectChannel: buildProjectChannelOutputFromProjection(projectChannelProjection, {
592
+ canonicalProjectId: projectId,
593
+ requestedChannelId: requestedChannelId || null
594
+ })
595
+ }
596
+ : {}),
597
+ supremeIntent: {
598
+ totals: supremeIntentGovernance.totals,
599
+ topScopeHotspots: supremeIntentGovernance.top_scope_hotspots,
600
+ topMatchedRules: supremeIntentGovernance.top_matched_rules,
601
+ recentGovernedItems: supremeIntentGovernance.recent_governed_items
602
+ },
603
+ archive: {
604
+ totals: semanticArchive.totals,
605
+ byLibrary: semanticArchive.by_library,
606
+ byArchiveClass: semanticArchive.by_archive_class,
607
+ byReuseScope: semanticArchive.by_reuse_scope,
608
+ recentItems: semanticArchive.recent_items
609
+ },
610
+ backflow: {
611
+ totals: semanticBackflow.totals,
612
+ blockedSpecIds: semanticBackflow.blocked_spec_ids,
613
+ localBlockedByReason: semanticBackflow.local.blocked_by_reason,
614
+ recentLocalBlockedItems: semanticBackflow.local.recent_blocked_items,
615
+ centralMergeBlockedByReason: semanticBackflow.central_merge.blocked_by_reason,
616
+ recentCentralMergeReceipts: semanticBackflow.central_merge.receipts,
617
+ centralReleaseBlockedByReason: semanticBackflow.central_release.blocked_by_reason,
618
+ recentCentralReleaseReceipts: semanticBackflow.central_release.receipts
619
+ },
620
+ actionQueue: actionProjection.actionQueue,
321
621
  items,
322
- partial: record.partial === true,
323
- partialReasons: Array.isArray(record.partialReasons) ? record.partialReasons : []
622
+ partial: record.partial === true || semanticSharedSourceInfo.projection.partial || projectChannelProjection.partial,
623
+ partialReasons: Array.from(new Set(partialReasons))
324
624
  };
325
625
  }
326
626