sneakoscope 6.1.0 → 6.2.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 (246) hide show
  1. package/README.md +35 -11
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/dist/bin/fast-inline.js +18 -9
  5. package/dist/bin/sks-dispatch.js +2 -2
  6. package/dist/cli/args.js +2 -0
  7. package/dist/cli/command-manifest-lite.js +2 -3
  8. package/dist/cli/command-registry.js +3 -4
  9. package/dist/cli/help-fast.js +1 -1
  10. package/dist/cli/install-helpers.js +116 -306
  11. package/dist/cli/install-tool-helpers.js +287 -0
  12. package/dist/cli/router.js +40 -4
  13. package/dist/commands/codex-lb.js +51 -20
  14. package/dist/commands/codex.js +39 -1
  15. package/dist/commands/doctor.js +242 -20
  16. package/dist/commands/tmux.js +5 -1
  17. package/dist/commands/zellij-monitor-pane.js +2 -0
  18. package/dist/commands/zellij-viewport-pane.js +3 -1
  19. package/dist/commands/zellij.js +1 -1
  20. package/dist/config/skills-manifest.json +59 -59
  21. package/dist/core/agent-bridge/agent-manifest.js +48 -0
  22. package/dist/core/agents/agent-command-surface.js +2 -1
  23. package/dist/core/agents/agent-effort-policy.js +38 -35
  24. package/dist/core/agents/agent-plan.js +100 -21
  25. package/dist/core/agents/agent-role-config.js +43 -46
  26. package/dist/core/agents/agent-runner-codex-exec.js +16 -3
  27. package/dist/core/agents/agent-schema.js +3 -2
  28. package/dist/core/agents/native-cli-session-swarm.js +1 -1
  29. package/dist/core/agents/zellij-right-lane-cockpit.js +2 -2
  30. package/dist/core/codex/agent-config-file-repair.js +94 -193
  31. package/dist/core/codex/codex-cli-update.js +723 -0
  32. package/dist/core/codex/codex-config-guard.js +185 -9
  33. package/dist/core/codex/codex-config-readability.js +21 -8
  34. package/dist/core/codex/codex-config-toml.js +14 -11
  35. package/dist/core/codex/codex-project-config-policy.js +3 -6
  36. package/dist/core/codex/codex-startup-config-postcheck.js +52 -42
  37. package/dist/core/codex-adapter.js +35 -22
  38. package/dist/core/codex-app/codex-agent-role-sync.js +13 -54
  39. package/dist/core/codex-app/codex-app-launcher.js +48 -17
  40. package/dist/core/codex-app/codex-app-restart.js +23 -2
  41. package/dist/core/codex-app/mcp-manager.js +679 -0
  42. package/dist/core/codex-app/sks-menubar.js +533 -8
  43. package/dist/core/codex-control/codex-0139-image-path-real-probe.js +15 -4
  44. package/dist/core/codex-control/codex-0139-web-search-probe.js +17 -6
  45. package/dist/core/codex-control/codex-lb-launch-recovery.js +293 -0
  46. package/dist/core/codex-control/codex-reliability-shield.js +89 -29
  47. package/dist/core/codex-control/codex-sdk-adapter.js +44 -8
  48. package/dist/core/codex-control/codex-task-runner.js +62 -9
  49. package/dist/core/codex-control/python-codex-sdk-adapter.js +30 -3
  50. package/dist/core/codex-exec-output-schema.js +35 -6
  51. package/dist/core/codex-lb/codex-lb-env.js +1 -1
  52. package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +291 -0
  53. package/dist/core/codex-native/codex-native-feature-broker.js +9 -16
  54. package/dist/core/codex-native/codex-native-repair-transaction.js +1 -1
  55. package/dist/core/codex-native/core-skill-manifest.js +8 -4
  56. package/dist/core/codex-runtime/codex-desktop-config-policy.js +2 -3
  57. package/dist/core/commands/agent-bridge-command.js +23 -2
  58. package/dist/core/commands/agent-command.js +19 -5
  59. package/dist/core/commands/basic-cli.js +47 -6
  60. package/dist/core/commands/command-utils.js +1 -1
  61. package/dist/core/commands/mad-sks-command.js +76 -10
  62. package/dist/core/commands/menubar-command.js +94 -0
  63. package/dist/core/commands/naruto-command.js +645 -1156
  64. package/dist/core/commands/research-command.js +293 -231
  65. package/dist/core/commands/run-command.js +100 -23
  66. package/dist/core/commands/team-command.js +2 -3
  67. package/dist/core/commands/team-legacy-observe-command.js +94 -359
  68. package/dist/core/commands/wiki-command.js +11 -5
  69. package/dist/core/db-safety.js +2 -2
  70. package/dist/core/decision-lattice.js +6 -6
  71. package/dist/core/doctor/codex-startup-config-repair.js +8 -3
  72. package/dist/core/doctor/doctor-codex-startup-repair.js +6 -141
  73. package/dist/core/feature-fixture-executor.js +71 -7
  74. package/dist/core/feature-fixture-runner.js +53 -12
  75. package/dist/core/feature-fixtures.js +47 -14
  76. package/dist/core/feature-registry.js +28 -27
  77. package/dist/core/fsx.js +1 -0
  78. package/dist/core/harness-conflicts.js +18 -9
  79. package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +14 -8
  80. package/dist/core/hooks-runtime/hook-io.js +8 -4
  81. package/dist/core/hooks-runtime/light-turn.js +70 -0
  82. package/dist/core/hooks-runtime/naruto-decision-gate.js +184 -0
  83. package/dist/core/hooks-runtime/payload-signals.js +270 -0
  84. package/dist/core/hooks-runtime/stop-repeat-guard.js +89 -0
  85. package/dist/core/hooks-runtime/team-digest.js +0 -1
  86. package/dist/core/hooks-runtime/tool-output-quarantine.js +93 -0
  87. package/dist/core/hooks-runtime.js +438 -354
  88. package/dist/core/init/skills.js +16 -30
  89. package/dist/core/init.js +144 -36
  90. package/dist/core/managed-assets/managed-assets-manifest.js +566 -10
  91. package/dist/core/mission.js +24 -1
  92. package/dist/core/pipeline-internals/runtime-core.js +570 -177
  93. package/dist/core/pipeline-internals/runtime-gates.js +174 -48
  94. package/dist/core/preflight/parallel-preflight-engine.js +66 -4
  95. package/dist/core/proof/route-adapter.js +1 -1
  96. package/dist/core/proof/route-proof-gate.js +7 -2
  97. package/dist/core/proof/selftest-proof-fixtures.js +3 -5
  98. package/dist/core/proof-field.js +1 -1
  99. package/dist/core/provider/model-router.js +42 -31
  100. package/dist/core/recallpulse/policy.js +12 -28
  101. package/dist/core/recallpulse.js +11 -6
  102. package/dist/core/release/npm-pack-proof.js +247 -0
  103. package/dist/core/release/package-dist-snapshot.js +151 -0
  104. package/dist/core/release/package-size-budget.js +4 -1
  105. package/dist/core/release/release-authorization-snapshot.js +115 -0
  106. package/dist/core/release/release-gate-affected-selector.js +14 -2
  107. package/dist/core/release/release-gate-cache-v2.js +30 -0
  108. package/dist/core/release/release-gate-contract.js +161 -0
  109. package/dist/core/release/release-gate-dag.js +1 -0
  110. package/dist/core/release/release-real-contract.js +90 -10
  111. package/dist/core/release-parallel-full-coverage.js +31 -143
  112. package/dist/core/research/claim-evidence-matrix.js +41 -6
  113. package/dist/core/research/experiment-plan.js +14 -10
  114. package/dist/core/research/falsification.js +9 -2
  115. package/dist/core/research/implementation-blueprint-densifier.js +82 -60
  116. package/dist/core/research/implementation-blueprint.js +32 -26
  117. package/dist/core/research/mock-result.js +122 -11
  118. package/dist/core/research/replication-pack.js +15 -8
  119. package/dist/core/research/research-adversarial-review.js +1068 -0
  120. package/dist/core/research/research-claim-builder.js +69 -17
  121. package/dist/core/research/research-claim-synthesizer.js +343 -0
  122. package/dist/core/research/research-cycle-runner.js +53 -3
  123. package/dist/core/research/research-falsification-runner.js +176 -0
  124. package/dist/core/research/research-final-reviewer.js +44 -125
  125. package/dist/core/research/research-plan-markdown.js +123 -0
  126. package/dist/core/research/research-realistic-report.js +14 -6
  127. package/dist/core/research/research-review-artifact-digest.js +66 -0
  128. package/dist/core/research/research-source-evidence.js +144 -0
  129. package/dist/core/research/research-source-layer-catalog.js +68 -0
  130. package/dist/core/research/research-source-ledger-merge.js +250 -12
  131. package/dist/core/research/research-source-shards.js +26 -70
  132. package/dist/core/research/research-stage-runner.js +237 -247
  133. package/dist/core/research/research-super-search.js +188 -0
  134. package/dist/core/research/research-synthesis-prompt.js +20 -1
  135. package/dist/core/research/research-synthesis-writer.js +86 -5
  136. package/dist/core/research/research-work-graph.js +25 -18
  137. package/dist/core/research/source-quality-report.js +21 -0
  138. package/dist/core/research.js +424 -390
  139. package/dist/core/retention.js +70 -2
  140. package/dist/core/routes/constants.js +1 -1
  141. package/dist/core/routes/dollar-manifest-lite.js +11 -11
  142. package/dist/core/routes.js +149 -69
  143. package/dist/core/runtime/task-profile.js +66 -0
  144. package/dist/core/runtime/verification-budget.js +12 -0
  145. package/dist/core/security/high-risk-contracts.js +6 -6
  146. package/dist/core/stop-gate/stop-gate-check.js +49 -12
  147. package/dist/core/subagents/agent-catalog.js +287 -0
  148. package/dist/core/subagents/model-policy.js +259 -0
  149. package/dist/core/subagents/naruto-help-contract.js +47 -0
  150. package/dist/core/subagents/official-subagent-config.js +488 -0
  151. package/dist/core/subagents/official-subagent-preparation.js +297 -0
  152. package/dist/core/subagents/official-subagent-prompt.js +159 -0
  153. package/dist/core/subagents/official-subagent-runner.js +129 -0
  154. package/dist/core/subagents/subagent-evidence.js +663 -0
  155. package/dist/core/subagents/terminology.js +16 -0
  156. package/dist/core/subagents/thread-budget.js +21 -0
  157. package/dist/core/subagents/triwiki-attention.js +168 -0
  158. package/dist/core/super-search/runtime-helpers.js +173 -19
  159. package/dist/core/super-search/runtime.js +140 -15
  160. package/dist/core/super-search/source-records.js +49 -8
  161. package/dist/core/team-review-policy.js +15 -0
  162. package/dist/core/triwiki/code-pack-head-freshness.js +291 -0
  163. package/dist/core/triwiki/triwiki-module-card.js +1 -1
  164. package/dist/core/triwiki-wrongness/wrongness-ledger.js +9 -2
  165. package/dist/core/version-manager.js +51 -1
  166. package/dist/core/version.js +1 -1
  167. package/dist/core/work-order-ledger.js +40 -1
  168. package/dist/core/zellij/zellij-fake-adapter.js +3 -1
  169. package/dist/core/zellij/zellij-launcher.js +49 -10
  170. package/dist/core/zellij/zellij-layout-builder.js +14 -5
  171. package/dist/core/zellij/zellij-official-subagent-activity.js +477 -0
  172. package/dist/core/zellij/zellij-official-subagent-telemetry.js +264 -0
  173. package/dist/core/zellij/zellij-pane-proof.js +9 -1
  174. package/dist/core/zellij/zellij-slot-pane-renderer.js +17 -5
  175. package/dist/core/zellij/zellij-slot-telemetry.js +15 -3
  176. package/dist/core/zellij/zellij-ui-mode.js +1 -1
  177. package/dist/core/zellij/zellij-update.js +14 -1
  178. package/dist/core/zellij/zellij-viewport-binder.js +3 -0
  179. package/dist/scripts/agent-role-config-repair-check.js +14 -16
  180. package/dist/scripts/architecture-guard-check.js +8 -1
  181. package/dist/scripts/canonical-test-runner.js +7 -1
  182. package/dist/scripts/check-route-modularity.js +0 -1
  183. package/dist/scripts/check-ts-contracts.js +1 -1
  184. package/dist/scripts/codex-control-all-pipelines-check.js +7 -3
  185. package/dist/scripts/codex-control-tool-output-continuity-audit-check.js +27 -0
  186. package/dist/scripts/codex-lb-fast-mode-truth-check.js +11 -1
  187. package/dist/scripts/codex-lb-fast-ui-preservation-check.js +9 -2
  188. package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +13 -2
  189. package/dist/scripts/codex-native-agent-role-content-check.js +27 -7
  190. package/dist/scripts/codex-native-repair-transaction-check.js +3 -1
  191. package/dist/scripts/codex-sdk-all-pipelines-check.js +7 -4
  192. package/dist/scripts/codex-sdk-backend-router-check.js +2 -0
  193. package/dist/scripts/codex-sdk-research-pipeline-check.js +30 -8
  194. package/dist/scripts/db-route-materialization-check.js +33 -0
  195. package/dist/scripts/docs-truthfulness-check.js +3 -1
  196. package/dist/scripts/doctor-codex-startup-repair-check.js +12 -15
  197. package/dist/scripts/doctor-fix-production-blackbox.js +12 -2
  198. package/dist/scripts/doctor-startup-config-repair-blackbox.js +8 -2
  199. package/dist/scripts/doctor-startup-config-repair-check.js +12 -2
  200. package/dist/scripts/install-update-preserves-config-check.js +6 -1
  201. package/dist/scripts/lib/codex-sdk-gate-lib.js +4 -0
  202. package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +0 -1
  203. package/dist/scripts/managed-role-manifest-parity-check.js +5 -4
  204. package/dist/scripts/naruto-codex-e2e-check.js +14 -7
  205. package/dist/scripts/naruto-shadow-clone-swarm-check.js +4 -201
  206. package/dist/scripts/npm-publish-performance-check.js +20 -12
  207. package/dist/scripts/official-subagent-workflow-check.js +145 -0
  208. package/dist/scripts/package-published-contract-check.js +6 -29
  209. package/dist/scripts/packlist-performance-check.js +18 -21
  210. package/dist/scripts/parallel-verification-engine-check.js +2 -2
  211. package/dist/scripts/prepublish-release-check-or-fast.js +23 -86
  212. package/dist/scripts/python-codex-sdk-all-pipelines-check.js +8 -0
  213. package/dist/scripts/release-affected-selector-check.js +74 -1
  214. package/dist/scripts/release-check-stamp.js +153 -248
  215. package/dist/scripts/release-dag-full-coverage-check.js +7 -15
  216. package/dist/scripts/release-dynamic-presets-check.js +2 -1
  217. package/dist/scripts/release-gate-dag-runner-check.js +0 -1
  218. package/dist/scripts/release-gate-dag-runner.js +12 -1
  219. package/dist/scripts/release-gate-existence-audit.js +1 -2
  220. package/dist/scripts/release-parallel-full-coverage-check.js +12 -6
  221. package/dist/scripts/release-parallel-speed-budget-check.js +18 -2
  222. package/dist/scripts/release-real-check.js +26 -4
  223. package/dist/scripts/release-registry-check.js +61 -16
  224. package/dist/scripts/research-blueprint-densifier-check.js +2 -2
  225. package/dist/scripts/research-real-cycle-no-legacy-final-md-check.js +11 -7
  226. package/dist/scripts/sizecheck.js +2 -2
  227. package/dist/scripts/sks-3-1-4-directive-check-lib.js +8 -2
  228. package/dist/scripts/sks-3-1-5-directive-check-lib.js +3 -2
  229. package/dist/scripts/sks-3-1-6-directive-check-lib.js +5 -3
  230. package/dist/scripts/sks-menubar-install-check.js +14 -1
  231. package/dist/scripts/super-search-provider-interface-check.js +31 -18
  232. package/dist/scripts/trust-fixture-check.js +32 -10
  233. package/dist/scripts/wrongness-fixture-check.js +1 -1
  234. package/dist/scripts/zellij-layout-valid-check.js +5 -5
  235. package/dist/scripts/zellij-spawn-on-demand-layout-check.js +3 -3
  236. package/docs/demo.tape +1 -1
  237. package/infra-harness-gates.json +1486 -0
  238. package/package.json +15 -10
  239. package/release-gates.v2.json +4060 -0
  240. package/runtime-required-scripts.json +9 -0
  241. package/dist/commands/db.js +0 -6
  242. package/dist/core/commands/db-command.js +0 -146
  243. package/dist/core/research/prompt.js +0 -15
  244. package/dist/scripts/codex-0139-feature-probes-check.js +0 -30
  245. package/dist/scripts/codex-0139-marketplace-source-check.js +0 -13
  246. package/dist/scripts/codex-control-tool-call-sequence-repair-check.js +0 -14
@@ -48,7 +48,7 @@ export const RECALLPULSE_POLICY = Object.freeze({
48
48
  'generated_skill_installation',
49
49
  'codex_app_stop_hooks',
50
50
  'dfix_ultralight_behavior',
51
- 'team_minimum_five_lane_review',
51
+ 'official_subagent_risk_scoped_review_with_legacy_team_compatibility',
52
52
  'research_xhigh_agent_requirements',
53
53
  'db_destructive_operation_blocking',
54
54
  'imagegen_evidence_requirements'
@@ -176,37 +176,19 @@ export const RESEARCH_AGENT_PERSONA_CONTRACT = Object.freeze([
176
176
  id: 'einstein',
177
177
  display_name: 'Einstein Agent',
178
178
  historical_inspiration: 'Albert Einstein',
179
- persona: 'first-principles reframer',
180
- role: 'first_principles_reframer',
181
- mandate: 'Strip assumptions, identify invariants, and build decisive thought experiments.',
182
- required_outputs: ['eureka_moment', 'assumptions_removed', 'invariant_or_simplifying_frame', 'decisive_thought_experiment']
183
- },
184
- {
185
- id: 'feynman',
186
- display_name: 'Feynman Agent',
187
- historical_inspiration: 'Richard Feynman',
188
- persona: 'explanation experimentalist',
189
- role: 'explanation_experimentalist',
190
- mandate: 'Make the idea teachable, testable, and hard to hide behind jargon.',
191
- required_outputs: ['eureka_moment', 'plain_language_mechanism', 'toy_model', 'cheap_empirical_probe']
192
- },
193
- {
194
- id: 'turing',
195
- display_name: 'Turing Agent',
196
- historical_inspiration: 'Alan Turing',
197
- persona: 'formalization and adversarial cases',
198
- role: 'formalization_and_adversarial_cases',
199
- mandate: 'Formalize inputs, outputs, algorithms, limits, and countercases.',
200
- required_outputs: ['eureka_moment', 'formal_definition', 'algorithmic_shape', 'adversarial_case']
179
+ persona: 'first-principles reframer and explanation experimentalist',
180
+ role: 'first_principles_experimental_reframer',
181
+ mandate: 'Strip assumptions, identify invariants, explain the mechanism plainly, and build decisive thought experiments and cheap probes.',
182
+ required_outputs: ['eureka_moment', 'assumptions_removed', 'invariant_or_simplifying_frame', 'plain_language_mechanism', 'decisive_thought_experiment', 'cheap_empirical_probe']
201
183
  },
202
184
  {
203
185
  id: 'von_neumann',
204
186
  display_name: 'von Neumann Agent',
205
187
  historical_inspiration: 'John von Neumann',
206
- persona: 'systems strategy agent',
207
- role: 'systems_strategy_agent',
208
- mandate: 'Map system dynamics, scaling behavior, incentives, and worst-case interactions.',
209
- required_outputs: ['eureka_moment', 'system_model', 'scaling_risk', 'robustness_condition']
188
+ persona: 'formal systems and strategy agent',
189
+ role: 'formal_systems_strategy_agent',
190
+ mandate: 'Formalize inputs, outputs, algorithms, limits, system dynamics, scaling behavior, incentives, and worst-case interactions.',
191
+ required_outputs: ['eureka_moment', 'formal_definition', 'algorithmic_shape', 'adversarial_case', 'system_model', 'scaling_risk', 'robustness_condition']
210
192
  },
211
193
  {
212
194
  id: 'skeptic',
@@ -220,7 +202,9 @@ export const RESEARCH_AGENT_PERSONA_CONTRACT = Object.freeze([
220
202
  ].map((agent) => Object.freeze({
221
203
  ...agent,
222
204
  persona_boundary: 'persona-inspired cognitive lens only; do not impersonate the historical person',
223
- reasoning_effort: 'xhigh',
205
+ custom_agent: 'research_reviewer',
206
+ model: 'gpt-5.6-sol',
207
+ reasoning_effort: 'max',
224
208
  service_tier: 'fast'
225
209
  })));
226
210
  //# sourceMappingURL=policy.js.map
@@ -199,7 +199,7 @@ export async function evaluateRecallPulseFixtures(root, opts = {}) {
199
199
  fixture('repeated-stop-hook-blocker', true, 'Duplicate suppression keys collapse repeated blocker text into one durable status row.'),
200
200
  fixture('hook-only-status-visibility', true, 'mission-status-ledger.json preserves recoverable user-visible status.'),
201
201
  fixture('research-persona-missing', true, 'Research validation blocks missing agent display_name/persona/persona_boundary.'),
202
- fixture('research-effort-not-xhigh', true, 'Research validation blocks non-xhigh agent rows.'),
202
+ fixture('research-model-policy-not-sol-max', true, 'Research validation blocks reviewer rows that are not bound to the research_reviewer GPT-5.6 Sol Max policy.'),
203
203
  fixture('research-eureka-missing', true, 'Research validation blocks missing literal Eureka! ideas.'),
204
204
  fixture('research-impersonation', true, 'Research validation blocks persona-boundary violations.'),
205
205
  fixture('oversized-l1', true, 'L1 token and item limits reject oversized active recall.'),
@@ -368,7 +368,7 @@ export async function buildRecallPulseGovernanceReport(root, opts = {}) {
368
368
  ],
369
369
  migration_paths: {
370
370
  existing_missions: 'Run sks recallpulse run <mission-id> and sks recallpulse governance <mission-id> to add report-only artifacts.',
371
- existing_research_artifacts: 'Research gates now require agent display_name/persona/persona_boundary fields; old ledgers should be migrated by adding those fields before claiming pass.',
371
+ existing_research_artifacts: 'Research gates require agent display_name/persona/persona_boundary fields and the research_reviewer GPT-5.6 Sol Max binding; old ledgers must be migrated before claiming pass.',
372
372
  generated_skills: 'Do not edit generated installed skills directly; rerun init/bootstrap from engine source when generated text needs refreshing.'
373
373
  },
374
374
  release_gate: '0.8.0 remains report-only unless packcheck, selftest, sizecheck, registry metadata check, TriWiki validate, and RecallPulse fixture eval pass.'
@@ -397,8 +397,13 @@ export function validateResearchAgentPersonas(agentLedger = {}, geniusSummaryTex
397
397
  issues.push(`${expected.id}:persona_boundary_missing`);
398
398
  if (row.persona_boundary && !/do not impersonate|not impersonat|lens only/i.test(row.persona_boundary))
399
399
  issues.push(`${expected.id}:persona_boundary_not_enforced`);
400
- if (row.effort !== 'xhigh' && row.reasoning_effort !== 'xhigh')
401
- issues.push(`${expected.id}:effort_not_xhigh`);
400
+ const modelPolicy = row.model_policy && typeof row.model_policy === 'object' ? row.model_policy : row;
401
+ if (modelPolicy.custom_agent !== 'research_reviewer')
402
+ issues.push(`${expected.id}:custom_agent_not_research_reviewer`);
403
+ if (modelPolicy.model !== 'gpt-5.6-sol')
404
+ issues.push(`${expected.id}:model_not_sol`);
405
+ if (modelPolicy.reasoning_effort !== 'max' && modelPolicy.model_reasoning_effort !== 'max')
406
+ issues.push(`${expected.id}:effort_not_max`);
402
407
  if (row.service_tier && row.service_tier !== 'fast')
403
408
  issues.push(`${expected.id}:service_tier_not_fast`);
404
409
  if (!row.eureka?.idea || row.eureka?.exclamation !== 'Eureka!')
@@ -923,13 +928,13 @@ function preservedRoutePersonality(routeId = '', routeName = '') {
923
928
  DFix: 'ultralight direct-fix path stays tiny and does not start the full pipeline',
924
929
  Answer: 'answer-only path stays conversational and does not start implementation',
925
930
  SKS: 'general SKS discovery/help personality stays simple',
926
- Team: 'Team keeps analysis, debate, executor, and five-lane review identity',
931
+ Team: 'Team redirects to the bounded official Naruto workflow with parent-owned integration and risk-scoped review',
927
932
  QALoop: 'QA-LOOP keeps dogfood, checklist, remediation, and reverification identity',
928
933
  PPT: 'PPT keeps restrained information-first HTML/PDF delivery identity',
929
934
  ImageUXReview: 'Image UX Review keeps gpt-image-2 annotated raster review identity',
930
935
  ComputerUse: 'Computer Use keeps maximum-speed native Mac/non-web visual lane identity',
931
936
  Goal: 'Goal stays a native /goal persistence bridge, not a heavyweight route',
932
- Research: 'Research keeps named xhigh persona agent council, Eureka, debate, paper, and falsification identity',
937
+ Research: 'Research keeps Super Search evidence, three composite Sol Max adversarial lenses, bounded revision, paper, and falsification identity',
933
938
  AutoResearch: 'AutoResearch keeps iterative experiment loop identity',
934
939
  DB: 'DB keeps conservative read-first destructive-operation safety identity',
935
940
  MadSKS: 'MAD-SKS keeps explicit scoped high-risk authorization identity',
@@ -0,0 +1,247 @@
1
+ import crypto from 'node:crypto';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ export const NPM_PACK_PROOF_SCHEMA = 'sks.npm-pack-proof.v1';
5
+ export const NPM_PACK_PROOF_COMMAND = Object.freeze(['npm', 'pack', '--dry-run', '--ignore-scripts', '--json']);
6
+ export const PACKLIST_PERFORMANCE_REPORT_SCHEMA = 'sks.packlist-performance.v1';
7
+ export const PACKAGE_SURFACE_BUDGET_REPORT_SCHEMA = 'sks.package-surface-budget.v1';
8
+ export function npmPackProofPath(root) {
9
+ return path.join(root, '.sneakoscope', 'reports', 'npm-pack-proof.json');
10
+ }
11
+ export function writeNpmPackProof(root, info, packMs) {
12
+ const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
13
+ const inputDigest = currentNpmPackInputDigest(root);
14
+ const normalizedInfo = normalizeNpmPackInfo(info);
15
+ const infoDigest = sha256Json(normalizedInfo);
16
+ const fileListDigest = sha256Json(normalizedInfo.files);
17
+ const proof = {
18
+ schema: NPM_PACK_PROOF_SCHEMA,
19
+ ok: true,
20
+ generated_at: new Date().toISOString(),
21
+ command: NPM_PACK_PROOF_COMMAND,
22
+ input_digest: inputDigest,
23
+ info_digest: infoDigest,
24
+ file_list_digest: fileListDigest,
25
+ proof_id: sha256Text(`${NPM_PACK_PROOF_SCHEMA}\n${inputDigest}\n${infoDigest}\n${fileListDigest}\n${String(pkg.name || '')}@${String(pkg.version || '')}`),
26
+ package_name: String(pkg.name || ''),
27
+ package_version: String(pkg.version || ''),
28
+ pack_ms: Math.max(0, Math.floor(Number(packMs) || 0)),
29
+ info
30
+ };
31
+ const file = npmPackProofPath(root);
32
+ fs.mkdirSync(path.dirname(file), { recursive: true });
33
+ fs.writeFileSync(file, `${JSON.stringify(proof, null, 2)}\n`);
34
+ return proof;
35
+ }
36
+ export function readCurrentNpmPackProof(root) {
37
+ const blockers = [];
38
+ const file = npmPackProofPath(root);
39
+ let proof = null;
40
+ try {
41
+ proof = JSON.parse(fs.readFileSync(file, 'utf8'));
42
+ }
43
+ catch {
44
+ blockers.push('npm_pack_proof_missing_or_invalid');
45
+ return { ok: false, proof: null, blockers };
46
+ }
47
+ const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
48
+ if (proof?.schema !== NPM_PACK_PROOF_SCHEMA || proof?.ok !== true)
49
+ blockers.push('npm_pack_proof_schema_invalid');
50
+ if (!sameStringList([...(proof?.command || [])], [...NPM_PACK_PROOF_COMMAND]))
51
+ blockers.push('npm_pack_proof_command_invalid');
52
+ if (proof?.package_name !== pkg.name || proof?.package_version !== pkg.version)
53
+ blockers.push('npm_pack_proof_package_identity_mismatch');
54
+ if (proof?.input_digest !== currentNpmPackInputDigest(root))
55
+ blockers.push('npm_pack_proof_stale');
56
+ if (!proof?.info || !Array.isArray(proof.info.files))
57
+ blockers.push('npm_pack_proof_files_missing');
58
+ if (proof?.info) {
59
+ const normalizedInfo = normalizeNpmPackInfo(proof.info);
60
+ const infoDigest = sha256Json(normalizedInfo);
61
+ const fileListDigest = sha256Json(normalizedInfo.files);
62
+ const expectedProofId = sha256Text(`${NPM_PACK_PROOF_SCHEMA}\n${proof.input_digest}\n${infoDigest}\n${fileListDigest}\n${String(pkg.name || '')}@${String(pkg.version || '')}`);
63
+ if (proof.info_digest !== infoDigest)
64
+ blockers.push('npm_pack_proof_info_digest_mismatch');
65
+ if (proof.file_list_digest !== fileListDigest)
66
+ blockers.push('npm_pack_proof_file_list_digest_mismatch');
67
+ if (proof.proof_id !== expectedProofId)
68
+ blockers.push('npm_pack_proof_id_mismatch');
69
+ }
70
+ return { ok: blockers.length === 0, proof, blockers };
71
+ }
72
+ export function readCurrentNpmPackGateArtifacts(root) {
73
+ const proofResult = readCurrentNpmPackProof(root);
74
+ const blockers = [...proofResult.blockers];
75
+ const packlistReport = readJsonReport(path.join(root, '.sneakoscope', 'reports', 'packlist-performance.json'));
76
+ const packageSurfaceReport = readJsonReport(path.join(root, '.sneakoscope', 'reports', 'package-surface-budget.json'));
77
+ if (!packlistReport)
78
+ blockers.push('packlist_performance_report_missing_or_invalid');
79
+ else {
80
+ if (packlistReport.schema !== PACKLIST_PERFORMANCE_REPORT_SCHEMA || packlistReport.ok !== true)
81
+ blockers.push('packlist_performance_report_schema_invalid');
82
+ if (Array.isArray(packlistReport.blockers) && packlistReport.blockers.length > 0)
83
+ blockers.push('packlist_performance_report_has_blockers');
84
+ if (Array.isArray(packlistReport.forbidden) && packlistReport.forbidden.length > 0)
85
+ blockers.push('packlist_performance_report_forbidden_files');
86
+ if (Array.isArray(packlistReport.runtime_required_missing) && packlistReport.runtime_required_missing.length > 0)
87
+ blockers.push('packlist_performance_report_runtime_files_missing');
88
+ }
89
+ if (!packageSurfaceReport)
90
+ blockers.push('package_surface_report_missing_or_invalid');
91
+ else {
92
+ if (packageSurfaceReport.schema !== PACKAGE_SURFACE_BUDGET_REPORT_SCHEMA || packageSurfaceReport.ok !== true)
93
+ blockers.push('package_surface_report_schema_invalid');
94
+ if (Array.isArray(packageSurfaceReport.blockers) && packageSurfaceReport.blockers.length > 0)
95
+ blockers.push('package_surface_report_has_blockers');
96
+ if (Array.isArray(packageSurfaceReport.forbidden_findings) && packageSurfaceReport.forbidden_findings.length > 0)
97
+ blockers.push('package_surface_report_forbidden_files');
98
+ }
99
+ const info = proofResult.proof?.info;
100
+ if (info && packlistReport) {
101
+ if (packlistReport.pack_proof_id !== proofResult.proof?.proof_id)
102
+ blockers.push('packlist_performance_report_proof_id_mismatch');
103
+ if (packlistReport.pack_info_sha256 !== proofResult.proof?.info_digest)
104
+ blockers.push('packlist_performance_report_info_digest_mismatch');
105
+ if (packlistReport.pack_file_list_sha256 !== proofResult.proof?.file_list_digest)
106
+ blockers.push('packlist_performance_report_file_list_digest_mismatch');
107
+ if (!sameNumber(packlistReport.entryCount, info.entryCount))
108
+ blockers.push('packlist_performance_report_entry_count_mismatch');
109
+ if (!sameNumber(packlistReport.size, info.size))
110
+ blockers.push('packlist_performance_report_size_mismatch');
111
+ if (!sameNumber(packlistReport.unpackedSize, info.unpackedSize))
112
+ blockers.push('packlist_performance_report_unpacked_size_mismatch');
113
+ }
114
+ if (info && packageSurfaceReport) {
115
+ if (packageSurfaceReport.pack_proof_id !== proofResult.proof?.proof_id)
116
+ blockers.push('package_surface_report_proof_id_mismatch');
117
+ if (packageSurfaceReport.pack_info_sha256 !== proofResult.proof?.info_digest)
118
+ blockers.push('package_surface_report_info_digest_mismatch');
119
+ if (packageSurfaceReport.pack_file_list_sha256 !== proofResult.proof?.file_list_digest)
120
+ blockers.push('package_surface_report_file_list_digest_mismatch');
121
+ if (!sameNumber(packageSurfaceReport.actual_file_count, info.entryCount))
122
+ blockers.push('package_surface_report_entry_count_mismatch');
123
+ if (!sameNumber(packageSurfaceReport.actual_tarball_bytes, info.size))
124
+ blockers.push('package_surface_report_size_mismatch');
125
+ }
126
+ return {
127
+ ok: blockers.length === 0,
128
+ proof: proofResult.proof,
129
+ packlist_report: packlistReport,
130
+ package_surface_report: packageSurfaceReport,
131
+ blockers: [...new Set(blockers)]
132
+ };
133
+ }
134
+ export function currentNpmPackInputDigest(root) {
135
+ const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
136
+ const roots = new Set(['package.json', 'package-lock.json', 'npm-shrinkwrap.json', '.npmignore', '.gitignore']);
137
+ for (const entry of fs.readdirSync(root)) {
138
+ if (/^(?:README|LICEN[CS]E|NOTICE)(?:\.|$)/i.test(entry))
139
+ roots.add(entry);
140
+ }
141
+ for (const raw of Array.isArray(pkg.files) ? pkg.files : []) {
142
+ const value = String(raw || '').trim();
143
+ if (!value || value.startsWith('!'))
144
+ continue;
145
+ const prefix = value.split(/[*?]/, 1)[0]?.replace(/\/+$/, '') || '';
146
+ if (prefix)
147
+ roots.add(prefix);
148
+ }
149
+ addPackagePath(roots, pkg.main);
150
+ addPackagePath(roots, pkg.browser);
151
+ if (typeof pkg.bin === 'string')
152
+ addPackagePath(roots, pkg.bin);
153
+ else if (pkg.bin && typeof pkg.bin === 'object')
154
+ for (const value of Object.values(pkg.bin))
155
+ addPackagePath(roots, value);
156
+ if (typeof pkg.man === 'string')
157
+ addPackagePath(roots, pkg.man);
158
+ else if (Array.isArray(pkg.man))
159
+ for (const value of pkg.man)
160
+ addPackagePath(roots, value);
161
+ addPackagePath(roots, pkg.directories?.bin);
162
+ const files = new Set();
163
+ for (const relative of roots)
164
+ collectRoot(root, relative, files);
165
+ const hash = crypto.createHash('sha256');
166
+ for (const relative of [...files].sort()) {
167
+ const file = path.join(root, relative);
168
+ const stat = fs.statSync(file);
169
+ hash.update(relative.replace(/\\/g, '/'));
170
+ hash.update('\0');
171
+ hash.update(String(stat.size));
172
+ hash.update('\0');
173
+ hash.update(crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex'));
174
+ hash.update('\0');
175
+ }
176
+ return hash.digest('hex');
177
+ }
178
+ export function normalizeNpmPackInfo(info = {}) {
179
+ const files = (Array.isArray(info.files) ? info.files : [])
180
+ .map((file) => ({
181
+ path: String(file?.path || '').replace(/\\/g, '/'),
182
+ size: Number(file?.size || 0),
183
+ mode: Number(file?.mode || 0)
184
+ }))
185
+ .filter((file) => file.path)
186
+ .sort((left, right) => left.path.localeCompare(right.path));
187
+ return {
188
+ id: String(info.id || ''),
189
+ name: String(info.name || ''),
190
+ version: String(info.version || ''),
191
+ filename: String(info.filename || ''),
192
+ size: Number(info.size || 0),
193
+ unpackedSize: Number(info.unpackedSize || 0),
194
+ shasum: String(info.shasum || ''),
195
+ integrity: String(info.integrity || ''),
196
+ entryCount: Number(info.entryCount || files.length),
197
+ files
198
+ };
199
+ }
200
+ function addPackagePath(roots, value) {
201
+ const relative = String(value || '').trim().replace(/^\.\//, '');
202
+ if (relative && !path.isAbsolute(relative) && !relative.startsWith('../'))
203
+ roots.add(relative);
204
+ }
205
+ function sha256Json(value) {
206
+ return sha256Text(JSON.stringify(value));
207
+ }
208
+ function sha256Text(value) {
209
+ return crypto.createHash('sha256').update(value).digest('hex');
210
+ }
211
+ function collectRoot(root, relative, out) {
212
+ const target = path.join(root, relative);
213
+ if (!fs.existsSync(target))
214
+ return;
215
+ const stat = fs.statSync(target);
216
+ if (stat.isFile()) {
217
+ out.add(path.relative(root, target));
218
+ return;
219
+ }
220
+ if (!stat.isDirectory())
221
+ return;
222
+ for (const entry of fs.readdirSync(target, { withFileTypes: true })) {
223
+ const child = path.join(relative, entry.name);
224
+ if (entry.isDirectory())
225
+ collectRoot(root, child, out);
226
+ else if (entry.isFile())
227
+ out.add(child);
228
+ }
229
+ }
230
+ function sameStringList(left, right) {
231
+ return left.length === right.length && left.every((value, index) => value === right[index]);
232
+ }
233
+ function readJsonReport(file) {
234
+ try {
235
+ const parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
236
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : null;
237
+ }
238
+ catch {
239
+ return null;
240
+ }
241
+ }
242
+ function sameNumber(left, right) {
243
+ const leftNumber = Number(left);
244
+ const rightNumber = Number(right);
245
+ return Number.isFinite(leftNumber) && Number.isFinite(rightNumber) && leftNumber === rightNumber;
246
+ }
247
+ //# sourceMappingURL=npm-pack-proof.js.map
@@ -0,0 +1,151 @@
1
+ import crypto from 'node:crypto';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ export function packageDistSnapshot(root, pkg) {
5
+ const distRoot = path.join(root, 'dist');
6
+ if (!fs.existsSync(distRoot))
7
+ return { digest: null, file_count: 0 };
8
+ const entries = packageFileEntries(pkg);
9
+ const files = [];
10
+ collectFiles(distRoot, files);
11
+ const included = files
12
+ .filter((file) => packageFileIncluded(`dist/${path.relative(distRoot, file).split(path.sep).join('/')}`, entries))
13
+ .sort();
14
+ const hash = crypto.createHash('sha256');
15
+ for (const file of included) {
16
+ const rel = path.relative(distRoot, file).split(path.sep).join('/');
17
+ const bytes = fs.readFileSync(file);
18
+ hash.update(rel);
19
+ hash.update('\0');
20
+ hash.update(String(bytes.length));
21
+ hash.update('\0');
22
+ hash.update(crypto.createHash('sha256').update(bytes).digest('hex'));
23
+ hash.update('\0');
24
+ }
25
+ return { digest: hash.digest('hex'), file_count: included.length };
26
+ }
27
+ export function packageFilesSnapshot(root, pkg) {
28
+ const entries = packageFileEntries(pkg);
29
+ const candidates = new Set();
30
+ const missingEntries = [];
31
+ for (const entry of entries) {
32
+ if (entry.negated || hasGlob(entry.pattern))
33
+ continue;
34
+ const full = path.join(root, entry.pattern);
35
+ if (!fs.existsSync(full)) {
36
+ missingEntries.push(entry.pattern);
37
+ continue;
38
+ }
39
+ const stat = fs.statSync(full);
40
+ if (stat.isDirectory()) {
41
+ const found = [];
42
+ collectFiles(full, found);
43
+ for (const file of found)
44
+ candidates.add(path.relative(root, file).split(path.sep).join('/'));
45
+ }
46
+ else if (stat.isFile()) {
47
+ candidates.add(entry.pattern);
48
+ }
49
+ }
50
+ const files = [...candidates].filter((file) => packageFileIncluded(file, entries)).sort();
51
+ const hash = crypto.createHash('sha256');
52
+ for (const entry of missingEntries.sort()) {
53
+ hash.update(entry);
54
+ hash.update('\0missing\0');
55
+ }
56
+ for (const file of files) {
57
+ const bytes = fs.readFileSync(path.join(root, file));
58
+ hash.update(file);
59
+ hash.update('\0');
60
+ hash.update(String(bytes.length));
61
+ hash.update('\0');
62
+ hash.update(crypto.createHash('sha256').update(bytes).digest('hex'));
63
+ hash.update('\0');
64
+ }
65
+ return {
66
+ digest: crypto.createHash('sha256').update(hash.digest('hex')).digest('hex'),
67
+ file_count: files.length,
68
+ missing_entries: missingEntries
69
+ };
70
+ }
71
+ function collectFiles(dir, out) {
72
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
73
+ const file = path.join(dir, entry.name);
74
+ if (entry.isDirectory())
75
+ collectFiles(file, out);
76
+ else if (entry.isFile())
77
+ out.push(file);
78
+ }
79
+ }
80
+ function packageFileEntries(pkg) {
81
+ return (Array.isArray(pkg.files) ? pkg.files : [])
82
+ .map((raw) => {
83
+ const value = String(raw || '').trim();
84
+ const negated = value.startsWith('!');
85
+ const pattern = normalizeRel(negated ? value.slice(1) : value);
86
+ return pattern ? { negated, pattern } : null;
87
+ })
88
+ .filter((entry) => entry !== null);
89
+ }
90
+ function packageFileIncluded(file, entries) {
91
+ let included = false;
92
+ for (const entry of entries) {
93
+ if (matchesPackagePattern(file, entry.pattern))
94
+ included = !entry.negated;
95
+ }
96
+ return included;
97
+ }
98
+ function matchesPackagePattern(file, pattern) {
99
+ const rel = normalizeRel(file);
100
+ const normalized = normalizeRel(pattern);
101
+ if (!rel || !normalized)
102
+ return false;
103
+ if (!hasGlob(normalized))
104
+ return rel === normalized || rel.startsWith(`${normalized}/`);
105
+ const re = globPatternToRegExp(normalized);
106
+ if (re.test(rel))
107
+ return true;
108
+ const parts = rel.split('/');
109
+ parts.pop();
110
+ while (parts.length) {
111
+ if (re.test(parts.join('/')))
112
+ return true;
113
+ parts.pop();
114
+ }
115
+ return false;
116
+ }
117
+ function globPatternToRegExp(pattern) {
118
+ let out = '^';
119
+ for (let i = 0; i < pattern.length; i += 1) {
120
+ const char = pattern[i];
121
+ if (char === '*') {
122
+ if (pattern[i + 1] === '*') {
123
+ if (pattern[i + 2] === '/') {
124
+ out += '(?:[^/]+/)*';
125
+ i += 2;
126
+ }
127
+ else {
128
+ out += '.*';
129
+ i += 1;
130
+ }
131
+ }
132
+ else {
133
+ out += '[^/]*';
134
+ }
135
+ continue;
136
+ }
137
+ if (char === '?') {
138
+ out += '[^/]';
139
+ continue;
140
+ }
141
+ out += char.replace(/[|\\{}()[\]^$+?.]/g, '\\$&');
142
+ }
143
+ return new RegExp(`${out}$`);
144
+ }
145
+ function hasGlob(value) {
146
+ return /[*?]/.test(value);
147
+ }
148
+ function normalizeRel(value) {
149
+ return String(value || '').split(path.sep).join('/').replace(/^\.\/+/, '').replace(/\/+$/, '');
150
+ }
151
+ //# sourceMappingURL=package-dist-snapshot.js.map
@@ -1,2 +1,5 @@
1
- export const DEFAULT_MAX_PACK_BYTES = 2414 * 1024;
1
+ // 6.2.0 measured ceiling: next narrow packed boundary.
2
+ export const DEFAULT_MAX_PACK_BYTES = 2428 * 1024;
3
+ // 6.2.0 measured ceiling: next narrow unpacked boundary.
4
+ export const DEFAULT_MAX_UNPACKED_BYTES = 11_141_120;
2
5
  //# sourceMappingURL=package-size-budget.js.map
@@ -0,0 +1,115 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import crypto from 'node:crypto';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { packageDistSnapshot, packageFilesSnapshot } from './package-dist-snapshot.js';
6
+ export const RELEASE_AUTHORIZATION_SNAPSHOT_KEYS = Object.freeze([
7
+ 'git_commit',
8
+ 'source_digest',
9
+ 'source_file_count',
10
+ 'package_files_sha256',
11
+ 'package_file_count',
12
+ 'release_gate_sha256',
13
+ 'dist_build_sha256',
14
+ 'dist_file_count'
15
+ ]);
16
+ export function releaseAuthorizationSnapshot(root, pkg) {
17
+ const source = releaseSourceSnapshot(root);
18
+ const packageFiles = packageFilesSnapshot(root, pkg);
19
+ const dist = packageDistSnapshot(root, pkg);
20
+ return {
21
+ git_commit: gitCommit(root),
22
+ package_files_sha256: packageFiles.digest,
23
+ package_file_count: packageFiles.file_count,
24
+ dist_build_sha256: dist.digest,
25
+ dist_file_count: dist.file_count,
26
+ release_gate_sha256: releaseGateHash(root, pkg),
27
+ source_digest: source.digest,
28
+ source_file_count: source.file_count
29
+ };
30
+ }
31
+ export function sameReleaseAuthorizationSnapshot(left, right) {
32
+ return RELEASE_AUTHORIZATION_SNAPSHOT_KEYS.every((key) => left?.[key] === right?.[key]);
33
+ }
34
+ function gitCommit(root) {
35
+ const result = spawnSync('git', ['rev-parse', 'HEAD'], { cwd: root, encoding: 'utf8' });
36
+ return result.status === 0 ? result.stdout.trim() : null;
37
+ }
38
+ function releaseGateHash(root, pkg) {
39
+ const manifests = ['release-gates.v2.json', 'infra-harness-gates.json'].map((rel) => {
40
+ const file = path.join(root, rel);
41
+ return fs.existsSync(file) ? `${rel}\0${fs.readFileSync(file, 'utf8')}` : `${rel}\0missing`;
42
+ }).join('\0');
43
+ return sha256(`${pkg.scripts?.['release:check'] || ''}\0${pkg.scripts?.['prepublishOnly'] || ''}\0${manifests}`);
44
+ }
45
+ function releaseSourceSnapshot(root) {
46
+ const files = gitFiles(root).filter(releaseRelevant).sort();
47
+ const hash = crypto.createHash('sha256');
48
+ for (const file of files) {
49
+ const full = path.join(root, file);
50
+ let stat;
51
+ try {
52
+ stat = fs.statSync(full);
53
+ }
54
+ catch {
55
+ continue;
56
+ }
57
+ if (!stat.isFile())
58
+ continue;
59
+ const bytes = fs.readFileSync(full);
60
+ hash.update(file);
61
+ hash.update('\0');
62
+ hash.update(String(bytes.length));
63
+ hash.update('\0');
64
+ hash.update(sha256(bytes));
65
+ hash.update('\0');
66
+ }
67
+ return { digest: hash.digest('hex'), file_count: files.length };
68
+ }
69
+ function gitFiles(root) {
70
+ const result = spawnSync('git', ['ls-files', '-z', '--cached', '--others', '--exclude-standard'], {
71
+ cwd: root,
72
+ encoding: 'utf8',
73
+ maxBuffer: 64 * 1024 * 1024
74
+ });
75
+ if (result.status !== 0)
76
+ throw new Error(`unable_to_list_release_files:${result.stderr || result.stdout}`);
77
+ return result.stdout.split('\0').filter(Boolean);
78
+ }
79
+ function releaseRelevant(file) {
80
+ if (!file || file.startsWith('.sneakoscope/') || file.startsWith('.codex/') || file.startsWith('.agents/'))
81
+ return false;
82
+ if (file.startsWith('node_modules/') || file.startsWith('dist/') || file.startsWith('coverage/'))
83
+ return false;
84
+ if (file.startsWith('crates/sks-core/target/'))
85
+ return false;
86
+ if (/\.tgz$|\.log$/i.test(file))
87
+ return false;
88
+ if (/^(package|package-lock)\.json$/.test(file))
89
+ return true;
90
+ if (file === 'release-gates.v2.json' || file === 'infra-harness-gates.json' || file === 'runtime-required-scripts.json')
91
+ return true;
92
+ if (file === '.npmignore' || file === '.npmrc' || file === 'LICENSE')
93
+ return true;
94
+ if (file.startsWith('config/'))
95
+ return true;
96
+ if (/^tsconfig.*\.json$/.test(file))
97
+ return true;
98
+ if (/^(README|CHANGELOG|LICENSE)(\.md)?$/i.test(file))
99
+ return true;
100
+ return [
101
+ '.github/workflows/',
102
+ 'bin/',
103
+ 'src/',
104
+ 'scripts/',
105
+ 'test/',
106
+ 'docs/',
107
+ 'schemas/',
108
+ 'crates/sks-core/Cargo.',
109
+ 'crates/sks-core/src/'
110
+ ].some((prefix) => file.startsWith(prefix));
111
+ }
112
+ function sha256(value) {
113
+ return crypto.createHash('sha256').update(value).digest('hex');
114
+ }
115
+ //# sourceMappingURL=release-authorization-snapshot.js.map
@@ -113,8 +113,8 @@ function selectionResult(all, selected, changedFiles, mode, reasons, skipped) {
113
113
  }
114
114
  };
115
115
  }
116
- function resolveChangedFiles(root, changedSince) {
117
- const base = changedSince === 'auto' ? 'HEAD' : changedSince;
116
+ export function resolveChangedFiles(root, changedSince) {
117
+ const base = changedSince === 'auto' ? autoChangedFilesBase(root) : changedSince;
118
118
  const args = base === 'HEAD'
119
119
  ? ['diff', '--name-only', 'HEAD']
120
120
  : ['diff', '--name-only', String(base)];
@@ -126,6 +126,18 @@ function resolveChangedFiles(root, changedSince) {
126
126
  ].map((file) => file.trim()).filter(Boolean);
127
127
  return [...new Set(files)].sort();
128
128
  }
129
+ function autoChangedFilesBase(root) {
130
+ const upstream = spawnSync('git', ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{upstream}'], {
131
+ cwd: root,
132
+ encoding: 'utf8'
133
+ });
134
+ const upstreamRef = upstream.status === 0 ? String(upstream.stdout || '').trim() : '';
135
+ if (!upstreamRef)
136
+ return 'HEAD';
137
+ const mergeBase = spawnSync('git', ['merge-base', 'HEAD', upstreamRef], { cwd: root, encoding: 'utf8' });
138
+ const base = mergeBase.status === 0 ? String(mergeBase.stdout || '').trim() : '';
139
+ return base || 'HEAD';
140
+ }
129
141
  function gateCommandReferencesScript(gate, file) {
130
142
  const base = file.replace(/\\/g, '/').split('/').pop()?.replace(/\.(ts|tsx)$/, '') || '';
131
143
  if (!base)