sneakoscope 4.8.7 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (261) hide show
  1. package/README.md +51 -726
  2. package/config/bench-baseline.json +7 -0
  3. package/crates/sks-core/Cargo.lock +1 -1
  4. package/crates/sks-core/Cargo.toml +1 -1
  5. package/crates/sks-core/src/main.rs +1 -1
  6. package/dist/bin/install.js +35 -0
  7. package/dist/bin/sks.js +1 -1
  8. package/dist/cli/cli-theme.js +51 -0
  9. package/dist/cli/command-registry.js +15 -4
  10. package/dist/cli/help-fast.js +18 -8
  11. package/dist/cli/insane-search-command.js +36 -8
  12. package/dist/cli/install-helpers.js +32 -0
  13. package/dist/commands/codex-lb.js +2 -0
  14. package/dist/commands/doctor.js +94 -9
  15. package/dist/commands/proof.js +6 -3
  16. package/dist/config/skills-manifest.json +82 -54
  17. package/dist/core/agents/agent-conflict-graph.js +5 -0
  18. package/dist/core/agents/agent-lease.js +5 -0
  19. package/dist/core/agents/agent-ledger-schemas.js +1 -0
  20. package/dist/core/agents/agent-lifecycle.js +5 -3
  21. package/dist/core/agents/agent-orchestrator.js +268 -62
  22. package/dist/core/agents/agent-output-validator.js +14 -3
  23. package/dist/core/agents/agent-patch-queue-store.js +95 -2
  24. package/dist/core/agents/agent-patch-queue.js +6 -3
  25. package/dist/core/agents/agent-patch-schema.js +13 -0
  26. package/dist/core/agents/agent-proof-evidence.js +6 -1
  27. package/dist/core/agents/agent-runner-fake.js +40 -0
  28. package/dist/core/agents/agent-worker-pipeline.js +36 -2
  29. package/dist/core/agents/codex-exec-worker-adapter.js +2 -0
  30. package/dist/core/agents/native-cli-worker.js +0 -1
  31. package/dist/core/agents/native-worker-backend-router.js +58 -1
  32. package/dist/core/codex-app/sks-menubar.js +477 -132
  33. package/dist/core/codex-app.js +1 -0
  34. package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
  35. package/dist/core/codex-control/codex-sdk-env-policy.js +1 -1
  36. package/dist/core/codex-control/schemas/agent-worker-result.schema.js +12 -3
  37. package/dist/core/codex-hooks/codex-hook-managed-install.js +5 -0
  38. package/dist/core/codex-hooks/codex-hook-state-writer.js +70 -11
  39. package/dist/core/codex-hooks/codex-hook-trust-doctor.js +2 -2
  40. package/dist/core/codex-lb/codex-lb-env.js +20 -1
  41. package/dist/core/commands/basic-cli.js +18 -1
  42. package/dist/core/commands/check-command.js +37 -5
  43. package/dist/core/commands/computer-use-command.js +62 -7
  44. package/dist/core/commands/db-command.js +31 -5
  45. package/dist/core/commands/fast-mode-command.js +3 -0
  46. package/dist/core/commands/gate-result-contract.js +43 -0
  47. package/dist/core/commands/gates-command.js +6 -1
  48. package/dist/core/commands/gc-command.js +29 -2
  49. package/dist/core/commands/goal-command.js +9 -2
  50. package/dist/core/commands/gx-command.js +79 -7
  51. package/dist/core/commands/image-ux-review-command.js +188 -13
  52. package/dist/core/commands/mad-db-command.js +85 -176
  53. package/dist/core/commands/mad-sks-command.js +230 -29
  54. package/dist/core/commands/menubar-command.js +24 -2
  55. package/dist/core/commands/naruto-command.js +64 -10
  56. package/dist/core/commands/plan-command.js +76 -0
  57. package/dist/core/commands/ppt-command.js +159 -24
  58. package/dist/core/commands/qa-loop-command.js +6 -2
  59. package/dist/core/commands/release-command.js +55 -2
  60. package/dist/core/commands/research-command.js +1 -1
  61. package/dist/core/commands/review-command.js +217 -0
  62. package/dist/core/commands/route-success-helpers.js +59 -0
  63. package/dist/core/commands/run-command.js +19 -7
  64. package/dist/core/commands/seo-command.js +49 -1
  65. package/dist/core/commands/ui-command.js +161 -0
  66. package/dist/core/commands/uninstall-command.js +15 -1
  67. package/dist/core/db-safety.js +2 -2
  68. package/dist/core/doctor/doctor-dirty-planner.js +51 -7
  69. package/dist/core/doctor/doctor-transaction.js +8 -0
  70. package/dist/core/doctor/doctor-zellij-repair.js +1 -0
  71. package/dist/core/doctor/imagegen-repair.js +161 -0
  72. package/dist/core/feature-fixture-runner.js +2 -2
  73. package/dist/core/feature-fixtures.js +58 -37
  74. package/dist/core/feature-registry.js +102 -2
  75. package/dist/core/fsx.js +39 -6
  76. package/dist/core/image-ux-review/imagegen-adapter.js +48 -11
  77. package/dist/core/image-ux-review.js +16 -0
  78. package/dist/core/imagegen/imagegen-capability.js +11 -5
  79. package/dist/core/imagegen/require-imagegen.js +57 -0
  80. package/dist/core/init/skills.js +10 -5
  81. package/dist/core/mad-db/mad-db-coordinator.js +94 -18
  82. package/dist/core/mad-db/mad-db-policy.js +12 -10
  83. package/dist/core/mad-sks/executors/executor-base.js +8 -2
  84. package/dist/core/mad-sks/executors/index.js +4 -0
  85. package/dist/core/mad-sks/executors/sql-plane-executor.js +194 -0
  86. package/dist/core/naruto/naruto-active-pool.js +15 -4
  87. package/dist/core/naruto/naruto-real-worker-child.js +11 -1
  88. package/dist/core/naruto/naruto-role-policy.js +3 -0
  89. package/dist/core/naruto/naruto-task-hints.js +10 -0
  90. package/dist/core/naruto/naruto-work-graph.js +8 -2
  91. package/dist/core/naruto/naruto-work-item.js +6 -0
  92. package/dist/core/naruto/solution-tournament.js +101 -0
  93. package/dist/core/permission-gates.js +30 -0
  94. package/dist/core/pipeline-internals/runtime-core.js +11 -3
  95. package/dist/core/pipeline-internals/runtime-gates.js +27 -0
  96. package/dist/core/ppt-review/index.js +6 -1
  97. package/dist/core/ppt-review/slide-imagegen-review.js +75 -10
  98. package/dist/core/ppt.js +70 -2
  99. package/dist/core/proof/auto-finalize.js +70 -11
  100. package/dist/core/proof/proof-schema.js +2 -0
  101. package/dist/core/proof/route-adapter.js +5 -1
  102. package/dist/core/proof/route-finalizer.js +8 -5
  103. package/dist/core/proof/selftest-proof-fixtures.js +18 -5
  104. package/dist/core/proof/validation.js +2 -0
  105. package/dist/core/provider/model-router.js +53 -0
  106. package/dist/core/release/release-gate-node.js +3 -0
  107. package/dist/core/release/release-gate-resource-governor.js +1 -0
  108. package/dist/core/routes/constants.js +1 -1
  109. package/dist/core/routes.js +65 -18
  110. package/dist/core/safety/mutation-guard.js +5 -1
  111. package/dist/core/stop-gate/gate-evaluator.js +102 -0
  112. package/dist/core/stop-gate/stop-gate-check.js +16 -1
  113. package/dist/core/stop-gate/stop-gate-writer.js +4 -0
  114. package/dist/core/triwiki/agents-md-projector.js +184 -0
  115. package/dist/core/triwiki-wrongness/wrongness-schema.js +3 -1
  116. package/dist/core/trust-kernel/trust-kernel-schema.js +1 -0
  117. package/dist/core/trust-kernel/trust-report.js +1 -1
  118. package/dist/core/trust-kernel/trust-status.js +2 -0
  119. package/dist/core/ui/dashboard-html.js +111 -0
  120. package/dist/core/update/update-migration-state.js +386 -15
  121. package/dist/core/update-check.js +178 -81
  122. package/dist/core/verification/diff-quality.js +100 -0
  123. package/dist/core/verification/impact-scan.js +164 -0
  124. package/dist/core/verification/machine-feedback.js +146 -0
  125. package/dist/core/verification/mistake-rule-compiler.js +195 -0
  126. package/dist/core/version.js +1 -1
  127. package/dist/core/zellij/zellij-self-heal.js +9 -6
  128. package/dist/core/zellij/zellij-slot-telemetry.js +1 -1
  129. package/dist/scripts/check-feature-quality.js +2 -2
  130. package/dist/scripts/cli-output-consistency-check.js +57 -0
  131. package/dist/scripts/coding-bench-check.js +136 -0
  132. package/dist/scripts/doctor-imagegen-repair-check.js +62 -0
  133. package/dist/scripts/ensure-bin-executable.js +11 -3
  134. package/dist/scripts/harness-benchmark-check.js +104 -0
  135. package/dist/scripts/legacy-update-e2e-check.js +228 -0
  136. package/dist/scripts/mad-db-command-check.js +11 -8
  137. package/dist/scripts/mad-db-route-identity-check.js +8 -6
  138. package/dist/scripts/mad-db-safety-conflict-matrix-check.js +31 -8
  139. package/dist/scripts/mad-db-skill-policy-snapshot-check.js +4 -5
  140. package/dist/scripts/naruto-real-active-pool-runtime-check.js +26 -1
  141. package/dist/scripts/ppt-real-imagegen-wiring-check.js +5 -1
  142. package/dist/scripts/proof-root-cause-policy-check.js +2 -0
  143. package/dist/scripts/release-dag-full-coverage-check.js +13 -4
  144. package/dist/scripts/release-gate-dag-runner.js +14 -0
  145. package/dist/scripts/release-gate-existence-audit.js +2 -1
  146. package/dist/scripts/release-gate-planner.js +2 -1
  147. package/dist/scripts/release-gate-script-parity-check.js +45 -17
  148. package/dist/scripts/release-metadata-1-19-check.js +2 -1
  149. package/dist/scripts/seo-geo-feature-fixture-quality-check.js +1 -1
  150. package/dist/scripts/sks-1-11-gate-lib.js +8 -6
  151. package/dist/scripts/sks-menubar-install-check.js +57 -20
  152. package/dist/scripts/ux-review-real-loop-fixture-check.js +9 -4
  153. package/dist/scripts/ux-review-run-wires-imagegen-check.js +4 -0
  154. package/dist/scripts/zellij-slot-telemetry-runtime-check.js +1 -0
  155. package/docs/assets/sneakoscope-architecture-pipeline.jpg +0 -0
  156. package/docs/demo.tape +28 -0
  157. package/package.json +31 -24
  158. package/schemas/codex/completion-proof.schema.json +3 -2
  159. package/schemas/release/release-gate-node.schema.json +2 -1
  160. package/dist/scripts/agent-backfill-route-blackbox.js +0 -5
  161. package/dist/scripts/agent-dynamic-pool-route-blackbox.js +0 -5
  162. package/dist/scripts/agent-parallel-write-blackbox.js +0 -56
  163. package/dist/scripts/agent-patch-swarm-route-blackbox.js +0 -10
  164. package/dist/scripts/agent-route-blackbox-lib.js +0 -132
  165. package/dist/scripts/blackbox-command-import-smoke.js +0 -143
  166. package/dist/scripts/blackbox-global-shim.js +0 -77
  167. package/dist/scripts/blackbox-matrix.js +0 -70
  168. package/dist/scripts/blackbox-npx-one-shot.js +0 -69
  169. package/dist/scripts/blackbox-pack-install.js +0 -174
  170. package/dist/scripts/brand-neutrality-zero-leakage-blackbox.js +0 -4
  171. package/dist/scripts/build-once-runner-blackbox.js +0 -34
  172. package/dist/scripts/codex-0140-integration-blackbox.js +0 -13
  173. package/dist/scripts/codex-agent-type-blackbox.js +0 -4
  174. package/dist/scripts/codex-app-harness-blackbox.js +0 -4
  175. package/dist/scripts/codex-app-skill-agent-blackbox.js +0 -4
  176. package/dist/scripts/codex-hook-approval-blackbox.js +0 -4
  177. package/dist/scripts/codex-init-deep-directory-local-blackbox.js +0 -4
  178. package/dist/scripts/codex-native-feature-broker-blackbox.js +0 -4
  179. package/dist/scripts/codex-native-pattern-analysis-blackbox.js +0 -4
  180. package/dist/scripts/codex-native-read-repair-split-blackbox.js +0 -55
  181. package/dist/scripts/codex-native-reference-cache-blackbox.js +0 -41
  182. package/dist/scripts/core-skill-integrity-blackbox.js +0 -32
  183. package/dist/scripts/dfix-fast-blackbox-check.js +0 -37
  184. package/dist/scripts/dfix-parallel-write-blackbox.js +0 -48
  185. package/dist/scripts/dfix-patch-swarm-route-blackbox.js +0 -10
  186. package/dist/scripts/doctor-dirty-repair-blackbox.js +0 -22
  187. package/dist/scripts/doctor-dirty-semantic-blackbox.js +0 -8
  188. package/dist/scripts/doctor-native-capability-repair-blackbox.js +0 -39
  189. package/dist/scripts/doctor-transaction-engine-blackbox.js +0 -28
  190. package/dist/scripts/doctor-zellij-fix-blackbox.js +0 -4
  191. package/dist/scripts/doctor-zellij-no-homebrew-blackbox.js +0 -4
  192. package/dist/scripts/doctor-zellij-upgrade-blackbox.js +0 -4
  193. package/dist/scripts/gate-pack-runner-blackbox.js +0 -27
  194. package/dist/scripts/gate-pack-v2-blackbox.js +0 -18
  195. package/dist/scripts/geo-cli-blackbox-check.js +0 -18
  196. package/dist/scripts/loop-collision-blackbox.js +0 -3
  197. package/dist/scripts/loop-concurrency-oversubscription-blackbox.js +0 -3
  198. package/dist/scripts/loop-fixture-production-misuse-blackbox.js +0 -3
  199. package/dist/scripts/loop-kill-interrupt-real-blackbox.js +0 -3
  200. package/dist/scripts/loop-merge-strategy-blackbox.js +0 -3
  201. package/dist/scripts/loop-mesh-production-e2e-blackbox.js +0 -3
  202. package/dist/scripts/loop-side-effect-blackbox.js +0 -3
  203. package/dist/scripts/mad-db-operation-lifecycle-blackbox.js +0 -29
  204. package/dist/scripts/mad-sks-actual-executor-blackbox.js +0 -5
  205. package/dist/scripts/mad-zellij-headless-fallback-blackbox.js +0 -4
  206. package/dist/scripts/mad-zellij-self-heal-blackbox.js +0 -4
  207. package/dist/scripts/naruto-loop-mesh-blackbox.js +0 -3
  208. package/dist/scripts/naruto-real-parallelism-blackbox.js +0 -307
  209. package/dist/scripts/naruto-worktree-coding-blackbox.js +0 -29
  210. package/dist/scripts/parallel-runtime-real-blackbox.js +0 -44
  211. package/dist/scripts/pipeline-codex-native-doctor-mad-routing-real-blackbox.js +0 -77
  212. package/dist/scripts/pipeline-codex-native-e2e-blackbox.js +0 -13
  213. package/dist/scripts/pipeline-codex-native-image-routing-real-blackbox.js +0 -50
  214. package/dist/scripts/pipeline-codex-native-loop-routing-real-blackbox.js +0 -74
  215. package/dist/scripts/pipeline-codex-native-qa-routing-real-blackbox.js +0 -51
  216. package/dist/scripts/pipeline-codex-native-research-routing-real-blackbox.js +0 -45
  217. package/dist/scripts/pipeline-execution-profile-routing-blackbox.js +0 -4
  218. package/dist/scripts/postinstall-global-doctor-blackbox.js +0 -12
  219. package/dist/scripts/ppt-full-e2e-blackbox-check.js +0 -109
  220. package/dist/scripts/ppt-imagegen-blackbox-check.js +0 -46
  221. package/dist/scripts/qa-backfill-route-blackbox.js +0 -5
  222. package/dist/scripts/qa-patch-swarm-route-blackbox.js +0 -10
  223. package/dist/scripts/release-full-parallelism-blackbox.js +0 -41
  224. package/dist/scripts/release-triwiki-first-runner-blackbox.js +0 -48
  225. package/dist/scripts/release-wiring-3110-blackbox.js +0 -27
  226. package/dist/scripts/release-wiring-3112-blackbox.js +0 -17
  227. package/dist/scripts/release-wiring-3113-blackbox.js +0 -17
  228. package/dist/scripts/research-backfill-route-blackbox.js +0 -5
  229. package/dist/scripts/research-final-reviewer-blackbox.js +0 -70
  230. package/dist/scripts/research-stage-cycle-runtime-blackbox.js +0 -40
  231. package/dist/scripts/research-synthesis-writer-blackbox.js +0 -24
  232. package/dist/scripts/route-blackbox-realism-check.js +0 -21
  233. package/dist/scripts/scheduler-resource-claim-blackbox.js +0 -24
  234. package/dist/scripts/seo-cli-blackbox-check.js +0 -18
  235. package/dist/scripts/sks-3110-all-feature-regression-blackbox.js +0 -116
  236. package/dist/scripts/sks-3112-all-feature-regression-blackbox.js +0 -29
  237. package/dist/scripts/sks-3113-all-feature-regression-blackbox.js +0 -17
  238. package/dist/scripts/sks-400-all-feature-regression-blackbox.js +0 -21
  239. package/dist/scripts/sks-400-extreme-parallel-blackbox.js +0 -8
  240. package/dist/scripts/sks-400-five-minute-blackbox.js +0 -9
  241. package/dist/scripts/sks-400-legacy-purge-blackbox.js +0 -8
  242. package/dist/scripts/sks-401-all-feature-regression-blackbox.js +0 -46
  243. package/dist/scripts/sks-401-five-minute-actual-blackbox.js +0 -23
  244. package/dist/scripts/sks-402-all-feature-regression-blackbox.js +0 -9
  245. package/dist/scripts/sks-402-five-minute-real-blackbox.js +0 -22
  246. package/dist/scripts/sksd-warm-cache-blackbox.js +0 -12
  247. package/dist/scripts/team-backfill-route-blackbox.js +0 -5
  248. package/dist/scripts/team-parallel-write-blackbox.js +0 -55
  249. package/dist/scripts/team-patch-swarm-route-blackbox.js +0 -10
  250. package/dist/scripts/triwiki-affected-graph-blackbox.js +0 -28
  251. package/dist/scripts/triwiki-proof-bank-blackbox.js +0 -30
  252. package/dist/scripts/triwiki-proof-bank-lock-blackbox.js +0 -7
  253. package/dist/scripts/ux-patch-swarm-route-blackbox.js +0 -10
  254. package/dist/scripts/ux-review-imagegen-blackbox-check.js +0 -67
  255. package/dist/scripts/zellij-initial-main-only-blackbox.js +0 -28
  256. package/dist/scripts/zellij-pane-lock-concurrency-blackbox.js +0 -80
  257. package/dist/scripts/zellij-pane-lock-open-worker-integration-blackbox.js +0 -137
  258. package/dist/scripts/zellij-self-heal-typed-blackbox.js +0 -4
  259. package/dist/scripts/zellij-slot-telemetry-real-blackbox.js +0 -20
  260. package/dist/scripts/zellij-stacked-fallback-integration-blackbox.js +0 -81
  261. package/dist/scripts/zellij-worker-pane-real-ui-blackbox.js +0 -202
package/dist/core/ppt.js CHANGED
@@ -9,6 +9,7 @@ import { buildPptStyleTokens, selectPptDesignReference } from './ppt/style-token
9
9
  export { PPT_DESIGN_REFERENCE_PROFILES, buildPptStyleTokens, selectPptDesignReference } from './ppt/style-tokens.js';
10
10
  import { buildPptHtml } from './ppt/html.js';
11
11
  export { buildPptHtml } from './ppt/html.js';
12
+ import { imageDimensions, sha256File } from './wiki-image/image-hash.js';
12
13
  export const PPT_REQUIRED_GATE_FIELDS = Object.freeze([
13
14
  'clarification_contract_sealed',
14
15
  'audience_strategy_sealed',
@@ -385,12 +386,66 @@ async function existingGeneratedImageAssets(dir, existing = {}) {
385
386
  const target = path.join(dir, asset.output_path);
386
387
  try {
387
388
  const stat = await fsp.stat(target);
388
- checked.push({ ...asset, byte_size: stat.size });
389
+ const sha = await sha256File(target);
390
+ const dims = await imageDimensions(target).catch(() => null);
391
+ const evidenceBlockers = pptImageAssetEvidenceBlockers(asset, { sha });
392
+ checked.push({
393
+ ...asset,
394
+ byte_size: stat.size,
395
+ output_sha256: asset.output_sha256 || sha,
396
+ evidence_class: asset.evidence_class || null,
397
+ output_source: asset.output_source || null,
398
+ dimensions: dims ? { width: dims.width, height: dims.height, format: dims.format } : asset.dimensions || null,
399
+ evidence_blockers: evidenceBlockers,
400
+ evidence_verified: evidenceBlockers.length === 0
401
+ });
389
402
  }
390
403
  catch { }
391
404
  }
392
405
  return checked;
393
406
  }
407
+ function pptImageAssetEvidenceBlockers(asset = {}, evidence = {}) {
408
+ const blockers = [];
409
+ const evidenceClass = String(asset.evidence_class || '');
410
+ const outputSource = String(asset.output_source || '');
411
+ const outputSha = String(asset.output_sha256 || '');
412
+ if (evidenceClass !== 'codex_app_imagegen')
413
+ blockers.push(evidenceClass ? `ppt_image_asset_evidence_class_not_codex_app:${evidenceClass}` : 'ppt_image_asset_evidence_class_missing');
414
+ if (!['manual_attach', 'auto_discovered_generated_images'].includes(outputSource))
415
+ blockers.push(`ppt_image_asset_output_source_invalid:${outputSource || 'missing'}`);
416
+ if (!outputSha)
417
+ blockers.push('ppt_image_asset_output_sha256_missing');
418
+ else if (evidence.sha && outputSha !== evidence.sha)
419
+ blockers.push('ppt_image_asset_output_sha256_mismatch');
420
+ return [...new Set(blockers)];
421
+ }
422
+ function buildPptImagegenEvidence(imageAssetLedger = {}) {
423
+ const assets = Array.isArray(imageAssetLedger.assets) ? imageAssetLedger.assets : [];
424
+ const required = imageAssetLedger.required === true;
425
+ const requiredAssets = assets.filter((asset) => asset.status === 'generated' || required);
426
+ const blockers = [
427
+ ...(imageAssetLedger.blockers || []),
428
+ ...assets.flatMap((asset) => asset.evidence_blockers || [])
429
+ ].map(String);
430
+ return {
431
+ schema: 'sks.ppt-imagegen-evidence.v1',
432
+ required,
433
+ required_count: imageAssetLedger.required_count || 0,
434
+ generated_count: imageAssetLedger.generated_count || 0,
435
+ generated_image_evidence: !required || (imageAssetLedger.generated_count || 0) >= (imageAssetLedger.required_count || 0),
436
+ assets: requiredAssets.map((asset) => ({
437
+ id: asset.id || null,
438
+ output_path: asset.output_path || null,
439
+ output_source: asset.output_source || null,
440
+ output_sha256: asset.output_sha256 || null,
441
+ evidence_class: asset.evidence_class || null,
442
+ evidence_verified: asset.evidence_verified === true,
443
+ blockers: asset.evidence_blockers || []
444
+ })),
445
+ blockers: [...new Set(blockers)],
446
+ passed: !required || ((imageAssetLedger.passed === true) && blockers.length === 0)
447
+ };
448
+ }
394
449
  export async function buildPptImageAssetLedger(dir, contract = {}, storyboard = buildPptStoryboard(contract), styleTokens = buildPptStyleTokens(contract), existing = null) {
395
450
  const required = imageAssetRequired(contract);
396
451
  const plannedAssets = planPptImageAssets(contract, storyboard, styleTokens);
@@ -400,12 +455,15 @@ export async function buildPptImageAssetLedger(dir, contract = {}, storyboard =
400
455
  const imagegenDisabled = /^(0|false|no)$/i.test(String(process.env.SKS_PPT_IMAGEGEN ?? 'auto'));
401
456
  const blockers = [];
402
457
  const generated = [...reused];
458
+ const evidenceBlockers = generated.flatMap((asset) => asset.evidence_blockers || []);
403
459
  if (pending.length > 0 && required && imagegenDisabled) {
404
460
  blockers.push('imagegen_disabled_by_SKS_PPT_IMAGEGEN');
405
461
  }
406
462
  else if (pending.length > 0 && required) {
407
463
  blockers.push('missing_codex_app_imagegen_gpt_image_2_asset_evidence');
408
464
  }
465
+ if (required)
466
+ blockers.push(...evidenceBlockers);
409
467
  const assets = [
410
468
  ...generated,
411
469
  ...pending
@@ -443,6 +501,13 @@ export async function buildPptImageAssetLedger(dir, contract = {}, storyboard =
443
501
  failed_count: 0,
444
502
  blockers,
445
503
  assets,
504
+ imagegen_evidence: buildPptImagegenEvidence({
505
+ required,
506
+ required_count: requiredCount,
507
+ generated_count: generatedCount,
508
+ blockers,
509
+ assets
510
+ }),
446
511
  passed,
447
512
  notes: [
448
513
  required
@@ -943,6 +1008,7 @@ export function defaultPptGate(contract = {}) {
943
1008
  style_tokens_created: false,
944
1009
  image_asset_ledger_created: false,
945
1010
  image_asset_policy_satisfied: false,
1011
+ imagegen_evidence: { schema: 'sks.ppt-imagegen-evidence.v1', required: false, passed: true, blockers: [] },
946
1012
  review_policy_created: false,
947
1013
  review_ledger_created: false,
948
1014
  bounded_iteration_complete: false,
@@ -1040,9 +1106,10 @@ export async function writePptBuildArtifacts(dir, contract = null) {
1040
1106
  parallel_report: async () => writeJsonAtomic(path.join(dir, PPT_PARALLEL_REPORT_ARTIFACT), parallelReport)
1041
1107
  });
1042
1108
  const baseGate = defaultPptGate(sealed);
1109
+ const imagegenEvidence = buildPptImagegenEvidence(imageAssetLedger);
1043
1110
  const gate = {
1044
1111
  ...baseGate,
1045
- passed: report.passed && imageAssetLedger.passed && reviewLedger.passed && iterationReport.passed && cleanupReport.source_html_preserved && cleanupReport.temp_cleanup_completed && parallelReport.passed,
1112
+ passed: report.passed && imageAssetLedger.passed && imagegenEvidence.passed && reviewLedger.passed && iterationReport.passed && cleanupReport.source_html_preserved && cleanupReport.temp_cleanup_completed && parallelReport.passed,
1046
1113
  audience_strategy_sealed: baseGate.audience_strategy_sealed,
1047
1114
  source_ledger_created: true,
1048
1115
  fact_ledger_created: true,
@@ -1051,6 +1118,7 @@ export async function writePptBuildArtifacts(dir, contract = null) {
1051
1118
  style_tokens_created: true,
1052
1119
  image_asset_ledger_created: true,
1053
1120
  image_asset_policy_satisfied: imageAssetLedger.passed,
1121
+ imagegen_evidence: imagegenEvidence,
1054
1122
  review_policy_created: true,
1055
1123
  review_ledger_created: true,
1056
1124
  bounded_iteration_complete: iterationReport.passed,
@@ -4,6 +4,7 @@ import { finalizeRouteWithProof } from './route-finalizer.js';
4
4
  import { routeRequiresAgentIntake } from '../agents/agent-plan.js';
5
5
  import { readAgentGateStatus } from '../agents/agent-gate.js';
6
6
  import { DEFAULT_AGENT_COUNT } from '../agents/agent-schema.js';
7
+ import { evaluateGate } from '../stop-gate/gate-evaluator.js';
7
8
  const AGENT_ARTIFACTS = [
8
9
  'agents/agent-proof-evidence.json',
9
10
  'agents/agent-sessions.json',
@@ -18,10 +19,13 @@ export async function maybeFinalizeRoute(root, { missionId, route, gateFile = nu
18
19
  return { ok: false, skipped: true, reason: 'mission_id_or_route_missing' };
19
20
  }
20
21
  const missionDir = path.join(root, '.sneakoscope', 'missions', missionId);
21
- const gateObject = gate || (gateFile && await exists(path.join(missionDir, gateFile))
22
+ const diskGateObject = gateFile && await exists(path.join(missionDir, gateFile))
22
23
  ? await readJson(path.join(missionDir, gateFile), null)
23
- : null);
24
- const passed = gateObject?.passed === true || gateObject?.ok === true || gateObject?.status === 'pass';
24
+ : null;
25
+ const gateObject = diskGateObject || gate || null;
26
+ const gateVerdict = gateFile ? await evaluateGate(root, missionId, gateFile) : null;
27
+ const callerGateMismatch = Boolean(gate && diskGateObject && stableJson(gate) !== stableJson(diskGateObject));
28
+ const passed = gateVerdict ? gateVerdict.pass && !callerGateMismatch : gateObject?.passed === true || gateObject?.ok === true || gateObject?.status === 'pass';
25
29
  const mission = await readJson(path.join(missionDir, 'mission.json'), {});
26
30
  const prompt = mission.prompt || '';
27
31
  const agentRequired = agents !== false && routeRequiresAgentIntake(route, { task: prompt, noAgents: agents === false });
@@ -30,8 +34,18 @@ export async function maybeFinalizeRoute(root, { missionId, route, gateFile = nu
30
34
  const agentGate = agentRequired ? await readAgentGateStatus(root, missionId) : null;
31
35
  const agentArtifacts = agentGate ? await existingAgentArtifacts(root, missionId) : [];
32
36
  const agentBlockers = agentRequired && agentGate?.ok !== true ? ['agent_gate_not_passed'] : [];
33
- const effectiveAgentBlockers = mock ? [] : agentBlockers;
34
- const finalStatus = statusHint || (blockers.length || effectiveAgentBlockers.length ? 'blocked' : (passed ? (mock ? 'verified_partial' : 'verified') : (mock ? 'verified_partial' : 'blocked')));
37
+ const gateBlockers = gateVerdict && !gateVerdict.pass
38
+ ? [`route_gate_${gateVerdict.verdict}`, ...gateVerdict.reasons.map((item) => `route_gate_${item}`)]
39
+ : [];
40
+ if (callerGateMismatch)
41
+ gateBlockers.push('route_gate_caller_disk_mismatch');
42
+ const computedStatus = computeAutoFinalizeStatus({
43
+ mock,
44
+ passed,
45
+ blockers: [...blockers, ...agentBlockers, ...gateBlockers]
46
+ });
47
+ const statusResolution = applyStatusHint(computedStatus, statusHint);
48
+ const finalStatus = statusResolution.status;
35
49
  const proof = await finalizeRouteWithProof(root, {
36
50
  missionId,
37
51
  route,
@@ -48,14 +62,18 @@ export async function maybeFinalizeRoute(root, { missionId, route, gateFile = nu
48
62
  ...(agentGate?.proof?.fake_backend_disclaimer ? [agentGate.proof.fake_backend_disclaimer] : []),
49
63
  ...(mock && agentBlockers.length ? [`Mock agent intake does not satisfy full production gate: ${agentBlockers.join(', ')}`] : []),
50
64
  ...(mock ? ['Route was finalized from an explicit mock/fixture command path.'] : []),
65
+ ...(gateVerdict?.verdict === 'mock_only' ? ['Route gate is mock fixture evidence and cannot satisfy a real completion gate.'] : []),
66
+ ...(statusResolution.rejected ? [`statusHint rejected: requested ${statusResolution.rejected.requested}, computed ${statusResolution.rejected.computed}.`] : []),
51
67
  ...(!passed && !mock ? ['Route gate did not pass' + (reason ? ': ' + reason : '') + '.'] : [])
52
68
  ],
53
69
  blockers: [
54
70
  ...blockers,
55
- ...effectiveAgentBlockers,
56
- ...(!passed && !mock ? ['route_gate_not_passed'] : [])
71
+ ...agentBlockers,
72
+ ...gateBlockers,
73
+ ...(!passed && !mock && !gateBlockers.length ? ['route_gate_not_passed'] : [])
57
74
  ],
58
75
  statusHint: finalStatus,
76
+ statusHintRejected: statusResolution.rejected,
59
77
  mock,
60
78
  fixClaim,
61
79
  requireRelation,
@@ -65,7 +83,7 @@ export async function maybeFinalizeRoute(root, { missionId, route, gateFile = nu
65
83
  failureAnalysis,
66
84
  lightweightEvidence
67
85
  });
68
- return { ...proof, auto_finalized: true, gate_passed: passed, status_hint: finalStatus };
86
+ return { ...proof, auto_finalized: true, gate_passed: passed, gate_verdict: gateVerdict, status_hint: finalStatus, status_hint_rejected: statusResolution.rejected };
69
87
  }
70
88
  async function existingAgentArtifacts(root, missionId) {
71
89
  const dir = path.join(root, '.sneakoscope', 'missions', missionId);
@@ -94,8 +112,9 @@ async function ensureMockAgentEvidence(root, missionId, route, prompt) {
94
112
  if (!(await exists(path.join(dir, 'agent-proof-evidence.json')))) {
95
113
  await writeJsonAtomic(path.join(dir, 'agent-proof-evidence.json'), {
96
114
  schema: 'sks.agent-proof-evidence.v1',
97
- ok: true,
98
- status: 'passed',
115
+ ok: false,
116
+ status: 'mock_fixture',
117
+ execution_class: 'mock_fixture',
99
118
  mission_id: missionId,
100
119
  route,
101
120
  backend: 'fake',
@@ -109,8 +128,48 @@ async function ensureMockAgentEvidence(root, missionId, route, prompt) {
109
128
  consensus_ok: true,
110
129
  janitor_report: 'agents/agent-janitor-report.json',
111
130
  janitor_ok: true,
112
- blockers: []
131
+ blockers: ['mock_fixture_cannot_satisfy_real_agent_gate']
113
132
  });
114
133
  }
115
134
  }
135
+ const STATUS_RANK = {
136
+ blocked: 0,
137
+ failed: 0,
138
+ not_verified: 0,
139
+ mock_only: 1,
140
+ verified_partial: 2,
141
+ verified: 3
142
+ };
143
+ function computeAutoFinalizeStatus({ mock, passed, blockers }) {
144
+ if (mock)
145
+ return 'mock_only';
146
+ if (blockers.length > 0)
147
+ return 'blocked';
148
+ return passed ? 'verified' : 'blocked';
149
+ }
150
+ function applyStatusHint(computed, requested) {
151
+ if (!requested)
152
+ return { status: computed, rejected: null };
153
+ const requestedRank = STATUS_RANK[requested];
154
+ const computedRank = STATUS_RANK[computed];
155
+ if (requestedRank === undefined || computedRank === undefined) {
156
+ return { status: computed, rejected: { requested, computed, reason: 'unknown_status_hint' } };
157
+ }
158
+ if (computed === 'mock_only' && requested !== 'mock_only') {
159
+ return { status: computed, rejected: { requested, computed, reason: 'mock_fixture_status_cap' } };
160
+ }
161
+ if (requestedRank > computedRank) {
162
+ return { status: computed, rejected: { requested, computed, reason: 'status_hint_upgrade_rejected' } };
163
+ }
164
+ return { status: requested, rejected: null };
165
+ }
166
+ function stableJson(value) {
167
+ if (Array.isArray(value))
168
+ return `[${value.map(stableJson).join(',')}]`;
169
+ if (value && typeof value === 'object') {
170
+ const record = value;
171
+ return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableJson(record[key])}`).join(',')}}`;
172
+ }
173
+ return JSON.stringify(value);
174
+ }
116
175
  //# sourceMappingURL=auto-finalize.js.map
@@ -3,6 +3,7 @@ export const COMPLETION_PROOF_SCHEMA = 'sks.completion-proof.v1';
3
3
  export const COMPLETION_PROOF_STATUSES = Object.freeze([
4
4
  'verified',
5
5
  'verified_partial',
6
+ 'mock_only',
6
7
  'blocked',
7
8
  'not_verified',
8
9
  'failed'
@@ -12,6 +13,7 @@ export function emptyCompletionProof(overrides = {}) {
12
13
  schema: COMPLETION_PROOF_SCHEMA,
13
14
  version: PACKAGE_VERSION,
14
15
  generated_at: nowIso(),
16
+ execution_class: null,
15
17
  mission_id: null,
16
18
  route: null,
17
19
  status: 'not_verified',
@@ -5,7 +5,7 @@ import { normalizeProofRoute, routeRequiresImageVoxelAnchors } from './route-pro
5
5
  import { linkProofClaimsToEvidence, proofEvidenceSummary } from '../evidence/evidence-proof-linker.js';
6
6
  import { writeTrustArtifactsForProof } from '../trust-kernel/trust-report.js';
7
7
  import { enforceRetention } from '../retention.js';
8
- export async function writeRouteCompletionProof(root, { missionId = null, route = null, status = 'verified_partial', gate = null, summary = {}, artifacts = [], evidence = {}, claims = [], unverified = [], blockers = [], failureAnalysis = null, nextHumanActions = [], lightweightEvidence = false } = {}) {
8
+ export async function writeRouteCompletionProof(root, { missionId = null, route = null, status = 'verified_partial', gate = null, summary = {}, artifacts = [], evidence = {}, claims = [], unverified = [], blockers = [], failureAnalysis = null, nextHumanActions = [], lightweightEvidence = false, executionClass = null, statusHintRejected = null } = {}) {
9
9
  const collected = lightweightEvidence ? { files: [] } : await collectProofEvidence(root);
10
10
  const normalizedRoute = normalizeProofRoute(route);
11
11
  const mergedEvidence = {
@@ -21,6 +21,7 @@ export async function writeRouteCompletionProof(root, { missionId = null, route
21
21
  unverified
22
22
  });
23
23
  const written = await writeCompletionProof(root, {
24
+ execution_class: executionClass,
24
25
  mission_id: missionId,
25
26
  route: normalizedRoute,
26
27
  status: normalizedStatus,
@@ -36,6 +37,7 @@ export async function writeRouteCompletionProof(root, { missionId = null, route
36
37
  claims,
37
38
  unverified,
38
39
  blockers,
40
+ ...(statusHintRejected ? { status_hint_rejected: statusHintRejected } : {}),
39
41
  failure_analysis: normalizeFailureAnalysis(failureAnalysis || evidence.failure_analysis || evidence.root_cause_analysis),
40
42
  next_human_actions: nextHumanActions
41
43
  }, {
@@ -88,6 +90,8 @@ function normalizeFailureAnalysis(value) {
88
90
  };
89
91
  }
90
92
  function normalizeRouteProofStatus(status, { route, evidence, blockers, unverified }) {
93
+ if (status === 'mock_only')
94
+ return 'mock_only';
91
95
  if (blockers?.length)
92
96
  return status === 'failed' ? 'failed' : 'blocked';
93
97
  if (status === 'verified' && unverified?.length)
@@ -7,7 +7,7 @@ import { wrongnessProofEvidence } from '../triwiki-wrongness/wrongness-proof-lin
7
7
  import { computerUseStatusReport } from '../computer-use-status.js';
8
8
  import { readComputerUseLiveEvidence } from '../computer-use-live-evidence.js';
9
9
  import { leanChangeEvidenceFromReport, scanCodeStructure } from '../code-structure.js';
10
- export async function finalizeRouteWithProof(root, { missionId, route, gateFile = null, gate = null, artifacts = [], visualEvidence = null, dbEvidence = null, madSksEvidence = null, testEvidence = null, commandEvidence = null, claims = [], unverified = [], blockers = [], statusHint = 'verified_partial', strict = false, mock = false, fixClaim = false, requireRelation = false, visualClaim = undefined, agents = undefined, allowActiveWrongnessPartial = false, failureAnalysis = null, lightweightEvidence = false } = {}) {
10
+ export async function finalizeRouteWithProof(root, { missionId, route, gateFile = null, gate = null, artifacts = [], visualEvidence = null, dbEvidence = null, madSksEvidence = null, testEvidence = null, commandEvidence = null, claims = [], unverified = [], blockers = [], statusHint = 'verified_partial', strict = false, mock = false, fixClaim = false, requireRelation = false, visualClaim = undefined, agents = undefined, allowActiveWrongnessPartial = false, failureAnalysis = null, lightweightEvidence = false, statusHintRejected = null } = {}) {
11
11
  const policy = routeFinalizerPolicy(route, { strict, fixClaim, requireRelation, visualClaim });
12
12
  const localBlockers = [...blockers];
13
13
  const providedVisualEvidence = visualEvidence;
@@ -68,10 +68,11 @@ export async function finalizeRouteWithProof(root, { missionId, route, gateFile
68
68
  || !computerUseLive?.evidence
69
69
  || computerUseLive.evidence.mode !== 'live_capture_success'
70
70
  || computerUseLive.evidence.image_voxel?.linked !== true));
71
- const status = localBlockers.length
72
- ? (strict ? 'blocked' : statusHint === 'verified' ? 'verified_partial' : statusHint)
73
- : visualComputerUseDowngrade ? 'verified_partial'
74
- : statusHint;
71
+ const status = mock ? 'mock_only'
72
+ : localBlockers.length
73
+ ? (strict ? 'blocked' : statusHint === 'verified' ? 'verified_partial' : statusHint)
74
+ : visualComputerUseDowngrade ? 'verified_partial'
75
+ : statusHint;
75
76
  const finalUnverified = [
76
77
  ...unverified,
77
78
  ...(imageEvidence?.mock ? ['Image voxel evidence is mock fixture evidence and does not claim a real visual run.'] : []),
@@ -138,6 +139,8 @@ export async function finalizeRouteWithProof(root, { missionId, route, gateFile
138
139
  blockers: localBlockers,
139
140
  failureAnalysis: resolvedFailureAnalysis,
140
141
  lightweightEvidence,
142
+ executionClass: mock ? 'mock_fixture' : 'real',
143
+ statusHintRejected,
141
144
  summary: {
142
145
  files_changed: collected.files?.length || 0,
143
146
  commands_run: evidence.commands?.length || 0,
@@ -26,20 +26,33 @@ export async function writeSelftestRouteProof(root, { missionId, route = '$Team'
26
26
  return writeRouteCompletionProof(root, {
27
27
  missionId,
28
28
  route,
29
- status: 'verified_partial',
30
- gate: { passed: true, source: gateSource || defaults.gateSource },
29
+ status: 'mock_only',
30
+ executionClass: 'mock_fixture',
31
+ gate: {
32
+ passed: false,
33
+ ok: false,
34
+ execution_class: 'mock_fixture',
35
+ source: gateSource || defaults.gateSource,
36
+ blockers: ['selftest_fixture_cannot_claim_real_route_completion']
37
+ },
31
38
  summary: { selftest: true, tests_passed: 1, manual_review_required: true },
32
39
  artifacts: artifacts || defaults.artifacts,
33
40
  evidence: {
34
- route_gate: { passed: true },
35
- commands: [{ cmd: 'sks selftest --mock', status: 'verified_partial' }]
41
+ route_gate: {
42
+ passed: false,
43
+ ok: false,
44
+ execution_class: 'mock_fixture',
45
+ blockers: ['selftest_fixture_cannot_claim_real_route_completion']
46
+ },
47
+ commands: [{ cmd: 'sks selftest --mock', status: 'mock_only' }]
36
48
  },
37
49
  claims: [{
38
50
  id: `selftest-${kind.replaceAll('_', '-')}-proof`,
39
51
  text: CLAIM_TEXT[kind] || CLAIM_TEXT.team_gate,
40
52
  status: 'verified_partial'
41
53
  }],
42
- unverified: unverified || defaults.unverified
54
+ unverified: unverified || defaults.unverified,
55
+ blockers: ['selftest_fixture_cannot_claim_real_route_completion']
43
56
  });
44
57
  }
45
58
  //# sourceMappingURL=selftest-proof-fixtures.js.map
@@ -10,6 +10,8 @@ export function validateCompletionProof(proof = {}) {
10
10
  issues.push('schema');
11
11
  if (!COMPLETION_PROOF_STATUSES.includes(String(record.status)))
12
12
  issues.push('status');
13
+ if (!['real', 'mock_fixture'].includes(String(record.execution_class)))
14
+ issues.push('execution_class');
13
15
  if (!record.summary || typeof record.summary !== 'object')
14
16
  issues.push('summary');
15
17
  if (!record.evidence || typeof record.evidence !== 'object')
@@ -0,0 +1,53 @@
1
+ const CHAINS = {
2
+ quick: [
3
+ { model: 'gpt-5.4-mini', reasoning: 'low', serviceTier: 'fast' },
4
+ { model: 'gpt-5.5', reasoning: 'low', serviceTier: 'fast' }
5
+ ],
6
+ standard: [
7
+ { model: 'gpt-5.5', reasoning: 'medium', serviceTier: 'fast' }
8
+ ],
9
+ agentic: [
10
+ { model: 'gpt-5.3-codex', reasoning: 'high', serviceTier: 'fast' },
11
+ { model: 'gpt-5.5', reasoning: 'high', serviceTier: 'fast' }
12
+ ],
13
+ ultrabrain: [
14
+ { model: 'gpt-5.5', reasoning: 'xhigh', serviceTier: 'standard' }
15
+ ],
16
+ verify: [
17
+ { model: 'gpt-5.4-mini', reasoning: 'medium', serviceTier: 'fast' }
18
+ ],
19
+ review: [
20
+ { model: 'gpt-5.5', reasoning: 'high', serviceTier: 'fast' }
21
+ ]
22
+ };
23
+ export async function routeModel(category, opts = {}) {
24
+ const chain = CHAINS[category] || CHAINS.standard;
25
+ const degraded = new Set((opts.lbHealth?.degraded_models || []).map((model) => String(model)));
26
+ for (const choice of chain) {
27
+ if (degraded.has(choice.model))
28
+ continue;
29
+ if (opts.lbHealth?.quota_low && choice.reasoning === 'xhigh')
30
+ return { ...choice, reasoning: 'high' };
31
+ return choice;
32
+ }
33
+ return chain[chain.length - 1] ?? CHAINS.standard[0];
34
+ }
35
+ export function categoryForWorkerRole(role) {
36
+ const text = String(role || '').toLowerCase();
37
+ if (/verif|test|qa/.test(text))
38
+ return 'verify';
39
+ if (/review|critic|judge/.test(text))
40
+ return 'review';
41
+ if (/research|explore|read|scout/.test(text))
42
+ return 'quick';
43
+ if (/plan|architect|strategy/.test(text))
44
+ return 'ultrabrain';
45
+ return 'agentic';
46
+ }
47
+ export function modelRouteReason(category, choice, opts = {}) {
48
+ if (opts.explicit)
49
+ return `${category}->${choice.model} (explicit env override)`;
50
+ const suffix = opts.quotaLow ? 'quota discipline' : opts.degraded?.length ? 'lb degraded fallback' : 'quota discipline';
51
+ return `${category}->${choice.model} (${suffix})`;
52
+ }
53
+ //# sourceMappingURL=model-router.js.map
@@ -16,6 +16,7 @@ export const RELEASE_GATE_RESOURCE_CLASSES = [
16
16
  'global-config',
17
17
  'publish',
18
18
  'fs-read',
19
+ 'fs-write',
19
20
  'timing-sensitive'
20
21
  ];
21
22
  export function validateReleaseGateManifest(input) {
@@ -47,6 +48,8 @@ export function validateReleaseGateManifest(input) {
47
48
  errors.push(`gate_side_effect_invalid:${gate?.id || 'unknown'}`);
48
49
  if (!Number.isFinite(Number(gate?.timeout_ms)) || Number(gate.timeout_ms) <= 0)
49
50
  errors.push(`gate_timeout_missing:${gate?.id || 'unknown'}`);
51
+ if (gate?.output_contract !== undefined && gate.output_contract !== 'sks.gate-result.v1')
52
+ errors.push(`gate_output_contract_invalid:${gate?.id || 'unknown'}`);
50
53
  if (!gate?.cache || typeof gate.cache.enabled !== 'boolean' || !Array.isArray(gate.cache.inputs))
51
54
  errors.push(`gate_cache_missing:${gate?.id || 'unknown'}`);
52
55
  if (!gate?.isolation || gate.isolation.report_dir !== 'per-gate')
@@ -19,6 +19,7 @@ export function defaultReleaseGateBudget() {
19
19
  'global-config': 1,
20
20
  publish: 1,
21
21
  'fs-read': Math.min(96, cores * 10),
22
+ 'fs-write': Math.min(12, Math.max(1, cores)),
22
23
  'timing-sensitive': 1
23
24
  };
24
25
  for (const key of Object.keys(base)) {
@@ -9,7 +9,7 @@ export const FROM_CHAT_IMG_CHECKLIST_ARTIFACT = 'from-chat-img-checklist.md';
9
9
  export const FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT = 'from-chat-img-temp-triwiki.json';
10
10
  export const FROM_CHAT_IMG_QA_LOOP_ARTIFACT = 'from-chat-img-qa-loop.json';
11
11
  export const FROM_CHAT_IMG_TEMP_TRIWIKI_SESSIONS = 5;
12
- export const USAGE_TOPICS = 'install|setup|bootstrap|root|deps|zellij|tmux|auto-review|team|qa-loop|ppt|image-ux-review|computer-use|goal|fast-mode|research|seo-geo-optimizer|db|git|codex|codex-app|codex-native|hooks|features|all-features|dfix|commit|commit-and-push|design|imagegen|dollar|context7|insane-search|ultra-search|xai|pipeline|reasoning|guard|conflicts|versioning|eval|harness|hproof|gx|wiki|wrongness|code-structure|proof-field|skill-dream|rust';
12
+ export const USAGE_TOPICS = 'install|setup|bootstrap|root|deps|zellij|tmux|auto-review|team|qa-loop|ppt|image-ux-review|computer-use|goal|fast-mode|review|ui|research|seo-geo-optimizer|db|git|codex|codex-app|codex-native|hooks|features|all-features|dfix|commit|commit-and-push|design|imagegen|dollar|context7|insane-search|ultra-search|xai|pipeline|reasoning|guard|conflicts|versioning|eval|harness|hproof|gx|wiki|memory|wrongness|code-structure|proof-field|skill-dream|rust';
13
13
  export const RECOMMENDED_MCP_SERVERS = [
14
14
  {
15
15
  id: 'context7',