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
@@ -3,8 +3,11 @@ import { ensureDir, nowIso, readJson, sha256, writeJsonAtomic, writeTextAtomic }
3
3
  import { runCodexWebSearch } from '../codex/codex-web-search-adapter.js';
4
4
  import { humanizeBlockers } from '../errors/blocker-humanizer.js';
5
5
  import { ensureProviderCapability } from '../provider/provider-self-heal.js';
6
- import { buildAttemptLedger, buildClaims, buildConvergence, buildLeads, buildProof, buildXDiscoverySources, dedupeSources, extractFirstUrl, normalizeGenericSourceRows, renderSynthesis, sourceFromUrlFetch, sourceFromWebRow } from './runtime-helpers.js';
6
+ import { buildAttemptLedger, buildClaims, buildConvergence, buildLeads, buildProof, buildXDiscoverySources, dedupeSources, extractFirstUrl, materializeContext7SourceRows, renderSynthesis, sourceFromUrlFetch, sourceFromWebRow } from './runtime-helpers.js';
7
7
  export async function runSuperSearch(input) {
8
+ const operationDeadlineMs = resolveSuperSearchDeadline(input);
9
+ if (operationDeadlineMs <= Date.now())
10
+ throw new Error('research_cycle_timeout_exceeded');
8
11
  const root = path.resolve(input.root || process.cwd());
9
12
  const missionDir = path.resolve(input.missionDir);
10
13
  const missionId = input.missionId || path.basename(missionDir);
@@ -27,6 +30,7 @@ export async function runSuperSearch(input) {
27
30
  const sourceRows = [];
28
31
  const warnings = [...providerPlan.warnings];
29
32
  const blockers = [...providerPlan.blockers];
33
+ const queryExecutionRows = [];
30
34
  let providerSelfHeal;
31
35
  if (!providerPlan.selected_providers.length && mode !== 'url_acquisition') {
32
36
  if (!input.offline) {
@@ -51,28 +55,74 @@ export async function runSuperSearch(input) {
51
55
  blockers.push('source_acquisition_unavailable');
52
56
  }
53
57
  if (input.context7 && providerPlan.selected_providers.includes('context7')) {
54
- const raw = await input.context7(queryVariants[0] || input.query);
55
- sourceRows.push(...normalizeGenericSourceRows(raw, 'context7', 'official_docs', intent, 'A0'));
58
+ try {
59
+ const query = queryVariants[0] || input.query;
60
+ const raw = await raceSuperSearchOperation(input.context7(query), operationDeadlineMs);
61
+ const normalized = await materializeContext7SourceRows(raw, artifactDir, intent);
62
+ sourceRows.push(...normalized);
63
+ queryExecutionRows.push({ query, status: 'completed', source_count: normalized.length, blockers: [], warnings: [] });
64
+ }
65
+ catch (error) {
66
+ const blocker = `context7_query_failed:${error instanceof Error ? error.message : String(error)}`;
67
+ blockers.push(blocker);
68
+ queryExecutionRows.push({ query: queryVariants[0] || input.query, status: 'failed', source_count: 0, blockers: [blocker], warnings: [] });
69
+ }
56
70
  }
57
71
  else if (intent === 'official_documentation' && !input.offline) {
58
72
  warnings.push('context7_not_invoked_for_docs_query');
59
73
  }
60
74
  if (providerPlan.selected_providers.includes('codex_web')) {
61
- const webEvidence = await runCodexWebSearch(queryVariants[0] || input.query, {
62
- ...(input.codexWebSearch ? { search: input.codexWebSearch } : {}),
63
- artifactDir,
64
- ...(input.offline === undefined ? {} : { offline: input.offline }),
65
- ...(input.env ? { env: input.env } : {})
75
+ const queries = queryVariants.slice(0, queryBudget(mode, input.maxQueryVariants));
76
+ const webRows = await raceSuperSearchOperation(Promise.all(queries.map(async (query) => {
77
+ try {
78
+ const evidence = await runCodexWebSearch(query, {
79
+ ...(input.codexWebSearch ? { search: input.codexWebSearch } : {}),
80
+ artifactDir,
81
+ ...(input.offline === undefined ? {} : { offline: input.offline }),
82
+ ...(input.env ? { env: input.env } : {})
83
+ });
84
+ return { query, evidence, error: null };
85
+ }
86
+ catch (error) {
87
+ return { query, evidence: null, error: error instanceof Error ? error.message : String(error) };
88
+ }
89
+ })), operationDeadlineMs);
90
+ for (const row of webRows) {
91
+ if (!row.evidence) {
92
+ const blocker = `codex_web_query_failed:${row.error || 'unknown'}`;
93
+ blockers.push(blocker);
94
+ queryExecutionRows.push({ query: row.query, status: 'failed', source_count: 0, blockers: [blocker], warnings: [] });
95
+ continue;
96
+ }
97
+ if (row.evidence.blockers.length)
98
+ blockers.push(...row.evidence.blockers);
99
+ warnings.push(...row.evidence.warnings);
100
+ const normalized = row.evidence.normalized_results.map((result, index) => sourceFromWebRow(result, index, intent));
101
+ sourceRows.push(...normalized);
102
+ queryExecutionRows.push({
103
+ query: row.query,
104
+ status: row.evidence.status === 'completed' ? 'completed' : 'skipped',
105
+ source_count: normalized.length,
106
+ blockers: [...row.evidence.blockers],
107
+ warnings: [...row.evidence.warnings]
108
+ });
109
+ }
110
+ const hydrated = await hydrateDiscoverySources(sourceRows, artifactDir, intent, {
111
+ allowLocal: input.allowLocalFetch === true,
112
+ limit: hydrationBudget(mode, input.maxHydratedSources),
113
+ deadlineEpochMs: operationDeadlineMs
66
114
  });
67
- if (webEvidence.blockers.length)
68
- blockers.push(...webEvidence.blockers);
69
- warnings.push(...webEvidence.warnings);
70
- sourceRows.push(...webEvidence.normalized_results.map((row, index) => sourceFromWebRow(row, index, intent)));
115
+ sourceRows.push(...hydrated.sources);
116
+ if (hydrated.sources.length)
117
+ warnings.push(...hydrated.blockers.map((blocker) => `partial_hydration:${blocker}`));
118
+ else
119
+ blockers.push(...hydrated.blockers);
120
+ warnings.push(...hydrated.warnings);
71
121
  }
72
122
  if (mode === 'url_acquisition') {
73
123
  const url = extractFirstUrl(input.query);
74
124
  if (url) {
75
- const fetched = await sourceFromUrlFetch(url, artifactDir, intent, { allowLocal: input.allowLocalFetch === true });
125
+ const fetched = await sourceFromUrlFetch(url, artifactDir, intent, { allowLocal: input.allowLocalFetch === true, deadlineEpochMs: operationDeadlineMs });
76
126
  sourceRows.push(fetched.source);
77
127
  blockers.push(...fetched.blockers);
78
128
  warnings.push(...fetched.warnings);
@@ -102,6 +152,13 @@ export async function runSuperSearch(input) {
102
152
  intent,
103
153
  axes,
104
154
  query_variants: queryVariants,
155
+ query_execution: {
156
+ schema: 'sks.super-search-query-execution.v1',
157
+ planned: queryExecutionRows.length,
158
+ completed: queryExecutionRows.filter((row) => row.status === 'completed').length,
159
+ failed: queryExecutionRows.filter((row) => row.status === 'failed').length,
160
+ rows: queryExecutionRows
161
+ },
105
162
  provider_plan: providerPlan,
106
163
  sources: deduped,
107
164
  leads,
@@ -250,6 +307,7 @@ async function writeArtifacts(artifactDir, result) {
250
307
  await writeJsonAtomic(path.join(artifactDir, 'intent.json'), { schema: 'sks.super-search-intent.v1', intent: result.intent, mode: result.mode });
251
308
  await writeJsonAtomic(path.join(artifactDir, 'axes.json'), { schema: 'sks.super-search-axes.v1', axes: result.axes });
252
309
  await writeJsonAtomic(path.join(artifactDir, 'query-variants.json'), { schema: 'sks.super-search-query-variants.v1', query_variants: result.query_variants });
310
+ await writeJsonAtomic(path.join(artifactDir, 'query-execution.json'), result.query_execution);
253
311
  await writeJsonAtomic(path.join(artifactDir, 'provider-plan.json'), { schema: 'sks.super-search-provider-plan.v1', ...result.provider_plan });
254
312
  await writeJsonAtomic(path.join(artifactDir, 'source-ledger.json'), { schema: 'sks.super-search-source-ledger.v1', sources: result.sources });
255
313
  await writeJsonAtomic(path.join(artifactDir, 'lead-ledger.json'), { schema: 'sks.super-search-lead-ledger.v1', leads: result.leads });
@@ -271,7 +329,9 @@ async function writeArtifacts(artifactDir, result) {
271
329
  passed: result.proof.ok,
272
330
  execution_class: 'production',
273
331
  mock_only: false,
274
- replacement_state: result.proof.ok ? 'usable_provider_independent_runtime' : 'replacement_incomplete',
332
+ replacement_state: result.proof.ok
333
+ ? (result.proof.provider_independent ? 'usable_provider_independent_runtime' : 'usable_verified_runtime')
334
+ : 'replacement_incomplete',
275
335
  blockers: result.proof.blockers,
276
336
  human_summary: blockerDiagnostics.human_summary,
277
337
  next_actions: [
@@ -288,7 +348,7 @@ async function writeArtifacts(artifactDir, result) {
288
348
  await writeJsonAtomic(path.join(artifactDir, 'super-search-result.json'), result);
289
349
  }
290
350
  async function readCache(artifactDir, query, mode) {
291
- const key = sha256(JSON.stringify({ query: query.trim().toLowerCase(), mode, adapter: 'super-search-runtime-v1' })).slice(0, 16);
351
+ const key = sha256(JSON.stringify({ query: query.trim().toLowerCase(), mode, adapter: 'super-search-runtime-v2' })).slice(0, 16);
292
352
  const artifact = path.join(artifactDir, 'cache', `${key}.json`);
293
353
  const ttl_ms = mode === 'x_search' ? 2 * 60 * 1000 : mode === 'offline_cache' ? 7 * 24 * 60 * 60 * 1000 : 10 * 60 * 1000;
294
354
  const cached = await readJson(artifact, null);
@@ -297,4 +357,69 @@ async function readCache(artifactDir, query, mode) {
297
357
  const age_ms = Date.now() - Date.parse(cached.generated_at);
298
358
  return { key, artifact, ttl_ms, hit: true, stale: age_ms > ttl_ms, age_ms, result: cached };
299
359
  }
360
+ function queryBudget(mode, explicit) {
361
+ if (Number.isFinite(Number(explicit)))
362
+ return Math.max(1, Math.min(8, Math.floor(Number(explicit))));
363
+ if (mode === 'fast' || mode === 'url_acquisition' || mode === 'offline_cache')
364
+ return 1;
365
+ if (mode === 'balanced' || mode === 'x_search')
366
+ return 3;
367
+ if (mode === 'deep')
368
+ return 5;
369
+ return 8;
370
+ }
371
+ function hydrationBudget(mode, explicit) {
372
+ if (Number.isFinite(Number(explicit)))
373
+ return Math.max(0, Math.min(8, Math.floor(Number(explicit))));
374
+ if (mode === 'fast' || mode === 'url_acquisition' || mode === 'offline_cache')
375
+ return 1;
376
+ if (mode === 'balanced' || mode === 'x_search')
377
+ return 3;
378
+ if (mode === 'deep')
379
+ return 5;
380
+ return 8;
381
+ }
382
+ async function hydrateDiscoverySources(sources, artifactDir, intent, opts) {
383
+ const urls = [...new Set(sources
384
+ .filter((source) => source.acquisition_verdict !== 'verified_content')
385
+ .map((source) => source.canonical_url || source.original_url)
386
+ .filter((url) => Boolean(url)))]
387
+ .slice(0, opts.limit);
388
+ if (!urls.length)
389
+ return { sources: [], blockers: [], warnings: [] };
390
+ const rows = await raceSuperSearchOperation(Promise.all(urls.map((url) => sourceFromUrlFetch(url, artifactDir, intent, { allowLocal: opts.allowLocal, deadlineEpochMs: opts.deadlineEpochMs }))), opts.deadlineEpochMs);
391
+ const verified = rows.filter((row) => row.source.acquisition_verdict === 'verified_content').map((row) => row.source);
392
+ const blockers = rows.flatMap((row) => row.source.acquisition_verdict === 'verified_content' ? [] : row.blockers);
393
+ const warnings = rows.flatMap((row) => row.warnings);
394
+ return { sources: verified, blockers, warnings };
395
+ }
396
+ function resolveSuperSearchDeadline(input) {
397
+ const hard = Number(input.hardTimeoutMs);
398
+ const absolute = Number(input.deadlineEpochMs);
399
+ const candidates = [
400
+ Number.isFinite(hard) && hard > 0 ? Date.now() + hard : Number.POSITIVE_INFINITY,
401
+ Number.isFinite(absolute) && absolute > 0 ? absolute : Number.POSITIVE_INFINITY
402
+ ];
403
+ const deadline = Math.min(...candidates);
404
+ return Number.isFinite(deadline) ? deadline : Date.now() + 120_000;
405
+ }
406
+ async function raceSuperSearchOperation(promise, deadlineEpochMs) {
407
+ const remainingMs = Math.max(0, Math.floor(deadlineEpochMs - Date.now()));
408
+ if (remainingMs <= 0)
409
+ throw new Error('research_cycle_timeout_exceeded');
410
+ let timer = null;
411
+ try {
412
+ return await Promise.race([
413
+ promise,
414
+ new Promise((_resolve, reject) => {
415
+ timer = setTimeout(() => reject(new Error('research_cycle_timeout_exceeded')), remainingMs);
416
+ timer.unref?.();
417
+ })
418
+ ]);
419
+ }
420
+ finally {
421
+ if (timer)
422
+ clearTimeout(timer);
423
+ }
424
+ }
300
425
  //# sourceMappingURL=runtime.js.map
@@ -17,8 +17,16 @@ export function makeSource(opts) {
17
17
  const now = nowIso();
18
18
  const canonical = opts.url ? canonicalizeUrl(opts.url) : null;
19
19
  const domain = canonical ? safeDomain(canonical) : null;
20
- const content = `${opts.title}\n${opts.snippet}`;
21
- const verified = opts.verdict === 'verified_content';
20
+ const verifiedArtifact = Boolean(opts.contentArtifact)
21
+ && /^[a-f0-9]{32,}$/i.test(String(opts.contentSha256 || ''))
22
+ && Number(opts.contentLength || 0) > 0;
23
+ const requestedVerified = opts.verdict === 'verified_content';
24
+ const verdict = requestedVerified && !verifiedArtifact ? 'weak_content' : opts.verdict;
25
+ const verified = verdict === 'verified_content';
26
+ const blockers = [
27
+ ...(opts.blockers || []),
28
+ ...(requestedVerified && !verifiedArtifact ? ['verified_content_artifact_missing'] : [])
29
+ ];
22
30
  return {
23
31
  source_id: `src-${sha256(`${opts.providerId}:${canonical || opts.title}:${opts.snippet}`).slice(0, 12)}`,
24
32
  provider_id: opts.providerId,
@@ -35,23 +43,56 @@ export function makeSource(opts) {
35
43
  language: null,
36
44
  snippet: opts.snippet,
37
45
  content_artifact: opts.contentArtifact ?? null,
38
- content_sha256: opts.contentSha256 ?? (content.trim() ? sha256(content) : null),
39
- content_length: opts.contentLength ?? (content.trim().length || null),
40
- acquisition_verdict: opts.verdict,
46
+ content_sha256: opts.contentSha256 ?? null,
47
+ content_length: opts.contentLength ?? null,
48
+ acquisition_verdict: verdict,
41
49
  acquisition_path: opts.path,
42
50
  authority_tier: opts.authority,
43
51
  freshness_score: 0.5,
44
52
  relevance_score: 0.6,
45
- trust_score: verified ? 0.9 : opts.verdict === 'weak_content' ? 0.55 : 0.35,
53
+ trust_score: verified ? 0.9 : verdict === 'weak_content' ? 0.55 : 0.35,
46
54
  primary_source: opts.primary,
47
55
  authenticated_source: false,
48
56
  local_only_raw: false,
49
57
  duplicate_cluster_id: null,
50
- independence_cluster_id: domain || opts.providerId,
58
+ independence_cluster_id: independenceClusterForDomain(domain) || opts.providerId,
51
59
  warnings: opts.warnings || [],
52
- blockers: opts.blockers || []
60
+ blockers
53
61
  };
54
62
  }
63
+ export function independenceClusterForDomain(value) {
64
+ const host = String(value || '').trim().toLowerCase().replace(/^\.+|\.+$/g, '');
65
+ if (!host)
66
+ return null;
67
+ const ownership = knownOwnershipCluster(host);
68
+ if (ownership)
69
+ return ownership;
70
+ const labels = host.split('.').filter(Boolean);
71
+ if (labels.length <= 2)
72
+ return host;
73
+ const publicSuffix = labels.slice(-2).join('.');
74
+ const multiLabelSuffixes = new Set([
75
+ 'co.uk', 'org.uk', 'ac.uk', 'gov.uk', 'com.au', 'net.au', 'org.au',
76
+ 'co.jp', 'ne.jp', 'or.jp', 'com.br', 'com.cn', 'com.sg', 'co.kr', 'co.nz'
77
+ ]);
78
+ return multiLabelSuffixes.has(publicSuffix)
79
+ ? labels.slice(-3).join('.')
80
+ : labels.slice(-2).join('.');
81
+ }
82
+ function knownOwnershipCluster(host) {
83
+ const groups = [
84
+ ['owner:openai', ['openai.com', 'chatgpt.com']],
85
+ ['owner:x', ['x.com', 'twitter.com']],
86
+ ['owner:github', ['github.com', 'githubusercontent.com', 'githubassets.com']],
87
+ ['owner:google', ['google.com', 'youtube.com', 'googleusercontent.com']],
88
+ ['owner:microsoft', ['microsoft.com', 'azure.com', 'visualstudio.com']]
89
+ ];
90
+ for (const [cluster, domains] of groups) {
91
+ if (domains.some((domain) => host === domain || host.endsWith(`.${domain}`)))
92
+ return cluster;
93
+ }
94
+ return null;
95
+ }
55
96
  function canonicalizeUrl(raw) {
56
97
  try {
57
98
  const url = new URL(raw);
@@ -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;
@@ -0,0 +1,291 @@
1
+ import fsp from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { readJson, runProcess, writeJsonAtomic } from '../fsx.js';
4
+ const CODE_PACK_METADATA_PATHS = new Set([
5
+ '.sneakoscope/wiki/code-pack.json',
6
+ '.sneakoscope/wiki/code-pack.prev.json'
7
+ ]);
8
+ const COMMIT_MARKER = '@SKS-CODE-PACK';
9
+ const ADVISORY_CACHE_SCHEMA = 'sks.code-pack-head-freshness-cache.v1';
10
+ const ADVISORY_CACHE_PATH = path.join('.sneakoscope', 'cache', 'code-pack-head-freshness.json');
11
+ export async function inspectCodePackHeadFreshness(root, packShaInput, opts = {}) {
12
+ const timeoutMs = Math.max(1, Math.floor(opts.timeoutMs ?? 5_000));
13
+ const startedAt = Date.now();
14
+ const packSha = normalizeGitSha(packShaInput);
15
+ const fastHead = await readGitHeadFromAdminFiles(root);
16
+ if (!packSha)
17
+ return staleWithCurrentHead(root, null, timeoutMs, fastHead, false, 'invalid_pack_sha');
18
+ if (fastHead === packSha)
19
+ return freshness(true, true, 'exact_head', fastHead, packSha, false, []);
20
+ // Only the non-blocking hook consumes this cache. Authoritative wiki
21
+ // validation always replays Git history and never trusts advisory state.
22
+ if (opts.advisoryCache && fastHead) {
23
+ const cached = await readAdvisoryCache(root, packSha, fastHead);
24
+ if (cached)
25
+ return cached;
26
+ }
27
+ // One common-path Git process returns HEAD plus every committed path after
28
+ // the pack was generated. Excluding all parents of packSha keeps packSha in
29
+ // the walk (including a root commit), so its presence proves ancestry. We
30
+ // keep scanning after the pack marker because a later merge can introduce
31
+ // sibling-branch commits that Git orders after packSha. `-m` exposes merge
32
+ // resolution paths and `--no-renames` makes touched paths auditable.
33
+ const history = await runProcess('git', [
34
+ '-c',
35
+ 'core.quotepath=true',
36
+ 'log',
37
+ '--topo-order',
38
+ '-m',
39
+ '--no-ext-diff',
40
+ `--format=${COMMIT_MARKER}%x09%H`,
41
+ '--name-status',
42
+ '--no-renames',
43
+ 'HEAD',
44
+ '--not',
45
+ `${packSha}^@`,
46
+ '--'
47
+ ], {
48
+ cwd: root,
49
+ timeoutMs,
50
+ maxOutputBytes: 64 * 1024,
51
+ env: gitEnvironment({
52
+ GIT_NO_REPLACE_OBJECTS: '1',
53
+ GIT_OPTIONAL_LOCKS: '0',
54
+ LC_ALL: 'C'
55
+ })
56
+ }).catch(() => null);
57
+ if (!history || history.code !== 0 || history.timedOut) {
58
+ return staleWithCurrentHead(root, packSha, remainingMs(startedAt, timeoutMs), fastHead, false, history?.timedOut ? 'git_timeout' : 'git_failed');
59
+ }
60
+ const parsed = parseHistory(history.stdout, packSha);
61
+ if (history.truncated || !parsed.currentSha || parsed.invalid) {
62
+ const currentSha = parsed.currentSha
63
+ || fastHead
64
+ || await readCurrentHead(root, remainingMs(startedAt, timeoutMs));
65
+ return freshness(false, false, history.truncated ? 'history_truncated' : 'history_parse_invalid', currentSha, packSha, false, parsed.changedPaths);
66
+ }
67
+ if (!parsed.sawPack) {
68
+ return freshness(false, true, 'pack_not_ancestor', parsed.currentSha, packSha, false, parsed.changedPaths);
69
+ }
70
+ const metadataOnly = parsed.changedPaths.every((value) => CODE_PACK_METADATA_PATHS.has(value));
71
+ const exactHead = parsed.currentSha === packSha;
72
+ const result = freshness(metadataOnly, true, metadataOnly ? 'metadata_only_history' : 'source_change_history', parsed.currentSha, packSha, metadataOnly && !exactHead, parsed.changedPaths);
73
+ if (opts.advisoryCache && fastHead === parsed.currentSha) {
74
+ await writeAdvisoryCache(root, result).catch(() => undefined);
75
+ }
76
+ return result;
77
+ }
78
+ function parseHistory(stdout, packSha) {
79
+ let currentSha = null;
80
+ let activeCommit = null;
81
+ let sawPack = false;
82
+ let invalid = false;
83
+ const changedPaths = [];
84
+ const seenPaths = new Set();
85
+ for (const line of String(stdout || '').split(/\r?\n/)) {
86
+ if (line === '')
87
+ continue;
88
+ const marker = line.match(/^@SKS-CODE-PACK\t([0-9a-f]{40,64})$/i);
89
+ if (marker) {
90
+ activeCommit = String(marker[1]).toLowerCase();
91
+ currentSha ||= activeCommit;
92
+ if (activeCommit === packSha)
93
+ sawPack = true;
94
+ continue;
95
+ }
96
+ if (!activeCommit) {
97
+ invalid = true;
98
+ break;
99
+ }
100
+ const separator = line.indexOf('\t');
101
+ const status = separator > 0 ? line.slice(0, separator) : '';
102
+ const pathText = separator > 0 ? line.slice(separator + 1) : '';
103
+ if (!/^[A-Z][0-9]*$/.test(status) || !pathText) {
104
+ invalid = true;
105
+ break;
106
+ }
107
+ if (activeCommit === packSha)
108
+ continue;
109
+ // Do not trim Git paths: leading/trailing whitespace is meaningful and
110
+ // must never be normalized into an allowlisted metadata path.
111
+ for (const changedPath of pathText.split('\t')) {
112
+ if (!changedPath || seenPaths.has(changedPath))
113
+ continue;
114
+ seenPaths.add(changedPath);
115
+ changedPaths.push(changedPath);
116
+ }
117
+ }
118
+ return { currentSha, sawPack, invalid, changedPaths };
119
+ }
120
+ async function readAdvisoryCache(root, packSha, currentSha) {
121
+ const cached = await readJson(path.join(root, ADVISORY_CACHE_PATH), null).catch(() => null);
122
+ if (cached?.schema !== ADVISORY_CACHE_SCHEMA)
123
+ return null;
124
+ if (normalizeGitSha(cached.pack_sha) !== packSha || normalizeGitSha(cached.current_sha) !== currentSha)
125
+ return null;
126
+ const changedPaths = Array.isArray(cached.changed_paths)
127
+ ? cached.changed_paths.filter((value) => typeof value === 'string').slice(0, 64)
128
+ : [];
129
+ const fresh = cached.fresh === true;
130
+ if (fresh && (cached.metadata_only_drift !== true || changedPaths.some((value) => !CODE_PACK_METADATA_PATHS.has(value)))) {
131
+ return null;
132
+ }
133
+ return freshness(fresh, true, 'advisory_cache', currentSha, packSha, fresh, changedPaths);
134
+ }
135
+ async function writeAdvisoryCache(root, result) {
136
+ if (!result.pack_sha || !result.current_sha)
137
+ return;
138
+ await writeJsonAtomic(path.join(root, ADVISORY_CACHE_PATH), {
139
+ schema: ADVISORY_CACHE_SCHEMA,
140
+ pack_sha: result.pack_sha,
141
+ current_sha: result.current_sha,
142
+ fresh: result.fresh,
143
+ reason: result.reason,
144
+ metadata_only_drift: result.metadata_only_drift,
145
+ changed_paths: result.changed_paths.slice(0, 64),
146
+ checked_at: new Date().toISOString()
147
+ });
148
+ }
149
+ async function staleWithCurrentHead(root, packSha, timeoutMs, knownCurrentSha = null, conclusive = true, reason = 'git_failed') {
150
+ const currentSha = knownCurrentSha || await readCurrentHead(root, timeoutMs);
151
+ return freshness(false, conclusive, reason, currentSha, packSha, false, []);
152
+ }
153
+ async function readCurrentHead(root, timeoutMs) {
154
+ if (timeoutMs <= 0)
155
+ return null;
156
+ const head = await runProcess('git', ['rev-parse', 'HEAD'], {
157
+ cwd: root,
158
+ timeoutMs,
159
+ maxOutputBytes: 4 * 1024,
160
+ env: gitEnvironment({
161
+ GIT_NO_REPLACE_OBJECTS: '1',
162
+ GIT_OPTIONAL_LOCKS: '0',
163
+ LC_ALL: 'C'
164
+ })
165
+ }).catch(() => null);
166
+ return head && head.code === 0 && !head.truncated ? normalizeGitSha(head.stdout) : null;
167
+ }
168
+ async function readGitHeadFromAdminFiles(root) {
169
+ const gitDir = await resolveGitDir(root);
170
+ if (!gitDir)
171
+ return null;
172
+ const headText = await readSmallText(path.join(gitDir, 'HEAD'), 4 * 1024);
173
+ if (!headText)
174
+ return null;
175
+ const detached = normalizeGitSha(headText);
176
+ if (detached)
177
+ return detached;
178
+ const symbolic = headText.match(/^ref:\s*(refs\/[^\r\n]+)\s*$/);
179
+ const ref = symbolic ? String(symbolic[1]) : '';
180
+ if (!safeGitRef(ref))
181
+ return null;
182
+ const commonDir = await resolveCommonDir(gitDir);
183
+ for (const base of [...new Set([gitDir, commonDir])]) {
184
+ const loose = await readLooseRef(base, ref);
185
+ if (loose)
186
+ return loose;
187
+ }
188
+ return readPackedRef(commonDir, ref);
189
+ }
190
+ async function resolveGitDir(root) {
191
+ const dotGit = path.join(root, '.git');
192
+ const stat = await fsp.stat(dotGit).catch(() => null);
193
+ if (!stat)
194
+ return null;
195
+ if (stat.isDirectory())
196
+ return dotGit;
197
+ if (!stat.isFile())
198
+ return null;
199
+ const text = await readSmallText(dotGit, 4 * 1024);
200
+ const match = text?.match(/^gitdir:\s*(.+?)\s*$/m);
201
+ return match ? path.resolve(path.dirname(dotGit), String(match[1])) : null;
202
+ }
203
+ async function resolveCommonDir(gitDir) {
204
+ const text = await readSmallText(path.join(gitDir, 'commondir'), 4 * 1024);
205
+ return text?.trim() ? path.resolve(gitDir, text.trim()) : gitDir;
206
+ }
207
+ async function readLooseRef(base, ref) {
208
+ const file = safeRefPath(base, ref);
209
+ if (!file)
210
+ return null;
211
+ return normalizeGitSha(await readSmallText(file, 4 * 1024));
212
+ }
213
+ async function readPackedRef(commonDir, ref) {
214
+ const text = await readSmallText(path.join(commonDir, 'packed-refs'), 4 * 1024 * 1024);
215
+ if (!text)
216
+ return null;
217
+ for (const line of text.split(/\r?\n/)) {
218
+ if (!line || line.startsWith('#') || line.startsWith('^'))
219
+ continue;
220
+ const separator = line.indexOf(' ');
221
+ if (separator <= 0 || line.slice(separator + 1) !== ref)
222
+ continue;
223
+ return normalizeGitSha(line.slice(0, separator));
224
+ }
225
+ return null;
226
+ }
227
+ async function readSmallText(file, maxBytes) {
228
+ const stat = await fsp.stat(file).catch(() => null);
229
+ if (!stat?.isFile() || stat.size > maxBytes)
230
+ return null;
231
+ return fsp.readFile(file, 'utf8').catch(() => null);
232
+ }
233
+ function safeGitRef(ref) {
234
+ return /^refs\/[A-Za-z0-9._/-]+$/.test(ref)
235
+ && !ref.includes('..')
236
+ && !ref.includes('//')
237
+ && !ref.includes('@{')
238
+ && !ref.endsWith('/')
239
+ && !ref.endsWith('.')
240
+ && !ref.endsWith('.lock');
241
+ }
242
+ function safeRefPath(base, ref) {
243
+ if (!safeGitRef(ref))
244
+ return null;
245
+ const candidate = path.resolve(base, ...ref.split('/'));
246
+ const relative = path.relative(path.resolve(base), candidate);
247
+ return relative && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative) ? candidate : null;
248
+ }
249
+ function remainingMs(startedAt, timeoutMs) {
250
+ return Math.max(0, timeoutMs - (Date.now() - startedAt));
251
+ }
252
+ function gitEnvironment(extra = {}) {
253
+ return {
254
+ GIT_ALTERNATE_OBJECT_DIRECTORIES: undefined,
255
+ GIT_COMMON_DIR: undefined,
256
+ GIT_CONFIG: undefined,
257
+ GIT_CONFIG_COUNT: '0',
258
+ GIT_CONFIG_GLOBAL: undefined,
259
+ GIT_CONFIG_NOSYSTEM: undefined,
260
+ GIT_CONFIG_PARAMETERS: undefined,
261
+ GIT_CONFIG_SYSTEM: undefined,
262
+ GIT_DIR: undefined,
263
+ GIT_DISCOVERY_ACROSS_FILESYSTEM: undefined,
264
+ GIT_EXTERNAL_DIFF: undefined,
265
+ GIT_GRAFT_FILE: undefined,
266
+ GIT_INDEX_FILE: undefined,
267
+ GIT_NAMESPACE: undefined,
268
+ GIT_OBJECT_DIRECTORY: undefined,
269
+ GIT_QUARANTINE_PATH: undefined,
270
+ GIT_REPLACE_REF_BASE: undefined,
271
+ GIT_SHALLOW_FILE: undefined,
272
+ GIT_WORK_TREE: undefined,
273
+ ...extra
274
+ };
275
+ }
276
+ function freshness(fresh, conclusive, reason, currentSha, packSha, metadataOnlyDrift, changedPaths) {
277
+ return {
278
+ fresh,
279
+ conclusive,
280
+ reason,
281
+ current_sha: currentSha,
282
+ pack_sha: packSha,
283
+ metadata_only_drift: metadataOnlyDrift,
284
+ changed_paths: changedPaths
285
+ };
286
+ }
287
+ function normalizeGitSha(value) {
288
+ const text = String(value || '').trim();
289
+ return /^[0-9a-f]{40,64}$/i.test(text) && !/^0+$/.test(text) ? text.toLowerCase() : null;
290
+ }
291
+ //# sourceMappingURL=code-pack-head-freshness.js.map
@@ -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'),
@@ -65,7 +65,14 @@ async function writeWrongnessLedgerUnlocked(root, ledger) {
65
65
  export async function readCombinedWrongnessRecords(root, missionId = null) {
66
66
  const project = await readWrongnessLedger(root, null);
67
67
  const mission = missionId ? await readWrongnessLedger(root, missionId) : emptyWrongnessLedger('mission', missionId);
68
- return dedupeRecords([...project.records, ...mission.records]);
68
+ // The project ledger is also the cross-mission index, so it contains copies
69
+ // of mission-scoped records. A mission proof must inherit only truly global
70
+ // project records plus rows owned by that mission; otherwise unrelated old
71
+ // missions can block every future route forever.
72
+ const projectRecords = missionId
73
+ ? project.records.filter((record) => !record.mission_id || record.mission_id === missionId)
74
+ : project.records;
75
+ return dedupeRecords([...projectRecords, ...mission.records]);
69
76
  }
70
77
  export async function addWrongnessRecord(root, input = {}, opts = {}) {
71
78
  const row = asRecord(input);
@@ -291,7 +298,7 @@ export async function recordDbSafetyMismatchWrongness(root, input = {}) {
291
298
  wrongness_kind: kind,
292
299
  severity: kind === 'db_safety_false_negative' ? 'high' : 'medium',
293
300
  claim: { text: `DB safety expected ${expected} but classified ${actual}.` },
294
- detected_by: { source: 'db_safety_check', command: typeof row.command === 'string' ? row.command : 'sks db check', artifact: typeof row.artifact === 'string' ? row.artifact : null, detail: typeof row.sql === 'string' ? row.sql : null },
301
+ detected_by: { source: 'db_safety_check', command: typeof row.command === 'string' ? row.command : '$DB internal safety check', artifact: typeof row.artifact === 'string' ? row.artifact : null, detail: typeof row.sql === 'string' ? row.sql : null },
295
302
  root_cause: { category: 'missing_db_policy', explanation: 'A DB safety expectation did not match the current classifier output.' },
296
303
  corrective_action: { summary: 'Adjust the policy/classifier or fixture expectation, then rerun DB safety validation.', required_evidence: ['db-operation-report.json'], patch_status: 'pending' },
297
304
  links: { artifacts: typeof row.artifact === 'string' ? [row.artifact] : [] }