sneakoscope 6.0.3 → 6.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 (378) hide show
  1. package/README.md +29 -12
  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/bin/fast-inline.js +18 -14
  6. package/dist/bin/sks-dispatch.js +2 -4
  7. package/dist/cli/args.js +2 -0
  8. package/dist/cli/command-manifest-lite.js +2 -3
  9. package/dist/cli/command-registry.js +3 -4
  10. package/dist/cli/help-fast.js +1 -1
  11. package/dist/cli/install-helpers.js +348 -763
  12. package/dist/cli/install-tool-helpers.js +287 -0
  13. package/dist/cli/router.js +91 -6
  14. package/dist/commands/codex-lb.js +188 -53
  15. package/dist/commands/codex.js +44 -5
  16. package/dist/commands/doctor.js +302 -46
  17. package/dist/commands/tmux.js +5 -1
  18. package/dist/commands/versioning.js +7 -0
  19. package/dist/commands/zellij-monitor-pane.js +2 -0
  20. package/dist/commands/zellij-viewport-pane.js +3 -1
  21. package/dist/commands/zellij.js +1 -1
  22. package/dist/config/skills-manifest.json +59 -59
  23. package/dist/core/agent-bridge/agent-manifest.js +48 -0
  24. package/dist/core/agents/agent-central-ledger.js +9 -0
  25. package/dist/core/agents/agent-cleanup-executor.js +334 -41
  26. package/dist/core/agents/agent-cleanup.js +20 -1
  27. package/dist/core/agents/agent-command-surface.js +3 -1
  28. package/dist/core/agents/agent-effort-policy.js +30 -38
  29. package/dist/core/agents/agent-janitor.js +9 -10
  30. package/dist/core/agents/agent-namespace-safety.js +56 -0
  31. package/dist/core/agents/agent-orchestrator.js +25 -3
  32. package/dist/core/agents/agent-output-validator.js +1 -1
  33. package/dist/core/agents/agent-plan.js +100 -21
  34. package/dist/core/agents/agent-role-config.js +43 -49
  35. package/dist/core/agents/agent-runner-codex-exec.js +18 -3
  36. package/dist/core/agents/agent-runner-process.js +1 -0
  37. package/dist/core/agents/agent-schema.js +3 -2
  38. package/dist/core/agents/fast-mode-policy.js +3 -5
  39. package/dist/core/agents/native-cli-session-swarm.js +1 -1
  40. package/dist/core/agents/native-worker-backend-router.js +2 -1
  41. package/dist/core/agents/work-partition/repo-inventory.js +68 -7
  42. package/dist/core/agents/zellij-right-lane-cockpit.js +2 -2
  43. package/dist/core/code-structure.js +5 -4
  44. package/dist/core/codex/agent-config-file-repair.js +94 -193
  45. package/dist/core/codex/codex-cli-update.js +723 -0
  46. package/dist/core/codex/codex-config-guard.js +38 -11
  47. package/dist/core/codex/codex-project-config-policy.js +3 -6
  48. package/dist/core/codex/codex-startup-config-postcheck.js +52 -42
  49. package/dist/core/codex-adapter.js +35 -22
  50. package/dist/core/codex-app/codex-agent-role-sync.js +13 -54
  51. package/dist/core/codex-app/codex-app-fast-ui-repair.js +51 -20
  52. package/dist/core/codex-app/codex-app-launcher.js +48 -17
  53. package/dist/core/codex-app/codex-app-restart.js +23 -2
  54. package/dist/core/codex-app/codex-app-ui-state-snapshot.js +11 -3
  55. package/dist/core/codex-app/sks-menubar.js +136 -5
  56. package/dist/core/codex-app.js +35 -14
  57. package/dist/core/codex-compat/codex-hook-warning-detector.js +10 -1
  58. package/dist/core/codex-compat/codex-release-manifest.js +6 -6
  59. package/dist/core/codex-control/codex-0139-doctor-real-probe.js +7 -1
  60. package/dist/core/codex-control/codex-0139-image-path-real-probe.js +29 -12
  61. package/dist/core/codex-control/codex-0139-probe-runner.js +103 -28
  62. package/dist/core/codex-control/codex-0139-real-probe-summary.js +7 -3
  63. package/dist/core/codex-control/codex-0139-real-probes.js +21 -6
  64. package/dist/core/codex-control/codex-0139-sandbox-real-probe.js +39 -13
  65. package/dist/core/codex-control/codex-0139-web-search-probe.js +28 -14
  66. package/dist/core/codex-control/{codex-0142-capability.js → codex-0144-capability.js} +22 -22
  67. package/dist/core/codex-control/codex-0144-collab-agent-real-probe.js +63 -0
  68. package/dist/core/codex-control/codex-lb-launch-recovery.js +278 -0
  69. package/dist/core/codex-control/codex-multi-agent-event-normalizer.js +5 -1
  70. package/dist/core/codex-control/codex-reliability-shield.js +93 -30
  71. package/dist/core/codex-control/codex-sdk-adapter.js +96 -13
  72. package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
  73. package/dist/core/codex-control/codex-sdk-sandbox-policy.js +6 -3
  74. package/dist/core/codex-control/codex-task-runner.js +62 -9
  75. package/dist/core/codex-control/python-codex-sdk-adapter.js +30 -3
  76. package/dist/core/codex-exec-output-schema.js +35 -6
  77. package/dist/core/codex-lb/codex-lb-env.js +30 -1
  78. package/dist/core/codex-lb/codex-lb-tool-catalog.js +478 -0
  79. package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +291 -0
  80. package/dist/core/codex-native/codex-native-feature-broker.js +31 -38
  81. package/dist/core/codex-native/codex-native-feature-matrix.js +2 -2
  82. package/dist/core/codex-native/codex-native-repair-transaction.js +1 -1
  83. package/dist/core/codex-native/core-skill-manifest.js +8 -4
  84. package/dist/core/codex-native/native-capability-postcheck.js +16 -8
  85. package/dist/core/codex-native/native-capability-repair-matrix.js +76 -27
  86. package/dist/core/codex-plugins/codex-plugin-json.js +67 -21
  87. package/dist/core/codex-plugins/codex-plugin-repair.js +118 -0
  88. package/dist/core/codex-runtime/codex-desktop-config-policy.js +305 -0
  89. package/dist/core/commands/agent-bridge-command.js +23 -2
  90. package/dist/core/commands/agent-command.js +38 -5
  91. package/dist/core/commands/basic-cli.js +77 -30
  92. package/dist/core/commands/command-utils.js +1 -1
  93. package/dist/core/commands/gc-command.js +27 -4
  94. package/dist/core/commands/image-ux-review-command.js +55 -24
  95. package/dist/core/commands/mad-sks-command.js +182 -137
  96. package/dist/core/commands/naruto-command.js +643 -1153
  97. package/dist/core/commands/pipeline-command.js +1 -0
  98. package/dist/core/commands/research-command.js +293 -231
  99. package/dist/core/commands/run-command.js +100 -23
  100. package/dist/core/commands/team-command.js +2 -3
  101. package/dist/core/commands/team-legacy-observe-command.js +94 -359
  102. package/dist/core/commands/wiki-command.js +179 -83
  103. package/dist/core/computer-use-live-evidence.js +166 -3
  104. package/dist/core/computer-use-status.js +5 -2
  105. package/dist/core/daemon/sksd-hook-daemon-entrypoint.js +2 -2
  106. package/dist/core/daemon/sksd-hook-daemon.js +171 -28
  107. package/dist/core/daemon/sksd-hook-dispatch.js +2 -2
  108. package/dist/core/db-safety.js +2 -2
  109. package/dist/core/decision-lattice.js +6 -6
  110. package/dist/core/dfix/verification-selector.js +6 -4
  111. package/dist/core/doctor/browser-use-repair.js +54 -13
  112. package/dist/core/doctor/codex-0139-doctor.js +3 -2
  113. package/dist/core/doctor/codex-startup-config-repair.js +8 -3
  114. package/dist/core/doctor/computer-use-repair.js +28 -39
  115. package/dist/core/doctor/doctor-codex-startup-repair.js +24 -149
  116. package/dist/core/doctor/doctor-context7-repair.js +1 -1
  117. package/dist/core/doctor/doctor-dirty-planner.js +1 -1
  118. package/dist/core/doctor/doctor-native-capability-repair.js +74 -3
  119. package/dist/core/doctor/imagegen-repair.js +47 -12
  120. package/dist/core/doctor/legacy-global-hook-cleanup.js +179 -0
  121. package/dist/core/feature-fixture-executor.js +71 -7
  122. package/dist/core/feature-fixture-runner.js +53 -12
  123. package/dist/core/feature-fixtures.js +47 -14
  124. package/dist/core/feature-registry.js +53 -58
  125. package/dist/core/fsx.js +54 -6
  126. package/dist/core/harness-conflicts.js +19 -10
  127. package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +5 -4
  128. package/dist/core/hooks-runtime/hook-invocation-dedupe.js +147 -0
  129. package/dist/core/hooks-runtime/hook-io.js +14 -4
  130. package/dist/core/hooks-runtime/light-turn.js +70 -0
  131. package/dist/core/hooks-runtime/payload-signals.js +270 -0
  132. package/dist/core/hooks-runtime/team-digest.js +0 -1
  133. package/dist/core/hooks-runtime/tool-output-quarantine.js +93 -0
  134. package/dist/core/hooks-runtime.js +418 -250
  135. package/dist/core/image/image-artifact-path-contract.js +8 -6
  136. package/dist/core/image/image-artifact-registry.js +5 -1
  137. package/dist/core/image-ux-review/imagegen-adapter.js +5 -2
  138. package/dist/core/imagegen/imagegen-capability.js +10 -13
  139. package/dist/core/imagegen/require-imagegen.js +37 -11
  140. package/dist/core/init/skills.js +16 -30
  141. package/dist/core/init.js +144 -36
  142. package/dist/core/managed-assets/managed-assets-manifest.js +417 -14
  143. package/dist/core/mission.js +24 -1
  144. package/dist/core/naruto/naruto-work-graph.js +70 -4
  145. package/dist/core/ops/reporting.js +3 -0
  146. package/dist/core/pipeline-internals/runtime-core.js +578 -180
  147. package/dist/core/pipeline-internals/runtime-gates.js +191 -49
  148. package/dist/core/ppt/style-tokens.js +1 -1
  149. package/dist/core/ppt-review/index.js +1 -1
  150. package/dist/core/ppt-review/slide-exporter.js +23 -17
  151. package/dist/core/ppt-review/slide-imagegen-review.js +1 -1
  152. package/dist/core/ppt-review/slide-issue-extraction.js +4 -2
  153. package/dist/core/preflight/parallel-preflight-engine.js +50 -1
  154. package/dist/core/product-design-plugin.js +2 -2
  155. package/dist/core/proof/route-finalizer.js +1 -1
  156. package/dist/core/proof/route-proof-gate.js +7 -2
  157. package/dist/core/proof-field.js +3 -3
  158. package/dist/core/provider/model-router.js +38 -32
  159. package/dist/core/recallpulse/policy.js +12 -28
  160. package/dist/core/recallpulse.js +11 -6
  161. package/dist/core/release/gate-manifest.js +18 -12
  162. package/dist/core/release/gate-pack-manifest.js +1 -1
  163. package/dist/core/release/npm-pack-proof.js +247 -0
  164. package/dist/core/release/package-dist-snapshot.js +151 -0
  165. package/dist/core/release/package-size-budget.js +5 -0
  166. package/dist/core/release/release-authorization-snapshot.js +115 -0
  167. package/dist/core/release/release-gate-affected-selector.js +15 -3
  168. package/dist/core/release/release-gate-cache-v2.js +30 -0
  169. package/dist/core/release/release-gate-contract.js +161 -0
  170. package/dist/core/release/release-gate-dag.js +44 -3
  171. package/dist/core/release/release-gate-hermetic-env.js +28 -17
  172. package/dist/core/release/release-real-contract.js +496 -0
  173. package/dist/core/release-parallel-full-coverage.js +31 -143
  174. package/dist/core/research/claim-evidence-matrix.js +41 -6
  175. package/dist/core/research/experiment-plan.js +14 -10
  176. package/dist/core/research/falsification.js +9 -2
  177. package/dist/core/research/implementation-blueprint-densifier.js +82 -60
  178. package/dist/core/research/implementation-blueprint.js +32 -26
  179. package/dist/core/research/mock-result.js +122 -11
  180. package/dist/core/research/replication-pack.js +15 -8
  181. package/dist/core/research/research-adversarial-review.js +1068 -0
  182. package/dist/core/research/research-claim-builder.js +69 -17
  183. package/dist/core/research/research-claim-synthesizer.js +343 -0
  184. package/dist/core/research/research-cycle-runner.js +53 -3
  185. package/dist/core/research/research-falsification-runner.js +176 -0
  186. package/dist/core/research/research-final-reviewer.js +44 -125
  187. package/dist/core/research/research-realistic-report.js +14 -6
  188. package/dist/core/research/research-review-artifact-digest.js +66 -0
  189. package/dist/core/research/research-source-evidence.js +144 -0
  190. package/dist/core/research/research-source-layer-catalog.js +68 -0
  191. package/dist/core/research/research-source-ledger-merge.js +250 -12
  192. package/dist/core/research/research-source-shards.js +26 -70
  193. package/dist/core/research/research-stage-runner.js +237 -247
  194. package/dist/core/research/research-super-search.js +184 -0
  195. package/dist/core/research/research-synthesis-prompt.js +20 -1
  196. package/dist/core/research/research-synthesis-writer.js +86 -5
  197. package/dist/core/research/research-work-graph.js +25 -18
  198. package/dist/core/research/source-quality-report.js +21 -0
  199. package/dist/core/research.js +429 -280
  200. package/dist/core/retention/retention-budget.js +25 -6
  201. package/dist/core/retention.js +980 -101
  202. package/dist/core/routes/constants.js +1 -1
  203. package/dist/core/routes/dollar-manifest-lite.js +11 -11
  204. package/dist/core/routes/evidence.js +4 -4
  205. package/dist/core/routes/ppt-policy.js +1 -1
  206. package/dist/core/routes.js +92 -64
  207. package/dist/core/runtime/task-profile.js +66 -0
  208. package/dist/core/runtime/verification-budget.js +12 -0
  209. package/dist/core/secret-redaction.js +4 -0
  210. package/dist/core/security/high-risk-contracts.js +6 -6
  211. package/dist/core/stop-gate/stop-gate-check.js +49 -12
  212. package/dist/core/subagents/agent-catalog.js +215 -0
  213. package/dist/core/subagents/model-policy.js +118 -0
  214. package/dist/core/subagents/naruto-help-contract.js +40 -0
  215. package/dist/core/subagents/official-subagent-config.js +488 -0
  216. package/dist/core/subagents/official-subagent-preparation.js +251 -0
  217. package/dist/core/subagents/official-subagent-prompt.js +137 -0
  218. package/dist/core/subagents/official-subagent-runner.js +129 -0
  219. package/dist/core/subagents/subagent-evidence.js +663 -0
  220. package/dist/core/subagents/terminology.js +16 -0
  221. package/dist/core/subagents/thread-budget.js +21 -0
  222. package/dist/core/subagents/triwiki-attention.js +65 -0
  223. package/dist/core/super-search/runtime-helpers.js +173 -19
  224. package/dist/core/super-search/runtime.js +140 -15
  225. package/dist/core/super-search/source-records.js +49 -8
  226. package/dist/core/team-review-policy.js +15 -0
  227. package/dist/core/triwiki/code-pack.js +8 -2
  228. package/dist/core/triwiki/triwiki-cache-key.js +108 -29
  229. package/dist/core/triwiki/triwiki-module-card.js +1 -1
  230. package/dist/core/triwiki-attention.js +13 -6
  231. package/dist/core/triwiki-provenance.js +274 -0
  232. package/dist/core/triwiki-runtime.js +21 -7
  233. package/dist/core/triwiki-wrongness/wrongness-ledger.js +187 -61
  234. package/dist/core/triwiki-wrongness/wrongness-retrieval.js +11 -2
  235. package/dist/core/triwiki-wrongness/wrongness-trust-policy.js +2 -0
  236. package/dist/core/update-check.js +23 -15
  237. package/dist/core/version-manager.js +51 -1
  238. package/dist/core/version.js +1 -1
  239. package/dist/core/wiki-coordinate.js +128 -12
  240. package/dist/core/work-order-ledger.js +208 -10
  241. package/dist/core/zellij/zellij-command.js +12 -1
  242. package/dist/core/zellij/zellij-dashboard-pane.js +3 -3
  243. package/dist/core/zellij/zellij-fake-adapter.js +3 -1
  244. package/dist/core/zellij/zellij-launcher.js +51 -21
  245. package/dist/core/zellij/zellij-layout-builder.js +14 -5
  246. package/dist/core/zellij/zellij-official-subagent-activity.js +477 -0
  247. package/dist/core/zellij/zellij-official-subagent-telemetry.js +264 -0
  248. package/dist/core/zellij/zellij-pane-proof.js +32 -6
  249. package/dist/core/zellij/zellij-slot-pane-renderer.js +17 -5
  250. package/dist/core/zellij/zellij-slot-telemetry.js +15 -3
  251. package/dist/core/zellij/zellij-ui-mode.js +1 -1
  252. package/dist/core/zellij/zellij-viewport-binder.js +3 -0
  253. package/dist/core/zellij/zellij-worker-pane-manager.js +5 -3
  254. package/dist/scripts/agent-fast-mode-default-check.js +48 -29
  255. package/dist/scripts/agent-role-config-repair-check.js +34 -15
  256. package/dist/scripts/agent-wiki-context-proof-check.js +16 -2
  257. package/dist/scripts/all-feature-deep-completion-check.js +14 -4
  258. package/dist/scripts/architecture-guard-check.js +8 -1
  259. package/dist/scripts/build-dist.js +17 -5
  260. package/dist/scripts/canonical-test-runner.js +188 -0
  261. package/dist/scripts/check-command-module-budget.js +38 -16
  262. package/dist/scripts/check-legacy-free.js +1 -1
  263. package/dist/scripts/check-route-modularity.js +0 -1
  264. package/dist/scripts/check-ts-contracts.js +1 -1
  265. package/dist/scripts/codex-0139-interrupt-agent-check.js +5 -1
  266. package/dist/scripts/{codex-0142-app-server-v2-check.js → codex-0144-app-server-v2-check.js} +11 -10
  267. package/dist/scripts/{codex-0142-binary-identity-check.js → codex-0144-binary-identity-check.js} +4 -4
  268. package/dist/scripts/codex-0144-capability-check.js +21 -0
  269. package/dist/scripts/{codex-0139-real-probes-check.js → codex-0144-core-real-probes-check.js} +19 -5
  270. package/dist/scripts/{codex-0142-doctor-wiring-check.js → codex-0144-doctor-wiring-check.js} +6 -6
  271. package/dist/scripts/{codex-0142-manifest-check.js → codex-0144-manifest-check.js} +11 -3
  272. package/dist/scripts/{codex-0142-policy-check.js → codex-0144-policy-check.js} +2 -2
  273. package/dist/scripts/{codex-0142-thread-store-check.js → codex-0144-thread-store-check.js} +3 -3
  274. package/dist/scripts/codex-app-provider-model-ui-check.js +53 -19
  275. package/dist/scripts/codex-app-ui-preservation-check.js +35 -4
  276. package/dist/scripts/codex-control-all-pipelines-check.js +7 -3
  277. package/dist/scripts/codex-control-side-effect-scope-check.js +2 -2
  278. package/dist/scripts/codex-control-tool-output-continuity-audit-check.js +27 -0
  279. package/dist/scripts/codex-effort-auto-discovery-check.js +1 -1
  280. package/dist/scripts/codex-lb-fast-mode-truth-check.js +1 -0
  281. package/dist/scripts/{codex-lb-gpt55-fast-profile-check.js → codex-lb-gpt56-fast-profile-check.js} +56 -5
  282. package/dist/scripts/codex-model-metadata-check.js +1 -1
  283. package/dist/scripts/codex-native-agent-role-content-check.js +15 -7
  284. package/dist/scripts/codex-native-repair-transaction-check.js +3 -1
  285. package/dist/scripts/codex-sdk-all-pipelines-check.js +7 -4
  286. package/dist/scripts/codex-sdk-research-pipeline-check.js +30 -8
  287. package/dist/scripts/codex-sdk-sandbox-policy-check.js +5 -1
  288. package/dist/scripts/codex-sdk-version-compat-check.js +2 -1
  289. package/dist/scripts/db-route-materialization-check.js +33 -0
  290. package/dist/scripts/dfix-fixture-check.js +1 -1
  291. package/dist/scripts/docs-truthfulness-check.js +4 -2
  292. package/dist/scripts/doctor-codex-startup-repair-check.js +47 -25
  293. package/dist/scripts/doctor-context7-repair-check.js +2 -1
  294. package/dist/scripts/doctor-fix-production-blackbox.js +12 -2
  295. package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +34 -7
  296. package/dist/scripts/doctor-imagegen-repair-check.js +14 -4
  297. package/dist/scripts/doctor-startup-config-repair-blackbox.js +9 -3
  298. package/dist/scripts/doctor-startup-config-repair-check.js +13 -3
  299. package/dist/scripts/install-update-preserves-config-check.js +7 -2
  300. package/dist/scripts/legacy-gate-inventory-check.js +7 -5
  301. package/dist/scripts/legacy-strong-inventory-check.js +7 -5
  302. package/dist/scripts/legacy-upgrade-matrix-check.js +4 -4
  303. package/dist/scripts/lib/native-cli-session-swarm-check-lib.js +173 -13
  304. package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +165 -6
  305. package/dist/scripts/managed-role-manifest-parity-check.js +5 -4
  306. package/dist/scripts/mutation-callsite-coverage-check.js +0 -11
  307. package/dist/scripts/naruto-codex-e2e-check.js +14 -7
  308. package/dist/scripts/naruto-shadow-clone-swarm-check.js +4 -201
  309. package/dist/scripts/npm-publish-performance-check.js +20 -12
  310. package/dist/scripts/official-subagent-workflow-check.js +145 -0
  311. package/dist/scripts/package-published-contract-check.js +6 -20
  312. package/dist/scripts/packlist-performance-check.js +17 -3
  313. package/dist/scripts/parallel-verification-engine-check.js +2 -2
  314. package/dist/scripts/postinstall-safe-side-effects-check.js +8 -3
  315. package/dist/scripts/ppt-no-mock-as-real-check.js +3 -1
  316. package/dist/scripts/prepublish-release-check-or-fast.js +23 -86
  317. package/dist/scripts/product-design-plugin-routing-check.js +1 -1
  318. package/dist/scripts/release-affected-selector-check.js +74 -1
  319. package/dist/scripts/release-check-stamp.js +324 -239
  320. package/dist/scripts/release-dag-full-coverage-check.js +7 -15
  321. package/dist/scripts/release-dynamic-presets-check.js +10 -1
  322. package/dist/scripts/release-gate-dag-runner-check.js +3 -3
  323. package/dist/scripts/release-gate-dag-runner.js +35 -11
  324. package/dist/scripts/release-gate-existence-audit.js +1 -2
  325. package/dist/scripts/release-gate-script-parity-check.js +1 -1
  326. package/dist/scripts/release-parallel-full-coverage-check.js +12 -6
  327. package/dist/scripts/release-parallel-speed-budget-check.js +18 -2
  328. package/dist/scripts/release-real-check.js +390 -157
  329. package/dist/scripts/release-registry-check.js +61 -16
  330. package/dist/scripts/release-runtime-truth-matrix-check.js +22 -0
  331. package/dist/scripts/research-blueprint-densifier-check.js +2 -2
  332. package/dist/scripts/research-real-cycle-no-legacy-final-md-check.js +11 -7
  333. package/dist/scripts/route-proof-artifact-structure-check.js +1 -0
  334. package/dist/scripts/search-visibility-gate-lib.js +1 -1
  335. package/dist/scripts/seo-geo-route-identity-check.js +30 -4
  336. package/dist/scripts/sizecheck.js +4 -4
  337. package/dist/scripts/sks-1-11-gate-lib.js +53 -6
  338. package/dist/scripts/sks-3-1-4-directive-check-lib.js +8 -2
  339. package/dist/scripts/sks-3-1-5-directive-check-lib.js +3 -2
  340. package/dist/scripts/sks-3-1-6-directive-check-lib.js +5 -3
  341. package/dist/scripts/sks-menubar-install-check.js +8 -0
  342. package/dist/scripts/sks-uninstall-regression-check.js +1 -1
  343. package/dist/scripts/sksd-daemon-check.js +16 -6
  344. package/dist/scripts/trust-fixture-check.js +32 -10
  345. package/dist/scripts/write-build-manifest.js +2 -1
  346. package/dist/scripts/wrongness-fixture-check.js +1 -1
  347. package/dist/scripts/zellij-layout-valid-check.js +36 -11
  348. package/dist/scripts/zellij-pane-proof-check.js +33 -2
  349. package/dist/scripts/zellij-real-session-cleanup-check.js +122 -2
  350. package/dist/scripts/zellij-real-session-launch-check.js +76 -5
  351. package/dist/scripts/zellij-slot-pane-renderer-check.js +4 -4
  352. package/dist/scripts/zellij-spawn-on-demand-layout-check.js +3 -3
  353. package/docs/demo.tape +1 -1
  354. package/infra-harness-gates.json +1486 -0
  355. package/package.json +32 -19
  356. package/release-gates.v2.json +4060 -0
  357. package/runtime-required-scripts.json +9 -0
  358. package/schemas/codex/{app-server-0.142 → app-server-0.144}/codex_app_server_protocol.v2.schemas.json +1146 -781
  359. package/schemas/codex/codex-0139-real-probe-result.schema.json +39 -5
  360. package/schemas/codex/ppt-slide-issue-ledger.schema.json +2 -1
  361. package/dist/commands/db.js +0 -6
  362. package/dist/core/codex-control/codex-0139-multi-agent-real-probe.js +0 -107
  363. package/dist/core/commands/db-command.js +0 -146
  364. package/dist/core/research/prompt.js +0 -15
  365. package/dist/scripts/agent-native-release-gate.js +0 -274
  366. package/dist/scripts/codex-0142-capability-check.js +0 -21
  367. package/dist/scripts/codex-control-tool-call-sequence-repair-check.js +0 -14
  368. package/dist/scripts/command-performance-scorecard-check.js +0 -204
  369. package/dist/scripts/config-managed-merge-callsite-coverage-check.js +0 -212
  370. package/dist/scripts/dollar-performance-scorecard-check.js +0 -257
  371. package/dist/scripts/gate-timing-check.js +0 -16
  372. package/dist/scripts/ops-maturity-scorecard-check.js +0 -12
  373. package/dist/scripts/performance-baseline-check.js +0 -12
  374. package/dist/scripts/performance-improvement-report-check.js +0 -58
  375. package/dist/scripts/release-parallel-check.js +0 -389
  376. package/dist/scripts/release-runner-efficiency-check.js +0 -15
  377. package/dist/scripts/retention-long-run-smoke-check.js +0 -299
  378. package/docs/assets/sneakoscope-architecture-pipeline.jpg +0 -0
@@ -1,6 +1,21 @@
1
1
  export const MIN_TEAM_REVIEWER_LANES = 5;
2
2
  export const MIN_TEAM_REVIEW_STAGE_AGENT_SESSIONS = MIN_TEAM_REVIEWER_LANES;
3
3
  export const MIN_TEAM_REVIEW_POLICY_TEXT = `Minimum Team review policy: run at least ${MIN_TEAM_REVIEWER_LANES} independent reviewer/QA validation lanes before integration or final, even when the requested reviewer role count is lower.`;
4
+ export const DEFAULT_OFFICIAL_REVIEWER_LANES = 1;
5
+ export const MAX_AUTOMATIC_OFFICIAL_REVIEWER_LANES = 2;
6
+ export const MAX_CRITICAL_OFFICIAL_REVIEWER_LANES = 3;
7
+ export const OFFICIAL_SUBAGENT_REVIEW_POLICY_TEXT = 'Official subagent review policy: start with one focused reviewer, expand to two only for independent review domains, and use at most three automatic reviewers for critical multi-domain risk. The parent owns integration and may honor a larger explicit operator request.';
8
+ export function officialSubagentReviewLaneBudget(input = {}) {
9
+ if (Number.isFinite(Number(input.explicit)) && Number(input.explicit) > 0) {
10
+ return { requested: Math.floor(Number(input.explicit)), source: 'explicit_operator' };
11
+ }
12
+ const domains = Math.max(0, Math.floor(Number(input.independentDomains || 0)));
13
+ const ceiling = input.critical === true ? MAX_CRITICAL_OFFICIAL_REVIEWER_LANES : MAX_AUTOMATIC_OFFICIAL_REVIEWER_LANES;
14
+ return {
15
+ requested: Math.max(DEFAULT_OFFICIAL_REVIEWER_LANES, Math.min(ceiling, domains || DEFAULT_OFFICIAL_REVIEWER_LANES)),
16
+ source: 'risk_scoped_automatic'
17
+ };
18
+ }
4
19
  function numericCount(value, fallback = 0) {
5
20
  const number = Number(value);
6
21
  return Number.isFinite(number) ? Math.max(0, Math.floor(number)) : fallback;
@@ -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 {
@@ -14,7 +14,7 @@ export const DEFAULT_TRIWIKI_MODULE_CARDS = [
14
14
  moduleCard('doctor-dirty-repair', ['src/core/doctor/doctor-dirty-planner.ts', 'src/core/doctor/doctor-repair-postcheck.ts', 'src/scripts/doctor-dirty-*.ts'], ['doctor:dirty'], ['doctor-production'], 'high'),
15
15
  moduleCard('startup-config-repair', ['src/core/doctor/*startup*.ts', 'src/scripts/doctor-startup-*.ts'], ['doctor:startup'], ['doctor-production'], 'high'),
16
16
  moduleCard('context7-mcp', ['src/core/doctor/*context7*.ts', 'src/commands/context7.ts'], ['doctor:context7', 'context7:'], ['startup-mcp'], 'critical'),
17
- moduleCard('supabase-mcp', ['src/core/doctor/*supabase*.ts', 'src/commands/db.ts'], ['doctor:supabase', 'db:'], ['startup-mcp'], 'critical'),
17
+ moduleCard('supabase-mcp', ['src/core/doctor/*supabase*.ts', 'src/core/db-safety.ts', 'src/core/pipeline-internals/runtime-core.ts'], ['doctor:supabase', 'mad-db:', 'mad-sks:'], ['startup-mcp'], 'critical'),
18
18
  moduleCard('native-capability', ['src/core/codex-native/**', 'src/scripts/native-*.ts'], ['native:', 'codex-native:'], ['native-capability'], 'high'),
19
19
  moduleCard('secret-preservation', ['src/core/**/secret*.ts', 'src/scripts/secret-*.ts', 'safety-mutation-allowlist.json'], ['secret:', 'supabase-secret'], ['doctor-production'], 'critical'),
20
20
  moduleCard('core-skill', ['.agents/skills/**', 'src/scripts/core-skill-*.ts'], ['core-skill:'], ['core-skill'], 'high'),
@@ -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
  }
@@ -0,0 +1,274 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { PACKAGE_VERSION, nowIso, sha256 } from './fsx.js';
4
+ export const TRIWIKI_CONTEXT_PACK_PROVENANCE_SCHEMA = 'sks.triwiki-context-pack-provenance.v1';
5
+ export const TRIWIKI_SOURCE_MANIFEST_SCHEMA = 'sks.triwiki-source-manifest.v1';
6
+ const SOURCE_MANIFEST_MAX_FILES = 512;
7
+ const SOURCE_MANIFEST_MAX_BYTES = 8 * 1024 * 1024;
8
+ const DYNAMIC_SOURCE_PREFIXES = Object.freeze([
9
+ '.git',
10
+ 'node_modules',
11
+ 'dist',
12
+ '.sneakoscope/missions',
13
+ '.sneakoscope/reports',
14
+ '.sneakoscope/wiki',
15
+ '.sneakoscope/cache',
16
+ '.sneakoscope/tmp',
17
+ '.sneakoscope/locks',
18
+ '.sneakoscope/agents'
19
+ ]);
20
+ function canonicalJson(value) {
21
+ if (value === null)
22
+ return 'null';
23
+ if (typeof value !== 'object')
24
+ return JSON.stringify(value) ?? 'null';
25
+ if (typeof value.toJSON === 'function')
26
+ return canonicalJson(value.toJSON());
27
+ if (Array.isArray(value))
28
+ return `[${value.map((entry) => canonicalJson(entry)).join(',')}]`;
29
+ const record = value;
30
+ return `{${Object.keys(record)
31
+ .filter((key) => record[key] !== undefined && typeof record[key] !== 'function' && typeof record[key] !== 'symbol')
32
+ .sort()
33
+ .map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`)
34
+ .join(',')}}`;
35
+ }
36
+ function normalizedRelativePath(value) {
37
+ return value.split(path.sep).join('/').replace(/^\.\//, '').replace(/\/$/, '') || '.';
38
+ }
39
+ function pathIsInside(root, candidate) {
40
+ const relative = path.relative(root, candidate);
41
+ return relative === '' || (!relative.startsWith(`..${path.sep}`) && relative !== '..' && !path.isAbsolute(relative));
42
+ }
43
+ function isDynamicSourcePath(relativePath) {
44
+ const normalized = normalizedRelativePath(relativePath);
45
+ return DYNAMIC_SOURCE_PREFIXES.some((prefix) => normalized === prefix || normalized.startsWith(`${prefix}/`));
46
+ }
47
+ function authoritativeCitations(pack) {
48
+ const anchorValues = Array.isArray(pack?.wiki?.a)
49
+ ? pack.wiki.a.map((row) => row?.[8])
50
+ : (Array.isArray(pack?.wiki?.anchors) ? pack.wiki.anchors.map((anchor) => anchor?.p) : []);
51
+ const claimValues = (Array.isArray(pack?.claims) ? pack.claims : [])
52
+ .flatMap((claim) => Array.isArray(claim?.source_paths) ? claim.source_paths : []);
53
+ const values = [...anchorValues, ...claimValues];
54
+ const normalized = values
55
+ .filter((value) => typeof value === 'string' && value.trim())
56
+ .map((value) => value.trim());
57
+ return [...new Set(normalized)].sort((a, b) => a.localeCompare(b));
58
+ }
59
+ /**
60
+ * Bounded byte manifest for the exact local hydration citations carried by a
61
+ * context pack. Runtime/generated state is intentionally excluded so ordinary
62
+ * mission/report churn cannot invalidate otherwise-current source memory.
63
+ */
64
+ export function buildTriWikiSourceManifest(pack, root) {
65
+ const citations = authoritativeCitations(pack);
66
+ const includedCitations = [];
67
+ const excludedDynamicCitations = [];
68
+ const roots = [];
69
+ const links = [];
70
+ const entries = [];
71
+ const blockers = [];
72
+ const resolvedRoot = root ? path.resolve(root) : '';
73
+ let realRoot = '';
74
+ try {
75
+ realRoot = resolvedRoot ? fs.realpathSync(resolvedRoot) : '';
76
+ }
77
+ catch { }
78
+ let totalBytes = 0;
79
+ const seenRealDirectories = new Set();
80
+ const seenEntryPaths = new Set();
81
+ const addBlocker = (value) => {
82
+ if (!blockers.includes(value))
83
+ blockers.push(value);
84
+ };
85
+ const walk = (absolute, displayPath) => {
86
+ let lstat;
87
+ let real;
88
+ try {
89
+ lstat = fs.lstatSync(absolute);
90
+ real = fs.realpathSync(absolute);
91
+ }
92
+ catch {
93
+ addBlocker(`source_manifest_path_unreadable:${displayPath}`);
94
+ return;
95
+ }
96
+ if (!pathIsInside(realRoot, real)) {
97
+ addBlocker(`source_manifest_path_outside_root:${displayPath}`);
98
+ return;
99
+ }
100
+ let stat = lstat;
101
+ if (lstat.isSymbolicLink()) {
102
+ links.push({ path: displayPath, target: normalizedRelativePath(path.relative(realRoot, real)) });
103
+ try {
104
+ stat = fs.statSync(absolute);
105
+ }
106
+ catch {
107
+ addBlocker(`source_manifest_path_unreadable:${displayPath}`);
108
+ return;
109
+ }
110
+ }
111
+ if (stat.isDirectory()) {
112
+ if (seenRealDirectories.has(real))
113
+ return;
114
+ seenRealDirectories.add(real);
115
+ let children;
116
+ try {
117
+ children = fs.readdirSync(absolute, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
118
+ }
119
+ catch {
120
+ addBlocker(`source_manifest_path_unreadable:${displayPath}`);
121
+ return;
122
+ }
123
+ for (const child of children) {
124
+ const childDisplay = normalizedRelativePath(path.posix.join(displayPath, child.name));
125
+ if (isDynamicSourcePath(childDisplay))
126
+ continue;
127
+ walk(path.join(absolute, child.name), childDisplay);
128
+ if (blockers.includes('source_manifest_file_limit_exceeded') || blockers.includes('source_manifest_byte_limit_exceeded'))
129
+ return;
130
+ }
131
+ return;
132
+ }
133
+ if (!stat.isFile())
134
+ return;
135
+ if (seenEntryPaths.has(displayPath))
136
+ return;
137
+ if (entries.length >= SOURCE_MANIFEST_MAX_FILES) {
138
+ addBlocker('source_manifest_file_limit_exceeded');
139
+ return;
140
+ }
141
+ if (totalBytes + stat.size > SOURCE_MANIFEST_MAX_BYTES) {
142
+ addBlocker('source_manifest_byte_limit_exceeded');
143
+ return;
144
+ }
145
+ let bytes;
146
+ try {
147
+ bytes = fs.readFileSync(absolute);
148
+ }
149
+ catch {
150
+ addBlocker(`source_manifest_path_unreadable:${displayPath}`);
151
+ return;
152
+ }
153
+ totalBytes += bytes.length;
154
+ seenEntryPaths.add(displayPath);
155
+ entries.push({ path: displayPath, bytes: bytes.length, sha256: sha256(bytes) });
156
+ };
157
+ if (!realRoot)
158
+ addBlocker('source_manifest_root_missing');
159
+ for (const citation of citations) {
160
+ if (!realRoot)
161
+ break;
162
+ if (/^[a-z][a-z0-9+.-]*:\/\//i.test(citation)) {
163
+ addBlocker(`source_manifest_remote_citation_unbound:${citation}`);
164
+ continue;
165
+ }
166
+ const absolute = path.isAbsolute(citation) ? path.resolve(citation) : path.resolve(resolvedRoot, citation);
167
+ const relative = normalizedRelativePath(path.relative(resolvedRoot, absolute));
168
+ if (!pathIsInside(resolvedRoot, absolute)) {
169
+ addBlocker(`source_manifest_path_outside_root:${citation}`);
170
+ continue;
171
+ }
172
+ if (isDynamicSourcePath(relative)) {
173
+ excludedDynamicCitations.push(relative);
174
+ continue;
175
+ }
176
+ includedCitations.push(relative);
177
+ let stat;
178
+ try {
179
+ stat = fs.statSync(absolute);
180
+ }
181
+ catch {
182
+ addBlocker(`source_manifest_path_unreadable:${relative}`);
183
+ continue;
184
+ }
185
+ roots.push({ path: relative, kind: stat.isDirectory() ? 'directory' : 'file' });
186
+ walk(absolute, relative);
187
+ }
188
+ roots.sort((a, b) => a.path.localeCompare(b.path));
189
+ links.sort((a, b) => a.path.localeCompare(b.path));
190
+ entries.sort((a, b) => a.path.localeCompare(b.path));
191
+ blockers.sort((a, b) => a.localeCompare(b));
192
+ return {
193
+ schema: TRIWIKI_SOURCE_MANIFEST_SCHEMA,
194
+ scope: 'authoritative_citation_bytes',
195
+ root_binding: 'project_relative',
196
+ limits: { max_files: SOURCE_MANIFEST_MAX_FILES, max_total_bytes: SOURCE_MANIFEST_MAX_BYTES },
197
+ excluded_dynamic_prefixes: [...DYNAMIC_SOURCE_PREFIXES],
198
+ citations: includedCitations.sort((a, b) => a.localeCompare(b)),
199
+ excluded_dynamic_citations: excludedDynamicCitations.sort((a, b) => a.localeCompare(b)),
200
+ roots,
201
+ links,
202
+ entries,
203
+ file_count: entries.length,
204
+ total_bytes: totalBytes,
205
+ complete: blockers.length === 0,
206
+ blockers
207
+ };
208
+ }
209
+ export function triWikiSourceSnapshotId(sourceManifest) {
210
+ return sha256(canonicalJson(sourceManifest));
211
+ }
212
+ export function triWikiPayloadSha256(pack) {
213
+ const provenance = pack?.provenance && typeof pack.provenance === 'object'
214
+ ? { ...pack.provenance }
215
+ : {};
216
+ delete provenance.payload_sha256;
217
+ return sha256(canonicalJson({ ...pack, provenance }));
218
+ }
219
+ export function sealTriWikiContextPack(pack, options = {}) {
220
+ const { provenance: _priorProvenance, ...payload } = pack || {};
221
+ const sourceManifest = buildTriWikiSourceManifest(payload, options.root);
222
+ const provenance = {
223
+ schema: TRIWIKI_CONTEXT_PACK_PROVENANCE_SCHEMA,
224
+ generated_at: options.generatedAt || nowIso(),
225
+ package_snapshot_id: `sneakoscope@${options.packageVersion || PACKAGE_VERSION}`,
226
+ source_snapshot_id: triWikiSourceSnapshotId(sourceManifest),
227
+ source_manifest: sourceManifest
228
+ };
229
+ const sealed = { ...payload, provenance };
230
+ provenance.payload_sha256 = triWikiPayloadSha256(sealed);
231
+ return sealed;
232
+ }
233
+ export function validateTriWikiContextPackProvenance(pack, options = {}) {
234
+ const issues = [];
235
+ const provenance = pack?.provenance;
236
+ if (!provenance || typeof provenance !== 'object') {
237
+ issues.push({ id: 'context_pack_provenance_missing', severity: 'error' });
238
+ return { ok: false, issues };
239
+ }
240
+ if (provenance.schema !== TRIWIKI_CONTEXT_PACK_PROVENANCE_SCHEMA) {
241
+ issues.push({ id: 'context_pack_provenance_schema', severity: 'error' });
242
+ }
243
+ const generatedAt = String(provenance.generated_at || '');
244
+ if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/.test(generatedAt) || !Number.isFinite(Date.parse(generatedAt))) {
245
+ issues.push({ id: 'context_pack_generated_at', severity: 'error' });
246
+ }
247
+ const expectedPackage = `sneakoscope@${options.packageVersion || PACKAGE_VERSION}`;
248
+ if (provenance.package_snapshot_id !== expectedPackage) {
249
+ issues.push({ id: 'context_pack_package_snapshot_mismatch', severity: 'error' });
250
+ }
251
+ const sourceManifest = provenance.source_manifest;
252
+ if (!sourceManifest || sourceManifest.schema !== TRIWIKI_SOURCE_MANIFEST_SCHEMA || sourceManifest.scope !== 'authoritative_citation_bytes') {
253
+ issues.push({ id: 'context_pack_source_manifest_missing', severity: 'error' });
254
+ }
255
+ if (sourceManifest?.complete !== true || !Array.isArray(sourceManifest?.blockers) || sourceManifest.blockers.length) {
256
+ issues.push({ id: 'context_pack_source_manifest_incomplete', severity: 'error' });
257
+ }
258
+ const storedSource = sourceManifest ? triWikiSourceSnapshotId(sourceManifest) : '';
259
+ if (!/^[0-9a-f]{64}$/.test(String(provenance.source_snapshot_id || '')) || provenance.source_snapshot_id !== storedSource) {
260
+ issues.push({ id: 'context_pack_source_snapshot_mismatch', severity: 'error' });
261
+ }
262
+ const currentSourceManifest = buildTriWikiSourceManifest(pack, options.root);
263
+ if (!currentSourceManifest.complete)
264
+ issues.push({ id: 'context_pack_current_source_manifest_incomplete', severity: 'error' });
265
+ if (provenance.source_snapshot_id !== triWikiSourceSnapshotId(currentSourceManifest)) {
266
+ issues.push({ id: 'context_pack_source_bytes_mismatch', severity: 'error' });
267
+ }
268
+ const expectedPayload = triWikiPayloadSha256(pack);
269
+ if (!/^[0-9a-f]{64}$/.test(String(provenance.payload_sha256 || '')) || provenance.payload_sha256 !== expectedPayload) {
270
+ issues.push({ id: 'context_pack_payload_sha256_mismatch', severity: 'error' });
271
+ }
272
+ return { ok: issues.length === 0, issues };
273
+ }
274
+ //# sourceMappingURL=triwiki-provenance.js.map
@@ -1,13 +1,14 @@
1
1
  import path from 'node:path';
2
- import crypto from 'node:crypto';
3
2
  import { ensureDir, readJson, writeJsonAtomic } from './fsx.js';
3
+ import { validateWikiCoordinateIndex } from './wiki-coordinate.js';
4
+ import { validateTriWikiContextPackProvenance } from './triwiki-provenance.js';
4
5
  // Inference-path TriWiki consumption. Routes/the agent kernel READ the deployed
5
6
  // context pack written by `sks wiki refresh|pack` (the SSOT); they never rebuild
6
7
  // it on the hot path. This is the seam that turns the TriWiki engine from an
7
8
  // advisory prompt note into an actually-consulted, proof-referenced context source.
8
9
  export const TRIWIKI_CONTEXT_PACK_REL = '.sneakoscope/wiki/context-pack.json';
9
10
  export const TRIWIKI_RUNTIME_SCHEMA = 'sks.triwiki-runtime-context.v1';
10
- function emptyContext(file) {
11
+ function emptyContext(file, warning = 'no_triwiki_context_pack (run `sks wiki refresh` to populate the project memory pack)') {
11
12
  return {
12
13
  schema: TRIWIKI_RUNTIME_SCHEMA,
13
14
  present: false,
@@ -19,7 +20,7 @@ function emptyContext(file) {
19
20
  claim_count: 0,
20
21
  anchor_count: 0,
21
22
  trust_avg: null,
22
- warning: 'no_triwiki_context_pack (run `sks wiki refresh` to populate the project memory pack)'
23
+ warning
23
24
  };
24
25
  }
25
26
  /**
@@ -38,14 +39,27 @@ export async function loadTriWikiRuntimeContext(root) {
38
39
  }
39
40
  if (!pack || typeof pack !== 'object')
40
41
  return emptyContext(file);
41
- const attention = pack.attention || {};
42
- const wiki = pack.wiki || {};
42
+ const attention = pack.attention;
43
+ const wiki = pack.wiki;
44
+ if (!wiki || typeof wiki !== 'object') {
45
+ return emptyContext(file, 'invalid_triwiki_context_pack:wiki_index_missing (run `sks wiki refresh`)');
46
+ }
47
+ const coordinateValidation = validateWikiCoordinateIndex(wiki, { root, claims: pack.claims });
48
+ const provenanceValidation = validateTriWikiContextPackProvenance(pack, { root });
49
+ const issues = [...coordinateValidation.issues, ...provenanceValidation.issues];
50
+ if (issues.length) {
51
+ const issueIds = issues.map((issue) => String(issue.id || 'unknown')).slice(0, 8);
52
+ return emptyContext(file, `invalid_triwiki_context_pack:${issueIds.join(',')} (run \`sks wiki refresh\`)`);
53
+ }
54
+ if (!attention || !Array.isArray(attention.use_first) || !Array.isArray(attention.hydrate_first) || !Array.isArray(pack.claims)) {
55
+ return emptyContext(file, 'invalid_triwiki_context_pack:attention_or_claims_missing (run `sks wiki refresh`)');
56
+ }
43
57
  const anchorCount = Array.isArray(wiki.a) ? wiki.a.length : (Array.isArray(wiki.anchors) ? wiki.anchors.length : 0);
44
58
  return {
45
59
  schema: TRIWIKI_RUNTIME_SCHEMA,
46
60
  present: true,
47
61
  context_pack_path: file,
48
- context_pack_hash: crypto.createHash('sha256').update(JSON.stringify(pack)).digest('hex'),
62
+ context_pack_hash: pack.provenance.payload_sha256,
49
63
  mission: typeof pack.mission === 'string' ? pack.mission : null,
50
64
  use_first: Array.isArray(attention.use_first) ? attention.use_first : [],
51
65
  hydrate_first: Array.isArray(attention.hydrate_first) ? attention.hydrate_first : [],
@@ -58,7 +72,7 @@ export async function loadTriWikiRuntimeContext(root) {
58
72
  /** Compact instruction block injected into read-only agents / route additionalContext. */
59
73
  export function triWikiContextBlock(ctx) {
60
74
  if (!ctx.present)
61
- return 'TriWiki: no context pack present; run `sks wiki refresh` before relying on cached project memory.';
75
+ return `TriWiki unavailable: ${ctx.warning || 'context pack missing or invalid'}; do not rely on cached project memory.`;
62
76
  const ids = (rows) => rows.map((row) => (Array.isArray(row) ? row[0] : row?.id)).filter(Boolean).slice(0, 6);
63
77
  const use = ids(ctx.use_first);
64
78
  const hyd = ids(ctx.hydrate_first);