sneakoscope 4.0.15 → 4.1.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.
- package/README.md +10 -1
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/bin/sks.js +1 -1
- package/dist/cli/install-helpers.js +12 -0
- package/dist/cli/router.js +8 -0
- package/dist/commands/doctor.js +89 -25
- package/dist/core/agents/agent-role-config.js +18 -41
- package/dist/core/codex-app/codex-agent-role-sync.js +3 -3
- package/dist/core/codex-control/codex-app-server-v2-client.js +1 -1
- package/dist/core/codex-native/codex-native-feature-broker.js +63 -10
- package/dist/core/codex-native/codex-native-feature-matrix.js +11 -2
- package/dist/core/commands/basic-cli.js +9 -0
- package/dist/core/doctor/codex-doctor-bridge.js +135 -21
- package/dist/core/doctor/doctor-dirty-planner.js +43 -4
- package/dist/core/doctor/doctor-readiness-matrix.js +117 -5
- package/dist/core/doctor/doctor-repair-postcheck.js +3 -2
- package/dist/core/doctor/doctor-transaction.js +10 -3
- package/dist/core/fsx.js +1 -1
- package/dist/core/init.js +2 -2
- package/dist/core/managed-assets/managed-assets-manifest.js +106 -0
- package/dist/core/providers/glm/bench/glm-benchmark-runner.js +3 -3
- package/dist/core/providers/glm/bench/glm-benchmark-types.js +1 -1
- package/dist/core/routes.js +8 -4
- package/dist/core/update/update-migration-state.js +280 -0
- package/dist/core/update-check.js +151 -4
- package/dist/core/version.js +1 -1
- package/dist/scripts/codex-0142-doctor-wiring-check.js +21 -0
- package/dist/scripts/codex-0142-manifest-check.js +1 -1
- package/dist/scripts/doctor-fix-production-blackbox.js +4 -4
- package/dist/scripts/doctor-plain-fix-native-assets-check.js +12 -0
- package/dist/scripts/doctor-post-repair-authoritative-check.js +39 -0
- package/dist/scripts/doctor-transaction-owns-mutations-check.js +14 -0
- package/dist/scripts/doctor-warning-only-not-blocker-check.js +39 -0
- package/dist/scripts/loop-directive-check-lib.js +1 -1
- package/dist/scripts/machine-local-evidence-zero-check.js +22 -0
- package/dist/scripts/managed-role-manifest-parity-check.js +20 -0
- package/dist/scripts/postinstall-global-doctor-blackbox.js +12 -0
- package/dist/scripts/update-concurrent-lock-check.js +10 -0
- package/dist/scripts/update-doctor-lifecycle-check.js +13 -0
- package/dist/scripts/update-first-command-migration-check.js +13 -0
- package/dist/scripts/update-new-binary-reexec-check.js +12 -0
- package/package.json +13 -1
- package/schemas/doctor-status-v2.schema.json +42 -0
- package/schemas/update-migration.schema.json +35 -0
package/README.md
CHANGED
|
@@ -35,7 +35,16 @@ Set up this agent project with Sneakoscope Codex. Use [[mandarange/Sneakoscope-C
|
|
|
35
35
|
|
|
36
36
|
## 🚀 Current Release
|
|
37
37
|
|
|
38
|
-
SKS **4.0
|
|
38
|
+
SKS **4.1.0** turns the Codex `rust-v0.142.0` compatibility surface into the authoritative Doctor/update readiness path. Doctor now consumes structured Codex Doctor semantics, separates pre-repair observation from post-repair truth, repairs managed native assets from plain `sks doctor --fix`, and gates update completion on a current project migration receipt.
|
|
39
|
+
|
|
40
|
+
What changed in 4.1.0:
|
|
41
|
+
|
|
42
|
+
- **Semantic Doctor readiness.** Warning-only Codex Doctor output stays ready, blocking checks block readiness, and unknown non-zero/unparseable Doctor output fails closed.
|
|
43
|
+
- **Post-repair authority.** `sks doctor --fix` records pre-repair Codex Doctor output but bases readiness on the final post-repair Doctor run.
|
|
44
|
+
- **Managed native assets.** Skills, agent roles, hooks, and Context7 transport share the 4.1.0 managed manifest; stale directive markers no longer appear in generated role content.
|
|
45
|
+
- **Codex 0.142 wiring.** The native feature broker exposes multi-agent mode, rollout budget strategy, indexed web search, current time, app-server overload, MCP reconnect, plugin refresh, thread search, remote native environment, and terminal subagent error handling as current capabilities.
|
|
46
|
+
- **Update lifecycle receipts.** `sks update now` runs old-version Doctor preflight, installs through the guarded npm path, re-resolves the new package-local binary, runs new-version global Doctor, and writes a project migration receipt before reporting `updated`.
|
|
47
|
+
- **Local evidence hygiene.** Machine-local `.sneakoscope` runtime evidence is ignored and guarded so release commits do not carry host paths, secrets, or transient proof logs.
|
|
39
48
|
|
|
40
49
|
What changed in 4.0.15:
|
|
41
50
|
|
|
@@ -4,7 +4,7 @@ use std::io::{self, Read, Seek, SeekFrom};
|
|
|
4
4
|
fn main() {
|
|
5
5
|
let mut args = std::env::args().skip(1);
|
|
6
6
|
match args.next().as_deref() {
|
|
7
|
-
Some("--version") => println!("sks-rs 4.0
|
|
7
|
+
Some("--version") => println!("sks-rs 4.1.0"),
|
|
8
8
|
Some("compact-info") => {
|
|
9
9
|
let mut input = String::new();
|
|
10
10
|
let _ = io::stdin().read_to_string(&mut input);
|
package/dist/bin/sks.js
CHANGED
|
@@ -15,6 +15,7 @@ import { reconcileCodexAppUpgradeProcesses } from '../core/codex-app.js';
|
|
|
15
15
|
import { recordCodexLbHealthEvent } from '../core/codex-lb-circuit.js';
|
|
16
16
|
import { loadCodexLbEnv, writeCodexLbKeychain, codexLbMetadataPath } from '../core/codex-lb/codex-lb-env.js';
|
|
17
17
|
import { buildCodexLbSetupPlan, codexLbPersistenceSummary, installCodexLbShellProfileSnippet, selectedCodexLbPersistenceModes } from '../core/codex-lb/codex-lb-setup.js';
|
|
18
|
+
import { runPostinstallGlobalDoctorAndMarkPending } from '../core/update/update-migration-state.js';
|
|
18
19
|
const DEFAULT_CODEX_APP_PLUGINS = [
|
|
19
20
|
['browser', 'openai-bundled'],
|
|
20
21
|
['chrome', 'openai-bundled'],
|
|
@@ -80,6 +81,17 @@ export async function postinstall({ bootstrap, args = [] }) {
|
|
|
80
81
|
console.log(`Codex App Fast mode: skipped (${fastModeRepair.reason}).`);
|
|
81
82
|
else if (fastModeRepair.status === 'failed')
|
|
82
83
|
console.log(`Codex App Fast mode: auto repair failed. Run \`sks setup\`. ${fastModeRepair.error || ''}`.trim());
|
|
84
|
+
const postinstallDoctor = await runPostinstallGlobalDoctorAndMarkPending().catch((err) => ({
|
|
85
|
+
ok: false,
|
|
86
|
+
doctor: null,
|
|
87
|
+
pending: null,
|
|
88
|
+
blockers: [err?.message || String(err)],
|
|
89
|
+
warnings: []
|
|
90
|
+
}));
|
|
91
|
+
if (postinstallDoctor.ok)
|
|
92
|
+
console.log('SKS update migration: global Doctor ran; project receipt will be finalized on first normal command.');
|
|
93
|
+
else
|
|
94
|
+
console.log(`SKS update migration: global Doctor did not complete; first normal command will retry. ${(postinstallDoctor.blockers || []).join(', ')}`.trim());
|
|
83
95
|
// Terminating a third-party app's processes during `npm i` is unsafe by default; opt-in only.
|
|
84
96
|
const appProcessRepair = process.env.SKS_POSTINSTALL_RECONCILE_APP_PROCESSES === '1'
|
|
85
97
|
? await reconcileCodexAppUpgradeProcesses()
|
package/dist/cli/router.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { COMMAND_ALIASES, COMMANDS, } from './command-registry.js';
|
|
2
2
|
import { detectGlobalMode, glmWithoutMadResult } from './global-mode-router.js';
|
|
3
|
+
import { ensureCurrentMigrationBeforeCommand } from '../core/update/update-migration-state.js';
|
|
3
4
|
export function isCommandName(value) {
|
|
4
5
|
return Object.prototype.hasOwnProperty.call(COMMANDS, value);
|
|
5
6
|
}
|
|
@@ -48,6 +49,13 @@ export async function dispatch(args) {
|
|
|
48
49
|
return result;
|
|
49
50
|
}
|
|
50
51
|
const entry = COMMANDS[command];
|
|
52
|
+
const migrationGate = await ensureCurrentMigrationBeforeCommand({ command, args: rest });
|
|
53
|
+
if (!migrationGate.ok) {
|
|
54
|
+
console.error(`SKS update migration blocked: ${migrationGate.blockers.join(', ')}`);
|
|
55
|
+
console.error('Run: sks doctor --fix --yes');
|
|
56
|
+
process.exitCode = 1;
|
|
57
|
+
return migrationGate;
|
|
58
|
+
}
|
|
51
59
|
const mod = await entry.lazy();
|
|
52
60
|
if (typeof mod.run !== 'function')
|
|
53
61
|
throw new Error(`Command ${command} must export run(command, args)`);
|
package/dist/commands/doctor.js
CHANGED
|
@@ -49,10 +49,12 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
49
49
|
let setupRepair = null;
|
|
50
50
|
const sksUpdate = doctorFix
|
|
51
51
|
? {
|
|
52
|
-
schema: 'sks.update-now.
|
|
52
|
+
schema: 'sks.update-now.v2',
|
|
53
53
|
ok: true,
|
|
54
54
|
status: 'skipped',
|
|
55
|
-
reason: 'manual_update_commands_only'
|
|
55
|
+
reason: 'manual_update_commands_only',
|
|
56
|
+
stages: [],
|
|
57
|
+
migration_current: true
|
|
56
58
|
}
|
|
57
59
|
: null;
|
|
58
60
|
let migrationPreFix = null;
|
|
@@ -145,9 +147,9 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
145
147
|
? await writeFixMigrationJournal(root, migrationPreFix, configRepair, setupRepair).catch(() => null)
|
|
146
148
|
: null;
|
|
147
149
|
let codexConfig = configRepair?.after || await inspectCodexConfigReadability(root, configProbeOpts);
|
|
148
|
-
const
|
|
149
|
-
const codexDoctorDiff = compareCodexDoctorBridge(codexDoctorBefore,
|
|
150
|
-
codexStartupRepair = mergeObservedCodexStartupWarnings(codexStartupRepair,
|
|
150
|
+
const preRepairCodexDoctor = await runCodexDoctorBridge({ codexBin: codexBin || null, cwd: root, required: flag(args, '--require-actual-codex') });
|
|
151
|
+
const codexDoctorDiff = compareCodexDoctorBridge(codexDoctorBefore, preRepairCodexDoctor);
|
|
152
|
+
codexStartupRepair = mergeObservedCodexStartupWarnings(codexStartupRepair, preRepairCodexDoctor);
|
|
151
153
|
const codex = codexBin
|
|
152
154
|
? { bin: codexBin, version: 'fixture-or-explicit', available: true }
|
|
153
155
|
: await getCodexInfo().catch(() => ({ bin: null, version: null, available: false }));
|
|
@@ -308,7 +310,8 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
308
310
|
id: 'setup',
|
|
309
311
|
ok: setupRepair !== null,
|
|
310
312
|
repaired: setupRepair !== null,
|
|
311
|
-
blockers: setupRepair === null ? ['setup_repair_not_recorded'] : []
|
|
313
|
+
blockers: setupRepair === null ? ['setup_repair_not_recorded'] : [],
|
|
314
|
+
rollback_evidence: setupRepair?.config_backup_path || 'setup_force_regeneration_idempotent_manifest'
|
|
312
315
|
})
|
|
313
316
|
},
|
|
314
317
|
{
|
|
@@ -318,7 +321,8 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
318
321
|
ok: codexStartupRepair?.ok !== false,
|
|
319
322
|
repaired: doctorFix,
|
|
320
323
|
blockers: codexStartupRepair?.blockers || [],
|
|
321
|
-
warnings: codexStartupRepair?.warnings || []
|
|
324
|
+
warnings: codexStartupRepair?.warnings || [],
|
|
325
|
+
rollback_evidence: codexStartupRepair?.report_path || 'codex_startup_repair_report'
|
|
322
326
|
})
|
|
323
327
|
},
|
|
324
328
|
{
|
|
@@ -327,7 +331,8 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
327
331
|
id: 'startup_config_repair',
|
|
328
332
|
ok: startupConfigRepair?.ok === true,
|
|
329
333
|
repaired: startupConfigRepair?.apply === true,
|
|
330
|
-
blockers: startupConfigRepair?.blockers || []
|
|
334
|
+
blockers: startupConfigRepair?.blockers || [],
|
|
335
|
+
rollback_evidence: startupConfigRepair?.backup_path || 'startup_config_repair_idempotent_report'
|
|
331
336
|
})
|
|
332
337
|
},
|
|
333
338
|
{
|
|
@@ -337,7 +342,8 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
337
342
|
ok: context7Repair?.ok !== false,
|
|
338
343
|
repaired: doctorFix,
|
|
339
344
|
blockers: context7Repair?.blockers || [],
|
|
340
|
-
warnings: context7Repair?.warnings || []
|
|
345
|
+
warnings: context7Repair?.warnings || [],
|
|
346
|
+
rollback_evidence: context7Repair?.report_path || 'context7_repair_report'
|
|
341
347
|
})
|
|
342
348
|
},
|
|
343
349
|
{
|
|
@@ -348,7 +354,8 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
348
354
|
repaired: context7McpRepair?.repaired === true,
|
|
349
355
|
manual_required: context7McpRepair?.manual_required === true,
|
|
350
356
|
blockers: context7McpRepair?.blockers || [],
|
|
351
|
-
warnings: context7McpRepair?.warnings || []
|
|
357
|
+
warnings: context7McpRepair?.warnings || [],
|
|
358
|
+
rollback_evidence: context7McpRepair?.backup_path || 'context7_mcp_repair_idempotent_report'
|
|
352
359
|
})
|
|
353
360
|
},
|
|
354
361
|
{
|
|
@@ -361,7 +368,8 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
361
368
|
manual_required: supabaseMcpRepair?.manual_required === true,
|
|
362
369
|
required_for_ready: false,
|
|
363
370
|
blockers: supabaseMcpRepair?.blockers || [],
|
|
364
|
-
warnings: supabaseMcpRepair?.warnings || []
|
|
371
|
+
warnings: supabaseMcpRepair?.warnings || [],
|
|
372
|
+
rollback_evidence: 'optional_supabase_no_ready_mutation_required'
|
|
365
373
|
})
|
|
366
374
|
},
|
|
367
375
|
{
|
|
@@ -370,7 +378,8 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
370
378
|
id: 'command_alias_cleanup',
|
|
371
379
|
ok: commandAliasCleanup?.ok !== false,
|
|
372
380
|
repaired: Array.isArray(commandAliasCleanup?.actions) && commandAliasCleanup.actions.length > 0,
|
|
373
|
-
blockers: commandAliasCleanup?.blockers || []
|
|
381
|
+
blockers: commandAliasCleanup?.blockers || [],
|
|
382
|
+
rollback_evidence: commandAliasCleanup?.report_path || 'command_alias_cleanup_report'
|
|
374
383
|
})
|
|
375
384
|
},
|
|
376
385
|
{
|
|
@@ -379,14 +388,17 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
379
388
|
id: 'native_capability_repair',
|
|
380
389
|
ok: doctorNativeCapabilityRepair?.ok !== false,
|
|
381
390
|
repaired: doctorFix,
|
|
382
|
-
blockers: doctorNativeCapabilityRepair?.blockers || []
|
|
391
|
+
blockers: doctorNativeCapabilityRepair?.blockers || [],
|
|
392
|
+
rollback_evidence: doctorNativeCapabilityRepair?.secret_preservation_guard || 'native_capability_repair_report'
|
|
383
393
|
})
|
|
384
394
|
}
|
|
385
395
|
]
|
|
386
396
|
}).catch((err) => ({
|
|
387
|
-
schema: 'sks.doctor-fix-transaction.
|
|
397
|
+
schema: 'sks.doctor-fix-transaction.v2',
|
|
398
|
+
generated_at: new Date().toISOString(),
|
|
388
399
|
ok: false,
|
|
389
400
|
postcheck_ok: false,
|
|
401
|
+
dirty_plan: doctorDirtyPlan,
|
|
390
402
|
phases: [
|
|
391
403
|
{
|
|
392
404
|
id: 'doctor_fix_transaction',
|
|
@@ -395,9 +407,11 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
395
407
|
manual_required: false,
|
|
396
408
|
blockers: [err?.message || String(err)],
|
|
397
409
|
warnings: [],
|
|
398
|
-
artifact_path: null
|
|
410
|
+
artifact_path: null,
|
|
411
|
+
rollback_evidence: null
|
|
399
412
|
}
|
|
400
413
|
],
|
|
414
|
+
mutations_without_rollback: 0,
|
|
401
415
|
rollback_performed: false,
|
|
402
416
|
raw_secret_values_recorded: false
|
|
403
417
|
}))
|
|
@@ -432,7 +446,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
432
446
|
const mcpPluginInventory = pluginInventory?.report
|
|
433
447
|
? await writeMcpPluginInventoryArtifacts(root, { inventory: pluginInventory.report }).catch((err) => ({ error: err?.message || String(err), candidates: null }))
|
|
434
448
|
: null;
|
|
435
|
-
const repairCodexNative = doctorFix
|
|
449
|
+
const repairCodexNative = doctorFix;
|
|
436
450
|
const codexNativeRepair = repairCodexNative
|
|
437
451
|
? await repairCodexNativeManagedAssets({
|
|
438
452
|
root,
|
|
@@ -485,13 +499,41 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
485
499
|
if (reinspected)
|
|
486
500
|
codexConfig = reinspected;
|
|
487
501
|
}
|
|
502
|
+
const postRepairCodexDoctor = doctorFix
|
|
503
|
+
? await runCodexDoctorBridge({ codexBin: codexBin || null, cwd: root, required: flag(args, '--fix') || flag(args, '--require-actual-codex') }).catch((err) => ({
|
|
504
|
+
schema: 'sks.codex-doctor-bridge.v2',
|
|
505
|
+
generated_at: new Date().toISOString(),
|
|
506
|
+
available: false,
|
|
507
|
+
exit_code: null,
|
|
508
|
+
process_exit_code: null,
|
|
509
|
+
disposition: 'block',
|
|
510
|
+
semantic_ok: false,
|
|
511
|
+
source_format: 'text-fallback',
|
|
512
|
+
blocking_checks: [],
|
|
513
|
+
warning_checks: [],
|
|
514
|
+
informational_checks: [],
|
|
515
|
+
environment_diagnostics_ok: false,
|
|
516
|
+
git_diagnostics_ok: false,
|
|
517
|
+
terminal_diagnostics_ok: false,
|
|
518
|
+
app_server_diagnostics_ok: false,
|
|
519
|
+
thread_inventory_ok: false,
|
|
520
|
+
stdout_tail: '',
|
|
521
|
+
stderr_tail: '',
|
|
522
|
+
blockers: [`post_repair_codex_doctor_exception:${err?.message || String(err)}`],
|
|
523
|
+
warnings: []
|
|
524
|
+
}))
|
|
525
|
+
: preRepairCodexDoctor;
|
|
526
|
+
const authoritativeCodexDoctor = postRepairCodexDoctor;
|
|
527
|
+
const codexDoctorAuthoritativeDiff = compareCodexDoctorBridge(codexDoctorBefore, authoritativeCodexDoctor);
|
|
488
528
|
const pkgBytes = await dirSize(root).catch(() => 0);
|
|
489
529
|
const ready = await writeDoctorReadinessMatrix(root, {
|
|
490
530
|
codex,
|
|
491
531
|
codex_config: codexConfig,
|
|
492
532
|
codex_app: codexApp,
|
|
493
533
|
codex_lb: codexLb,
|
|
494
|
-
codex_doctor:
|
|
534
|
+
codex_doctor: authoritativeCodexDoctor,
|
|
535
|
+
pre_repair_codex_doctor: preRepairCodexDoctor,
|
|
536
|
+
post_repair_codex_doctor: postRepairCodexDoctor,
|
|
495
537
|
require_codex_doctor: flag(args, '--fix') || flag(args, '--require-actual-codex'),
|
|
496
538
|
zellij,
|
|
497
539
|
context7_repair: context7Repair,
|
|
@@ -502,6 +544,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
502
544
|
doctor_fix_transaction: doctorFixTransaction,
|
|
503
545
|
doctor_dirty_plan: doctorDirtyPlan,
|
|
504
546
|
doctor_fix_postcheck: doctorFixPostcheck,
|
|
547
|
+
doctor_native_capability: doctorNativeCapabilityRepair,
|
|
505
548
|
local_model: localModel,
|
|
506
549
|
agent_role_config: agentRoleConfigRepair,
|
|
507
550
|
repair: configRepair,
|
|
@@ -522,7 +565,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
522
565
|
const zellijReadiness = buildZellijReadiness(root, zellij, ready);
|
|
523
566
|
const runtimeReadiness = buildRuntimeReadiness(zellijReadiness, codexNativeFeatureMatrix);
|
|
524
567
|
const result = {
|
|
525
|
-
schema: 'sks.doctor-status.
|
|
568
|
+
schema: 'sks.doctor-status.v2',
|
|
526
569
|
ok: ready.ready && (!sksUpdate || sksUpdate.ok !== false) && commandAliasCleanup.ok !== false && codexStartupRepair.ok !== false && (!doctorFixPostcheck || doctorFixPostcheck.ok !== false),
|
|
527
570
|
root,
|
|
528
571
|
node: { ok: Number(process.versions.node.split('.')[0]) >= 20, version: process.version },
|
|
@@ -533,8 +576,11 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
533
576
|
codex_app_ui: codexAppUi,
|
|
534
577
|
provider_context: providerContext,
|
|
535
578
|
codex_lb: codexLb,
|
|
536
|
-
codex_doctor:
|
|
537
|
-
|
|
579
|
+
codex_doctor: authoritativeCodexDoctor,
|
|
580
|
+
pre_repair_codex_doctor: preRepairCodexDoctor,
|
|
581
|
+
post_repair_codex_doctor: postRepairCodexDoctor,
|
|
582
|
+
codex_doctor_diff: codexDoctorAuthoritativeDiff,
|
|
583
|
+
observational_codex_doctor_diff: codexDoctorDiff,
|
|
538
584
|
zellij,
|
|
539
585
|
zellij_repair: zellijRepair,
|
|
540
586
|
context7_repair: context7Repair,
|
|
@@ -609,7 +655,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
609
655
|
console.log(` manual: ${action}`);
|
|
610
656
|
for (const warning of codexStartupRepair.warnings || [])
|
|
611
657
|
console.log(` warning: ${warning}`);
|
|
612
|
-
console.log(` codex doctor: ${
|
|
658
|
+
console.log(` codex doctor: ${authoritativeCodexDoctor.available ? (authoritativeCodexDoctor.disposition || (authoritativeCodexDoctor.exit_code === 0 ? 'pass' : 'warn')) : 'unavailable'}`);
|
|
613
659
|
console.log(`Rust acc.: ${rust.mode || (rust.available ? 'rust_accelerated' : 'js_fallback')} ${rust.version || rust.status || ''}`);
|
|
614
660
|
console.log(`Codex App: ${ready.codex_app_ready ? 'ok' : 'optional_missing'}`);
|
|
615
661
|
console.log('SKS Runtime Readiness:');
|
|
@@ -686,7 +732,14 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
686
732
|
}
|
|
687
733
|
}
|
|
688
734
|
const codex0138 = codex0138Capability.report || {};
|
|
689
|
-
console.log('Codex
|
|
735
|
+
console.log('Codex current compatibility:');
|
|
736
|
+
console.log(` target: rust-v0.142.0`);
|
|
737
|
+
console.log(` runtime: ${codex.version || 'unknown'}`);
|
|
738
|
+
console.log(` multi-agent mode: ${codexNativeFeatureMatrix.features?.multi_agent_mode?.ok ? 'verified' : 'unverified'}`);
|
|
739
|
+
console.log(` rollout budget: ${codexNativeFeatureMatrix.features?.rollout_budget?.ok ? 'verified' : 'unverified'}`);
|
|
740
|
+
console.log(` indexed search: ${codexNativeFeatureMatrix.features?.indexed_web_search?.ok ? 'verified' : 'unverified'}`);
|
|
741
|
+
console.log(` current time: ${codexNativeFeatureMatrix.features?.current_time_read?.ok ? 'verified' : 'unverified'}`);
|
|
742
|
+
console.log('Historical compatibility: Codex 0.138 features');
|
|
690
743
|
console.log(` /app handoff: ${codex0138.supports_app_handoff ? 'ok' : 'unavailable'}`);
|
|
691
744
|
console.log(` plugin JSON: ${codex0138.supports_plugin_json ? 'ok' : 'unavailable'}`);
|
|
692
745
|
console.log(` image path exposure: ${codex0138.supports_image_path_exposure ? 'ok' : 'unavailable'}`);
|
|
@@ -716,6 +769,7 @@ async function runDoctor(args = [], root, doctorFix) {
|
|
|
716
769
|
console.log('Ready:');
|
|
717
770
|
console.log(` cli_ready: ${ready.cli_ready ? 'yes' : 'no'}`);
|
|
718
771
|
console.log(` mad_ready: ${ready.mad_ready ? 'yes' : 'no'}`);
|
|
772
|
+
console.log(` managed_state_current: ${ready.managed_state_current ? 'yes' : 'no'}`);
|
|
719
773
|
console.log(` ready: ${ready.ready ? 'yes' : 'no'}`);
|
|
720
774
|
if (!ready.ready) {
|
|
721
775
|
console.log('Primary blocker:');
|
|
@@ -747,6 +801,9 @@ function buildRuntimeReadiness(zellijReadiness, matrix) {
|
|
|
747
801
|
const defaults = matrix?.invocation_defaults || {};
|
|
748
802
|
const hookPolicy = defaults.hook_evidence_policy || 'unknown-do-not-count';
|
|
749
803
|
const agentStrategy = defaults.loop_worker_role_strategy || 'message-role';
|
|
804
|
+
const multiAgentMode = defaults.multi_agent_mode || 'none';
|
|
805
|
+
const rolloutBudget = defaults.rollout_budget_strategy || 'sks-local-only';
|
|
806
|
+
const researchSource = defaults.research_source_strategy || 'local-files';
|
|
750
807
|
const zellijStatus = zellijReadiness?.status === 'ok'
|
|
751
808
|
? 'ok'
|
|
752
809
|
: zellijReadiness?.cli_ready ? 'headless_available' : 'repair_required';
|
|
@@ -759,7 +816,7 @@ function buildRuntimeReadiness(zellijReadiness, matrix) {
|
|
|
759
816
|
repairActions.push('Homebrew + Zellij: sks doctor --fix --install-homebrew --yes');
|
|
760
817
|
}
|
|
761
818
|
if (codexNative !== 'ok')
|
|
762
|
-
repairActions.push('Codex Native managed assets: sks doctor --fix --
|
|
819
|
+
repairActions.push('Codex Native managed assets: sks doctor --fix --yes');
|
|
763
820
|
if (matrix?.features?.project_memory?.ok !== true)
|
|
764
821
|
repairActions.push('Project memory: sks codex-native init-deep --apply --directory-local');
|
|
765
822
|
return {
|
|
@@ -768,14 +825,21 @@ function buildRuntimeReadiness(zellijReadiness, matrix) {
|
|
|
768
825
|
codex_native: codexNative,
|
|
769
826
|
loop_mesh: agentStrategy === 'agent_type' ? 'ok' : 'fallback',
|
|
770
827
|
qa_visual: defaults.qa_visual_review_strategy || 'blocked',
|
|
771
|
-
research_sources:
|
|
828
|
+
research_sources: researchSource,
|
|
772
829
|
image_followup: defaults.image_followup_strategy || 'blocked',
|
|
773
830
|
hook_evidence_policy: hookPolicy,
|
|
774
831
|
agent_role_strategy: agentStrategy,
|
|
832
|
+
multi_agent_mode: multiAgentMode,
|
|
833
|
+
rollout_budget_strategy: rolloutBudget,
|
|
834
|
+
current_time_source: defaults.current_time_source || 'external-clock',
|
|
835
|
+
overload_retry_policy: defaults.overload_retry_policy || 'generic',
|
|
775
836
|
notes: [
|
|
776
837
|
...(zellijStatus === 'headless_available' ? ['MAD can run with --headless; live panes require repair'] : []),
|
|
777
838
|
...(hookPolicy !== 'approved-only' ? ['hook-derived evidence will not count'] : []),
|
|
778
|
-
...(agentStrategy !== 'agent_type' ? ['message-role fallback active'] : [])
|
|
839
|
+
...(agentStrategy !== 'agent_type' ? ['message-role fallback active'] : []),
|
|
840
|
+
...(multiAgentMode === 'proactive' ? ['Codex 0.142 multi-agent proactive mode available for Naruto-style routes'] : []),
|
|
841
|
+
...(rolloutBudget === 'codex-0142-shared' ? ['Codex 0.142 rollout budget can be recorded in route proof'] : []),
|
|
842
|
+
...(researchSource === 'indexed-web-search' ? ['Codex 0.142 indexed web search selected for source-intelligence routes'] : [])
|
|
779
843
|
],
|
|
780
844
|
repair_actions: [...new Set(repairActions)]
|
|
781
845
|
};
|
|
@@ -1,26 +1,19 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { ensureDir, nowIso, writeJsonAtomic, writeTextAtomic } from '../fsx.js';
|
|
4
|
-
import {
|
|
4
|
+
import { MANAGED_AGENT_ROLES, managedAgentRoleByFile, managedAgentRoleByName, managedAgentRoleContent, managedAgentRoleOwnsText } from '../managed-assets/managed-assets-manifest.js';
|
|
5
5
|
export const AGENT_ROLE_CONFIG_REPAIR_SCHEMA = 'sks.agent-role-config-repair.v1';
|
|
6
|
-
export const SKS_OWNED_AGENT_CONFIGS = new Map([
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
['implementation-worker.toml', roleConfig('implementation_worker', 'Implementation specialist for bounded SKS Team write sets.', 'workspace-write')],
|
|
11
|
-
['db-safety-reviewer.toml', roleConfig('db_safety_reviewer', 'Read-only database safety reviewer for SQL, migrations, Supabase, and rollback safety.', 'read-only')],
|
|
12
|
-
['qa-reviewer.toml', roleConfig('qa_reviewer', 'Strict read-only verification reviewer for correctness, regressions, and final evidence.', 'read-only')]
|
|
13
|
-
]);
|
|
6
|
+
export const SKS_OWNED_AGENT_CONFIGS = new Map(MANAGED_AGENT_ROLES.map((role) => [
|
|
7
|
+
role.filename,
|
|
8
|
+
{ name: role.codex_name, sandbox: role.sandbox, content: managedAgentRoleContent(role), id: role.id }
|
|
9
|
+
]));
|
|
14
10
|
export function managedAgentRoleConfigForFile(file) {
|
|
15
|
-
|
|
11
|
+
const role = managedAgentRoleByFile(file);
|
|
12
|
+
return role ? managedAgentRoleContent(role) : null;
|
|
16
13
|
}
|
|
17
14
|
export function managedAgentRoleConfigForRole(role) {
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
if (config.name === normalized || path.basename(file, '.toml').replace(/-/g, '_') === normalized)
|
|
21
|
-
return { file, content: config.content };
|
|
22
|
-
}
|
|
23
|
-
return null;
|
|
15
|
+
const match = managedAgentRoleByName(role);
|
|
16
|
+
return match ? { file: match.filename, content: managedAgentRoleContent(match) } : null;
|
|
24
17
|
}
|
|
25
18
|
export async function repairAgentRoleConfigs(input) {
|
|
26
19
|
const root = path.resolve(input.root);
|
|
@@ -31,12 +24,14 @@ export async function repairAgentRoleConfigs(input) {
|
|
|
31
24
|
const created = [];
|
|
32
25
|
const repaired = [];
|
|
33
26
|
const existing = [];
|
|
34
|
-
for (const
|
|
27
|
+
for (const role of MANAGED_AGENT_ROLES) {
|
|
28
|
+
const file = role.filename;
|
|
29
|
+
const content = managedAgentRoleContent(role);
|
|
35
30
|
const found = candidates.find((dir) => fs.existsSync(path.join(dir, file)));
|
|
36
31
|
if (found) {
|
|
37
32
|
const foundPath = path.join(found, file);
|
|
38
33
|
const text = fs.readFileSync(foundPath, 'utf8');
|
|
39
|
-
if (isValidRoleConfig(text,
|
|
34
|
+
if (isValidRoleConfig(text, role)) {
|
|
40
35
|
existing.push(path.relative(root, foundPath) || foundPath);
|
|
41
36
|
continue;
|
|
42
37
|
}
|
|
@@ -44,7 +39,7 @@ export async function repairAgentRoleConfigs(input) {
|
|
|
44
39
|
if (input.apply) {
|
|
45
40
|
const target = foundPath.startsWith(path.join(root, '.codex', 'agents')) ? foundPath : path.join(root, '.codex', 'agents', file);
|
|
46
41
|
await ensureDir(path.dirname(target));
|
|
47
|
-
await writeTextAtomic(target,
|
|
42
|
+
await writeTextAtomic(target, content);
|
|
48
43
|
repaired.push(path.relative(root, target));
|
|
49
44
|
}
|
|
50
45
|
continue;
|
|
@@ -53,7 +48,7 @@ export async function repairAgentRoleConfigs(input) {
|
|
|
53
48
|
if (input.apply) {
|
|
54
49
|
const target = path.join(root, '.codex', 'agents', file);
|
|
55
50
|
await ensureDir(path.dirname(target));
|
|
56
|
-
await writeTextAtomic(target,
|
|
51
|
+
await writeTextAtomic(target, content);
|
|
57
52
|
created.push(path.relative(root, target));
|
|
58
53
|
}
|
|
59
54
|
}
|
|
@@ -69,6 +64,7 @@ export async function repairAgentRoleConfigs(input) {
|
|
|
69
64
|
existing,
|
|
70
65
|
created,
|
|
71
66
|
repaired,
|
|
67
|
+
manifest_role_ids: MANAGED_AGENT_ROLES.map((role) => role.id),
|
|
72
68
|
warnings_suppressed: true,
|
|
73
69
|
blockers: input.apply && requiredFixes !== appliedFixes ? ['agent_role_config_repair_incomplete'] : []
|
|
74
70
|
};
|
|
@@ -76,28 +72,9 @@ export async function repairAgentRoleConfigs(input) {
|
|
|
76
72
|
await writeJsonAtomic(input.reportPath, report);
|
|
77
73
|
return report;
|
|
78
74
|
}
|
|
79
|
-
function
|
|
80
|
-
|
|
81
|
-
`name = "${name}"`,
|
|
82
|
-
`description = "${description}"`,
|
|
83
|
-
`model = "${REQUIRED_CODEX_MODEL}"`,
|
|
84
|
-
'model_reasoning_effort = "medium"',
|
|
85
|
-
`sandbox_mode = "${sandbox}"`,
|
|
86
|
-
'approval_policy = "never"',
|
|
87
|
-
'developer_instructions = """',
|
|
88
|
-
`You are the SKS ${name} role.`,
|
|
89
|
-
sandbox === 'read-only' ? 'Do not edit files.' : 'Only edit the bounded files assigned by the parent orchestrator.',
|
|
90
|
-
'Return concise source-backed findings and LIVE_EVENT lines when applicable.',
|
|
91
|
-
'"""',
|
|
92
|
-
''
|
|
93
|
-
].join('\n');
|
|
94
|
-
return { name, sandbox, content };
|
|
95
|
-
}
|
|
96
|
-
function isValidRoleConfig(text, config) {
|
|
97
|
-
return text.includes(`name = "${config.name}"`)
|
|
75
|
+
function isValidRoleConfig(text, role) {
|
|
76
|
+
return managedAgentRoleOwnsText(text, role)
|
|
98
77
|
&& text.includes('description = "')
|
|
99
|
-
&& text.includes(`model = "${REQUIRED_CODEX_MODEL}"`)
|
|
100
|
-
&& text.includes(`sandbox_mode = "${config.sandbox}"`)
|
|
101
78
|
&& text.includes('developer_instructions = """');
|
|
102
79
|
}
|
|
103
80
|
//# sourceMappingURL=agent-role-config.js.map
|
|
@@ -86,12 +86,12 @@ export async function syncCodexAgentRoles(input) {
|
|
|
86
86
|
function roleToml(role, payload) {
|
|
87
87
|
return [
|
|
88
88
|
`name = "${role}"`,
|
|
89
|
-
`description = "SKS managed
|
|
89
|
+
`description = "SKS managed 4.1.0 directive role: ${role}"`,
|
|
90
90
|
'model_reasoning_effort = "medium"',
|
|
91
91
|
role.includes('implementer') ? 'sandbox_mode = "workspace-write"' : 'sandbox_mode = "read-only"',
|
|
92
92
|
'approval_policy = "never"',
|
|
93
93
|
'developer_instructions = """',
|
|
94
|
-
`You are ${role}. SKS managed
|
|
94
|
+
`You are ${role}. SKS managed 4.1.0 directive role with bounded ownership.`,
|
|
95
95
|
'Bounded ownership: use only the assigned owner files/directories and treat memory as guidance, not permission.',
|
|
96
96
|
role.includes('implementer') ? 'Maker/checker separation: implementer may patch only owner scope and cannot self-approve.' : 'Maker/checker separation: checker is read-only and must reject missing gates or missing proof artifacts.',
|
|
97
97
|
role.includes('implementer') ? 'Allowed sandbox: workspace-write only within assigned owner scope.' : 'Allowed sandbox: read-only; checker roles cannot mutate.',
|
|
@@ -107,7 +107,7 @@ function roleToml(role, payload) {
|
|
|
107
107
|
].join('\n');
|
|
108
108
|
}
|
|
109
109
|
function isSksManagedDirectiveRole(text) {
|
|
110
|
-
return /SKS managed 3\.1\.(?:4|5|6|7|11) (?:directive|bounded) role/.test(text)
|
|
110
|
+
return /SKS managed (?:3\.1\.(?:4|5|6|7|11)|4\.1\.0) (?:directive|bounded) role/.test(text)
|
|
111
111
|
|| /\bmessage_role_prefix\s*=/.test(text) && /SKS managed 3\.1\./.test(text);
|
|
112
112
|
}
|
|
113
113
|
function blockersOf(value) {
|