sneakoscope 5.8.0 → 5.10.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 (153) hide show
  1. package/README.md +1 -1
  2. package/config/competitor-scorecard-baseline.json +97 -0
  3. package/config/perf-budgets.v1.json +10 -0
  4. package/crates/sks-core/Cargo.lock +1 -1
  5. package/crates/sks-core/Cargo.toml +1 -1
  6. package/crates/sks-core/src/main.rs +1 -1
  7. package/dist/bin/fast-inline.js +147 -0
  8. package/dist/bin/install.js +1 -2
  9. package/dist/bin/package.json +1 -0
  10. package/dist/bin/sks-dispatch.js +55 -0
  11. package/dist/bin/sks.js +10 -30
  12. package/dist/cli/command-manifest-lite.js +129 -0
  13. package/dist/cli/command-registry.js +1 -1
  14. package/dist/cli/commands-fast.js +29 -0
  15. package/dist/cli/help-fast.js +7 -9
  16. package/dist/cli/root-fast.js +48 -0
  17. package/dist/cli/router.js +16 -9
  18. package/dist/cli/super-search-command.js +5 -19
  19. package/dist/commands/doctor.js +243 -65
  20. package/dist/config/skills-manifest.json +57 -57
  21. package/dist/core/agents/agent-orchestrator.js +10 -3
  22. package/dist/core/agents/agent-worker-pipeline.js +9 -6
  23. package/dist/core/agents/parallel-runtime-proof.js +30 -3
  24. package/dist/core/agents/parallel-write-fixture.js +301 -0
  25. package/dist/core/codex-control/codex-fake-sdk-adapter.js +11 -1
  26. package/dist/core/codex-control/codex-reliability-shield.js +13 -1
  27. package/dist/core/codex-control/codex-sdk-adapter.js +49 -8
  28. package/dist/core/codex-control/codex-sdk-config-policy.js +1 -1
  29. package/dist/core/codex-control/codex-sdk-env-policy.js +10 -0
  30. package/dist/core/codex-control/codex-task-runner.js +1 -0
  31. package/dist/core/codex-control/schemas/agent-worker-result.schema.js +66 -11
  32. package/dist/core/commands/basic-cli.js +16 -7
  33. package/dist/core/commands/gc-command.js +45 -1
  34. package/dist/core/doctor/doctor-idempotence.js +93 -0
  35. package/dist/core/errors/blocker-humanizer.js +13 -0
  36. package/dist/core/errors/next-action-map.js +56 -0
  37. package/dist/core/fsx.js +7 -4
  38. package/dist/core/git/git-worktree-cleanup.js +27 -0
  39. package/dist/core/git/git-worktree-merge-queue.js +120 -37
  40. package/dist/core/install/installed-package-smoke.js +121 -0
  41. package/dist/core/naruto/naruto-active-pool.js +6 -2
  42. package/dist/core/naruto/naruto-real-worker-child.js +2 -2
  43. package/dist/core/perf/fsx-hotpath.js +63 -0
  44. package/dist/core/perf/import-graph-budget.js +111 -0
  45. package/dist/core/perf/perf-budget.js +192 -0
  46. package/dist/core/perf/performance-profiler.js +109 -0
  47. package/dist/core/provider/provider-self-heal.js +152 -0
  48. package/dist/core/quality/competitor-scorecard.js +116 -0
  49. package/dist/core/release/gate-timing.js +105 -0
  50. package/dist/core/release/release-gate-hermetic-env.js +2 -0
  51. package/dist/core/retention/retention-budget.js +62 -0
  52. package/dist/core/retention.js +160 -2
  53. package/dist/core/routes/diagnostic-allowlist.js +2 -2
  54. package/dist/core/routes/dollar-manifest-lite.js +85 -0
  55. package/dist/core/routes.js +31 -24
  56. package/dist/core/structured-output-adapter.js +1 -1
  57. package/dist/core/super-search/doctor.js +97 -0
  58. package/dist/core/super-search/local-http-smoke.js +98 -0
  59. package/dist/core/super-search/runtime-helpers.js +120 -8
  60. package/dist/core/super-search/runtime.js +43 -2
  61. package/dist/core/update-check.js +44 -2
  62. package/dist/core/version.js +1 -1
  63. package/dist/scripts/agent-fast-mode-default-check.js +10 -1
  64. package/dist/scripts/build-dist.js +32 -0
  65. package/dist/scripts/codex-control-stream-idle-watchdog-check.js +17 -1
  66. package/dist/scripts/command-performance-scorecard-check.js +86 -0
  67. package/dist/scripts/competitor-scorecard-check.js +25 -0
  68. package/dist/scripts/doctor-fastpath-check.js +19 -0
  69. package/dist/scripts/doctor-idempotence-check.js +8 -0
  70. package/dist/scripts/dollar-performance-scorecard-check.js +60 -0
  71. package/dist/scripts/fsx-hotpath-check.js +11 -0
  72. package/dist/scripts/gate-timing-check.js +16 -0
  73. package/dist/scripts/high-risk-contracts-check.js +24 -0
  74. package/dist/scripts/hook-latency-quantum-check.js +122 -0
  75. package/dist/scripts/import-graph-budget-check.js +11 -0
  76. package/dist/scripts/installed-package-smoke-check.js +12 -0
  77. package/dist/scripts/lib/native-cli-session-swarm-check-lib.js +2 -0
  78. package/dist/scripts/naruto-codex-e2e-check.js +100 -0
  79. package/dist/scripts/package-published-contract-check.js +7 -0
  80. package/dist/scripts/packlist-performance-check.js +31 -3
  81. package/dist/scripts/parallel-production-smoke-check.js +21 -0
  82. package/dist/scripts/perf-budget-check.js +14 -0
  83. package/dist/scripts/performance-baseline-check.js +12 -0
  84. package/dist/scripts/performance-improvement-report-check.js +58 -0
  85. package/dist/scripts/quantum-baseline-report.js +38 -0
  86. package/dist/scripts/release-check-stamp.js +117 -16
  87. package/dist/scripts/release-gate-dag-runner-check.js +5 -0
  88. package/dist/scripts/release-gate-dag-runner.js +15 -0
  89. package/dist/scripts/release-runner-efficiency-check.js +15 -0
  90. package/dist/scripts/retention-apply-smoke-check.js +21 -0
  91. package/dist/scripts/retention-budget-check.js +8 -0
  92. package/dist/scripts/retention-dry-run-check.js +10 -0
  93. package/dist/scripts/route-intent-regression-check.js +44 -0
  94. package/dist/scripts/super-search-live-smoke-check.js +117 -0
  95. package/dist/scripts/super-search-local-http-smoke-check.js +18 -0
  96. package/dist/scripts/super-search-offline-contract-check.js +45 -0
  97. package/dist/scripts/update-fastpath-check.js +30 -0
  98. package/dist/scripts/update-first-command-migration-check.js +2 -3
  99. package/package.json +51 -30
  100. package/dist/scripts/check-source-runtime.js +0 -4
  101. package/dist/scripts/codex-0-134-official-compat-report.js +0 -110
  102. package/dist/scripts/gpt-image-2-real-file-smoke.js +0 -448
  103. package/dist/scripts/loop-artifact-paths-check.js +0 -3
  104. package/dist/scripts/loop-blocker-check.js +0 -15
  105. package/dist/scripts/loop-cli-check.js +0 -3
  106. package/dist/scripts/loop-cli-registry-check.js +0 -3
  107. package/dist/scripts/loop-concurrency-budget-check.js +0 -3
  108. package/dist/scripts/loop-concurrency-budget-runtime-check.js +0 -3
  109. package/dist/scripts/loop-continuation-enforcer-check.js +0 -4
  110. package/dist/scripts/loop-decomposer-check.js +0 -3
  111. package/dist/scripts/loop-execution-profile-routing-check.js +0 -4
  112. package/dist/scripts/loop-final-arbiter-contract-check.js +0 -3
  113. package/dist/scripts/loop-fixture-policy-check.js +0 -3
  114. package/dist/scripts/loop-fixture-safety-check.js +0 -3
  115. package/dist/scripts/loop-gate-fixture-guard-check.js +0 -3
  116. package/dist/scripts/loop-gate-ladder-check.js +0 -3
  117. package/dist/scripts/loop-gate-runner-check.js +0 -3
  118. package/dist/scripts/loop-gate-selector-check.js +0 -3
  119. package/dist/scripts/loop-gpt-final-contract-crossref-check.js +0 -3
  120. package/dist/scripts/loop-gpt-final-fixture-guard-check.js +0 -3
  121. package/dist/scripts/loop-gpt-final-gate-contract-check.js +0 -3
  122. package/dist/scripts/loop-integration-finalizer-check.js +0 -3
  123. package/dist/scripts/loop-integration-merge-strategy-check.js +0 -3
  124. package/dist/scripts/loop-interrupt-registry-check.js +0 -3
  125. package/dist/scripts/loop-lease-check.js +0 -3
  126. package/dist/scripts/loop-merge-strategy-check.js +0 -3
  127. package/dist/scripts/loop-mutation-ledger-check.js +0 -3
  128. package/dist/scripts/loop-observability-check.js +0 -3
  129. package/dist/scripts/loop-owner-inference-check.js +0 -3
  130. package/dist/scripts/loop-planner-check.js +0 -3
  131. package/dist/scripts/loop-planner-project-memory-check.js +0 -4
  132. package/dist/scripts/loop-planner-project-memory-deep-check.js +0 -4
  133. package/dist/scripts/loop-proof-check.js +0 -3
  134. package/dist/scripts/loop-proof-summary-cli-check.js +0 -3
  135. package/dist/scripts/loop-risk-classifier-check.js +0 -3
  136. package/dist/scripts/loop-runtime-check.js +0 -3
  137. package/dist/scripts/loop-scheduler-check.js +0 -3
  138. package/dist/scripts/loop-schema-check.js +0 -3
  139. package/dist/scripts/loop-side-effect-final-arbiter-check.js +0 -3
  140. package/dist/scripts/loop-side-effect-scanner-check.js +0 -3
  141. package/dist/scripts/loop-state-check.js +0 -3
  142. package/dist/scripts/loop-status-proof-ux-check.js +0 -3
  143. package/dist/scripts/loop-worker-fixture-guard-check.js +0 -3
  144. package/dist/scripts/loop-worker-handle-registration-check.js +0 -3
  145. package/dist/scripts/loop-worker-interrupt-check.js +0 -3
  146. package/dist/scripts/loop-worktree-policy-check.js +0 -3
  147. package/dist/scripts/loop-zellij-ui-check.js +0 -3
  148. package/dist/scripts/official-docs-compat-report.js +0 -304
  149. package/dist/scripts/readme-architecture-imagegen-official-check.js +0 -448
  150. package/dist/scripts/release-metadata-1-16-check.js +0 -81
  151. package/dist/scripts/release-metadata-1-17-check.js +0 -51
  152. package/dist/scripts/release-metadata-1-19-check.js +0 -479
  153. package/dist/scripts/uninstall-inventory-check.js +0 -3
@@ -0,0 +1,48 @@
1
+ import fs from 'node:fs';
2
+ export function rootJsonFast(cwd = process.cwd()) {
3
+ const project = findProjectRootSync(cwd);
4
+ const global = joinPath(process.env.HOME || process.env.USERPROFILE || cwd, '.sneakoscope');
5
+ const active = project || global;
6
+ console.log(JSON.stringify({
7
+ cwd,
8
+ mode: project ? 'project' : 'global',
9
+ active_root: active,
10
+ project_root: project,
11
+ global_root: global,
12
+ using_global_root: !project
13
+ }, null, 2));
14
+ }
15
+ function findProjectRootSync(start) {
16
+ let dir = normalizeStart(start);
17
+ for (;;) {
18
+ if (fs.existsSync(joinPath(dir, '.sneakoscope')))
19
+ return dir;
20
+ if (fs.existsSync(joinPath(dir, 'AGENTS.md')) && fs.existsSync(joinPath(dir, 'package.json')))
21
+ return dir;
22
+ const parent = parentDir(dir);
23
+ if (parent === dir)
24
+ return null;
25
+ dir = parent;
26
+ }
27
+ }
28
+ function normalizeStart(start) {
29
+ const value = stripTrailingSlash(start || process.cwd());
30
+ if (value.startsWith('/'))
31
+ return value || '/';
32
+ return joinPath(process.cwd(), value);
33
+ }
34
+ function joinPath(left, right) {
35
+ const base = stripTrailingSlash(left || '/');
36
+ return `${base === '/' ? '' : base}/${right}`;
37
+ }
38
+ function parentDir(value) {
39
+ const dir = stripTrailingSlash(value);
40
+ if (dir === '/')
41
+ return dir;
42
+ const index = dir.lastIndexOf('/');
43
+ return index <= 0 ? '/' : dir.slice(0, index);
44
+ }
45
+ function stripTrailingSlash(value) {
46
+ return value.replace(/\/+$/, '') || '/';
47
+ }
48
+ //# sourceMappingURL=root-fast.js.map
@@ -1,16 +1,13 @@
1
- import { COMMAND_ALIASES, COMMANDS, } from './command-registry.js';
1
+ import { COMMAND_ALIASES_LITE, COMMAND_MANIFEST_BY_NAME, COMMAND_NAME_SET, } from './command-manifest-lite.js';
2
2
  import { detectGlobalMode, glmWithoutMadResult } from './global-mode-router.js';
3
- import { ensureCurrentMigrationBeforeCommand } from '../core/update/update-migration-state.js';
4
- import { projectRoot, readJson } from '../core/fsx.js';
5
- import { stateFile } from '../core/mission.js';
6
3
  export function isCommandName(value) {
7
- return Object.prototype.hasOwnProperty.call(COMMANDS, value);
4
+ return COMMAND_NAME_SET.has(value);
8
5
  }
9
6
  export function normalizeCommand(args = []) {
10
7
  const cmd = args[0];
11
8
  if (!cmd)
12
9
  return { command: null, rawCommand: null, aliasTarget: null, args: [...args] };
13
- const mapped = cmd in COMMAND_ALIASES ? COMMAND_ALIASES[cmd] : cmd;
10
+ const mapped = cmd in COMMAND_ALIASES_LITE ? COMMAND_ALIASES_LITE[cmd] : cmd;
14
11
  const rest = args.slice(1);
15
12
  const command = isCommandName(mapped) ? mapped : null;
16
13
  return {
@@ -78,13 +75,14 @@ async function dispatchInner(argv) {
78
75
  };
79
76
  return result;
80
77
  }
81
- const entry = COMMANDS[command];
78
+ const entry = COMMAND_MANIFEST_BY_NAME[command];
82
79
  const commandGate = await ensureActiveRouteCommandGate(command, rest);
83
80
  if (!commandGate.ok) {
84
81
  console.error(commandGate.message);
85
82
  process.exitCode = 1;
86
83
  return commandGate;
87
84
  }
85
+ const { ensureCurrentMigrationBeforeCommand } = await import('../core/update/update-migration-state.js');
88
86
  const migrationGate = await ensureCurrentMigrationBeforeCommand({
89
87
  command,
90
88
  args: rest,
@@ -105,13 +103,15 @@ async function dispatchInner(argv) {
105
103
  process.exitCode = 1;
106
104
  return migrationGate;
107
105
  }
108
- const mod = await entry.lazy();
106
+ const { COMMANDS } = await import('./command-registry.js');
107
+ const commandEntry = COMMANDS[command];
108
+ const mod = await commandEntry.lazy();
109
109
  if (typeof mod.run !== 'function')
110
110
  throw new Error(`Command ${command} must export run(command, args)`);
111
111
  return mod.run(rawCommand || command, rest);
112
112
  }
113
113
  async function ensureActiveRouteCommandGate(command, args) {
114
- const entry = COMMANDS[command];
114
+ const entry = COMMAND_MANIFEST_BY_NAME[command];
115
115
  if (command === 'route' || entry.readonly === true || entry.allowedDuringActiveRoute === true && entry.mutatesRouteState !== true) {
116
116
  return { ok: true, status: 'allowed' };
117
117
  }
@@ -119,6 +119,13 @@ async function ensureActiveRouteCommandGate(command, args) {
119
119
  return { ok: true, status: 'allowed' };
120
120
  if (safeReadOnlySubcommand(args))
121
121
  return { ok: true, status: 'allowed_status_subcommand' };
122
+ if (process.env.SKS_TEST_ISOLATION === '1' && process.env.SKS_RELEASE_FIXTURE_ACTIVE_ROUTE_BYPASS === '1') {
123
+ return { ok: true, status: 'allowed_release_fixture_isolation' };
124
+ }
125
+ const [{ projectRoot, readJson }, { stateFile }] = await Promise.all([
126
+ import('../core/fsx.js'),
127
+ import('../core/mission.js')
128
+ ]);
122
129
  const root = await projectRoot(process.cwd()).catch(() => process.cwd());
123
130
  const state = await readJson(stateFile(root), {}).catch(() => ({}));
124
131
  if (!activeRouteStateBlocksCommand(state))
@@ -3,6 +3,7 @@ import os from 'node:os';
3
3
  import path from 'node:path';
4
4
  import { randomUUID } from 'node:crypto';
5
5
  import { runSuperSearch } from '../core/super-search/index.js';
6
+ import { buildSuperSearchDoctorReport, printSuperSearchDoctorReport } from '../core/super-search/doctor.js';
6
7
  import { evaluateLocalGate } from '../core/commands/route-success-helpers.js';
7
8
  import { evaluateRealEvidencePolicy } from '../core/verification/real-evidence-policy.js';
8
9
  export async function superSearchCommand(sub = 'help', args = []) {
@@ -37,6 +38,7 @@ async function runCommand(args) {
37
38
  const result = await runSuperSearch({
38
39
  missionDir,
39
40
  query,
41
+ allowLocalFetch: args.includes('--allow-local'),
40
42
  ...(mode ? { mode } : {})
41
43
  });
42
44
  const gate = await evaluateSuperSearchGate(missionDir);
@@ -61,24 +63,8 @@ async function runCommand(args) {
61
63
  }
62
64
  async function doctorCommand(args) {
63
65
  const json = args.includes('--json');
64
- const report = {
65
- schema: 'sks.super-search-doctor.v1',
66
- ok: true,
67
- core_ready: true,
68
- xai_required: false,
69
- optional: {
70
- context7: 'external_runtime_optional_by_intent',
71
- codex_web: process.env.SKS_CODEX_WEB_SEARCH_AVAILABLE === '1' || process.env.CODEX_WEB_SEARCH_AVAILABLE === '1' ? 'available' : 'not_bound',
72
- authenticated_chrome: 'operator_consented_optional',
73
- official_x_api: 'credentials_optional_not_required'
74
- },
75
- blockers: [],
76
- warnings: []
77
- };
78
- if (json)
79
- console.log(JSON.stringify(report, null, 2));
80
- else
81
- console.log('Super-Search doctor: core ready; xAI/Grok is not required.');
66
+ const report = await buildSuperSearchDoctorReport(args);
67
+ printSuperSearchDoctorReport(report, json);
82
68
  return report;
83
69
  }
84
70
  async function inspectCommand(action, args) {
@@ -153,7 +139,7 @@ function positional(args) {
153
139
  if (!value)
154
140
  continue;
155
141
  if (value.startsWith('--')) {
156
- if (value !== '--json')
142
+ if (value !== '--json' && value !== '--allow-local')
157
143
  i++;
158
144
  continue;
159
145
  }
@@ -8,60 +8,196 @@ import { getCodexInfo } from '../core/codex-adapter.js';
8
8
  import { rustInfo } from '../core/rust-accelerator.js';
9
9
  import { codexAppIntegrationStatus } from '../core/codex-app.js';
10
10
  import { codexLbMetrics, readCodexLbCircuit } from '../core/codex-lb-circuit.js';
11
- import { ensureGlobalCodexSkillsDuringInstall, ensureGlobalCodexFastModeDuringInstall } from '../cli/install-helpers.js';
12
11
  import { normalizeInstallScope } from '../core/init.js';
13
12
  import { inspectCodexConfigReadability } from '../core/codex/codex-config-readability.js';
14
- import { repairCodexConfigEperm } from '../core/codex/codex-config-eperm-repair.js';
15
- import { writeDoctorReadinessMatrix } from '../core/doctor/doctor-readiness-matrix.js';
16
- import { runCodexDoctorBridge, compareCodexDoctorBridge } from '../core/doctor/codex-doctor-bridge.js';
17
- import { cleanDuplicateGlobalSksInstalls } from '../core/doctor/global-sks-install-cleanup.js';
18
13
  import { checkZellijCapability } from '../core/zellij/zellij-capability.js';
19
14
  import { inventoryCodexPermissionProfiles } from '../core/codex/codex-permission-profiles.js';
20
15
  import { appendMigrationEvents, hashConfigText } from '../core/migration/migration-transaction-journal.js';
21
- import { repairCodexAppFastUi } from '../core/codex-app/codex-app-fast-ui-repair.js';
22
16
  import { resolveProviderContext } from '../core/provider/provider-context.js';
23
17
  import { readLocalModelConfig } from '../core/agents/ollama-worker-config.js';
24
- import { repairAgentRoleConfigs } from '../core/agents/agent-role-config.js';
25
18
  import { writeCodex0138CapabilityArtifacts } from '../core/codex-control/codex-0138-capability.js';
26
- import { runCodex0138Doctor } from '../core/doctor/codex-0138-doctor.js';
27
19
  import { writeCodexPluginInventoryArtifacts, pluginAppTemplatePolicy } from '../core/codex-plugins/codex-plugin-json.js';
28
20
  import { writeMcpPluginInventoryArtifacts } from '../core/mcp/mcp-plugin-inventory.js';
29
- import { runDoctorZellijRepair, doctorZellijRepairConsoleLine } from '../core/doctor/doctor-zellij-repair.js';
30
- import { runDoctorContext7Repair } from '../core/doctor/doctor-context7-repair.js';
31
- import { runDoctorCodexStartupRepair } from '../core/doctor/doctor-codex-startup-repair.js';
32
21
  import { buildCodexAppHarnessMatrix } from '../core/codex-app/codex-app-harness-matrix.js';
33
22
  import { buildCodexNativeFeatureMatrix } from '../core/codex-native/codex-native-feature-broker.js';
34
- import { repairCodexNativeManagedAssets } from '../core/codex-native/codex-native-repair-transaction.js';
35
- import { runDoctorNativeCapabilityRepair } from '../core/doctor/doctor-native-capability-repair.js';
36
- import { runDoctorCommandAliasCleanup } from '../core/doctor/command-alias-cleanup.js';
37
- import { repairCodexStartupConfig } from '../core/doctor/codex-startup-config-repair.js';
38
- import { repairContext7Mcp } from '../core/doctor/context7-mcp-repair.js';
39
- import { repairSupabaseMcp } from '../core/doctor/supabase-mcp-repair.js';
40
- import { runDoctorFixTransaction } from '../core/doctor/doctor-transaction.js';
41
- import { planDoctorDirtyRepair } from '../core/doctor/doctor-dirty-planner.js';
42
- import { doctorRepairPostcheck } from '../core/doctor/doctor-repair-postcheck.js';
43
23
  import { withSecretPreservationGuard } from '../core/config/config-migration-journal.js';
44
24
  import { isUpdateMigrationReceiptCurrent, projectUpdateMigrationReceiptPath, writeProjectUpdateMigrationReceipt } from '../core/update/update-migration-state.js';
45
25
  import { inspectSksMenuBarStatus, installSksMenuBar } from '../core/codex-app/sks-menubar.js';
46
26
  import { sweepSksTempDirs } from '../core/retention.js';
47
- import { reconcileSkills } from '../core/init/skills.js';
48
- import { codexHookTrustDoctor } from '../core/codex-hooks/codex-hook-trust-doctor.js';
49
27
  import { detectImagegenCapability } from '../core/imagegen/imagegen-capability.js';
50
- import { repairCodexImagegen } from '../core/doctor/imagegen-repair.js';
51
- import { repairComputerUse } from '../core/doctor/computer-use-repair.js';
52
- import { repairBrowserUse } from '../core/doctor/browser-use-repair.js';
53
- import { detectAndRepairMcpTransportCollisions } from '../core/doctor/mcp-transport-collision-repair.js';
54
28
  export async function run(_command, args = []) {
55
29
  const root = await projectRoot();
56
30
  const doctorFix = flag(args, '--fix');
31
+ const doctorProfile = doctorProfileFromArgs(args, doctorFix);
57
32
  if (!flag(args, '--json')) {
58
33
  cliUi.banner('doctor');
59
34
  cliUi.step(doctorFix ? 'repairing and validating' : 'validating');
60
35
  }
36
+ if (!doctorFix && flag(args, '--json') && doctorProfile === 'fast')
37
+ return runDoctorJsonFastPath(args, root);
61
38
  if (doctorFix)
62
39
  return withSecretPreservationGuard(root, 'doctor-fix', () => runDoctor(args, root, doctorFix));
63
40
  return runDoctor(args, root, doctorFix);
64
41
  }
42
+ async function runDoctorJsonFastPath(args = [], root) {
43
+ const startedAtMs = Date.now();
44
+ const codexBin = readOption(args, '--codex-bin', process.env.SKS_DOCTOR_CODEX_BIN || '');
45
+ const configProbeOpts = {
46
+ codexProbe: false,
47
+ actualCodex: false,
48
+ requireActualCodex: false,
49
+ codexBin: codexBin || undefined
50
+ };
51
+ const [codex, rust, codexConfig, sneakoscopeExists] = await Promise.all([
52
+ codexBin
53
+ ? Promise.resolve({ bin: codexBin, version: 'fixture-or-explicit', available: true })
54
+ : getCodexInfo().catch(() => ({ bin: null, version: null, available: false })),
55
+ rustInfo().catch((err) => ({ available: false, mode: 'js_fallback', status: 'error', version: null, error: err.message })),
56
+ inspectCodexConfigReadability(root, configProbeOpts).catch((err) => ({
57
+ ok: false,
58
+ checks: [],
59
+ operator_actions: [],
60
+ blockers: [err?.message || String(err)]
61
+ })),
62
+ exists(`${root}/.sneakoscope`)
63
+ ]);
64
+ const ready = {
65
+ schema: 'sks.doctor-readiness-matrix.v2',
66
+ generated_at: nowIso(),
67
+ ready: Boolean(codexConfig?.ok),
68
+ cli_ready: Boolean(codexConfig?.ok),
69
+ mad_ready: false,
70
+ managed_state_current: sneakoscopeExists,
71
+ codex_config_readable_by_node: Boolean(codexConfig?.ok),
72
+ codex_config_readable_by_codex_cli: false,
73
+ codex_config_readable_in_zellij_context: false,
74
+ codex_app_ready: false,
75
+ primary_blocker: codexConfig?.ok ? null : 'codex_config_unreadable',
76
+ blockers: codexConfig?.ok ? [] : ['codex_config_unreadable'],
77
+ next_actions: codexConfig?.ok ? [] : ['Run `sks doctor --fix --json` to repair managed config.']
78
+ };
79
+ const codexNativeFeatureMatrix = fallbackCodexNativeFeatureMatrix(codex, [], ['native_feature_matrix_deferred_to_full_doctor_or_route_gate']);
80
+ const zellijReadiness = buildZellijReadiness(root, { status: 'skipped', required_for: ['sks --mad', 'interactive lane UI'] }, ready);
81
+ const runtimeReadiness = buildRuntimeReadiness(zellijReadiness, codexNativeFeatureMatrix);
82
+ const deferredImagegen = deferredNativeRepair('sks.doctor-imagegen-repair.v1', false, [
83
+ 'Run `sks doctor --fix --repair-native-capabilities --json` after enabling Codex App image_generation.'
84
+ ]);
85
+ const deferredComputerUse = deferredNativeRepair('sks.doctor-computer-use-repair.v1', false, [
86
+ 'Computer Use route needs manual OS/App permission verification before use.'
87
+ ]);
88
+ const deferredBrowserUse = deferredNativeRepair('sks.doctor-browser-use-repair.v1', false, [
89
+ 'Chrome/web review route needs the Codex Chrome Extension enabled before use.'
90
+ ]);
91
+ const result = {
92
+ schema: 'sks.doctor-status.v2',
93
+ elapsed_ms: Date.now() - startedAtMs,
94
+ ok: ready.ready,
95
+ root,
96
+ fast_path: true,
97
+ no_fix_write_policy: 'no_writes_performed',
98
+ arg_warnings: doctorArgWarnings(args),
99
+ node: { ok: Number(process.versions.node.split('.')[0]) >= 20, version: process.version },
100
+ codex,
101
+ codex_config: codexConfig,
102
+ rust,
103
+ codex_app: { ok: false, skipped: true, warnings: ['codex_app_optional_diagnostic_skipped'] },
104
+ codex_app_ui: {
105
+ schema: 'sks.codex-app-fast-ui-repair.v1',
106
+ ok: true,
107
+ apply: false,
108
+ skipped: true,
109
+ actions: [],
110
+ blockers: [],
111
+ warnings: ['codex_app_ui_repair_deferred']
112
+ },
113
+ sks_menubar: {
114
+ schema: 'sks.codex-app-sks-menubar.v1',
115
+ ok: true,
116
+ apply: false,
117
+ status: 'skipped_fast_path',
118
+ actions: [],
119
+ blockers: [],
120
+ warnings: ['menubar_install_deferred_to_fix_or_full_doctor']
121
+ },
122
+ provider_context: {
123
+ schema: 'sks.provider-context.v1',
124
+ generated_at: nowIso(),
125
+ provider: 'unknown',
126
+ auth_mode: 'unknown',
127
+ route: '$Doctor',
128
+ service_tier: process.env.SKS_SERVICE_TIER || 'fast',
129
+ source: 'skipped',
130
+ confidence: 'low',
131
+ conflict: false,
132
+ warnings: ['provider_context_optional_diagnostic_skipped'],
133
+ signals: {}
134
+ },
135
+ codex_lb: codexLbMetrics(await readCodexLbCircuit(root).catch(() => ({}))),
136
+ codex_doctor: null,
137
+ pre_repair_codex_doctor: null,
138
+ post_repair_codex_doctor: null,
139
+ codex_doctor_diff: null,
140
+ observational_codex_doctor_diff: null,
141
+ zellij: { ok: true, skipped: true, status: 'skipped_fast_path', required_for: ['sks --mad', 'interactive lane UI'] },
142
+ zellij_repair: { schema: 'sks.zellij-self-heal.v1', ok: true, skipped: true, blockers: [], warnings: ['zellij_repair_deferred_to_full_doctor_or_route_gate'] },
143
+ context7_repair: { schema: 'sks.doctor-context7-repair.v1', ok: true, fix: false, skipped: true, actions: [], blockers: [], warnings: ['context7_repair_deferred_to_fix'] },
144
+ codex_startup_repair: { schema: 'sks.doctor-codex-startup-repair.v1', ok: true, fix: false, skipped: true, actions: [], blockers: [], warnings: ['codex_startup_repair_deferred_to_fix'] },
145
+ startup_config_repair: null,
146
+ context7_mcp_repair: null,
147
+ supabase_mcp_repair: null,
148
+ doctor_fix_transaction: null,
149
+ doctor_fix_postcheck: null,
150
+ postcheck: null,
151
+ local_model: null,
152
+ agent_role_config: { schema: 'sks.agent-role-config-repair.v1', ok: true, apply: false, skipped: true, blockers: [] },
153
+ zellij_readiness: zellijReadiness,
154
+ codex_permission_profiles: { skipped: true, reason: 'doctor_json_fast_path_no_report_write' },
155
+ command_aliases: { schema: 'sks.command-alias-cleanup.v1', ok: true, skipped: true, reason: 'doctor_json_fast_path_no_write' },
156
+ sks_temp_sweep: { ok: true, skipped: true, action_count: 0, reason: 'doctor_without_fix', error: null },
157
+ imagegen: { ok: false, auth_readiness: null, codex_app_builtin_available: false },
158
+ imagegen_repair: deferredImagegen,
159
+ codex_0138: { capability: null, doctor: { schema: 'sks.codex-0138-doctor.v1', ok: true, skipped: true, blockers: [], warnings: ['historical_codex_0138_doctor_skipped'] }, plugins: null, plugin_app_template_policy: null, mcp_plugin_inventory: null },
160
+ codex_app_harness_matrix: { schema: 'sks.codex-app-harness-matrix.v1', ok: true, skipped: true, app_features: {}, sks_integrations: {}, blockers: [], warnings: ['codex_app_harness_optional_diagnostic_skipped'] },
161
+ codex_native_feature_matrix: codexNativeFeatureMatrix,
162
+ runtime_readiness: runtimeReadiness,
163
+ ready,
164
+ sneakoscope: { ok: sneakoscopeExists },
165
+ package: { bytes: 0, human: formatBytes(0) },
166
+ skills: { skipped: true, reason: 'doctor_without_fix' },
167
+ repair: {
168
+ sks_update: null,
169
+ setup: null,
170
+ codex_config: null,
171
+ migration_journal: null,
172
+ global_sks_installs: null,
173
+ agent_role_config: null,
174
+ zellij: null,
175
+ context7: null,
176
+ codex_startup: null,
177
+ startup_config: null,
178
+ context7_mcp: null,
179
+ supabase_mcp: null,
180
+ mcp_transport_collision: null,
181
+ imagegen: deferredImagegen,
182
+ computer_use: deferredComputerUse,
183
+ browser_use: deferredBrowserUse,
184
+ hook_trust: null,
185
+ sks_menubar: null,
186
+ doctor_transaction: null,
187
+ doctor_dirty_plan: null,
188
+ doctor_postcheck: null,
189
+ codex_native: null,
190
+ doctor_native_capability: null,
191
+ command_aliases: null,
192
+ skills: { skipped: true, reason: 'doctor_without_fix' },
193
+ sks_temp_sweep: { ok: true, skipped: true, reason: 'doctor_without_fix', actions: [] }
194
+ }
195
+ };
196
+ printJson(result);
197
+ if (!result.ok)
198
+ process.exitCode = 1;
199
+ return result;
200
+ }
65
201
  async function runDoctor(args = [], root, doctorFix) {
66
202
  const startedAtMs = Date.now();
67
203
  const sksTempSweep = doctorFix ? await sweepSksTempDirs(root, { maxAgeHours: 24 }).catch((err) => ({
@@ -82,7 +218,17 @@ async function runDoctor(args = [], root, doctorFix) {
82
218
  const shouldRunZellijRepair = deepDiagnostics || flag(args, '--repair-zellij') || flag(args, '--install-homebrew') || process.env.SKS_REQUIRE_ZELLIJ === '1';
83
219
  const nativeCapabilityDiagnosticsRequested = deepDiagnostics || flag(args, '--repair-native-capabilities');
84
220
  const doctorPhaseIds = doctorPhaseIdsForProfile(doctorProfile);
85
- const doctorDirtyPlan = doctorFix ? planDoctorDirtyRepair(root, doctorPhaseIds) : null;
221
+ const { runDoctorCommandAliasCleanup } = await import('../core/doctor/command-alias-cleanup.js');
222
+ const { runDoctorNativeCapabilityRepair } = await import('../core/doctor/doctor-native-capability-repair.js');
223
+ const { runDoctorCodexStartupRepair } = await import('../core/doctor/doctor-codex-startup-repair.js');
224
+ const { runDoctorContext7Repair } = await import('../core/doctor/doctor-context7-repair.js');
225
+ const { compareCodexDoctorBridge, runCodexDoctorBridge } = await import('../core/doctor/codex-doctor-bridge.js');
226
+ const { repairCodexAppFastUi } = await import('../core/codex-app/codex-app-fast-ui-repair.js');
227
+ const { runDoctorZellijRepair, doctorZellijRepairConsoleLine } = await import('../core/doctor/doctor-zellij-repair.js');
228
+ const { repairAgentRoleConfigs } = await import('../core/agents/agent-role-config.js');
229
+ const { runCodex0138Doctor } = await import('../core/doctor/codex-0138-doctor.js');
230
+ const { writeDoctorReadinessMatrix } = await import('../core/doctor/doctor-readiness-matrix.js');
231
+ const doctorDirtyPlan = doctorFix ? (await import('../core/doctor/doctor-dirty-planner.js')).planDoctorDirtyRepair(root, doctorPhaseIds) : null;
86
232
  let setupRepair = null;
87
233
  let sksUpdate = null;
88
234
  let migrationPreFix = null;
@@ -100,7 +246,7 @@ async function runDoctor(args = [], root, doctorFix) {
100
246
  install_scope: installScope,
101
247
  config_backup_path: null,
102
248
  global_skills: installScope === 'global' && !flag(args, '--local-only')
103
- ? deepDiagnostics ? await ensureGlobalCodexSkillsDuringInstall({ force: true }) : { status: 'skipped', reason: 'default_doctor_no_global_skill_regeneration' }
249
+ ? deepDiagnostics ? await (await import('../cli/install-helpers.js')).ensureGlobalCodexSkillsDuringInstall({ force: true }) : { status: 'skipped', reason: 'default_doctor_no_global_skill_regeneration' }
104
250
  : { status: 'skipped', reason: 'project or local-only repair' },
105
251
  // Re-seed the Codex App Fast-mode UI table ([user.fast_mode] visible/enabled/
106
252
  // default_profile) in the global ~/.codex/config.toml so existing installs whose
@@ -108,17 +254,17 @@ async function runDoctor(args = [], root, doctorFix) {
108
254
  // backs up + parse-validates before writing, no-op when already present.
109
255
  codex_app_fast_mode: flag(args, '--local-only')
110
256
  ? { status: 'skipped', reason: 'local-only repair' }
111
- : await ensureGlobalCodexFastModeDuringInstall().catch((err) => ({ status: 'failed', error: err?.message || String(err) }))
257
+ : await (await import('../cli/install-helpers.js')).ensureGlobalCodexFastModeDuringInstall().catch((err) => ({ status: 'failed', error: err?.message || String(err) }))
112
258
  };
113
259
  }
114
260
  const skillsReconcile = doctorFix
115
261
  ? {
116
- global: await reconcileSkills({
262
+ global: await (await import('../core/init/skills.js')).reconcileSkills({
117
263
  targetDir: path.join(os.homedir(), '.agents', 'skills'),
118
264
  scope: 'global',
119
265
  fix: true
120
266
  }).catch((err) => ({ ok: false, error: err?.message || String(err) })),
121
- project: await reconcileSkills({
267
+ project: await (await import('../core/init/skills.js')).reconcileSkills({
122
268
  targetDir: path.join(root, '.agents', 'skills'),
123
269
  scope: 'project',
124
270
  fix: true
@@ -184,7 +330,7 @@ async function runDoctor(args = [], root, doctorFix) {
184
330
  report_path: `${root}/.sneakoscope/reports/doctor-codex-startup-repair.json`
185
331
  }));
186
332
  const codexDoctorBefore = flag(args, '--fix') && deepDiagnostics ? await runCodexDoctorBridge({ codexBin: codexBin || null, cwd: root, required: flag(args, '--require-actual-codex') }).catch(() => null) : null;
187
- const configRepair = flag(args, '--fix') ? await repairCodexConfigEperm(root, { fix: true, ...configProbeOpts }) : null;
333
+ const configRepair = flag(args, '--fix') ? await (await import('../core/codex/codex-config-eperm-repair.js')).repairCodexConfigEperm(root, { fix: true, ...configProbeOpts }) : null;
188
334
  const migrationJournal = flag(args, '--fix')
189
335
  ? await writeFixMigrationJournal(root, migrationPreFix, configRepair, setupRepair).catch(() => null)
190
336
  : null;
@@ -380,7 +526,7 @@ async function runDoctor(args = [], root, doctorFix) {
380
526
  report_path: `${root}/.sneakoscope/reports/doctor-context7-repair.json`
381
527
  }));
382
528
  const startupConfigRepair = doctorFix
383
- ? await repairCodexStartupConfig({ root, apply: true }).catch((err) => ({
529
+ ? await (await import('../core/doctor/codex-startup-config-repair.js')).repairCodexStartupConfig({ root, apply: true }).catch((err) => ({
384
530
  schema: 'sks.codex-startup-config-repair.v1',
385
531
  ok: false,
386
532
  apply: true,
@@ -388,7 +534,7 @@ async function runDoctor(args = [], root, doctorFix) {
388
534
  }))
389
535
  : null;
390
536
  const context7McpRepair = doctorFix
391
- ? await repairContext7Mcp({ root, apply: true }).catch((err) => ({
537
+ ? await (await import('../core/doctor/context7-mcp-repair.js')).repairContext7Mcp({ root, apply: true }).catch((err) => ({
392
538
  schema: 'sks.doctor-context7-mcp-repair.v1',
393
539
  ok: false,
394
540
  apply: true,
@@ -399,7 +545,7 @@ async function runDoctor(args = [], root, doctorFix) {
399
545
  }))
400
546
  : null;
401
547
  const supabaseMcpRepair = doctorFix && doctorPhaseIds.includes('supabase_mcp_repair')
402
- ? await repairSupabaseMcp({ root, apply: true }).catch((err) => ({
548
+ ? await (await import('../core/doctor/supabase-mcp-repair.js')).repairSupabaseMcp({ root, apply: true }).catch((err) => ({
403
549
  schema: 'sks.doctor-supabase-mcp-repair.v1',
404
550
  ok: false,
405
551
  apply: true,
@@ -419,7 +565,7 @@ async function runDoctor(args = [], root, doctorFix) {
419
565
  }))
420
566
  : null;
421
567
  const hookTrustRepair = doctorFix && doctorPhaseIds.includes('hook_trust_repair')
422
- ? await codexHookTrustDoctor(root, { fix: true, managed: true, actual: true }).catch((err) => ({
568
+ ? await (await import('../core/codex-hooks/codex-hook-trust-doctor.js')).codexHookTrustDoctor(root, { fix: true, managed: true, actual: true }).catch((err) => ({
423
569
  schema: 'sks.codex-hook-trust-doctor.v2',
424
570
  ok: false,
425
571
  actual: true,
@@ -429,7 +575,7 @@ async function runDoctor(args = [], root, doctorFix) {
429
575
  }))
430
576
  : null;
431
577
  const doctorFixTransaction = doctorFix
432
- ? await runDoctorFixTransaction({
578
+ ? await (await import('../core/doctor/doctor-transaction.js')).runDoctorFixTransaction({
433
579
  root,
434
580
  dirtyPlan: doctorDirtyPlan,
435
581
  json: flag(args, '--json'),
@@ -599,7 +745,7 @@ async function runDoctor(args = [], root, doctorFix) {
599
745
  raw_secret_values_recorded: false
600
746
  }))
601
747
  : null;
602
- const doctorFixPostcheck = doctorFix ? doctorRepairPostcheck(doctorFixTransaction) : null;
748
+ const doctorFixPostcheck = doctorFix ? (await import('../core/doctor/doctor-repair-postcheck.js')).doctorRepairPostcheck(doctorFixTransaction) : null;
603
749
  const zellij = await checkZellijCapability({ root, require: process.env.SKS_REQUIRE_ZELLIJ === '1' });
604
750
  const localModel = await readLocalModelConfig().catch(() => null);
605
751
  const permissionProfiles = await inventoryCodexPermissionProfiles(root, { writeReport: true });
@@ -618,8 +764,9 @@ async function runDoctor(args = [], root, doctorFix) {
618
764
  blockers: [err?.message || String(err)]
619
765
  }));
620
766
  const globalSksInstallCleanup = flag(args, '--fix') && !flag(args, '--local-only')
621
- ? await cleanDuplicateGlobalSksInstalls({ root, fix: true }).catch((err) => ({ schema: 'sks.global-sks-install-cleanup.v1', ok: false, fix: true, error: err?.message || String(err), blockers: ['global_sks_install_cleanup_exception'] }))
767
+ ? await (await import('../core/doctor/global-sks-install-cleanup.js')).cleanDuplicateGlobalSksInstalls({ root, fix: true }).catch((err) => ({ schema: 'sks.global-sks-install-cleanup.v1', ok: false, fix: true, error: err?.message || String(err), blockers: ['global_sks_install_cleanup_exception'] }))
622
768
  : null;
769
+ const shouldProbeNativeCapabilityRepairs = doctorFix || deepDiagnostics || nativeCapabilityDiagnosticsRequested;
623
770
  const imagegen = await detectImagegenCapability({ codexBin: codexBin || undefined }).catch((err) => ({ ok: false, error: err.message, auth_readiness: null, core_ready: false, blockers: ['imagegen_detection_exception'] }));
624
771
  const imagegenRepair = imagegen.core_ready === true
625
772
  ? {
@@ -635,35 +782,49 @@ async function runDoctor(args = [], root, doctorFix) {
635
782
  manual_actions: [],
636
783
  communication_test: { level: 'flag_level', ok: true, checked: 'codex features list --json (feature-flag/plugin metadata only)', real_generation_round_trip_performed: false, blocker: null }
637
784
  }
638
- : await repairCodexImagegen({ root, apply: doctorFix, codexBin: codexBin || null }).catch((err) => ({
639
- schema: 'sks.doctor-imagegen-repair.v1',
785
+ : shouldProbeNativeCapabilityRepairs
786
+ ? await (await import('../core/doctor/imagegen-repair.js')).repairCodexImagegen({ root, apply: doctorFix, codexBin: codexBin || null }).catch((err) => ({
787
+ schema: 'sks.doctor-imagegen-repair.v1',
788
+ ok: false,
789
+ attempted: true,
790
+ apply: doctorFix,
791
+ recovered: false,
792
+ blockers: [err?.message || String(err)],
793
+ manual_actions: ['Run `sks doctor --fix --json` after enabling Codex App image_generation.']
794
+ }))
795
+ : deferredNativeRepair('sks.doctor-imagegen-repair.v1', doctorFix, [
796
+ 'Run `sks doctor --fix --repair-native-capabilities --json` after enabling Codex App image_generation.'
797
+ ]);
798
+ const computerUseRepair = shouldProbeNativeCapabilityRepairs
799
+ ? await (await import('../core/doctor/computer-use-repair.js')).repairComputerUse({ root, apply: doctorFix, codexBin: codexBin || null }).catch((err) => ({
800
+ schema: 'sks.doctor-computer-use-repair.v1',
640
801
  ok: false,
641
- attempted: true,
802
+ attempted: false,
642
803
  apply: doctorFix,
643
804
  recovered: false,
644
805
  blockers: [err?.message || String(err)],
645
- manual_actions: ['Run `sks doctor --fix --json` after enabling Codex App image_generation.']
646
- }));
647
- const computerUseRepair = await repairComputerUse({ root, apply: doctorFix, codexBin: codexBin || null }).catch((err) => ({
648
- schema: 'sks.doctor-computer-use-repair.v1',
649
- ok: false,
650
- attempted: false,
651
- apply: doctorFix,
652
- recovered: false,
653
- blockers: [err?.message || String(err)],
654
- next_actions: ['Run `sks doctor --fix --json` after checking Codex App settings for Computer Use.']
655
- }));
656
- const browserUseRepair = await repairBrowserUse({ root, apply: doctorFix, codexBin: codexBin || null }).catch((err) => ({
657
- schema: 'sks.doctor-browser-use-repair.v1',
658
- ok: false,
659
- attempted: false,
660
- apply: doctorFix,
661
- recovered: false,
662
- blockers: [err?.message || String(err)],
663
- next_actions: ['Run `sks doctor --fix --json` after checking Codex App settings for Browser Use / Chrome extension.']
664
- }));
806
+ next_actions: ['Run `sks doctor --fix --json` after checking Codex App settings for Computer Use.']
807
+ }))
808
+ : deferredNativeRepair('sks.doctor-computer-use-repair.v1', doctorFix, [
809
+ 'Computer Use route needs manual OS/App permission verification before use.',
810
+ 'Run `sks doctor --fix --repair-native-capabilities --json` for an explicit Computer Use repair probe.'
811
+ ]);
812
+ const browserUseRepair = shouldProbeNativeCapabilityRepairs
813
+ ? await (await import('../core/doctor/browser-use-repair.js')).repairBrowserUse({ root, apply: doctorFix, codexBin: codexBin || null }).catch((err) => ({
814
+ schema: 'sks.doctor-browser-use-repair.v1',
815
+ ok: false,
816
+ attempted: false,
817
+ apply: doctorFix,
818
+ recovered: false,
819
+ blockers: [err?.message || String(err)],
820
+ next_actions: ['Run `sks doctor --fix --json` after checking Codex App settings for Browser Use / Chrome extension.']
821
+ }))
822
+ : deferredNativeRepair('sks.doctor-browser-use-repair.v1', doctorFix, [
823
+ 'Chrome/web review route needs the Codex Chrome Extension enabled before use.',
824
+ 'Run `sks doctor --fix --repair-native-capabilities --json` for an explicit Browser Use repair probe.'
825
+ ]);
665
826
  const mcpTransportCollisionRepair = doctorFix
666
- ? await detectAndRepairMcpTransportCollisions({ root, apply: true }).catch((err) => ({
827
+ ? await (await import('../core/doctor/mcp-transport-collision-repair.js')).detectAndRepairMcpTransportCollisions({ root, apply: true }).catch((err) => ({
667
828
  schema: 'sks.mcp-transport-collision-repair.v1',
668
829
  ok: false,
669
830
  apply: true,
@@ -675,7 +836,9 @@ async function runDoctor(args = [], root, doctorFix) {
675
836
  raw_secret_values_recorded: false
676
837
  }))
677
838
  : null;
678
- const nativeCapabilityReadinessStatus = (repair) => (repair?.recovered === true || repair?.ok === true ? 'ok' : repair?.attempted ? 'blocked' : 'not-needed');
839
+ const nativeCapabilityReadinessStatus = (repair) => repair?.skipped === true
840
+ ? (repair.status || 'deferred')
841
+ : (repair?.recovered === true || repair?.ok === true ? 'ok' : repair?.attempted ? 'blocked' : 'not-needed');
679
842
  const nativeCapabilityReadiness = {
680
843
  schema: 'sks.native-capability-readiness.v1',
681
844
  generated_at: nowIso(),
@@ -702,7 +865,7 @@ async function runDoctor(args = [], root, doctorFix) {
702
865
  : null;
703
866
  const repairCodexNative = doctorFix && doctorPhaseIds.includes('native_capability_repair');
704
867
  const codexNativeRepair = repairCodexNative
705
- ? await repairCodexNativeManagedAssets({
868
+ ? await (await import('../core/codex-native/codex-native-repair-transaction.js')).repairCodexNativeManagedAssets({
706
869
  root,
707
870
  requestedBy: 'doctor --fix',
708
871
  yes: flag(args, '--yes') || flag(args, '-y')
@@ -1211,6 +1374,21 @@ function buildRuntimeReadiness(zellijReadiness, matrix) {
1211
1374
  repair_actions: [...new Set(repairActions)]
1212
1375
  };
1213
1376
  }
1377
+ function deferredNativeRepair(schema, doctorFix, nextActions) {
1378
+ return {
1379
+ schema,
1380
+ generated_at: nowIso(),
1381
+ ok: true,
1382
+ skipped: true,
1383
+ status: 'deferred_to_explicit_native_capability_probe',
1384
+ attempted: false,
1385
+ apply: doctorFix,
1386
+ recovered: false,
1387
+ blockers: [],
1388
+ next_actions: nextActions,
1389
+ manual_actions: nextActions
1390
+ };
1391
+ }
1214
1392
  function fallbackCodexNativeFeatureMatrix(codex, blockers = [], warnings = []) {
1215
1393
  return {
1216
1394
  schema: 'sks.codex-native-feature-matrix.v1',