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.
Files changed (30) hide show
  1. package/README.md +1 -1
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/crates/sks-core/src/main.rs +1 -1
  5. package/dist/.sks-build-stamp.json +4 -4
  6. package/dist/bin/sks.js +1 -1
  7. package/dist/core/agents/agent-message-bus.js +89 -2
  8. package/dist/core/agents/runtime-proof-summary.js +46 -2
  9. package/dist/core/codex/codex-cli-syntax-builder.js +4 -1
  10. package/dist/core/codex-control/codex-0139-capability.js +68 -12
  11. package/dist/core/codex-control/codex-multi-agent-event-normalizer.js +15 -0
  12. package/dist/core/codex-control/codex-tool-schema-fixtures.js +57 -0
  13. package/dist/core/commands/naruto-command.js +9 -4
  14. package/dist/core/fsx.js +1 -1
  15. package/dist/core/mcp/mcp-0-134-policy.js +3 -0
  16. package/dist/core/pipeline-internals/runtime-core.js +6 -1
  17. package/dist/core/release/release-cache-key.js +128 -0
  18. package/dist/core/release/release-gate-cache-v2.js +6 -7
  19. package/dist/core/release/release-proof-truth.js +63 -0
  20. package/dist/core/safety/side-effect-runtime-report.js +19 -4
  21. package/dist/core/version.js +1 -1
  22. package/dist/core/zellij/zellij-capability.js +41 -0
  23. package/dist/core/zellij/zellij-command.js +14 -2
  24. package/dist/core/zellij/zellij-fake-adapter.js +163 -0
  25. package/dist/core/zellij/zellij-update.js +28 -3
  26. package/dist/core/zellij/zellij-worker-pane-manager.js +116 -5
  27. package/dist/core/zellij/zellij-worker-pane-summary.js +65 -0
  28. package/dist/scripts/github-release-body-helper.js +63 -0
  29. package/dist/scripts/release-speed-summary.js +11 -0
  30. 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.sessionName, async () => {
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 stackRequested = process.env.SKS_ZELLIJ_WORKER_STACKED !== '0'
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: stackRequested,
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(sessionName, fn) {
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.1",
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",