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,463 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const http = require('http');
|
|
3
|
+
const https = require('https');
|
|
4
|
+
const fs = require('fs-extra');
|
|
5
|
+
const {
|
|
6
|
+
SEMANTIC_SHARED_SYNC_BUNDLE_API_VERSION,
|
|
7
|
+
SEMANTIC_SHARED_SYNC_INDEX_API_VERSION,
|
|
8
|
+
SEMANTIC_SHARED_SYNC_SHARD_API_VERSION
|
|
9
|
+
} = require('./shared-sync-export');
|
|
10
|
+
|
|
11
|
+
const SEMANTIC_SHARED_SYNC_RELEASE_RECEIPT_API_VERSION = 'sce.semantic.shared-sync.release-receipt/v0.1';
|
|
12
|
+
const SEMANTIC_SHARED_SOURCE_DESCRIPTOR_API_VERSION = 'sce.semantic.shared-source-descriptor/v0.1';
|
|
13
|
+
|
|
14
|
+
function normalizeString(value) {
|
|
15
|
+
if (typeof value !== 'string') {
|
|
16
|
+
return '';
|
|
17
|
+
}
|
|
18
|
+
return value.trim();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function normalizeInteger(value, fallback = 0) {
|
|
22
|
+
const parsed = Number.parseInt(`${value}`, 10);
|
|
23
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
24
|
+
return fallback;
|
|
25
|
+
}
|
|
26
|
+
return parsed;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function normalizeBoolean(value, fallback = false) {
|
|
30
|
+
if (typeof value === 'boolean') {
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
const normalized = normalizeString(`${value || ''}`).toLowerCase();
|
|
34
|
+
if (!normalized) {
|
|
35
|
+
return fallback;
|
|
36
|
+
}
|
|
37
|
+
if (['1', 'true', 'yes', 'y', 'on'].includes(normalized)) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
if (['0', 'false', 'no', 'n', 'off'].includes(normalized)) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
return fallback;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function isObject(value) {
|
|
47
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function isHttpSource(source = '') {
|
|
51
|
+
return /^https?:\/\//i.test(normalizeString(source));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function inferSourceRootFromSource(source = '') {
|
|
55
|
+
const normalized = normalizeString(source);
|
|
56
|
+
if (!normalized) {
|
|
57
|
+
return '';
|
|
58
|
+
}
|
|
59
|
+
if (isHttpSource(normalized)) {
|
|
60
|
+
const sceMarkerIndex = normalized.indexOf('/.sce/');
|
|
61
|
+
if (sceMarkerIndex > 0) {
|
|
62
|
+
return normalized.slice(0, sceMarkerIndex);
|
|
63
|
+
}
|
|
64
|
+
return normalizeString(normalized.replace(/\/[^/]*$/, ''));
|
|
65
|
+
}
|
|
66
|
+
const normalizedPath = path.resolve(normalized);
|
|
67
|
+
const marker = `${path.sep}.sce${path.sep}`;
|
|
68
|
+
const markerIndex = normalizedPath.indexOf(marker);
|
|
69
|
+
if (markerIndex > -1) {
|
|
70
|
+
return normalizedPath.slice(0, markerIndex);
|
|
71
|
+
}
|
|
72
|
+
return path.dirname(normalizedPath);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function toProjectRelative(projectPath, targetPath) {
|
|
76
|
+
return path.relative(projectPath, targetPath).replace(/\\/g, '/');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function resolveDefaultSemanticSharedPublishedBaseDir(specId = '') {
|
|
80
|
+
const normalizedSpecId = normalizeString(specId);
|
|
81
|
+
if (!normalizedSpecId) {
|
|
82
|
+
return '';
|
|
83
|
+
}
|
|
84
|
+
return `.sce/specs/${normalizedSpecId}/registry/semantic-shared/published`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function resolveDefaultSemanticSharedPublishedBundleOutFile(specId = '') {
|
|
88
|
+
const baseDir = resolveDefaultSemanticSharedPublishedBaseDir(specId);
|
|
89
|
+
return baseDir ? `${baseDir}/latest.bundle.json` : '';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function resolveDefaultSemanticSharedPublishedIndexOutFile(specId = '') {
|
|
93
|
+
const baseDir = resolveDefaultSemanticSharedPublishedBaseDir(specId);
|
|
94
|
+
return baseDir ? `${baseDir}/latest.index.json` : '';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function resolveDefaultSemanticSharedPublishedReceiptOutFile(specId = '') {
|
|
98
|
+
const baseDir = resolveDefaultSemanticSharedPublishedBaseDir(specId);
|
|
99
|
+
return baseDir ? `${baseDir}/latest.receipt.json` : '';
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function resolveDefaultSemanticSharedPublishedSourceDescriptorOutFile(specId = '') {
|
|
103
|
+
const baseDir = resolveDefaultSemanticSharedPublishedBaseDir(specId);
|
|
104
|
+
return baseDir ? `${baseDir}/source-descriptor.json` : '';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function resolveDefaultSemanticSharedPublishedShardOutFile(specId = '', targetLibrary = '') {
|
|
108
|
+
const baseDir = resolveDefaultSemanticSharedPublishedBaseDir(specId);
|
|
109
|
+
const normalizedLibrary = normalizeString(targetLibrary);
|
|
110
|
+
return baseDir && normalizedLibrary
|
|
111
|
+
? `${baseDir}/shards/${normalizedLibrary}.json`
|
|
112
|
+
: '';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function fetchJsonFromHttp(source, timeoutMs = 15000) {
|
|
116
|
+
const normalized = normalizeString(source);
|
|
117
|
+
if (!normalized) {
|
|
118
|
+
return Promise.reject(new Error('shared release source is required'));
|
|
119
|
+
}
|
|
120
|
+
const client = normalized.startsWith('https://') ? https : http;
|
|
121
|
+
return new Promise((resolve, reject) => {
|
|
122
|
+
const request = client.get(normalized, {
|
|
123
|
+
timeout: timeoutMs,
|
|
124
|
+
headers: {
|
|
125
|
+
Accept: 'application/json'
|
|
126
|
+
}
|
|
127
|
+
}, (response) => {
|
|
128
|
+
const chunks = [];
|
|
129
|
+
response.on('data', (chunk) => chunks.push(chunk));
|
|
130
|
+
response.on('end', () => {
|
|
131
|
+
const body = Buffer.concat(chunks).toString('utf8');
|
|
132
|
+
if (response.statusCode < 200 || response.statusCode >= 300) {
|
|
133
|
+
reject(new Error(`shared release source responded ${response.statusCode}`));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
resolve(JSON.parse(body));
|
|
138
|
+
} catch (error) {
|
|
139
|
+
reject(new Error(`shared release source returned invalid JSON: ${error.message}`));
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
request.on('timeout', () => {
|
|
144
|
+
request.destroy(new Error('shared release source request timed out'));
|
|
145
|
+
});
|
|
146
|
+
request.on('error', reject);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async function loadJsonSource(projectPath, source, fileSystem = fs) {
|
|
151
|
+
const normalized = normalizeString(source);
|
|
152
|
+
if (!normalized) {
|
|
153
|
+
throw new Error('shared release source is required');
|
|
154
|
+
}
|
|
155
|
+
if (isHttpSource(normalized)) {
|
|
156
|
+
return fetchJsonFromHttp(normalized);
|
|
157
|
+
}
|
|
158
|
+
const absolutePath = path.isAbsolute(normalized)
|
|
159
|
+
? normalized
|
|
160
|
+
: path.resolve(projectPath, normalized);
|
|
161
|
+
if (!await fileSystem.pathExists(absolutePath)) {
|
|
162
|
+
throw new Error(`shared release source file not found: ${source}`);
|
|
163
|
+
}
|
|
164
|
+
return fileSystem.readJson(absolutePath);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function resolveCandidateShardSource(projectPath, bundleSource, shardFile) {
|
|
168
|
+
const normalizedShardFile = normalizeString(shardFile);
|
|
169
|
+
if (!normalizedShardFile) {
|
|
170
|
+
return '';
|
|
171
|
+
}
|
|
172
|
+
if (isHttpSource(normalizedShardFile) || path.isAbsolute(normalizedShardFile)) {
|
|
173
|
+
return normalizedShardFile;
|
|
174
|
+
}
|
|
175
|
+
if (/^\.sce[\\/]/i.test(normalizedShardFile)) {
|
|
176
|
+
const sourceRoot = inferSourceRootFromSource(path.isAbsolute(bundleSource) ? bundleSource : path.resolve(projectPath, bundleSource));
|
|
177
|
+
if (isHttpSource(sourceRoot)) {
|
|
178
|
+
return `${sourceRoot.replace(/\/+$/, '')}/${normalizedShardFile.replace(/^\/+/, '')}`;
|
|
179
|
+
}
|
|
180
|
+
if (sourceRoot) {
|
|
181
|
+
return path.resolve(sourceRoot, normalizedShardFile);
|
|
182
|
+
}
|
|
183
|
+
return path.resolve(projectPath, normalizedShardFile);
|
|
184
|
+
}
|
|
185
|
+
if (isHttpSource(bundleSource)) {
|
|
186
|
+
return new URL(normalizedShardFile, bundleSource).toString();
|
|
187
|
+
}
|
|
188
|
+
const bundleDir = path.dirname(path.isAbsolute(bundleSource) ? bundleSource : path.resolve(projectPath, bundleSource));
|
|
189
|
+
return path.resolve(bundleDir, normalizedShardFile);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function assessApprovedCentralEntryGate(entry = {}) {
|
|
193
|
+
const publication = isObject(entry.publication) ? entry.publication : {};
|
|
194
|
+
const publishState = normalizeString(publication.publish_state);
|
|
195
|
+
const blockedReason = normalizeString(publication.blocked_reason);
|
|
196
|
+
const blockedGate = isObject(publication.blocked_gate) ? publication.blocked_gate : null;
|
|
197
|
+
const reasons = [];
|
|
198
|
+
|
|
199
|
+
if (publishState && publishState !== 'published-shared') {
|
|
200
|
+
reasons.push({
|
|
201
|
+
reason: 'entry-not-shared-ready',
|
|
202
|
+
publish_state: publishState
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
if (blockedReason) {
|
|
206
|
+
reasons.push({
|
|
207
|
+
reason: 'entry-has-blocked-reason',
|
|
208
|
+
blocked_reason: blockedReason
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
if (blockedGate) {
|
|
212
|
+
reasons.push({
|
|
213
|
+
reason: 'entry-has-blocked-gate',
|
|
214
|
+
blocked_gate: blockedGate
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return {
|
|
219
|
+
allowed: reasons.length === 0,
|
|
220
|
+
reasons
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async function publishSemanticSharedRegistry(options = {}, dependencies = {}) {
|
|
225
|
+
const projectPath = dependencies.projectPath || process.cwd();
|
|
226
|
+
const fileSystem = dependencies.fileSystem || fs;
|
|
227
|
+
const specId = normalizeString(options.spec);
|
|
228
|
+
const inputFile = normalizeString(options.inputFile || options.input_file)
|
|
229
|
+
|| (specId ? `.sce/specs/${specId}/registry/semantic-shared/latest.bundle.json` : '');
|
|
230
|
+
if (!inputFile) {
|
|
231
|
+
throw new Error('candidate bundle source is required (use --input-file or provide --spec)');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const candidateBundle = await loadJsonSource(projectPath, inputFile, fileSystem);
|
|
235
|
+
if (!isObject(candidateBundle) || normalizeString(candidateBundle.api_version) !== SEMANTIC_SHARED_SYNC_BUNDLE_API_VERSION) {
|
|
236
|
+
throw new Error(`invalid semantic shared candidate bundle: ${inputFile}`);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const minSources = normalizeInteger(options.minSources || options.min_sources, 1);
|
|
240
|
+
const minEntries = normalizeInteger(options.minEntries || options.min_entries, 1);
|
|
241
|
+
const requireZeroBlocked = normalizeBoolean(options.requireZeroBlocked ?? options.require_zero_blocked, true);
|
|
242
|
+
const generatedAt = new Date().toISOString();
|
|
243
|
+
const blocked = [];
|
|
244
|
+
|
|
245
|
+
const totals = isObject(candidateBundle.totals) ? candidateBundle.totals : {};
|
|
246
|
+
const sourceReports = Array.isArray(candidateBundle.sources) ? candidateBundle.sources : [];
|
|
247
|
+
const libraries = Array.isArray(candidateBundle.libraries) ? candidateBundle.libraries : [];
|
|
248
|
+
|
|
249
|
+
if (sourceReports.length < minSources) {
|
|
250
|
+
blocked.push({
|
|
251
|
+
reason: 'insufficient-sources',
|
|
252
|
+
required_sources: minSources,
|
|
253
|
+
actual_sources: sourceReports.length
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
if (normalizeInteger(totals.merged_entries, 0) < minEntries) {
|
|
257
|
+
blocked.push({
|
|
258
|
+
reason: 'insufficient-merged-entries',
|
|
259
|
+
required_entries: minEntries,
|
|
260
|
+
actual_entries: normalizeInteger(totals.merged_entries, 0)
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
if (requireZeroBlocked && normalizeInteger(totals.blocked, 0) > 0) {
|
|
264
|
+
blocked.push({
|
|
265
|
+
reason: 'candidate-has-blocked-entries',
|
|
266
|
+
blocked_entries: normalizeInteger(totals.blocked, 0)
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const publishedLibraries = [];
|
|
271
|
+
const publishedIndexShards = {};
|
|
272
|
+
for (const library of libraries) {
|
|
273
|
+
const targetLibrary = normalizeString(library && library.target_library);
|
|
274
|
+
const publishedShardFile = resolveDefaultSemanticSharedPublishedShardOutFile(specId, targetLibrary);
|
|
275
|
+
const candidateShardSource = resolveCandidateShardSource(projectPath, inputFile, normalizeString(library && library.shard_file));
|
|
276
|
+
let shardPayload = {
|
|
277
|
+
api_version: SEMANTIC_SHARED_SYNC_SHARD_API_VERSION,
|
|
278
|
+
generated_at: generatedAt,
|
|
279
|
+
target_library: targetLibrary,
|
|
280
|
+
total_entries: 0,
|
|
281
|
+
entries: []
|
|
282
|
+
};
|
|
283
|
+
if (candidateShardSource) {
|
|
284
|
+
const loadedShard = await loadJsonSource(projectPath, candidateShardSource, fileSystem);
|
|
285
|
+
if (isObject(loadedShard) && normalizeString(loadedShard.api_version) === SEMANTIC_SHARED_SYNC_SHARD_API_VERSION) {
|
|
286
|
+
const shardEntries = Array.isArray(loadedShard.entries) ? loadedShard.entries : [];
|
|
287
|
+
const shardBlockedEntries = [];
|
|
288
|
+
for (const entry of shardEntries) {
|
|
289
|
+
const gate = assessApprovedCentralEntryGate(entry);
|
|
290
|
+
if (!gate.allowed) {
|
|
291
|
+
shardBlockedEntries.push({
|
|
292
|
+
capability_id: normalizeString(entry && entry.capability_id) || null,
|
|
293
|
+
lesson_id: normalizeString(entry && entry.lesson_id) || null,
|
|
294
|
+
target_library: targetLibrary || normalizeString(entry && entry.target_library) || null,
|
|
295
|
+
reason: 'entry-failed-approved-central-gate',
|
|
296
|
+
gate
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (shardBlockedEntries.length > 0) {
|
|
301
|
+
blocked.push(...shardBlockedEntries);
|
|
302
|
+
}
|
|
303
|
+
shardPayload = {
|
|
304
|
+
...loadedShard,
|
|
305
|
+
generated_at: generatedAt,
|
|
306
|
+
publication: {
|
|
307
|
+
publish_state: blocked.length === 0 ? 'approved-central' : 'publish-blocked',
|
|
308
|
+
source_bundle: inputFile
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
if (publishedShardFile) {
|
|
314
|
+
const absoluteShardPath = path.join(projectPath, publishedShardFile);
|
|
315
|
+
await fileSystem.ensureDir(path.dirname(absoluteShardPath));
|
|
316
|
+
await fileSystem.writeJson(absoluteShardPath, shardPayload, { spaces: 2 });
|
|
317
|
+
}
|
|
318
|
+
publishedLibraries.push({
|
|
319
|
+
target_library: targetLibrary,
|
|
320
|
+
shard_file: publishedShardFile || null,
|
|
321
|
+
entry_count: normalizeInteger(shardPayload.total_entries, 0),
|
|
322
|
+
latest_published_at: normalizeString(library && library.latest_published_at) || null
|
|
323
|
+
});
|
|
324
|
+
publishedIndexShards[targetLibrary] = {
|
|
325
|
+
shard_file: publishedShardFile || null,
|
|
326
|
+
entry_count: normalizeInteger(shardPayload.total_entries, 0),
|
|
327
|
+
latest_published_at: normalizeString(library && library.latest_published_at) || null
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const success = blocked.length === 0;
|
|
332
|
+
const bundlePayload = {
|
|
333
|
+
api_version: SEMANTIC_SHARED_SYNC_BUNDLE_API_VERSION,
|
|
334
|
+
mode: 'semantic-publish-shared-registry',
|
|
335
|
+
success,
|
|
336
|
+
generated_at: generatedAt,
|
|
337
|
+
spec_id: specId || normalizeString(candidateBundle.spec_id) || null,
|
|
338
|
+
mirror_root: normalizeString(candidateBundle.mirror_root) || '.sce/knowledge/semantic-shared',
|
|
339
|
+
governance: {
|
|
340
|
+
release_state: success ? 'approved-central' : 'publish-blocked',
|
|
341
|
+
candidate_bundle: normalizeString(inputFile),
|
|
342
|
+
min_sources: minSources,
|
|
343
|
+
min_entries: minEntries,
|
|
344
|
+
require_zero_blocked: requireZeroBlocked
|
|
345
|
+
},
|
|
346
|
+
totals: {
|
|
347
|
+
sources: sourceReports.length,
|
|
348
|
+
merged_entries: normalizeInteger(totals.merged_entries, 0),
|
|
349
|
+
superseded: normalizeInteger(totals.superseded, 0),
|
|
350
|
+
blocked: blocked.length
|
|
351
|
+
},
|
|
352
|
+
sources: sourceReports,
|
|
353
|
+
libraries: publishedLibraries,
|
|
354
|
+
blocked
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
const bundleOutFile = normalizeString(options.outFile || options.out_file)
|
|
358
|
+
|| resolveDefaultSemanticSharedPublishedBundleOutFile(specId);
|
|
359
|
+
const indexOutFile = normalizeString(options.indexFile || options.index_file)
|
|
360
|
+
|| resolveDefaultSemanticSharedPublishedIndexOutFile(specId);
|
|
361
|
+
const receiptOutFile = normalizeString(options.receiptFile || options.receipt_file)
|
|
362
|
+
|| resolveDefaultSemanticSharedPublishedReceiptOutFile(specId);
|
|
363
|
+
const sourceDescriptorOutFile = normalizeString(options.sourceDescriptorFile || options.source_descriptor_file)
|
|
364
|
+
|| resolveDefaultSemanticSharedPublishedSourceDescriptorOutFile(specId);
|
|
365
|
+
const sourceName = normalizeString(options.sourceName || options.source_name) || 'central';
|
|
366
|
+
const publicBundle = normalizeString(options.publicBundle || options.public_bundle);
|
|
367
|
+
const publicRoot = normalizeString(options.publicRoot || options.public_root);
|
|
368
|
+
|
|
369
|
+
const indexPayload = {
|
|
370
|
+
api_version: SEMANTIC_SHARED_SYNC_INDEX_API_VERSION,
|
|
371
|
+
generated_at: generatedAt,
|
|
372
|
+
spec_id: specId || normalizeString(candidateBundle.spec_id) || null,
|
|
373
|
+
bundle_file: bundleOutFile || null,
|
|
374
|
+
shard_count: publishedLibraries.length,
|
|
375
|
+
shards: publishedIndexShards
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
const receiptPayload = {
|
|
379
|
+
api_version: SEMANTIC_SHARED_SYNC_RELEASE_RECEIPT_API_VERSION,
|
|
380
|
+
mode: 'semantic-publish-shared-registry',
|
|
381
|
+
success,
|
|
382
|
+
generated_at: generatedAt,
|
|
383
|
+
spec_id: specId || normalizeString(candidateBundle.spec_id) || null,
|
|
384
|
+
candidate_bundle: normalizeString(inputFile),
|
|
385
|
+
governance: bundlePayload.governance,
|
|
386
|
+
totals: bundlePayload.totals,
|
|
387
|
+
libraries: publishedLibraries,
|
|
388
|
+
blocked
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
let absoluteBundlePath = '';
|
|
392
|
+
if (bundleOutFile) {
|
|
393
|
+
absoluteBundlePath = path.isAbsolute(bundleOutFile)
|
|
394
|
+
? bundleOutFile
|
|
395
|
+
: path.join(projectPath, bundleOutFile);
|
|
396
|
+
await fileSystem.ensureDir(path.dirname(absoluteBundlePath));
|
|
397
|
+
await fileSystem.writeJson(absoluteBundlePath, bundlePayload, { spaces: 2 });
|
|
398
|
+
bundlePayload.out_file = toProjectRelative(projectPath, absoluteBundlePath);
|
|
399
|
+
}
|
|
400
|
+
if (indexOutFile) {
|
|
401
|
+
const absoluteIndexPath = path.isAbsolute(indexOutFile)
|
|
402
|
+
? indexOutFile
|
|
403
|
+
: path.join(projectPath, indexOutFile);
|
|
404
|
+
await fileSystem.ensureDir(path.dirname(absoluteIndexPath));
|
|
405
|
+
await fileSystem.writeJson(absoluteIndexPath, indexPayload, { spaces: 2 });
|
|
406
|
+
}
|
|
407
|
+
if (receiptOutFile) {
|
|
408
|
+
const absoluteReceiptPath = path.isAbsolute(receiptOutFile)
|
|
409
|
+
? receiptOutFile
|
|
410
|
+
: path.join(projectPath, receiptOutFile);
|
|
411
|
+
await fileSystem.ensureDir(path.dirname(absoluteReceiptPath));
|
|
412
|
+
await fileSystem.writeJson(absoluteReceiptPath, receiptPayload, { spaces: 2 });
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
let sourceDescriptor = null;
|
|
416
|
+
if (sourceDescriptorOutFile) {
|
|
417
|
+
const absoluteDescriptorPath = path.isAbsolute(sourceDescriptorOutFile)
|
|
418
|
+
? sourceDescriptorOutFile
|
|
419
|
+
: path.join(projectPath, sourceDescriptorOutFile);
|
|
420
|
+
const sourceBundle = publicBundle || absoluteBundlePath || bundlePayload.out_file || bundleOutFile || null;
|
|
421
|
+
const inferredRoot = publicRoot || inferSourceRootFromSource(sourceBundle || '');
|
|
422
|
+
sourceDescriptor = {
|
|
423
|
+
api_version: SEMANTIC_SHARED_SOURCE_DESCRIPTOR_API_VERSION,
|
|
424
|
+
mode: 'semantic-shared-source-descriptor',
|
|
425
|
+
generated_at: generatedAt,
|
|
426
|
+
spec_id: specId || normalizeString(candidateBundle.spec_id) || null,
|
|
427
|
+
source: {
|
|
428
|
+
name: sourceName,
|
|
429
|
+
enabled: true,
|
|
430
|
+
bundle: sourceBundle,
|
|
431
|
+
root: inferredRoot || null,
|
|
432
|
+
required_release_state: success ? 'approved-central' : 'publish-blocked'
|
|
433
|
+
},
|
|
434
|
+
publication: {
|
|
435
|
+
release_state: bundlePayload.governance.release_state,
|
|
436
|
+
bundle_file: bundlePayload.out_file || bundleOutFile || null,
|
|
437
|
+
receipt_file: receiptOutFile || null
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
await fileSystem.ensureDir(path.dirname(absoluteDescriptorPath));
|
|
441
|
+
await fileSystem.writeJson(absoluteDescriptorPath, sourceDescriptor, { spaces: 2 });
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return {
|
|
445
|
+
...receiptPayload,
|
|
446
|
+
out_file: bundlePayload.out_file || bundleOutFile || null,
|
|
447
|
+
index_file: indexOutFile || null,
|
|
448
|
+
receipt_file: receiptOutFile || null,
|
|
449
|
+
source_descriptor_file: sourceDescriptorOutFile || null,
|
|
450
|
+
source_descriptor: sourceDescriptor
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
module.exports = {
|
|
455
|
+
SEMANTIC_SHARED_SYNC_RELEASE_RECEIPT_API_VERSION,
|
|
456
|
+
SEMANTIC_SHARED_SOURCE_DESCRIPTOR_API_VERSION,
|
|
457
|
+
resolveDefaultSemanticSharedPublishedBundleOutFile,
|
|
458
|
+
resolveDefaultSemanticSharedPublishedIndexOutFile,
|
|
459
|
+
resolveDefaultSemanticSharedPublishedReceiptOutFile,
|
|
460
|
+
resolveDefaultSemanticSharedPublishedSourceDescriptorOutFile,
|
|
461
|
+
resolveDefaultSemanticSharedPublishedShardOutFile,
|
|
462
|
+
publishSemanticSharedRegistry
|
|
463
|
+
};
|