sneakoscope 4.8.7 → 5.3.0

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 (261) hide show
  1. package/README.md +51 -726
  2. package/config/bench-baseline.json +7 -0
  3. package/crates/sks-core/Cargo.lock +1 -1
  4. package/crates/sks-core/Cargo.toml +1 -1
  5. package/crates/sks-core/src/main.rs +1 -1
  6. package/dist/bin/install.js +35 -0
  7. package/dist/bin/sks.js +1 -1
  8. package/dist/cli/cli-theme.js +51 -0
  9. package/dist/cli/command-registry.js +15 -4
  10. package/dist/cli/help-fast.js +18 -8
  11. package/dist/cli/insane-search-command.js +36 -8
  12. package/dist/cli/install-helpers.js +32 -0
  13. package/dist/commands/codex-lb.js +2 -0
  14. package/dist/commands/doctor.js +94 -9
  15. package/dist/commands/proof.js +6 -3
  16. package/dist/config/skills-manifest.json +82 -54
  17. package/dist/core/agents/agent-conflict-graph.js +5 -0
  18. package/dist/core/agents/agent-lease.js +5 -0
  19. package/dist/core/agents/agent-ledger-schemas.js +1 -0
  20. package/dist/core/agents/agent-lifecycle.js +5 -3
  21. package/dist/core/agents/agent-orchestrator.js +268 -62
  22. package/dist/core/agents/agent-output-validator.js +14 -3
  23. package/dist/core/agents/agent-patch-queue-store.js +95 -2
  24. package/dist/core/agents/agent-patch-queue.js +6 -3
  25. package/dist/core/agents/agent-patch-schema.js +13 -0
  26. package/dist/core/agents/agent-proof-evidence.js +6 -1
  27. package/dist/core/agents/agent-runner-fake.js +40 -0
  28. package/dist/core/agents/agent-worker-pipeline.js +36 -2
  29. package/dist/core/agents/codex-exec-worker-adapter.js +2 -0
  30. package/dist/core/agents/native-cli-worker.js +0 -1
  31. package/dist/core/agents/native-worker-backend-router.js +58 -1
  32. package/dist/core/codex-app/sks-menubar.js +477 -132
  33. package/dist/core/codex-app.js +1 -0
  34. package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
  35. package/dist/core/codex-control/codex-sdk-env-policy.js +1 -1
  36. package/dist/core/codex-control/schemas/agent-worker-result.schema.js +12 -3
  37. package/dist/core/codex-hooks/codex-hook-managed-install.js +5 -0
  38. package/dist/core/codex-hooks/codex-hook-state-writer.js +70 -11
  39. package/dist/core/codex-hooks/codex-hook-trust-doctor.js +2 -2
  40. package/dist/core/codex-lb/codex-lb-env.js +20 -1
  41. package/dist/core/commands/basic-cli.js +18 -1
  42. package/dist/core/commands/check-command.js +37 -5
  43. package/dist/core/commands/computer-use-command.js +62 -7
  44. package/dist/core/commands/db-command.js +31 -5
  45. package/dist/core/commands/fast-mode-command.js +3 -0
  46. package/dist/core/commands/gate-result-contract.js +43 -0
  47. package/dist/core/commands/gates-command.js +6 -1
  48. package/dist/core/commands/gc-command.js +29 -2
  49. package/dist/core/commands/goal-command.js +9 -2
  50. package/dist/core/commands/gx-command.js +79 -7
  51. package/dist/core/commands/image-ux-review-command.js +188 -13
  52. package/dist/core/commands/mad-db-command.js +85 -176
  53. package/dist/core/commands/mad-sks-command.js +230 -29
  54. package/dist/core/commands/menubar-command.js +24 -2
  55. package/dist/core/commands/naruto-command.js +64 -10
  56. package/dist/core/commands/plan-command.js +76 -0
  57. package/dist/core/commands/ppt-command.js +159 -24
  58. package/dist/core/commands/qa-loop-command.js +6 -2
  59. package/dist/core/commands/release-command.js +55 -2
  60. package/dist/core/commands/research-command.js +1 -1
  61. package/dist/core/commands/review-command.js +217 -0
  62. package/dist/core/commands/route-success-helpers.js +59 -0
  63. package/dist/core/commands/run-command.js +19 -7
  64. package/dist/core/commands/seo-command.js +49 -1
  65. package/dist/core/commands/ui-command.js +161 -0
  66. package/dist/core/commands/uninstall-command.js +15 -1
  67. package/dist/core/db-safety.js +2 -2
  68. package/dist/core/doctor/doctor-dirty-planner.js +51 -7
  69. package/dist/core/doctor/doctor-transaction.js +8 -0
  70. package/dist/core/doctor/doctor-zellij-repair.js +1 -0
  71. package/dist/core/doctor/imagegen-repair.js +161 -0
  72. package/dist/core/feature-fixture-runner.js +2 -2
  73. package/dist/core/feature-fixtures.js +58 -37
  74. package/dist/core/feature-registry.js +102 -2
  75. package/dist/core/fsx.js +39 -6
  76. package/dist/core/image-ux-review/imagegen-adapter.js +48 -11
  77. package/dist/core/image-ux-review.js +16 -0
  78. package/dist/core/imagegen/imagegen-capability.js +11 -5
  79. package/dist/core/imagegen/require-imagegen.js +57 -0
  80. package/dist/core/init/skills.js +10 -5
  81. package/dist/core/mad-db/mad-db-coordinator.js +94 -18
  82. package/dist/core/mad-db/mad-db-policy.js +12 -10
  83. package/dist/core/mad-sks/executors/executor-base.js +8 -2
  84. package/dist/core/mad-sks/executors/index.js +4 -0
  85. package/dist/core/mad-sks/executors/sql-plane-executor.js +194 -0
  86. package/dist/core/naruto/naruto-active-pool.js +15 -4
  87. package/dist/core/naruto/naruto-real-worker-child.js +11 -1
  88. package/dist/core/naruto/naruto-role-policy.js +3 -0
  89. package/dist/core/naruto/naruto-task-hints.js +10 -0
  90. package/dist/core/naruto/naruto-work-graph.js +8 -2
  91. package/dist/core/naruto/naruto-work-item.js +6 -0
  92. package/dist/core/naruto/solution-tournament.js +101 -0
  93. package/dist/core/permission-gates.js +30 -0
  94. package/dist/core/pipeline-internals/runtime-core.js +11 -3
  95. package/dist/core/pipeline-internals/runtime-gates.js +27 -0
  96. package/dist/core/ppt-review/index.js +6 -1
  97. package/dist/core/ppt-review/slide-imagegen-review.js +75 -10
  98. package/dist/core/ppt.js +70 -2
  99. package/dist/core/proof/auto-finalize.js +70 -11
  100. package/dist/core/proof/proof-schema.js +2 -0
  101. package/dist/core/proof/route-adapter.js +5 -1
  102. package/dist/core/proof/route-finalizer.js +8 -5
  103. package/dist/core/proof/selftest-proof-fixtures.js +18 -5
  104. package/dist/core/proof/validation.js +2 -0
  105. package/dist/core/provider/model-router.js +53 -0
  106. package/dist/core/release/release-gate-node.js +3 -0
  107. package/dist/core/release/release-gate-resource-governor.js +1 -0
  108. package/dist/core/routes/constants.js +1 -1
  109. package/dist/core/routes.js +65 -18
  110. package/dist/core/safety/mutation-guard.js +5 -1
  111. package/dist/core/stop-gate/gate-evaluator.js +102 -0
  112. package/dist/core/stop-gate/stop-gate-check.js +16 -1
  113. package/dist/core/stop-gate/stop-gate-writer.js +4 -0
  114. package/dist/core/triwiki/agents-md-projector.js +184 -0
  115. package/dist/core/triwiki-wrongness/wrongness-schema.js +3 -1
  116. package/dist/core/trust-kernel/trust-kernel-schema.js +1 -0
  117. package/dist/core/trust-kernel/trust-report.js +1 -1
  118. package/dist/core/trust-kernel/trust-status.js +2 -0
  119. package/dist/core/ui/dashboard-html.js +111 -0
  120. package/dist/core/update/update-migration-state.js +386 -15
  121. package/dist/core/update-check.js +178 -81
  122. package/dist/core/verification/diff-quality.js +100 -0
  123. package/dist/core/verification/impact-scan.js +164 -0
  124. package/dist/core/verification/machine-feedback.js +146 -0
  125. package/dist/core/verification/mistake-rule-compiler.js +195 -0
  126. package/dist/core/version.js +1 -1
  127. package/dist/core/zellij/zellij-self-heal.js +9 -6
  128. package/dist/core/zellij/zellij-slot-telemetry.js +1 -1
  129. package/dist/scripts/check-feature-quality.js +2 -2
  130. package/dist/scripts/cli-output-consistency-check.js +57 -0
  131. package/dist/scripts/coding-bench-check.js +136 -0
  132. package/dist/scripts/doctor-imagegen-repair-check.js +62 -0
  133. package/dist/scripts/ensure-bin-executable.js +11 -3
  134. package/dist/scripts/harness-benchmark-check.js +104 -0
  135. package/dist/scripts/legacy-update-e2e-check.js +228 -0
  136. package/dist/scripts/mad-db-command-check.js +11 -8
  137. package/dist/scripts/mad-db-route-identity-check.js +8 -6
  138. package/dist/scripts/mad-db-safety-conflict-matrix-check.js +31 -8
  139. package/dist/scripts/mad-db-skill-policy-snapshot-check.js +4 -5
  140. package/dist/scripts/naruto-real-active-pool-runtime-check.js +26 -1
  141. package/dist/scripts/ppt-real-imagegen-wiring-check.js +5 -1
  142. package/dist/scripts/proof-root-cause-policy-check.js +2 -0
  143. package/dist/scripts/release-dag-full-coverage-check.js +13 -4
  144. package/dist/scripts/release-gate-dag-runner.js +14 -0
  145. package/dist/scripts/release-gate-existence-audit.js +2 -1
  146. package/dist/scripts/release-gate-planner.js +2 -1
  147. package/dist/scripts/release-gate-script-parity-check.js +45 -17
  148. package/dist/scripts/release-metadata-1-19-check.js +2 -1
  149. package/dist/scripts/seo-geo-feature-fixture-quality-check.js +1 -1
  150. package/dist/scripts/sks-1-11-gate-lib.js +8 -6
  151. package/dist/scripts/sks-menubar-install-check.js +57 -20
  152. package/dist/scripts/ux-review-real-loop-fixture-check.js +9 -4
  153. package/dist/scripts/ux-review-run-wires-imagegen-check.js +4 -0
  154. package/dist/scripts/zellij-slot-telemetry-runtime-check.js +1 -0
  155. package/docs/assets/sneakoscope-architecture-pipeline.jpg +0 -0
  156. package/docs/demo.tape +28 -0
  157. package/package.json +31 -24
  158. package/schemas/codex/completion-proof.schema.json +3 -2
  159. package/schemas/release/release-gate-node.schema.json +2 -1
  160. package/dist/scripts/agent-backfill-route-blackbox.js +0 -5
  161. package/dist/scripts/agent-dynamic-pool-route-blackbox.js +0 -5
  162. package/dist/scripts/agent-parallel-write-blackbox.js +0 -56
  163. package/dist/scripts/agent-patch-swarm-route-blackbox.js +0 -10
  164. package/dist/scripts/agent-route-blackbox-lib.js +0 -132
  165. package/dist/scripts/blackbox-command-import-smoke.js +0 -143
  166. package/dist/scripts/blackbox-global-shim.js +0 -77
  167. package/dist/scripts/blackbox-matrix.js +0 -70
  168. package/dist/scripts/blackbox-npx-one-shot.js +0 -69
  169. package/dist/scripts/blackbox-pack-install.js +0 -174
  170. package/dist/scripts/brand-neutrality-zero-leakage-blackbox.js +0 -4
  171. package/dist/scripts/build-once-runner-blackbox.js +0 -34
  172. package/dist/scripts/codex-0140-integration-blackbox.js +0 -13
  173. package/dist/scripts/codex-agent-type-blackbox.js +0 -4
  174. package/dist/scripts/codex-app-harness-blackbox.js +0 -4
  175. package/dist/scripts/codex-app-skill-agent-blackbox.js +0 -4
  176. package/dist/scripts/codex-hook-approval-blackbox.js +0 -4
  177. package/dist/scripts/codex-init-deep-directory-local-blackbox.js +0 -4
  178. package/dist/scripts/codex-native-feature-broker-blackbox.js +0 -4
  179. package/dist/scripts/codex-native-pattern-analysis-blackbox.js +0 -4
  180. package/dist/scripts/codex-native-read-repair-split-blackbox.js +0 -55
  181. package/dist/scripts/codex-native-reference-cache-blackbox.js +0 -41
  182. package/dist/scripts/core-skill-integrity-blackbox.js +0 -32
  183. package/dist/scripts/dfix-fast-blackbox-check.js +0 -37
  184. package/dist/scripts/dfix-parallel-write-blackbox.js +0 -48
  185. package/dist/scripts/dfix-patch-swarm-route-blackbox.js +0 -10
  186. package/dist/scripts/doctor-dirty-repair-blackbox.js +0 -22
  187. package/dist/scripts/doctor-dirty-semantic-blackbox.js +0 -8
  188. package/dist/scripts/doctor-native-capability-repair-blackbox.js +0 -39
  189. package/dist/scripts/doctor-transaction-engine-blackbox.js +0 -28
  190. package/dist/scripts/doctor-zellij-fix-blackbox.js +0 -4
  191. package/dist/scripts/doctor-zellij-no-homebrew-blackbox.js +0 -4
  192. package/dist/scripts/doctor-zellij-upgrade-blackbox.js +0 -4
  193. package/dist/scripts/gate-pack-runner-blackbox.js +0 -27
  194. package/dist/scripts/gate-pack-v2-blackbox.js +0 -18
  195. package/dist/scripts/geo-cli-blackbox-check.js +0 -18
  196. package/dist/scripts/loop-collision-blackbox.js +0 -3
  197. package/dist/scripts/loop-concurrency-oversubscription-blackbox.js +0 -3
  198. package/dist/scripts/loop-fixture-production-misuse-blackbox.js +0 -3
  199. package/dist/scripts/loop-kill-interrupt-real-blackbox.js +0 -3
  200. package/dist/scripts/loop-merge-strategy-blackbox.js +0 -3
  201. package/dist/scripts/loop-mesh-production-e2e-blackbox.js +0 -3
  202. package/dist/scripts/loop-side-effect-blackbox.js +0 -3
  203. package/dist/scripts/mad-db-operation-lifecycle-blackbox.js +0 -29
  204. package/dist/scripts/mad-sks-actual-executor-blackbox.js +0 -5
  205. package/dist/scripts/mad-zellij-headless-fallback-blackbox.js +0 -4
  206. package/dist/scripts/mad-zellij-self-heal-blackbox.js +0 -4
  207. package/dist/scripts/naruto-loop-mesh-blackbox.js +0 -3
  208. package/dist/scripts/naruto-real-parallelism-blackbox.js +0 -307
  209. package/dist/scripts/naruto-worktree-coding-blackbox.js +0 -29
  210. package/dist/scripts/parallel-runtime-real-blackbox.js +0 -44
  211. package/dist/scripts/pipeline-codex-native-doctor-mad-routing-real-blackbox.js +0 -77
  212. package/dist/scripts/pipeline-codex-native-e2e-blackbox.js +0 -13
  213. package/dist/scripts/pipeline-codex-native-image-routing-real-blackbox.js +0 -50
  214. package/dist/scripts/pipeline-codex-native-loop-routing-real-blackbox.js +0 -74
  215. package/dist/scripts/pipeline-codex-native-qa-routing-real-blackbox.js +0 -51
  216. package/dist/scripts/pipeline-codex-native-research-routing-real-blackbox.js +0 -45
  217. package/dist/scripts/pipeline-execution-profile-routing-blackbox.js +0 -4
  218. package/dist/scripts/postinstall-global-doctor-blackbox.js +0 -12
  219. package/dist/scripts/ppt-full-e2e-blackbox-check.js +0 -109
  220. package/dist/scripts/ppt-imagegen-blackbox-check.js +0 -46
  221. package/dist/scripts/qa-backfill-route-blackbox.js +0 -5
  222. package/dist/scripts/qa-patch-swarm-route-blackbox.js +0 -10
  223. package/dist/scripts/release-full-parallelism-blackbox.js +0 -41
  224. package/dist/scripts/release-triwiki-first-runner-blackbox.js +0 -48
  225. package/dist/scripts/release-wiring-3110-blackbox.js +0 -27
  226. package/dist/scripts/release-wiring-3112-blackbox.js +0 -17
  227. package/dist/scripts/release-wiring-3113-blackbox.js +0 -17
  228. package/dist/scripts/research-backfill-route-blackbox.js +0 -5
  229. package/dist/scripts/research-final-reviewer-blackbox.js +0 -70
  230. package/dist/scripts/research-stage-cycle-runtime-blackbox.js +0 -40
  231. package/dist/scripts/research-synthesis-writer-blackbox.js +0 -24
  232. package/dist/scripts/route-blackbox-realism-check.js +0 -21
  233. package/dist/scripts/scheduler-resource-claim-blackbox.js +0 -24
  234. package/dist/scripts/seo-cli-blackbox-check.js +0 -18
  235. package/dist/scripts/sks-3110-all-feature-regression-blackbox.js +0 -116
  236. package/dist/scripts/sks-3112-all-feature-regression-blackbox.js +0 -29
  237. package/dist/scripts/sks-3113-all-feature-regression-blackbox.js +0 -17
  238. package/dist/scripts/sks-400-all-feature-regression-blackbox.js +0 -21
  239. package/dist/scripts/sks-400-extreme-parallel-blackbox.js +0 -8
  240. package/dist/scripts/sks-400-five-minute-blackbox.js +0 -9
  241. package/dist/scripts/sks-400-legacy-purge-blackbox.js +0 -8
  242. package/dist/scripts/sks-401-all-feature-regression-blackbox.js +0 -46
  243. package/dist/scripts/sks-401-five-minute-actual-blackbox.js +0 -23
  244. package/dist/scripts/sks-402-all-feature-regression-blackbox.js +0 -9
  245. package/dist/scripts/sks-402-five-minute-real-blackbox.js +0 -22
  246. package/dist/scripts/sksd-warm-cache-blackbox.js +0 -12
  247. package/dist/scripts/team-backfill-route-blackbox.js +0 -5
  248. package/dist/scripts/team-parallel-write-blackbox.js +0 -55
  249. package/dist/scripts/team-patch-swarm-route-blackbox.js +0 -10
  250. package/dist/scripts/triwiki-affected-graph-blackbox.js +0 -28
  251. package/dist/scripts/triwiki-proof-bank-blackbox.js +0 -30
  252. package/dist/scripts/triwiki-proof-bank-lock-blackbox.js +0 -7
  253. package/dist/scripts/ux-patch-swarm-route-blackbox.js +0 -10
  254. package/dist/scripts/ux-review-imagegen-blackbox-check.js +0 -67
  255. package/dist/scripts/zellij-initial-main-only-blackbox.js +0 -28
  256. package/dist/scripts/zellij-pane-lock-concurrency-blackbox.js +0 -80
  257. package/dist/scripts/zellij-pane-lock-open-worker-integration-blackbox.js +0 -137
  258. package/dist/scripts/zellij-self-heal-typed-blackbox.js +0 -4
  259. package/dist/scripts/zellij-slot-telemetry-real-blackbox.js +0 -20
  260. package/dist/scripts/zellij-stacked-fallback-integration-blackbox.js +0 -81
  261. package/dist/scripts/zellij-worker-pane-real-ui-blackbox.js +0 -202
@@ -3,7 +3,7 @@ import fs from 'node:fs';
3
3
  import { spawn } from 'node:child_process';
4
4
  import { PACKAGE_VERSION, appendJsonlBounded, exists, nowIso, packageRoot, readJson, sksRoot, writeJsonAtomic } from '../fsx.js';
5
5
  import { initProject } from '../init.js';
6
- import { createMission, setCurrent } from '../mission.js';
6
+ import { createMission, findLatestMission, missionDir, setCurrent, stateFile } from '../mission.js';
7
7
  import { buildMadHighLaunchProfileNoWrite, madHighProfileName } from '../auto-review.js';
8
8
  import { permissionGateSummary } from '../permission-gates.js';
9
9
  import { attachZellijSessionInteractive, launchMadZellijUi, sanitizeZellijSessionName } from '../zellij/zellij-launcher.js';
@@ -26,6 +26,7 @@ import { repairZellijForSks } from '../zellij/zellij-self-heal.js';
26
26
  import { buildMadGlmLaunchArtifact, buildMadGlmLaunchProfileNoWrite, resolveMadGlmLaunchKey, writeMadGlmCodexWrapper } from '../providers/glm/glm-mad-launch.js';
27
27
  import { GLM_MAD_MODE } from '../providers/glm/glm-52-settings.js';
28
28
  import { assertNonGlmMadRoute } from '../routes/model-mode-router.js';
29
+ const MAD_SKS_DEFAULT_TTL_MS = 10 * 60 * 1000;
29
30
  export async function madHighCommand(args = [], deps = {}) {
30
31
  const subcommand = firstSubcommand(args);
31
32
  if (subcommand)
@@ -65,6 +66,7 @@ export async function madHighCommand(args = [], deps = {}) {
65
66
  const launchRoot = process.cwd();
66
67
  if (!(await exists(path.join(launchRoot, '.sneakoscope'))))
67
68
  await initProject(launchRoot, {});
69
+ await cleanupExpiredMadSks(launchRoot);
68
70
  if (dryRun) {
69
71
  const zellijPlan = skipZellijRepair
70
72
  ? { schema: 'sks.zellij-self-heal.v1', ok: true, status: 'skipped', dry_run: true, planned_mutations: [], command: null, blockers: [], warnings: ['zellij_repair_skipped'] }
@@ -76,7 +78,8 @@ export async function madHighCommand(args = [], deps = {}) {
76
78
  interactive: false,
77
79
  installHomebrew: rawArgs.includes('--install-homebrew'),
78
80
  allowHeadlessFallback: headlessZellij,
79
- dryRun: true
81
+ dryRun: true,
82
+ quiet: rawArgs.includes('--json')
80
83
  });
81
84
  const report = {
82
85
  schema: 'sks.mad-sks-zellij-dry-run.v1',
@@ -123,7 +126,8 @@ export async function madHighCommand(args = [], deps = {}) {
123
126
  autoApprove: rawArgs.includes('--yes') || rawArgs.includes('-y'),
124
127
  interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY && process.env.SKS_NO_QUESTION !== '1'),
125
128
  installHomebrew: rawArgs.includes('--install-homebrew'),
126
- allowHeadlessFallback: headlessZellij
129
+ allowHeadlessFallback: headlessZellij,
130
+ quiet: rawArgs.includes('--json')
127
131
  });
128
132
  const zellijRepairBlocked = !headlessZellij && (zellijUpdate.status === 'manual_required'
129
133
  || zellijUpdate.strategy === 'manual-required'
@@ -240,10 +244,10 @@ export async function madHighCommand(args = [], deps = {}) {
240
244
  if (glmRuntime?.profile)
241
245
  console.log(`GLM MAD launch active: ${glmRuntime.profile.model} via OpenRouter; GPT fallback blocked.`);
242
246
  if (madDbGrant.requested)
243
- console.log('MAD-DB flag observed; use the first-class route: sks mad-db run|exec|apply-migration.');
247
+ console.log('MAD-DB flag observed; deprecated route now redirects to MAD-SKS SQL-plane: sks mad-sks sql|apply-migration.');
244
248
  if (updateNotice.update_available === true)
245
249
  console.log(`SKS update notice: ${updateNotice.latest_version} available (non-blocking).`);
246
- console.log('Scoped high-power maintenance authority active; add explicit --allow-* flags for packages, services, network, browser/Computer Use, generated assets, file permissions, or system/admin scopes. MAD-DB SQL-plane execution is not active in MAD-SKS; use the first-class MadDB route for DROP/TRUNCATE/all-row SQL-plane work.');
250
+ console.log('Scoped high-power maintenance authority active; add explicit --allow-* flags for packages, services, network, browser/Computer Use, generated assets, file permissions, or system/admin scopes. SQL-plane execution is available through MAD-SKS sql-plane and still requires control-plane denial, read-back proof, and read-only restoration.');
247
251
  const launchLb = lb.status === 'present' ? { ...lb, status: 'configured' } : lb;
248
252
  const zellijVisiblePaneSetting = readOption(cleanArgs, '--zellij-visible-panes', process.env.SKS_ZELLIJ_VISIBLE_PANES || process.env.SKS_ZELLIJ_VISIBLE_PANE_CAP || '8');
249
253
  const zellijViewportSetting = readOption(cleanArgs, '--zellij-viewports', process.env.SKS_ZELLIJ_VIEWPORTS || '4');
@@ -702,12 +706,20 @@ async function activateMadZellijPermissionState(cwd = process.cwd(), args = [])
702
706
  direct_execute_sql_allowed: dbWriteAllowed,
703
707
  normal_db_writes_allowed: dbWriteAllowed,
704
708
  migration_apply_allowed: dbWriteAllowed,
709
+ sql_plane: {
710
+ requested: false,
711
+ capability_id: null,
712
+ operation_classes: [],
713
+ read_back_passed: false,
714
+ profile_closed: false
715
+ },
705
716
  catastrophic_safety_guard_active: true,
706
717
  permission_profile: permissionGateSummary(),
707
718
  permission_model: permission,
708
719
  protected_core_policy: protectedCorePolicyPath,
709
720
  protected_core_before: protectedCoreBeforePath,
710
721
  protected_core_digest: protectedCoreBefore.digest,
722
+ expires_at: new Date(Date.now() + MAD_SKS_DEFAULT_TTL_MS).toISOString(),
711
723
  codex_native_invocation_plan: {
712
724
  selected_strategy: 'message-role-fallback',
713
725
  hook_evidence_policy: 'background-verification-do-not-count-until-refreshed',
@@ -897,7 +909,7 @@ function codexLbImmediateLaunchOpts(args = [], lb = {}, opts = {}) {
897
909
  const session = explicitSession || sanitizeZellijSessionName(`sks-openai-fallback-${Date.now().toString(36)}-${path.basename(root) || 'project'}`);
898
910
  console.log(`codex-lb bypass active for this launch: ${lb.chain_health?.status || lb.status}`);
899
911
  console.log(`Using fresh OpenAI fallback Zellij session: ${session}`);
900
- return { ...opts, session, codexArgs: [...(opts.codexArgs || []), '-c', 'model_provider="openai"'], codexLbBypassed: true };
912
+ return { ...opts, session, codexArgs: [...(opts.codexArgs || []), '-c', 'model_provider="openai"'], 'codexLbBypassed': true };
901
913
  }
902
914
  if (!lb?.ok)
903
915
  return opts;
@@ -915,7 +927,17 @@ export async function madSksFixture(root) {
915
927
  const { id, dir } = await createMission(root, { mode: 'mad-sks', prompt: '$MAD-SKS fixture permission gate' });
916
928
  await writeCodex0138CapabilityArtifacts(root, { missionId: id }).catch(() => null);
917
929
  await writeCodex0139CapabilityArtifacts(root, { missionId: id }).catch(() => null);
918
- const gate = { schema_version: 1, passed: true, mad_sks_permission_active: true, permissions_deactivated: true, catastrophic_safety_guard_active: true, permission_profile: permissionGateSummary(), fixture: true };
930
+ const gate = {
931
+ schema_version: 1,
932
+ passed: false,
933
+ execution_class: 'mock_fixture',
934
+ mad_sks_permission_active: false,
935
+ permissions_deactivated: false,
936
+ catastrophic_safety_guard_active: true,
937
+ permission_profile: permissionGateSummary(),
938
+ fixture: true,
939
+ blockers: ['mad_sks_fixture_mode_cannot_claim_real']
940
+ };
919
941
  await writeJsonAtomic(path.join(dir, 'mad-sks-gate.json'), gate);
920
942
  return { mission_id: id, dir, gate };
921
943
  }
@@ -923,8 +945,12 @@ const MAD_SKS_COMMAND_SURFACE = Object.freeze([
923
945
  'plan',
924
946
  'run',
925
947
  'apply',
948
+ 'sql',
949
+ 'apply-migration',
926
950
  'doctor',
927
951
  'status',
952
+ 'close',
953
+ 'revoke',
928
954
  'permissions',
929
955
  'proof',
930
956
  'repair-config',
@@ -937,9 +963,16 @@ async function madSksSubcommand(subcommand, args = []) {
937
963
  const json = args.includes('--json');
938
964
  const targetRoot = path.resolve(readOption(args, '--target-root', process.cwd()));
939
965
  const userIntent = readOption(args, '--intent', 'MAD-SKS user-authorized maintenance');
940
- const flags = parseMadSksFlags(['--mad-sks', subcommand === 'plan' ? '--plan-only' : '', ...args].filter(Boolean));
966
+ const sqlPlaneSubcommand = subcommand === 'sql' || subcommand === 'apply-migration';
967
+ const flags = parseMadSksFlags([
968
+ '--mad-sks',
969
+ subcommand === 'plan' ? '--plan-only' : '',
970
+ ...(sqlPlaneSubcommand ? ['--allow-db-write', '--yes'] : []),
971
+ ...args
972
+ ].filter(Boolean));
941
973
  const permission = buildMadSksPermissionModel({ targetRoot, userIntent, flags });
942
974
  const root = await sksRoot();
975
+ await cleanupExpiredMadSks(root);
943
976
  if (subcommand === 'permissions') {
944
977
  const protectedCore = resolveProtectedCore({ packageRoot: packageRoot(), targetRoot });
945
978
  return emit({
@@ -971,7 +1004,7 @@ async function madSksSubcommand(subcommand, args = []) {
971
1004
  return emit({
972
1005
  schema: 'sks.mad-sks-explain.v1',
973
1006
  ok: true,
974
- summary: 'MAD-SKS is a user-authorized general permission widening mode, not a DB-only unlock. Target project work can be widened by explicit flags, while SKS harness/package/dist/scripts/schemas/release metadata remain immutable protected core.',
1007
+ summary: 'MAD-SKS is a user-authorized general permission widening mode and the merged SQL-plane execution route. Target project work can be widened by explicit flags, while SQL-plane work runs through the sql-plane executor with MadDB capability/profile/read-back safeguards and SKS harness/package/dist/scripts/schemas/release metadata remain immutable protected core.',
975
1008
  command_surface: [...MAD_SKS_COMMAND_SURFACE],
976
1009
  catastrophic_safeguards: permission.forbidden_scopes,
977
1010
  immutable_harness_guard: 'installed_harness_only_with_engine_source_exception'
@@ -992,6 +1025,9 @@ async function madSksSubcommand(subcommand, args = []) {
992
1025
  permission_active: false
993
1026
  }, json);
994
1027
  }
1028
+ if (subcommand === 'close' || subcommand === 'revoke') {
1029
+ return closeMadSks(root, args, json, subcommand);
1030
+ }
995
1031
  if (subcommand === 'repair-config') {
996
1032
  const apply = args.includes('--apply') || args.includes('--yes');
997
1033
  const dryRun = args.includes('--dry-run') || !apply;
@@ -1062,6 +1098,34 @@ async function madSksSubcommand(subcommand, args = []) {
1062
1098
  if (subcommand === 'run') {
1063
1099
  return materializeMadSksRun(root, targetRoot, permission, userIntent, json, { action: 'run', args });
1064
1100
  }
1101
+ if (subcommand === 'sql') {
1102
+ const sql = readOption(args, '--sql', null) || positionalText(args);
1103
+ return materializeMadSksRun(root, targetRoot, permission, sql || userIntent, json, {
1104
+ action: 'apply',
1105
+ resultSchema: 'sks.mad-sks-sql.v1',
1106
+ args,
1107
+ executor: 'sql-plane',
1108
+ sql,
1109
+ verifySql: readOption(args, '--verify-sql', null),
1110
+ rollbackSql: readOption(args, '--rollback-sql', null),
1111
+ acceptNotRollbackable: args.includes('--accept-not-rollbackable')
1112
+ });
1113
+ }
1114
+ if (subcommand === 'apply-migration') {
1115
+ const migrationFile = readOption(args, '--file', null) || args.find((arg) => !String(arg).startsWith('--')) || null;
1116
+ return materializeMadSksRun(root, targetRoot, permission, userIntent, json, {
1117
+ action: 'apply',
1118
+ resultSchema: 'sks.mad-sks-apply-migration.v1',
1119
+ args,
1120
+ executor: 'sql-plane',
1121
+ sqlAction: 'apply-migration',
1122
+ migrationFile,
1123
+ migrationName: readOption(args, '--name', null),
1124
+ verifySql: readOption(args, '--verify-sql', null),
1125
+ rollbackSql: readOption(args, '--rollback-sql', null),
1126
+ acceptNotRollbackable: args.includes('--accept-not-rollbackable')
1127
+ });
1128
+ }
1065
1129
  if (subcommand === 'rollback-apply') {
1066
1130
  const rollbackPlanPath = readOption(args, '--rollback-plan', readOption(args, '--plan', null));
1067
1131
  const result = await applyMadSksRollbackPlan({
@@ -1097,7 +1161,7 @@ async function materializeMadSksRun(root, targetRoot, permission, userIntent, js
1097
1161
  if (!opts.authorizationManifestPath)
1098
1162
  await writeJsonAtomic(authorizationPath, authorization);
1099
1163
  const args = Array.isArray(opts.args) ? opts.args : [];
1100
- const executorId = readOption(args, '--executor', inferMadSksExecutor(args));
1164
+ const executorId = opts.executor || readOption(args, '--executor', inferMadSksExecutor(args));
1101
1165
  const targetFile = readOption(args, '--write-file', readOption(args, '--path', path.join('.sneakoscope', 'mad-sks-target-file.txt')));
1102
1166
  const executorInput = {
1103
1167
  executor: executorId,
@@ -1111,13 +1175,20 @@ async function materializeMadSksRun(root, targetRoot, permission, userIntent, js
1111
1175
  authorization_manifest: authorization,
1112
1176
  authorization_manifest_path: authorizationPath,
1113
1177
  permission_model: permission,
1114
- yes: args.includes('--yes')
1178
+ yes: args.includes('--yes') || opts.acceptNotRollbackable === true,
1179
+ mission_id: id,
1180
+ user_intent: userIntent,
1181
+ args
1115
1182
  };
1116
1183
  const operation = readOption(args, '--operation', null);
1117
1184
  const command = readOption(args, '--command', null);
1118
1185
  const argv = readRepeatedOption(args, '--argv');
1119
- const sql = readOption(args, '--sql', null);
1120
- const rollbackSql = readOption(args, '--rollback-sql', null);
1186
+ const sql = opts.sql || readOption(args, '--sql', null);
1187
+ const rollbackSql = opts.rollbackSql || readOption(args, '--rollback-sql', null);
1188
+ const verifySql = opts.verifySql || readOption(args, '--verify-sql', null);
1189
+ const migrationFile = opts.migrationFile || readOption(args, '--migration-file', null) || readOption(args, '--file', null);
1190
+ const migrationName = opts.migrationName || readOption(args, '--name', null);
1191
+ const sqlAction = opts.sqlAction || null;
1121
1192
  if (operation)
1122
1193
  executorInput.operation = operation;
1123
1194
  if (command)
@@ -1128,6 +1199,16 @@ async function materializeMadSksRun(root, targetRoot, permission, userIntent, js
1128
1199
  executorInput.sql = sql;
1129
1200
  if (rollbackSql)
1130
1201
  executorInput.rollback_sql = rollbackSql;
1202
+ if (verifySql)
1203
+ executorInput.verify_sql = verifySql;
1204
+ if (migrationFile)
1205
+ executorInput.migration_file = migrationFile;
1206
+ if (migrationName)
1207
+ executorInput.migration_name = migrationName;
1208
+ if (sqlAction)
1209
+ executorInput.action = sqlAction;
1210
+ if (opts.acceptNotRollbackable === true)
1211
+ executorInput.accept_not_rollbackable = true;
1131
1212
  const executorResult = await runMadSksExecutor(executorInput);
1132
1213
  const protectedProbe = await evaluateMadSksWrite({ packageRoot: packageRoot(), targetRoot, operation: 'file_write', path: path.join(packageRoot(), 'src', 'core', 'version.ts') });
1133
1214
  const audit = createMadSksAuditLedger({
@@ -1182,19 +1263,6 @@ async function materializeMadSksRun(root, targetRoot, permission, userIntent, js
1182
1263
  ]
1183
1264
  });
1184
1265
  await writeMadSksProofEvidence(proofPath, proof);
1185
- const gate = {
1186
- schema_version: 1,
1187
- passed: proof.ok === true && executorResult.ok === true,
1188
- mad_sks_permission_active: true,
1189
- permissions_deactivated: true,
1190
- full_system_authority: permission.mode === 'full_system_authority',
1191
- immutable_harness_guard_passed: comparison.ok === true,
1192
- audit_ledger: auditPath,
1193
- rollback_plan: rollbackPath,
1194
- proof_evidence: proofPath,
1195
- permission_profile: permissionGateSummary()
1196
- };
1197
- await writeJsonAtomic(path.join(dir, 'mad-sks-gate.json'), gate);
1198
1266
  await setCurrent(root, {
1199
1267
  mission_id: id,
1200
1268
  route: 'MadSKS',
@@ -1206,9 +1274,37 @@ async function materializeMadSksRun(root, targetRoot, permission, userIntent, js
1206
1274
  mad_sks_gate_file: 'mad-sks-gate.json',
1207
1275
  prompt: userIntent
1208
1276
  });
1277
+ const restore = await verifyMadSksPermissionRestored(root, id);
1278
+ const sqlPlane = executorResult.sql_plane && typeof executorResult.sql_plane === 'object'
1279
+ ? executorResult.sql_plane
1280
+ : { requested: false, capability_id: null, operation_classes: [], read_back_passed: false, profile_closed: false };
1281
+ const sqlPlaneRequested = sqlPlane.requested === true;
1282
+ const sqlPlanePassed = !sqlPlaneRequested || (sqlPlane.read_back_passed === true && sqlPlane.profile_closed === true);
1283
+ const gateBlockers = [
1284
+ ...(restore.permissions_deactivated === true ? [] : ['permission_restore_failed']),
1285
+ ...(comparison.ok === true ? [] : ['protected_core_changed']),
1286
+ ...(executorResult.ok === true ? [] : (executorResult.blockers || ['mad_sks_executor_failed'])),
1287
+ ...(sqlPlanePassed ? [] : ['mad_sks_sql_plane_read_back_or_profile_close_failed'])
1288
+ ];
1289
+ const gate = {
1290
+ schema_version: 1,
1291
+ passed: proof.ok === true && executorResult.ok === true && restore.permissions_deactivated === true && comparison.ok === true && sqlPlanePassed,
1292
+ mad_sks_permission_active: false,
1293
+ permissions_deactivated: restore.permissions_deactivated === true,
1294
+ full_system_authority: permission.mode === 'full_system_authority',
1295
+ immutable_harness_guard_passed: comparison.ok === true,
1296
+ audit_ledger: auditPath,
1297
+ rollback_plan: rollbackPath,
1298
+ proof_evidence: proofPath,
1299
+ permission_restore_read_back: restore,
1300
+ permission_profile: permissionGateSummary(),
1301
+ sql_plane: sqlPlane,
1302
+ blockers: [...new Set(gateBlockers)]
1303
+ };
1304
+ await writeJsonAtomic(path.join(dir, 'mad-sks-gate.json'), gate);
1209
1305
  return emit({
1210
- schema: opts.action === 'apply' ? 'sks.mad-sks-apply.v1' : 'sks.mad-sks-run.v1',
1211
- ok: proof.ok === true && executorResult.ok === true,
1306
+ schema: opts.resultSchema || (opts.action === 'apply' ? 'sks.mad-sks-apply.v1' : 'sks.mad-sks-run.v1'),
1307
+ ok: gate.passed === true,
1212
1308
  status: executorResult.status,
1213
1309
  mission_id: id,
1214
1310
  target_root: targetRoot,
@@ -1224,9 +1320,86 @@ async function materializeMadSksRun(root, targetRoot, permission, userIntent, js
1224
1320
  blocked_actions: [protectedProbe, ...(executorResult.blocked_actions || [])]
1225
1321
  }, json);
1226
1322
  }
1323
+ async function closeMadSks(root, args = [], json = false, action = 'close') {
1324
+ const missionId = readOption(args, '--mission', null) || args.find((arg) => !String(arg).startsWith('--')) || await findLatestMission(root);
1325
+ if (!missionId) {
1326
+ const result = { schema: 'sks.mad-sks-close.v1', ok: false, action, mission_id: null, blockers: ['mad_sks_mission_missing'] };
1327
+ process.exitCode = 1;
1328
+ return emit(result, json);
1329
+ }
1330
+ await setCurrent(root, {
1331
+ mission_id: missionId,
1332
+ route: 'MadSKS',
1333
+ route_command: '$MAD-SKS',
1334
+ mode: 'MADSKS',
1335
+ phase: action === 'revoke' ? 'MADSKS_PERMISSION_REVOKED' : 'MADSKS_PERMISSION_CLOSED',
1336
+ mad_sks_active: false,
1337
+ mad_sks_modifier: false,
1338
+ mad_sks_gate_file: 'mad-sks-gate.json',
1339
+ mad_sks_closed_at: nowIso()
1340
+ });
1341
+ const restore = await verifyMadSksPermissionRestored(root, missionId);
1342
+ const result = await writeMadSksCloseGate(root, missionId, action, restore);
1343
+ if (!result.ok)
1344
+ process.exitCode = 1;
1345
+ return emit(result, json);
1346
+ }
1347
+ async function cleanupExpiredMadSks(root) {
1348
+ const missionId = await findLatestMission(root);
1349
+ if (!missionId)
1350
+ return null;
1351
+ const gate = await readJson(path.join(missionDir(root, missionId), 'mad-sks-gate.json'), null);
1352
+ const expires = Date.parse(String(gate?.expires_at || ''));
1353
+ if (gate?.mad_sks_permission_active !== true || !Number.isFinite(expires) || expires > Date.now())
1354
+ return gate;
1355
+ await setCurrent(root, {
1356
+ mission_id: missionId,
1357
+ route: 'MadSKS',
1358
+ route_command: '$MAD-SKS',
1359
+ mode: 'MADSKS',
1360
+ phase: 'MADSKS_PERMISSION_EXPIRED_CLOSED',
1361
+ mad_sks_active: false,
1362
+ mad_sks_modifier: false,
1363
+ mad_sks_gate_file: 'mad-sks-gate.json'
1364
+ });
1365
+ const restore = await verifyMadSksPermissionRestored(root, missionId);
1366
+ return writeMadSksCloseGate(root, missionId, 'ttl_expired_lazy_cleanup', restore);
1367
+ }
1368
+ async function writeMadSksCloseGate(root, missionId, action, restore) {
1369
+ const file = path.join(missionDir(root, missionId), 'mad-sks-gate.json');
1370
+ const previous = await readJson(file, {});
1371
+ const gate = {
1372
+ ...previous,
1373
+ schema_version: previous.schema_version || 1,
1374
+ passed: restore.permissions_deactivated === true,
1375
+ mad_sks_permission_active: false,
1376
+ permissions_deactivated: restore.permissions_deactivated === true,
1377
+ permission_restore_read_back: restore,
1378
+ closed_at: nowIso(),
1379
+ close_reason: action,
1380
+ blockers: restore.permissions_deactivated === true ? [] : ['permission_restore_failed']
1381
+ };
1382
+ await writeJsonAtomic(file, gate);
1383
+ return { schema: 'sks.mad-sks-close.v1', ok: gate.passed === true, action, mission_id: missionId, gate };
1384
+ }
1385
+ async function verifyMadSksPermissionRestored(root, missionId) {
1386
+ const state = await readJson(stateFile(root), {});
1387
+ const gate = await readJson(path.join(missionDir(root, missionId), 'mad-sks-gate.json'), {});
1388
+ const permissionsDeactivated = state.mission_id === missionId
1389
+ && state.mad_sks_active !== true
1390
+ && gate.mad_sks_permission_active !== true;
1391
+ return {
1392
+ schema: 'sks.mad-sks-permission-restore-readback.v1',
1393
+ checked_at: nowIso(),
1394
+ mission_id: missionId,
1395
+ permissions_deactivated: permissionsDeactivated,
1396
+ state_mad_sks_active: state.mad_sks_active === true,
1397
+ gate_mad_sks_permission_active: gate.mad_sks_permission_active === true
1398
+ };
1399
+ }
1227
1400
  function inferMadSksExecutor(args = []) {
1228
1401
  if (readOption(args, '--sql', null))
1229
- return 'db-write';
1402
+ return 'sql-plane';
1230
1403
  if (readOption(args, '--command', null) || args.includes('--argv'))
1231
1404
  return 'shell-command';
1232
1405
  if (readOption(args, '--package', null) || args.includes('--allow-package-install'))
@@ -1241,6 +1414,34 @@ function inferMadSksExecutor(args = []) {
1241
1414
  return 'generated-asset';
1242
1415
  return 'file-write';
1243
1416
  }
1417
+ function positionalText(args = []) {
1418
+ const valueFlags = new Set([
1419
+ '--sql',
1420
+ '--verify-sql',
1421
+ '--rollback-sql',
1422
+ '--target-root',
1423
+ '--intent',
1424
+ '--executor',
1425
+ '--cwd',
1426
+ '--name',
1427
+ '--file',
1428
+ '--migration-file'
1429
+ ]);
1430
+ const out = [];
1431
+ for (let index = 0; index < args.length; index += 1) {
1432
+ const arg = String(args[index] || '');
1433
+ if (!arg || arg === '--json' || arg === '--yes' || arg === '-y' || arg === '--accept-not-rollbackable')
1434
+ continue;
1435
+ if (valueFlags.has(arg)) {
1436
+ index += 1;
1437
+ continue;
1438
+ }
1439
+ if (arg.startsWith('--'))
1440
+ continue;
1441
+ out.push(arg);
1442
+ }
1443
+ return out.join(' ').trim();
1444
+ }
1244
1445
  function readRepeatedOption(args = [], name) {
1245
1446
  const values = [];
1246
1447
  for (let i = 0; i < args.length; i += 1) {
@@ -1,4 +1,5 @@
1
1
  import path from 'node:path';
2
+ import { ui as cliUi } from '../../cli/cli-theme.js';
2
3
  import { projectRoot } from '../fsx.js';
3
4
  import { inspectSksMenuBarStatus, installSksMenuBar, restartSksMenuBar, uninstallSksMenuBar } from '../codex-app/sks-menubar.js';
4
5
  export async function menubarCommand(subcommand = 'status', args = []) {
@@ -9,15 +10,25 @@ export async function menubarCommand(subcommand = 'status', args = []) {
9
10
  const result = await inspectSksMenuBarStatus({ root, ...(home ? { home } : {}) });
10
11
  if (flag(args, '--json'))
11
12
  return printJson(result);
13
+ cliUi.banner('menubar status');
14
+ if (result.ok)
15
+ cliUi.ok(result.running ? 'running' : 'installed status checked');
16
+ else
17
+ cliUi.warn('needs attention');
12
18
  printStatus(result);
13
19
  if (!result.ok)
14
20
  process.exitCode = 1;
15
21
  return result;
16
22
  }
17
23
  if (action === 'install') {
18
- const result = await installSksMenuBar({ root, ...(home ? { home } : {}), apply: true, launch: !flag(args, '--no-launch') });
24
+ const result = await installSksMenuBar({ root, ...(home ? { home } : {}), apply: true, launch: !flag(args, '--no-launch'), quiet: flag(args, '--json') });
19
25
  if (flag(args, '--json'))
20
26
  return printJson(result);
27
+ cliUi.banner('menubar install');
28
+ if (result.ok)
29
+ cliUi.ok(result.status);
30
+ else
31
+ cliUi.fail(result.status);
21
32
  console.log(`SKS menu bar install: ${result.status}`);
22
33
  for (const actionLine of result.actions)
23
34
  console.log(`- ${actionLine}`);
@@ -33,6 +44,11 @@ export async function menubarCommand(subcommand = 'status', args = []) {
33
44
  const result = await restartSksMenuBar({ root, ...(home ? { home } : {}) });
34
45
  if (flag(args, '--json'))
35
46
  return printJson(result);
47
+ cliUi.banner('menubar restart');
48
+ if (result.ok)
49
+ cliUi.ok('restart requested');
50
+ else
51
+ cliUi.fail('restart failed');
36
52
  console.log(`SKS menu bar restart: ${result.ok ? 'ok' : 'failed'}`);
37
53
  if ('error' in result && result.error)
38
54
  console.log(`error: ${result.error}`);
@@ -44,6 +60,11 @@ export async function menubarCommand(subcommand = 'status', args = []) {
44
60
  const result = await uninstallSksMenuBar({ root, ...(home ? { home } : {}) });
45
61
  if (flag(args, '--json'))
46
62
  return printJson(result);
63
+ cliUi.banner('menubar uninstall');
64
+ if (result.ok)
65
+ cliUi.ok('uninstall complete');
66
+ else
67
+ cliUi.fail('uninstall failed');
47
68
  console.log(`SKS menu bar uninstall: ${result.ok ? 'ok' : 'failed'}`);
48
69
  for (const actionLine of result.actions)
49
70
  console.log(`- ${actionLine}`);
@@ -76,7 +97,8 @@ function printStatus(result) {
76
97
  console.log(`Running: ${result.running ? 'yes' : 'no'}`);
77
98
  console.log(`Launchd: ${result.launchd.ok ? result.launchd.state || 'present' : result.launchd.error || 'missing'}`);
78
99
  console.log(`Version: ${result.build_stamp?.package_version || 'unknown'} (package ${result.package_version})`);
79
- console.log(`Target: ${result.action_target.sks_entry || 'missing'} ${result.action_target.sks_entry_exists ? '(ok)' : '(missing)'}`);
100
+ console.log(`Target: ${result.action_target.sks_entry || 'runtime'} ${result.action_target.ok ? '(smoke ok)' : '(smoke failed)'}`);
101
+ console.log(`Codex sync:${result.codex_sync.bundle_id || 'disabled'} ${result.codex_sync.codex_running === null ? '' : result.codex_sync.codex_running ? '(running)' : '(not running)'}`);
80
102
  console.log(`Signature: ${result.signature.identifier || 'unknown'} ${result.signature.ok ? '(ok)' : '(check)'}`);
81
103
  if (result.warnings.length) {
82
104
  console.log('Warnings:');