sneakoscope 2.0.10 → 2.0.11

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 (48) 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/build-manifest.json +24 -8
  8. package/dist/cli/command-registry.js +1 -0
  9. package/dist/cli/install-helpers.js +8 -20
  10. package/dist/commands/doctor.js +5 -9
  11. package/dist/commands/zellij-slot-column-anchor.js +23 -0
  12. package/dist/core/agents/agent-orchestrator.js +59 -11
  13. package/dist/core/agents/agent-patch-schema.js +8 -1
  14. package/dist/core/commands/naruto-command.js +118 -19
  15. package/dist/core/fsx.js +1 -1
  16. package/dist/core/git/git-worktree-checkpoint.js +52 -0
  17. package/dist/core/git/git-worktree-cross-rebase.js +54 -0
  18. package/dist/core/git/git-worktree-merge-queue.js +69 -0
  19. package/dist/core/git/git-worktree-patch-envelope.js +8 -1
  20. package/dist/core/init.js +2 -2
  21. package/dist/core/naruto/naruto-allocation-policy.js +99 -0
  22. package/dist/core/naruto/naruto-real-worker-child.js +110 -11
  23. package/dist/core/naruto/naruto-rebalance-policy.js +36 -0
  24. package/dist/core/naruto/naruto-task-hints.js +71 -0
  25. package/dist/core/pipeline/finalize-pipeline-result.js +3 -1
  26. package/dist/core/pipeline/gpt-final-required.js +22 -2
  27. package/dist/core/version.js +1 -1
  28. package/dist/core/zellij/zellij-right-column-manager.js +45 -2
  29. package/dist/core/zellij/zellij-slot-column-anchor.js +59 -0
  30. package/dist/core/zellij/zellij-worker-pane-manager.js +70 -9
  31. package/dist/scripts/git-worktree-checkpoint-check.js +20 -0
  32. package/dist/scripts/git-worktree-cross-rebase-check.js +27 -0
  33. package/dist/scripts/naruto-actual-worker-control-plane-check.js +29 -0
  34. package/dist/scripts/naruto-allocation-policy-check.js +33 -0
  35. package/dist/scripts/naruto-extreme-parallelism-real-check.js +5 -4
  36. package/dist/scripts/naruto-orchestrator-runtime-source-check.js +11 -0
  37. package/dist/scripts/naruto-real-active-pool-runtime-check.js +4 -2
  38. package/dist/scripts/naruto-rebalance-policy-check.js +28 -0
  39. package/dist/scripts/naruto-shadow-clone-swarm-check.js +7 -3
  40. package/dist/scripts/release-dag-full-coverage-check.js +15 -1
  41. package/dist/scripts/release-readiness-report.js +1 -1
  42. package/dist/scripts/zellij-first-slot-down-stack-check.js +20 -0
  43. package/dist/scripts/zellij-first-slot-down-stack-real-check.js +16 -0
  44. package/dist/scripts/zellij-right-column-manager-check.js +7 -2
  45. package/dist/scripts/zellij-slot-column-anchor-check.js +24 -0
  46. package/dist/scripts/zellij-slot-only-ui-check.js +4 -2
  47. package/dist/scripts/zellij-worker-pane-manager-single-owner-check.js +11 -4
  48. package/package.json +12 -3
package/README.md CHANGED
@@ -16,7 +16,7 @@ Set up this agent project with Sneakoscope Codex. Use [[mandarange/Sneakoscope-C
16
16
 
17
17
  ## Current Release
18
18
 
19
- SKS **2.0.10** is the slot-only Zellij and Naruto runtime stabilization release. Compact slot panes are now the default visual worker surface, the initial Zellij session stays main-only until the first visible worker is reserved, overflow workers continue headlessly with runtime evidence instead of opening excess panes, and dashboard panes stay opt-in. The release path remains manifest-backed through the v2 DAG runner, with real Zellij/Naruto/worktree proof gates split into `real-check`.
19
+ SKS **2.0.11** is the slot-only Zellij and Naruto runtime stabilization release. Compact slot panes are now the default visual worker surface, the initial Zellij session stays main-only until the first visible worker is reserved, overflow workers continue headlessly with runtime evidence instead of opening excess panes, and dashboard panes stay opt-in. The release path remains manifest-backed through the v2 DAG runner, with real Zellij/Naruto/worktree proof gates split into `real-check`.
20
20
 
21
21
  What changed:
22
22
 
@@ -76,7 +76,7 @@ dependencies = [
76
76
 
77
77
  [[package]]
78
78
  name = "sks-core"
79
- version = "2.0.10"
79
+ version = "2.0.11"
80
80
  dependencies = [
81
81
  "serde_json",
82
82
  ]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "sks-core"
3
- version = "2.0.10"
3
+ version = "2.0.11"
4
4
  edition = "2021"
5
5
 
6
6
  [dependencies]
@@ -4,7 +4,7 @@ use std::io::{self, Read, Seek, SeekFrom};
4
4
  fn main() {
5
5
  let mut args = std::env::args().skip(1);
6
6
  match args.next().as_deref() {
7
- Some("--version") => println!("sks-rs 2.0.10"),
7
+ Some("--version") => println!("sks-rs 2.0.11"),
8
8
  Some("compact-info") => {
9
9
  let mut input = String::new();
10
10
  let _ = io::stdin().read_to_string(&mut input);
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schema": "sks.dist-build-stamp.v1",
3
3
  "package_name": "sneakoscope",
4
- "package_version": "2.0.10",
5
- "source_digest": "ee8d0f4a75b8f5aeb6bfa26042f194cba01728768422448bf9b1e54748007137",
6
- "source_file_count": 2030,
7
- "built_at_source_time": 1780813031543
4
+ "package_version": "2.0.11",
5
+ "source_digest": "7f7339938c95fb98e1fb072192115eb0ca8cbc8136800d007b85d51fe413de19",
6
+ "source_file_count": 2046,
7
+ "built_at_source_time": 1780821479881
8
8
  }
package/dist/bin/sks.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const FAST_PACKAGE_VERSION = '2.0.10';
2
+ const FAST_PACKAGE_VERSION = '2.0.11';
3
3
  const args = process.argv.slice(2);
4
4
  try {
5
5
  if (args[0] === '--agent' && args[1] === 'worker') {
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "schema": "sks.dist-build.v2",
3
- "version": "2.0.10",
4
- "package_version": "2.0.10",
3
+ "version": "2.0.11",
4
+ "package_version": "2.0.11",
5
5
  "typescript": true,
6
6
  "mjs_runtime_files": 0,
7
- "compiled_file_count": 1092,
8
- "compiled_js_count": 1092,
7
+ "compiled_file_count": 1108,
8
+ "compiled_js_count": 1108,
9
9
  "compiled_dts_count": 0,
10
- "source_digest": "ee8d0f4a75b8f5aeb6bfa26042f194cba01728768422448bf9b1e54748007137",
11
- "source_file_count": 2030,
12
- "source_files_hash": "26a7831ee3d5b0909718d62eefcb828bfc074c18f454d5f46f5ebdf2ded482f6",
13
- "source_list_hash": "26a7831ee3d5b0909718d62eefcb828bfc074c18f454d5f46f5ebdf2ded482f6",
10
+ "source_digest": "7f7339938c95fb98e1fb072192115eb0ca8cbc8136800d007b85d51fe413de19",
11
+ "source_file_count": 2046,
12
+ "source_files_hash": "b94b6d01c22138f134b831e0e793a981744316d3e78bf457e00d81cadd9d5c07",
13
+ "source_list_hash": "b94b6d01c22138f134b831e0e793a981744316d3e78bf457e00d81cadd9d5c07",
14
14
  "src_mjs_runtime_files": 0,
15
15
  "dist_stamp_schema": "sks.dist-build-stamp.v1",
16
16
  "files": [
@@ -101,6 +101,7 @@
101
101
  "commands/versioning.js",
102
102
  "commands/wiki.js",
103
103
  "commands/zellij-lane.js",
104
+ "commands/zellij-slot-column-anchor.js",
104
105
  "commands/zellij-slot-pane.js",
105
106
  "commands/zellij.js",
106
107
  "core/agents/agent-central-ledger.js",
@@ -348,8 +349,10 @@
348
349
  "core/git/git-repo-detection.js",
349
350
  "core/git/git-worktree-cache-policy.js",
350
351
  "core/git/git-worktree-capability.js",
352
+ "core/git/git-worktree-checkpoint.js",
351
353
  "core/git/git-worktree-cleanup.js",
352
354
  "core/git/git-worktree-conflict-resolver.js",
355
+ "core/git/git-worktree-cross-rebase.js",
353
356
  "core/git/git-worktree-diff.js",
354
357
  "core/git/git-worktree-manager.js",
355
358
  "core/git/git-worktree-merge-queue.js",
@@ -428,6 +431,7 @@
428
431
  "core/mistake-recall.js",
429
432
  "core/naruto/hardware-capacity-probe.js",
430
433
  "core/naruto/naruto-active-pool.js",
434
+ "core/naruto/naruto-allocation-policy.js",
431
435
  "core/naruto/naruto-backpressure.js",
432
436
  "core/naruto/naruto-concurrency-governor.js",
433
437
  "core/naruto/naruto-finalizer.js",
@@ -437,7 +441,9 @@
437
441
  "core/naruto/naruto-patch-transaction-batch.js",
438
442
  "core/naruto/naruto-real-worker-child.js",
439
443
  "core/naruto/naruto-real-worker-runtime.js",
444
+ "core/naruto/naruto-rebalance-policy.js",
440
445
  "core/naruto/naruto-role-policy.js",
446
+ "core/naruto/naruto-task-hints.js",
441
447
  "core/naruto/naruto-verification-dag.js",
442
448
  "core/naruto/naruto-verification-pool.js",
443
449
  "core/naruto/naruto-work-graph.js",
@@ -638,6 +644,7 @@
638
644
  "core/zellij/zellij-right-column-layout-proof.js",
639
645
  "core/zellij/zellij-right-column-manager.js",
640
646
  "core/zellij/zellij-screen-proof.js",
647
+ "core/zellij/zellij-slot-column-anchor.js",
641
648
  "core/zellij/zellij-slot-pane-renderer.js",
642
649
  "core/zellij/zellij-ui-mode.js",
643
650
  "core/zellij/zellij-worker-pane-manager.js",
@@ -847,7 +854,9 @@
847
854
  "scripts/git-precommit-fixture-check.js",
848
855
  "scripts/git-worktree-cache-performance-check.js",
849
856
  "scripts/git-worktree-capability-check.js",
857
+ "scripts/git-worktree-checkpoint-check.js",
850
858
  "scripts/git-worktree-cleanup-check.js",
859
+ "scripts/git-worktree-cross-rebase-check.js",
851
860
  "scripts/git-worktree-diff-envelope-check.js",
852
861
  "scripts/git-worktree-diff-export-check.js",
853
862
  "scripts/git-worktree-dirty-lock-check.js",
@@ -931,15 +940,19 @@
931
940
  "scripts/memory-summary-rebuild-check.js",
932
941
  "scripts/mutation-callsite-coverage-check.js",
933
942
  "scripts/naruto-active-pool-check.js",
943
+ "scripts/naruto-actual-worker-control-plane-check.js",
944
+ "scripts/naruto-allocation-policy-check.js",
934
945
  "scripts/naruto-concurrency-governor-check.js",
935
946
  "scripts/naruto-extreme-parallelism-check.js",
936
947
  "scripts/naruto-extreme-parallelism-real-check.js",
937
948
  "scripts/naruto-gpt-final-pack-check.js",
949
+ "scripts/naruto-orchestrator-runtime-source-check.js",
938
950
  "scripts/naruto-parallel-patch-apply-check.js",
939
951
  "scripts/naruto-readonly-routing-check.js",
940
952
  "scripts/naruto-real-active-pool-check.js",
941
953
  "scripts/naruto-real-active-pool-runtime-check.js",
942
954
  "scripts/naruto-real-local-gpt-final-smoke.js",
955
+ "scripts/naruto-rebalance-policy-check.js",
943
956
  "scripts/naruto-role-distribution-check.js",
944
957
  "scripts/naruto-shadow-clone-swarm-check.js",
945
958
  "scripts/naruto-verification-pool-check.js",
@@ -1087,6 +1100,8 @@
1087
1100
  "scripts/zellij-developer-controls-check.js",
1088
1101
  "scripts/zellij-doctor-readiness-check.js",
1089
1102
  "scripts/zellij-dynamic-pane-lifecycle-check.js",
1103
+ "scripts/zellij-first-slot-down-stack-check.js",
1104
+ "scripts/zellij-first-slot-down-stack-real-check.js",
1090
1105
  "scripts/zellij-initial-main-only-blackbox.js",
1091
1106
  "scripts/zellij-lane-renderer-check.js",
1092
1107
  "scripts/zellij-launch-command-truth-check.js",
@@ -1099,6 +1114,7 @@
1099
1114
  "scripts/zellij-right-column-headless-overflow-check.js",
1100
1115
  "scripts/zellij-right-column-manager-check.js",
1101
1116
  "scripts/zellij-screen-proof-check.js",
1117
+ "scripts/zellij-slot-column-anchor-check.js",
1102
1118
  "scripts/zellij-slot-only-ui-check.js",
1103
1119
  "scripts/zellij-slot-pane-renderer-check.js",
1104
1120
  "scripts/zellij-spawn-on-demand-layout-check.js",
@@ -105,6 +105,7 @@ export const COMMANDS = {
105
105
  tmux: entry('beta', 'Show removed-runtime migration notice', 'dist/commands/tmux.js', directCommand(() => import('../commands/tmux.js'), 'dist/commands/tmux.js')),
106
106
  'zellij-lane': entry('beta', 'Render a Zellij lane frame for SKS sessions', 'dist/commands/zellij-lane.js', directCommand(() => import('../commands/zellij-lane.js'), 'dist/commands/zellij-lane.js')),
107
107
  'zellij-slot-pane': entry('beta', 'Render a compact Zellij worker slot pane', 'dist/commands/zellij-slot-pane.js', directCommand(() => import('../commands/zellij-slot-pane.js'), 'dist/commands/zellij-slot-pane.js')),
108
+ 'zellij-slot-column-anchor': entry('beta', 'Render the compact SLOTS anchor pane for first-slot-down Zellij stacks', 'dist/commands/zellij-slot-column-anchor.js', directCommand(() => import('../commands/zellij-slot-column-anchor.js'), 'dist/commands/zellij-slot-column-anchor.js')),
108
109
  zellij: entry('beta', 'Inspect Zellij runtime status and explain repair (no auto-install)', 'dist/commands/zellij.js', directCommand(() => import('../commands/zellij.js'), 'dist/commands/zellij.js')),
109
110
  mad: entry('beta', 'MAD-SKS Zellij permission launcher', 'dist/commands/mad-sks.js', directCommand(() => import('../commands/mad-sks.js'), 'dist/commands/mad-sks.js')),
110
111
  'mad-sks': entry('beta', 'MAD-SKS scoped permission modifier', 'dist/commands/mad-sks.js', directCommand(() => import('../commands/mad-sks.js'), 'dist/commands/mad-sks.js')),
@@ -13,7 +13,6 @@ import { context7ConfigToml, DOLLAR_SKILL_NAMES, GETDESIGN_REFERENCE, hasContext
13
13
  import { checkZellijCapability } from '../core/zellij/zellij-capability.js';
14
14
  import { reconcileCodexAppUpgradeProcesses } from '../core/codex-app.js';
15
15
  import { recordCodexLbHealthEvent } from '../core/codex-lb-circuit.js';
16
- import { runSksUpdateCheck, runSksUpdateNow } from '../core/update-check.js';
17
16
  import { loadCodexLbEnv, writeCodexLbKeychain, codexLbMetadataPath } from '../core/codex-lb/codex-lb-env.js';
18
17
  import { buildCodexLbSetupPlan, codexLbPersistenceSummary, installCodexLbShellProfileSnippet, selectedCodexLbPersistenceModes } from '../core/codex-lb/codex-lb-setup.js';
19
18
  const DEFAULT_CODEX_APP_PLUGINS = [
@@ -2233,26 +2232,15 @@ export async function maybePromptCodexUpdateForLaunch(args = [], opts = {}) {
2233
2232
  return installCodexLatest(command, latest.version, current);
2234
2233
  }
2235
2234
  export async function maybePromptSksUpdateForLaunch(args = [], opts = {}) {
2236
- if (hasFlag(args, '--json') || hasFlag(args, '--skip-sks-update') || process.env.SKS_SKIP_SKS_UPDATE === '1')
2237
- return { status: 'skipped' };
2238
- const label = opts.label || 'SKS launch';
2239
- const check = await runSksUpdateCheck({ timeoutMs: 5000 }).catch((err) => ({
2240
- ok: false,
2241
- update_available: false,
2242
- latest: null,
2235
+ void args;
2236
+ void opts;
2237
+ return {
2238
+ status: 'skipped',
2239
+ reason: 'manual_update_commands_only',
2243
2240
  current: PACKAGE_VERSION,
2244
- command: null,
2245
- error: err?.message || String(err)
2246
- }));
2247
- if (!check.update_available) {
2248
- return { status: check.error ? 'unavailable' : 'current', latest: check.latest || null, current: check.current || PACKAGE_VERSION, error: check.error || null };
2249
- }
2250
- const command = check.command || `sks update now --version ${check.latest}`;
2251
- if (shouldAutoApproveInstall(args)) {
2252
- return runSksUpdateNow({ version: check.latest, timeoutMs: 10 * 60 * 1000, maxOutputBytes: 128 * 1024 });
2253
- }
2254
- console.log(`SKS update available before ${label}: ${check.current} -> ${check.latest}. Run when ready: ${command}`);
2255
- return { status: 'available', latest: check.latest || null, current: check.current || PACKAGE_VERSION, command };
2241
+ latest: null,
2242
+ command: null
2243
+ };
2256
2244
  }
2257
2245
  export function shouldAutoApproveInstall(args = [], env = process.env) {
2258
2246
  if (hasFlag(args, '--from-postinstall') && env.SKS_POSTINSTALL_AUTO_INSTALL_CLI_TOOLS !== '1')
@@ -18,21 +18,17 @@ import { appendMigrationEvents, hashConfigText } from '../core/migration/migrati
18
18
  import { repairCodexAppFastUi } from '../core/codex-app/codex-app-fast-ui-repair.js';
19
19
  import { resolveProviderContext } from '../core/provider/provider-context.js';
20
20
  import { readLocalModelConfig } from '../core/agents/ollama-worker-config.js';
21
- import { runSksUpdateNow } from '../core/update-check.js';
22
21
  import { repairAgentRoleConfigs } from '../core/agents/agent-role-config.js';
23
22
  export async function run(_command, args = []) {
24
23
  const doctorFix = flag(args, '--fix');
25
24
  let setupRepair = null;
26
25
  const sksUpdate = doctorFix
27
- ? await runSksUpdateNow({
28
- timeoutMs: 10 * 60 * 1000,
29
- maxOutputBytes: 128 * 1024
30
- }).catch((err) => ({
26
+ ? {
31
27
  schema: 'sks.update-now.v1',
32
- ok: false,
33
- status: 'failed',
34
- error: err?.message || String(err)
35
- }))
28
+ ok: true,
29
+ status: 'skipped',
30
+ reason: 'manual_update_commands_only'
31
+ }
36
32
  : null;
37
33
  let migrationPreFix = null;
38
34
  if (doctorFix) {
@@ -0,0 +1,23 @@
1
+ import { renderZellijSlotColumnAnchorFromArtifacts } from '../core/zellij/zellij-slot-column-anchor.js';
2
+ export async function run(_command = 'zellij-slot-column-anchor', args = []) {
3
+ const missionId = readOption(args, '--mission', 'latest') || 'latest';
4
+ const artifactRoot = readOption(args, '--artifact-root', process.cwd()) || process.cwd();
5
+ const mode = readOption(args, '--mode', 'compact-slots') || 'compact-slots';
6
+ const watch = hasFlag(args, '--watch');
7
+ const intervalMs = Math.max(250, Number(readOption(args, '--interval-ms', '1000') || 1000));
8
+ for (;;) {
9
+ const text = await renderZellijSlotColumnAnchorFromArtifacts({ artifactRoot, missionId, mode });
10
+ process.stdout.write('\x1Bc' + text + '\n');
11
+ if (!watch)
12
+ break;
13
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
14
+ }
15
+ }
16
+ function readOption(args, name, fallback) {
17
+ const index = args.indexOf(name);
18
+ return index >= 0 && args[index + 1] ? String(args[index + 1]) : fallback;
19
+ }
20
+ function hasFlag(args, flag) {
21
+ return args.includes(flag);
22
+ }
23
+ //# sourceMappingURL=zellij-slot-column-anchor.js.map
@@ -55,6 +55,7 @@ import { selectFinalGptPatchSource } from '../pipeline/final-gpt-patch-stage.js'
55
55
  import { allocateWorkerWorktree } from '../git/git-worktree-manager.js';
56
56
  import { exportGitWorktreeDiff } from '../git/git-worktree-diff.js';
57
57
  import { buildGitWorktreePatchEnvelope } from '../git/git-worktree-patch-envelope.js';
58
+ import { checkpointWorkerWorktree } from '../git/git-worktree-checkpoint.js';
58
59
  import { cleanupGitWorktree } from '../git/git-worktree-cleanup.js';
59
60
  import { createGitIntegrationWorktree } from '../git/git-integration-worktree.js';
60
61
  import { applyGitWorktreeMergeQueue } from '../git/git-worktree-merge-queue.js';
@@ -270,6 +271,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
270
271
  worktree_root: gitWorktreePolicy?.worktree_root || null,
271
272
  allocations: [],
272
273
  diffs: [],
274
+ checkpoints: [],
273
275
  cleanup: [],
274
276
  blockers: []
275
277
  };
@@ -424,7 +426,10 @@ export async function runNativeAgentOrchestrator(opts = {}) {
424
426
  await writeJsonAtomic(path.join(ledgerRoot, 'local-collaboration-policy.json'), localCollaborationPolicy);
425
427
  const localParticipated = localCollaborationParticipated(results);
426
428
  const candidatePatchEnvelopes = results.flatMap((result) => Array.isArray(result.patch_envelopes) ? result.patch_envelopes : []);
427
- const gptFinalArbiter = localParticipated
429
+ const worktreeParticipated = candidatePatchEnvelopes.some((envelope) => envelope?.source === 'git-worktree-diff' || envelope?.git_worktree?.worktree_path)
430
+ || results.some((result) => result?.git_worktree_diff || result?.git_worktree_checkpoint);
431
+ const gptFinalRequired = localParticipated || worktreeParticipated;
432
+ const gptFinalArbiter = gptFinalRequired
428
433
  ? await runFinalGptReviewStage({
429
434
  schema: 'sks.gpt-final-arbiter-input.v1',
430
435
  route,
@@ -448,10 +453,10 @@ export async function runNativeAgentOrchestrator(opts = {}) {
448
453
  rollback_plan: { verification_rollback_dag: strategyCompiled.verification_rollback_dag || null }
449
454
  }, { cwd: root, mutationLedgerRoot: path.join(ledgerRoot, 'gpt-final-arbiter') })
450
455
  : null;
451
- const finalGptPatchStage = localParticipated
456
+ const finalGptPatchStage = gptFinalRequired
452
457
  ? selectFinalGptPatchSource(gptFinalArbiter, candidatePatchEnvelopes)
453
458
  : null;
454
- const resultsForPatchSwarm = localParticipated && finalGptPatchStage?.ok === true && gptFinalArbiter?.result?.status === 'modified'
459
+ const resultsForPatchSwarm = gptFinalRequired && finalGptPatchStage?.ok === true && gptFinalArbiter?.result?.status === 'modified'
455
460
  ? withFinalGptPatchEnvelopes(results, finalGptPatchStage.patch_envelopes)
456
461
  : results;
457
462
  const patchSwarm = await runAgentPatchSwarmRuntime(root, ledgerRoot, {
@@ -462,7 +467,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
462
467
  results: resultsForPatchSwarm,
463
468
  parallelWritePolicy,
464
469
  verificationRollbackDag: strategyCompiled.verification_rollback_dag,
465
- dryRun: opts.dryRunPatches === true || opts.applyPatches !== true || (localParticipated && gptFinalArbiter?.ok !== true),
470
+ dryRun: opts.dryRunPatches === true || opts.applyPatches !== true || (gptFinalRequired && gptFinalArbiter?.ok !== true),
466
471
  gptFinalArbiter,
467
472
  finalGptPatchStage
468
473
  });
@@ -491,8 +496,8 @@ export async function runNativeAgentOrchestrator(opts = {}) {
491
496
  ...(noSubagentScalingPolicy.ok ? [] : noSubagentScalingPolicy.blockers),
492
497
  ...(fastModePropagation.ok ? [] : fastModePropagation.blockers),
493
498
  ...(gitWorktreeRuntime.required === true && gitWorktreeRuntime.ok === false ? gitWorktreeRuntime.blockers || ['git_worktree_runtime_not_ok'] : []),
494
- ...(localParticipated && gptFinalArbiter?.ok !== true ? gptFinalArbiter?.blockers || ['gpt_final_arbiter_not_ok'] : []),
495
- ...(localParticipated && finalGptPatchStage?.ok === false ? finalGptPatchStage.blockers || ['final_gpt_patch_stage_not_ok'] : []),
499
+ ...(gptFinalRequired && gptFinalArbiter?.ok !== true ? gptFinalArbiter?.blockers || ['gpt_final_arbiter_not_ok'] : []),
500
+ ...(gptFinalRequired && finalGptPatchStage?.ok === false ? finalGptPatchStage.blockers || ['final_gpt_patch_stage_not_ok'] : []),
496
501
  ...(patchSwarm.ok ? [] : patchSwarm.blockers),
497
502
  ...(janitor.ok ? [] : janitor.blockers)
498
503
  ];
@@ -647,6 +652,14 @@ async function finalizeWorkerGitWorktree(input) {
647
652
  workerId: String(input.agent.id || input.slice.id || 'worker')
648
653
  });
649
654
  await writeJsonAtomic(path.join(input.workerWorktree.artifactDir, 'git-worktree-diff.json'), diff);
655
+ const checkpoint = await checkpointWorkerWorktree({
656
+ worktreePath: allocation.worktree_path,
657
+ repoRoot: allocation.main_repo_root || input.root,
658
+ workerId: String(input.agent.id || input.slice.id || 'worker'),
659
+ taskId: String(input.slice.id || input.agent.id || 'task'),
660
+ mode: 'auto'
661
+ });
662
+ await writeJsonAtomic(path.join(input.workerWorktree.artifactDir, 'git-worktree-checkpoint.json'), checkpoint);
650
663
  input.runtime.diffs.push({
651
664
  agent_id: input.agent.id,
652
665
  slice_id: input.slice.id,
@@ -656,18 +669,29 @@ async function finalizeWorkerGitWorktree(input) {
656
669
  diff_bytes: diff.diff_bytes,
657
670
  blockers: diff.blockers
658
671
  });
672
+ input.runtime.checkpoints.push({
673
+ agent_id: input.agent.id,
674
+ slice_id: input.slice.id,
675
+ ok: checkpoint.ok,
676
+ mode_applied: checkpoint.mode_applied,
677
+ commit_hash: checkpoint.commit_hash,
678
+ changed_files: checkpoint.changed_files,
679
+ blockers: checkpoint.blockers
680
+ });
659
681
  if (!diff.clean && diff.ok) {
660
682
  const envelope = buildGitWorktreePatchEnvelope({
661
683
  diff,
662
684
  agentId: String(input.agent.id || 'agent'),
663
685
  sessionId: String(input.agent.session_id || ''),
664
686
  slotId: String(input.agent.slot_id || ''),
665
- generationIndex: Math.max(1, Math.floor(Number(input.agent.generation_index || 1)))
687
+ generationIndex: Math.max(1, Math.floor(Number(input.agent.generation_index || 1))),
688
+ checkpoint
666
689
  });
667
690
  input.result.patch_envelopes = [...(Array.isArray(input.result.patch_envelopes) ? input.result.patch_envelopes : []), envelope];
668
691
  input.result.changed_files = [...new Set([...(input.result.changed_files || []), ...diff.changed_files])];
669
- input.result.artifacts = [...new Set([...(input.result.artifacts || []), path.relative(input.ledgerRoot, path.join(input.workerWorktree.artifactDir, 'git-worktree-diff.json'))])];
692
+ input.result.artifacts = [...new Set([...(input.result.artifacts || []), path.relative(input.ledgerRoot, path.join(input.workerWorktree.artifactDir, 'git-worktree-diff.json')), path.relative(input.ledgerRoot, path.join(input.workerWorktree.artifactDir, 'git-worktree-checkpoint.json'))])];
670
693
  input.result.git_worktree_diff = diff;
694
+ input.result.git_worktree_checkpoint = checkpoint;
671
695
  }
672
696
  const cleanup = await cleanupGitWorktree({
673
697
  repoRoot: allocation.main_repo_root || input.root,
@@ -684,7 +708,7 @@ async function finalizeWorkerGitWorktree(input) {
684
708
  retention_lock_path: cleanup.retention_lock_path,
685
709
  blockers: cleanup.blockers
686
710
  });
687
- input.runtime.blockers.push(...diff.blockers, ...cleanup.blockers);
711
+ input.runtime.blockers.push(...diff.blockers, ...checkpoint.blockers, ...cleanup.blockers);
688
712
  input.runtime.ok = input.runtime.blockers.length === 0;
689
713
  await writeJsonAtomic(path.join(input.ledgerRoot, 'agent-git-worktree-runtime.json'), input.runtime);
690
714
  }
@@ -1003,6 +1027,7 @@ async function runAgentPatchSwarmRuntime(root, ledgerRoot, input) {
1003
1027
  }
1004
1028
  async function runGitWorktreeIntegrationPrimary(root, ledgerRoot, missionId, entries, queueStore) {
1005
1029
  const diffs = entries.map((entry) => gitWorktreeDiffFromQueueEntry(entry)).filter(Boolean);
1030
+ const checkpoints = entries.map((entry) => gitWorktreeCheckpointFromQueueEntry(entry)).filter(Boolean);
1006
1031
  const repoRoot = diffs[0]?.main_repo_root || root;
1007
1032
  const baseRef = diffs.find((diff) => diff.base_head)?.base_head || undefined;
1008
1033
  const integration = await createGitIntegrationWorktree({ repoRoot, missionId, ...(baseRef ? { baseRef } : {}) });
@@ -1039,13 +1064,15 @@ async function runGitWorktreeIntegrationPrimary(root, ledgerRoot, missionId, ent
1039
1064
  await queueStore.markApplying(entry.id);
1040
1065
  const queueReport = await applyGitWorktreeMergeQueue({
1041
1066
  integrationWorktreePath: integration.worktree_path,
1042
- diffs
1067
+ diffs,
1068
+ checkpoints
1043
1069
  });
1044
1070
  const rollbackPlan = queueReport.ok ? await captureGitWorktreeRollbackPlan(repoRoot, queueReport.changed_files || []) : { ok: false, rollback: [], blockers: ['git_worktree_integration_prevalidation_failed'] };
1045
1071
  const mainApplyReport = queueReport.ok && rollbackPlan.ok
1046
1072
  ? await applyGitWorktreeMergeQueue({
1047
1073
  integrationWorktreePath: repoRoot,
1048
- diffs
1074
+ diffs,
1075
+ checkpoints
1049
1076
  })
1050
1077
  : null;
1051
1078
  const rollbackEvidence = mainApplyReport?.ok
@@ -1176,6 +1203,27 @@ function gitWorktreeDiffFromQueueEntry(entry) {
1176
1203
  blockers: []
1177
1204
  };
1178
1205
  }
1206
+ function gitWorktreeCheckpointFromQueueEntry(entry) {
1207
+ const envelope = entry?.envelope || {};
1208
+ const meta = envelope.git_worktree || {};
1209
+ const checkpoint = meta.checkpoint || null;
1210
+ if (!checkpoint || checkpoint.mode_applied !== 'checkpoint-commit' || !checkpoint.commit_hash)
1211
+ return null;
1212
+ return {
1213
+ schema: 'sks.git-worktree-checkpoint.v1',
1214
+ ok: Array.isArray(checkpoint.blockers) ? checkpoint.blockers.length === 0 : true,
1215
+ generated_at: nowIso(),
1216
+ worktree_path: String(meta.worktree_path || ''),
1217
+ repo_root: String(meta.main_repo_root || ''),
1218
+ worker_id: String(envelope.agent_id || entry.agent_id || entry.id),
1219
+ task_id: String(envelope.task_slice_id || entry.id || ''),
1220
+ mode_requested: 'auto',
1221
+ mode_applied: 'checkpoint-commit',
1222
+ commit_hash: String(checkpoint.commit_hash),
1223
+ changed_files: Array.isArray(checkpoint.changed_files) ? checkpoint.changed_files.map(String) : Array.isArray(meta.changed_files) ? meta.changed_files.map(String) : [],
1224
+ blockers: Array.isArray(checkpoint.blockers) ? checkpoint.blockers.map(String) : []
1225
+ };
1226
+ }
1179
1227
  function normalizeDesiredWorkItemCount(value, minimumValue, targetActiveSlots) {
1180
1228
  const parsed = Number(value);
1181
1229
  const minimum = Number(minimumValue);
@@ -117,7 +117,14 @@ function normalizeGitWorktreeMetadata(input) {
117
117
  base_head: input?.base_head == null ? null : String(input.base_head),
118
118
  worktree_head: input?.worktree_head == null ? null : String(input.worktree_head),
119
119
  changed_files: Array.isArray(input?.changed_files) ? input.changed_files.map(String) : [],
120
- diff_bytes: Number(input?.diff_bytes || 0)
120
+ diff_bytes: Number(input?.diff_bytes || 0),
121
+ checkpoint: input?.checkpoint ? {
122
+ ...(input.checkpoint.schema === undefined ? {} : { schema: String(input.checkpoint.schema) }),
123
+ ...(input.checkpoint.mode_applied === undefined ? {} : { mode_applied: String(input.checkpoint.mode_applied) }),
124
+ commit_hash: input.checkpoint.commit_hash == null ? null : String(input.checkpoint.commit_hash),
125
+ changed_files: Array.isArray(input.checkpoint.changed_files) ? input.checkpoint.changed_files.map(String) : [],
126
+ blockers: Array.isArray(input.checkpoint.blockers) ? input.checkpoint.blockers.map(String) : []
127
+ } : null
121
128
  };
122
129
  }
123
130
  function normalizeHint(input) {