scene-capability-engine 3.6.65 → 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.
- package/CHANGELOG.md +16 -0
- package/README.md +17 -6
- package/README.zh.md +18 -6
- package/bin/scene-capability-engine.js +4 -0
- package/docs/README.md +2 -2
- package/docs/command-reference.md +382 -6
- package/docs/document-governance.md +3 -2
- package/docs/integration-modes.md +62 -478
- package/docs/integration-philosophy.md +56 -263
- package/docs/magicball-project-portfolio-contract.md +114 -2
- package/docs/project-management/README.md +14 -0
- package/docs/project-management/assurance/backup.md +3 -0
- package/docs/project-management/assurance/config.md +3 -0
- package/docs/project-management/assurance/evidence/README.md +3 -0
- package/docs/project-management/assurance/incidents/README.md +3 -0
- package/docs/project-management/assurance/logs.md +3 -0
- package/docs/project-management/assurance/overview.md +3 -0
- package/docs/project-management/assurance/recovery/README.md +3 -0
- package/docs/project-management/assurance/resource.md +3 -0
- package/docs/project-management/assurance/runbooks/README.md +3 -0
- package/docs/project-management/delivery/acceptance/README.md +3 -0
- package/docs/project-management/delivery/acceptance/evidence/README.md +3 -0
- package/docs/project-management/delivery/acceptance/exceptions/README.md +3 -0
- package/docs/project-management/delivery/acceptance/reports/README.md +3 -0
- package/docs/project-management/delivery/documents/changes.md +3 -0
- package/docs/project-management/delivery/documents/issues.md +3 -0
- package/docs/project-management/delivery/documents/overview.md +3 -0
- package/docs/project-management/delivery/documents/planning.md +3 -0
- package/docs/project-management/delivery/documents/requirements.md +3 -0
- package/docs/project-management/delivery/documents/tracking.md +3 -0
- package/docs/project-management/delivery/handoffs/README.md +3 -0
- package/docs/project-management/delivery/handoffs/evidence/README.md +3 -0
- package/docs/project-management/delivery/handoffs/records/README.md +3 -0
- package/docs/project-management/delivery/overview.md +10 -0
- package/docs/project-management/delivery/releases/README.md +3 -0
- package/docs/project-management/delivery/releases/baselines/README.md +3 -0
- package/docs/project-management/delivery/releases/evidence/README.md +3 -0
- package/docs/project-management/delivery/tables/changes.md +3 -0
- package/docs/project-management/delivery/tables/issues.md +3 -0
- package/docs/project-management/delivery/tables/planning.md +3 -0
- package/docs/project-management/delivery/tables/requirements.md +3 -0
- package/docs/project-management/delivery/tables/tracking.md +3 -0
- package/docs/project-management/environment/agent-discovery.md +3 -0
- package/docs/project-management/environment/development.md +3 -0
- package/docs/project-management/environment/overview.md +10 -0
- package/docs/project-management/environment/testing.md +3 -0
- package/docs/project-management/environment/version-alignment.md +3 -0
- package/docs/quick-start-with-ai-tools.md +68 -308
- package/docs/releases/README.md +2 -0
- package/docs/releases/v3.6.66.md +23 -0
- package/docs/releases/v3.6.67.md +23 -0
- package/docs/steering-governance.md +64 -2
- package/docs/zh/README.md +2 -2
- package/docs/zh/releases/README.md +2 -0
- package/docs/zh/releases/v3.6.66.md +23 -0
- package/docs/zh/releases/v3.6.67.md +23 -0
- package/lib/commands/adopt.js +24 -0
- package/lib/commands/native.js +158 -0
- package/lib/commands/project.js +95 -0
- package/lib/commands/semantic.js +1459 -0
- package/lib/commands/session.js +74 -3
- package/lib/commands/spec-bootstrap.js +10 -1
- package/lib/commands/spec-gate.js +10 -1
- package/lib/commands/spec-pipeline.js +10 -1
- package/lib/commands/studio.js +405 -30
- package/lib/commands/task.js +141 -7
- package/lib/governance/supreme-principles.js +530 -0
- package/lib/problem/problem-evaluator.js +4 -0
- package/lib/project/candidate-inspection-service.js +24 -1
- package/lib/project/portfolio-projection-service.js +315 -5
- package/lib/project/project-channel-output.js +94 -0
- package/lib/project/project-channel-projection.js +181 -0
- package/lib/project/root-onboarding-service.js +60 -8
- package/lib/project/semantic-shared-source-projection.js +150 -0
- package/lib/project/supervision-action-model.js +277 -0
- package/lib/project/supervision-projection-service.js +305 -5
- package/lib/project/target-resolution-service.js +70 -5
- package/lib/project/visibility-policy.js +93 -0
- package/lib/runtime/multi-spec-scene-session.js +8 -1
- package/lib/runtime/project-channel-context-store.js +387 -0
- package/lib/runtime/project-channel-context.js +406 -0
- package/lib/runtime/scene-session-binding.js +46 -0
- package/lib/runtime/session-store.js +186 -0
- package/lib/runtime/steering-contract.js +7 -1
- package/lib/semantic/archive-report.js +283 -0
- package/lib/semantic/archive-routing.js +67 -0
- package/lib/semantic/backflow-report.js +245 -0
- package/lib/semantic/capability-contract.js +30 -0
- package/lib/semantic/delta-export.js +145 -0
- package/lib/semantic/interaction-observer.js +254 -0
- package/lib/semantic/kernel-loader.js +881 -0
- package/lib/semantic/native-runtime.js +359 -0
- package/lib/semantic/progress-ledger.js +433 -0
- package/lib/semantic/replay-evaluator.js +382 -0
- package/lib/semantic/shared-publication.js +592 -0
- package/lib/semantic/shared-source-config.js +183 -0
- package/lib/semantic/shared-source-connect.js +139 -0
- package/lib/semantic/shared-source-discovery.js +98 -0
- package/lib/semantic/shared-sync-export.js +413 -0
- package/lib/semantic/shared-sync-intake.js +592 -0
- package/lib/semantic/shared-sync-merge.js +547 -0
- package/lib/semantic/shared-sync-release.js +463 -0
- package/lib/semantic/supreme-intent-report.js +300 -0
- package/lib/state/sce-state-store.js +1360 -0
- package/lib/steering/context-sync-manager.js +276 -25
- package/lib/studio/spec-intake-governor.js +39 -3
- package/lib/studio/task-envelope.js +35 -2
- package/lib/workspace/takeover-baseline.js +342 -83
- package/package.json +7 -2
- package/scripts/agent-governance-baseline-audit.js +395 -0
- package/scripts/clarification-first-audit.js +9 -9
- package/scripts/deprecated-entry-audit.js +240 -0
- package/scripts/release-posture-report.js +262 -0
- package/template/.sce/README.md +62 -228
- package/template/.sce/config/semantic-shared-sources.json +5 -0
- package/template/.sce/config/supreme-principles-policy.json +105 -0
- package/template/.sce/config/takeover-baseline.json +7 -0
- package/template/.sce/steering/CORE_PRINCIPLES.md +23 -63
- package/template/.sce/steering/CURRENT_CONTEXT.md +4 -0
- package/template/.sce/steering/RULES_GUIDE.md +17 -9
- 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
|
|
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.
|
|
622
|
+
partial: record.partial === true || semanticSharedSourceInfo.projection.partial || projectChannelProjection.partial,
|
|
623
|
+
partialReasons: Array.from(new Set(partialReasons))
|
|
324
624
|
};
|
|
325
625
|
}
|
|
326
626
|
|