sneakoscope 4.8.7 → 5.1.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 (288) hide show
  1. package/README.md +51 -726
  2. package/bench/tasks/t01-off-by-one/repo/package.json +9 -0
  3. package/bench/tasks/t01-off-by-one/repo/src/pagination.js +5 -0
  4. package/bench/tasks/t01-off-by-one/repo/test.js +5 -0
  5. package/bench/tasks/t01-off-by-one/task.json +13 -0
  6. package/bench/tasks/t02-signature-cochange/repo/package.json +9 -0
  7. package/bench/tasks/t02-signature-cochange/repo/src/admin.js +5 -0
  8. package/bench/tasks/t02-signature-cochange/repo/src/audit.js +5 -0
  9. package/bench/tasks/t02-signature-cochange/repo/src/labels.js +3 -0
  10. package/bench/tasks/t02-signature-cochange/repo/src/profile.js +5 -0
  11. package/bench/tasks/t02-signature-cochange/repo/test.js +9 -0
  12. package/bench/tasks/t02-signature-cochange/task.json +12 -0
  13. package/bench/tasks/t03-type-puzzle/repo/package.json +9 -0
  14. package/bench/tasks/t03-type-puzzle/repo/src/config.js +4 -0
  15. package/bench/tasks/t03-type-puzzle/repo/test.js +6 -0
  16. package/bench/tasks/t03-type-puzzle/task.json +13 -0
  17. package/bench/tasks/t04-refactor-preserve/repo/package.json +9 -0
  18. package/bench/tasks/t04-refactor-preserve/repo/src/cart.js +8 -0
  19. package/bench/tasks/t04-refactor-preserve/repo/test.js +4 -0
  20. package/bench/tasks/t04-refactor-preserve/task.json +12 -0
  21. package/bench/tasks/t05-performance/repo/package.json +9 -0
  22. package/bench/tasks/t05-performance/repo/src/pairs.js +9 -0
  23. package/bench/tasks/t05-performance/repo/test.js +11 -0
  24. package/bench/tasks/t05-performance/task.json +12 -0
  25. package/bench/tasks/t06-mistake-rule/repo/package.json +9 -0
  26. package/bench/tasks/t06-mistake-rule/repo/src/loader.js +6 -0
  27. package/bench/tasks/t06-mistake-rule/repo/test.js +7 -0
  28. package/bench/tasks/t06-mistake-rule/task.json +12 -0
  29. package/config/bench-baseline.json +7 -0
  30. package/crates/sks-core/Cargo.lock +1 -1
  31. package/crates/sks-core/Cargo.toml +1 -1
  32. package/crates/sks-core/src/main.rs +1 -1
  33. package/dist/bin/install.js +35 -0
  34. package/dist/bin/sks.js +1 -1
  35. package/dist/cli/cli-theme.js +51 -0
  36. package/dist/cli/command-registry.js +15 -4
  37. package/dist/cli/help-fast.js +18 -8
  38. package/dist/cli/insane-search-command.js +36 -8
  39. package/dist/cli/install-helpers.js +32 -0
  40. package/dist/commands/codex-lb.js +2 -0
  41. package/dist/commands/doctor.js +62 -6
  42. package/dist/commands/proof.js +6 -3
  43. package/dist/config/skills-manifest.json +82 -54
  44. package/dist/core/agents/agent-conflict-graph.js +5 -0
  45. package/dist/core/agents/agent-lease.js +5 -0
  46. package/dist/core/agents/agent-ledger-schemas.js +1 -0
  47. package/dist/core/agents/agent-orchestrator.js +268 -62
  48. package/dist/core/agents/agent-output-validator.js +14 -3
  49. package/dist/core/agents/agent-patch-queue-store.js +95 -2
  50. package/dist/core/agents/agent-patch-queue.js +6 -3
  51. package/dist/core/agents/agent-patch-schema.js +13 -0
  52. package/dist/core/agents/agent-proof-evidence.js +6 -1
  53. package/dist/core/agents/agent-runner-fake.js +40 -0
  54. package/dist/core/agents/agent-worker-pipeline.js +36 -2
  55. package/dist/core/agents/codex-exec-worker-adapter.js +2 -0
  56. package/dist/core/agents/native-worker-backend-router.js +58 -1
  57. package/dist/core/codex-app/sks-menubar.js +18 -5
  58. package/dist/core/codex-app.js +1 -0
  59. package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
  60. package/dist/core/codex-control/codex-sdk-env-policy.js +1 -1
  61. package/dist/core/codex-control/schemas/agent-worker-result.schema.js +12 -3
  62. package/dist/core/codex-hooks/codex-hook-managed-install.js +5 -0
  63. package/dist/core/codex-hooks/codex-hook-state-writer.js +70 -11
  64. package/dist/core/codex-hooks/codex-hook-trust-doctor.js +2 -2
  65. package/dist/core/codex-lb/codex-lb-env.js +20 -1
  66. package/dist/core/commands/basic-cli.js +21 -2
  67. package/dist/core/commands/check-command.js +37 -5
  68. package/dist/core/commands/computer-use-command.js +62 -7
  69. package/dist/core/commands/db-command.js +31 -5
  70. package/dist/core/commands/fast-mode-command.js +3 -0
  71. package/dist/core/commands/gate-result-contract.js +43 -0
  72. package/dist/core/commands/gates-command.js +6 -1
  73. package/dist/core/commands/gc-command.js +29 -2
  74. package/dist/core/commands/goal-command.js +9 -2
  75. package/dist/core/commands/gx-command.js +79 -7
  76. package/dist/core/commands/image-ux-review-command.js +188 -13
  77. package/dist/core/commands/mad-db-command.js +85 -176
  78. package/dist/core/commands/mad-sks-command.js +230 -29
  79. package/dist/core/commands/menubar-command.js +22 -1
  80. package/dist/core/commands/naruto-command.js +64 -10
  81. package/dist/core/commands/plan-command.js +76 -0
  82. package/dist/core/commands/ppt-command.js +159 -24
  83. package/dist/core/commands/qa-loop-command.js +6 -2
  84. package/dist/core/commands/release-command.js +55 -2
  85. package/dist/core/commands/research-command.js +1 -1
  86. package/dist/core/commands/review-command.js +217 -0
  87. package/dist/core/commands/route-success-helpers.js +59 -0
  88. package/dist/core/commands/run-command.js +19 -7
  89. package/dist/core/commands/seo-command.js +49 -1
  90. package/dist/core/commands/ui-command.js +161 -0
  91. package/dist/core/commands/uninstall-command.js +15 -1
  92. package/dist/core/db-safety.js +2 -2
  93. package/dist/core/doctor/doctor-transaction.js +8 -0
  94. package/dist/core/doctor/doctor-zellij-repair.js +1 -0
  95. package/dist/core/doctor/imagegen-repair.js +161 -0
  96. package/dist/core/feature-fixture-runner.js +2 -2
  97. package/dist/core/feature-fixtures.js +58 -37
  98. package/dist/core/feature-registry.js +102 -2
  99. package/dist/core/fsx.js +39 -6
  100. package/dist/core/image-ux-review/imagegen-adapter.js +48 -11
  101. package/dist/core/image-ux-review.js +16 -0
  102. package/dist/core/imagegen/imagegen-capability.js +11 -5
  103. package/dist/core/imagegen/require-imagegen.js +57 -0
  104. package/dist/core/init/skills.js +10 -5
  105. package/dist/core/mad-db/mad-db-coordinator.js +94 -18
  106. package/dist/core/mad-db/mad-db-policy.js +12 -10
  107. package/dist/core/mad-sks/executors/executor-base.js +8 -2
  108. package/dist/core/mad-sks/executors/index.js +4 -0
  109. package/dist/core/mad-sks/executors/sql-plane-executor.js +194 -0
  110. package/dist/core/naruto/naruto-active-pool.js +15 -4
  111. package/dist/core/naruto/naruto-real-worker-child.js +10 -0
  112. package/dist/core/naruto/naruto-role-policy.js +3 -0
  113. package/dist/core/naruto/naruto-task-hints.js +10 -0
  114. package/dist/core/naruto/naruto-work-graph.js +8 -2
  115. package/dist/core/naruto/naruto-work-item.js +6 -0
  116. package/dist/core/naruto/solution-tournament.js +101 -0
  117. package/dist/core/permission-gates.js +30 -0
  118. package/dist/core/pipeline-internals/runtime-core.js +11 -3
  119. package/dist/core/pipeline-internals/runtime-gates.js +27 -0
  120. package/dist/core/ppt-review/index.js +6 -1
  121. package/dist/core/ppt-review/slide-imagegen-review.js +75 -10
  122. package/dist/core/ppt.js +70 -2
  123. package/dist/core/proof/auto-finalize.js +70 -11
  124. package/dist/core/proof/proof-schema.js +2 -0
  125. package/dist/core/proof/route-adapter.js +5 -1
  126. package/dist/core/proof/route-finalizer.js +8 -5
  127. package/dist/core/proof/selftest-proof-fixtures.js +18 -5
  128. package/dist/core/proof/validation.js +2 -0
  129. package/dist/core/provider/model-router.js +53 -0
  130. package/dist/core/release/release-gate-node.js +3 -0
  131. package/dist/core/release/release-gate-resource-governor.js +1 -0
  132. package/dist/core/routes/constants.js +1 -1
  133. package/dist/core/routes.js +65 -18
  134. package/dist/core/safety/mutation-guard.js +5 -1
  135. package/dist/core/stop-gate/gate-evaluator.js +102 -0
  136. package/dist/core/stop-gate/stop-gate-check.js +16 -1
  137. package/dist/core/stop-gate/stop-gate-writer.js +4 -0
  138. package/dist/core/triwiki/agents-md-projector.js +184 -0
  139. package/dist/core/triwiki-wrongness/wrongness-schema.js +3 -1
  140. package/dist/core/trust-kernel/trust-kernel-schema.js +1 -0
  141. package/dist/core/trust-kernel/trust-report.js +1 -1
  142. package/dist/core/trust-kernel/trust-status.js +2 -0
  143. package/dist/core/ui/dashboard-html.js +111 -0
  144. package/dist/core/update/update-migration-state.js +366 -15
  145. package/dist/core/update-check.js +178 -81
  146. package/dist/core/verification/diff-quality.js +100 -0
  147. package/dist/core/verification/impact-scan.js +164 -0
  148. package/dist/core/verification/machine-feedback.js +146 -0
  149. package/dist/core/verification/mistake-rule-compiler.js +195 -0
  150. package/dist/core/version.js +1 -1
  151. package/dist/core/zellij/zellij-self-heal.js +9 -6
  152. package/dist/scripts/check-feature-quality.js +2 -2
  153. package/dist/scripts/cli-output-consistency-check.js +57 -0
  154. package/dist/scripts/coding-bench-check.js +136 -0
  155. package/dist/scripts/doctor-imagegen-repair-check.js +62 -0
  156. package/dist/scripts/ensure-bin-executable.js +11 -3
  157. package/dist/scripts/harness-benchmark-check.js +104 -0
  158. package/dist/scripts/legacy-update-e2e-check.js +228 -0
  159. package/dist/scripts/mad-db-command-check.js +11 -8
  160. package/dist/scripts/mad-db-route-identity-check.js +8 -6
  161. package/dist/scripts/mad-db-safety-conflict-matrix-check.js +31 -8
  162. package/dist/scripts/mad-db-skill-policy-snapshot-check.js +4 -5
  163. package/dist/scripts/ppt-real-imagegen-wiring-check.js +5 -1
  164. package/dist/scripts/proof-root-cause-policy-check.js +2 -0
  165. package/dist/scripts/release-dag-full-coverage-check.js +13 -4
  166. package/dist/scripts/release-gate-dag-runner.js +14 -0
  167. package/dist/scripts/release-gate-existence-audit.js +2 -1
  168. package/dist/scripts/release-gate-planner.js +2 -1
  169. package/dist/scripts/release-gate-script-parity-check.js +1 -1
  170. package/dist/scripts/release-metadata-1-19-check.js +2 -1
  171. package/dist/scripts/seo-geo-feature-fixture-quality-check.js +1 -1
  172. package/dist/scripts/sks-1-11-gate-lib.js +8 -6
  173. package/dist/scripts/ux-review-real-loop-fixture-check.js +9 -4
  174. package/dist/scripts/ux-review-run-wires-imagegen-check.js +4 -0
  175. package/docs/assets/sneakoscope-architecture-pipeline.jpg +0 -0
  176. package/docs/demo.tape +28 -0
  177. package/package.json +67 -3
  178. package/schemas/codex/completion-proof.schema.json +3 -2
  179. package/schemas/release/release-gate-node.schema.json +2 -1
  180. package/dist/scripts/agent-backfill-route-blackbox.js +0 -5
  181. package/dist/scripts/agent-dynamic-pool-route-blackbox.js +0 -5
  182. package/dist/scripts/agent-parallel-write-blackbox.js +0 -56
  183. package/dist/scripts/agent-patch-swarm-route-blackbox.js +0 -10
  184. package/dist/scripts/agent-route-blackbox-lib.js +0 -132
  185. package/dist/scripts/blackbox-command-import-smoke.js +0 -143
  186. package/dist/scripts/blackbox-global-shim.js +0 -77
  187. package/dist/scripts/blackbox-matrix.js +0 -70
  188. package/dist/scripts/blackbox-npx-one-shot.js +0 -69
  189. package/dist/scripts/blackbox-pack-install.js +0 -174
  190. package/dist/scripts/brand-neutrality-zero-leakage-blackbox.js +0 -4
  191. package/dist/scripts/build-once-runner-blackbox.js +0 -34
  192. package/dist/scripts/codex-0140-integration-blackbox.js +0 -13
  193. package/dist/scripts/codex-agent-type-blackbox.js +0 -4
  194. package/dist/scripts/codex-app-harness-blackbox.js +0 -4
  195. package/dist/scripts/codex-app-skill-agent-blackbox.js +0 -4
  196. package/dist/scripts/codex-hook-approval-blackbox.js +0 -4
  197. package/dist/scripts/codex-init-deep-directory-local-blackbox.js +0 -4
  198. package/dist/scripts/codex-native-feature-broker-blackbox.js +0 -4
  199. package/dist/scripts/codex-native-pattern-analysis-blackbox.js +0 -4
  200. package/dist/scripts/codex-native-read-repair-split-blackbox.js +0 -55
  201. package/dist/scripts/codex-native-reference-cache-blackbox.js +0 -41
  202. package/dist/scripts/core-skill-integrity-blackbox.js +0 -32
  203. package/dist/scripts/dfix-fast-blackbox-check.js +0 -37
  204. package/dist/scripts/dfix-parallel-write-blackbox.js +0 -48
  205. package/dist/scripts/dfix-patch-swarm-route-blackbox.js +0 -10
  206. package/dist/scripts/doctor-context7-mcp-repair-blackbox.js +0 -16
  207. package/dist/scripts/doctor-dirty-repair-blackbox.js +0 -22
  208. package/dist/scripts/doctor-dirty-semantic-blackbox.js +0 -8
  209. package/dist/scripts/doctor-fix-production-blackbox.js +0 -26
  210. package/dist/scripts/doctor-native-capability-repair-blackbox.js +0 -39
  211. package/dist/scripts/doctor-startup-config-repair-blackbox.js +0 -13
  212. package/dist/scripts/doctor-supabase-mcp-repair-blackbox.js +0 -14
  213. package/dist/scripts/doctor-transaction-engine-blackbox.js +0 -28
  214. package/dist/scripts/doctor-zellij-fix-blackbox.js +0 -4
  215. package/dist/scripts/doctor-zellij-no-homebrew-blackbox.js +0 -4
  216. package/dist/scripts/doctor-zellij-upgrade-blackbox.js +0 -4
  217. package/dist/scripts/gate-pack-runner-blackbox.js +0 -27
  218. package/dist/scripts/gate-pack-v2-blackbox.js +0 -18
  219. package/dist/scripts/geo-cli-blackbox-check.js +0 -18
  220. package/dist/scripts/loop-collision-blackbox.js +0 -3
  221. package/dist/scripts/loop-concurrency-oversubscription-blackbox.js +0 -3
  222. package/dist/scripts/loop-fixture-production-misuse-blackbox.js +0 -3
  223. package/dist/scripts/loop-kill-interrupt-real-blackbox.js +0 -3
  224. package/dist/scripts/loop-merge-strategy-blackbox.js +0 -3
  225. package/dist/scripts/loop-mesh-production-e2e-blackbox.js +0 -3
  226. package/dist/scripts/loop-side-effect-blackbox.js +0 -3
  227. package/dist/scripts/mad-db-operation-lifecycle-blackbox.js +0 -29
  228. package/dist/scripts/mad-sks-actual-executor-blackbox.js +0 -5
  229. package/dist/scripts/mad-zellij-headless-fallback-blackbox.js +0 -4
  230. package/dist/scripts/mad-zellij-self-heal-blackbox.js +0 -4
  231. package/dist/scripts/naruto-loop-mesh-blackbox.js +0 -3
  232. package/dist/scripts/naruto-real-parallelism-blackbox.js +0 -307
  233. package/dist/scripts/naruto-worktree-coding-blackbox.js +0 -29
  234. package/dist/scripts/parallel-runtime-real-blackbox.js +0 -44
  235. package/dist/scripts/pipeline-codex-native-doctor-mad-routing-real-blackbox.js +0 -77
  236. package/dist/scripts/pipeline-codex-native-e2e-blackbox.js +0 -13
  237. package/dist/scripts/pipeline-codex-native-image-routing-real-blackbox.js +0 -50
  238. package/dist/scripts/pipeline-codex-native-loop-routing-real-blackbox.js +0 -74
  239. package/dist/scripts/pipeline-codex-native-qa-routing-real-blackbox.js +0 -51
  240. package/dist/scripts/pipeline-codex-native-research-routing-real-blackbox.js +0 -45
  241. package/dist/scripts/pipeline-execution-profile-routing-blackbox.js +0 -4
  242. package/dist/scripts/postinstall-global-doctor-blackbox.js +0 -12
  243. package/dist/scripts/ppt-full-e2e-blackbox-check.js +0 -109
  244. package/dist/scripts/ppt-imagegen-blackbox-check.js +0 -46
  245. package/dist/scripts/project-skill-dedupe-blackbox.js +0 -36
  246. package/dist/scripts/qa-backfill-route-blackbox.js +0 -5
  247. package/dist/scripts/qa-patch-swarm-route-blackbox.js +0 -10
  248. package/dist/scripts/release-full-parallelism-blackbox.js +0 -41
  249. package/dist/scripts/release-triwiki-first-runner-blackbox.js +0 -48
  250. package/dist/scripts/release-wiring-3110-blackbox.js +0 -27
  251. package/dist/scripts/release-wiring-3112-blackbox.js +0 -17
  252. package/dist/scripts/release-wiring-3113-blackbox.js +0 -17
  253. package/dist/scripts/research-backfill-route-blackbox.js +0 -5
  254. package/dist/scripts/research-final-reviewer-blackbox.js +0 -70
  255. package/dist/scripts/research-stage-cycle-runtime-blackbox.js +0 -40
  256. package/dist/scripts/research-synthesis-writer-blackbox.js +0 -24
  257. package/dist/scripts/route-blackbox-realism-check.js +0 -21
  258. package/dist/scripts/scheduler-resource-claim-blackbox.js +0 -24
  259. package/dist/scripts/seo-cli-blackbox-check.js +0 -18
  260. package/dist/scripts/sks-3110-all-feature-regression-blackbox.js +0 -116
  261. package/dist/scripts/sks-3112-all-feature-regression-blackbox.js +0 -29
  262. package/dist/scripts/sks-3113-all-feature-regression-blackbox.js +0 -17
  263. package/dist/scripts/sks-400-all-feature-regression-blackbox.js +0 -21
  264. package/dist/scripts/sks-400-extreme-parallel-blackbox.js +0 -8
  265. package/dist/scripts/sks-400-five-minute-blackbox.js +0 -9
  266. package/dist/scripts/sks-400-legacy-purge-blackbox.js +0 -8
  267. package/dist/scripts/sks-401-all-feature-regression-blackbox.js +0 -46
  268. package/dist/scripts/sks-401-five-minute-actual-blackbox.js +0 -23
  269. package/dist/scripts/sks-402-all-feature-regression-blackbox.js +0 -9
  270. package/dist/scripts/sks-402-five-minute-real-blackbox.js +0 -22
  271. package/dist/scripts/sksd-warm-cache-blackbox.js +0 -12
  272. package/dist/scripts/supabase-secret-preservation-blackbox.js +0 -29
  273. package/dist/scripts/team-backfill-route-blackbox.js +0 -5
  274. package/dist/scripts/team-parallel-write-blackbox.js +0 -55
  275. package/dist/scripts/team-patch-swarm-route-blackbox.js +0 -10
  276. package/dist/scripts/triwiki-affected-graph-blackbox.js +0 -28
  277. package/dist/scripts/triwiki-proof-bank-blackbox.js +0 -30
  278. package/dist/scripts/triwiki-proof-bank-lock-blackbox.js +0 -7
  279. package/dist/scripts/update-preserves-supabase-keys-blackbox.js +0 -27
  280. package/dist/scripts/ux-patch-swarm-route-blackbox.js +0 -10
  281. package/dist/scripts/ux-review-imagegen-blackbox-check.js +0 -67
  282. package/dist/scripts/zellij-initial-main-only-blackbox.js +0 -28
  283. package/dist/scripts/zellij-pane-lock-concurrency-blackbox.js +0 -80
  284. package/dist/scripts/zellij-pane-lock-open-worker-integration-blackbox.js +0 -137
  285. package/dist/scripts/zellij-self-heal-typed-blackbox.js +0 -4
  286. package/dist/scripts/zellij-slot-telemetry-real-blackbox.js +0 -20
  287. package/dist/scripts/zellij-stacked-fallback-integration-blackbox.js +0 -81
  288. package/dist/scripts/zellij-worker-pane-real-ui-blackbox.js +0 -202
@@ -181,7 +181,7 @@ function inspectExpectedArtifact(root, tempRoot, artifact, ctx = {}) {
181
181
  return { ...result, failure: 'json_parse' };
182
182
  }
183
183
  if (schema === 'sks.completion-proof.v1')
184
- return { ...result, schema_ok: parsed.schema === schema, content_ok: ['verified', 'verified_partial', 'blocked'].includes(parsed.status), status: parsed.status };
184
+ return { ...result, schema_ok: parsed.schema === schema, content_ok: ['verified', 'verified_partial', 'mock_only', 'blocked'].includes(parsed.status), status: parsed.status };
185
185
  if (schema === 'sks.image-voxel-ledger.v1') {
186
186
  const anchorCount = Array.isArray(parsed.anchors) ? parsed.anchors.length : 0;
187
187
  const relationCount = Array.isArray(parsed.relations) ? parsed.relations.length : 0;
@@ -241,7 +241,7 @@ function renderFeatureFixtureMarkdown(report = {}) {
241
241
  }
242
242
  export function validateCompletionProofArtifact(file) {
243
243
  const proof = JSON.parse(fs.readFileSync(file, 'utf8'));
244
- return proof.schema === 'sks.completion-proof.v1' && ['verified', 'verified_partial', 'blocked'].includes(proof.status);
244
+ return proof.schema === 'sks.completion-proof.v1' && ['verified', 'verified_partial', 'mock_only', 'blocked'].includes(proof.status);
245
245
  }
246
246
  export function validateImageVoxelArtifact(file, { requireAnchors = true, requireRelations = false } = {}) {
247
247
  const ledger = JSON.parse(fs.readFileSync(file, 'utf8'));
@@ -2,7 +2,7 @@ import { PACKAGE_VERSION } from './fsx.js';
2
2
  export const FEATURE_FIXTURE_SCHEMA = 'sks.feature-fixtures.v1';
3
3
  export const FEATURE_QUALITY_LEVELS = Object.freeze([
4
4
  'runtime_verified',
5
- 'runtime_mock_verified',
5
+ 'wiring_only',
6
6
  'integration_optional',
7
7
  'static_contract',
8
8
  'missing'
@@ -12,21 +12,31 @@ const FIXTURES = Object.freeze({
12
12
  'cli-version': fixture('execute', 'sks --version', [], 'pass'),
13
13
  'cli-root': fixture('execute', 'sks root --json', [], 'pass'),
14
14
  'cli-doctor': fixture('real_optional', 'sks doctor --json', [], 'pass'),
15
+ 'doctor:imagegen-repair': fixture('execute_and_validate_artifacts', 'sks doctor --json', [{ path: '.sneakoscope/reports/feature-fixtures/doctor-imagegen-repair.json', schema: 'sks.doctor-imagegen-repair.v1', optional: true }], 'pass', {
16
+ quality: 'runtime_verified',
17
+ validates_json_fields: ['imagegen_repair', 'repair.imagegen']
18
+ }),
15
19
  'cli-paths': fixture('execute_and_validate_artifacts', 'sks paths managed --json', ['.sneakoscope/managed-paths.json'], 'pass'),
16
20
  'cli-rollback': fixture('execute', 'sks rollback list --json', [], 'pass'),
17
21
  'cli-setup': fixture('real_optional', 'sks setup --json --local-only', [], 'pass'),
18
22
  'cli-codex': fixture('execute', 'sks codex compatibility --json', [], 'pass'),
19
23
  'cli-codex-app': fixture('real_optional', 'sks codex-app check --json', [], 'pass'),
20
24
  'cli-codex-lb': fixture('execute_and_validate_artifacts', 'sks codex-lb metrics --json', [], 'pass'),
21
- 'cli-hooks': fixture('mock', 'sks hooks trust-report --json', [], 'pass'),
25
+ 'cli-hooks': fixture('execute', 'sks hooks trust-report --json', [], 'pass'),
22
26
  'cli-features': fixture('execute', 'sks features check --json', [], 'pass'),
23
27
  'cli-commands': fixture('execute', 'sks commands --json', [], 'pass'),
24
28
  'cli-check': fixture('execute', 'sks check --tier confidence --sla 5m --plan --json', [], 'pass'),
29
+ 'cli-plan': fixture('execute', 'sks plan "fixture" --json', [], 'pass'),
30
+ 'cli-review': fixture('execute', 'sks review --diff HEAD --json', [], 'pass'),
31
+ 'cli-ui': fixture('static', 'sks ui [--port 4477] [--mission latest] [--once] [--json]', [], 'pass', {
32
+ quality: 'static_contract',
33
+ reason: 'UI command opens a localhost dashboard; release fixture tracks the CLI contract without launching a server.'
34
+ }),
25
35
  'cli-run': fixture('execute_and_validate_artifacts', 'sks run "fixture" --mock --json', ['run-classification.json', 'completion-proof.json', 'evidence-index.json', 'route-completion-contract.json', 'trust-report.json'], 'pass'),
26
36
  'cli-status': fixture('execute', 'sks status --json', [], 'pass'),
27
37
  'cli-usage': fixture('execute', 'sks usage overview', [], 'pass'),
28
38
  'cli-quickstart': fixture('execute', 'sks quickstart', [], 'pass'),
29
- 'cli-update': fixture('mock', 'sks update now --dry-run --json', [], 'pass'),
39
+ 'cli-update': fixture('execute', 'sks update now --dry-run --json', [], 'pass'),
30
40
  'cli-update-check': fixture('static', 'sks update-check --json', [], 'pass'),
31
41
  'cli-guard': fixture('execute', 'sks guard check --json', [], 'pass'),
32
42
  'cli-conflicts': fixture('execute', 'sks conflicts check --json', [], 'pass'),
@@ -35,20 +45,21 @@ const FIXTURES = Object.freeze({
35
45
  'cli-fix-path': fixture('execute', 'sks fix-path --json', [], 'pass'),
36
46
  'cli-selftest': fixture('execute', 'sks selftest --mock', [], 'pass'),
37
47
  'cli-git': fixture('execute', 'sks git policy --json', [], 'pass'),
38
- 'cli-goal': fixture('mock', 'sks goal status latest --json', ['goal-workflow.json'], 'pass'),
48
+ 'cli-uninstall': fixture('execute', 'sks uninstall --dry-run --json', [], 'pass'),
49
+ 'cli-goal': fixture('execute_and_validate_artifacts', 'sks goal status latest --json', ['goal-workflow.json'], 'pass'),
39
50
  'cli-seo-geo-optimizer': fixture('execute_and_validate_artifacts', 'sks seo-geo-optimizer fixture --mode seo --json', ['search-visibility/site-inventory.json', 'search-visibility/seo-findings.json', 'search-visibility/verification-report.json', 'seo-gate.json', 'completion-proof.json'], 'pass'),
40
- 'cli-research': fixture('mock', 'sks research status latest --json', ['research-gate.json', 'completion-proof.json'], 'pass'),
41
- 'cli-qa-loop': fixture('mock', 'sks qa-loop status latest --json', ['qa-loop-proof.json', 'completion-proof.json'], 'pass'),
42
- 'cli-ppt': fixture('mock', 'sks ppt fixture --mock --json', ['ppt-imagegen-review-gate.json', 'completion-proof.json'], 'pass'),
43
- 'cli-image-ux-review': fixture('mock', 'sks image-ux-review status latest --json', ['image-ux-generated-review-ledger.json', 'image-voxel-ledger.json'], 'pass'),
51
+ 'cli-research': fixture('execute_and_validate_artifacts', 'sks research status latest --json', ['research-gate.json', 'completion-proof.json'], 'pass'),
52
+ 'cli-qa-loop': fixture('execute_and_validate_artifacts', 'sks qa-loop status latest --json', ['qa-loop-proof.json', 'completion-proof.json'], 'pass'),
53
+ 'cli-ppt': fixture('execute_and_validate_artifacts', 'sks ppt fixture --mock --json', ['ppt-imagegen-review-gate.json', 'completion-proof.json'], 'pass'),
54
+ 'cli-image-ux-review': fixture('execute_and_validate_artifacts', 'sks image-ux-review status latest --json', ['image-ux-generated-review-ledger.json', 'image-voxel-ledger.json'], 'pass'),
44
55
  'cli-computer-use': fixture('real_optional', 'sks computer-use status --json', [], 'pass'),
45
- 'cli-pipeline': fixture('mock', 'sks pipeline status latest --json', ['pipeline-plan.json'], 'pass'),
46
- 'cli-validate-artifacts': fixture('mock', 'sks validate-artifacts latest --json', ['validation-report.json'], 'pass'),
47
- 'cli-hproof': fixture('mock', 'sks hproof check latest', ['completion-proof.json'], 'pass'),
56
+ 'cli-pipeline': fixture('execute_and_validate_artifacts', 'sks pipeline status latest --json', ['pipeline-plan.json'], 'pass'),
57
+ 'cli-validate-artifacts': fixture('execute_and_validate_artifacts', 'sks validate-artifacts latest --json', ['validation-report.json'], 'pass'),
58
+ 'cli-hproof': fixture('execute_and_validate_artifacts', 'sks hproof check latest', ['completion-proof.json'], 'pass'),
48
59
  'cli-proof-field': fixture('execute', 'sks proof-field scan --json --intent fixture', [], 'pass'),
49
- 'cli-recallpulse': fixture('mock', 'sks recallpulse status latest --json', ['recallpulse-report.json'], 'pass'),
60
+ 'cli-recallpulse': fixture('execute_and_validate_artifacts', 'sks recallpulse status latest --json', ['recallpulse-report.json'], 'pass'),
50
61
  'cli-agent': fixture('execute_and_validate_artifacts', 'sks agent run fixture --mock --json', ['agents/agent-central-ledger.json', 'agents/agent-task-board.json', 'agents/agent-leases.json', 'agents/agent-no-overlap-proof.json', 'agents/agent-session-cleanup.json', 'agents/agent-proof-evidence.json', 'agents/agent-effort-policy.json'], 'pass'),
51
- 'cli-gx': fixture('mock', 'sks gx validate fixture', ['gx-validation.json'], 'pass'),
62
+ 'cli-gx': fixture('execute_and_validate_artifacts', 'sks gx validate fixture', ['gx-validation.json'], 'pass'),
52
63
  'cli-perf': fixture('execute', 'sks perf cold-start --json --iterations 1', [], 'pass'),
53
64
  'cli-bench': fixture('execute_and_validate_artifacts', 'sks bench core --tier npx-one-shot --json --iterations 1', ['.sneakoscope/reports/performance/core-bench.json'], 'pass'),
54
65
  'cli-code-structure': fixture('execute', 'sks code-structure scan --json', [], 'pass'),
@@ -63,16 +74,16 @@ const FIXTURES = Object.freeze({
63
74
  'cli-dfix': fixture('execute_and_validate_artifacts', 'sks dfix fixture --json', ['completion-proof.json', 'dfix-gate.json', 'dfix-verification.json'], 'pass'),
64
75
  'cli-wiki': fixture('execute_and_validate_artifacts', 'sks wiki image-ingest test/fixtures/images/one-by-one.png --json', [{ path: '.sneakoscope/wiki/image-voxel-ledger.json', schema: 'sks.image-voxel-ledger.v1', require_anchors: false }], 'pass'),
65
76
  'cli-db': fixture('execute', 'sks db policy', [], 'pass'),
66
- 'cli-wizard': fixture('mock', 'sks wizard', [], 'pass'),
67
- 'cli-bootstrap': fixture('mock', 'sks bootstrap --dry-run', [], 'pass'),
68
- 'cli-deps': fixture('mock', 'sks deps check --json', [], 'pass'),
69
- 'cli-auth': fixture('mock', 'sks auth status --json', [], 'pass'),
70
- 'cli-codex-native': fixture('mock', 'sks codex-native status --json', [], 'pass'),
77
+ 'cli-wizard': fixture('execute', 'sks wizard', [], 'pass'),
78
+ 'cli-bootstrap': fixture('execute', 'sks bootstrap --dry-run', [], 'pass'),
79
+ 'cli-deps': fixture('execute', 'sks deps check --json', [], 'pass'),
80
+ 'cli-auth': fixture('execute', 'sks auth status --json', [], 'pass'),
81
+ 'cli-codex-native': fixture('execute', 'sks codex-native status --json', [], 'pass'),
71
82
  'cli-zellij': fixture('mock', 'npm run zellij:capability --silent', [], 'pass'),
72
83
  'cli-tmux': fixture('mock', 'removed runtime migration notice: sks tmux --json', [], 'pass'),
73
- 'cli-mad': fixture('mock', 'sks mad --help', [], 'pass'),
84
+ 'cli-mad': fixture('execute', 'sks mad --help', [], 'pass'),
74
85
  'cli-mad-sks': fixture('static', 'sks mad-sks status --json', [], 'pass'),
75
- 'cli-auto-review': fixture('mock', 'sks auto-review status --json', [], 'pass'),
86
+ 'cli-auto-review': fixture('execute', 'sks auto-review status --json', [], 'pass'),
76
87
  'cli-commit': fixture('mock', 'sks commit --dry-run', [], 'pass'),
77
88
  'cli-commit-and-push': fixture('mock', 'sks commit-and-push --dry-run', [], 'pass'),
78
89
  'cli-context7': fixture('real_optional', 'sks context7 check --json', [], 'pass'),
@@ -80,29 +91,39 @@ const FIXTURES = Object.freeze({
80
91
  'cli-ultra-search': fixture('execute', 'sks ultra-search doctor --json', [], 'pass'),
81
92
  'cli-xai': fixture('real_optional', 'sks xai check --json', [], 'pass'),
82
93
  'cli-task': fixture('execute', 'sks task instant --plan --json', [], 'pass'),
83
- 'cli-release': fixture('mock', 'sks release affected --json', [], 'pass'),
94
+ 'cli-release': fixture('execute', 'sks release affected --json', [], 'pass'),
84
95
  'cli-triwiki': fixture('execute', 'sks triwiki index --json', [], 'pass'),
85
96
  'cli-daemon': fixture('execute', 'sks daemon status --json', [], 'pass'),
86
- 'cli-all-features': fixture('mock', 'sks all-features complete --json', [`.sneakoscope/reports/all-feature-completion-${PACKAGE_VERSION}.json`], 'pass'),
87
- 'cli-init': fixture('mock', 'sks init --local-only --dry-run', [], 'pass'),
88
- 'cli-eval': fixture('mock', 'sks eval run --mock --json', [], 'pass'),
89
- 'cli-harness': fixture('mock', 'sks harness fixture --mock --json', [], 'pass'),
90
- 'cli-naruto': fixture('mock', 'sks naruto run "fixture" --backend fake --work-items 4 --json', ['completion-proof.json', 'naruto-gate.json'], 'pass'),
91
- 'cli-team': fixture('mock', 'sks team "fixture" --mock --clones 4 --backend fake --work-items 4 --json', ['naruto-gate.json', 'team-alias-to-naruto.json'], 'pass'),
92
- 'cli-reasoning': fixture('mock', 'sks reasoning status --json', [], 'pass'),
93
- 'cli-profile': fixture('mock', 'sks profile status --json', [], 'pass'),
94
- 'skill-db-safety-guard': fixture('mock', 'sks db check --sql "SELECT 1" --json', ['db-operation-report.json', 'completion-proof.json'], 'pass'),
95
- 'skill-honest-mode': fixture('mock', 'sks proof smoke --json', ['completion-proof.json', 'trust-report.json'], 'pass'),
96
- 'skill-imagegen': fixture('mock', 'sks image-ux-review fixture --mock --json', ['image-ux-generated-review-ledger.json', 'image-voxel-ledger.json'], 'pass'),
97
- 'skill-gx-visual-validate': fixture('mock', 'sks gx validate fixture --mock --json', ['gx-validation.json'], 'pass'),
97
+ 'cli-all-features': fixture('execute_and_validate_artifacts', 'sks all-features complete --json', [`.sneakoscope/reports/all-feature-completion-${PACKAGE_VERSION}.json`], 'pass'),
98
+ 'cli-init': fixture('execute', 'sks init --local-only --dry-run', [], 'pass'),
99
+ 'cli-eval': fixture('execute', 'sks eval run --mock --json', [], 'pass'),
100
+ 'cli-harness': fixture('execute', 'sks harness fixture --mock --json', [], 'pass'),
101
+ 'cli-naruto': fixture('execute_and_validate_artifacts', 'sks naruto run "fixture" --backend fake --work-items 4 --json', ['completion-proof.json', 'naruto-gate.json'], 'pass'),
102
+ 'cli-team': fixture('execute_and_validate_artifacts', 'sks team "fixture" --mock --clones 4 --backend fake --work-items 4 --json', ['naruto-gate.json', 'team-alias-to-naruto.json'], 'pass'),
103
+ 'cli-reasoning': fixture('execute', 'sks reasoning status --json', [], 'pass'),
104
+ 'cli-profile': fixture('execute', 'sks profile status --json', [], 'pass'),
105
+ 'skill-db-safety-guard': fixture('execute_and_validate_artifacts', 'sks db check --sql "SELECT 1" --json', ['db-operation-report.json', 'completion-proof.json'], 'pass'),
106
+ 'skill-honest-mode': fixture('execute_and_validate_artifacts', 'sks proof smoke --json', ['completion-proof.json', 'trust-report.json'], 'pass'),
107
+ 'skill-imagegen': fixture('execute_and_validate_artifacts', 'sks image-ux-review fixture --mock --json', ['image-ux-generated-review-ledger.json', 'image-voxel-ledger.json'], 'pass'),
108
+ 'ux-review:run-wires-imagegen': fixture('execute_and_validate_artifacts', 'npm run ux-review:run-wires-imagegen --silent', [{ path: 'image-ux-review-gate.json', schema: 'sks.image-ux-review-gate.v2', optional: true }], 'pass', {
109
+ validates_source_contracts: ['requireCodexImagegen', 'generateGptImage2CalloutReview', 'evidence_class', 'output_sha256']
110
+ }),
111
+ 'ppt:real-imagegen-wiring': fixture('execute_and_validate_artifacts', 'npm run ppt:real-imagegen-wiring --silent', [{ path: 'ppt-imagegen-review-gate.json', schema: 'sks.ppt-imagegen-review-gate.v1', optional: true }], 'pass', {
112
+ validates_source_contracts: ['generateGptImage2CalloutReview', 'buildSlideImagegenEvidence', 'imagegen_evidence']
113
+ }),
114
+ 'skill-gx-visual-validate': fixture('execute_and_validate_artifacts', 'sks gx validate fixture --mock --json', ['gx-validation.json'], 'pass'),
98
115
  'skill-context7-docs': fixture('real_optional', 'sks context7 check --json', [], 'pass'),
99
- 'skill-seo-geo-optimizer': fixture('mock', 'sks seo-geo-optimizer fixture --mode geo --json', ['search-visibility/site-inventory.json', 'search-visibility/geo-findings.json', 'geo-gate.json', 'completion-proof.json'], 'pass'),
116
+ 'skill-seo-geo-optimizer': fixture('execute_and_validate_artifacts', 'sks seo-geo-optimizer fixture --mode geo --json', ['search-visibility/site-inventory.json', 'search-visibility/geo-findings.json', 'geo-gate.json', 'completion-proof.json'], 'pass'),
100
117
  'cli-proof': fixture('execute_and_validate_artifacts', 'sks proof smoke --json', ['.sneakoscope/proof/latest.json'], 'pass'),
101
118
  'cli-trust': fixture('execute_and_validate_artifacts', 'sks trust report latest --json', ['trust-report.json'], 'pass'),
102
119
  'cli-wrongness': fixture('execute_and_validate_artifacts', 'sks wrongness add --kind missing_evidence --claim "fixture wrongness" --json', ['.sneakoscope/wiki/wrongness-ledger.json'], 'pass'),
103
120
  'route-team': fixture('execute_and_validate_artifacts', 'sks team "fixture" --mock --clones 4 --backend fake --work-items 4 --json', ['naruto-gate.json', 'team-alias-to-naruto.json'], 'pass'),
104
121
  'route-team-alias': fixture('execute_and_validate_artifacts', 'sks team "fixture" --mock --clones 4 --backend fake --work-items 4 --json', ['naruto-gate.json', 'team-alias-to-naruto.json'], 'pass'),
105
122
  'route-naruto': fixture('execute_and_validate_artifacts', 'sks naruto run "fixture" --clones 4 --backend fake --work-items 4 --json', ['agents/agent-proof-evidence.json', 'agents/agent-scheduler-state.json'], 'pass'),
123
+ 'route-work': fixture('execute_and_validate_artifacts', 'sks naruto run "fixture" --backend fake --work-items 4 --json', ['completion-proof.json', 'naruto-gate.json'], 'pass'),
124
+ 'route-swarm': fixture('execute_and_validate_artifacts', 'sks naruto run "fixture" --backend fake --work-items 4 --json', ['completion-proof.json', 'naruto-gate.json'], 'pass'),
125
+ 'route-plan': fixture('execute', 'sks plan "fixture" --json', [], 'pass'),
126
+ 'route-review': fixture('execute', 'sks review --diff HEAD --json', [], 'pass'),
106
127
  'route-shadowclone': fixture('mock', '$ShadowClone alias of $Naruto shadow-clone swarm route', [], 'pass'),
107
128
  'route-kagebunshin': fixture('mock', '$Kagebunshin alias of $Naruto shadow-clone swarm route', [], 'pass'),
108
129
  'route-qa-loop': fixture('execute_and_validate_artifacts', 'sks qa-loop run latest --mock --json', ['completion-proof.json', 'qa-gate.json'], 'pass'),
@@ -120,11 +141,11 @@ const FIXTURES = Object.freeze({
120
141
  'route-ultrasearch': fixture('execute', 'sks run "$UltraSearch source intelligence fixture" --execute --json', [], 'pass'),
121
142
  'route-seo-geo-optimizer': fixture('execute_and_validate_artifacts', 'sks seo-geo-optimizer fixture --mode geo --json', ['search-visibility/site-inventory.json', 'search-visibility/geo-findings.json', 'search-visibility/verification-report.json', 'geo-gate.json', 'completion-proof.json'], 'pass'),
122
143
  'route-autoresearch': fixture('mock', '$AutoResearch fixture route', ['research-gate.json', 'completion-proof.json'], 'pass'),
123
- 'route-mad-sks': fixture('mock', '$MAD-SKS permission gate route', ['mad-sks-gate.json', 'completion-proof.json'], 'pass'),
144
+ 'route-mad-sks': fixture('mock', '$MAD-SKS permission gate + sql_plane route', [{ path: 'mad-sks-gate.json', schema: 'sks.mad-sks-gate.v1' }, 'completion-proof.json'], 'pass'),
124
145
  'route-from-chat-img': fixture('mock', '$From-Chat-IMG visual work order route', ['from-chat-img-work-order.md', 'image-voxel-ledger.json', 'completion-proof.json'], 'pass'),
125
146
  'route-ux-review': fixture('mock', '$UX-Review image UX alias route', ['image-ux-generated-review-ledger.json', 'image-voxel-ledger.json'], 'pass'),
126
147
  'route-db': fixture('execute_and_validate_artifacts', 'sks db check --sql "SELECT 1" --json', ['completion-proof.json', 'db-operation-report.json'], 'pass'),
127
- 'route-mad-db': fixture('mock', '$MAD-DB one-cycle DB break-glass route contract', ['mad-db-capability.json', 'mad-db-ledger.jsonl', 'completion-proof.json'], 'pass'),
148
+ 'route-mad-db': fixture('mock', '$MAD-DB deprecated alias to $MAD-SKS sql-plane contract', ['mad-sks-gate.json', 'completion-proof.json'], 'pass'),
128
149
  'route-wiki': fixture('execute_and_validate_artifacts', 'sks wiki image-ingest test/fixtures/images/one-by-one.png --json', [{ path: 'completion-proof.json', schema: 'sks.completion-proof.v1' }, { path: 'image-voxel-ledger.json', schema: 'sks.image-voxel-ledger.v1' }], 'pass'),
129
150
  'route-gx': fixture('execute_and_validate_artifacts', 'sks gx validate fixture --mock --json', ['completion-proof.json', { path: 'image-voxel-ledger.json', schema: 'sks.image-voxel-ledger.v1' }, 'gx-validation.json'], 'pass'),
130
151
  'route-sks': fixture('mock', '$SKS control-surface route', ['completion-proof.json'], 'pass'),
@@ -249,7 +270,7 @@ function qualityForKind(kind) {
249
270
  if (kind === 'execute' || kind === 'execute_and_validate_artifacts')
250
271
  return 'runtime_verified';
251
272
  if (kind === 'mock')
252
- return 'runtime_mock_verified';
273
+ return 'wiring_only';
253
274
  if (kind === 'real_optional')
254
275
  return 'integration_optional';
255
276
  if (kind === 'not_available')
@@ -2,6 +2,7 @@ import fs from 'node:fs/promises';
2
2
  import { existsSync } from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import { spawnSync } from 'node:child_process';
5
+ import { COMMANDS } from '../cli/command-registry.js';
5
6
  import { COMMAND_CATALOG, DOLLAR_COMMAND_ALIASES, DOLLAR_COMMANDS, ROUTES } from './routes.js';
6
7
  import { FEATURE_QUALITY_LEVELS, fixtureForFeature, fixtureSummary, validateFeatureFixtures } from './feature-fixtures.js';
7
8
  import { runFeatureFixture, writeFeatureFixtureReports } from './feature-fixture-runner.js';
@@ -51,6 +52,8 @@ export async function buildFeatureRegistry({ root = packageRoot(), generatedAt =
51
52
  }
52
53
  features.push(nativeAgentIntakeFeature());
53
54
  features.push(agentProofEvidenceFeature());
55
+ features.push(doctorImagegenRepairFeature());
56
+ features.push(...imagegenWiringFeatures());
54
57
  for (const skillName of skillNames) {
55
58
  if (!skillCoveredByRoute(skillName))
56
59
  features.push(skillFeature(skillName));
@@ -102,7 +105,8 @@ export function validateFeatureRegistry(registry = {}) {
102
105
  const blockers = [
103
106
  ...Object.entries(unmapped).flatMap(([kind, values]) => values.map((value) => `${kind}:${value}`)),
104
107
  ...duplicateFeatureIds.map((id) => `duplicate_feature_id:${id}`),
105
- ...routeMentionsWithoutRoute.map((mention) => `doc_route_mention_without_route:${mention}`)
108
+ ...routeMentionsWithoutRoute.map((mention) => `doc_route_mention_without_route:${mention}`),
109
+ ...routeGateConsistencyBlockers()
106
110
  ];
107
111
  return {
108
112
  ok: blockers.length === 0,
@@ -118,6 +122,7 @@ export function validateFeatureRegistry(registry = {}) {
118
122
  unmapped,
119
123
  duplicate_feature_ids: duplicateFeatureIds,
120
124
  doc_route_mentions_without_route: routeMentionsWithoutRoute,
125
+ route_gate_consistency_blockers: routeGateConsistencyBlockers(),
121
126
  blockers,
122
127
  nonblocking_known_gaps: [
123
128
  'feature fixtures remain progressive',
@@ -127,6 +132,41 @@ export function validateFeatureRegistry(registry = {}) {
127
132
  feature_quality_summary: featureQualitySummary(features)
128
133
  };
129
134
  }
135
+ export function routeGateConsistencyBlockers() {
136
+ const blockers = [];
137
+ for (const route of ROUTES) {
138
+ const cliName = routeCliCommandName(route);
139
+ if (!cliName)
140
+ continue;
141
+ const entry = COMMANDS[cliName];
142
+ if (!entry?.ownsGates)
143
+ continue;
144
+ const routeGates = stopGateFiles(route.stopGate);
145
+ const owned = new Set((entry.ownedGateFiles || []).map((file) => String(file)));
146
+ if (!routeGates.length && owned.size > 0)
147
+ blockers.push(`route_gate_mismatch:${route.id}:routes_none_registry_${[...owned].join('|')}`);
148
+ for (const gate of routeGates) {
149
+ if (!owned.has(gate))
150
+ blockers.push(`route_gate_mismatch:${route.id}:${gate}_not_owned_by_${cliName}`);
151
+ }
152
+ }
153
+ return blockers;
154
+ }
155
+ function routeCliCommandName(route) {
156
+ const command = String(route.command || '').replace(/^\$/, '').toLowerCase();
157
+ if (Object.hasOwn(COMMANDS, command))
158
+ return command;
159
+ const alias = (route.dollarAliases || [])
160
+ .map((value) => String(value || '').replace(/^\$/, '').toLowerCase())
161
+ .find((value) => Object.hasOwn(COMMANDS, value));
162
+ return alias || null;
163
+ }
164
+ function stopGateFiles(stopGate) {
165
+ const text = String(stopGate || '');
166
+ if (!text || text === 'none' || text === 'honest_mode' || text === 'plan-only')
167
+ return [];
168
+ return text.split('|').map((part) => part.trim()).filter((part) => part.endsWith('.json'));
169
+ }
130
170
  export async function writeFeatureInventoryDocs({ root = packageRoot(), outFile = path.join(root, 'docs', 'feature-inventory.md') } = {}) {
131
171
  const registry = await buildFeatureRegistry({ root });
132
172
  const markdown = renderFeatureInventoryMarkdown(registry);
@@ -674,6 +714,66 @@ function agentProofEvidenceFeature() {
674
714
  }
675
715
  });
676
716
  }
717
+ function doctorImagegenRepairFeature() {
718
+ return baseFeature({
719
+ id: 'doctor:imagegen-repair',
720
+ commands: ['sks doctor --json', 'sks doctor --fix --json'],
721
+ aliases: ['repair.imagegen', 'imagegen_repair'],
722
+ category: 'safety',
723
+ maturity: 'beta',
724
+ intent: 'Doctor repair path that detects Codex App imagegen, attempts repair when requested, and reports imagegen_repair evidence without claiming success unless re-detection passes.',
725
+ voxel_triwiki_integration: 'policy voxel required for visual/image routes that depend on Codex App imagegen',
726
+ completion_proof_integration: 'doctor report imagegen_repair is consumed by imagegen route blockers before visual route proof',
727
+ known_gaps: ['live Codex App feature enablement remains environment-dependent and reports manual actions when unavailable'],
728
+ source_refs: {
729
+ cli_command_names: ['doctor'],
730
+ handler_keys: ['doctor'],
731
+ dollar_commands: [],
732
+ app_skill_aliases: [],
733
+ skills: ['imagegen']
734
+ }
735
+ });
736
+ }
737
+ function imagegenWiringFeatures() {
738
+ return [
739
+ baseFeature({
740
+ id: 'ux-review:run-wires-imagegen',
741
+ commands: ['npm run ux-review:run-wires-imagegen', 'sks ux-review run --image <screenshot> --generate-callouts --json'],
742
+ aliases: ['$Image-UX-Review', '$UX-Review'],
743
+ category: 'visual-memory',
744
+ maturity: 'beta',
745
+ intent: 'Image UX route start gate, shared gpt-image-2 adapter, callout extraction, and Codex App evidence validation wiring.',
746
+ voxel_triwiki_integration: 'image/source/bbox voxel required',
747
+ completion_proof_integration: 'image-ux-review-gate and Completion Proof must separate real Codex image evidence from mock/API fallback evidence',
748
+ known_gaps: ['live Codex App image generation remains environment-dependent'],
749
+ source_refs: {
750
+ cli_command_names: ['image-ux-review'],
751
+ handler_keys: ['image-ux-review', 'ux-review'],
752
+ dollar_commands: ['$Image-UX-Review', '$UX-Review'],
753
+ app_skill_aliases: ['$image-ux-review', '$ux-review'],
754
+ skills: ['image-ux-review', 'ux-review', 'imagegen']
755
+ }
756
+ }),
757
+ baseFeature({
758
+ id: 'ppt:real-imagegen-wiring',
759
+ commands: ['npm run ppt:real-imagegen-wiring', 'sks ppt review --deck <pptx> --json'],
760
+ aliases: ['$PPT'],
761
+ category: 'visual-memory',
762
+ maturity: 'beta',
763
+ intent: 'PPT slide callout review path reuses the shared gpt-image-2 adapter and records imagegen_evidence in PPT gates.',
764
+ voxel_triwiki_integration: 'image/source/bbox voxel required',
765
+ completion_proof_integration: 'ppt-imagegen-review-gate and ppt-gate must include Codex App imagegen evidence classes and hashes',
766
+ known_gaps: ['live deck export and live Codex App image generation remain environment-dependent'],
767
+ source_refs: {
768
+ cli_command_names: ['ppt'],
769
+ handler_keys: ['ppt'],
770
+ dollar_commands: ['$PPT'],
771
+ app_skill_aliases: ['$ppt'],
772
+ skills: ['ppt', 'imagegen']
773
+ }
774
+ })
775
+ ];
776
+ }
677
777
  function skillFeature(skillName) {
678
778
  return baseFeature({
679
779
  id: `skill-${slug(skillName)}`,
@@ -876,7 +976,7 @@ function routeKnownGaps(command) {
876
976
  if (command === '$MAD-SKS')
877
977
  return ['permission closed by owning gate'];
878
978
  if (command === '$MAD-DB')
879
- return ['active cycle must execute requested SQL-plane work, read back postconditions, and close the mission-local write profile'];
979
+ return ['deprecated alias; SQL-plane execution is merged into $MAD-SKS and must still read back postconditions and close the mission-local write profile'];
880
980
  return [];
881
981
  }
882
982
  function checkRow(id, ok, blockers = []) {
package/dist/core/fsx.js CHANGED
@@ -5,12 +5,42 @@ import os from 'node:os';
5
5
  import crypto from 'node:crypto';
6
6
  import { spawn } from 'node:child_process';
7
7
  import { fileURLToPath } from 'node:url';
8
- export const PACKAGE_VERSION = '4.8.7';
8
+ export const PACKAGE_VERSION = '5.1.2';
9
9
  export const DEFAULT_PROCESS_TAIL_BYTES = 256 * 1024;
10
10
  export const DEFAULT_PROCESS_TIMEOUT_MS = 30 * 60 * 1000;
11
11
  export function nowIso() {
12
12
  return new Date().toISOString();
13
13
  }
14
+ export function lastLine(chunk) {
15
+ const lines = String(chunk || '').split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
16
+ return lines[lines.length - 1] || '';
17
+ }
18
+ export function throttleLines(fn, ms = 500) {
19
+ let lastAt = 0;
20
+ let pending = null;
21
+ let timer = null;
22
+ const flush = () => {
23
+ timer = null;
24
+ if (!pending)
25
+ return;
26
+ lastAt = Date.now();
27
+ const line = pending;
28
+ pending = null;
29
+ fn(line);
30
+ };
31
+ return (chunk) => {
32
+ const line = lastLine(chunk);
33
+ if (!line)
34
+ return;
35
+ pending = line;
36
+ const now = Date.now();
37
+ const wait = Math.max(0, ms - (now - lastAt));
38
+ if (wait === 0)
39
+ flush();
40
+ else if (!timer)
41
+ timer = setTimeout(flush, wait);
42
+ };
43
+ }
14
44
  export function sha256(input) {
15
45
  return crypto.createHash('sha256').update(input).digest('hex');
16
46
  }
@@ -109,18 +139,21 @@ export async function writeReceiptRotated(p, data, opts = {}) {
109
139
  const rotated = prior
110
140
  .filter((entry) => entry.isFile() && entry.name.startsWith(`${base}.`) && entry.name.endsWith('.json'))
111
141
  .map((entry) => path.join(path.dirname(p), entry.name));
142
+ const rotatedFiles = new Set(rotated);
112
143
  const existing = await fsp.stat(p).catch(() => null);
113
144
  if (existing) {
114
145
  const stamp = new Date(existing.mtimeMs).toISOString().replace(/[:.]/g, '-');
115
- await fsp.rename(p, path.join(path.dirname(p), `${base}.${stamp}.json`)).catch(() => undefined);
146
+ const rotatedPath = path.join(path.dirname(p), `${base}.${stamp}.json`);
147
+ await fsp.rename(p, rotatedPath).catch(() => undefined);
148
+ rotatedFiles.add(rotatedPath);
116
149
  }
117
150
  await writeJsonAtomic(p, data);
118
- const rows = await Promise.all(rotated.map(async (file) => ({ file, stat: await fsp.stat(file).catch(() => null) })));
119
- rows
151
+ const rows = await Promise.all([...rotatedFiles].map(async (file) => ({ file, stat: await fsp.stat(file).catch(() => null) })));
152
+ const removable = rows
120
153
  .filter((row) => Boolean(row.stat))
121
154
  .sort((a, b) => b.stat.mtimeMs - a.stat.mtimeMs)
122
- .slice(keep)
123
- .forEach((row) => void fsp.rm(row.file, { force: true }).catch(() => undefined));
155
+ .slice(keep);
156
+ await Promise.all(removable.map((row) => fsp.rm(row.file, { force: true }).catch(() => undefined)));
124
157
  }
125
158
  export async function writeBinaryAtomic(p, data) {
126
159
  await ensureDir(path.dirname(p));
@@ -107,6 +107,7 @@ export function createCodexAppImagegenAdapter(opts = {}) {
107
107
  schema: 'sks.image-ux-gpt-image-2-response.v1',
108
108
  created_at: nowIso(),
109
109
  provider: 'codex_app_imagegen',
110
+ evidence_class: 'codex_app_imagegen',
110
111
  model: 'gpt-image-2',
111
112
  ok: false,
112
113
  status: 'blocked',
@@ -131,11 +132,13 @@ export function createCodexAppImagegenAdapter(opts = {}) {
131
132
  schema: 'sks.image-ux-gpt-image-2-response.v1',
132
133
  created_at: nowIso(),
133
134
  provider: 'codex_app_imagegen',
135
+ evidence_class: 'codex_app_imagegen',
134
136
  model: 'gpt-image-2',
135
137
  ok: true,
136
138
  status: 'generated',
137
139
  output_image_path: dest,
138
140
  output_image_sha256: meta.sha256,
141
+ output_sha256: meta.sha256,
139
142
  output_id: meta.output_id,
140
143
  output_source: outputSource,
141
144
  image_artifact_path_contract: imageContract?.artifact_path || null,
@@ -161,6 +164,7 @@ export function createCodexAppImagegenAdapter(opts = {}) {
161
164
  schema: 'sks.image-ux-gpt-image-2-response.v1',
162
165
  created_at: nowIso(),
163
166
  provider: 'codex_app_imagegen',
167
+ evidence_class: 'codex_app_imagegen',
164
168
  model: 'gpt-image-2',
165
169
  ok: false,
166
170
  status: 'blocked',
@@ -196,6 +200,22 @@ export function createFakeImagegenAdapter(opts = {}) {
196
200
  await ensureDir(input.output_dir);
197
201
  const requestArtifact = path.join(input.output_dir, 'image-ux-gpt-image-2-request.json');
198
202
  const responseArtifact = path.join(input.output_dir, 'image-ux-gpt-image-2-response.json');
203
+ if (!imagegenMockContext(opts)) {
204
+ await writeJsonAtomic(responseArtifact, {
205
+ schema: 'sks.image-ux-gpt-image-2-response.v1',
206
+ created_at: nowIso(),
207
+ provider: 'fake_imagegen_adapter',
208
+ fake_adapter: true,
209
+ execution_class: 'mock_fixture',
210
+ evidence_class: 'mock_fixture',
211
+ model: 'gpt-image-2',
212
+ ok: false,
213
+ status: 'blocked',
214
+ blocker: 'fake_imagegen_requires_test_or_mock_context',
215
+ local_only: true
216
+ });
217
+ return { ok: false, status: 'blocked', generated_image_path: null, output_id: null, blocker: 'fake_imagegen_requires_test_or_mock_context', provider: 'fake_imagegen_adapter', request_artifact: null, response_artifact: responseArtifact, latency_ms: Date.now() - started };
218
+ }
199
219
  const validation = await validateGptImage2Request({
200
220
  provider: 'fake_imagegen_adapter',
201
221
  endpoint: 'local hermetic fixture',
@@ -227,6 +247,9 @@ export function createFakeImagegenAdapter(opts = {}) {
227
247
  schema: 'sks.image-ux-gpt-image-2-response.v1',
228
248
  created_at: nowIso(),
229
249
  provider: 'fake_imagegen_adapter',
250
+ fake_adapter: true,
251
+ execution_class: 'mock_fixture',
252
+ evidence_class: 'mock_fixture',
230
253
  model: 'gpt-image-2',
231
254
  ok: false,
232
255
  status: 'blocked',
@@ -251,16 +274,20 @@ export function createFakeImagegenAdapter(opts = {}) {
251
274
  schema: 'sks.image-ux-gpt-image-2-response.v1',
252
275
  created_at: nowIso(),
253
276
  provider: 'fake_imagegen_adapter',
277
+ fake_adapter: true,
278
+ execution_class: 'mock_fixture',
279
+ evidence_class: 'mock_fixture',
254
280
  model: 'gpt-image-2',
255
281
  ok: true,
256
282
  status: 'generated',
257
283
  output_image_path: out,
258
284
  output_image_sha256: meta.sha256,
285
+ output_sha256: meta.sha256,
259
286
  output_id: meta.output_id,
287
+ output_source: 'mock_fixture',
260
288
  image_artifact_path_contract: imageContract?.artifact_path || null,
261
289
  dimensions: { width: meta.width, height: meta.height, format: meta.format },
262
290
  latency_ms: Date.now() - started,
263
- fake_adapter: true,
264
291
  source: 'mock_like_fixture',
265
292
  real_generated: false,
266
293
  mock: true,
@@ -320,6 +347,7 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
320
347
  schema: 'sks.image-ux-gpt-image-2-response.v1',
321
348
  created_at: nowIso(),
322
349
  provider: 'openai_images_api',
350
+ evidence_class: 'non_codex_api_fallback',
323
351
  model: 'gpt-image-2',
324
352
  ok: false,
325
353
  status: 'blocked',
@@ -334,6 +362,7 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
334
362
  schema: 'sks.image-ux-gpt-image-2-response.v1',
335
363
  created_at: nowIso(),
336
364
  provider: 'openai_images_api',
365
+ evidence_class: 'non_codex_api_fallback',
337
366
  model: 'gpt-image-2',
338
367
  ok: false,
339
368
  status: 'blocked',
@@ -397,6 +426,7 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
397
426
  schema: 'sks.image-ux-gpt-image-2-response.v1',
398
427
  created_at: nowIso(),
399
428
  provider: 'openai_responses_image_generation',
429
+ evidence_class: 'non_codex_api_fallback',
400
430
  model: 'gpt-image-2',
401
431
  responses_model: responsesImagegenModel(opts),
402
432
  auth_source: auth.auth_source,
@@ -404,6 +434,7 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
404
434
  status: 'generated',
405
435
  output_image_path: out,
406
436
  output_image_sha256: meta.sha256,
437
+ output_sha256: meta.sha256,
407
438
  output_id: meta.output_id,
408
439
  image_artifact_path_contract: imageContract?.artifact_path || null,
409
440
  dimensions: { width: meta.width, height: meta.height, format: meta.format },
@@ -454,12 +485,14 @@ export function createOpenAIImagesApiAdapter(opts = {}) {
454
485
  schema: 'sks.image-ux-gpt-image-2-response.v1',
455
486
  created_at: nowIso(),
456
487
  provider: 'openai_images_api',
488
+ evidence_class: 'non_codex_api_fallback',
457
489
  model: 'gpt-image-2',
458
490
  auth_source: auth.auth_source,
459
491
  ok: true,
460
492
  status: 'generated',
461
493
  output_image_path: out,
462
494
  output_image_sha256: meta.sha256,
495
+ output_sha256: meta.sha256,
463
496
  output_id: meta.output_id,
464
497
  image_artifact_path_contract: imageContract?.artifact_path || null,
465
498
  dimensions: { width: meta.width, height: meta.height, format: meta.format },
@@ -511,24 +544,17 @@ async function resolveImageArtifactRoot(input) {
511
544
  return projectRoot(input.output_dir || process.cwd()).catch(() => cwdRoot);
512
545
  }
513
546
  export async function generateGptImage2CalloutReview(input, opts = {}) {
514
- if (opts.fake === true || process.env.SKS_TEST_FAKE_IMAGEGEN === '1') {
515
- return createFakeImagegenAdapter(opts.fakeAdapter || {}).generateCalloutReview(input);
547
+ if ((opts.fake === true || process.env.SKS_TEST_FAKE_IMAGEGEN === '1') && imagegenMockContext(opts)) {
548
+ return createFakeImagegenAdapter({ ...(opts.fakeAdapter || {}), mockContext: true }).generateCalloutReview(input);
516
549
  }
517
550
  const capability = await detectImagegenCapability(opts.capability || {}).catch(() => null);
518
- // Auto-enable the OpenAI direct-key API fallback whenever an OPENAI_API_KEY is
519
- // available, so a missing/failed Codex App $imagegen surface still produces a
520
- // real image instead of a hard block. Explicit opt-out wins: pass
521
- // allowApiFallback:false or SKS_IMAGEGEN_ALLOW_API_FALLBACK=0.
522
- const openAiKeyPresent = Boolean(opts.openai?.apiKey || process.env.OPENAI_API_KEY);
523
- const explicitDisableApiFallback = opts.allowApiFallback === false || process.env.SKS_IMAGEGEN_ALLOW_API_FALLBACK === '0';
524
551
  // codex-lb imagegen is a direct API fallback, not Codex App imagegen evidence.
525
552
  // It must be explicitly enabled by the caller or environment.
526
553
  const explicitDisableCodexLbFallback = opts.allowCodexLbApiFallback === false || process.env.SKS_IMAGEGEN_ALLOW_CODEX_LB_API_FALLBACK === '0';
527
554
  const allowCodexLbApiFallback = !explicitDisableCodexLbFallback && (opts.allowCodexLbApiFallback === true
528
555
  || process.env.SKS_IMAGEGEN_ALLOW_CODEX_LB_API_FALLBACK === '1');
529
- const allowApiFallback = !explicitDisableApiFallback && (opts.allowApiFallback === true
556
+ const allowApiFallback = (opts.allowApiFallback === true
530
557
  || process.env.SKS_IMAGEGEN_ALLOW_API_FALLBACK === '1'
531
- || openAiKeyPresent
532
558
  || allowCodexLbApiFallback);
533
559
  const openaiOptions = {
534
560
  ...(opts.openai || {}),
@@ -544,6 +570,13 @@ export async function generateGptImage2CalloutReview(input, opts = {}) {
544
570
  return codexResult;
545
571
  return createOpenAIImagesApiAdapter(openaiOptions).generateCalloutReview(input);
546
572
  }
573
+ function imagegenMockContext(opts = {}) {
574
+ return opts.mockContext === true
575
+ || opts.testContext === true
576
+ || process.env.NODE_ENV === 'test'
577
+ || process.env.SKS_SELFTEST_MOCK === '1'
578
+ || process.env.SKS_MOCK === '1';
579
+ }
547
580
  export function imagegenCapabilityBlocker(surface = 'Codex App $imagegen') {
548
581
  return {
549
582
  schema: 'sks.image-ux-imagegen-blocker.v1',
@@ -705,6 +738,9 @@ export async function generatedImageMetadata(root, imagePath, opts = {}) {
705
738
  source_screen_id: opts.source_screen_id || null,
706
739
  provider_model: 'gpt-image-2',
707
740
  provider_surface: opts.provider_surface || 'codex_app_imagegen',
741
+ evidence_class: opts.evidence_class || (opts.mock ? 'mock_fixture' : 'codex_app_imagegen'),
742
+ output_source: opts.output_source || (opts.mock ? 'mock_fixture' : 'manual_attach'),
743
+ output_sha256: opts.output_sha256 || await sha256File(absolute),
708
744
  requested_fidelity: 'high_fidelity_automatic',
709
745
  image_input_fidelity_note: 'high_fidelity_automatic',
710
746
  privacy: 'local-only',
@@ -729,6 +765,7 @@ function redactedImagegenResponse(payload, ok, latencyMs, provider = 'openai_ima
729
765
  schema: 'sks.image-ux-gpt-image-2-response.v1',
730
766
  created_at: nowIso(),
731
767
  provider,
768
+ evidence_class: provider === 'codex_app_imagegen' ? 'codex_app_imagegen' : 'non_codex_api_fallback',
732
769
  model: 'gpt-image-2',
733
770
  ok,
734
771
  status: ok ? 'generated' : 'blocked',