sneakoscope 1.19.0 → 1.20.2

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 (87) hide show
  1. package/README.md +7 -1
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/crates/sks-core/src/main.rs +1 -1
  5. package/dist/.sks-build-stamp.json +4 -4
  6. package/dist/bin/sks.js +1 -1
  7. package/dist/build-manifest.json +51 -9
  8. package/dist/cli/command-registry.d.ts +2 -0
  9. package/dist/cli/command-registry.js +1 -0
  10. package/dist/cli/install-helpers.js +15 -5
  11. package/dist/commands/doctor.js +134 -2
  12. package/dist/commands/image-ux-review.d.ts +7 -0
  13. package/dist/commands/ppt.d.ts +7 -0
  14. package/dist/commands/zellij.d.ts +4 -0
  15. package/dist/commands/zellij.js +111 -0
  16. package/dist/core/agents/agent-orchestrator.d.ts +7 -0
  17. package/dist/core/agents/agent-orchestrator.js +14 -1
  18. package/dist/core/agents/agent-proof-evidence.d.ts +9 -0
  19. package/dist/core/agents/agent-proof-evidence.js +9 -0
  20. package/dist/core/agents/route-collaboration-ledger.d.ts +7 -0
  21. package/dist/core/commands/image-ux-review-command.d.ts +7 -0
  22. package/dist/core/commands/image-ux-review-command.js +11 -0
  23. package/dist/core/commands/ppt-command.d.ts +7 -0
  24. package/dist/core/commands/wiki-command.d.ts +0 -1
  25. package/dist/core/commands/wiki-command.js +0 -9
  26. package/dist/core/feature-registry.js +1 -0
  27. package/dist/core/fsx.d.ts +1 -1
  28. package/dist/core/fsx.js +1 -1
  29. package/dist/core/image-ux-review/codex-app-generated-image-discovery.d.ts +44 -0
  30. package/dist/core/image-ux-review/codex-app-generated-image-discovery.js +118 -0
  31. package/dist/core/image-ux-review/imagegen-adapter.d.ts +1 -0
  32. package/dist/core/image-ux-review/imagegen-adapter.js +128 -33
  33. package/dist/core/imagegen/imagegen-auth-readiness.d.ts +30 -0
  34. package/dist/core/imagegen/imagegen-auth-readiness.js +83 -0
  35. package/dist/core/imagegen/imagegen-capability.d.ts +1 -0
  36. package/dist/core/imagegen/imagegen-capability.js +8 -0
  37. package/dist/core/init.js +79 -26
  38. package/dist/core/migration/migration-transaction-journal.d.ts +48 -0
  39. package/dist/core/migration/migration-transaction-journal.js +60 -0
  40. package/dist/core/release/gate-cache.d.ts +28 -0
  41. package/dist/core/release/gate-cache.js +39 -0
  42. package/dist/core/release/gate-manifest.d.ts +39 -0
  43. package/dist/core/release/gate-manifest.js +0 -0
  44. package/dist/core/responses-retry-policy.d.ts +33 -0
  45. package/dist/core/responses-retry-policy.js +46 -1
  46. package/dist/core/routes.js +1 -1
  47. package/dist/core/safety/mutation-guard.d.ts +52 -0
  48. package/dist/core/safety/mutation-guard.js +158 -0
  49. package/dist/core/safety/mutation-ledger.d.ts +33 -0
  50. package/dist/core/safety/mutation-ledger.js +75 -0
  51. package/dist/core/safety/requested-scope-contract.d.ts +36 -0
  52. package/dist/core/safety/requested-scope-contract.js +0 -0
  53. package/dist/core/skills/core-rollout-trace.d.ts +8 -0
  54. package/dist/core/skills/core-rollout-trace.js +33 -0
  55. package/dist/core/skills/core-skill-card.d.ts +35 -0
  56. package/dist/core/skills/core-skill-card.js +0 -0
  57. package/dist/core/skills/core-skill-deployment.d.ts +36 -0
  58. package/dist/core/skills/core-skill-deployment.js +116 -0
  59. package/dist/core/skills/core-skill-epoch.d.ts +35 -0
  60. package/dist/core/skills/core-skill-epoch.js +75 -0
  61. package/dist/core/skills/core-skill-patch-apply.d.ts +7 -0
  62. package/dist/core/skills/core-skill-patch-apply.js +100 -0
  63. package/dist/core/skills/core-skill-patch.d.ts +11 -0
  64. package/dist/core/skills/core-skill-patch.js +113 -0
  65. package/dist/core/skills/core-skill-runtime.d.ts +24 -0
  66. package/dist/core/skills/core-skill-runtime.js +39 -0
  67. package/dist/core/skills/core-skill-scorer.d.ts +16 -0
  68. package/dist/core/skills/core-skill-scorer.js +78 -0
  69. package/dist/core/skills/core-skill-types.d.ts +127 -0
  70. package/dist/core/skills/core-skill-types.js +16 -0
  71. package/dist/core/skills/core-skill-validation.d.ts +21 -0
  72. package/dist/core/skills/core-skill-validation.js +30 -0
  73. package/dist/core/skills/rejected-skill-patch-buffer.d.ts +8 -0
  74. package/dist/core/skills/rejected-skill-patch-buffer.js +32 -0
  75. package/dist/core/triwiki-runtime.d.ts +37 -0
  76. package/dist/core/triwiki-runtime.js +91 -0
  77. package/dist/core/version.d.ts +1 -1
  78. package/dist/core/version.js +1 -1
  79. package/dist/core/zellij/zellij-lane-renderer.d.ts +53 -1
  80. package/dist/core/zellij/zellij-lane-renderer.js +244 -29
  81. package/dist/core/zellij/zellij-layout-builder.d.ts +1 -1
  82. package/dist/core/zellij/zellij-screen-proof.d.ts +19 -0
  83. package/dist/core/zellij/zellij-screen-proof.js +35 -1
  84. package/dist/scripts/release-parallel-check.js +26 -0
  85. package/package.json +29 -3
  86. package/schemas/skills/core-skill-card.schema.json +27 -0
  87. package/schemas/skills/core-skill-patch.schema.json +39 -0
package/README.md CHANGED
@@ -16,7 +16,13 @@ Set up this agent project with Sneakoscope Codex. Use [[mandarange/Sneakoscope-C
16
16
 
17
17
  ## Current Release
18
18
 
19
- SKS **1.19.0** is the MAD Zellij dependency repair release: bootstrap/deps repair and `sks --mad --yes` now install or repair required CLI tooling, including Zellij on macOS/Homebrew, before opening the interactive runtime. npm postinstall still bootstraps and reports missing tools, but it does not silently mutate Homebrew/npm global tools unless `SKS_POSTINSTALL_AUTO_INSTALL_CLI_TOOLS=1` is set. MAD and Team layouts now use Zellij's documented background-layout launch form, and launch failures surface labeled Zellij stderr/stdout tails instead of only `zellij_command_failed`.
19
+ SKS **1.20.2** is a stabilization patch that closes the enforcement/integration/execution layers on top of the 1.20.1 infrastructure: a **Mutation Guard** routes genuinely-risky global/config/permission/package mutations through the Requested-Scope Contract + Mutation Ledger (`safety:mutation-callsite-coverage` fails any unguarded, unallowlisted risky call site); `release:check:dynamic:execute` turns the change-aware planner into a real **caching gate runner** (schema v2, real/heavy gates deferred to `release:real-check`, dynamic-only cannot authorize publish); the **Core Skill** deployed snapshot is now read by the route runtime and recorded in `agent-proof-evidence.json` (`selected_core_skill`), with promotions written to the mutation ledger; and `sks doctor` exposes an explicit **`zellij_readiness`** block (`zellij:doctor-readiness`). See `docs/dynamic-release-pipeline.md`.
20
+
21
+ SKS **1.20.1** introduces the **SKS Core Skill Engine** — a SkillOpt-style self-evolving skill layer — while locking the harness into a deploy-ready stable build. Skills are the agent's *external, versioned state* (Core Skill Cards): an optimizer proposes **bounded** add/delete/replace edits to a single skill document under a **textual edit budget**, edits are accepted **only on strict held-out improvement**, rejected edits are buffered so they are never retried, and the **deployed snapshot is immutable**. Critically, the optimizer runs only in training/evaluation — the **deployment/inference path reads the deployed snapshot and never makes an extra model call**, and a skill patch can never mutate code/config/package/global files.
22
+
23
+ 1.20.1 also adds a **Requested-Scope Contract + Mutation Ledger** so SKS performs **no side effect the user did not request** (deny-by-default; global/destructive mutations require explicit `--yes`/env opt-in and a backup or no-op reason), and a **dynamic, risk-based release pipeline** (`release:gate-planner` builds `release-gates.json`; `release:check:dynamic` runs only P0 always-on gates plus gates whose files changed; `release:gate-budget` reports the slowest gates) so unrelated heavy gates are skipped during incremental checks while publish never skips a required gate.
24
+
25
+ It carries forward the 1.19.x hardening unchanged: legacy 1.18.x/1.19.x→1.20.1 **zero-break upgrade** (user `model`/`service_tier`/`model_reasoning_effort` and user-disabled Codex App flags never overwritten; existing skill cards preserved), the **migration transaction journal** (`.sneakoscope/reports/migration-1.20.1-journal.jsonl`), **Zellij launch-command truth** + real-session **heartbeat-timeout blocker** + the redesigned **Zellij lane UI**, **packlist/publish-performance** gates, a **postinstall safe-side-effects** gate, and the **TS source-of-truth / Rust optional-accelerator** boundary (publish never compiles Rust). `sks zellij status`/`repair` inspects the Zellij runtime without auto-installing anything.
20
26
 
21
27
  ```bash
22
28
  sks mad-sks plan --target-root <path> --json
@@ -76,7 +76,7 @@ dependencies = [
76
76
 
77
77
  [[package]]
78
78
  name = "sks-core"
79
- version = "1.19.0"
79
+ version = "1.20.2"
80
80
  dependencies = [
81
81
  "serde_json",
82
82
  ]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "sks-core"
3
- version = "1.19.0"
3
+ version = "1.20.2"
4
4
  edition = "2021"
5
5
 
6
6
  [dependencies]
@@ -4,7 +4,7 @@ use std::io::{self, Read, Seek, SeekFrom};
4
4
  fn main() {
5
5
  let mut args = std::env::args().skip(1);
6
6
  match args.next().as_deref() {
7
- Some("--version") => println!("sks-rs 1.19.0"),
7
+ Some("--version") => println!("sks-rs 1.20.2"),
8
8
  Some("compact-info") => {
9
9
  let mut input = String::new();
10
10
  let _ = io::stdin().read_to_string(&mut input);
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schema": "sks.dist-build-stamp.v1",
3
3
  "package_name": "sneakoscope",
4
- "package_version": "1.19.0",
5
- "source_digest": "5eecdb85fa4e3cd359035b49803cd3e9ea0174810596807caf55b2507fb33d18",
6
- "source_file_count": 1690,
7
- "built_at_source_time": 1780116105711
4
+ "package_version": "1.20.2",
5
+ "source_digest": "d1ccddca4a2c7be54d3129554ea90f8d07efb093592c1e269399fa0e5b92d3ba",
6
+ "source_file_count": 1740,
7
+ "built_at_source_time": 1780235613612
8
8
  }
package/dist/bin/sks.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const FAST_PACKAGE_VERSION = '1.19.0';
2
+ const FAST_PACKAGE_VERSION = '1.20.2';
3
3
  const args = process.argv.slice(2);
4
4
  try {
5
5
  if (args[0] === '--agent' && args[1] === 'worker') {
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "schema": "sks.dist-build.v2",
3
- "version": "1.19.0",
4
- "package_version": "1.19.0",
3
+ "version": "1.20.2",
4
+ "package_version": "1.20.2",
5
5
  "typescript": true,
6
6
  "mjs_runtime_files": 0,
7
- "compiled_file_count": 974,
8
- "compiled_js_count": 487,
9
- "compiled_dts_count": 487,
10
- "source_digest": "5eecdb85fa4e3cd359035b49803cd3e9ea0174810596807caf55b2507fb33d18",
11
- "source_file_count": 1690,
12
- "source_files_hash": "c2267339884b83e1bfed20e6979b80f8a7abc07a05860d74c249d7684cb1c92d",
13
- "source_list_hash": "c2267339884b83e1bfed20e6979b80f8a7abc07a05860d74c249d7684cb1c92d",
7
+ "compiled_file_count": 1016,
8
+ "compiled_js_count": 508,
9
+ "compiled_dts_count": 508,
10
+ "source_digest": "d1ccddca4a2c7be54d3129554ea90f8d07efb093592c1e269399fa0e5b92d3ba",
11
+ "source_file_count": 1740,
12
+ "source_files_hash": "7484278e30e61755c2158548e697943af09e5a59de7c6b60018a0ac57848c6ec",
13
+ "source_list_hash": "7484278e30e61755c2158548e697943af09e5a59de7c6b60018a0ac57848c6ec",
14
14
  "src_mjs_runtime_files": 0,
15
15
  "dist_stamp_schema": "sks.dist-build-stamp.v1",
16
16
  "files": [
@@ -186,6 +186,8 @@
186
186
  "commands/wiki.js",
187
187
  "commands/zellij-lane.d.ts",
188
188
  "commands/zellij-lane.js",
189
+ "commands/zellij.d.ts",
190
+ "commands/zellij.js",
189
191
  "core/agents/agent-central-ledger.d.ts",
190
192
  "core/agents/agent-central-ledger.js",
191
193
  "core/agents/agent-cleanup-executor.d.ts",
@@ -616,6 +618,8 @@
616
618
  "core/image-ux-review.js",
617
619
  "core/image-ux-review/callout-extraction.d.ts",
618
620
  "core/image-ux-review/callout-extraction.js",
621
+ "core/image-ux-review/codex-app-generated-image-discovery.d.ts",
622
+ "core/image-ux-review/codex-app-generated-image-discovery.js",
619
623
  "core/image-ux-review/fix-loop.d.ts",
620
624
  "core/image-ux-review/fix-loop.js",
621
625
  "core/image-ux-review/fix-task-planner.d.ts",
@@ -630,6 +634,8 @@
630
634
  "core/image-ux-review/recapture.js",
631
635
  "core/imagegen/gpt-image-2-request-validator.d.ts",
632
636
  "core/imagegen/gpt-image-2-request-validator.js",
637
+ "core/imagegen/imagegen-auth-readiness.d.ts",
638
+ "core/imagegen/imagegen-auth-readiness.js",
633
639
  "core/imagegen/imagegen-capability.d.ts",
634
640
  "core/imagegen/imagegen-capability.js",
635
641
  "core/init.d.ts",
@@ -690,6 +696,8 @@
690
696
  "core/memory-governor.js",
691
697
  "core/memory-summary.d.ts",
692
698
  "core/memory-summary.js",
699
+ "core/migration/migration-transaction-journal.d.ts",
700
+ "core/migration/migration-transaction-journal.js",
693
701
  "core/mission.d.ts",
694
702
  "core/mission.js",
695
703
  "core/mistake-memory.d.ts",
@@ -829,6 +837,10 @@
829
837
  "core/recallpulse.js",
830
838
  "core/release-parallel-full-coverage.d.ts",
831
839
  "core/release-parallel-full-coverage.js",
840
+ "core/release/gate-cache.d.ts",
841
+ "core/release/gate-cache.js",
842
+ "core/release/gate-manifest.d.ts",
843
+ "core/release/gate-manifest.js",
832
844
  "core/reporting/markdown-table.d.ts",
833
845
  "core/reporting/markdown-table.js",
834
846
  "core/research.d.ts",
@@ -841,12 +853,40 @@
841
853
  "core/routes.js",
842
854
  "core/rust-accelerator.d.ts",
843
855
  "core/rust-accelerator.js",
856
+ "core/safety/mutation-guard.d.ts",
857
+ "core/safety/mutation-guard.js",
858
+ "core/safety/mutation-ledger.d.ts",
859
+ "core/safety/mutation-ledger.js",
860
+ "core/safety/requested-scope-contract.d.ts",
861
+ "core/safety/requested-scope-contract.js",
844
862
  "core/secret-redaction.d.ts",
845
863
  "core/secret-redaction.js",
846
864
  "core/session/project-namespace.d.ts",
847
865
  "core/session/project-namespace.js",
848
866
  "core/skill-forge.d.ts",
849
867
  "core/skill-forge.js",
868
+ "core/skills/core-rollout-trace.d.ts",
869
+ "core/skills/core-rollout-trace.js",
870
+ "core/skills/core-skill-card.d.ts",
871
+ "core/skills/core-skill-card.js",
872
+ "core/skills/core-skill-deployment.d.ts",
873
+ "core/skills/core-skill-deployment.js",
874
+ "core/skills/core-skill-epoch.d.ts",
875
+ "core/skills/core-skill-epoch.js",
876
+ "core/skills/core-skill-patch-apply.d.ts",
877
+ "core/skills/core-skill-patch-apply.js",
878
+ "core/skills/core-skill-patch.d.ts",
879
+ "core/skills/core-skill-patch.js",
880
+ "core/skills/core-skill-runtime.d.ts",
881
+ "core/skills/core-skill-runtime.js",
882
+ "core/skills/core-skill-scorer.d.ts",
883
+ "core/skills/core-skill-scorer.js",
884
+ "core/skills/core-skill-types.d.ts",
885
+ "core/skills/core-skill-types.js",
886
+ "core/skills/core-skill-validation.d.ts",
887
+ "core/skills/core-skill-validation.js",
888
+ "core/skills/rejected-skill-patch-buffer.d.ts",
889
+ "core/skills/rejected-skill-patch-buffer.js",
850
890
  "core/source-intelligence/appshots-evidence.d.ts",
851
891
  "core/source-intelligence/appshots-evidence.js",
852
892
  "core/source-intelligence/codex-history-search.d.ts",
@@ -875,6 +915,8 @@
875
915
  "core/team-review-policy.js",
876
916
  "core/triwiki-attention.d.ts",
877
917
  "core/triwiki-attention.js",
918
+ "core/triwiki-runtime.d.ts",
919
+ "core/triwiki-runtime.js",
878
920
  "core/triwiki-wrongness/avoidance-rules.d.ts",
879
921
  "core/triwiki-wrongness/avoidance-rules.js",
880
922
  "core/triwiki-wrongness/image-wrongness.d.ts",
@@ -50,6 +50,7 @@ export declare const COMMANDS: {
50
50
  hermes: CommandEntry;
51
51
  tmux: CommandEntry;
52
52
  'zellij-lane': CommandEntry;
53
+ zellij: CommandEntry;
53
54
  mad: CommandEntry;
54
55
  'mad-sks': CommandEntry;
55
56
  'auto-review': CommandEntry;
@@ -137,6 +138,7 @@ export declare const TYPED_COMMANDS: {
137
138
  hermes: CommandEntry;
138
139
  tmux: CommandEntry;
139
140
  'zellij-lane': CommandEntry;
141
+ zellij: CommandEntry;
140
142
  mad: CommandEntry;
141
143
  'mad-sks': CommandEntry;
142
144
  'auto-review': CommandEntry;
@@ -103,6 +103,7 @@ export const COMMANDS = {
103
103
  hermes: entry('labs', 'Create Hermes Agent skill package', 'dist/commands/hermes.js', directCommand(() => import('../commands/hermes.js'), 'dist/commands/hermes.js')),
104
104
  tmux: entry('beta', 'Show removed-runtime migration notice', 'dist/commands/tmux.js', directCommand(() => import('../commands/tmux.js'), 'dist/commands/tmux.js')),
105
105
  'zellij-lane': entry('beta', 'Render a Zellij lane frame for SKS sessions', 'dist/commands/zellij-lane.js', directCommand(() => import('../commands/zellij-lane.js'), 'dist/commands/zellij-lane.js')),
106
+ zellij: entry('beta', 'Inspect Zellij runtime status and explain repair (no auto-install)', 'dist/commands/zellij.js', directCommand(() => import('../commands/zellij.js'), 'dist/commands/zellij.js')),
106
107
  mad: entry('beta', 'MAD-SKS Zellij permission launcher', 'dist/commands/mad-sks.js', directCommand(() => import('../commands/mad-sks.js'), 'dist/commands/mad-sks.js')),
107
108
  'mad-sks': entry('beta', 'MAD-SKS scoped permission modifier', 'dist/commands/mad-sks.js', directCommand(() => import('../commands/mad-sks.js'), 'dist/commands/mad-sks.js')),
108
109
  'auto-review': entry('beta', 'Manage auto-review profile', 'dist/commands/auto-review.js', directCommand(() => import('../commands/auto-review.js'), 'dist/commands/auto-review.js')),
@@ -4,6 +4,8 @@ import fsp from 'node:fs/promises';
4
4
  import readline from 'node:readline/promises';
5
5
  import { stdin as input, stdout as output } from 'node:process';
6
6
  import { ensureDir, exists, globalSksRoot, packageRoot, PACKAGE_VERSION, readText, runProcess, tmpdir, which, writeTextAtomic } from '../core/fsx.js';
7
+ import { createRequestedScopeContract } from '../core/safety/requested-scope-contract.js';
8
+ import { guardedPackageInstall, guardContextForRoute } from '../core/safety/mutation-guard.js';
7
9
  import { EMPTY_CODEX_INFO, getCodexInfo } from '../core/codex-adapter.js';
8
10
  import { formatHarnessConflictReport, llmHarnessCleanupPrompt, scanHarnessConflicts } from '../core/harness-conflicts.js';
9
11
  import { initProject, installSkills } from '../core/init.js';
@@ -2124,10 +2126,14 @@ export async function ensureCodexCliTool({ skip = false, args = [] } = {}) {
2124
2126
  if (!await confirmInstallYesDefault(`Codex CLI is missing. Install latest Codex CLI with ${command}?`, args)) {
2125
2127
  return { status: 'needs_approval', command, error: 'Codex CLI not found on PATH.' };
2126
2128
  }
2127
- const install = await runProcess(npmBin, ['i', '-g', '@openai/codex@latest'], {
2128
- timeoutMs: 120000,
2129
- maxOutputBytes: 128 * 1024
2130
- }).catch((err) => ({ code: 1, stdout: '', stderr: err.message }));
2129
+ // Global package install is a confirmation-required mutation: route it through
2130
+ // the mutation guard so it is scope-checked and recorded in the ledger. The
2131
+ // user already approved via confirmInstallYesDefault above (confirmed:true).
2132
+ const installRoot = globalSksRoot();
2133
+ const installContract = createRequestedScopeContract({
2134
+ route: 'install', userRequest: command, projectRoot: installRoot, overrides: { package_install: true }
2135
+ });
2136
+ const install = await guardedPackageInstall(guardContextForRoute(installRoot, installContract, command), '@openai/codex@latest', { confirmed: true, command: npmBin, args: ['i', '-g', '@openai/codex@latest'], timeoutMs: 120000 }).catch((err) => ({ code: 1, stdout: '', stderr: err.message }));
2131
2137
  if (install.code !== 0) {
2132
2138
  return { status: 'failed', error: `${install.stderr || install.stdout || 'npm i -g @openai/codex@latest failed'}`.trim() };
2133
2139
  }
@@ -2159,7 +2165,11 @@ export async function ensureZellijCliTool(args = [], opts = {}) {
2159
2165
  if (!await confirmInstallYesDefault(question, args))
2160
2166
  return { target: 'zellij', status: 'needs_approval', command: repairCommand, error: before.blockers[0] || before.warnings[0] || null };
2161
2167
  const brewArgs = hasInstalledZellij ? ['upgrade', 'zellij'] : ['install', 'zellij'];
2162
- const install = await runProcess(brew, brewArgs, { timeoutMs: 180000, maxOutputBytes: 128 * 1024 }).catch((err) => ({ code: 1, stdout: '', stderr: err.message }));
2168
+ const zellijRoot = globalSksRoot();
2169
+ const zellijContract = createRequestedScopeContract({
2170
+ route: 'install', userRequest: repairCommand, projectRoot: zellijRoot, overrides: { package_install: true, zellij_install: true }
2171
+ });
2172
+ const install = await guardedPackageInstall(guardContextForRoute(zellijRoot, zellijContract, repairCommand), 'zellij', { confirmed: true, command: brew, args: brewArgs, timeoutMs: 180000 }).catch((err) => ({ code: 1, stdout: '', stderr: err.message }));
2163
2173
  if (install.code !== 0)
2164
2174
  return { target: 'zellij', status: 'failed', command: repairCommand, error: `${install.stderr || install.stdout || repairCommand + ' failed'}`.trim() };
2165
2175
  const after = await checkZellijCapability({ require: false, writeReport: false });
@@ -13,9 +13,14 @@ import { writeDoctorReadinessMatrix } from '../core/doctor/doctor-readiness-matr
13
13
  import { runCodexDoctorBridge, compareCodexDoctorBridge } from '../core/doctor/codex-doctor-bridge.js';
14
14
  import { checkZellijCapability } from '../core/zellij/zellij-capability.js';
15
15
  import { inventoryCodexPermissionProfiles } from '../core/codex/codex-permission-profiles.js';
16
+ import { appendMigrationEvents, hashConfigText } from '../core/migration/migration-transaction-journal.js';
16
17
  export async function run(_command, args = []) {
17
18
  let setupRepair = null;
19
+ let migrationPreFix = null;
18
20
  if (flag(args, '--fix')) {
21
+ // Snapshot config content before ANY mutation so the migration journal can
22
+ // record real before/after hashes for the whole --fix transaction.
23
+ migrationPreFix = await captureCodexConfigSnapshot();
19
24
  const { setupCommand } = await import('../core/commands/basic-cli.js');
20
25
  const installScope = installScopeFromArgs(args);
21
26
  // Back up the existing managed project config before --force regeneration so a
@@ -44,6 +49,9 @@ export async function run(_command, args = []) {
44
49
  };
45
50
  const codexDoctorBefore = flag(args, '--fix') ? await runCodexDoctorBridge({ codexBin: codexBin || null, cwd: root, required: flag(args, '--require-actual-codex') }).catch(() => null) : null;
46
51
  const configRepair = flag(args, '--fix') ? await repairCodexConfigEperm(root, { fix: true, ...configProbeOpts }) : null;
52
+ const migrationJournal = flag(args, '--fix')
53
+ ? await writeFixMigrationJournal(root, migrationPreFix, configRepair, setupRepair).catch(() => null)
54
+ : null;
47
55
  const codexConfig = configRepair?.after || await inspectCodexConfigReadability(root, configProbeOpts);
48
56
  const codexDoctor = await runCodexDoctorBridge({ codexBin: codexBin || null, cwd: root, required: flag(args, '--require-actual-codex') });
49
57
  const codexDoctorDiff = compareCodexDoctorBridge(codexDoctorBefore, codexDoctor);
@@ -61,6 +69,8 @@ export async function run(_command, args = []) {
61
69
  const codexLb = codexLbMetrics(await readCodexLbCircuit(root).catch(() => ({})));
62
70
  const zellij = await checkZellijCapability({ root, require: process.env.SKS_REQUIRE_ZELLIJ === '1' });
63
71
  const permissionProfiles = await inventoryCodexPermissionProfiles(root, { writeReport: true });
72
+ const { detectImagegenCapability } = await import('../core/imagegen/imagegen-capability.js');
73
+ const imagegen = await detectImagegenCapability({ codexBin: codexBin || undefined }).catch((err) => ({ ok: false, error: err.message, auth_readiness: null }));
64
74
  const pkgBytes = await dirSize(root).catch(() => 0);
65
75
  const ready = await writeDoctorReadinessMatrix(root, {
66
76
  codex,
@@ -77,6 +87,7 @@ export async function run(_command, args = []) {
77
87
  ...(configRepair?.operator_actions || [])
78
88
  ]
79
89
  });
90
+ const zellijReadiness = buildZellijReadiness(root, zellij, ready);
80
91
  const result = {
81
92
  schema: 'sks.doctor-status.v1',
82
93
  ok: ready.ready,
@@ -90,11 +101,17 @@ export async function run(_command, args = []) {
90
101
  codex_doctor: codexDoctor,
91
102
  codex_doctor_diff: codexDoctorDiff,
92
103
  zellij,
104
+ zellij_readiness: zellijReadiness,
93
105
  codex_permission_profiles: permissionProfiles,
106
+ imagegen: {
107
+ ok: imagegen.auth_readiness?.available_paths?.length > 0,
108
+ auth_readiness: imagegen.auth_readiness || null,
109
+ codex_app_builtin_available: imagegen.codex_app?.available === true
110
+ },
94
111
  ready,
95
112
  sneakoscope: { ok: await exists(`${root}/.sneakoscope`) },
96
113
  package: { bytes: pkgBytes, human: formatBytes(pkgBytes) },
97
- repair: { setup: setupRepair, codex_config: configRepair }
114
+ repair: { setup: setupRepair, codex_config: configRepair, migration_journal: migrationJournal }
98
115
  };
99
116
  if (flag(args, '--json')) {
100
117
  printJson(result);
@@ -110,11 +127,26 @@ export async function run(_command, args = []) {
110
127
  console.log('Project config:');
111
128
  console.log(` node read: ${ready.codex_config_readable_by_node ? 'ok' : 'failed'}`);
112
129
  console.log(` codex cli read: ${ready.codex_config_readable_by_codex_cli ? 'ok' : (actual?.status || 'failed')}`);
113
- console.log(` Zellij: ${zellij.status}`);
114
130
  console.log(` removed runtime: tmux`);
131
+ console.log('Zellij:');
132
+ console.log(` binary: ${zellijReadiness.binary} ${zellijReadiness.version || ''} ${zellijReadiness.status === 'ok' ? 'ok' : zellijReadiness.status}`);
133
+ console.log(` required_for: ${zellijReadiness.required_for.join(', ')}`);
134
+ console.log(` layout: ${zellijReadiness.layout_proof}`);
135
+ console.log(` pane proof: ${zellijReadiness.pane_proof}`);
136
+ console.log(` screen proof:${zellijReadiness.screen_proof}`);
137
+ console.log(` tmux: ${zellijReadiness.tmux_removed_runtime ? 'removed_runtime' : 'present'}`);
115
138
  console.log(` codex doctor: ${codexDoctor.available ? (codexDoctor.exit_code === 0 ? 'ok' : 'warning') : 'unavailable'}`);
116
139
  console.log(`Rust acc.: ${rust.mode || (rust.available ? 'rust_accelerated' : 'js_fallback')} ${rust.version || rust.status || ''}`);
117
140
  console.log(`Codex App: ${ready.codex_app_ready ? 'ok' : 'optional_missing'}`);
141
+ const imagegenReady = imagegen.auth_readiness;
142
+ if (imagegenReady) {
143
+ const paths = imagegenReady.available_paths?.length ? imagegenReady.available_paths.join(', ') : 'none';
144
+ console.log(`Image Gen: auth=${imagegenReady.auth_mode} | headless_auto=${imagegenReady.headless_auto_available ? 'available' : 'unavailable'} | paths: ${paths}`);
145
+ if (!imagegenReady.headless_auto_available) {
146
+ for (const action of imagegenReady.next_actions || [])
147
+ console.log(` - ${action}`);
148
+ }
149
+ }
118
150
  console.log(`codex-lb: ${codexLb.ok ? 'ok' : `warning ${codexLb.circuit?.state || 'unknown'}`}`);
119
151
  console.log(`Permissions: config profile and permission profile are tracked separately (${permissionProfiles.codex_config_profile_field}, ${permissionProfiles.codex_permission_profile_field})`);
120
152
  console.log('Ready:');
@@ -130,6 +162,9 @@ export async function run(_command, args = []) {
130
162
  for (const action of configRepair.repair_actions)
131
163
  console.log(` - ${action.name}: ${action.ok ? 'ok' : 'failed'}`);
132
164
  }
165
+ if (migrationJournal?.journal_path) {
166
+ console.log(`Migration journal: ${migrationJournal.journal_path} (${migrationJournal.event_count} events, ${migrationJournal.mutations_without_rollback} without rollback)`);
167
+ }
133
168
  if (!ready.ready && ready.next_actions?.length) {
134
169
  console.log('What still needs you:');
135
170
  for (const action of ready.next_actions)
@@ -138,6 +173,103 @@ export async function run(_command, args = []) {
138
173
  if (!result.ok)
139
174
  process.exitCode = 1;
140
175
  }
176
+ // Assemble the explicit Zellij readiness block for `doctor --json` from the
177
+ // capability probe + readiness matrix. Proof statuses are availability-derived:
178
+ // `verified` is reserved for a real environment run (SKS_REQUIRE_ZELLIJ=1 gates);
179
+ // here they report `optional` when the binary is usable and `unavailable` when
180
+ // Zellij is missing/too old. Zellij missing keeps mad_ready=false while cli_ready
181
+ // can remain true (the matrix already enforces this).
182
+ function buildZellijReadiness(root, zellij, ready) {
183
+ const status = String(zellij?.status || 'missing');
184
+ const usable = status === 'ok';
185
+ const proofStatus = usable ? 'optional' : 'unavailable';
186
+ const readiness = {
187
+ schema: 'sks.zellij-readiness.v1',
188
+ binary: zellij?.bin || 'zellij',
189
+ status,
190
+ min_version: zellij?.min_version || '0.41.0',
191
+ version: zellij?.version || null,
192
+ required_for: zellij?.required_for || ['sks --mad', 'interactive lane UI'],
193
+ layout_proof: proofStatus,
194
+ pane_proof: proofStatus,
195
+ screen_proof: proofStatus,
196
+ tmux_removed_runtime: true,
197
+ mad_ready: ready?.mad_ready === true,
198
+ cli_ready: ready?.cli_ready === true,
199
+ ready_for_interactive_runtime: ready?.codex_config_readable_in_zellij_context === true
200
+ };
201
+ return readiness;
202
+ }
203
+ async function codexHomeConfigPath() {
204
+ const path = await import('node:path');
205
+ const os = await import('node:os');
206
+ const home = process.env.CODEX_HOME || path.join(process.env.HOME || os.homedir(), '.codex');
207
+ return path.join(home, 'config.toml');
208
+ }
209
+ async function captureCodexConfigSnapshot() {
210
+ const fsp = await import('node:fs/promises');
211
+ const path = await import('node:path');
212
+ const read = async (p) => {
213
+ if (!p)
214
+ return null;
215
+ try {
216
+ return await fsp.readFile(p, 'utf8');
217
+ }
218
+ catch {
219
+ return null;
220
+ }
221
+ };
222
+ const root = await projectRoot();
223
+ const projectPath = root ? path.join(root, '.codex', 'config.toml') : null;
224
+ const homePath = await codexHomeConfigPath();
225
+ return {
226
+ project_path: projectPath,
227
+ project_text: await read(projectPath),
228
+ home_path: homePath,
229
+ home_text: await read(homePath)
230
+ };
231
+ }
232
+ // Build a migration journal for the --fix transaction with real before/after
233
+ // content hashes and the backup paths produced by setup/structure/split repair.
234
+ async function writeFixMigrationJournal(root, preFix, configRepair, setupRepair) {
235
+ if (!preFix)
236
+ return null;
237
+ const fsp = await import('node:fs/promises');
238
+ const read = async (p) => {
239
+ if (!p)
240
+ return null;
241
+ try {
242
+ return await fsp.readFile(p, 'utf8');
243
+ }
244
+ catch {
245
+ return null;
246
+ }
247
+ };
248
+ const projectAfter = await read(preFix.project_path);
249
+ const homeAfter = await read(preFix.home_path);
250
+ const structureRepairs = Array.isArray(configRepair?.structure_repairs) ? configRepair.structure_repairs : [];
251
+ const projectStructure = structureRepairs.find((repair) => repair.scope === 'project');
252
+ const homeStructure = structureRepairs.find((repair) => repair.scope === 'codex_home');
253
+ const events = [
254
+ {
255
+ step: 'doctor_fix_project_config',
256
+ target: preFix.project_path || '.codex/config.toml',
257
+ beforeHash: preFix.project_text != null ? hashConfigText(preFix.project_text) : null,
258
+ afterHash: projectAfter != null ? hashConfigText(projectAfter) : null,
259
+ backupPath: setupRepair?.config_backup_path || projectStructure?.backup_path || configRepair?.policy?.backup_path || null
260
+ },
261
+ {
262
+ step: 'doctor_fix_codex_home_config',
263
+ target: preFix.home_path || '~/.codex/config.toml',
264
+ beforeHash: preFix.home_text != null ? hashConfigText(preFix.home_text) : null,
265
+ afterHash: homeAfter != null ? hashConfigText(homeAfter) : null,
266
+ backupPath: homeStructure?.backup_path || null
267
+ }
268
+ ].filter((event) => event.beforeHash != null || event.afterHash != null);
269
+ if (!events.length)
270
+ return null;
271
+ return appendMigrationEvents(root, events);
272
+ }
141
273
  async function backupProjectConfigBeforeFix() {
142
274
  try {
143
275
  const fsp = await import('node:fs/promises');
@@ -914,6 +914,7 @@ export declare function run(command: any, args?: any): Promise<void | {
914
914
  backend: string;
915
915
  route: string;
916
916
  route_command: string;
917
+ selected_core_skill: any;
917
918
  route_blackbox_kind: string;
918
919
  real_route_command_used: boolean;
919
920
  native_cli_session_proof: string | null;
@@ -1039,6 +1040,12 @@ export declare function run(command: any, args?: any): Promise<void | {
1039
1040
  janitor_ok: boolean;
1040
1041
  trust_report: string;
1041
1042
  wrongness_records: string;
1043
+ triwiki_context: string;
1044
+ triwiki_context_consulted: boolean;
1045
+ context_pack_hash: any;
1046
+ triwiki_use_first_count: number;
1047
+ triwiki_hydrate_first_count: number;
1048
+ triwiki_claim_count: number;
1042
1049
  changed_files_lease_checked: boolean;
1043
1050
  dependency_collision_risk: any;
1044
1051
  blockers: any[];
@@ -763,6 +763,7 @@ export declare function run(command: any, args?: any): Promise<void | {
763
763
  backend: string;
764
764
  route: string;
765
765
  route_command: string;
766
+ selected_core_skill: any;
766
767
  route_blackbox_kind: string;
767
768
  real_route_command_used: boolean;
768
769
  native_cli_session_proof: string | null;
@@ -888,6 +889,12 @@ export declare function run(command: any, args?: any): Promise<void | {
888
889
  janitor_ok: boolean;
889
890
  trust_report: string;
890
891
  wrongness_records: string;
892
+ triwiki_context: string;
893
+ triwiki_context_consulted: boolean;
894
+ context_pack_hash: any;
895
+ triwiki_use_first_count: number;
896
+ triwiki_hydrate_first_count: number;
897
+ triwiki_claim_count: number;
891
898
  changed_files_lease_checked: boolean;
892
899
  dependency_collision_risk: any;
893
900
  blockers: any[];
@@ -0,0 +1,4 @@
1
+ export declare const ZELLIJ_COMMAND_SCHEMA = "sks.zellij-command.v1";
2
+ export declare const ZELLIJ_REPAIR_SCHEMA = "sks.zellij-repair.v1";
3
+ export declare function run(_command?: string, args?: string[]): Promise<void>;
4
+ //# sourceMappingURL=zellij.d.ts.map
@@ -0,0 +1,111 @@
1
+ import { projectRoot } from '../core/fsx.js';
2
+ import { flag } from '../cli/args.js';
3
+ import { printJson } from '../cli/output.js';
4
+ import { checkZellijCapability } from '../core/zellij/zellij-capability.js';
5
+ export const ZELLIJ_COMMAND_SCHEMA = 'sks.zellij-command.v1';
6
+ export const ZELLIJ_REPAIR_SCHEMA = 'sks.zellij-repair.v1';
7
+ function installHint() {
8
+ if (process.platform === 'darwin')
9
+ return 'brew install zellij';
10
+ if (process.platform === 'linux')
11
+ return 'cargo install --locked zellij # or your distro package, e.g. `apt install zellij` / `pacman -S zellij`';
12
+ return 'See https://zellij.dev/documentation/installation';
13
+ }
14
+ export async function run(_command = 'zellij', args = []) {
15
+ const sub = (args.find((arg) => !arg.startsWith('-')) || 'status').toLowerCase();
16
+ const json = flag(args, '--json');
17
+ const root = await projectRoot();
18
+ if (sub === 'help')
19
+ return printHelp(json);
20
+ if (sub === 'repair')
21
+ return zellijRepair(root, args, json);
22
+ return zellijStatus(root, args, json);
23
+ }
24
+ async function zellijStatus(root, args, json) {
25
+ const requireReal = flag(args, '--require-real') || process.env.SKS_REQUIRE_ZELLIJ === '1';
26
+ const capability = await checkZellijCapability({ root, require: requireReal });
27
+ const status = capability.status || 'unknown';
28
+ const ready = status === 'ok';
29
+ const result = {
30
+ schema: ZELLIJ_COMMAND_SCHEMA,
31
+ subcommand: 'status',
32
+ ok: ready || !requireReal,
33
+ status,
34
+ version: capability.version || null,
35
+ required_for: ['sks --mad', 'sks team open-zellij', 'interactive lane UI'],
36
+ blockers: capability.blockers || [],
37
+ warnings: capability.warnings || [],
38
+ install_hint: ready ? null : installHint(),
39
+ next_actions: ready
40
+ ? []
41
+ : [`Install Zellij: ${installHint()}`, 'Then re-run `sks zellij status` and `sks doctor --fix`.']
42
+ };
43
+ if (json) {
44
+ printJson(result);
45
+ }
46
+ else {
47
+ console.log('SKS Zellij runtime');
48
+ console.log(` status: ${status}${result.version ? ` (${result.version})` : ''}`);
49
+ console.log(` required: ${result.required_for.join(', ')}`);
50
+ if (result.blockers.length)
51
+ console.log(` blockers: ${result.blockers.join(', ')}`);
52
+ if (!ready) {
53
+ console.log(' next:');
54
+ for (const action of result.next_actions)
55
+ console.log(` - ${action}`);
56
+ }
57
+ }
58
+ if (!result.ok)
59
+ process.exitCode = 1;
60
+ }
61
+ async function zellijRepair(root, args, json) {
62
+ // Explain-only by default: SKS never auto-installs Zellij (no Homebrew/cargo
63
+ // side-effects from this command). It surfaces the exact operator steps.
64
+ const capability = await checkZellijCapability({ root, require: false });
65
+ const status = capability.status || 'unknown';
66
+ const autoInstall = false;
67
+ const result = {
68
+ schema: ZELLIJ_REPAIR_SCHEMA,
69
+ subcommand: 'repair',
70
+ ok: true,
71
+ mode: 'explain',
72
+ status,
73
+ auto_install: autoInstall,
74
+ operator_actions: [
75
+ `Install or upgrade Zellij: ${installHint()}`,
76
+ 'Verify: `sks zellij status` (or `npm run zellij:capability`).',
77
+ 'Opt-in dependency repair through SKS: `sks deps check --yes` or `sks bootstrap --yes`.',
78
+ 'Recover Codex config issues: `sks doctor --fix`.'
79
+ ]
80
+ };
81
+ if (json) {
82
+ printJson(result);
83
+ }
84
+ else {
85
+ console.log('SKS Zellij repair (explain-only; no automatic install)');
86
+ console.log(` current status: ${status}`);
87
+ for (const action of result.operator_actions)
88
+ console.log(` - ${action}`);
89
+ }
90
+ }
91
+ function printHelp(json) {
92
+ const result = {
93
+ schema: ZELLIJ_COMMAND_SCHEMA,
94
+ subcommand: 'help',
95
+ ok: true,
96
+ usage: 'sks zellij status|repair|capability [--require-real] [--json]',
97
+ subcommands: {
98
+ status: 'Report Zellij runtime capability and interactive-route readiness.',
99
+ repair: 'Explain how to install/repair Zellij (no automatic install).',
100
+ capability: 'Alias for status.'
101
+ }
102
+ };
103
+ if (json)
104
+ printJson(result);
105
+ else {
106
+ console.log('sks zellij — inspect and repair the Zellij interactive runtime');
107
+ console.log(' sks zellij status [--require-real] [--json]');
108
+ console.log(' sks zellij repair [--explain] [--json]');
109
+ }
110
+ }
111
+ //# sourceMappingURL=zellij.js.map
@@ -530,6 +530,7 @@ export declare function runNativeAgentOrchestrator(opts?: AgentRunOptions): Prom
530
530
  backend: string;
531
531
  route: string;
532
532
  route_command: string;
533
+ selected_core_skill: any;
533
534
  route_blackbox_kind: string;
534
535
  real_route_command_used: boolean;
535
536
  native_cli_session_proof: string | null;
@@ -655,6 +656,12 @@ export declare function runNativeAgentOrchestrator(opts?: AgentRunOptions): Prom
655
656
  janitor_ok: boolean;
656
657
  trust_report: string;
657
658
  wrongness_records: string;
659
+ triwiki_context: string;
660
+ triwiki_context_consulted: boolean;
661
+ context_pack_hash: any;
662
+ triwiki_use_first_count: number;
663
+ triwiki_hydrate_first_count: number;
664
+ triwiki_claim_count: number;
658
665
  changed_files_lease_checked: boolean;
659
666
  dependency_collision_risk: any;
660
667
  blockers: any[];