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
@@ -2,8 +2,7 @@ import path from 'node:path';
2
2
  import { appendJsonlBounded, nowIso, readJson, readText, writeJsonAtomic, writeTextAtomic, exists } from './fsx.js';
3
3
  import { OUTCOME_RUBRIC } from './proof-field.js';
4
4
  import { RESEARCH_AGENT_PERSONA_CONTRACT, validateResearchAgentPersonas } from './recallpulse.js';
5
- import { appendAgentLedgerEvent, initializeAgentCentralLedger } from './agents/agent-central-ledger.js';
6
- import { CLAIM_EVIDENCE_MATRIX_ARTIFACT, buildClaimEvidenceMatrixFromLedgers, defaultClaimEvidenceMatrix, readClaimEvidenceMatrix, validateClaimEvidenceMatrix, writeClaimEvidenceMatrix } from './research/claim-evidence-matrix.js';
5
+ import { CLAIM_EVIDENCE_MATRIX_ARTIFACT, defaultClaimEvidenceMatrix, readClaimEvidenceMatrix, validateClaimEvidenceMatrix, writeClaimEvidenceMatrix } from './research/claim-evidence-matrix.js';
7
6
  import { EXPERIMENT_PLAN_JSON_ARTIFACT, EXPERIMENT_PLAN_MARKDOWN_ARTIFACT, defaultExperimentPlan, readExperimentPlan, validateExperimentPlan, writeExperimentPlan } from './research/experiment-plan.js';
8
7
  import { IMPLEMENTATION_BLUEPRINT_ARTIFACT, defaultImplementationBlueprint, readImplementationBlueprint, validateImplementationBlueprint, writeImplementationBlueprint } from './research/implementation-blueprint.js';
9
8
  import { IMPLEMENTATION_BLUEPRINT_MARKDOWN_ARTIFACT, renderImplementationBlueprintMarkdown } from './research/implementation-blueprint-markdown.js';
@@ -15,11 +14,23 @@ import { analyzeResearchReportQuality, countWords } from './research/research-re
15
14
  import { validateFalsificationCoverage } from './research/falsification.js';
16
15
  import { writeResearchHandoffArtifacts } from './research/research-handoff.js';
17
16
  import { RESEARCH_WORK_GRAPH_ARTIFACT, writeResearchWorkGraph } from './research/research-work-graph.js';
17
+ import { buildResearchReviewArtifactDigest, validateResearchReviewArtifactDigest } from './research/research-review-artifact-digest.js';
18
+ import { RESEARCH_SOURCE_LAYER_IDS, RESEARCH_SOURCE_LAYERS } from './research/research-source-layer-catalog.js';
19
+ import { eligibleResearchSourceIdSet } from './research/research-source-evidence.js';
20
+ import { renderResearchPlanMarkdown, renderResearchSourceSkillMarkdown } from './research/research-plan-markdown.js';
18
21
  import { resolveCodexAppExecutionProfile } from './codex-app/codex-app-execution-profile.js';
19
22
  import { resolveCodexNativeInvocationPlan } from './codex-native/codex-native-invocation-router.js';
23
+ import { SUBAGENT_EVIDENCE_FILENAME, SUBAGENT_PARENT_SUMMARY_FILENAME, buildSubagentEvidence, normalizeSubagentParentSummary, readSubagentEvents } from './subagents/subagent-evidence.js';
24
+ export { RESEARCH_SOURCE_LAYER_IDS, RESEARCH_SOURCE_LAYERS } from './research/research-source-layer-catalog.js';
20
25
  export const RESEARCH_PAPER_ARTIFACT = 'research-paper.md';
21
26
  export const RESEARCH_SOURCE_SKILL_ARTIFACT = 'research-source-skill.md';
22
27
  export const RESEARCH_GENIUS_SUMMARY_ARTIFACT = 'genius-opinion-summary.md';
28
+ export const RESEARCH_REVIEWER_CUSTOM_AGENT = 'research_reviewer';
29
+ export const RESEARCH_REVIEWER_CONFIG_ARTIFACT = '.codex/agents/research-reviewer.toml';
30
+ const RESEARCH_ADVERSARIAL_REVIEW_LEDGER_ARTIFACT = 'research-adversarial-review.json';
31
+ const RESEARCH_ADVERSARIAL_CONVERGENCE_ARTIFACT = 'research-adversarial-convergence.json';
32
+ const RESEARCH_ADVERSARIAL_REVISION_LEDGER_ARTIFACT = 'research-revision-ledger.json';
33
+ const RESEARCH_HONEST_MODE_CANONICAL_ARTIFACT = 'research-honest-mode.json';
23
34
  export const RESEARCH_PAPER_SECTION_GROUPS = Object.freeze([
24
35
  ['abstract'],
25
36
  ['introduction'],
@@ -83,167 +94,51 @@ export const RESEARCH_AGENT_COUNCIL = Object.freeze(RESEARCH_AGENT_PERSONA_CONTR
83
94
  function validateResearchAgentLedger(agentLedger = {}, geniusSummaryText = '') {
84
95
  return validateResearchAgentPersonas({ ...agentLedger, agents: agentLedger.agents || [] }, geniusSummaryText);
85
96
  }
86
- export const RESEARCH_SOURCE_LAYERS = Object.freeze([
87
- {
88
- id: 'academic_literature',
89
- label: 'Academic literature',
90
- purpose: 'Find recent papers, preprints, formal reviews, citations, and open scholarly metadata before synthesis.',
91
- evidence_role: 'formal_evidence',
92
- examples: ['arXiv', 'Semantic Scholar', 'OpenAlex', 'Crossref', 'PubMed'],
93
- query_templates: ['"<topic>" arxiv', '"<topic>" site:semanticscholar.org', '"<topic>" OpenAlex Crossref PubMed']
94
- },
95
- {
96
- id: 'official_government_data',
97
- label: 'Official government and leading-institution knowledge',
98
- purpose: 'Ground claims in public datasets, policy papers, national statistics, and leading-country institutional sources.',
99
- evidence_role: 'authoritative_baseline',
100
- examples: ['World Bank', 'OECD', 'Eurostat', 'data.gov', 'data.gov.uk', 'NIST'],
101
- query_templates: ['"<topic>" site:worldbank.org OR site:oecd.org', '"<topic>" site:data.gov OR site:data.gov.uk', '"<topic>" site:nist.gov']
102
- },
103
- {
104
- id: 'standards_primary_docs',
105
- label: 'Standards and primary documents',
106
- purpose: 'Check primary specifications, standards, RFCs, policy originals, and official project documents before relying on summaries.',
107
- evidence_role: 'primary_source',
108
- examples: ['IETF RFCs', 'W3C', 'ISO abstracts', 'official standards bodies', 'project primary docs'],
109
- query_templates: ['"<topic>" RFC standard specification', '"<topic>" W3C IETF NIST standard', '"<topic>" official specification']
110
- },
111
- {
112
- id: 'news_current_events',
113
- label: 'Current news and global reporting',
114
- purpose: 'Capture recent events, public impact, and regional framing from reputable news and global news indices.',
115
- evidence_role: 'recency_signal',
116
- examples: ['GDELT', 'BBC', 'CNN', 'Reuters', 'AP', 'regional reputable outlets'],
117
- query_templates: ['"<topic>" BBC CNN latest', '"<topic>" GDELT news', '"<topic>" Reuters AP analysis']
118
- },
119
- {
120
- id: 'public_discourse',
121
- label: 'Public discourse',
122
- purpose: 'Sample public practitioner and community discourse without treating popularity as truth.',
123
- evidence_role: 'sentiment_and_edge_cases',
124
- examples: ['X/Twitter recent search', 'Reddit', 'Hacker News', 'public forums'],
125
- query_templates: ['"<topic>" site:x.com OR site:twitter.com', '"<topic>" site:reddit.com', '"<topic>" "Hacker News"']
126
- },
127
- {
128
- id: 'developer_practitioner',
129
- label: 'Developer and practitioner knowledge',
130
- purpose: 'Find implementation pitfalls, developer questions, bug reports, and operational lessons.',
131
- evidence_role: 'practice_feedback',
132
- examples: ['Stack Overflow', 'Stack Exchange', 'GitHub issues', 'release notes', 'engineering blogs'],
133
- query_templates: ['"<topic>" site:stackoverflow.com', '"<topic>" site:stackexchange.com', '"<topic>" site:github.com issues']
134
- },
135
- {
136
- id: 'counterevidence_factcheck',
137
- label: 'Counterevidence and fact-checking',
138
- purpose: 'Actively search for failures, critiques, null results, retractions, fact checks, and source conflicts.',
139
- evidence_role: 'falsification',
140
- examples: ['Google Fact Check Tools', 'Retraction Watch', 'critical reviews', 'benchmark failures', 'negative results'],
141
- query_templates: ['"<topic>" critique failure limitation', '"<topic>" fact check retraction', '"<topic>" counterevidence null result']
142
- }
143
- ]);
144
- export const RESEARCH_SOURCE_LAYER_IDS = Object.freeze(RESEARCH_SOURCE_LAYERS.map((layer) => layer.id));
145
- export const RESEARCH_NATIVE_AGENT_PERSONAS = Object.freeze([
146
- {
147
- id: 'research_source_miner',
148
- role: 'source_miner',
149
- label: 'Research Source Miner',
150
- replaces: 'legacy research intake runtime',
151
- read_only: true,
152
- mandate: 'Collect layered public sources, source quality notes, source blockers, and cross-layer triangulation inputs before synthesis.',
153
- outputs: [RESEARCH_SOURCE_SKILL_ARTIFACT, 'source-ledger.json']
154
- },
155
- {
156
- id: 'research_skeptic',
157
- role: 'skeptic',
158
- label: 'Research Skeptic',
159
- replaces: 'debate-ledger runtime',
160
- read_only: true,
161
- mandate: 'Attack the strongest claim with counterevidence, source-quality downgrades, missing controls, and falsification cases.',
162
- outputs: ['debate-ledger.json', 'falsification-ledger.json']
163
- },
164
- {
165
- id: 'research_synthesis',
166
- role: 'synthesis',
167
- label: 'Research Synthesis',
168
- replaces: 'manual paper/report assembly',
169
- read_only: true,
170
- mandate: 'Synthesize only cited, falsifiable claims that survived agent debate into the report and paper artifacts.',
171
- outputs: ['research-report.md']
172
- },
173
- {
174
- id: 'research_verifier',
175
- role: 'verifier',
176
- label: 'Research Verifier',
177
- replaces: 'unverified consensus closeout',
178
- read_only: true,
179
- mandate: 'Check source coverage, citation coverage, persona contract, claim support, falsification, and paper sections before proof.',
180
- outputs: ['research-gate.evaluated.json', 'research-gate.json']
181
- }
182
- ]);
183
97
  export function researchNativeAgentPlan(prompt = '', opts = {}) {
184
- const paperArtifact = opts.paperArtifact || RESEARCH_PAPER_ARTIFACT;
185
- const personas = RESEARCH_NATIVE_AGENT_PERSONAS.map((persona) => ({
186
- ...persona,
187
- session_id: opts.missionId ? `${opts.missionId}-${persona.id}` : `${persona.id}-session`,
188
- reasoning_effort: 'xhigh',
189
- service_tier: 'fast'
98
+ const personas = RESEARCH_AGENT_COUNCIL.map((persona) => ({
99
+ id: persona.id,
100
+ display_name: researchAgentAgentName(persona),
101
+ persona: persona.persona,
102
+ persona_boundary: persona.persona_boundary,
103
+ role: persona.role,
104
+ mandate: persona.mandate,
105
+ custom_agent: RESEARCH_REVIEWER_CUSTOM_AGENT,
106
+ model: 'gpt-5.6-sol',
107
+ reasoning_effort: 'max',
108
+ read_only: true
190
109
  }));
191
110
  const batches = [
192
111
  {
193
- id: 'research-source-mining-batch',
194
- cycle_phase: 'R2_SOURCE_SEARCH',
195
- agents: ['research_source_miner'],
196
- mode: 'native_agent_batch',
197
- read_only: true,
198
- outputs: [RESEARCH_SOURCE_SKILL_ARTIFACT, 'source-ledger.json']
199
- },
200
- {
201
- id: 'research-skeptic-falsification-batch',
202
- cycle_phase: 'R4_DEBATE_R5_FALSIFY',
203
- agents: ['research_skeptic'],
204
- mode: 'native_agent_batch',
205
- read_only: true,
206
- outputs: ['debate-ledger.json', 'falsification-ledger.json']
207
- },
208
- {
209
- id: 'research-synthesis-batch',
210
- cycle_phase: 'R6_APPLY_R7_PAPER',
211
- agents: ['research_synthesis'],
212
- mode: 'native_agent_batch',
213
- read_only: true,
214
- outputs: ['research-report.md', paperArtifact, 'novelty-ledger.json']
215
- },
216
- {
217
- id: 'research-verification-batch',
218
- cycle_phase: 'R8_VERIFY',
219
- agents: ['research_verifier'],
220
- mode: 'native_agent_batch',
112
+ id: 'research-official-adversarial-review',
113
+ cycle_phase: 'R8_ADVERSARIAL_REVIEW',
114
+ agents: personas.map((persona) => persona.id),
115
+ mode: 'official_codex_subagent',
221
116
  read_only: true,
222
- outputs: ['research-gate.evaluated.json', 'research-gate.json', RESEARCH_GENIUS_SUMMARY_ARTIFACT]
117
+ outputs: ['subagent-plan.json', 'subagent-events.jsonl', 'subagent-parent-summary.json', 'subagent-evidence.json', 'research-adversarial-convergence.json', RESEARCH_GENIUS_SUMMARY_ARTIFACT]
223
118
  }
224
119
  ];
225
120
  return {
226
- schema: 'sks.research-native-agent-plan.v1',
121
+ schema: 'sks.research-official-subagent-plan.v1',
227
122
  prompt,
228
- backend: 'native_multi_session_agent_kernel',
123
+ backend: 'official_codex_subagent',
229
124
  legacy_runtime: false,
230
125
  legacy_artifact_alias_policy: {
231
- 'agent-ledger.json': 'native research agent findings; not runtime proof from removed legacy infrastructure',
232
- 'debate-ledger.json': 'compatibility alias for native skeptical debate evidence; not old consensus runtime proof'
126
+ 'agent-ledger.json': 'compatibility projection from evidence-correlated official reviewer outcomes; not independent runtime proof',
127
+ 'debate-ledger.json': 'compatibility projection from official adversarial reviewer outcomes; not a custom debate scheduler'
233
128
  },
234
129
  session_count: personas.length,
235
130
  personas,
236
131
  batches,
237
132
  communication: {
238
- central_ledger: 'agents/agent-events.jsonl',
239
- messages: 'agents/agent-messages.jsonl',
240
- task_board: 'agents/agent-task-board.json',
241
- proof: 'agents/agent-proof-evidence.json'
133
+ plan: 'subagent-plan.json',
134
+ lifecycle: 'subagent-events.jsonl',
135
+ parent_summary: 'subagent-parent-summary.json',
136
+ proof: 'subagent-evidence.json'
242
137
  },
243
138
  autoresearch_cycle_policy: {
244
139
  uses_agent_batches: true,
245
140
  batch_template: batches.map((batch) => ({ id: batch.id, agents: batch.agents, outputs: batch.outputs })),
246
- rule: 'Every AutoResearch cycle runs source mining, skeptical falsification, synthesis, and verification as native agent batches before keep/discard.'
141
+ rule: 'Every AutoResearch synthesis is challenged by three distinct composite official reviewer threads; revisions are bounded and followed by a fresh full review cycle.'
247
142
  }
248
143
  };
249
144
  }
@@ -267,12 +162,17 @@ export function createResearchPlan(prompt, opts = {}) {
267
162
  prompt,
268
163
  depth,
269
164
  created_at: createdAt,
270
- methodology: opts.autoresearch ? 'native-agent-autoresearch-batch-frontier-loop' : 'native-agent-research-council-frontier-discovery-loop',
165
+ methodology: opts.autoresearch ? 'super-search-autoresearch-with-official-subagent-adversarial-convergence' : 'super-search-semantic-claims-with-official-subagent-adversarial-convergence',
271
166
  paper_artifact: paperArtifact,
272
167
  quality_contract: DEFAULT_RESEARCH_QUALITY_CONTRACT,
273
168
  native_agent_plan: nativeAgentPlan,
274
169
  codex_app_execution_profile: executionProfile ? compactExecutionProfile(executionProfile) : null,
275
170
  codex_native_invocation: codexNativeInvocation,
171
+ current_docs_policy: {
172
+ context7_required: opts.context7Required === true,
173
+ evidence_artifact: 'context7-evidence.jsonl',
174
+ rule: 'External library, SDK, API, MCP, package-manager, and generated-doc claims require resolve-library-id plus query-docs evidence before completion.'
175
+ },
276
176
  agent_sessions: nativeAgentPlan.personas,
277
177
  agent_batches: nativeAgentPlan.batches,
278
178
  autoresearch_cycle_policy: nativeAgentPlan.autoresearch_cycle_policy,
@@ -294,10 +194,10 @@ export function createResearchPlan(prompt, opts = {}) {
294
194
  },
295
195
  objective: 'Find the shortest useful mechanism that can be falsified or applied, grounded in maximum available source retrieval rather than broad summary.',
296
196
  execution_policy: {
297
- normal_run: 'real_long_running_research_until_unanimous_agent_consensus',
298
- default_cycle_timeout_minutes: 120,
299
- default_max_cycles: 12,
300
- safety_cap: 'Research repeats native agent source-mining, debate/falsification, synthesis, and verification batches until unanimous agent consensus or an explicit max-cycle safety cap pauses the run.',
197
+ normal_run: 'real_super_search_semantic_synthesis_and_official_subagent_review',
198
+ default_cycle_timeout_minutes: 20,
199
+ default_max_cycles: 3,
200
+ safety_cap: 'Research performs bounded source acquisition and up to three adversarial review/revision cycles. Any unresolved objection leaves the gate blocked.',
301
201
  mock_policy: '--mock is for selftests and dry harness checks only; normal Research must block rather than silently substitute mock output.'
302
202
  },
303
203
  outcome_rubric: OUTCOME_RUBRIC,
@@ -305,25 +205,27 @@ export function createResearchPlan(prompt, opts = {}) {
305
205
  mode: 'persona_inspired_agents_not_impersonation',
306
206
  policy: 'Use historical genius-inspired lenses as cognitive roles only. Do not claim to be, simulate private thoughts of, or speak as the real people.',
307
207
  effort_policy: {
308
- required_effort: 'xhigh',
309
- applies_to: 'every_research_agent_agent',
310
- rule: 'Every Research agent must run with xhigh reasoning effort; lower-effort agent findings cannot pass the research gate.'
208
+ custom_agent: RESEARCH_REVIEWER_CUSTOM_AGENT,
209
+ required_model: 'gpt-5.6-sol',
210
+ required_effort: 'max',
211
+ applies_to: 'every_official_adversarial_reviewer',
212
+ rule: 'Every adversarial reviewer uses the verified research_reviewer custom agent configuration with GPT-5.6 Sol Max. Long-context and source-tool acquisition uses Terra Medium; synthesis, falsification, and review use Sol Max.'
311
213
  },
312
214
  eureka_policy: {
313
215
  exclamation: 'Eureka!',
314
- rule: 'Every agent must record one literal Eureka! moment with a non-obvious idea before debate.'
216
+ rule: 'Every official reviewer must record one literal source-linked Eureka idea in its exact structured outcome.'
315
217
  },
316
218
  debate_policy: {
317
- mode: 'vigorous_evidence_bound_debate_until_unanimous_consensus',
318
- rule: 'Every agent must challenge at least one other agent or respond to a challenge before synthesis. The loop repeats until every agent records final agreement on the surviving mechanism or the safety cap pauses the run with an unpassed gate.'
219
+ mode: 'independent_adversarial_reviews_with_bounded_revision',
220
+ rule: 'Three distinct composite official reviewer threads independently attack the synthesized manuscript. Any objection triggers a bounded revision and a fresh full review; ambiguous lifecycle or outcomes fail closed.'
319
221
  },
320
222
  agents: RESEARCH_AGENT_COUNCIL,
321
223
  protocol: [
322
- 'Each agent drafts independent search queries and provisional findings before synthesis.',
323
- 'Each agent records effort=xhigh and one literal "Eureka!" idea before the council debate.',
324
- 'The council runs a vigorous evidence-bound debate where every agent challenges or responds.',
325
- 'The skeptic agent must run after the first four agents and attack the strongest surviving claim.',
326
- 'Synthesis may keep only claims with cited source-ledger ids, project evidence, or explicit hypothesis status.'
224
+ 'Super Search and semantic claim synthesis complete before the official reviewer threads start.',
225
+ 'Each official composite reviewer records one source-linked "Eureka!" idea, nonempty falsifiers, and a cheap decisive probe.',
226
+ 'Every reviewer attempts rejection independently; no reviewer lifecycle completion is treated as approval.',
227
+ 'Any critical, major, minor, or required revision prevents convergence and triggers a bounded revision when evidence integrity is intact.',
228
+ 'A fresh three-thread review must approve after every successful revision.'
327
229
  ]
328
230
  },
329
231
  web_research_policy: {
@@ -380,9 +282,9 @@ export function createResearchPlan(prompt, opts = {}) {
380
282
  'Do not modify code or project source files during Research. Research writes only route-local mission artifacts; implementation belongs to $Team or another execution route.',
381
283
  'Do not claim novelty without a novelty ledger entry.',
382
284
  'Separate facts, inferences, hypotheses, and speculations.',
383
- 'Run the genius-lens agent council independently before synthesis.',
384
- 'Every Research agent must run at reasoning_effort=xhigh, record one literal "Eureka!" idea, and participate in the debate.',
385
- 'The agent council must debate vigorously but stay evidence-bound; record challenges and responses in debate-ledger.json. Continue cycles until unanimous_consensus=true with every agent agreeing.',
285
+ 'Run three distinct evidence-correlated official composite reviewer subagent reviews after synthesis.',
286
+ 'Every reviewer must use the verified GPT-5.6 Sol Max research_reviewer policy, record one literal "Eureka!" idea, and return an exact structured outcome.',
287
+ 'Project official reviewer outcomes into debate-ledger.json for compatibility only; the canonical proof is the lifecycle-correlated adversarial review and convergence artifacts.',
386
288
  'Maximize safe web/source search as layered source retrieval and record queries, source layers, citations, quality notes, triangulation checks, and blockers in source-ledger.json.',
387
289
  `Create ${RESEARCH_SOURCE_SKILL_ARTIFACT} as a route-local source collection skill before synthesis; do not edit generated .agents/skills during the research run.`,
388
290
  'Actively seek disconfirming evidence before synthesis.',
@@ -396,8 +298,8 @@ export function createResearchPlan(prompt, opts = {}) {
396
298
  { id: 'R0_FRAME', goal: 'Frame the target outcome, constraints, and what would make the idea useful.' },
397
299
  { id: 'R1_SOURCE_SKILL', goal: `Create ${RESEARCH_SOURCE_SKILL_ARTIFACT} with layer-specific search routes, quality fields, and blockers before source gathering.` },
398
300
  { id: 'R2_SOURCE_SEARCH', goal: 'Run layered web/source retrieval across papers, official data, standards, news, public discourse, developer knowledge, and counterevidence.' },
399
- { id: 'R3_EUREKA', goal: 'Have each xhigh genius-lens agent shout Eureka! and record one non-obvious idea with source ids.' },
400
- { id: 'R4_DEBATE', goal: 'Run a vigorous evidence-bound council debate with every agent challenging or responding; repeat until unanimous agent consensus is recorded.' },
301
+ { id: 'R3_EUREKA', goal: 'Have each official Sol Max composite reviewer record one non-obvious source-linked Eureka idea without claiming historical-person identity or genius-level performance.' },
302
+ { id: 'R4_DEBATE', goal: 'Collect three independent composite adversarial reviewer outcomes, revise on any open objection, and require a fresh unanimous review before convergence.' },
401
303
  { id: 'R5_FALSIFY', goal: 'Attack each mechanism with counterexamples, missing evidence, source conflicts, and failure modes.' },
402
304
  { id: 'R6_APPLY', goal: 'Keep the smallest surviving mechanism, define a cheap probe, and write all ledgers.' },
403
305
  { id: 'R7_PAPER', goal: 'Convert the final research result into a concise paper manuscript with abstract, method, findings, limitations, and references.' },
@@ -428,124 +330,10 @@ export function createResearchPlan(prompt, opts = {}) {
428
330
  };
429
331
  }
430
332
  export function researchPlanMarkdown(plan) {
431
- const lines = [];
432
- lines.push('# SKS Research Plan');
433
- lines.push('');
434
- lines.push(`Prompt: ${plan.prompt}`);
435
- lines.push(`Depth: ${plan.depth}`);
436
- lines.push(`Methodology: ${plan.methodology}`);
437
- lines.push(`Research paper: ${researchPaperArtifactForPlan(plan)}`);
438
- if (plan.codex_app_execution_profile) {
439
- lines.push(`Execution profile: ${plan.codex_app_execution_profile.mode}; agent role strategy ${plan.codex_app_execution_profile.agent_role_strategy}`);
440
- }
441
- if (plan.execution_policy) {
442
- lines.push(`Execution: ${plan.execution_policy.normal_run}; default cycle timeout ${plan.execution_policy.default_cycle_timeout_minutes} minutes`);
443
- if (plan.execution_policy.default_max_cycles)
444
- lines.push(`Consensus loop: repeat until unanimous agent consensus; default safety cap ${plan.execution_policy.default_max_cycles} cycles`);
445
- lines.push(`Mock policy: ${plan.execution_policy.mock_policy}`);
446
- }
447
- if (plan.mutation_policy)
448
- lines.push(`Mutation policy: ${plan.mutation_policy.rule}`);
449
- lines.push('');
450
- if (plan.quality_contract) {
451
- const contract = plan.quality_contract;
452
- lines.push('## Quality Contract');
453
- lines.push(`- minimum sources: ${contract.min_sources_total}`);
454
- lines.push(`- minimum source layers covered: ${contract.min_source_layers_covered}`);
455
- lines.push(`- minimum counterevidence sources: ${contract.min_counterevidence_sources}`);
456
- lines.push(`- minimum key claims: ${contract.min_key_claims}`);
457
- lines.push(`- minimum triangulated claims: ${contract.min_trianguled_claims}`);
458
- lines.push(`- minimum blueprint sections: ${contract.min_implementation_blueprint_sections}`);
459
- lines.push(`- minimum falsification cases: ${contract.min_falsification_cases}`);
460
- lines.push(`- minimum experiment steps: ${contract.min_experiment_steps}`);
461
- lines.push(`- minimum report words: ${contract.min_report_words}`);
462
- lines.push('');
463
- }
464
- if (plan.native_agent_plan) {
465
- lines.push('## Native Agent Plan');
466
- lines.push(`Backend: ${plan.native_agent_plan.backend}`);
467
- lines.push(`Sessions: ${plan.native_agent_plan.session_count}`);
468
- lines.push(`AutoResearch batches: ${plan.native_agent_plan.autoresearch_cycle_policy?.uses_agent_batches ? 'enabled' : 'disabled'}`);
469
- for (const persona of plan.native_agent_plan.personas || []) {
470
- lines.push(`- ${persona.id}: ${persona.role}; outputs ${(persona.outputs || []).join(', ')}`);
471
- }
472
- for (const batch of plan.native_agent_plan.batches || []) {
473
- lines.push(`- batch ${batch.id}: ${(batch.agents || []).join(', ')} -> ${(batch.outputs || []).join(', ')}`);
474
- }
475
- lines.push('');
476
- }
477
- lines.push('## Rules');
478
- for (const rule of plan.rules)
479
- lines.push(`- ${rule}`);
480
- lines.push('');
481
- if (plan.research_council?.agents?.length) {
482
- lines.push('## Genius Agent Council');
483
- lines.push(`Policy: ${plan.research_council.policy}`);
484
- for (const agent of plan.research_council.agents)
485
- lines.push(`- ${researchAgentAgentName(agent)}: ${agent.persona || agent.role} - ${agent.mandate} (${agent.persona_boundary || 'persona-inspired lens only'})`);
486
- lines.push('');
487
- }
488
- if (plan.web_research_policy) {
489
- lines.push('## Web Research Policy');
490
- lines.push(`Mode: ${plan.web_research_policy.mode}`);
491
- lines.push(`Requirement: ${plan.web_research_policy.requirement}`);
492
- if (plan.web_research_policy.source_tool_routing)
493
- lines.push(`Source tool routing: ${plan.web_research_policy.source_tool_routing.mode}`);
494
- for (const querySet of plan.web_research_policy.query_sets || [])
495
- lines.push(`- query set: ${querySet}`);
496
- if (plan.web_research_policy.skill_creator?.artifact)
497
- lines.push(`- source skill artifact: ${plan.web_research_policy.skill_creator.artifact}`);
498
- for (const layer of plan.web_research_policy.source_layers || []) {
499
- lines.push(`- layer ${layer.id}: ${layer.purpose}`);
500
- }
501
- lines.push('');
502
- }
503
- lines.push('## Outcome Rubric');
504
- for (const item of plan.outcome_rubric || [])
505
- lines.push(`- ${item.id}: ${item.description}`);
506
- lines.push('');
507
- lines.push('## Phases');
508
- for (const phase of plan.phases)
509
- lines.push(`- ${phase.id}: ${phase.goal}`);
510
- lines.push('');
511
- lines.push('## Required Artifacts');
512
- for (const artifact of plan.required_artifacts)
513
- lines.push(`- ${artifact}`);
514
- lines.push('');
515
- return `${lines.join('\n')}\n`;
333
+ return renderResearchPlanMarkdown(plan, { researchPaperArtifactForPlan, researchAgentAgentName });
516
334
  }
517
335
  export function researchSourceSkillMarkdown(plan) {
518
- const layers = plan?.web_research_policy?.source_layers?.length ? plan.web_research_policy.source_layers : RESEARCH_SOURCE_LAYERS;
519
- const lines = [];
520
- lines.push('# Research Source Layer Skill');
521
- lines.push('');
522
- lines.push('Status: route-local candidate skill. Use it inside this research mission before agent synthesis. Do not install or edit generated .agents/skills from this artifact.');
523
- lines.push('Real-run policy: collect live sources for as long as needed within the mission timeout; mock or fixture evidence is valid only for explicit --mock selftests.');
524
- lines.push('');
525
- lines.push('## Trigger');
526
- lines.push('- Any `$Research` run that must collect broad public evidence before creative synthesis, debate, falsification, or paper writing.');
527
- lines.push('');
528
- lines.push('## Source Layers');
529
- for (const layer of layers) {
530
- lines.push(`- ${layer.id}: ${layer.purpose}`);
531
- lines.push(` Examples: ${(layer.examples || []).join(', ')}`);
532
- lines.push(` Query templates: ${(layer.query_templates || []).join(' | ')}`);
533
- }
534
- lines.push('');
535
- lines.push('## Output Contract');
536
- lines.push('- Fill source-ledger.json with `source_layers`, `sources[].layer`, `counterevidence_sources[].layer`, `citation_coverage`, `triangulation.cross_layer_checks`, and `blockers`.');
537
- lines.push('- Each source entry should record title, locator/URL, publisher or author when known, published_at when known, accessed_at, layer, reliability, credibility, stance, supports or undermines, and notes.');
538
- lines.push('- Public discourse sources such as X/Twitter or Reddit are signals and edge cases, not truth. They must be triangulated with formal, official, practitioner, or counterevidence layers.');
539
- lines.push('- If a layer cannot be searched with the available runtime or credentials, record the blocker and keep research-gate.json unpassed.');
540
- lines.push('- Do not modify repository source code or generated harness files during Research; write only route-local mission artifacts.');
541
- lines.push('');
542
- lines.push('## Debate Use');
543
- lines.push('- Every agent must cite source-ledger ids in findings and Eureka ideas.');
544
- lines.push('- The skeptic lens must challenge the strongest claim using counterevidence or source-quality downgrades.');
545
- lines.push('- Continue agent/debate/falsification cycles until every agent agrees to the surviving mechanism. Record `unanimous_consensus=true`, `consensus_iterations`, and per-agent agreement in debate-ledger.json.');
546
- lines.push('- Synthesis keeps only claims that survive cross-layer triangulation and falsification.');
547
- lines.push('');
548
- return `${lines.join('\n')}\n`;
336
+ return renderResearchSourceSkillMarkdown(plan, RESEARCH_SOURCE_LAYERS);
549
337
  }
550
338
  export function countResearchPaperSections(text = '') {
551
339
  const headings = String(text || '').toLowerCase().split(/\n/).filter((line) => /^#{1,3}\s+/.test(line));
@@ -601,8 +389,6 @@ export async function writeResearchPlan(dir, prompt, opts = {}) {
601
389
  await writeJsonAtomic(path.join(dir, 'debate-ledger.json'), defaultDebateLedger(plan));
602
390
  await writeJsonAtomic(path.join(dir, 'falsification-ledger.json'), defaultFalsificationLedger());
603
391
  await writeJsonAtomic(path.join(dir, 'research-gate.json'), defaultResearchGate());
604
- if (opts.missionId)
605
- await writeResearchNativeAgentLedger(dir, plan, { missionId: opts.missionId });
606
392
  await appendJsonlBounded(path.join(dir, 'events.jsonl'), { ts: nowIso(), type: 'research.plan.created', depth: plan.depth });
607
393
  return plan;
608
394
  }
@@ -640,104 +426,6 @@ function compactExecutionProfile(profile) {
640
426
  artifact_path: profile.artifact_path || '.sneakoscope/reports/codex-app-execution-profile.json'
641
427
  } : null;
642
428
  }
643
- export async function writeResearchNativeAgentLedger(dir, plan, opts = {}) {
644
- const missionId = opts.missionId || plan?.mission_id;
645
- if (!missionId)
646
- return null;
647
- const rosterRows = (plan?.native_agent_plan?.personas || RESEARCH_NATIVE_AGENT_PERSONAS).map((persona) => ({
648
- id: persona.id,
649
- session_id: persona.session_id || `${missionId}-${persona.id}`,
650
- persona_id: persona.id,
651
- role: persona.role,
652
- read_only: persona.read_only !== false,
653
- status: 'planned',
654
- output_artifacts: persona.outputs || []
655
- }));
656
- const batches = plan?.native_agent_plan?.batches || [];
657
- const root = await initializeAgentCentralLedger(dir, {
658
- missionId,
659
- route: '$Research',
660
- prompt: plan?.prompt || '',
661
- roster: {
662
- schema: 'sks.research-agent-roster.v1',
663
- mission_id: missionId,
664
- backend: 'native_multi_session_agent_kernel',
665
- roster: rosterRows,
666
- personas: plan?.native_agent_plan?.personas || RESEARCH_NATIVE_AGENT_PERSONAS
667
- },
668
- partition: {
669
- slices: batches.map((batch) => ({
670
- id: batch.id,
671
- owner_agent_id: (batch.agents || [])[0] || 'research_verifier',
672
- domain: batch.cycle_phase || batch.id,
673
- write_paths: batch.outputs || [],
674
- read_only: batch.read_only !== false
675
- })),
676
- leases: batches.flatMap((batch) => (batch.outputs || []).map((artifact) => ({
677
- path: artifact,
678
- owner_agent_id: (batch.agents || [])[0] || 'research_verifier',
679
- mode: 'route-local-artifact'
680
- })))
681
- }
682
- });
683
- for (const batch of batches) {
684
- await appendAgentLedgerEvent(root, {
685
- agent_id: (batch.agents || [])[0] || 'orchestrator',
686
- session_id: `${missionId}-${(batch.agents || [])[0] || 'orchestrator'}`,
687
- event_type: 'research_batch_planned',
688
- payload: { batch_id: batch.id, outputs: batch.outputs || [] }
689
- });
690
- }
691
- await writeJsonAtomic(path.join(dir, 'research-agent-batches.json'), {
692
- schema: 'sks.research-agent-batches.v1',
693
- mission_id: missionId,
694
- backend: 'native_multi_session_agent_kernel',
695
- batches,
696
- status: 'planned'
697
- });
698
- return root;
699
- }
700
- export async function writeResearchNativeAgentBatchCompletion(dir, plan, opts = {}) {
701
- const missionId = opts.missionId || plan?.mission_id || null;
702
- const batches = plan?.native_agent_plan?.batches || [];
703
- const completedAt = nowIso();
704
- await writeJsonAtomic(path.join(dir, 'research-agent-batches.json'), {
705
- schema: 'sks.research-agent-batches.v1',
706
- mission_id: missionId,
707
- backend: 'native_multi_session_agent_kernel',
708
- batches: batches.map((batch) => ({ ...batch, status: 'completed_mock', completed_at: completedAt })),
709
- status: 'completed_mock',
710
- completed_at: completedAt
711
- });
712
- if (!missionId)
713
- return null;
714
- const agentRoot = path.join(dir, 'agents');
715
- const sessionsPath = path.join(agentRoot, 'agent-sessions.json');
716
- const sessions = await readJson(sessionsPath, null);
717
- if (sessions?.sessions) {
718
- for (const [agentId, session] of Object.entries(sessions.sessions)) {
719
- sessions.sessions[agentId] = {
720
- ...session,
721
- status: 'closed',
722
- opened_at: session.opened_at || completedAt,
723
- heartbeat_at: completedAt,
724
- closed_at: completedAt
725
- };
726
- }
727
- await writeJsonAtomic(sessionsPath, sessions);
728
- }
729
- if (await exists(path.join(agentRoot, 'agent-events.jsonl'))) {
730
- for (const batch of batches) {
731
- await appendAgentLedgerEvent(agentRoot, {
732
- agent_id: (batch.agents || [])[0] || 'research_verifier',
733
- session_id: `${missionId}-${(batch.agents || [])[0] || 'research_verifier'}`,
734
- event_type: 'research_batch_completed',
735
- payload: { batch_id: batch.id, outputs: batch.outputs || [], mock: true }
736
- });
737
- }
738
- }
739
- return { mission_id: missionId, status: 'completed_mock', batch_count: batches.length };
740
- }
741
429
  export function defaultSourceLedger(plan = null) {
742
430
  const sourceLayers = plan?.web_research_policy?.source_layers?.length ? plan.web_research_policy.source_layers : RESEARCH_SOURCE_LAYERS;
743
431
  return {
@@ -805,9 +493,14 @@ export function defaultAgentLedger(plan = null) {
805
493
  persona_boundary: agent.persona_boundary || 'persona-inspired cognitive lens only; do not impersonate the historical person',
806
494
  role: agent.role,
807
495
  mandate: agent.mandate,
808
- effort: 'xhigh',
809
- reasoning_effort: 'xhigh',
810
- service_tier: agent.service_tier || 'fast',
496
+ model_policy: {
497
+ custom_agent: RESEARCH_REVIEWER_CUSTOM_AGENT,
498
+ model: 'gpt-5.6-sol',
499
+ reasoning_effort: 'max',
500
+ enforcement_source: RESEARCH_REVIEWER_CONFIG_ARTIFACT
501
+ },
502
+ observed_model: null,
503
+ observed_reasoning_effort: null,
811
504
  eureka: {
812
505
  exclamation: 'Eureka!',
813
506
  idea: '',
@@ -944,6 +637,7 @@ export function defaultResearchGate() {
944
637
  triangulation_checks: 0,
945
638
  independent_agents: 0,
946
639
  xhigh_agents: 0,
640
+ sol_max_policy_agents: 0,
947
641
  eureka_moments: 0,
948
642
  agent_findings: 0,
949
643
  debate_participants: 0,
@@ -963,10 +657,316 @@ export function defaultResearchGate() {
963
657
  notes: []
964
658
  };
965
659
  }
660
+ export async function validateCanonicalResearchAdversarialEvidence(dir) {
661
+ const expectedPersonaIds = RESEARCH_AGENT_COUNCIL.map((agent) => String(agent.id));
662
+ const expectedReviewerCount = expectedPersonaIds.length;
663
+ const [reviewLedger, revisionLedger, convergenceGate, honestMode, researchPlan, sourceLedger] = await Promise.all([
664
+ readJson(path.join(dir, RESEARCH_ADVERSARIAL_REVIEW_LEDGER_ARTIFACT), null),
665
+ readJson(path.join(dir, RESEARCH_ADVERSARIAL_REVISION_LEDGER_ARTIFACT), null),
666
+ readJson(path.join(dir, RESEARCH_ADVERSARIAL_CONVERGENCE_ARTIFACT), null),
667
+ readJson(path.join(dir, RESEARCH_HONEST_MODE_CANONICAL_ARTIFACT), null),
668
+ readJson(path.join(dir, 'research-plan.json'), null),
669
+ readJson(path.join(dir, 'source-ledger.json'), null)
670
+ ]);
671
+ const blockers = [];
672
+ if (reviewLedger?.schema !== 'sks.research-adversarial-review-ledger.v1')
673
+ blockers.push('canonical_adversarial_review_ledger_invalid');
674
+ if (revisionLedger?.schema !== 'sks.research-revision-ledger.v1')
675
+ blockers.push('canonical_adversarial_revision_ledger_invalid');
676
+ if (convergenceGate?.schema !== 'sks.research-adversarial-convergence.v1')
677
+ blockers.push('canonical_adversarial_convergence_invalid');
678
+ if (honestMode?.schema !== 'sks.research-honest-mode.v1')
679
+ blockers.push('canonical_research_honest_mode_invalid');
680
+ const reviewCycles = Array.isArray(reviewLedger?.review_cycles) ? reviewLedger.review_cycles : [];
681
+ const revisions = Array.isArray(revisionLedger?.revisions) ? revisionLedger.revisions : [];
682
+ const finalReview = reviewCycles.at(-1) || null;
683
+ const finalCycle = Number(finalReview?.cycle || 0);
684
+ const executionClass = String(convergenceGate?.execution_class || reviewLedger?.execution_class || finalReview?.execution_class || '');
685
+ const mockOnly = executionClass === 'mock_fixture';
686
+ if (!['real', 'mock_fixture'].includes(executionClass))
687
+ blockers.push('canonical_adversarial_execution_class_invalid');
688
+ if (!finalReview)
689
+ blockers.push('canonical_adversarial_final_review_missing');
690
+ if (Number(reviewLedger?.final_cycle || 0) !== finalCycle || finalCycle < 1)
691
+ blockers.push('canonical_adversarial_final_cycle_mismatch');
692
+ if (reviewCycles.length !== finalCycle)
693
+ blockers.push('canonical_adversarial_review_cycle_sequence_invalid');
694
+ if (String(finalReview?.execution_class || '') !== executionClass)
695
+ blockers.push('canonical_adversarial_final_execution_class_mismatch');
696
+ if (normalizeResearchStrings(reviewLedger?.blockers).length)
697
+ blockers.push(...normalizeResearchStrings(reviewLedger.blockers).map((blocker) => `canonical_adversarial_ledger:${blocker}`));
698
+ if (normalizeResearchStrings(finalReview?.blockers).length)
699
+ blockers.push(...normalizeResearchStrings(finalReview.blockers).map((blocker) => `canonical_adversarial_final_review:${blocker}`));
700
+ const reviewers = Array.isArray(finalReview?.reviewers) ? finalReview.reviewers : [];
701
+ const currentReviewArtifacts = await buildResearchReviewArtifactDigest(dir, researchPlan);
702
+ const recordedReviewArtifacts = finalReview?.review_artifacts;
703
+ blockers.push(...validateResearchReviewArtifactDigest(recordedReviewArtifacts, currentReviewArtifacts).map((blocker) => `canonical_adversarial_${blocker}`));
704
+ const reviewedArtifactBundle = String(recordedReviewArtifacts?.bundle_sha256 || '');
705
+ if (String(convergenceGate?.review_artifact_bundle_sha256 || '') !== reviewedArtifactBundle)
706
+ blockers.push('canonical_adversarial_convergence_artifact_bundle_mismatch');
707
+ if (String(convergenceGate?.current_artifact_bundle_sha256 || '') !== currentReviewArtifacts.bundle_sha256)
708
+ blockers.push('canonical_adversarial_convergence_current_artifact_bundle_mismatch');
709
+ if (convergenceGate?.review_artifact_hashes_ok !== true)
710
+ blockers.push('canonical_adversarial_artifact_hashes_not_ok');
711
+ const currentSourceIds = await eligibleResearchSourceIdSet(dir, sourceLedger, executionClass);
712
+ const personaIds = reviewers.map((reviewer) => String(reviewer?.persona_id || '').trim()).filter(Boolean);
713
+ const threadIds = reviewers.map((reviewer) => String(reviewer?.thread_id || '').trim()).filter(Boolean);
714
+ if (reviewers.length !== expectedReviewerCount)
715
+ blockers.push(`canonical_adversarial_reviewer_count:${reviewers.length}/${expectedReviewerCount}`);
716
+ for (const personaId of expectedPersonaIds) {
717
+ if (!personaIds.includes(personaId))
718
+ blockers.push(`canonical_adversarial_reviewer_missing:${personaId}`);
719
+ }
720
+ for (const duplicate of duplicateResearchStrings(personaIds))
721
+ blockers.push(`canonical_adversarial_reviewer_duplicate:${duplicate}`);
722
+ for (const duplicate of duplicateResearchStrings(threadIds))
723
+ blockers.push(`canonical_adversarial_thread_duplicate:${duplicate}`);
724
+ if (new Set(threadIds).size !== expectedReviewerCount)
725
+ blockers.push('canonical_adversarial_distinct_threads_missing');
726
+ for (const reviewer of reviewers)
727
+ blockers.push(...canonicalResearchReviewerBlockers(reviewer, currentSourceIds, reviewedArtifactBundle));
728
+ if (convergenceGate?.passed !== true)
729
+ blockers.push('canonical_adversarial_convergence_not_passed');
730
+ if (convergenceGate?.official_subagent_workflow !== true)
731
+ blockers.push('canonical_adversarial_official_workflow_missing');
732
+ if (Number(convergenceGate?.reviewer_count_required || 0) !== expectedReviewerCount)
733
+ blockers.push('canonical_adversarial_required_reviewer_count_invalid');
734
+ if (Number(convergenceGate?.reviewer_count_observed || 0) !== expectedReviewerCount)
735
+ blockers.push('canonical_adversarial_observed_reviewer_count_invalid');
736
+ if (Number(convergenceGate?.review_cycles || 0) !== reviewCycles.length)
737
+ blockers.push('canonical_adversarial_review_cycle_count_mismatch');
738
+ if (Number(convergenceGate?.revision_cycles || 0) !== revisions.length)
739
+ blockers.push('canonical_adversarial_revision_cycle_count_mismatch');
740
+ if (convergenceGate?.all_reviewers_approved !== true)
741
+ blockers.push('canonical_adversarial_unanimity_missing');
742
+ if (Number(convergenceGate?.unresolved_critical_objections || 0) !== 0)
743
+ blockers.push('canonical_adversarial_critical_objections_open');
744
+ if (Number(convergenceGate?.unresolved_objections || 0) !== 0)
745
+ blockers.push('canonical_adversarial_objections_open');
746
+ if (convergenceGate?.honest_mode_ok !== true)
747
+ blockers.push('canonical_adversarial_honest_mode_not_ok');
748
+ if (normalizeResearchStrings(convergenceGate?.blockers).length)
749
+ blockers.push(...normalizeResearchStrings(convergenceGate.blockers).map((blocker) => `canonical_adversarial_convergence:${blocker}`));
750
+ if (convergenceGate?.genius_level_guaranteed !== false || convergenceGate?.novelty_guaranteed !== false || convergenceGate?.publication_acceptance_guaranteed !== false) {
751
+ blockers.push('canonical_adversarial_guarantee_overclaim');
752
+ }
753
+ if (honestMode?.ok !== true || normalizeResearchStrings(honestMode?.blockers).length)
754
+ blockers.push('canonical_research_honest_mode_not_ok');
755
+ if (String(honestMode?.execution_class || '') !== executionClass)
756
+ blockers.push('canonical_research_honest_mode_execution_class_mismatch');
757
+ if (honestMode?.guarantees?.genius_level !== false
758
+ || honestMode?.guarantees?.novelty !== false
759
+ || honestMode?.guarantees?.breakthrough !== false
760
+ || honestMode?.guarantees?.publication_acceptance !== false) {
761
+ blockers.push('canonical_research_honest_mode_guarantee_overclaim');
762
+ }
763
+ const finalReviewedAt = researchTimestamp(finalReview?.reviewed_at);
764
+ if (!finalReviewedAt)
765
+ blockers.push('canonical_adversarial_final_review_timestamp_invalid');
766
+ for (const revision of revisions) {
767
+ const revisionCycle = Number(revision?.cycle || 0);
768
+ if (revision?.ok !== true)
769
+ blockers.push(`canonical_adversarial_revision_not_ok:${revisionCycle || 'unknown'}`);
770
+ if (!researchTimestamp(revision?.revised_at))
771
+ blockers.push(`canonical_adversarial_revision_timestamp_invalid:${revisionCycle || 'unknown'}`);
772
+ if (revisionCycle < 1 || revisionCycle >= finalCycle)
773
+ blockers.push(`canonical_adversarial_revision_not_followed_by_review:${revisionCycle || 'unknown'}`);
774
+ }
775
+ if (finalCycle > 1) {
776
+ const revisionCycles = new Set(revisions.map((revision) => Number(revision?.cycle || 0)));
777
+ for (let cycle = 1; cycle < finalCycle; cycle += 1) {
778
+ if (!revisionCycles.has(cycle))
779
+ blockers.push(`canonical_adversarial_review_without_revision:${cycle + 1}`);
780
+ }
781
+ }
782
+ const latestRevisionAt = Math.max(0, ...revisions.map((revision) => researchTimestamp(revision?.revised_at)));
783
+ if (latestRevisionAt && (!finalReviewedAt || finalReviewedAt < latestRevisionAt))
784
+ blockers.push('canonical_adversarial_post_revision_review_not_fresh');
785
+ if (revisions.length) {
786
+ const priorThreadIds = new Set(reviewCycles.slice(0, -1).flatMap((cycle) => (Array.isArray(cycle?.reviewers) ? cycle.reviewers : []).map((reviewer) => String(reviewer?.thread_id || '').trim()).filter(Boolean)));
787
+ for (const threadId of threadIds) {
788
+ if (priorThreadIds.has(threadId))
789
+ blockers.push(`canonical_adversarial_post_revision_thread_reused:${threadId}`);
790
+ }
791
+ const revisionRunIds = new Set(revisions.map((revision) => String(revision?.workflow_run_id || '').trim()).filter(Boolean));
792
+ if (revisionRunIds.has(String(finalReview?.workflow_run_id || '').trim()))
793
+ blockers.push('canonical_adversarial_post_revision_run_reused');
794
+ }
795
+ let rebuiltEvidence = null;
796
+ let persistedEvidence = null;
797
+ let normalizedParent = null;
798
+ if (mockOnly) {
799
+ if (convergenceGate?.official_subagent_evidence_ok !== true)
800
+ blockers.push('canonical_adversarial_mock_contract_evidence_not_ok');
801
+ }
802
+ else if (executionClass === 'real') {
803
+ const [parentSummary, evidence, events] = await Promise.all([
804
+ readJson(path.join(dir, SUBAGENT_PARENT_SUMMARY_FILENAME), null),
805
+ readJson(path.join(dir, SUBAGENT_EVIDENCE_FILENAME), null),
806
+ readSubagentEvents(dir)
807
+ ]);
808
+ normalizedParent = normalizeSubagentParentSummary(parentSummary);
809
+ persistedEvidence = evidence;
810
+ const workflowRunId = String(finalReview?.workflow_run_id || convergenceGate?.workflow_run_id || '').trim();
811
+ if (!workflowRunId)
812
+ blockers.push('canonical_adversarial_workflow_run_id_missing');
813
+ if (!normalizedParent.trustworthy || normalizedParent.status !== 'completed')
814
+ blockers.push(...(normalizedParent.blockers.length ? normalizedParent.blockers.map((blocker) => `canonical_adversarial_parent:${blocker}`) : ['canonical_adversarial_parent_untrustworthy']));
815
+ if (normalizedParent.run_id !== workflowRunId)
816
+ blockers.push('canonical_adversarial_parent_run_id_mismatch');
817
+ rebuiltEvidence = buildSubagentEvidence({
818
+ requestedSubagents: expectedReviewerCount,
819
+ events,
820
+ parentSummary,
821
+ parentSummaryPresent: normalizedParent.present,
822
+ workflowStatus: 'parent_completed',
823
+ runId: workflowRunId
824
+ });
825
+ if (!rebuiltEvidence.ok)
826
+ blockers.push(...rebuiltEvidence.blockers.map((blocker) => `canonical_adversarial_evidence:${blocker}`));
827
+ if (evidence?.schema !== 'sks.subagent-evidence.v1' || evidence?.ok !== true || evidence?.status !== 'completed')
828
+ blockers.push('canonical_adversarial_persisted_evidence_invalid');
829
+ if (convergenceGate?.official_subagent_evidence_ok !== true)
830
+ blockers.push('canonical_adversarial_convergence_evidence_not_ok');
831
+ if (String(convergenceGate?.workflow_run_id || '') !== workflowRunId)
832
+ blockers.push('canonical_adversarial_convergence_run_id_mismatch');
833
+ if (String(evidence?.run_id || '') !== workflowRunId)
834
+ blockers.push('canonical_adversarial_persisted_evidence_run_id_mismatch');
835
+ if (!sameResearchStringSet(threadIds, rebuiltEvidence?.completed_thread_ids))
836
+ blockers.push('canonical_adversarial_rebuilt_thread_correlation_failed');
837
+ if (!sameResearchStringSet(threadIds, evidence?.completed_thread_ids))
838
+ blockers.push('canonical_adversarial_persisted_thread_correlation_failed');
839
+ if (Number(evidence?.requested_subagents || 0) !== expectedReviewerCount
840
+ || Number(evidence?.started_threads || 0) !== expectedReviewerCount
841
+ || Number(evidence?.completed_threads || 0) !== expectedReviewerCount
842
+ || Number(evidence?.failed_threads || 0) !== 0
843
+ || normalizeResearchStrings(evidence?.open_thread_ids).length
844
+ || normalizeResearchStrings(evidence?.ambiguous_stop_thread_ids).length
845
+ || normalizeResearchStrings(evidence?.unmatched_stop_thread_ids).length
846
+ || evidence?.parent_summary_trustworthy !== true
847
+ || evidence?.parent_summary_status !== 'completed') {
848
+ blockers.push('canonical_adversarial_persisted_evidence_counts_invalid');
849
+ }
850
+ const finalReviewerByThread = new Map(reviewers.map((reviewer) => [String(reviewer?.thread_id || ''), reviewer]));
851
+ for (const row of Array.isArray(normalizedParent.raw?.thread_outcomes) ? normalizedParent.raw.thread_outcomes : []) {
852
+ const threadId = String(row?.thread_id || '').trim();
853
+ const outcome = parseExactResearchJsonObject(row?.summary);
854
+ const reviewer = finalReviewerByThread.get(threadId);
855
+ if (!reviewer || row?.status !== 'completed' || !outcome) {
856
+ blockers.push(`canonical_adversarial_parent_outcome_invalid:${threadId || 'unknown'}`);
857
+ continue;
858
+ }
859
+ blockers.push(...canonicalResearchReviewerBlockers({ ...outcome, thread_id: threadId, thread_status: row.status }, currentSourceIds, reviewedArtifactBundle)
860
+ .map((blocker) => `canonical_adversarial_parent_outcome:${blocker}`));
861
+ if (outcome.schema !== 'sks.research-adversarial-reviewer-outcome.v1'
862
+ || String(outcome.persona_id || '') !== String(reviewer.persona_id || '')
863
+ || String(outcome.verdict || '') !== String(reviewer.verdict || '')) {
864
+ blockers.push(`canonical_adversarial_parent_outcome_mismatch:${threadId}`);
865
+ }
866
+ }
867
+ }
868
+ return {
869
+ schema: 'sks.research-canonical-adversarial-validation.v1',
870
+ ok: [...new Set(blockers)].length === 0,
871
+ execution_class: executionClass || null,
872
+ mock_only: mockOnly,
873
+ review_cycles: reviewCycles.length,
874
+ revision_cycles: revisions.length,
875
+ final_cycle: finalCycle || null,
876
+ reviewer_thread_ids: [...new Set(threadIds)].sort(),
877
+ workflow_run_id: String(finalReview?.workflow_run_id || convergenceGate?.workflow_run_id || '').trim() || null,
878
+ parent_summary_trustworthy: normalizedParent?.trustworthy ?? false,
879
+ official_subagent_evidence_ok: rebuiltEvidence?.ok ?? (mockOnly ? true : false),
880
+ blockers: [...new Set(blockers)]
881
+ };
882
+ }
883
+ function canonicalResearchReviewerBlockers(reviewer, currentSourceIds = new Set(), expectedArtifactBundle = '') {
884
+ const personaId = String(reviewer?.persona_id || 'unknown');
885
+ const blockers = [];
886
+ if (reviewer?.schema !== 'sks.research-adversarial-reviewer-outcome.v1')
887
+ blockers.push(`canonical_adversarial_reviewer_schema:${personaId}`);
888
+ if (!String(reviewer?.thread_id || '').trim())
889
+ blockers.push(`canonical_adversarial_reviewer_thread_missing:${personaId}`);
890
+ if (reviewer?.thread_status !== 'completed')
891
+ blockers.push(`canonical_adversarial_reviewer_thread_not_completed:${personaId}`);
892
+ if (reviewer?.verdict !== 'approve')
893
+ blockers.push(`canonical_adversarial_reviewer_not_approved:${personaId}`);
894
+ if (!String(reviewer?.strongest_challenge || '').trim())
895
+ blockers.push(`canonical_adversarial_reviewer_challenge_missing:${personaId}`);
896
+ if (!normalizeResearchStrings(reviewer?.evidence_source_ids).length)
897
+ blockers.push(`canonical_adversarial_reviewer_evidence_missing:${personaId}`);
898
+ if (!normalizeResearchStrings(reviewer?.falsifiers).length)
899
+ blockers.push(`canonical_adversarial_reviewer_falsifier_missing:${personaId}`);
900
+ if (!normalizeResearchStrings(reviewer?.cheap_probes).length)
901
+ blockers.push(`canonical_adversarial_reviewer_probe_missing:${personaId}`);
902
+ if (!/^[a-f0-9]{64}$/i.test(String(reviewer?.review_artifact_bundle_sha256 || '')))
903
+ blockers.push(`canonical_adversarial_reviewer_artifact_bundle_missing:${personaId}`);
904
+ if (expectedArtifactBundle && String(reviewer?.review_artifact_bundle_sha256 || '') !== expectedArtifactBundle)
905
+ blockers.push(`canonical_adversarial_reviewer_artifact_bundle_mismatch:${personaId}`);
906
+ if (reviewer?.eureka?.exclamation !== 'Eureka!' || !String(reviewer?.eureka?.idea || '').trim() || !normalizeResearchStrings(reviewer?.eureka?.source_ids).length)
907
+ blockers.push(`canonical_adversarial_reviewer_eureka_missing:${personaId}`);
908
+ for (const sourceId of normalizeResearchStrings(reviewer?.evidence_source_ids)) {
909
+ if (!currentSourceIds.has(sourceId))
910
+ blockers.push(`canonical_adversarial_reviewer_source_unknown:${personaId}:${sourceId}`);
911
+ }
912
+ for (const sourceId of normalizeResearchStrings(reviewer?.eureka?.source_ids)) {
913
+ if (!currentSourceIds.has(sourceId))
914
+ blockers.push(`canonical_adversarial_reviewer_eureka_source_unknown:${personaId}:${sourceId}`);
915
+ }
916
+ const objections = [
917
+ ...(Array.isArray(reviewer?.critical_objections) ? reviewer.critical_objections : []),
918
+ ...(Array.isArray(reviewer?.major_objections) ? reviewer.major_objections : []),
919
+ ...(Array.isArray(reviewer?.minor_objections) ? reviewer.minor_objections : [])
920
+ ];
921
+ for (const objection of objections) {
922
+ for (const sourceId of normalizeResearchStrings(objection?.source_ids)) {
923
+ if (!currentSourceIds.has(sourceId))
924
+ blockers.push(`canonical_adversarial_reviewer_objection_source_unknown:${personaId}:${sourceId}`);
925
+ }
926
+ }
927
+ if (objections.length || normalizeResearchStrings(reviewer?.required_revisions).length)
928
+ blockers.push(`canonical_adversarial_reviewer_objections_open:${personaId}`);
929
+ return blockers;
930
+ }
931
+ function normalizeResearchStrings(value) {
932
+ return [...new Set((Array.isArray(value) ? value : value == null ? [] : [value]).map((item) => String(item || '').trim()).filter(Boolean))];
933
+ }
934
+ function duplicateResearchStrings(values) {
935
+ const seen = new Set();
936
+ const duplicates = new Set();
937
+ for (const value of values) {
938
+ if (seen.has(value))
939
+ duplicates.add(value);
940
+ seen.add(value);
941
+ }
942
+ return [...duplicates];
943
+ }
944
+ function sameResearchStringSet(left, right) {
945
+ const a = normalizeResearchStrings(left).sort();
946
+ const b = normalizeResearchStrings(right).sort();
947
+ return a.length === b.length && a.every((value, index) => value === b[index]);
948
+ }
949
+ function researchTimestamp(value) {
950
+ const parsed = Date.parse(String(value || ''));
951
+ return Number.isFinite(parsed) ? parsed : 0;
952
+ }
953
+ function parseExactResearchJsonObject(value) {
954
+ if (typeof value !== 'string' || !value.trim())
955
+ return null;
956
+ try {
957
+ const parsed = JSON.parse(value.trim());
958
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : null;
959
+ }
960
+ catch {
961
+ return null;
962
+ }
963
+ }
966
964
  export async function evaluateResearchGate(dir) {
967
965
  const gate = await readJson(path.join(dir, 'research-gate.json'), defaultResearchGate());
968
966
  const contract = await readResearchQualityContract(dir);
969
967
  const plan = await readJson(path.join(dir, 'research-plan.json'), null);
968
+ const context7Required = plan?.current_docs_policy?.context7_required === true;
969
+ const context7Evidence = await researchContext7Evidence(dir);
970
970
  const reportPresent = await exists(path.join(dir, 'research-report.md'));
971
971
  const reportText = reportPresent ? await readText(path.join(dir, 'research-report.md'), '') : '';
972
972
  const reportQuality = analyzeResearchReportQuality(reportText);
@@ -999,6 +999,7 @@ export async function evaluateResearchGate(dir) {
999
999
  const replicationPack = await readReplicationPack(dir);
1000
1000
  const replicationValidation = validateReplicationPack(replicationPack);
1001
1001
  const falsificationValidation = validateFalsificationCoverage(falsificationLedger, contract);
1002
+ const canonicalAdversarial = await validateCanonicalResearchAdversarialEvidence(dir);
1002
1003
  let sourceQualityReport = await readSourceQualityReport(dir);
1003
1004
  if (!sourceQualityReport && sourceLedger)
1004
1005
  sourceQualityReport = await writeSourceQualityReport(dir, sourceLedger, claimMatrix);
@@ -1013,7 +1014,12 @@ export async function evaluateResearchGate(dir) {
1013
1014
  const triangulationChecks = Array.isArray(sourceLedger?.triangulation?.cross_layer_checks) ? sourceLedger.triangulation.cross_layer_checks.length : 0;
1014
1015
  const agentRows = Array.isArray(agentLedger?.agents) ? agentLedger.agents : [];
1015
1016
  const independentAgents = agentRows.filter((agent) => Array.isArray(agent.findings) && agent.findings.length > 0).length;
1016
- const xhighAgents = agentRows.filter((agent) => agent.effort === 'xhigh').length;
1017
+ const solMaxPolicyAgents = agentRows.filter((agent) => {
1018
+ const policy = agent?.model_policy && typeof agent.model_policy === 'object' ? agent.model_policy : agent;
1019
+ return policy.custom_agent === RESEARCH_REVIEWER_CUSTOM_AGENT
1020
+ && policy.model === 'gpt-5.6-sol'
1021
+ && (policy.reasoning_effort === 'max' || policy.model_reasoning_effort === 'max');
1022
+ }).length;
1017
1023
  const eurekaMoments = agentRows.filter((agent) => agent.eureka?.exclamation === 'Eureka!' && String(agent.eureka?.idea || '').trim()).length;
1018
1024
  const agentFindings = agentRows.reduce((sum, agent) => sum + (Array.isArray(agent.findings) ? agent.findings.length : 0), 0);
1019
1025
  const debateRows = Array.isArray(debateLedger?.exchanges) ? debateLedger.exchanges : [];
@@ -1029,6 +1035,8 @@ export async function evaluateResearchGate(dir) {
1029
1035
  const reasons = [];
1030
1036
  if (!reportPresent && gate.report_present !== true)
1031
1037
  reasons.push('research_report_missing');
1038
+ if (context7Required && !context7Evidence.ok)
1039
+ reasons.push('context7_required_evidence_missing');
1032
1040
  if (reportWordCount < contract.min_report_words)
1033
1041
  reasons.push('research_report_too_short');
1034
1042
  if (!reportQuality.ok)
@@ -1067,13 +1075,13 @@ export async function evaluateResearchGate(dir) {
1067
1075
  reasons.push('cross_layer_triangulation_missing');
1068
1076
  if (Math.max(Number(gate.independent_agents || 0), independentAgents) < RESEARCH_AGENT_COUNCIL.length)
1069
1077
  reasons.push('independent_agents_missing');
1070
- if (Math.max(Number(gate.xhigh_agents || 0), xhighAgents) < RESEARCH_AGENT_COUNCIL.length)
1071
- reasons.push('agent_effort_not_xhigh');
1078
+ if (Math.max(Number(gate.sol_max_policy_agents || 0), solMaxPolicyAgents) < RESEARCH_AGENT_COUNCIL.length)
1079
+ reasons.push('agent_model_policy_not_sol_max');
1072
1080
  if (Math.max(Number(gate.eureka_moments || 0), eurekaMoments) < RESEARCH_AGENT_COUNCIL.length)
1073
1081
  reasons.push('eureka_missing');
1074
1082
  if (!personaValidation.ok)
1075
1083
  reasons.push(...personaValidation.issues.map((issue) => `agent_persona:${issue}`));
1076
- if (Math.max(Number(gate.agent_findings || 0), agentFindings) < 4)
1084
+ if (Math.max(Number(gate.agent_findings || 0), agentFindings) < RESEARCH_AGENT_COUNCIL.length)
1077
1085
  reasons.push('agent_findings_missing');
1078
1086
  if (Math.max(Number(gate.debate_participants || 0), debateParticipants) < RESEARCH_AGENT_COUNCIL.length)
1079
1087
  reasons.push('debate_participants_missing');
@@ -1123,6 +1131,8 @@ export async function evaluateResearchGate(dir) {
1123
1131
  reasons.push('replication_pack_missing');
1124
1132
  if (!replicationValidation.ok)
1125
1133
  reasons.push(...replicationValidation.blockers);
1134
+ if (!canonicalAdversarial.ok)
1135
+ reasons.push(...canonicalAdversarial.blockers);
1126
1136
  for (const artifact of contract.required_artifacts || []) {
1127
1137
  if (artifact === RESEARCH_FINAL_REVIEW_ARTIFACT)
1128
1138
  continue;
@@ -1196,7 +1206,8 @@ export async function evaluateResearchGate(dir) {
1196
1206
  claim_evidence_matrix_blockers: claimMatrixValidation.blockers,
1197
1207
  source_quality_report_ok: sourceQualityReport?.ok === true,
1198
1208
  independent_agents: Math.max(Number(gate.independent_agents || 0), independentAgents),
1199
- xhigh_agents: Math.max(Number(gate.xhigh_agents || 0), xhighAgents),
1209
+ xhigh_agents: 0,
1210
+ sol_max_policy_agents: Math.max(Number(gate.sol_max_policy_agents || 0), solMaxPolicyAgents),
1200
1211
  eureka_moments: Math.max(Number(gate.eureka_moments || 0), eurekaMoments),
1201
1212
  agent_persona_contract_ok: personaValidation.ok,
1202
1213
  agent_persona_issues: personaValidation.issues,
@@ -1214,11 +1225,15 @@ export async function evaluateResearchGate(dir) {
1214
1225
  implementation_blueprint_validation: blueprintValidation,
1215
1226
  experiment_plan_validation: experimentValidation,
1216
1227
  replication_pack_validation: replicationValidation,
1228
+ canonical_adversarial_validation: canonicalAdversarial,
1217
1229
  novelty_entries: Array.isArray(noveltyLedger?.entries) ? noveltyLedger.entries.length : null,
1218
1230
  final_review_approved: finalReview?.approved === true,
1219
1231
  final_review_blockers: Array.isArray(finalReview?.blockers) ? finalReview.blockers : [],
1220
1232
  citation_coverage: citationCoverage,
1221
- web_search_blockers: searchBlockers.length
1233
+ web_search_blockers: searchBlockers.length,
1234
+ context7_required: context7Required,
1235
+ context7_verified: context7Evidence.ok,
1236
+ context7_evidence_records: context7Evidence.count
1222
1237
  },
1223
1238
  gate: {
1224
1239
  ...gate,
@@ -1229,6 +1244,25 @@ export async function evaluateResearchGate(dir) {
1229
1244
  await writeJsonAtomic(path.join(dir, 'research-gate.evaluated.json'), result);
1230
1245
  return result;
1231
1246
  }
1247
+ async function researchContext7Evidence(dir) {
1248
+ const text = await readText(path.join(dir, 'context7-evidence.jsonl'), '');
1249
+ let resolve = false;
1250
+ let docs = false;
1251
+ let count = 0;
1252
+ for (const line of text.split(/\r?\n/)) {
1253
+ if (!line.trim())
1254
+ continue;
1255
+ count += 1;
1256
+ try {
1257
+ const row = JSON.parse(line);
1258
+ if (row?.stage === 'resolve-library-id')
1259
+ resolve = true;
1260
+ if (row?.stage === 'get-library-docs' || row?.stage === 'query-docs')
1261
+ docs = true;
1262
+ }
1263
+ catch { }
1264
+ }
1265
+ return { resolve, docs, ok: resolve && docs, count };
1266
+ }
1232
1267
  export { writeMockResearchResult } from './research/mock-result.js';
1233
- export { buildResearchPrompt } from './research/prompt.js';
1234
1268
  //# sourceMappingURL=research.js.map