sneakoscope 3.0.1 → 3.0.3
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/README.md +1 -1
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/.sks-build-stamp.json +4 -4
- package/dist/bin/sks.js +1 -1
- package/dist/core/agents/agent-message-bus.js +89 -2
- package/dist/core/agents/runtime-proof-summary.js +46 -2
- package/dist/core/codex/codex-cli-syntax-builder.js +4 -1
- package/dist/core/codex-control/codex-0139-capability.js +68 -12
- package/dist/core/codex-control/codex-multi-agent-event-normalizer.js +15 -0
- package/dist/core/codex-control/codex-tool-schema-fixtures.js +57 -0
- package/dist/core/commands/naruto-command.js +9 -4
- package/dist/core/fsx.js +1 -1
- package/dist/core/mcp/mcp-0-134-policy.js +3 -0
- package/dist/core/pipeline-internals/runtime-core.js +6 -1
- package/dist/core/release/release-cache-key.js +128 -0
- package/dist/core/release/release-gate-cache-v2.js +6 -7
- package/dist/core/release/release-proof-truth.js +63 -0
- package/dist/core/safety/side-effect-runtime-report.js +19 -4
- package/dist/core/version.js +1 -1
- package/dist/core/zellij/zellij-capability.js +41 -0
- package/dist/core/zellij/zellij-command.js +14 -2
- package/dist/core/zellij/zellij-fake-adapter.js +163 -0
- package/dist/core/zellij/zellij-update.js +28 -3
- package/dist/core/zellij/zellij-worker-pane-manager.js +116 -5
- package/dist/core/zellij/zellij-worker-pane-summary.js +65 -0
- package/dist/scripts/github-release-body-helper.js +63 -0
- package/dist/scripts/release-speed-summary.js +11 -0
- package/package.json +33 -2
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { appendJsonl, ensureDir, nowIso, packageRoot, readJson, writeJsonAtomic } from '../fsx.js';
|
|
3
|
+
import { appendParallelRuntimeEvent } from '../agents/parallel-runtime-proof.js';
|
|
3
4
|
import { providerPaneLabel } from '../provider/provider-badge.js';
|
|
4
5
|
import { resolveProviderContext } from '../provider/provider-context.js';
|
|
6
|
+
import { checkZellijStackedPaneCapability } from './zellij-capability.js';
|
|
5
7
|
import { runZellij } from './zellij-command.js';
|
|
6
8
|
import { extractZellijPaneIdFromOutput } from './zellij-lane-runtime.js';
|
|
7
9
|
import { buildZellijSlotColumnAnchorCommand } from './zellij-slot-column-anchor.js';
|
|
8
10
|
import { closeWorkerInRightColumn, prepareWorkerInRightColumn, readRightColumnState, recordSlotColumnAnchorInRightColumn, recordWorkerPaneInRightColumn } from './zellij-right-column-manager.js';
|
|
9
11
|
export const ZELLIJ_WORKER_PANE_SCHEMA = 'sks.zellij-worker-pane.v1';
|
|
10
12
|
export const ZELLIJ_WORKER_PANE_EVENT_SCHEMA = 'sks.zellij-worker-pane-event.v1';
|
|
13
|
+
export const ZELLIJ_PANE_CREATION_LOCK_METRICS_SCHEMA = 'sks.zellij-pane-creation-lock-metrics.v1';
|
|
11
14
|
export function buildWorkerPaneName(slotId, generationIndex) {
|
|
12
15
|
return `${slotId}/gen-${Math.max(1, Math.floor(Number(generationIndex) || 1))}`;
|
|
13
16
|
}
|
|
@@ -77,12 +80,15 @@ export function buildWorkerPaneArtifact(input) {
|
|
|
77
80
|
worker_direction_applied: input.workerDirectionApplied || (directionApplied === 'down' ? 'down' : directionApplied === 'unknown' ? 'unknown' : 'not_applied'),
|
|
78
81
|
worker_stacked_requested: input.stackedRequested === true,
|
|
79
82
|
worker_stacked_applied: input.stackedApplied === true,
|
|
83
|
+
worker_stacked_fallback_mode: input.stackedFallbackMode || null,
|
|
84
|
+
worker_stacked_capability: input.stackedCapability || null,
|
|
80
85
|
slot_column_anchor_pane_id: input.slotColumnAnchorPaneId || null,
|
|
81
86
|
right_column: input.rightColumn || null,
|
|
82
87
|
sdk_thread_id: input.sdkThreadId || null,
|
|
83
88
|
sdk_run_id: input.sdkRunId || null,
|
|
84
89
|
stream_event_count: Number(input.streamEventCount || 0),
|
|
85
90
|
structured_output_valid: input.structuredOutputValid === true,
|
|
91
|
+
warnings: input.warnings || [],
|
|
86
92
|
blockers
|
|
87
93
|
};
|
|
88
94
|
}
|
|
@@ -163,7 +169,7 @@ export async function openWorkerPane(input) {
|
|
|
163
169
|
// --direction right — splitting the screen into N side-by-side columns
|
|
164
170
|
// (observed in agent-zellij-pane-launch-ledger: terminal_1..terminal_5 all
|
|
165
171
|
// recorded as separate slot_column_anchor_pane_id values in one mission).
|
|
166
|
-
return withZellijPaneCreationLock(input
|
|
172
|
+
return withZellijPaneCreationLock(input, async () => {
|
|
167
173
|
// Re-read the right-column state now that we hold the lock: a previously
|
|
168
174
|
// serialized worker may have created the anchor and/or its own pane.
|
|
169
175
|
const freshState = rightColumn
|
|
@@ -221,9 +227,23 @@ export async function openWorkerPane(input) {
|
|
|
221
227
|
// worker (`new-pane --stacked`, zellij >= 0.43) so the right column stays a
|
|
222
228
|
// clean vertical stack instead of fragmenting the screen. Opt out with
|
|
223
229
|
// SKS_ZELLIJ_WORKER_STACKED=0.
|
|
224
|
-
const
|
|
230
|
+
const stackIntent = process.env.SKS_ZELLIJ_WORKER_STACKED !== '0'
|
|
225
231
|
&& Boolean(lastVisibleWorkerPaneId)
|
|
226
232
|
&& focus?.ok === true;
|
|
233
|
+
const stackedCapability = stackIntent
|
|
234
|
+
? await checkZellijStackedPaneCapability({ writeReport: false }).catch((err) => ({
|
|
235
|
+
schema: 'sks.zellij-stacked-pane-capability.v1',
|
|
236
|
+
ok: false,
|
|
237
|
+
zellij_bin: 'zellij',
|
|
238
|
+
version_text: null,
|
|
239
|
+
parsed_version: null,
|
|
240
|
+
supports_stacked_panes: false,
|
|
241
|
+
requires_update: false,
|
|
242
|
+
fallback_mode: 'headless-only',
|
|
243
|
+
blockers: [`zellij_stacked_capability_check_failed:${err?.code || err?.message || String(err)}`]
|
|
244
|
+
}))
|
|
245
|
+
: null;
|
|
246
|
+
const stackRequested = stackIntent && stackedCapability?.supports_stacked_panes === true;
|
|
227
247
|
const newPaneArgs = stackRequested
|
|
228
248
|
? ['--session', input.sessionName, 'action', 'new-pane', '--stacked', '--name', paneName, '--', 'sh', '-lc', input.workerCommand]
|
|
229
249
|
: ['--session', input.sessionName, 'action', 'new-pane', '--direction', directionRequested, '--near-current-pane', '--name', paneName, '--', 'sh', '-lc', input.workerCommand];
|
|
@@ -236,6 +256,7 @@ export async function openWorkerPane(input) {
|
|
|
236
256
|
: null;
|
|
237
257
|
let stackApplied = Boolean(stackRequested && launch?.ok);
|
|
238
258
|
let directionApplied = launch?.ok ? directionRequested : 'not_applied';
|
|
259
|
+
let stackedRejectedFallback = false;
|
|
239
260
|
if (createSession.ok && launch && !launch.ok) {
|
|
240
261
|
const fallbackArgs = ['--session', input.sessionName, 'action', 'new-pane', '--direction', directionRequested, '--name', paneName, '--', 'sh', '-lc', input.workerCommand];
|
|
241
262
|
const fallback = await runZellij(fallbackArgs, {
|
|
@@ -246,6 +267,7 @@ export async function openWorkerPane(input) {
|
|
|
246
267
|
if (fallback.ok) {
|
|
247
268
|
launch = fallback;
|
|
248
269
|
stackApplied = false;
|
|
270
|
+
stackedRejectedFallback = stackRequested;
|
|
249
271
|
directionApplied = rightColumn ? 'down' : 'unknown';
|
|
250
272
|
}
|
|
251
273
|
}
|
|
@@ -268,6 +290,10 @@ export async function openWorkerPane(input) {
|
|
|
268
290
|
...(launch && !launch.ok ? launch.blockers.map((blocker) => `zellij_worker_pane_${blocker}`) : []),
|
|
269
291
|
...(launch?.ok && !isRealZellijWorkerPaneIdSource(paneIdSource) ? ['zellij_worker_pane_id_real_source_missing'] : [])
|
|
270
292
|
];
|
|
293
|
+
const warnings = [
|
|
294
|
+
...(stackIntent && stackedCapability && !stackedCapability.supports_stacked_panes ? [`zellij_stacked_pane_fallback:${stackedCapability.fallback_mode}`] : []),
|
|
295
|
+
...(stackedRejectedFallback ? ['zellij_stacked_pane_rejected_fallback_down'] : [])
|
|
296
|
+
];
|
|
271
297
|
const record = buildWorkerPaneArtifact({
|
|
272
298
|
...input,
|
|
273
299
|
paneId,
|
|
@@ -288,13 +314,16 @@ export async function openWorkerPane(input) {
|
|
|
288
314
|
columnCreationDirectionApplied,
|
|
289
315
|
workerDirectionRequested: 'down',
|
|
290
316
|
workerDirectionApplied: directionApplied === 'down' ? 'down' : directionApplied === 'unknown' ? 'unknown' : 'not_applied',
|
|
291
|
-
stackedRequested:
|
|
317
|
+
stackedRequested: stackIntent,
|
|
292
318
|
stackedApplied: stackApplied,
|
|
319
|
+
stackedFallbackMode: stackIntent ? (stackApplied ? 'native-stacked' : stackedCapability?.fallback_mode || 'down-split-stack-emulation') : null,
|
|
320
|
+
stackedCapability,
|
|
293
321
|
slotColumnAnchorPaneId,
|
|
294
322
|
rightColumn: rightColumn ? { mode: 'spawn-on-first-worker', focus_pane_id: focusPaneId, y_order: rightColumn.yOrder, slot_column_anchor_pane_id: slotColumnAnchorPaneId } : null,
|
|
295
323
|
status: blockers.length ? 'failed' : 'running',
|
|
296
324
|
providerContext,
|
|
297
325
|
serviceTier: input.serviceTier || providerContext.service_tier,
|
|
326
|
+
warnings,
|
|
298
327
|
blockers
|
|
299
328
|
});
|
|
300
329
|
await writeWorkerPaneArtifact(root, record);
|
|
@@ -311,8 +340,27 @@ export async function openWorkerPane(input) {
|
|
|
311
340
|
ok: record.ok,
|
|
312
341
|
pane_id: record.pane_id,
|
|
313
342
|
pane_id_source: record.pane_id_source,
|
|
343
|
+
worker_stacked_requested: record.worker_stacked_requested === true,
|
|
344
|
+
worker_stacked_applied: record.worker_stacked_applied === true,
|
|
345
|
+
worker_stacked_fallback_mode: record.worker_stacked_fallback_mode || null,
|
|
314
346
|
blockers
|
|
315
347
|
});
|
|
348
|
+
await appendParallelRuntimeEvent(root, input.missionId, {
|
|
349
|
+
event_type: 'zellij_pane_created',
|
|
350
|
+
slot_id: input.slotId,
|
|
351
|
+
generation_index: input.generationIndex,
|
|
352
|
+
session_id: input.sessionId,
|
|
353
|
+
pid: null,
|
|
354
|
+
backend: String(input.backend || 'zellij'),
|
|
355
|
+
placement: 'zellij-pane',
|
|
356
|
+
meta: {
|
|
357
|
+
ok: record.ok,
|
|
358
|
+
pane_id: record.pane_id,
|
|
359
|
+
worker_stacked_requested: record.worker_stacked_requested === true,
|
|
360
|
+
worker_stacked_applied: record.worker_stacked_applied === true,
|
|
361
|
+
worker_stacked_fallback_mode: record.worker_stacked_fallback_mode || null
|
|
362
|
+
}
|
|
363
|
+
}).catch(() => undefined);
|
|
316
364
|
await appendJsonl(path.join(root, 'agent-zellij-pane-launch-ledger.jsonl'), {
|
|
317
365
|
schema: 'sks.agent-zellij-pane-launch.v1',
|
|
318
366
|
generated_at: nowIso(),
|
|
@@ -338,6 +386,7 @@ export async function openWorkerPane(input) {
|
|
|
338
386
|
worker_direction_applied: record.worker_direction_applied,
|
|
339
387
|
worker_stacked_requested: record.worker_stacked_requested === true,
|
|
340
388
|
worker_stacked_applied: record.worker_stacked_applied === true,
|
|
389
|
+
worker_stacked_fallback_mode: record.worker_stacked_fallback_mode || null,
|
|
341
390
|
slot_column_anchor_pane_id: record.slot_column_anchor_pane_id || null,
|
|
342
391
|
command: record.command,
|
|
343
392
|
worker_artifact_dir: input.workerArtifactDir,
|
|
@@ -627,8 +676,20 @@ function sleep(ms) {
|
|
|
627
676
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
628
677
|
}
|
|
629
678
|
const zellijPaneCreationLocks = new Map();
|
|
630
|
-
async function withZellijPaneCreationLock(
|
|
631
|
-
const key = String(sessionName || 'default');
|
|
679
|
+
async function withZellijPaneCreationLock(input, fn) {
|
|
680
|
+
const key = String(input.sessionName || 'default');
|
|
681
|
+
const requestedAt = nowIso();
|
|
682
|
+
const requestedMs = Date.now();
|
|
683
|
+
await appendWorkerPaneEvent(path.resolve(input.root), 'zellij_pane_creation_lock_requested', input, {}).catch(() => undefined);
|
|
684
|
+
await appendParallelRuntimeEvent(path.resolve(input.root), input.missionId, {
|
|
685
|
+
event_type: 'zellij_pane_creation_lock_requested',
|
|
686
|
+
slot_id: input.slotId,
|
|
687
|
+
generation_index: input.generationIndex,
|
|
688
|
+
session_id: input.sessionId,
|
|
689
|
+
pid: null,
|
|
690
|
+
backend: String(input.backend || 'zellij'),
|
|
691
|
+
placement: 'zellij-pane'
|
|
692
|
+
}).catch(() => undefined);
|
|
632
693
|
const previous = zellijPaneCreationLocks.get(key) || Promise.resolve();
|
|
633
694
|
let release;
|
|
634
695
|
const current = new Promise((resolve) => {
|
|
@@ -636,15 +697,65 @@ async function withZellijPaneCreationLock(sessionName, fn) {
|
|
|
636
697
|
});
|
|
637
698
|
zellijPaneCreationLocks.set(key, previous.then(() => current, () => current));
|
|
638
699
|
await previous.catch(() => undefined);
|
|
700
|
+
const acquiredAt = nowIso();
|
|
701
|
+
const acquiredMs = Date.now();
|
|
702
|
+
await appendWorkerPaneEvent(path.resolve(input.root), 'zellij_pane_creation_lock_acquired', input, { wait_ms: acquiredMs - requestedMs }).catch(() => undefined);
|
|
703
|
+
await appendParallelRuntimeEvent(path.resolve(input.root), input.missionId, {
|
|
704
|
+
event_type: 'zellij_pane_creation_lock_acquired',
|
|
705
|
+
slot_id: input.slotId,
|
|
706
|
+
generation_index: input.generationIndex,
|
|
707
|
+
session_id: input.sessionId,
|
|
708
|
+
pid: null,
|
|
709
|
+
backend: String(input.backend || 'zellij'),
|
|
710
|
+
placement: 'zellij-pane',
|
|
711
|
+
meta: { wait_ms: acquiredMs - requestedMs }
|
|
712
|
+
}).catch(() => undefined);
|
|
639
713
|
try {
|
|
640
714
|
return await fn();
|
|
641
715
|
}
|
|
642
716
|
finally {
|
|
717
|
+
const releasedAt = nowIso();
|
|
718
|
+
const releasedMs = Date.now();
|
|
719
|
+
const metrics = {
|
|
720
|
+
schema: ZELLIJ_PANE_CREATION_LOCK_METRICS_SCHEMA,
|
|
721
|
+
mission_id: input.missionId,
|
|
722
|
+
session_name: input.sessionName,
|
|
723
|
+
slot_id: input.slotId,
|
|
724
|
+
generation_index: input.generationIndex,
|
|
725
|
+
requested_at: requestedAt,
|
|
726
|
+
acquired_at: acquiredAt,
|
|
727
|
+
released_at: releasedAt,
|
|
728
|
+
wait_ms: acquiredMs - requestedMs,
|
|
729
|
+
held_ms: releasedMs - acquiredMs
|
|
730
|
+
};
|
|
731
|
+
await appendJsonl(paneCreationLockMetricsPath(path.resolve(input.root), input.missionId), metrics).catch(() => undefined);
|
|
732
|
+
await appendWorkerPaneEvent(path.resolve(input.root), 'zellij_pane_creation_lock_released', input, { wait_ms: metrics.wait_ms, held_ms: metrics.held_ms }).catch(() => undefined);
|
|
733
|
+
await appendParallelRuntimeEvent(path.resolve(input.root), input.missionId, {
|
|
734
|
+
event_type: 'zellij_pane_creation_lock_released',
|
|
735
|
+
slot_id: input.slotId,
|
|
736
|
+
generation_index: input.generationIndex,
|
|
737
|
+
session_id: input.sessionId,
|
|
738
|
+
pid: null,
|
|
739
|
+
backend: String(input.backend || 'zellij'),
|
|
740
|
+
placement: 'zellij-pane',
|
|
741
|
+
meta: { wait_ms: metrics.wait_ms, held_ms: metrics.held_ms }
|
|
742
|
+
}).catch(() => undefined);
|
|
643
743
|
release();
|
|
644
744
|
if (zellijPaneCreationLocks.get(key) === current)
|
|
645
745
|
zellijPaneCreationLocks.delete(key);
|
|
646
746
|
}
|
|
647
747
|
}
|
|
748
|
+
function paneCreationLockMetricsPath(root, missionId) {
|
|
749
|
+
return path.join(missionArtifactRoot(root, missionId), 'zellij', 'pane-creation-lock-events.jsonl');
|
|
750
|
+
}
|
|
751
|
+
function missionArtifactRoot(root, missionId) {
|
|
752
|
+
const resolved = path.resolve(root);
|
|
753
|
+
if (path.basename(resolved) === 'agents')
|
|
754
|
+
return path.dirname(resolved);
|
|
755
|
+
if (path.basename(resolved) === missionId)
|
|
756
|
+
return resolved;
|
|
757
|
+
return path.join(resolved, '.sneakoscope', 'missions', missionId);
|
|
758
|
+
}
|
|
648
759
|
function normalizeExistingZellijSession(sessionName, result) {
|
|
649
760
|
if (result.ok)
|
|
650
761
|
return result;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { readJson, readText, writeJsonAtomic } from '../fsx.js';
|
|
4
|
+
export async function buildZellijWorkerPaneSummary(root, missionId) {
|
|
5
|
+
const missionDir = path.join(path.resolve(root), '.sneakoscope', 'missions', missionId);
|
|
6
|
+
const ledgerRows = await readJsonl(path.join(path.resolve(root), 'agent-zellij-pane-launch-ledger.jsonl'));
|
|
7
|
+
const missionRows = ledgerRows.filter((row) => !row.mission_id || row.mission_id === missionId);
|
|
8
|
+
const state = await readJson(path.join(missionDir, 'zellij-right-column-state.json'), null);
|
|
9
|
+
const metrics = await readJsonl(path.join(missionDir, 'zellij', 'pane-creation-lock-events.jsonl'));
|
|
10
|
+
const requested = missionRows.filter((row) => row.worker_stacked_requested === true);
|
|
11
|
+
const applied = missionRows.filter((row) => row.worker_stacked_applied === true);
|
|
12
|
+
const fallbackRows = missionRows.filter((row) => row.worker_stacked_requested === true && row.worker_stacked_applied !== true);
|
|
13
|
+
const fallbackModes = {};
|
|
14
|
+
for (const row of fallbackRows) {
|
|
15
|
+
const mode = String(row.worker_stacked_fallback_mode || 'unknown');
|
|
16
|
+
fallbackModes[mode] = (fallbackModes[mode] || 0) + 1;
|
|
17
|
+
}
|
|
18
|
+
const anchors = new Set([
|
|
19
|
+
...missionRows.map((row) => row.slot_column_anchor_pane_id).filter(Boolean).map(String),
|
|
20
|
+
...(state?.slot_column_anchor_pane_id ? [String(state.slot_column_anchor_pane_id)] : [])
|
|
21
|
+
]);
|
|
22
|
+
const stackedCapable = missionRows.some((row) => row.worker_stacked_capability?.supports_stacked_panes === true);
|
|
23
|
+
const waitP95 = percentile(metrics.map((row) => Number(row.wait_ms || 0)), 0.95);
|
|
24
|
+
const heldP95 = percentile(metrics.map((row) => Number(row.held_ms || 0)), 0.95);
|
|
25
|
+
const blockers = [
|
|
26
|
+
...(anchors.size > 1 ? ['zellij_duplicate_slot_anchor_count_gt_1'] : []),
|
|
27
|
+
...(requested.length > 0 && applied.length === 0 && stackedCapable ? ['zellij_stacked_requested_but_none_applied'] : []),
|
|
28
|
+
...(waitP95 > 5000 && requested.length <= 1 ? ['zellij_pane_lock_wait_high_with_low_concurrency'] : [])
|
|
29
|
+
];
|
|
30
|
+
const summary = {
|
|
31
|
+
schema: 'sks.zellij-worker-pane-summary.v1',
|
|
32
|
+
ok: blockers.length === 0,
|
|
33
|
+
mission_id: missionId,
|
|
34
|
+
stacked_requested_count: requested.length,
|
|
35
|
+
stacked_applied_count: applied.length,
|
|
36
|
+
stacked_fallback_count: fallbackRows.length,
|
|
37
|
+
fallback_modes: fallbackModes,
|
|
38
|
+
pane_lock_wait_p95_ms: waitP95,
|
|
39
|
+
pane_lock_held_p95_ms: heldP95,
|
|
40
|
+
duplicate_slot_anchor_count: anchors.size,
|
|
41
|
+
blockers
|
|
42
|
+
};
|
|
43
|
+
await writeJsonAtomic(path.join(missionDir, 'zellij-worker-pane-summary.json'), summary);
|
|
44
|
+
await writeJsonAtomic(path.join(path.resolve(root), '.sneakoscope', 'reports', 'zellij-worker-pane-summary.json'), summary);
|
|
45
|
+
return summary;
|
|
46
|
+
}
|
|
47
|
+
async function readJsonl(file) {
|
|
48
|
+
const text = await readText(file, '').catch(() => '');
|
|
49
|
+
return String(text || '').split(/\n+/).filter(Boolean).flatMap((line) => {
|
|
50
|
+
try {
|
|
51
|
+
return [JSON.parse(line)];
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function percentile(values, p) {
|
|
59
|
+
const sorted = values.filter((value) => Number.isFinite(value)).sort((a, b) => a - b);
|
|
60
|
+
if (!sorted.length)
|
|
61
|
+
return 0;
|
|
62
|
+
const index = Math.min(sorted.length - 1, Math.max(0, Math.ceil(sorted.length * p) - 1));
|
|
63
|
+
return Math.round(sorted[index] || 0);
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=zellij-worker-pane-summary.js.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { assertGate, root } from './sks-1-18-gate-lib.js';
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
|
|
8
|
+
const truth = readJson('.sneakoscope/release-proof-truth.json') || readJson('dist/release-proof-truth.json');
|
|
9
|
+
const codex0139 = readJson('.sneakoscope/codex-0139-capability.json');
|
|
10
|
+
const zellij = readJson('.sneakoscope/reports/zellij-worker-pane-summary.json');
|
|
11
|
+
const changelog = fs.readFileSync(path.join(root, 'CHANGELOG.md'), 'utf8');
|
|
12
|
+
const latest = latestChangelogSection(changelog);
|
|
13
|
+
const sdkVersion = readCodexSdkPackageVersion();
|
|
14
|
+
const warnings = [
|
|
15
|
+
...(truth?.package_version && truth.package_version !== latest.version ? [`package version ${truth.package_version} does not match changelog latest ${latest.version}`] : []),
|
|
16
|
+
...(pkg.version !== latest.version ? [`package.json version ${pkg.version} does not match changelog latest ${latest.version}`] : []),
|
|
17
|
+
...(!truth ? ['release proof truth missing'] : []),
|
|
18
|
+
...(truth?.git_status_clean === false ? ['git working tree dirty when proof truth was generated'] : [])
|
|
19
|
+
];
|
|
20
|
+
const body = [
|
|
21
|
+
`Version: ${pkg.version}`,
|
|
22
|
+
`Commit: ${truth?.git_commit_sha || 'unknown'}`,
|
|
23
|
+
`Dirty: ${truth?.git_status_clean === false ? 'yes' : truth?.git_status_clean === true ? 'no' : 'unknown'}`,
|
|
24
|
+
`Release proof truth: ${truth ? '.sneakoscope/release-proof-truth.json' : 'missing'}`,
|
|
25
|
+
`Codex SDK package: ${sdkVersion || 'unknown'}`,
|
|
26
|
+
`External Codex CLI 0.139 capability: ${codex0139 ? `${codex0139.ok ? 'ok' : 'blocked'}${codex0139.parsed_version ? ` (${codex0139.parsed_version})` : ''}` : 'not recorded'}`,
|
|
27
|
+
`Zellij stacked panes: ${zellij ? `${zellij.stacked_applied_count || 0}/${zellij.stacked_requested_count || 0} applied, fallback ${zellij.stacked_fallback_count || 0}, SLOTS anchors ${zellij.duplicate_slot_anchor_count || 0}` : 'not recorded'}`,
|
|
28
|
+
`Packlist: ${truth?.npm_packlist_count ?? 'unknown'} files / ${truth?.npm_packlist_bytes ?? 'unknown'} bytes`,
|
|
29
|
+
...(warnings.length ? [`Warnings: ${warnings.join('; ')}`] : ['Warnings: none']),
|
|
30
|
+
'Release gates: passed',
|
|
31
|
+
'',
|
|
32
|
+
latest.body.trim()
|
|
33
|
+
].join('\n');
|
|
34
|
+
if (args.includes('--check')) {
|
|
35
|
+
assertGate(Boolean(truth && truth.schema === 'sks.release-proof-truth.v1'), 'release proof truth missing; run npm run release:proof-truth first');
|
|
36
|
+
assertGate(latest.version === pkg.version, 'latest changelog section must match package version', { latest: latest.version, package: pkg.version });
|
|
37
|
+
assertGate(body.includes(`Version: ${pkg.version}`) && body.includes('Commit:') && body.includes('Dirty:') && body.includes('Release proof truth:') && body.includes('Codex SDK package:') && body.includes('External Codex CLI 0.139 capability:') && body.includes('Zellij stacked panes:') && body.includes('Packlist:'), 'github release body helper missing source truth fields', { body });
|
|
38
|
+
assertGate(!warnings.some((warning) => warning.includes('package version') || warning.includes('changelog latest') || warning.includes('release proof truth missing')), 'github release body helper source truth warnings must not include version/proof mismatch', { warnings, body });
|
|
39
|
+
}
|
|
40
|
+
console.log(body);
|
|
41
|
+
function readJson(rel) {
|
|
42
|
+
try {
|
|
43
|
+
return JSON.parse(fs.readFileSync(path.join(root, rel), 'utf8'));
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function latestChangelogSection(text) {
|
|
50
|
+
const matches = [...text.matchAll(/^## \[([^\]]+)\][^\n]*\n/gm)];
|
|
51
|
+
const first = matches.find((match) => /^[0-9]+\.[0-9]+\.[0-9]+$/.test(match[1]));
|
|
52
|
+
if (!first)
|
|
53
|
+
return { version: null, body: '' };
|
|
54
|
+
const second = matches.find((match) => (match.index || 0) > (first.index || 0));
|
|
55
|
+
const start = (first.index || 0) + first[0].length;
|
|
56
|
+
const end = second?.index || text.length;
|
|
57
|
+
return { version: first[1], body: text.slice(start, end) };
|
|
58
|
+
}
|
|
59
|
+
function readCodexSdkPackageVersion() {
|
|
60
|
+
const lock = readJson('package-lock.json');
|
|
61
|
+
return lock?.packages?.['node_modules/@openai/codex-sdk']?.version || pkg.dependencies?.['@openai/codex-sdk'] || null;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=github-release-body-helper.js.map
|
|
@@ -25,6 +25,17 @@ console.log(JSON.stringify({
|
|
|
25
25
|
skipped_gate_ids: summary?.skipped_by_affected || [],
|
|
26
26
|
cached: summary?.cached || 0,
|
|
27
27
|
cached_gates: summary?.cached_gates || [],
|
|
28
|
+
version_neutralized_inputs: [
|
|
29
|
+
'package.json:version',
|
|
30
|
+
'package-lock.json:root.version',
|
|
31
|
+
'src/core/version.ts:PACKAGE_VERSION',
|
|
32
|
+
'src/core/fsx.ts:PACKAGE_VERSION',
|
|
33
|
+
'src/bin/sks.ts:FAST_PACKAGE_VERSION',
|
|
34
|
+
'dist/build-manifest.json:version'
|
|
35
|
+
],
|
|
36
|
+
behavior_affecting_inputs: [],
|
|
37
|
+
cache_key_policy: 'version-neutral-safe-v1',
|
|
38
|
+
cache_message: 'Release cache: version-only changes neutralized for behavior gates. Version correctness gates still ran uncached.',
|
|
28
39
|
executed: summary?.executed_gates?.length || 0,
|
|
29
40
|
executed_gates: summary?.executed_gates || [],
|
|
30
41
|
wall_ms: summary?.wall_ms || 0,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sneakoscope",
|
|
3
3
|
"displayName": "ㅅㅋㅅ",
|
|
4
|
-
"version": "3.0.
|
|
4
|
+
"version": "3.0.3",
|
|
5
5
|
"description": "Sneakoscope Codex: fast proof-first Codex trust layer with image-based Voxel TriWiki.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"homepage": "https://github.com/mandarange/Sneakoscope-Codex#readme",
|
|
@@ -701,7 +701,38 @@
|
|
|
701
701
|
"codex:model-metadata": "node ./dist/scripts/codex-model-metadata-check.js",
|
|
702
702
|
"codex:effort-auto-discovery": "node ./dist/scripts/codex-effort-auto-discovery-check.js",
|
|
703
703
|
"codex:account-usage-autodiscovery": "node ./dist/scripts/codex-account-usage-autodiscovery-check.js",
|
|
704
|
-
"codex:0138-feature-probes": "node ./dist/scripts/codex-0138-feature-probes-check.js"
|
|
704
|
+
"codex:0138-feature-probes": "node ./dist/scripts/codex-0138-feature-probes-check.js",
|
|
705
|
+
"zellij:stacked-version-parser": "node ./dist/scripts/zellij-stacked-version-parser-check.js",
|
|
706
|
+
"zellij:stacked-version-matrix": "node ./dist/scripts/zellij-stacked-version-matrix-check.js",
|
|
707
|
+
"zellij:stacked-capability-routing": "node ./dist/scripts/zellij-stacked-capability-routing-check.js",
|
|
708
|
+
"zellij:pane-creation-lock-metrics": "node ./dist/scripts/zellij-pane-creation-lock-metrics-check.js",
|
|
709
|
+
"zellij:pane-lock-does-not-block-worker": "node ./dist/scripts/zellij-pane-lock-does-not-block-worker-check.js",
|
|
710
|
+
"zellij:pane-lock-concurrency-blackbox": "node ./dist/scripts/zellij-pane-lock-concurrency-blackbox.js",
|
|
711
|
+
"release:cache-input-classifier": "node ./dist/scripts/release-cache-input-classifier-check.js",
|
|
712
|
+
"release:cache-version-neutral-fixtures": "node ./dist/scripts/release-cache-version-neutral-fixture-check.js",
|
|
713
|
+
"release:cache-neutralization-report": "node ./dist/scripts/release-cache-neutralization-report-check.js",
|
|
714
|
+
"agent:message-bus-reader": "node ./dist/scripts/agent-message-bus-reader-check.js",
|
|
715
|
+
"runtime:proof-summary-messages": "node ./dist/scripts/runtime-proof-summary-messages-check.js",
|
|
716
|
+
"naruto:proof-message-summary": "node ./dist/scripts/naruto-proof-message-summary-check.js",
|
|
717
|
+
"zellij:update-prompt-mode": "node ./dist/scripts/zellij-update-prompt-mode-check.js",
|
|
718
|
+
"zellij:update-prompt-safety": "node ./dist/scripts/zellij-update-prompt-safety-check.js",
|
|
719
|
+
"zellij:update-prompt-matrix": "node ./dist/scripts/zellij-update-prompt-matrix-check.js",
|
|
720
|
+
"release:proof-truth": "node ./dist/scripts/release-proof-truth-check.js",
|
|
721
|
+
"release:github-body-helper": "node ./dist/scripts/github-release-body-helper.js --check",
|
|
722
|
+
"codex:0139-feature-probes": "node ./dist/scripts/codex-0139-feature-probes-check.js",
|
|
723
|
+
"codex:0139-interrupt-agent": "node ./dist/scripts/codex-0139-interrupt-agent-check.js",
|
|
724
|
+
"codex:0139-rich-tool-schema": "node ./dist/scripts/codex-0139-rich-tool-schema-check.js",
|
|
725
|
+
"codex:0139-doctor-env-redaction": "node ./dist/scripts/codex-0139-doctor-env-redaction-check.js",
|
|
726
|
+
"codex:0139-code-mode-web-search": "node ./dist/scripts/codex-0139-code-mode-web-search-check.js",
|
|
727
|
+
"codex:0139-marketplace-source": "node ./dist/scripts/codex-0139-marketplace-source-check.js",
|
|
728
|
+
"codex:0139-sandbox-profile-alias": "node ./dist/scripts/codex-0139-sandbox-profile-alias-check.js",
|
|
729
|
+
"codex:0139-real-probes": "node ./dist/scripts/codex-0139-real-probes-check.js --require-real",
|
|
730
|
+
"zellij:fake-adapter": "node ./dist/scripts/zellij-fake-adapter-check.js",
|
|
731
|
+
"zellij:pane-lock-open-worker-integration": "node ./dist/scripts/zellij-pane-lock-open-worker-integration-blackbox.js",
|
|
732
|
+
"zellij:stacked-fallback-integration": "node ./dist/scripts/zellij-stacked-fallback-integration-blackbox.js",
|
|
733
|
+
"runtime:proof-zellij-stacked-summary": "node ./dist/scripts/runtime-proof-zellij-stacked-summary-check.js",
|
|
734
|
+
"naruto:proof-zellij-stacked-summary": "node ./dist/scripts/naruto-proof-zellij-stacked-summary-check.js",
|
|
735
|
+
"docs:codex-0139-wording": "node ./dist/scripts/docs-codex-0139-wording-check.js"
|
|
705
736
|
},
|
|
706
737
|
"keywords": [
|
|
707
738
|
"sneakoscope",
|