sneakoscope 6.0.2 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/README.md +5 -3
  2. package/config/codex-releases/{rust-v0.142.0.json → rust-v0.144.1.json} +6 -6
  3. package/crates/sks-core/Cargo.lock +1 -1
  4. package/crates/sks-core/Cargo.toml +1 -1
  5. package/dist/cli/install-helpers.js +255 -440
  6. package/dist/cli/router.js +53 -4
  7. package/dist/commands/codex-app.js +8 -3
  8. package/dist/commands/codex-lb.js +169 -40
  9. package/dist/commands/codex.js +6 -5
  10. package/dist/commands/doctor.js +60 -26
  11. package/dist/commands/versioning.js +7 -0
  12. package/dist/config/skills-manifest.json +57 -57
  13. package/dist/core/agents/agent-central-ledger.js +9 -0
  14. package/dist/core/agents/agent-cleanup-executor.js +334 -41
  15. package/dist/core/agents/agent-cleanup.js +20 -1
  16. package/dist/core/agents/agent-command-surface.js +2 -1
  17. package/dist/core/agents/agent-effort-policy.js +46 -33
  18. package/dist/core/agents/agent-janitor.js +9 -10
  19. package/dist/core/agents/agent-namespace-safety.js +56 -0
  20. package/dist/core/agents/agent-orchestrator.js +26 -4
  21. package/dist/core/agents/agent-output-validator.js +1 -1
  22. package/dist/core/agents/agent-proof-evidence.js +16 -2
  23. package/dist/core/agents/agent-role-config.js +3 -6
  24. package/dist/core/agents/agent-roster.js +2 -2
  25. package/dist/core/agents/agent-runner-codex-exec.js +2 -0
  26. package/dist/core/agents/agent-runner-process.js +1 -0
  27. package/dist/core/agents/fast-mode-policy.js +3 -5
  28. package/dist/core/agents/native-cli-session-swarm.js +18 -1
  29. package/dist/core/agents/native-worker-backend-router.js +180 -108
  30. package/dist/core/agents/parallel-write-fixture.js +15 -10
  31. package/dist/core/agents/runtime-proof-summary.js +21 -3
  32. package/dist/core/agents/work-partition/repo-inventory.js +68 -7
  33. package/dist/core/code-structure.js +5 -4
  34. package/dist/core/codex/codex-config-guard.js +31 -9
  35. package/dist/core/codex-app/codex-app-fast-ui-repair.js +51 -20
  36. package/dist/core/codex-app/codex-app-restart.js +38 -8
  37. package/dist/core/codex-app/codex-app-ui-state-snapshot.js +11 -3
  38. package/dist/core/codex-app/sks-menubar.js +100 -40
  39. package/dist/core/codex-app.js +60 -17
  40. package/dist/core/codex-compat/codex-hook-warning-detector.js +10 -1
  41. package/dist/core/codex-compat/codex-release-manifest.js +6 -6
  42. package/dist/core/codex-control/codex-0139-doctor-real-probe.js +7 -1
  43. package/dist/core/codex-control/codex-0139-image-path-real-probe.js +14 -8
  44. package/dist/core/codex-control/codex-0139-probe-runner.js +103 -28
  45. package/dist/core/codex-control/codex-0139-real-probe-summary.js +7 -3
  46. package/dist/core/codex-control/codex-0139-real-probes.js +21 -6
  47. package/dist/core/codex-control/codex-0139-sandbox-real-probe.js +39 -13
  48. package/dist/core/codex-control/codex-0139-web-search-probe.js +11 -8
  49. package/dist/core/codex-control/{codex-0142-capability.js → codex-0144-capability.js} +22 -22
  50. package/dist/core/codex-control/codex-0144-collab-agent-real-probe.js +63 -0
  51. package/dist/core/codex-control/codex-model-metadata.js +8 -4
  52. package/dist/core/codex-control/codex-multi-agent-event-normalizer.js +5 -1
  53. package/dist/core/codex-control/codex-reliability-shield.js +4 -1
  54. package/dist/core/codex-control/codex-sdk-adapter.js +53 -6
  55. package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
  56. package/dist/core/codex-control/codex-sdk-sandbox-policy.js +6 -3
  57. package/dist/core/codex-lb/codex-lb-env.js +107 -0
  58. package/dist/core/codex-lb/codex-lb-tool-catalog.js +478 -0
  59. package/dist/core/codex-native/codex-native-feature-broker.js +22 -22
  60. package/dist/core/codex-native/codex-native-feature-matrix.js +2 -2
  61. package/dist/core/codex-native/native-capability-postcheck.js +16 -8
  62. package/dist/core/codex-native/native-capability-repair-matrix.js +76 -27
  63. package/dist/core/codex-plugins/codex-plugin-json.js +67 -21
  64. package/dist/core/codex-plugins/codex-plugin-repair.js +118 -0
  65. package/dist/core/codex-runtime/codex-desktop-config-policy.js +306 -0
  66. package/dist/core/commands/agent-command.js +19 -0
  67. package/dist/core/commands/basic-cli.js +45 -24
  68. package/dist/core/commands/gc-command.js +27 -4
  69. package/dist/core/commands/image-ux-review-command.js +55 -24
  70. package/dist/core/commands/mad-sks-command.js +152 -132
  71. package/dist/core/commands/naruto-command.js +41 -10
  72. package/dist/core/commands/pipeline-command.js +1 -0
  73. package/dist/core/commands/wiki-command.js +179 -83
  74. package/dist/core/computer-use-live-evidence.js +166 -3
  75. package/dist/core/computer-use-status.js +5 -2
  76. package/dist/core/daemon/sksd-hook-daemon-entrypoint.js +2 -2
  77. package/dist/core/daemon/sksd-hook-daemon.js +171 -28
  78. package/dist/core/daemon/sksd-hook-dispatch.js +2 -2
  79. package/dist/core/dfix/verification-selector.js +6 -4
  80. package/dist/core/doctor/browser-use-repair.js +54 -13
  81. package/dist/core/doctor/codex-0139-doctor.js +3 -2
  82. package/dist/core/doctor/computer-use-repair.js +28 -39
  83. package/dist/core/doctor/doctor-codex-startup-repair.js +19 -9
  84. package/dist/core/doctor/doctor-context7-repair.js +1 -1
  85. package/dist/core/doctor/doctor-dirty-planner.js +1 -1
  86. package/dist/core/doctor/doctor-native-capability-repair.js +74 -3
  87. package/dist/core/doctor/imagegen-repair.js +47 -12
  88. package/dist/core/doctor/legacy-global-hook-cleanup.js +179 -0
  89. package/dist/core/feature-registry.js +25 -31
  90. package/dist/core/fsx.js +54 -6
  91. package/dist/core/harness-conflicts.js +1 -1
  92. package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +5 -4
  93. package/dist/core/hooks-runtime/hook-invocation-dedupe.js +147 -0
  94. package/dist/core/hooks-runtime/hook-io.js +6 -0
  95. package/dist/core/hooks-runtime.js +17 -2
  96. package/dist/core/image/image-artifact-path-contract.js +8 -6
  97. package/dist/core/image/image-artifact-registry.js +5 -1
  98. package/dist/core/image-ux-review/imagegen-adapter.js +5 -2
  99. package/dist/core/imagegen/imagegen-capability.js +10 -13
  100. package/dist/core/imagegen/require-imagegen.js +37 -11
  101. package/dist/core/managed-assets/managed-assets-manifest.js +1 -5
  102. package/dist/core/naruto/naruto-work-graph.js +70 -4
  103. package/dist/core/naruto/naruto-write-e2e.js +3 -4
  104. package/dist/core/ops/reporting.js +3 -0
  105. package/dist/core/pipeline-internals/runtime-core.js +12 -7
  106. package/dist/core/pipeline-internals/runtime-gates.js +17 -1
  107. package/dist/core/ppt/style-tokens.js +1 -1
  108. package/dist/core/ppt-review/index.js +1 -1
  109. package/dist/core/ppt-review/slide-exporter.js +23 -17
  110. package/dist/core/ppt-review/slide-imagegen-review.js +1 -1
  111. package/dist/core/ppt-review/slide-issue-extraction.js +4 -2
  112. package/dist/core/product-design-plugin.js +2 -2
  113. package/dist/core/proof/route-finalizer.js +1 -1
  114. package/dist/core/proof-field.js +3 -3
  115. package/dist/core/provider/model-router.js +68 -3
  116. package/dist/core/release/gate-manifest.js +18 -12
  117. package/dist/core/release/gate-pack-manifest.js +1 -1
  118. package/dist/core/release/package-size-budget.js +2 -0
  119. package/dist/core/release/release-gate-affected-selector.js +1 -1
  120. package/dist/core/release/release-gate-dag.js +43 -3
  121. package/dist/core/release/release-gate-hermetic-env.js +28 -17
  122. package/dist/core/release/release-real-contract.js +416 -0
  123. package/dist/core/retention/retention-budget.js +25 -6
  124. package/dist/core/retention.js +980 -101
  125. package/dist/core/routes/constants.js +1 -1
  126. package/dist/core/routes/evidence.js +4 -4
  127. package/dist/core/routes/model-mode-router.js +3 -0
  128. package/dist/core/routes/ppt-policy.js +1 -1
  129. package/dist/core/routes.js +11 -12
  130. package/dist/core/secret-redaction.js +4 -0
  131. package/dist/core/triwiki/code-pack.js +8 -2
  132. package/dist/core/triwiki/triwiki-cache-key.js +108 -29
  133. package/dist/core/triwiki-attention.js +13 -6
  134. package/dist/core/triwiki-provenance.js +274 -0
  135. package/dist/core/triwiki-runtime.js +21 -7
  136. package/dist/core/triwiki-wrongness/wrongness-ledger.js +178 -59
  137. package/dist/core/triwiki-wrongness/wrongness-retrieval.js +11 -2
  138. package/dist/core/triwiki-wrongness/wrongness-trust-policy.js +2 -0
  139. package/dist/core/update/update-migration-state.js +1 -1
  140. package/dist/core/update/update-notice.js +23 -0
  141. package/dist/core/update-check.js +69 -25
  142. package/dist/core/version.js +1 -1
  143. package/dist/core/wiki-coordinate.js +128 -12
  144. package/dist/core/work-order-ledger.js +168 -9
  145. package/dist/core/zellij/zellij-command.js +12 -1
  146. package/dist/core/zellij/zellij-dashboard-pane.js +3 -3
  147. package/dist/core/zellij/zellij-launcher.js +15 -14
  148. package/dist/core/zellij/zellij-pane-proof.js +32 -6
  149. package/dist/core/zellij/zellij-worker-pane-manager.js +5 -3
  150. package/dist/scripts/agent-fast-mode-default-check.js +48 -29
  151. package/dist/scripts/agent-role-config-repair-check.js +25 -4
  152. package/dist/scripts/agent-wiki-context-proof-check.js +16 -2
  153. package/dist/scripts/all-feature-deep-completion-check.js +14 -4
  154. package/dist/scripts/build-dist.js +17 -5
  155. package/dist/scripts/canonical-test-runner.js +188 -0
  156. package/dist/scripts/check-command-module-budget.js +38 -16
  157. package/dist/scripts/check-legacy-free.js +1 -1
  158. package/dist/scripts/codex-0139-interrupt-agent-check.js +5 -1
  159. package/dist/scripts/{codex-0142-app-server-v2-check.js → codex-0144-app-server-v2-check.js} +11 -10
  160. package/dist/scripts/{codex-0142-binary-identity-check.js → codex-0144-binary-identity-check.js} +4 -4
  161. package/dist/scripts/codex-0144-capability-check.js +21 -0
  162. package/dist/scripts/{codex-0139-real-probes-check.js → codex-0144-core-real-probes-check.js} +19 -5
  163. package/dist/scripts/{codex-0142-doctor-wiring-check.js → codex-0144-doctor-wiring-check.js} +6 -6
  164. package/dist/scripts/{codex-0142-manifest-check.js → codex-0144-manifest-check.js} +11 -3
  165. package/dist/scripts/{codex-0142-policy-check.js → codex-0144-policy-check.js} +2 -2
  166. package/dist/scripts/{codex-0142-thread-store-check.js → codex-0144-thread-store-check.js} +3 -3
  167. package/dist/scripts/codex-app-provider-model-ui-check.js +57 -8
  168. package/dist/scripts/codex-app-ui-preservation-check.js +35 -4
  169. package/dist/scripts/codex-control-side-effect-scope-check.js +2 -2
  170. package/dist/scripts/codex-effort-auto-discovery-check.js +1 -1
  171. package/dist/scripts/codex-lb-fast-mode-truth-check.js +1 -0
  172. package/dist/scripts/{codex-lb-gpt55-fast-profile-check.js → codex-lb-gpt56-fast-profile-check.js} +56 -5
  173. package/dist/scripts/codex-model-metadata-check.js +1 -1
  174. package/dist/scripts/codex-sdk-sandbox-policy-check.js +5 -1
  175. package/dist/scripts/codex-sdk-version-compat-check.js +2 -1
  176. package/dist/scripts/dfix-fixture-check.js +1 -1
  177. package/dist/scripts/docs-truthfulness-check.js +1 -1
  178. package/dist/scripts/doctor-codex-startup-repair-check.js +35 -10
  179. package/dist/scripts/doctor-context7-repair-check.js +2 -1
  180. package/dist/scripts/doctor-fix-proves-codex-read-check.js +1 -1
  181. package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +34 -7
  182. package/dist/scripts/doctor-imagegen-repair-check.js +14 -4
  183. package/dist/scripts/doctor-startup-config-repair-blackbox.js +1 -1
  184. package/dist/scripts/doctor-startup-config-repair-check.js +1 -1
  185. package/dist/scripts/gate-policy-audit-check.js +2 -2
  186. package/dist/scripts/install-update-preserves-config-check.js +1 -1
  187. package/dist/scripts/legacy-gate-inventory-check.js +7 -5
  188. package/dist/scripts/legacy-strong-inventory-check.js +7 -5
  189. package/dist/scripts/legacy-upgrade-matrix-check.js +5 -5
  190. package/dist/scripts/lib/native-cli-session-swarm-check-lib.js +175 -14
  191. package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +166 -6
  192. package/dist/scripts/mutation-callsite-coverage-check.js +0 -11
  193. package/dist/scripts/naruto-shadow-clone-swarm-check.js +88 -50
  194. package/dist/scripts/npm-publish-performance-check.js +2 -1
  195. package/dist/scripts/package-published-contract-check.js +9 -0
  196. package/dist/scripts/packlist-performance-check.js +5 -2
  197. package/dist/scripts/postinstall-safe-side-effects-check.js +8 -3
  198. package/dist/scripts/ppt-no-mock-as-real-check.js +3 -1
  199. package/dist/scripts/product-design-plugin-routing-check.js +1 -1
  200. package/dist/scripts/release-check-stamp.js +182 -2
  201. package/dist/scripts/release-dag-full-coverage-check.js +7 -7
  202. package/dist/scripts/release-dynamic-presets-check.js +8 -0
  203. package/dist/scripts/release-gate-dag-runner-check.js +3 -2
  204. package/dist/scripts/release-gate-dag-runner.js +24 -11
  205. package/dist/scripts/release-gate-existence-audit.js +8 -9
  206. package/dist/scripts/release-gate-script-parity-check.js +1 -1
  207. package/dist/scripts/release-real-check.js +368 -157
  208. package/dist/scripts/release-runtime-truth-matrix-check.js +22 -0
  209. package/dist/scripts/route-proof-artifact-structure-check.js +1 -0
  210. package/dist/scripts/scheduler-batch-dispatch-check.js +1 -1
  211. package/dist/scripts/search-visibility-gate-lib.js +1 -1
  212. package/dist/scripts/seo-geo-route-identity-check.js +30 -4
  213. package/dist/scripts/sizecheck.js +7 -2
  214. package/dist/scripts/sks-1-11-gate-lib.js +53 -6
  215. package/dist/scripts/sks-menubar-install-check.js +7 -0
  216. package/dist/scripts/sks-uninstall-regression-check.js +1 -1
  217. package/dist/scripts/sksd-daemon-check.js +16 -6
  218. package/dist/scripts/update-default-command-check.js +4 -2
  219. package/dist/scripts/write-build-manifest.js +2 -1
  220. package/dist/scripts/zellij-layout-valid-check.js +31 -6
  221. package/dist/scripts/zellij-pane-proof-check.js +33 -2
  222. package/dist/scripts/zellij-real-session-cleanup-check.js +122 -2
  223. package/dist/scripts/zellij-real-session-launch-check.js +76 -5
  224. package/dist/scripts/zellij-slot-pane-renderer-check.js +4 -4
  225. package/package.json +27 -30
  226. package/schemas/codex/{app-server-0.142 → app-server-0.144}/codex_app_server_protocol.v2.schemas.json +1146 -781
  227. package/schemas/codex/codex-0139-real-probe-result.schema.json +39 -5
  228. package/schemas/codex/ppt-slide-issue-ledger.schema.json +2 -1
  229. package/dist/core/codex-control/codex-0139-multi-agent-real-probe.js +0 -107
  230. package/dist/scripts/agent-native-release-gate.js +0 -274
  231. package/dist/scripts/codex-0142-capability-check.js +0 -21
  232. package/dist/scripts/command-performance-scorecard-check.js +0 -204
  233. package/dist/scripts/config-managed-merge-callsite-coverage-check.js +0 -212
  234. package/dist/scripts/dollar-performance-scorecard-check.js +0 -257
  235. package/dist/scripts/gate-timing-check.js +0 -16
  236. package/dist/scripts/ops-maturity-scorecard-check.js +0 -12
  237. package/dist/scripts/performance-baseline-check.js +0 -12
  238. package/dist/scripts/performance-improvement-report-check.js +0 -58
  239. package/dist/scripts/release-parallel-check.js +0 -389
  240. package/dist/scripts/release-runner-efficiency-check.js +0 -15
  241. package/dist/scripts/retention-long-run-smoke-check.js +0 -299
  242. package/docs/assets/sneakoscope-architecture-pipeline.jpg +0 -0
@@ -47,5 +47,5 @@ export const RECOMMENDED_SKILLS = [
47
47
  // Route-level effort names are scheduling intents, not model compatibility
48
48
  // claims. Actual per-model options come from Codex runtime metadata; SKS never
49
49
  // derives them from a model slug.
50
- export const ALLOWED_REASONING_EFFORTS = new Set(['low', 'medium', 'high', 'xhigh', 'ultra']);
50
+ export const ALLOWED_REASONING_EFFORTS = new Set(['low', 'medium', 'high', 'xhigh', 'max', 'ultra']);
51
51
  //# sourceMappingURL=constants.js.map
@@ -3,12 +3,12 @@ export const CODEX_IN_APP_BROWSER_EVIDENCE_SOURCE = 'codex_in_app_browser';
3
3
  export const CODEX_CHROME_EXTENSION_EVIDENCE_SOURCE = 'codex_chrome_extension';
4
4
  export const CODEX_WEB_VERIFICATION_EVIDENCE_SOURCE = CODEX_IN_APP_BROWSER_EVIDENCE_SOURCE;
5
5
  export const CODEX_IMAGEGEN_EVIDENCE_SOURCE = 'codex_app_imagegen_gpt_image_2';
6
- export const CODEX_IN_APP_BROWSER_DOC_URL = 'https://developers.openai.com/codex/app/browser';
7
- export const CODEX_CHROME_EXTENSION_DOC_URL = 'https://developers.openai.com/codex/app/chrome-extension';
8
- export const CODEX_COMPUTER_USE_DOC_URL = 'https://developers.openai.com/codex/app/computer-use';
6
+ export const CODEX_IN_APP_BROWSER_DOC_URL = 'https://learn.chatgpt.com/docs/browser';
7
+ export const CODEX_CHROME_EXTENSION_DOC_URL = 'https://learn.chatgpt.com/docs/chrome-extension';
8
+ export const CODEX_COMPUTER_USE_DOC_URL = 'https://learn.chatgpt.com/docs/computer-use';
9
9
  export const CODEX_RECORD_REPLAY_DOC_URL = 'https://developers.openai.com/codex/record-and-replay';
10
10
  export const CODEX_APP_SERVER_DOC_URL = 'https://developers.openai.com/codex/app-server';
11
- export const CODEX_APP_IMAGE_GENERATION_DOC_URL = 'https://developers.openai.com/codex/app/features#image-generation';
11
+ export const CODEX_APP_IMAGE_GENERATION_DOC_URL = 'https://learn.chatgpt.com/docs/image-generation';
12
12
  export const OPENAI_IMAGE_GENERATION_DOC_URL = 'https://developers.openai.com/api/docs/guides/image-generation';
13
13
  export const OPENAI_CHATGPT_IMAGES_2_DOC_URL = 'https://openai.com/index/introducing-chatgpt-images-2-0/';
14
14
  export const OPENAI_GPT_IMAGE_2_MODEL_DOC_URL = 'https://developers.openai.com/api/docs/models/gpt-image-2';
@@ -3,6 +3,9 @@ export function resolveSksModelMode(args = []) {
3
3
  const hasGlm = normalized.includes('--glm');
4
4
  const hasMad = normalized.includes('--mad') || normalized.includes('--MAD') || normalized.includes('--mad-sks');
5
5
  const hasNaruto = normalized.includes('--naruto') || normalized.includes('naruto');
6
+ if (hasGlm && hasNaruto && !hasMad) {
7
+ return decision('classic-naruto', false, true, 'naruto_command_glm_override_forbidden', normalized);
8
+ }
6
9
  if (hasGlm && hasNaruto) {
7
10
  return decision('glm-naruto', true, false, 'explicit_--glm_with_naruto', normalized);
8
11
  }
@@ -21,6 +21,6 @@ export function pptPipelineAllowlistPolicyText() {
21
21
  const conditionalSkills = PPT_CONDITIONAL_SKILL_ALLOWLIST.length
22
22
  ? PPT_CONDITIONAL_SKILL_ALLOWLIST.map((entry) => `${entry.skill}=${entry.condition}`).join('; ')
23
23
  : 'none';
24
- return `PPT pipeline allowlist: during $PPT design/render work, ignore installed skills and MCPs that are not explicitly part of the $PPT pipeline. The purpose is to prevent AI-like generic presentation design: decorative gradients, nested cards, vague SaaS visuals, and style choices not grounded in the audience, source material, Product Design plugin evidence, getdesign fallback reference, or the project design cache. Required SKS skills are ${PPT_PIPELINE_SKILL_ALLOWLIST.join(', ')}. Product Design plugin tools are allowed and preferred for design work: ${PRODUCT_DESIGN_PLUGIN_TOOL_ALLOWLIST.join(', ')}. Use ${PRODUCT_DESIGN_PLUGIN.id} first for get-context/user-context intake, research/ideate exploration, prototype/image-to-code/url-to-code artifact direction, audit/design-qa review, and share handoff when available. The imagegen skill is required for $PPT so Codex App can invoke official built-in $imagegen/gpt-image-2 for every generated raster asset or generated visual-review image; do not route PPT imagery through direct API fallback. Do not use generic design skills such as ${PRODUCT_DESIGN_LEGACY_DESIGN_FALLBACK_SKILLS.join(', ')} for $PPT just because they are installed. $PPT design must use Product Design plugin first; if unavailable, use getdesign-reference plus the built-in PPT design implementation pipeline: existing ${DESIGN_SYSTEM_SSOT.authority_file} when present, ${DESIGN_SYSTEM_SSOT.builder_prompt} as fallback builder prompt when missing, and route-local ppt-style-tokens.json as the fused design projection. Conditional skills/MCPs are allowed only when their condition is sealed in the contract: ${conditionalSkills}; ${PPT_PIPELINE_MCP_ALLOWLIST.map((entry) => `${entry.mcp}=${entry.condition}`).join('; ')}. Fact, image, and review evidence are first-class artifacts: gather user-provided context and required web/Context7 evidence into ppt-fact-ledger.json, block unsupported critical claims, plan required image resources through ppt-image-asset-ledger.json, then run a bounded review loop recorded in ppt-review-policy.json, ppt-review-ledger.json, and ppt-iteration-report.json. Required raster asset or generated visual-review evidence must come from Codex App $imagegen/gpt-image-2; direct API fallback, placeholder files, and prose-only substitutes do not satisfy the route gate. The review loop caps full-deck passes at 2, slide retries at 2, requires P0/P1 issue count to be zero, targets score >= 0.88, and stops when improvement delta is below 0.03 or evidence is missing. For Codex App visual critique, invoke $imagegen/gpt-image-2 (${CODEX_APP_IMAGE_GENERATION_DOC_URL}) when required; never simulate missing gpt-image-2 output. If required image-review evidence is unavailable, record the blocker instead of passing the gate. ${productDesignPluginPolicyText()} ${CODEX_IMAGEGEN_REQUIRED_POLICY}`;
24
+ return `PPT pipeline allowlist: during $PPT design/render work, ignore installed skills and MCPs that are not explicitly part of the $PPT pipeline. The purpose is to prevent AI-like generic presentation design: decorative gradients, nested cards, vague SaaS visuals, and style choices not grounded in the audience, source material, Product Design plugin evidence, getdesign fallback reference, or the project design cache. Required SKS skills are ${PPT_PIPELINE_SKILL_ALLOWLIST.join(', ')}. Product Design plugin tools are allowed and preferred for design work: ${PRODUCT_DESIGN_PLUGIN_TOOL_ALLOWLIST.join(', ')}. Use ${PRODUCT_DESIGN_PLUGIN.id} first for get-context/user-context intake, research/ideate exploration, index/image-to-code/url-to-code artifact direction, audit/design-qa review, and share handoff when available. The imagegen skill is required for $PPT so Codex App can invoke official built-in $imagegen/gpt-image-2 for every generated raster asset or generated visual-review image; do not route PPT imagery through direct API fallback. Do not use generic design skills such as ${PRODUCT_DESIGN_LEGACY_DESIGN_FALLBACK_SKILLS.join(', ')} for $PPT just because they are installed. $PPT design must use Product Design plugin first; if unavailable, use getdesign-reference plus the built-in PPT design implementation pipeline: existing ${DESIGN_SYSTEM_SSOT.authority_file} when present, ${DESIGN_SYSTEM_SSOT.builder_prompt} as fallback builder prompt when missing, and route-local ppt-style-tokens.json as the fused design projection. Conditional skills/MCPs are allowed only when their condition is sealed in the contract: ${conditionalSkills}; ${PPT_PIPELINE_MCP_ALLOWLIST.map((entry) => `${entry.mcp}=${entry.condition}`).join('; ')}. Fact, image, and review evidence are first-class artifacts: gather user-provided context and required web/Context7 evidence into ppt-fact-ledger.json, block unsupported critical claims, plan required image resources through ppt-image-asset-ledger.json, then run a bounded review loop recorded in ppt-review-policy.json, ppt-review-ledger.json, and ppt-iteration-report.json. Required raster asset or generated visual-review evidence must come from Codex App $imagegen/gpt-image-2; direct API fallback, placeholder files, and prose-only substitutes do not satisfy the route gate. The review loop caps full-deck passes at 2, slide retries at 2, requires P0/P1 issue count to be zero, targets score >= 0.88, and stops when improvement delta is below 0.03 or evidence is missing. For Codex App visual critique, invoke $imagegen/gpt-image-2 (${CODEX_APP_IMAGE_GENERATION_DOC_URL}) when required; never simulate missing gpt-image-2 output. If required image-review evidence is unavailable, record the blocker instead of passing the gate. ${productDesignPluginPolicyText()} ${CODEX_IMAGEGEN_REQUIRED_POLICY}`;
25
25
  }
26
26
  //# sourceMappingURL=ppt-policy.js.map
@@ -611,7 +611,7 @@ export const COMMAND_CATALOG = [
611
611
  { name: 'update', usage: 'sks update [check|now] [--version <version>] [--json] [--dry-run]', description: 'Check npm for the latest SKS release and update the global package by default; use `check` for status-only.' },
612
612
  { name: 'uninstall', usage: 'sks uninstall [--dry-run] [--yes] [--keep-config] [--keep-data] [--purge-projects] [--json]', description: 'Remove SKS global skills, hooks, menu bar, state, temp files, and optional project residue while preserving user-owned content by default.' },
613
613
  { name: 'deps', usage: 'sks deps check [--json] [--yes]', description: 'Check Node/npm, Codex CLI, and Zellij readiness; pass --yes to repair missing Codex CLI/Zellij tooling when supported.' },
614
- { name: 'codex', usage: 'sks codex compatibility|version|doctor|schema|0.142 [--json]', description: 'Check Codex CLI rust-v0.142.0 compatibility, installed version, 0.142 manifest/capability evidence, inherited legacy baselines, and vendored hook schema snapshot freshness.' },
614
+ { name: 'codex', usage: 'sks codex compatibility|version|doctor|schema|0.144 [--json]', description: 'Check Codex CLI rust-v0.144.1 compatibility, installed version, current manifest/capability evidence, inherited historical baselines, and vendored hook schema snapshot freshness.' },
615
615
  { name: 'codex-app', usage: 'sks codex-app [check|glm-profile install|set-openrouter-key --api-key-stdin|product-design|chrome-extension|pat status|remote-control]', description: 'Check Codex App install, GLM/OpenRouter model profile visibility, codex-lb key-entry guidance, Product Design plugin readiness, Codex Chrome Extension web verification readiness, PAT-safe status, first-party MCP/plugin readiness, and Codex CLI 0.130.0+ remote-control availability.' },
616
616
  { name: 'codex-native', usage: 'sks codex-native status|feature-broker|invocation-plan|init-deep [--json]', description: 'Inspect Codex Native feature broker readiness, invocation routing, pattern evidence, and managed memory setup.' },
617
617
  { name: 'hooks', usage: 'sks hooks explain|status|trust-report|replay|codex-validate|warning-check ... [--json]', description: 'Explain Codex hook events, validate vendored latest 10-event output schemas, replay fixtures, and enforce warning-zero SKS hook policies under the 0.134 compatibility matrix.' },
@@ -636,7 +636,7 @@ export const COMMAND_CATALOG = [
636
636
  { name: 'recallpulse', usage: 'sks recallpulse run|status|eval|governance|checklist <mission-id|latest>', description: 'Run report-only RecallPulse active recall, durable status, proof capsule, evidence envelope, and governance checks.' },
637
637
  { name: 'pipeline', usage: 'sks pipeline status|resume|plan|answer ...', description: 'Inspect the active skill-first route, materialized execution plan, ambiguity gates, and completion gates.' },
638
638
  { name: 'guard', usage: 'sks guard check [--json]', description: 'Check SKS harness self-protection lock, fingerprints, and source-repo exception state.' },
639
- { name: 'conflicts', usage: 'sks conflicts check|prompt [--json]', description: 'Detect other Codex harnesses such as OMX/DCodex and print the GPT-5.5 high cleanup prompt.' },
639
+ { name: 'conflicts', usage: 'sks conflicts check|prompt [--json]', description: 'Detect other Codex harnesses such as OMX/DCodex and print the GPT-5.6 high cleanup prompt.' },
640
640
  { name: 'versioning', usage: 'sks versioning status|bump|disable [--json]', description: 'Manage explicit project version syncs; SKS does not install Git pre-commit hooks.' },
641
641
  { name: 'features', usage: 'sks features list|check|inventory [--json] [--write-docs]', description: 'Build and validate the feature registry that maps CLI commands, hidden handlers, dollar routes, app skill aliases, and skills.' },
642
642
  { name: 'all-features', usage: 'sks all-features selftest --mock [--json]', description: 'Run the mock all-features contract selftest for feature registry, proof, Voxel TriWiki, and failure-contract coverage.' },
@@ -655,7 +655,7 @@ export const COMMAND_CATALOG = [
655
655
  { name: 'db', usage: 'sks db policy|scan|mcp-config|classify|check ...', description: 'Inspect and enforce database/Supabase safety policy.' },
656
656
  { name: 'eval', usage: 'sks eval run|compare|thresholds ...', description: 'Run deterministic context-quality and performance evidence checks.' },
657
657
  { name: 'harness', usage: 'sks harness fixture|review [--json]', description: 'Run Harness Growth Factory fixtures for forgetting, skills, experiments, tool taxonomy, permissions, MultiAgentV2, and Zellij views.' },
658
- { name: 'perf', usage: 'sks perf run|workflow|cold-start [--json] [--iterations N]', description: 'Measure structured GPT-5.5/SKS performance budgets, including cold-start, Proof Field workflow decisions, and fast-lane evidence.' },
658
+ { name: 'perf', usage: 'sks perf run|workflow|cold-start [--json] [--iterations N]', description: 'Measure structured GPT-5.6/SKS performance budgets, including cold-start, Proof Field workflow decisions, and fast-lane evidence.' },
659
659
  { name: 'bench', usage: 'sks bench core|route-fixtures|blackbox|trust-kernel [--json]', description: 'Measure core trust-kernel hot paths and write performance budget artifacts.' },
660
660
  { name: 'proof', usage: 'sks proof show|latest|validate|export|smoke [--json|--md]', description: 'Show, validate, export, or smoke-write the unified Completion Proof Engine surface.' },
661
661
  { name: 'trust', usage: 'sks trust report|validate|status|explain [latest|mission-id] [--json]', description: 'Validate route contracts, evidence indexes, stale/mock evidence, and trust report blockers.' },
@@ -1129,6 +1129,7 @@ export function subagentExecutionPolicyText(route, prompt = '') {
1129
1129
  'Native multi-session policy: REQUIRED for code-changing or execution work in this route.',
1130
1130
  'The selected SKS route itself authorizes route-owned worker/reviewer native sessions; the user does not need to separately ask for helper sessions when the default Naruto pipeline is active.',
1131
1131
  'Before editing, the parent orchestrator must visibly state the SKS route, split independent write scopes, and run worker/reviewer native sessions whenever the route can be split safely.',
1132
+ 'Determine native tool availability from the callable tool manifest in the current turn and from actual call results. If functions.exec or functions.collaboration.spawn_agent is exposed, use it; never report those tools unavailable because an obsolete CLI alias is missing.',
1132
1133
  'Run workers in parallel only with disjoint ownership. The parent owns integration, verification, and final evidence.',
1133
1134
  'If native sessions are unavailable or the work cannot be safely split, record explicit unavailable/unsplittable native-session evidence before editing.',
1134
1135
  noUnrequestedFallbackCodePolicyText()
@@ -1162,19 +1163,17 @@ export function routeReasoning(route, prompt = '') {
1162
1163
  return reasoning('medium', 'simple_fulfillment');
1163
1164
  }
1164
1165
  function narutoRouteReasoning(text = '') {
1165
- if (/(frontier|autoresearch|novelty|hypothesis|falsify|forensic|from-chat-img|가설|포렌식)/i.test(text))
1166
- return reasoning('xhigh', 'naruto_research_or_forensic_signal');
1167
- if (/(research|current docs?|library|framework|sdk|api|database|supabase|sql|migration|security|permission|mad|release|publish|deploy|commit|push|architecture|algorithm|리서치|문서|데이터베이스|마이그레이션|보안|권한|배포|커밋|푸쉬)/i.test(text))
1168
- return reasoning('high', 'naruto_knowledge_safety_or_release_signal');
1169
- if (/(tmux|zellij|terminal|cli|cmd|warp|tool(?:\s|-)?call|hook|router|routing|pipeline|multi[-\s]?pane|pane|process|config|터미널|라우팅|파이프라인|훅|도구|툴)/i.test(text))
1170
- return reasoning('medium', 'naruto_tooling_or_runtime_signal');
1171
- if (/(tiny|simple|small|one[-\s]?line|typo|copy|label|spacing|rename|text|readme|docs?|간단|단순|오타|문구|라벨|간격|색상)/i.test(text))
1172
- return reasoning('low', 'naruto_simple_bounded_work_signal');
1173
- return reasoning('medium', 'naruto_default_balanced_reasoning');
1166
+ if (/(frontier|autoresearch|novelty|hypothesis|falsify|forensic|from-chat-img|research|current docs?|library|framework|sdk|api|database|supabase|sql|migration|security|permission|mad|release|publish|deploy|commit|push|architecture|algorithm|strategy|planning|integration|refactor|가설|포렌식|리서치|문서|데이터베이스|마이그레이션|보안|권한|배포|커밋|푸쉬|전략|기획|통합|리팩터)/i.test(text))
1167
+ return reasoning('max', 'naruto_complex_or_high_risk_signal');
1168
+ return reasoning('xhigh', 'naruto_gpt56_baseline');
1174
1169
  }
1175
1170
  export function reasoningProfileName(effort) {
1176
1171
  if (effort === 'low')
1177
1172
  return 'sks-task-low';
1173
+ if (effort === 'ultra')
1174
+ return 'sks-research-ultra';
1175
+ if (effort === 'max')
1176
+ return 'sks-research-max';
1178
1177
  if (effort === 'xhigh')
1179
1178
  return 'sks-research-xhigh';
1180
1179
  if (effort === 'high')
@@ -17,6 +17,9 @@ const SECRET_PATTERNS = [
17
17
  /\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,
18
18
  /\bghp_[A-Za-z0-9_]{20,}\b/g,
19
19
  /\bBearer\s+[A-Za-z0-9._~+/=-]{16,}\b/gi,
20
+ /\bAuthorization\s*:\s*[^\r\n,}]+/gi,
21
+ /\b(?:Cookie|Set-Cookie)\s*:\s*[^\r\n,}]+/gi,
22
+ /\b[A-Za-z0-9-]+-Auth\s*:\s*[^\r\n,}]+/gi,
20
23
  /\b(?:access[_-]?token|api[_-]?key|secret|password|token)\s*[:=]\s*["']?[A-Za-z0-9._~+/=-]{12,}["']?/gi
21
24
  ];
22
25
  export const REDACTION_MARKER = '[redacted]';
@@ -62,6 +65,7 @@ export function containsPlaintextSecret(value, env = process.env) {
62
65
  }
63
66
  function secretKeyName(key = '') {
64
67
  return /(?:access[_-]?token|api[_-]?key|secret|password|token)$/i.test(String(key || ''))
68
+ || /(?:^|[_-])(?:auth|authorization|headers?|cookies?|bearer|credentials?|env)$/i.test(String(key || ''))
65
69
  || SECRET_ENV_NAMES.includes(String(key || '').toUpperCase());
66
70
  }
67
71
  function redactKeyValue(match) {
@@ -14,14 +14,20 @@ export function codePackPrevPath(root) {
14
14
  return path.join(codePackDir(root), 'code-pack.prev.json');
15
15
  }
16
16
  export function buildCodePack(root, index, tokenBudget = DEFAULT_CODE_PACK_TOKEN_BUDGET) {
17
+ const normalizedBudget = Number.isFinite(tokenBudget) && tokenBudget >= 0
18
+ ? Math.floor(tokenBudget)
19
+ : DEFAULT_CODE_PACK_TOKEN_BUDGET;
17
20
  const entries = [];
21
+ let totalTokenCost = 0;
18
22
  for (const card of index.modules) {
19
23
  const entry = buildEntryForModule(card);
20
24
  if (!entry)
21
25
  continue;
26
+ if (totalTokenCost + entry.token_cost > normalizedBudget)
27
+ continue;
22
28
  entries.push(entry);
29
+ totalTokenCost += entry.token_cost;
23
30
  }
24
- const totalTokenCost = entries.reduce((sum, entry) => sum + entry.token_cost, 0);
25
31
  return {
26
32
  schema: CODE_PACK_SCHEMA,
27
33
  generated_at: nowIso(),
@@ -29,7 +35,7 @@ export function buildCodePack(root, index, tokenBudget = DEFAULT_CODE_PACK_TOKEN
29
35
  source_file_count: index.scanned_file_count,
30
36
  index_digest: computeIndexDigest(index),
31
37
  entries,
32
- token_budget: tokenBudget,
38
+ token_budget: normalizedBudget,
33
39
  total_token_cost: totalTokenCost
34
40
  };
35
41
  }
@@ -9,7 +9,11 @@ const DEFAULT_EXCLUDED_DIRS = new Set([
9
9
  '.sneakoscope/reports',
10
10
  '.sneakoscope/missions',
11
11
  '.sneakoscope/quarantine',
12
- 'dist'
12
+ 'dist',
13
+ '.claude',
14
+ '.cache',
15
+ 'coverage',
16
+ 'build'
13
17
  ]);
14
18
  export function computeTriWikiCacheKey(input) {
15
19
  const root = path.resolve(input.root);
@@ -69,7 +73,12 @@ export function collectInputFiles(root, patterns) {
69
73
  unsupported.push(`unsupported_brace_glob:${pattern}`);
70
74
  continue;
71
75
  }
72
- const matches = expandInputPattern(root, pattern);
76
+ const normalized = normalizePattern(pattern);
77
+ if (!isSafeRelativePattern(root, normalized)) {
78
+ unsupported.push(`outside_root_or_unsafe_input:${pattern}`);
79
+ continue;
80
+ }
81
+ const matches = expandInputPattern(root, normalized);
73
82
  if (!matches.length) {
74
83
  const literal = path.resolve(root, pattern);
75
84
  if (fs.existsSync(literal))
@@ -87,44 +96,75 @@ export function collectInputFiles(root, patterns) {
87
96
  const hashed = hashPathIfPresent(root, rel);
88
97
  if (hashed.missing.length)
89
98
  missing.push(rel);
99
+ else if (hashed.unsupported?.length)
100
+ unsupported.push(...hashed.unsupported);
90
101
  else if (hashed.record)
91
102
  records.push(hashed.record);
92
103
  }
93
104
  return { records, missing: [...new Set(missing)].sort(), unsupported: [...new Set(unsupported)].sort() };
94
105
  }
95
- function expandInputPattern(root, pattern) {
96
- const normalized = normalizePattern(pattern);
106
+ function expandInputPattern(root, normalized) {
97
107
  if (!normalized.includes('*')) {
98
108
  const absolute = path.resolve(root, normalized);
99
- if (!fs.existsSync(absolute))
109
+ if (!fs.existsSync(absolute) || !safeInputPath(root, absolute, true))
100
110
  return [];
101
111
  return listFiles(root, absolute);
102
112
  }
103
113
  const regex = globToRegex(normalized);
104
- return listFiles(root, root).filter((rel) => regex.test(rel));
114
+ const prefix = staticGlobPrefix(normalized);
115
+ const start = path.resolve(root, prefix || '.');
116
+ if (!isWithinRoot(root, start) || !safeInputPath(root, start, false))
117
+ return [];
118
+ return listFiles(root, start).filter((rel) => regex.test(rel));
105
119
  }
106
120
  function normalizePattern(pattern) {
107
121
  return pattern.replace(/\\/g, '/').replace(/^\.\//, '');
108
122
  }
109
123
  function globToRegex(pattern) {
110
- const escaped = pattern
111
- .split('')
112
- .map((char) => {
113
- if (char === '*')
114
- return '*';
115
- return /[\\^$+?.()|{}[\]]/.test(char) ? `\\${char}` : char;
116
- })
117
- .join('');
118
- const regex = escaped
119
- .replace(/\*\*\//g, '(?:.*/)?')
120
- .replace(/\*\*/g, '.*')
121
- .replace(/\*/g, '[^/]*');
122
- return new RegExp(`^${regex}$`);
124
+ let regex = '^';
125
+ for (let index = 0; index < pattern.length; index += 1) {
126
+ const char = pattern[index] || '';
127
+ if (char === '*' && pattern[index + 1] === '*') {
128
+ if (pattern[index + 2] === '/') {
129
+ regex += '(?:.*/)?';
130
+ index += 2;
131
+ }
132
+ else {
133
+ regex += '.*';
134
+ index += 1;
135
+ }
136
+ continue;
137
+ }
138
+ if (char === '*') {
139
+ regex += '[^/]*';
140
+ continue;
141
+ }
142
+ regex += /[\\^$+?.()|{}[\]]/.test(char) ? `\\${char}` : char;
143
+ }
144
+ return new RegExp(`${regex}$`);
145
+ }
146
+ function staticGlobPrefix(pattern) {
147
+ const segments = pattern.split('/');
148
+ const fixed = segments.slice(0, segments.findIndex((segment) => segment.includes('*')) < 0
149
+ ? segments.length
150
+ : segments.findIndex((segment) => segment.includes('*')));
151
+ return fixed.join('/');
152
+ }
153
+ function isSafeRelativePattern(root, pattern) {
154
+ if (!pattern || path.isAbsolute(pattern) || pattern === '..' || pattern.startsWith('../'))
155
+ return false;
156
+ return isWithinRoot(root, path.resolve(root, pattern.replace(/\*.*$/, '')));
157
+ }
158
+ function isWithinRoot(root, candidate) {
159
+ const relative = path.relative(path.resolve(root), path.resolve(candidate));
160
+ return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
123
161
  }
124
162
  function listFiles(root, start) {
125
163
  const out = [];
126
164
  if (!fs.existsSync(start))
127
165
  return out;
166
+ if (!safeInputPath(root, start, true))
167
+ return out;
128
168
  let stat;
129
169
  try {
130
170
  stat = fs.lstatSync(start);
@@ -174,6 +214,9 @@ function isMissingOrInaccessible(error) {
174
214
  return code === 'ENOENT' || code === 'EACCES' || code === 'ENOTDIR' || code === 'EPERM';
175
215
  }
176
216
  function isExcluded(rel) {
217
+ const segments = normalizePattern(rel).split('/');
218
+ if (segments.some((segment) => segment === 'node_modules' || segment === '.git' || segment === '.claude' || segment === '.cache'))
219
+ return true;
177
220
  for (const dir of DEFAULT_EXCLUDED_DIRS) {
178
221
  if (rel === dir || rel.startsWith(`${dir}/`))
179
222
  return true;
@@ -182,8 +225,12 @@ function isExcluded(rel) {
182
225
  }
183
226
  function hashPathIfPresent(root, rel) {
184
227
  const absolute = path.resolve(root, rel);
228
+ if (!isWithinRoot(root, absolute))
229
+ return { hash: 'unsupported', missing: [], unsupported: [`outside_root:${rel}`] };
185
230
  if (!fs.existsSync(absolute))
186
231
  return { hash: 'missing', missing: [rel] };
232
+ if (!safeInputPath(root, absolute, true))
233
+ return { hash: 'unsupported', missing: [], unsupported: [`symlink_escape_or_unsafe_input:${rel}`] };
187
234
  const stat = fs.lstatSync(absolute);
188
235
  const mode = stat.isSymbolicLink() ? 'symlink' : stat.isDirectory() ? 'dir' : 'file';
189
236
  if (stat.isDirectory()) {
@@ -198,25 +245,57 @@ function hashPathIfPresent(root, rel) {
198
245
  const hash = hashJson({ rel, target, mode, outside_root: outsideRoot });
199
246
  return { hash, missing: [], record: { path: normalizePattern(rel), hash, size: target.length, mode } };
200
247
  }
248
+ if (!stat.isFile())
249
+ return { hash: 'unsupported', missing: [], unsupported: [`non_regular_input:${rel}`] };
201
250
  const hash = hashFileChunked(absolute, stat.size);
202
251
  return { hash, missing: [], record: { path: normalizePattern(rel), hash, size: stat.size, mode } };
203
252
  }
253
+ function safeInputPath(root, candidate, allowFinalSymlink) {
254
+ const resolvedRoot = path.resolve(root);
255
+ const resolvedCandidate = path.resolve(candidate);
256
+ if (!isWithinRoot(resolvedRoot, resolvedCandidate))
257
+ return false;
258
+ const relative = path.relative(resolvedRoot, resolvedCandidate);
259
+ const segments = relative ? relative.split(path.sep).filter(Boolean) : [];
260
+ let cursor = resolvedRoot;
261
+ for (let index = 0; index < segments.length; index += 1) {
262
+ cursor = path.join(cursor, segments[index]);
263
+ let stat;
264
+ try {
265
+ stat = fs.lstatSync(cursor);
266
+ }
267
+ catch (error) {
268
+ return false;
269
+ }
270
+ if (stat.isSymbolicLink() && !(allowFinalSymlink && index === segments.length - 1))
271
+ return false;
272
+ }
273
+ try {
274
+ const finalStat = fs.lstatSync(resolvedCandidate);
275
+ if (finalStat.isSymbolicLink() && allowFinalSymlink)
276
+ return true;
277
+ const realRoot = fs.realpathSync(resolvedRoot);
278
+ const realCandidate = fs.realpathSync(resolvedCandidate);
279
+ return isWithinRoot(realRoot, realCandidate);
280
+ }
281
+ catch (error) {
282
+ return false;
283
+ }
284
+ }
204
285
  function hashFileChunked(file, size) {
205
286
  const h = crypto.createHash('sha256');
206
287
  h.update(`size:${size}:`);
207
288
  const chunk = 256 * 1024;
208
289
  const fd = fs.openSync(file, 'r');
209
290
  try {
210
- if (size <= chunk * 3) {
211
- h.update(fs.readFileSync(file));
212
- }
213
- else {
214
- for (const offset of [0, Math.max(0, Math.floor(size / 2) - Math.floor(chunk / 2)), Math.max(0, size - chunk)]) {
215
- const buffer = Buffer.alloc(chunk);
216
- const read = fs.readSync(fd, buffer, 0, chunk, offset);
217
- h.update(`@${offset}:`);
218
- h.update(buffer.subarray(0, read));
219
- }
291
+ const buffer = Buffer.allocUnsafe(chunk);
292
+ let offset = 0;
293
+ while (offset < size) {
294
+ const read = fs.readSync(fd, buffer, 0, Math.min(buffer.length, size - offset), offset);
295
+ if (read <= 0)
296
+ break;
297
+ h.update(buffer.subarray(0, read));
298
+ offset += read;
220
299
  }
221
300
  }
222
301
  finally {
@@ -229,8 +229,10 @@ function uniqueAttentionRows(rows = [], max = 4) {
229
229
  * independent of the policy-claim RGBA/geometric selection above: code entries carry
230
230
  * no meaningful mission-coordinate proximity, so competing them against policy claims
231
231
  * for the same fixed slot budget would make their appearance arbitrary. Each surviving
232
- * entry becomes a use_first row (bare id, no fabricated RGBA) plus a hydrate_first row
233
- * pointing at its source citations, so a consumer knows which real files back it. */
232
+ * high-trust, clean entry becomes a use_first row (bare id, no fabricated RGBA).
233
+ * Lower-trust or wrongness-linked entries are hydrate-only so negative evidence can
234
+ * never be promoted into the high-trust fast path. Citation-backed hydrate rows tell
235
+ * consumers which real files must be read before relying on a summary. */
234
236
  function codePackAttentionRows(codePackEntries = [], tokenBudget = 2000, wrongnessByModule = {}) {
235
237
  const moduleWrongness = (entryId) => Number(wrongnessByModule[String(entryId || '').replace(/^code:/, '')] || 0);
236
238
  const sorted = [...(codePackEntries || [])]
@@ -245,13 +247,18 @@ function codePackAttentionRows(codePackEntries = [], tokenBudget = 2000, wrongne
245
247
  if (tokens + cost > tokenBudget)
246
248
  continue;
247
249
  tokens += cost;
248
- useFirst.push([entry.id, null, null]);
249
250
  const citationPaths = Array.isArray(entry.citations) ? entry.citations.map((c) => c?.path).filter(Boolean) : [];
250
251
  const citationReason = citationPaths.length ? `code_citations:${citationPaths.join(',')}` : null;
251
252
  const wrongCount = moduleWrongness(entry.id);
252
- // A module with past wrongness earns a hydrate row even without citations, tagged
253
- // with a wrongness:<count> signal so a consumer re-reads it before trusting recall.
254
- const reason = wrongCount > 0 ? `wrongness:${wrongCount}${citationReason ? `;${citationReason}` : ''}` : citationReason;
253
+ const action = trustAction(entry);
254
+ if (action === 'use' && wrongCount === 0)
255
+ useFirst.push([entry.id, null, null]);
256
+ const reasons = [
257
+ wrongCount > 0 ? `wrongness:${wrongCount}` : null,
258
+ action !== 'use' ? `trust_action:${action}` : null,
259
+ citationReason
260
+ ].filter(Boolean);
261
+ const reason = reasons.join(';');
255
262
  if (reason)
256
263
  hydrateFirst.push([entry.id, reason]);
257
264
  }