sneakoscope 10.4.0 → 10.5.1

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 (127) hide show
  1. package/README.md +11 -4
  2. package/config/skills-hash-ledger.v1.json +2 -1
  3. package/crates/sks-core/Cargo.lock +1 -1
  4. package/crates/sks-core/Cargo.toml +1 -1
  5. package/dist/cli/feature-commands.js +0 -2
  6. package/dist/config/skills-manifest.json +5 -4
  7. package/dist/core/agents/native-cli-worker-runtime.js +0 -28
  8. package/dist/core/auto-review.js +3 -2
  9. package/dist/core/codex/codex-cli-syntax-builder.js +2 -1
  10. package/dist/core/codex/codex-cli-update.js +1 -2
  11. package/dist/core/codex/codex-config-toml.js +2 -2
  12. package/dist/core/codex/codex-feature-flags.js +2 -10
  13. package/dist/core/codex/codex-service-tier.js +4 -0
  14. package/dist/core/codex-adapter.js +1 -2
  15. package/dist/core/codex-app.js +3 -8
  16. package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
  17. package/dist/core/codex-lb/desktop-service.js +51 -5
  18. package/dist/core/codex-native/core-skill-manifest.js +2 -2
  19. package/dist/core/codex-runtime/codex-desktop-config-policy.js +7 -50
  20. package/dist/core/commands/command-utils.js +0 -10
  21. package/dist/core/commands/research-command.js +1 -3
  22. package/dist/core/commands/review-command.js +5 -25
  23. package/dist/core/decision-contract.js +0 -1
  24. package/dist/core/dfix.js +0 -102
  25. package/dist/core/doctor/browser-use-repair.js +3 -48
  26. package/dist/core/doctor/codex-config-syntax-repair.js +15 -29
  27. package/dist/core/doctor/computer-use-repair.js +1 -33
  28. package/dist/core/doctor/doctor-codex-startup-repair.js +1 -3
  29. package/dist/core/doctor/imagegen-repair.js +2 -28
  30. package/dist/core/hooks-runtime/hook-context.js +2 -10
  31. package/dist/core/hooks-runtime/jev-turn-plan.js +15 -3
  32. package/dist/core/hooks-runtime/subagent-spawn-policy.js +1 -1
  33. package/dist/core/hooks-runtime.js +7 -4
  34. package/dist/core/init/skills.js +1 -1
  35. package/dist/core/init.js +11 -101
  36. package/dist/core/loops/loop-artifacts.js +2 -59
  37. package/dist/core/loops/loop-schema.js +1 -62
  38. package/dist/core/pipeline-internals/runtime-core.js +1 -12
  39. package/dist/core/preflight/parallel-preflight-engine.js +2 -1
  40. package/dist/core/release/gate-pack-manifest.js +0 -4
  41. package/dist/core/routes.js +31 -16
  42. package/dist/core/runtime/task-profile.js +3 -0
  43. package/dist/core/rust-accelerator.js +1 -1
  44. package/dist/core/skills/core-skill-deployment.js +1 -18
  45. package/dist/core/skills/core-skill-types.js +0 -5
  46. package/dist/core/subagents/official-subagent-config.js +1 -11
  47. package/dist/core/subagents/official-subagent-prompt.js +1 -1
  48. package/dist/core/subagents/triwiki-attention.js +0 -112
  49. package/dist/core/triwiki/triwiki-module-card.js +0 -1
  50. package/dist/core/update/update-migration-state/fast-mode-config.js +2 -2
  51. package/dist/core/version.js +1 -1
  52. package/dist/scripts/codex-native-gate-lib.js +1 -15
  53. package/dist/scripts/codex-native-runtime-e2e-fixture.js +0 -1
  54. package/dist/scripts/fast-codex-service-tier-proof-check.js +1 -1
  55. package/dist/scripts/goal-artifact-compat-check.js +7 -2
  56. package/dist/scripts/harness-benchmark-check.js +0 -28
  57. package/dist/scripts/naruto-ssot-routing-check.js +4 -2
  58. package/dist/scripts/release-metadata-check.js +1 -2
  59. package/dist/scripts/runtime-domain-gate-lib.js +0 -22
  60. package/dist/scripts/typed-routing-gate-lib.js +1 -10
  61. package/package.json +4 -6
  62. package/release-gates.v2.json +4 -93
  63. package/runtime-required-scripts.json +0 -10
  64. package/dist/core/loops/loop-checkpoint.js +0 -18
  65. package/dist/core/loops/loop-concurrency-budget.js +0 -56
  66. package/dist/core/loops/loop-decomposer.js +0 -55
  67. package/dist/core/loops/loop-final-arbiter-contract.js +0 -27
  68. package/dist/core/loops/loop-finalizer.js +0 -75
  69. package/dist/core/loops/loop-fixture-policy.js +0 -57
  70. package/dist/core/loops/loop-gate-ladder.js +0 -11
  71. package/dist/core/loops/loop-gate-registry.js +0 -95
  72. package/dist/core/loops/loop-gate-runner.js +0 -278
  73. package/dist/core/loops/loop-gate-selector.js +0 -49
  74. package/dist/core/loops/loop-gpt-final-arbiter.js +0 -79
  75. package/dist/core/loops/loop-integration-merge.js +0 -79
  76. package/dist/core/loops/loop-interrupt-registry.js +0 -117
  77. package/dist/core/loops/loop-lease.js +0 -87
  78. package/dist/core/loops/loop-merge-strategy.js +0 -104
  79. package/dist/core/loops/loop-mutation-ledger.js +0 -102
  80. package/dist/core/loops/loop-owner-inference.js +0 -37
  81. package/dist/core/loops/loop-owner-ledger.js +0 -1
  82. package/dist/core/loops/loop-planner.js +0 -199
  83. package/dist/core/loops/loop-proof-summary.js +0 -9
  84. package/dist/core/loops/loop-proof.js +0 -1
  85. package/dist/core/loops/loop-risk-classifier.js +0 -33
  86. package/dist/core/loops/loop-runtime-control.js +0 -26
  87. package/dist/core/loops/loop-runtime.js +0 -327
  88. package/dist/core/loops/loop-scheduler.js +0 -73
  89. package/dist/core/loops/loop-side-effect-scanner.js +0 -87
  90. package/dist/core/loops/loop-state.js +0 -60
  91. package/dist/core/loops/loop-worker-prompts.js +0 -44
  92. package/dist/core/loops/loop-worker-runtime.js +0 -300
  93. package/dist/core/loops/loop-worktree-runtime.js +0 -139
  94. package/dist/core/naruto/naruto-active-pool.js +0 -144
  95. package/dist/core/naruto/naruto-generation-scheduler.js +0 -17
  96. package/dist/core/naruto/naruto-loop-mesh.js +0 -41
  97. package/dist/core/naruto/naruto-loop-worker-router.js +0 -37
  98. package/dist/core/naruto/naruto-parallel-patch-apply.js +0 -78
  99. package/dist/core/naruto/naruto-patch-transaction-batch.js +0 -41
  100. package/dist/core/naruto/naruto-real-write-proof.js +0 -80
  101. package/dist/core/naruto/naruto-role-policy.js +0 -33
  102. package/dist/core/naruto/naruto-work-graph.js +0 -281
  103. package/dist/core/naruto/naruto-write-e2e.js +0 -500
  104. package/dist/core/python-tools/python-tool-runner.js +0 -32
  105. package/dist/core/skills/core-rollout-trace.js +0 -22
  106. package/dist/core/skills/core-skill-epoch.js +0 -63
  107. package/dist/core/skills/core-skill-meta-update.js +0 -17
  108. package/dist/core/skills/core-skill-patch-apply.js +0 -92
  109. package/dist/core/skills/core-skill-patch.js +0 -104
  110. package/dist/core/skills/core-skill-reflection.js +0 -77
  111. package/dist/core/skills/core-skill-scorer.js +0 -70
  112. package/dist/core/skills/core-skill-trainer.js +0 -91
  113. package/dist/core/skills/core-skill-validation.js +0 -24
  114. package/dist/core/skills/rejected-skill-patch-buffer.js +0 -29
  115. package/dist/scripts/core-skill-heldout-validation-check.js +0 -37
  116. package/dist/scripts/core-skill-no-inference-optimizer-check.js +0 -63
  117. package/dist/scripts/core-skill-patch-check.js +0 -67
  118. package/dist/scripts/loop-directive-check-lib.js +0 -455
  119. package/dist/scripts/loop-integration-finalizer-check.js +0 -2
  120. package/dist/scripts/loop-worker-fixture-child.js +0 -52
  121. package/dist/scripts/pipeline-codex-native-loop-routing-check.js +0 -3
  122. package/dist/scripts/pipeline-codex-native-loop-routing-real-blackbox.js +0 -52
  123. package/schemas/loops/loop-node.schema.json +0 -21
  124. package/schemas/loops/loop-plan.schema.json +0 -21
  125. package/schemas/loops/loop-proof.schema.json +0 -20
  126. package/schemas/loops/loop-state.schema.json +0 -19
  127. package/schemas/skills/core-skill-patch.schema.json +0 -39
package/README.md CHANGED
@@ -16,7 +16,7 @@
16
16
  Sneakoscope Codex (`sks`) is an open-source trust layer for Codex CLI and ChatGPT Desktop. It coordinates bounded AI coding agents, records machine-verifiable evidence, preserves project memory, and blocks release claims that are not supported by current tests or artifacts. Search visibility outcomes are measured separately; SKS does not promise rankings or traffic.
17
17
  <!-- END SKS SEARCH VISIBILITY MARKETING -->
18
18
 
19
- Current package: **SKS 10.4.0**. Install the latest stable release from npm.
19
+ Current package: **SKS 10.5.1**. Install the latest stable release from npm.
20
20
 
21
21
  [Quick start](#install-in-one-command) · [Commands](#everyday-commands) · [SKS Center](#sks-center-macos) · [Documentation](#documentation) · [Changelog](CHANGELOG.md)
22
22
 
@@ -170,9 +170,16 @@ sidecars, and the Jev choices.
170
170
 
171
171
  ## Naruto workflow
172
172
 
173
- The parent orchestrates: it decomposes the task, spawns a child for each
174
- disjoint slice, waits, and owns integration and final verification. It does not
175
- implement slices itself. The SKS PreToolUse hook denies parent source edits
173
+ Naruto is for work you ask to split, not the default for implementation. A bug
174
+ fix, a test, a refactor or config change, or a review is the main agent's own
175
+ job, the way Codex works by default: no mission, no subagent plan, no parent edit
176
+ gate. Naruto runs when you invoke `$sks-naruto`, pass `--agents N`, or ask for
177
+ subagents or parallel work in so many words, and, with Jev mode on, when Jev
178
+ judges that the task splits into independent parts (single is its default).
179
+
180
+ Inside Naruto the parent orchestrates: it decomposes the task, spawns a child for
181
+ each disjoint slice, waits, and owns integration and final verification. It does
182
+ not implement slices itself. The SKS PreToolUse hook denies parent source edits
176
183
  until the first child starts and while children are still running. Children
177
184
  receive bounded tasks and do not spawn children.
178
185
 
@@ -335,6 +335,7 @@
335
335
  {
336
336
  "canonical_name": "sks-naruto",
337
337
  "trusted_sha256": [
338
+ "26528b6b7d063c7cf0b5b9e996947d504cbc7ef4af976e480b5df3e6c7fcbac9",
338
339
  "5ac4c3ea1d4478f12f55df3c3d6c4ab272a40f731de8aa659aee08cb8e517a8b",
339
340
  "c88999663811a50d096b7cbb696fbea5b8f72707bcbf4a232bb07fe3a10cb2a6",
340
341
  "b2eb207b2773ab1995ee6e113ba6f3b64de43389e76aef4a0f06d4845ff86223",
@@ -342,7 +343,6 @@
342
343
  "da43debf97f0b4a1583d8202a7306aca97ac97865accf9bca8f41d75c84a1cb9",
343
344
  "b981bea4183376c6c0204941ad6c2e78782e2cdea4f8d25cc85630c609faaf95",
344
345
  "5df9c9678eb68fd79ceb998ae7a52dd54dc92336ad5169e8a01acca89f76bd60",
345
- "a1219f6dbad9c8c185953125ef0b8dccf081aa01efb8e8acaa543c6214ac049c",
346
346
  "49b5e3dcc1b537b49c2cf09e5b875cb16acb05c622b22798e265e64dacd8ac90"
347
347
  ]
348
348
  },
@@ -388,6 +388,7 @@
388
388
  {
389
389
  "canonical_name": "sks-prompt-pipeline",
390
390
  "trusted_sha256": [
391
+ "01b0d58e26d4493442041d1cd51b4a25ac15014be79b065a59520e21ef69a4b1",
391
392
  "5e423981384fc3825c74327c4ca0fe09905a0dc81a533676c7e76ebb385348fc",
392
393
  "f82a103e7962e416961add515d7b3e65df89848dec1fbb9319bd49d7f1dac982",
393
394
  "93fd938dccd65d9b4d1dd140b60e1baedc627e7fcc54f9afd95eb2e44efd1143",
@@ -259,7 +259,7 @@ dependencies = [
259
259
 
260
260
  [[package]]
261
261
  name = "sks-core"
262
- version = "10.4.0"
262
+ version = "10.5.1"
263
263
  dependencies = [
264
264
  "globset",
265
265
  "grep-matcher",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "sks-core"
3
- version = "10.4.0"
3
+ version = "10.5.1"
4
4
  edition = "2021"
5
5
 
6
6
  [dependencies]
@@ -280,8 +280,6 @@ async function hooksTrustReport(root) {
280
280
  { event: 'PreToolUse', command: 'sks hook pre-tool', writes: ['.sneakoscope/bus/tool-events.jsonl'], network: false, secret_policy: 'redacted', risk: 'medium' },
281
281
  { event: 'PermissionRequest', command: 'sks hook permission-request', writes: ['.sneakoscope/state'], network: false, secret_policy: 'redacted', risk: 'medium' },
282
282
  { event: 'PostToolUse', command: 'sks hook post-tool', writes: ['.sneakoscope/missions'], network: false, secret_policy: 'redacted', risk: 'medium' },
283
- { event: 'PreCompact', command: 'sks hook pre-compact', writes: ['.sneakoscope/state'], network: false, secret_policy: 'redacted', risk: 'low' },
284
- { event: 'PostCompact', command: 'sks hook post-compact', writes: ['.sneakoscope/state'], network: false, secret_policy: 'redacted', risk: 'low' },
285
283
  { event: 'UserPromptSubmit', command: 'sks hook user-prompt-submit', writes: ['.sneakoscope/missions'], network: false, secret_policy: 'redacted', risk: 'medium' },
286
284
  { event: 'SubagentStart', command: 'sks hook subagent-start', writes: ['.sneakoscope/missions'], network: false, secret_policy: 'redacted', risk: 'low' },
287
285
  { event: 'SubagentStop', command: 'sks hook subagent-stop', writes: ['.sneakoscope/missions'], network: false, secret_policy: 'redacted', risk: 'low' },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schema": "sks.skills-manifest.v1",
3
- "package_version": "10.4.0",
3
+ "package_version": "10.5.1",
4
4
  "skills": [
5
5
  {
6
6
  "canonical_name": "sks",
@@ -404,15 +404,15 @@
404
404
  {
405
405
  "canonical_name": "sks-naruto",
406
406
  "type": "core",
407
- "content_sha256": "5ac4c3ea1d4478f12f55df3c3d6c4ab272a40f731de8aa659aee08cb8e517a8b",
407
+ "content_sha256": "26528b6b7d063c7cf0b5b9e996947d504cbc7ef4af976e480b5df3e6c7fcbac9",
408
408
  "hash_history": [
409
+ "5ac4c3ea1d4478f12f55df3c3d6c4ab272a40f731de8aa659aee08cb8e517a8b",
409
410
  "c88999663811a50d096b7cbb696fbea5b8f72707bcbf4a232bb07fe3a10cb2a6",
410
411
  "b2eb207b2773ab1995ee6e113ba6f3b64de43389e76aef4a0f06d4845ff86223",
411
412
  "65e19a5d16f486b13541048c239e828f8039bfc6e38bafd7949d9c936fe4b5b2",
412
413
  "da43debf97f0b4a1583d8202a7306aca97ac97865accf9bca8f41d75c84a1cb9",
413
414
  "b981bea4183376c6c0204941ad6c2e78782e2cdea4f8d25cc85630c609faaf95",
414
415
  "5df9c9678eb68fd79ceb998ae7a52dd54dc92336ad5169e8a01acca89f76bd60",
415
- "a1219f6dbad9c8c185953125ef0b8dccf081aa01efb8e8acaa543c6214ac049c",
416
416
  "49b5e3dcc1b537b49c2cf09e5b875cb16acb05c622b22798e265e64dacd8ac90"
417
417
  ],
418
418
  "deprecated_aliases": []
@@ -467,8 +467,9 @@
467
467
  {
468
468
  "canonical_name": "sks-prompt-pipeline",
469
469
  "type": "official",
470
- "content_sha256": "5e423981384fc3825c74327c4ca0fe09905a0dc81a533676c7e76ebb385348fc",
470
+ "content_sha256": "01b0d58e26d4493442041d1cd51b4a25ac15014be79b065a59520e21ef69a4b1",
471
471
  "hash_history": [
472
+ "5e423981384fc3825c74327c4ca0fe09905a0dc81a533676c7e76ebb385348fc",
472
473
  "f82a103e7962e416961add515d7b3e65df89848dec1fbb9319bd49d7f1dac982",
473
474
  "93fd938dccd65d9b4d1dd140b60e1baedc627e7fcc54f9afd95eb2e44efd1143",
474
475
  "033bb114ec1fac3f8c312f698b1861ed4c2ce6f65c06f4f1a872c4b101b74b92",
@@ -6,7 +6,6 @@ import { fastModeEnv } from './fast-mode-policy.js';
6
6
  import { validateAgentWorkerResult } from './agent-worker-pipeline.js';
7
7
  import { appendParallelRuntimeEvent } from './parallel-runtime-proof.js';
8
8
  import { appendAgentMessage } from './agent-message-bus.js';
9
- import { markLoopWorkerInterrupted, registerLoopActiveWorker } from '../loops/loop-interrupt-registry.js';
10
9
  export const NATIVE_CLI_WORKER_RUNTIME_SCHEMA = 'sks.native-cli-worker-runtime.v3';
11
10
  export const NATIVE_CLI_WORKER_DEFAULT_TIMEOUT_MS = 60 * 60 * 1000;
12
11
  export const NATIVE_CLI_WORKER_TIMEOUT_BLOCKER = 'native_cli_worker_timeout';
@@ -140,16 +139,8 @@ class NativeCliWorkerRuntimeRecorder {
140
139
  this.active.add(child.pid);
141
140
  this.maxObserved = Math.max(this.maxObserved, this.active.size);
142
141
  let exit;
143
- let loopHandle = null;
144
142
  try {
145
143
  await this.record(record);
146
- loopHandle = await registerLoopWorkerHandle({
147
- root: ctx.opts.projectRoot || this.input.projectRoot || ctx.opts.cwd || packageRoot(),
148
- env: ctx.opts.env || {},
149
- agentId: String(ctx.agent.id || ctx.agent.session_id || 'agent'),
150
- sessionId: ctx.agent.session_id || null,
151
- pid: child.pid || null
152
- });
153
144
  await appendParallelRuntimeEvent(this.root, this.input.missionId, {
154
145
  event_type: 'worker_process_spawned',
155
146
  slot_id: ctx.agent.slot_id || ctx.agent.id || null,
@@ -184,9 +175,6 @@ class NativeCliWorkerRuntimeRecorder {
184
175
  const timeoutBlockers = supervisor.timedOut ? [NATIVE_CLI_WORKER_TIMEOUT_BLOCKER] : [];
185
176
  if (supervisor.timedOut)
186
177
  record.status = 'failed';
187
- if (loopHandle) {
188
- await markLoopWorkerInterrupted(ctx.opts.projectRoot || this.input.projectRoot || ctx.opts.cwd || packageRoot(), loopHandle.mission_id, loopHandle.worker_id, record.status === 'closed' ? 'completed' : 'failed').catch(() => undefined);
189
- }
190
178
  const parsed = await readJson(path.join(this.root, resultRel), null).catch(() => null);
191
179
  if (!parsed) {
192
180
  record.blockers = [...timeoutBlockers, 'native_cli_worker_result_missing'];
@@ -385,19 +373,3 @@ function changedFilesFromWorkerResult(result) {
385
373
  ]);
386
374
  return [...new Set([...direct, ...envelopeFiles].map((file) => String(file || '').replace(/\\/g, '/').replace(/^\.\/+/, '')).filter(Boolean))];
387
375
  }
388
- async function registerLoopWorkerHandle(input) {
389
- const missionId = String(input.env.SKS_MISSION_ID || input.env.SKS_PARENT_MISSION_ID || '').trim();
390
- const loopId = String(input.env.SKS_LOOP_ID || '').trim();
391
- const phase = String(input.env.SKS_LOOP_PHASE || '').trim();
392
- if (!missionId || !loopId || (phase !== 'maker' && phase !== 'checker'))
393
- return null;
394
- return registerLoopActiveWorker(input.root, {
395
- mission_id: missionId,
396
- loop_id: loopId,
397
- phase,
398
- worker_id: input.agentId,
399
- session_id: input.sessionId,
400
- pid: input.pid,
401
- interrupt_supported: Boolean(input.pid || input.sessionId)
402
- }).catch(() => null);
403
- }
@@ -3,6 +3,7 @@ import path from 'node:path';
3
3
  import { createHash } from 'node:crypto';
4
4
  import { ensureDir, exists, readText, writeTextAtomic } from './fsx.js';
5
5
  import { writeCodexConfigGuarded } from './codex/codex-config-guard.js';
6
+ import { CODEX_FAST_SERVICE_TIER_ID } from './codex/codex-service-tier.js';
6
7
  import { inspectConfinedPath, removeManagedPathVerified } from './managed-path-safety.js';
7
8
  import { RETIRED_AUTO_REVIEW_POLICY_TEXTS, RETIRED_SKS_CONFIG_PROFILE_NAMES } from './doctor/retired-auto-review-config.js';
8
9
  import { escapeRegExp } from './text/regex.js';
@@ -217,7 +218,7 @@ export function buildMadHighLaunchProfileNoWrite(opts = {}) {
217
218
  '--ask-for-approval',
218
219
  'never',
219
220
  '-c',
220
- 'service_tier=fast',
221
+ `service_tier=${CODEX_FAST_SERVICE_TIER_ID}`,
221
222
  '-c',
222
223
  'model_reasoning_effort=xhigh'
223
224
  ],
@@ -254,7 +255,7 @@ export async function ensureMadHighProfileForSetupOrRepair(opts = {}) {
254
255
  config_path: configPath,
255
256
  profile_config_path: path.join(path.dirname(configPath), `${MAD_HIGH_PROFILE}.config.toml`),
256
257
  profile_name: MAD_HIGH_PROFILE,
257
- launch_args: ['--profile', MAD_HIGH_PROFILE, '--sandbox', 'danger-full-access', '--ask-for-approval', 'never', '-c', 'service_tier=fast', '-c', 'model_reasoning_effort=xhigh'],
258
+ launch_args: ['--profile', MAD_HIGH_PROFILE, '--sandbox', 'danger-full-access', '--ask-for-approval', 'never', '-c', `service_tier=${CODEX_FAST_SERVICE_TIER_ID}`, '-c', 'model_reasoning_effort=xhigh'],
258
259
  sandbox_mode: 'danger-full-access',
259
260
  approval_policy: 'never',
260
261
  approvals_reviewer: AUTO_REVIEW_REVIEWER,
@@ -1,3 +1,4 @@
1
+ import { codexServiceTierId } from './codex-service-tier.js';
1
2
  export function buildCodexExecArgs(opts) {
2
3
  if (opts.danger && !opts.allowDanger) {
3
4
  throw new Error('codex exec danger mode requires explicit allowDanger=true');
@@ -30,7 +31,7 @@ export function buildCodexExecArgs(opts) {
30
31
  args.push('--sandbox', opts.sandbox);
31
32
  const serviceTier = normalizeCodexServiceTier(opts.serviceTier);
32
33
  if (serviceTier)
33
- args.push('-c', `service_tier=${serviceTier}`);
34
+ args.push('-c', `service_tier=${codexServiceTierId(serviceTier)}`);
34
35
  args.push(opts.prompt);
35
36
  return args;
36
37
  }
@@ -371,8 +371,7 @@ async function operatorCodexCandidates(explicitBin, env) {
371
371
  explicitBin,
372
372
  env.SKS_CODEX_UPDATE_BIN,
373
373
  env.SKS_CODEX_BIN,
374
- env.CODEX_BIN,
375
- env.DCODEX_CODEX_BIN
374
+ env.CODEX_BIN
376
375
  ];
377
376
  for (const value of explicitValues) {
378
377
  const raw = String(value || '').trim();
@@ -26,8 +26,8 @@ export function validateCodexConfigRoundTrip(text = '') {
26
26
  legacyKeys.push('user.fast_mode');
27
27
  if (parsed.profiles !== undefined)
28
28
  legacyKeys.push('profiles');
29
- if (parsed.notice?.fast_default_opt_out !== undefined)
30
- legacyKeys.push('notice.fast_default_opt_out');
29
+ if (parsed.features?.fast_mode_ui !== undefined)
30
+ legacyKeys.push('features.fast_mode_ui');
31
31
  const blockers = modelProviderAuthConflicts(parsed);
32
32
  return {
33
33
  ok: blockers.length === 0,
@@ -1,10 +1,2 @@
1
- export const MANAGED_CODEX_FEATURE_FLAGS = Object.freeze(['hooks', 'fast_mode', 'apps']);
2
- export const REMOVED_CODEX_FEATURE_FLAGS = Object.freeze([
3
- 'fast_mode_ui',
4
- 'codex_hooks',
5
- 'multi_agent_mode',
6
- 'remote_control',
7
- 'codex_git_commit',
8
- 'plugin_hooks',
9
- 'js_repl'
10
- ]);
1
+ export const REMOVED_CODEX_FEATURE_FLAGS = Object.freeze(['fast_mode_ui']);
2
+ export const DEPRECATED_CODEX_HOOKS_ALIAS_FLAG = 'codex_hooks';
@@ -0,0 +1,4 @@
1
+ export function codexServiceTierId(tier) {
2
+ return tier === 'fast' ? 'priority' : 'default';
3
+ }
4
+ export const CODEX_FAST_SERVICE_TIER_ID = codexServiceTierId('fast');
@@ -7,7 +7,6 @@ import { desktopBridgeLaunchBlockedProcessResult, withDesktopBridgeCliLaunchGuar
7
7
  import { prepareCodexAppServerRuntimeEnv } from './codex-control/codex-app-server-runtime-env.js';
8
8
  export async function findCodexBinary() {
9
9
  const resolved = await resolveCodexRuntime({
10
- explicitPath: process.env.DCODEX_CODEX_BIN || null,
11
10
  requestedBy: 'codex-adapter'
12
11
  });
13
12
  return resolved.identity?.realpath || null;
@@ -43,7 +42,7 @@ export function buildCodexExecArgs({ root, prompt, outputFile, json = true, prof
43
42
  }
44
43
  export async function runCodexExec({ root, recoveryRoot = root, prompt, outputFile, json = true, profile = null, extraArgs = [], onStdout, onStderr, logDir = null, stdoutFile = null, stderrFile = null, maxBufferBytes = 256 * 1024, timeoutMs = null, env = process.env, codexBin = null, findCodexBinaryImpl = findCodexBinary, runProcessImpl = runProcess, prepareCodexRuntimeEnvImpl = prepareCodexAppServerRuntimeEnv }) {
45
44
  const args = buildCodexExecArgs({ root, prompt, outputFile, json, profile, extraArgs });
46
- const effectiveTimeoutMs = Number(timeoutMs || process.env.SKS_CODEX_TIMEOUT_MS || process.env.DCODEX_CODEX_TIMEOUT_MS || 30 * 60 * 1000);
45
+ const effectiveTimeoutMs = Number(timeoutMs || process.env.SKS_CODEX_TIMEOUT_MS || 30 * 60 * 1000);
47
46
  const recoveryArgs = args.slice(1, -1);
48
47
  const runtimeEnv = await prepareCodexRuntimeEnvImpl({ env });
49
48
  const guarded = await withDesktopBridgeCliLaunchGuard({
@@ -15,7 +15,6 @@ export const CODEX_CHANGELOG_URL = 'https://developers.openai.com/codex/changelo
15
15
  export const CODEX_ACCESS_TOKENS_DOCS_URL = 'https://developers.openai.com/codex/enterprise/access-tokens';
16
16
  export const CODEX_CHROME_EXTENSION_SETUP_DOCS_URL = CODEX_CHROME_EXTENSION_DOC_URL;
17
17
  const REQUIRED_CODEX_APP_FEATURE_FLAGS = [
18
- 'codex_git_commit',
19
18
  'hooks',
20
19
  'fast_mode',
21
20
  'computer_use',
@@ -487,7 +486,7 @@ export function codexAppGuidance({ appInstalled, codex, mcpList, featureList, re
487
486
  if (featureList?.checked && featureList.ok && !requiredFeatureFlagsOk) {
488
487
  const missing = missingRequiredFeatureFlags(requiredFeatureFlags);
489
488
  lines.push(`Codex App feature flag(s) disabled or missing: ${missing.join(', ')}. Commit message generation, mobile/remote-control, and app-only tool paths can fail even when CLI chat works.`);
490
- lines.push('Verify with: codex features list | rg "codex_git_commit|hooks|fast_mode|computer_use|browser_use|browser_use_external|image_generation|in_app_browser|guardian_approval|tool_suggest|apps|plugins"');
489
+ lines.push('Verify with: codex features list | rg "hooks|fast_mode|computer_use|browser_use|browser_use_external|image_generation|in_app_browser|guardian_approval|tool_suggest|apps|plugins"');
491
490
  }
492
491
  if (defaultPlugins?.missing_enabled?.length) {
493
492
  lines.push(`Codex default plugin(s) installed but not enabled: ${defaultPlugins.missing_enabled.join(', ')}. Composer/tool UI can hide built-in surfaces even while feature flags look green.`);
@@ -530,7 +529,7 @@ export function codexAppGuidance({ appInstalled, codex, mcpList, featureList, re
530
529
  lines.push('Run: sks bridge provider configure; sks bridge provider validate; sks bridge provider enable; sks bridge catalog sync; sks bridge route set-default.');
531
530
  }
532
531
  if (!gitActions?.ok) {
533
- lines.push(`Codex App git commit/push actions are blocked: ${gitActions?.blockers?.join(', ') || 'git action readiness'}. The app Commit, Push, Commit and Push, and PR flows need codex_git_commit, hooks, and Codex CLI remote-control support.`);
532
+ lines.push(`Codex App git commit/push actions are blocked: ${gitActions?.blockers?.join(', ') || 'git action readiness'}. The app Commit, Push, Commit and Push, and PR flows need the hooks feature and Codex CLI remote-control support.`);
534
533
  lines.push('Run: sks doctor --fix; if remote-control is still blocked, update Codex CLI to the official latest stable release and restart older app-server/TUI sessions.');
535
534
  }
536
535
  else {
@@ -649,8 +648,6 @@ function missingRequiredFeatureFlags(flags = {}) {
649
648
  }
650
649
  export function codexGitActionReadiness({ requiredFeatureFlags = {}, remoteControl = {} } = {}) {
651
650
  const blockers = [];
652
- if (requiredFeatureFlags.codex_git_commit !== true)
653
- blockers.push('codex_git_commit');
654
651
  if (requiredFeatureFlags.hooks !== true)
655
652
  blockers.push('hooks');
656
653
  if (!remoteControl?.ok)
@@ -663,7 +660,7 @@ export function codexGitActionReadiness({ requiredFeatureFlags = {}, remoteContr
663
660
  push: ok,
664
661
  commit_push: ok,
665
662
  pull_request: ok,
666
- required_flags: ['codex_git_commit', 'hooks'],
663
+ required_flags: ['hooks'],
667
664
  required_capabilities: ['codex_cli_remote_control']
668
665
  };
669
666
  }
@@ -839,8 +836,6 @@ async function codexFastModeConfigStatus(opts = {}) {
839
836
  blockers.push(`${config.scope}:top_level_model_reasoning_effort`);
840
837
  }
841
838
  }
842
- if (/(^|\n)\s*fast_default_opt_out\s*=\s*true\s*(?:#.*)?(?=\n|$)/.test(tomlTable(config.text, 'notice')))
843
- blockers.push(`${config.scope}:fast_default_opt_out`);
844
839
  }
845
840
  const merged = configs.map((config) => config.text).join('\n');
846
841
  if (tomlTable(merged, 'user.fast_mode').trim())
@@ -1,5 +1,6 @@
1
1
  import { mapCodexSdkSandboxPolicy } from './codex-sdk-sandbox-policy.js';
2
2
  import { parseGptModelId } from '../subagents/model-tiers.js';
3
+ import { codexServiceTierId } from '../codex/codex-service-tier.js';
3
4
  export function buildCodexSdkConfig(input) {
4
5
  const model = String(input.model || process.env.SKS_CODEX_MODEL || process.env.CODEX_MODEL || '').trim();
5
6
  const serviceTier = String(input.serviceTier || process.env.SKS_SERVICE_TIER || 'fast');
@@ -7,7 +8,7 @@ export function buildCodexSdkConfig(input) {
7
8
  const config = {
8
9
  model_provider: 'openai',
9
10
  forced_login_method: 'chatgpt',
10
- service_tier: serviceTier === 'standard' ? 'standard' : 'fast',
11
+ service_tier: codexServiceTierId(serviceTier === 'standard' ? 'standard' : 'fast'),
11
12
  model_reasoning_effort: normalizeAstraSdkEffort(model, effort),
12
13
  mcp_servers: {},
13
14
  sks: {
@@ -21,6 +21,8 @@ export const DEFAULT_DESKTOP_BRIDGE_HOST = '127.0.0.1';
21
21
  export const DEFAULT_DESKTOP_BRIDGE_PORT = 49_152;
22
22
  export const DESKTOP_BRIDGE_SETTINGS_SCHEMA = 'sks.desktop-bridge-settings.v2';
23
23
  export const DESKTOP_BRIDGE_SERVICE_SCHEMA = 'sks.desktop-bridge-service.v2';
24
+ export const DESKTOP_BRIDGE_SETTINGS_MAX_BYTES = 256 * 1024;
25
+ const DESKTOP_BRIDGE_SETTINGS_RECOVERY_MAX_BYTES = 2 * 1024 * 1024;
24
26
  const DEFAULT_ALLOWED_ORIGINS = ['app://codex'];
25
27
  const OPENROUTER_BASE_URL = 'https://openrouter.ai/api/v1';
26
28
  export function desktopBridgeServicePaths(home = process.env.HOME || os.homedir()) {
@@ -147,8 +149,11 @@ export async function readDesktopBridgeServiceSettings(file) {
147
149
  throw new Error('desktop_bridge_settings_not_regular_file');
148
150
  if ((stat.mode & 0o077) !== 0)
149
151
  throw new Error('desktop_bridge_settings_permissions_unsafe');
152
+ if (stat.size > DESKTOP_BRIDGE_SETTINGS_RECOVERY_MAX_BYTES)
153
+ throw new Error('desktop_bridge_settings_too_large');
150
154
  const raw = await fsp.readFile(file, 'utf8');
151
- if (Buffer.byteLength(raw) > 256 * 1024)
155
+ const rawBytes = Buffer.byteLength(raw);
156
+ if (rawBytes > DESKTOP_BRIDGE_SETTINGS_RECOVERY_MAX_BYTES)
152
157
  throw new Error('desktop_bridge_settings_too_large');
153
158
  let parsed;
154
159
  try {
@@ -157,17 +162,58 @@ export async function readDesktopBridgeServiceSettings(file) {
157
162
  catch {
158
163
  throw new Error('desktop_bridge_settings_invalid_json');
159
164
  }
160
- return validateDesktopBridgeServiceSettings(parsed);
165
+ const validated = validateDesktopBridgeServiceSettings(parsed);
166
+ return rawBytes <= DESKTOP_BRIDGE_SETTINGS_MAX_BYTES ? validated : sessionPinsThatFit(validated);
161
167
  }
162
168
  export async function writeDesktopBridgeServiceSettings(file, settings) {
163
169
  await withFileLock(settingsLockOptions(file), async () => {
164
170
  await writeDesktopBridgeServiceSettingsUnlocked(file, settings);
165
171
  });
166
172
  }
173
+ function desktopBridgeSettingsDocument(settings) {
174
+ return {
175
+ schema: settings.schema,
176
+ listen_host: settings.listen_host,
177
+ listen_port: settings.listen_port,
178
+ provider_registry: settings.provider_registry,
179
+ route_policy: settings.route_policy,
180
+ provider_session_pins: settings.provider_session_pins,
181
+ client_capability_sha256: settings.client_capability_sha256,
182
+ allowed_origins: settings.allowed_origins,
183
+ connect_timeout_ms: settings.connect_timeout_ms,
184
+ idle_timeout_ms: settings.idle_timeout_ms,
185
+ official_passthrough: settings.official_passthrough,
186
+ auth_priority_enabled: settings.auth_priority_enabled ?? false
187
+ };
188
+ }
189
+ function desktopBridgeSettingsText(settings) {
190
+ return `${JSON.stringify(desktopBridgeSettingsDocument(settings), null, 2)}\n`;
191
+ }
192
+ export function sessionPinsThatFit(settings, maxBytes = DESKTOP_BRIDGE_SETTINGS_MAX_BYTES) {
193
+ if (Buffer.byteLength(desktopBridgeSettingsText(settings)) <= maxBytes)
194
+ return settings;
195
+ const pins = settings.provider_session_pins
196
+ .map((pin, index) => ({ pin, index }))
197
+ .sort((left, right) => Date.parse(right.pin.created_at) - Date.parse(left.pin.created_at) || left.index - right.index)
198
+ .map((row) => row.pin);
199
+ let lo = 0;
200
+ let hi = pins.length;
201
+ while (lo < hi) {
202
+ const mid = Math.ceil((lo + hi) / 2);
203
+ const size = Buffer.byteLength(desktopBridgeSettingsText({ ...settings, provider_session_pins: pins.slice(0, mid) }));
204
+ if (size <= maxBytes)
205
+ lo = mid;
206
+ else
207
+ hi = mid - 1;
208
+ }
209
+ const fitted = { ...settings, provider_session_pins: pins.slice(0, lo) };
210
+ if (Buffer.byteLength(desktopBridgeSettingsText(fitted)) > maxBytes)
211
+ throw new Error('desktop_bridge_settings_too_large');
212
+ return fitted;
213
+ }
167
214
  async function writeDesktopBridgeServiceSettingsUnlocked(file, settings) {
168
- const validated = validateDesktopBridgeServiceSettings(settings);
169
- const persisted = { schema: validated.schema, listen_host: validated.listen_host, listen_port: validated.listen_port, provider_registry: validated.provider_registry, route_policy: validated.route_policy, provider_session_pins: validated.provider_session_pins, client_capability_sha256: validated.client_capability_sha256, allowed_origins: validated.allowed_origins, connect_timeout_ms: validated.connect_timeout_ms, idle_timeout_ms: validated.idle_timeout_ms, official_passthrough: validated.official_passthrough, auth_priority_enabled: validated.auth_priority_enabled ?? false };
170
- await writeTextAtomic(file, `${JSON.stringify(persisted, null, 2)}\n`, { mode: 0o600 });
215
+ const validated = sessionPinsThatFit(validateDesktopBridgeServiceSettings(settings));
216
+ await writeTextAtomic(file, desktopBridgeSettingsText(validated), { mode: 0o600 });
171
217
  await fsp.chmod(file, 0o600);
172
218
  }
173
219
  async function runtimeCredentials(settings, options) {
@@ -13,8 +13,8 @@ const CORE_SKILL_DEFINITIONS = [
13
13
  display_name: 'naruto',
14
14
  route: '$Naruto',
15
15
  purpose: 'run a Codex official subagent workflow with official agent threads while parent integration remains owner.',
16
- discovery: 'Run $sks-naruto to delegate implementation to child subagents.',
17
- when: 'Use when the user invokes $sks-naruto or $sks-work, or the selected route is Naruto: ordinary implementation work, where the parent orchestrates and children implement.',
16
+ discovery: 'Run $sks-naruto to split independent work across subagents.',
17
+ when: 'Use when the user invokes $sks-naruto or $sks-work, asks for subagents or parallel work, or the selected route is Naruto: work that splits into independent parts, where the parent orchestrates and children implement.',
18
18
  workflow: 'Run sks naruto run "<task>" [--agents N] [--max-threads N] [--json] with Codex official subagent threads only. The parent orchestrates only: decompose, assign disjoint slices, spawn, integrate, and verify. Do not implement slice work in the parent thread; the SKS PreToolUse gate denies parent-thread source edits until the first child thread starts and while children are still running, and .sneakoscope artifacts stay parent-writable. The parent owns decomposition, per-wave capacity, later root-owned waves, integration, and final verification. Automatic targets begin at 4/6/8/16 by task size: bounded, explicit parallel, large-scale, then mass mechanical or exploration fan-out. After decomposition both lanes may expand to the SKS-owned 256-child ceiling when independent useful slices and real host capacity remain positive; max_threads defaults to a 256-child frame budget cap, never a target. A measured lower Codex host cap or explicit provider/API budget remains authoritative, and multi-wave scheduling reuses returned capacity. Every child runs the newest model of the tier its work needs (fast, balanced, context, or deep); no model family is pinned. When Jev mode is on, Jev picks the tier for each new spawn and SKS seals it, except a spawn that names a managed role, which runs the tier pinned in its role file. A user role preference stays authoritative. Do not choose child models yourself. Keep the four task-class profiles and compatibility IDs; max_depth=1 blocks nested delegation. Wait for every planned thread before final. In an active Codex App Naruto mission, commit the strict parent evidence with sks naruto parent-summary --mission <id> --stdin, then return localized Markdown without exposing the JSON.',
19
19
  safety: 'Preserve user-authored content, inherit the parent permission mode, do not spawn nested subagents, do not inject the full pack or the full TriWiki context into every child, and do not fall back to another model, process runtime, custom scheduler, or worker pool. Official Codex subagent threads are the only worker runtime; stop with explicit blocker evidence when the official path is unavailable.',
20
20
  cli: 'sks naruto run "<task>" [--agents N] [--max-threads N] [--json]; sks naruto status|subagents|proof [--mission <id>] [--json]; sks naruto parent-summary --mission <id> --stdin [--json]',
@@ -5,6 +5,8 @@ import { DEFAULT_CODEX_APP_PLUGINS } from '../routes.js';
5
5
  import { ensureDir, PACKAGE_VERSION, readText, writeTextAtomic } from '../fsx.js';
6
6
  import { removeLegacyTopLevelCodexModeLocks, writeCodexConfigGuarded } from '../codex/codex-config-guard.js';
7
7
  import { cleanupCodexConfigBackups, validateCodexConfigRoundTrip } from '../codex/codex-config-toml.js';
8
+ import { DEPRECATED_CODEX_HOOKS_ALIAS_FLAG, REMOVED_CODEX_FEATURE_FLAGS } from '../codex/codex-feature-flags.js';
9
+ import { CODEX_FAST_SERVICE_TIER_ID } from '../codex/codex-service-tier.js';
8
10
  import { escapeRegExp } from '../text/regex.js';
9
11
  export async function ensureGlobalCodexFastModeDuringInstall(opts = {}) {
10
12
  if (process.env.SKS_SKIP_CODEX_FAST_MODE_REPAIR === '1')
@@ -59,35 +61,19 @@ function normalizeCodexFastModeUiConfigOnce(text = '', opts = {}) {
59
61
  next = removeTopLevelTomlKeyIfValue(next, 'default_profile', 'sks-fast-high');
60
62
  next = removeTomlTable(next, 'user.fast_mode');
61
63
  next = removeTomlTable(next, 'profiles.sks-fast-high');
62
- next = removeTomlTableKey(next, 'notice', 'fast_default_opt_out');
63
- for (const legacyFlag of ['codex_hooks', 'remote_control', 'fast_mode_ui', 'codex_git_commit']) {
64
- next = removeTomlTableKey(next, 'features', legacyFlag, 'true');
64
+ next = removeTomlTableKey(next, 'features', DEPRECATED_CODEX_HOOKS_ALIAS_FLAG, 'true');
65
+ for (const legacyFlag of REMOVED_CODEX_FEATURE_FLAGS) {
66
+ next = removeTomlTableKey(next, 'features', legacyFlag);
65
67
  }
66
- next = removeTomlTableKey(next, 'features', 'multi_agent');
67
68
  if (opts.forceFastMode === true) {
68
- next = upsertTopLevelTomlString(next, 'service_tier', 'fast');
69
+ next = upsertTopLevelTomlString(next, 'service_tier', CODEX_FAST_SERVICE_TIER_ID);
69
70
  }
70
71
  else if (opts.forceFastModeOff === true) {
71
72
  next = removeTopLevelTomlKey(next, 'service_tier');
72
73
  }
73
74
  next = upsertTopLevelTomlBooleanIfAbsent(next, 'suppress_unstable_features_warning', true);
74
- for (const featureLine of [
75
- 'hooks = true',
76
- 'fast_mode = true',
77
- 'apps = true',
78
- 'computer_use = true',
79
- 'browser_use = true',
80
- 'browser_use_external = true',
81
- 'image_generation = true',
82
- 'in_app_browser = true',
83
- 'guardian_approval = true',
84
- 'tool_suggest = true',
85
- 'plugins = true'
86
- ]) {
87
- next = upsertTomlTableKeyIfAbsent(next, 'features', featureLine);
88
- }
89
75
  if (!hasTomlTable(next, 'features.multi_agent_v2') && !hasTomlTableKey(next, 'features', 'multi_agent_v2')) {
90
- next = upsertTomlTable(next, 'features.multi_agent_v2', '[features.multi_agent_v2]\nenabled = true\nexpose_spawn_agent_model_overrides = true');
76
+ next = upsertTomlTable(next, 'features.multi_agent_v2', '[features.multi_agent_v2]\nenabled = true');
91
77
  }
92
78
  if (process.env.SKS_MANAGE_CODEX_APP_PLUGINS === '1') {
93
79
  for (const [name, marketplace] of DEFAULT_CODEX_APP_PLUGINS) {
@@ -146,31 +132,6 @@ function removeTomlTableKey(text, table, key, expectedValue = null) {
146
132
  const keyPattern = new RegExp(`^\\s*${escapeRegExp(key)}\\s*=${valuePattern}`);
147
133
  return lines.filter((line, index) => index <= start || index >= end || !keyPattern.test(line)).join('\n').replace(/\n{3,}/g, '\n\n');
148
134
  }
149
- function upsertTomlTableKey(text, table, line) {
150
- const key = String(line).split('=')[0]?.trim() ?? '';
151
- const lines = String(text || '').trimEnd().split('\n');
152
- if (lines.length === 1 && lines[0] === '')
153
- lines.length = 0;
154
- const start = lines.findIndex((entry) => entry.trim() === `[${table}]`);
155
- if (start === -1)
156
- return [...lines, ...(lines.length ? [''] : []), `[${table}]`, line].join('\n').replace(/\n{3,}/g, '\n\n');
157
- let end = lines.length;
158
- for (let i = start + 1; i < lines.length; i += 1) {
159
- if (/^\s*\[.+\]\s*$/.test(lines[i] || '')) {
160
- end = i;
161
- break;
162
- }
163
- }
164
- const keyPattern = new RegExp(`^\\s*${escapeRegExp(key)}\\s*=`);
165
- for (let i = start + 1; i < end; i += 1) {
166
- if (keyPattern.test(lines[i] || '')) {
167
- lines[i] = line;
168
- return lines.join('\n').replace(/\n{3,}/g, '\n\n');
169
- }
170
- }
171
- lines.splice(end, 0, line);
172
- return lines.join('\n').replace(/\n{3,}/g, '\n\n');
173
- }
174
135
  function hasTomlTableKey(text, table, key) {
175
136
  const lines = String(text || '').split('\n');
176
137
  const start = lines.findIndex((line) => line.trim() === `[${table}]`);
@@ -185,10 +146,6 @@ function hasTomlTableKey(text, table, key) {
185
146
  }
186
147
  return false;
187
148
  }
188
- function upsertTomlTableKeyIfAbsent(text, table, line) {
189
- const key = String(line).split('=')[0]?.trim() ?? '';
190
- return hasTomlTableKey(text, table, key) ? String(text || '') : upsertTomlTableKey(text, table, line);
191
- }
192
149
  function upsertTopLevelTomlBooleanIfAbsent(text, key, value) {
193
150
  return hasTopLevelTomlKey(text, key) ? String(text || '') : upsertTopLevelTomlBoolean(text, key, value);
194
151
  }
@@ -75,16 +75,6 @@ export function readBoundedIntegerFlag(args, name, fallback, min, max) {
75
75
  export function readMaxCycles(args, fallback) {
76
76
  return readBoundedIntegerFlag(args, '--max-cycles', fallback, 1, 50);
77
77
  }
78
- export function ambientGoalContinuation() {
79
- return {
80
- schema_version: 1,
81
- enabled: true,
82
- mode: 'codex_native_goal_only',
83
- native_slash_command: '/goal',
84
- non_disruptive: true,
85
- rule: 'Use Codex native Goal as the only persisted goal owner. Never create SKS Goal missions, bridge artifacts, compatibility loops, or fallback goal state.'
86
- };
87
- }
88
78
  export function knownGeneratedSkillNames() {
89
79
  return Array.from(new Set([...DOLLAR_SKILL_NAMES, ...RECOMMENDED_SKILLS]));
90
80
  }
@@ -170,8 +170,7 @@ async function researchPrepare(args) {
170
170
  stop_gate: route.stopGate,
171
171
  clarification_gate: false,
172
172
  pipeline_plan_ready: validatePipelinePlan(pipelinePlan).ok,
173
- pipeline_plan_path: PIPELINE_PLAN_ARTIFACT,
174
- goal_continuation: pipelinePlan.goal_continuation
173
+ pipeline_plan_path: PIPELINE_PLAN_ARTIFACT
175
174
  });
176
175
  await setCurrent(root, {
177
176
  mission_id: id,
@@ -195,7 +194,6 @@ async function researchPrepare(args) {
195
194
  reasoning_effort: reasoning.effort,
196
195
  reasoning_profile: reasoning.profile,
197
196
  reasoning_temporary: true,
198
- goal_continuation: pipelinePlan.goal_continuation,
199
197
  pipeline_plan_ready: validatePipelinePlan(pipelinePlan).ok,
200
198
  pipeline_plan_path: PIPELINE_PLAN_ARTIFACT,
201
199
  prompt