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
@@ -5,6 +5,7 @@ import { normalizeReleaseCacheInputForBehavior } from './release-cache-key.js';
5
5
  import { computeTriWikiCacheKey } from '../triwiki/triwiki-cache-key.js';
6
6
  import { createTriWikiProofCard } from '../triwiki/triwiki-proof-card.js';
7
7
  import { readReusableTriWikiProofCard, writeTriWikiProofCard } from '../triwiki/triwiki-proof-bank.js';
8
+ import { readCurrentNpmPackGateArtifacts } from './npm-pack-proof.js';
8
9
  export const RELEASE_GATE_CACHE_V2_SCHEMA = 'sks.release-gate-cache.v2';
9
10
  export function releaseGateCacheFile(root) {
10
11
  return path.join(root, '.sneakoscope', 'reports', 'release-gates', 'cache-v2.json');
@@ -139,6 +140,18 @@ export function readReleaseGateCacheRecord(root, gate) {
139
140
  const key = releaseGateCacheKey(root, gate);
140
141
  const proof = readReusableTriWikiProofCard({ root, subjectId: gate.id, cacheKey: key });
141
142
  if (proof.hit && proof.card) {
143
+ const artifactBlockers = releaseGateCacheArtifactBlockers(root, gate);
144
+ if (artifactBlockers.length) {
145
+ writeReleaseCacheBridgeReport(root, {
146
+ gate_id: gate.id,
147
+ cache_key: key,
148
+ bridge: 'triwiki-to-release-v2',
149
+ source: proof.path || null,
150
+ duration_ms: Math.max(0, Math.floor(Number(proof.card.duration_ms) || 0)),
151
+ disagreement: `required_artifact_invalid:${artifactBlockers.join(',')}`
152
+ });
153
+ return null;
154
+ }
142
155
  writeReleaseCacheBridgeReport(root, {
143
156
  gate_id: gate.id,
144
157
  cache_key: key,
@@ -161,6 +174,18 @@ export function readReleaseGateCacheRecord(root, gate) {
161
174
  const record = readCacheRecord(file, key);
162
175
  if (!record || record.ok !== true)
163
176
  continue;
177
+ const artifactBlockers = releaseGateCacheArtifactBlockers(root, gate);
178
+ if (artifactBlockers.length) {
179
+ writeReleaseCacheBridgeReport(root, {
180
+ gate_id: gate.id,
181
+ cache_key: key,
182
+ bridge: 'release-v2-to-triwiki',
183
+ source: file,
184
+ duration_ms: Math.max(0, Math.floor(Number(record.duration_ms) || 0)),
185
+ disagreement: `required_artifact_invalid:${artifactBlockers.join(',')}`
186
+ });
187
+ return null;
188
+ }
164
189
  writeTriWikiProofFromReleaseCacheRecord(root, gate, key, record, file);
165
190
  writeReleaseCacheBridgeReport(root, {
166
191
  gate_id: gate.id,
@@ -182,6 +207,11 @@ export function readReleaseGateCacheRecord(root, gate) {
182
207
  }
183
208
  return null;
184
209
  }
210
+ function releaseGateCacheArtifactBlockers(root, gate) {
211
+ if (!['publish:packlist-performance', 'package:published-contract'].includes(gate.id))
212
+ return [];
213
+ return readCurrentNpmPackGateArtifacts(root).blockers;
214
+ }
185
215
  export function writeReleaseGateCacheHit(root, gate, durationMs = 0) {
186
216
  const key = releaseGateCacheKey(root, gate);
187
217
  const record = {
@@ -0,0 +1,161 @@
1
+ import crypto from 'node:crypto';
2
+ export const RELEASE_GATE_CONTRACT_SCHEMA = 'sks.release-gate-contract.v1';
3
+ export const RELEASE_GATE_CONTRACT_IDS = Object.freeze([
4
+ 'agent:message-bus-reader',
5
+ 'all-features:deep-completion',
6
+ 'appshots:thread-attachment-discovery',
7
+ 'architecture:guard',
8
+ 'certificate:sla',
9
+ 'codex-app:agent-role-comprehensive',
10
+ 'codex-app:execution-profile',
11
+ 'codex-app:fast-ui-preservation',
12
+ 'codex-app:handoff',
13
+ 'codex-control:all-pipelines',
14
+ 'codex-control:event-stream-ledger',
15
+ 'codex-lb:comprehensive',
16
+ 'codex-native:agent-role-content',
17
+ 'codex-native:feature-broker-comprehensive',
18
+ 'codex-native:hook-lifecycle-proof',
19
+ 'codex-plugin:app-template-policy',
20
+ 'codex-sdk:all-pipelines',
21
+ 'codex-sdk:integration-comprehensive',
22
+ 'codex:0.134-runner-truth',
23
+ 'codex:0.137-compat',
24
+ 'codex:0138-capability-comprehensive',
25
+ 'codex:0138-doctor',
26
+ 'codex:0144:app-server-v2',
27
+ 'codex:0144:binary-identity',
28
+ 'codex:0144:capability',
29
+ 'codex:0144:manifest',
30
+ 'codex:0144:policy',
31
+ 'codex:0144:thread-store',
32
+ 'codex:app-handoff-comprehensive',
33
+ 'codex:product-design-plugin-routing',
34
+ 'config:managed-merge',
35
+ 'context7:evidence-dedupe',
36
+ 'core-skill:card-schema-deployment-snapshot',
37
+ 'core-skill:heldout-validation',
38
+ 'core-skill:no-inference-optimizer',
39
+ 'core-skill:patch',
40
+ 'core-skill:route-runtime-integration',
41
+ 'dfix:fixture',
42
+ 'dfix:patch-handoff',
43
+ 'dfix:patch-swarm-route-blackbox',
44
+ 'dfix:verification',
45
+ 'dfix:verification-recommendation',
46
+ 'docs:truthfulness',
47
+ 'doctor:codex-app-harness',
48
+ 'doctor:fix-proves-codex-read',
49
+ 'doctor:fixes-codex-app-fast-ui',
50
+ 'evidence:flagship-coverage',
51
+ 'fast:codex-service-tier-proof',
52
+ 'geo:comprehensive',
53
+ 'git-collaboration:e2e',
54
+ 'git:worktree-checkpoint-rebase-sync',
55
+ 'git:worktree-diff-apply-pipeline',
56
+ 'git:worktree-diff-envelope',
57
+ 'git:worktree-dirty-lock',
58
+ 'git:worktree-dirty-main-detection',
59
+ 'git:worktree-manifest-append',
60
+ 'goal:artifact-compat',
61
+ 'hook:latency-budget',
62
+ 'hooks:concurrent-session-collision',
63
+ 'image:artifact-path-contract',
64
+ 'init-deep:backup-retention',
65
+ 'legacy:gate-inventory',
66
+ 'legacy:gate-purge',
67
+ 'legacy:strong-inventory',
68
+ 'legacy:update-e2e',
69
+ 'local-collab:all-pipelines-final-gpt',
70
+ 'loop-integration-finalizer-check',
71
+ 'mad-db:capability',
72
+ 'mad-db:command',
73
+ 'mad-db:mad-command',
74
+ 'mad-db:operation-lifecycle',
75
+ 'mad-sks:app-ui-no-mutation',
76
+ 'mad:preflight-blocks-unreadable-config',
77
+ 'mcp:plugin-inventory',
78
+ 'migration:upgrade-safety',
79
+ 'model-call:concurrency',
80
+ 'naruto:canonical-stop-gate',
81
+ 'naruto:worktree-coding:blackbox',
82
+ 'native-capability:repair-matrix',
83
+ 'native:image-generation-repair',
84
+ 'package:published-contract',
85
+ 'pipeline:codex-native-routing-comprehensive',
86
+ 'policy:gate-audit',
87
+ 'ppt:full-e2e-blackbox',
88
+ 'ppt:real-export-adapter',
89
+ 'ppt:real-imagegen-wiring',
90
+ 'ppt:reexport-rereview',
91
+ 'probes:memoization',
92
+ 'prompt:placeholder-guard',
93
+ 'proof:root-cause-policy',
94
+ 'provider:badge-context',
95
+ 'publish:packlist-performance',
96
+ 'python-sdk:all-pipelines',
97
+ 'qa-loop:comprehensive-verification',
98
+ 'release:aggressive-resource-governor',
99
+ 'release:batch-runner-comprehensive',
100
+ 'release:cache-key-comprehensive',
101
+ 'release:dag-runner',
102
+ 'release:gate-budget',
103
+ 'release:gate-selection-comprehensive',
104
+ 'release:metadata-current',
105
+ 'release:parallel-speed-budget',
106
+ 'release:proof-truth',
107
+ 'release:provenance',
108
+ 'release:runtime-truth-matrix',
109
+ 'research:claim-builder-blueprint-comprehensive',
110
+ 'research:complete-package-final-review-comprehensive',
111
+ 'research:execution-profile-routing',
112
+ 'responses:retry-policy-centralized',
113
+ 'runtime:proof-summary',
114
+ 'safety:mutation-callsite-coverage',
115
+ 'scheduler:comprehensive',
116
+ 'schema:check',
117
+ 'secret:preservation',
118
+ 'seo-geo:route-identity-comprehensive',
119
+ 'seo-geo:skill-rich-content',
120
+ 'seo:comprehensive',
121
+ 'shared-memory:check',
122
+ 'side-effect:runtime-report',
123
+ 'skill:name-canonicalizer',
124
+ 'sksd:daemon',
125
+ 'super-search:provider-interface',
126
+ 'test:code-index-agent-bridge-regression',
127
+ 'test:codex-runtime-recovery',
128
+ 'test:commands-regression',
129
+ 'test:core-root-regression',
130
+ 'test:dfix-ppt-gate',
131
+ 'test:mad-sks-regression',
132
+ 'test:menubar-doctor',
133
+ 'test:official-subagent-policy',
134
+ 'test:proof-stop-gate',
135
+ 'test:triwiki-voxel-integrity',
136
+ 'triwiki:cache-key',
137
+ 'triwiki:proof-comprehensive',
138
+ 'trust:check',
139
+ 'type-surface:codex-app',
140
+ 'typecheck',
141
+ 'ultra-router:auto-router',
142
+ 'ux-review:extract-wires-real-extractor',
143
+ 'ux-review:imagegen-blackbox',
144
+ 'ux-review:patch-diff-recheck',
145
+ 'ux-review:run-wires-imagegen',
146
+ 'wrongness:check'
147
+ ]);
148
+ export function releaseGateContractSnapshot() {
149
+ const ids = [...RELEASE_GATE_CONTRACT_IDS];
150
+ const sha256 = crypto
151
+ .createHash('sha256')
152
+ .update(`${RELEASE_GATE_CONTRACT_SCHEMA}\n${ids.join('\n')}\n`)
153
+ .digest('hex');
154
+ return {
155
+ schema: RELEASE_GATE_CONTRACT_SCHEMA,
156
+ ids,
157
+ count: ids.length,
158
+ sha256
159
+ };
160
+ }
161
+ //# sourceMappingURL=release-gate-contract.js.map
@@ -168,6 +168,7 @@ export async function runReleaseGateDag(input) {
168
168
  failures,
169
169
  affected_graph: affectedGraph,
170
170
  completion_certificate: completionCertificate,
171
+ release_authorization_snapshot: input.releaseAuthorizationSnapshot || null,
171
172
  triwiki_affected_graph: triwikiGraph,
172
173
  triwiki_selection_used: triwikiSelectionUsed,
173
174
  triwiki_selected_gates: triwikiGraph ? selected.map((gate) => gate.id) : [],
@@ -1,6 +1,33 @@
1
+ import { RELEASE_AUTHORIZATION_SNAPSHOT_KEYS, sameReleaseAuthorizationSnapshot } from './release-authorization-snapshot.js';
1
2
  export const RELEASE_REAL_RESULT_CONTRACT_SCHEMA = 'sks.release-real-result-contract.v1';
2
3
  export const RELEASE_REAL_LIVE_COVERAGE_SCHEMA = 'sks.release-real-live-coverage.v1';
3
4
  export const RELEASE_REAL_SKIP_PROOF_SCHEMA = 'sks.release-real-skip-proof.v1';
5
+ export const RELEASE_REAL_REQUIRED_CHECK_IDS = Object.freeze([
6
+ 'codex:actual-config-load-probe',
7
+ 'codex:0144-core-real-probes:require-real',
8
+ 'codex:0144:app-server-v2:real',
9
+ 'codex:0144:capability:real',
10
+ 'doctor:actual',
11
+ 'publish:dry-run-performance',
12
+ 'zellij:capability',
13
+ 'zellij:layout-valid',
14
+ 'zellij:real-session-launch',
15
+ 'zellij:pane-proof',
16
+ 'zellij:screen-proof',
17
+ 'zellij:real-session-cleanup',
18
+ 'naruto:worktree-coding:blackbox',
19
+ 'codex-sdk:real-smoke'
20
+ ]);
21
+ export const RELEASE_REAL_OPTIONAL_CHECK_IDS = Object.freeze([
22
+ 'agent:real-codex-parallel-workers-5',
23
+ 'imagegen:real-smoke',
24
+ 'ux-review:real-imagegen-smoke',
25
+ 'ppt:real-imagegen-smoke'
26
+ ]);
27
+ export const RELEASE_REAL_CHECK_IDS = Object.freeze([
28
+ ...RELEASE_REAL_REQUIRED_CHECK_IDS,
29
+ ...RELEASE_REAL_OPTIONAL_CHECK_IDS
30
+ ]);
4
31
  const SKIPPED_STATUSES = new Set(['skipped', 'not_run', 'not_requested']);
5
32
  const OPTIONAL_STATUSES = new Set(['integration_optional', 'optional', 'not_required', 'skipped_optional_unavailable']);
6
33
  const FAILED_STATUSES = new Set(['failed', 'blocked', 'error', 'unavailable', 'real_required_missing']);
@@ -161,6 +188,8 @@ export function validateReleaseRealSkipProof(input) {
161
188
  const blockers = [];
162
189
  const summary = input.summary;
163
190
  const stamp = input.distStamp;
191
+ const authorization = input.authorizationSnapshot;
192
+ const summaryAuthorization = summary?.release_authorization_snapshot;
164
193
  if (!input.summaryPath || !summary)
165
194
  blockers.push('release_real_skip_full_summary_missing');
166
195
  if (summary?.schema !== 'sks.release-gate-dag-run.v1')
@@ -181,22 +210,53 @@ export function validateReleaseRealSkipProof(input) {
181
210
  blockers.push('release_real_skip_full_summary_empty');
182
211
  if (!Array.isArray(summary?.selected_gate_ids) || summary.selected_gate_ids.length !== summary?.selected_gates)
183
212
  blockers.push('release_real_skip_full_summary_gate_ids_incomplete');
213
+ const expectedReleaseGateIds = unique((input.expectedReleaseGateIds || []).map(String).filter(Boolean)).sort();
214
+ const selectedReleaseGateIds = unique((Array.isArray(summary?.selected_gate_ids) ? summary.selected_gate_ids : []).map(String).filter(Boolean)).sort();
215
+ if (!expectedReleaseGateIds.length)
216
+ blockers.push('release_real_skip_expected_release_gate_ids_missing');
217
+ if (expectedReleaseGateIds.length && !sameStringList(expectedReleaseGateIds, selectedReleaseGateIds))
218
+ blockers.push('release_real_skip_full_summary_gate_ids_mismatch');
184
219
  if (summary?.failed !== 0 || summary?.completed !== summary?.selected_gates)
185
220
  blockers.push('release_real_skip_full_summary_incomplete');
186
221
  if (!/^[a-f0-9]{64}$/i.test(String(input.summarySha256 || '')))
187
222
  blockers.push('release_real_skip_full_summary_hash_missing');
188
- if (!/^[a-f0-9]{64}$/i.test(String(input.currentSourceDigest || '')))
223
+ if (!/^[a-f0-9]{40,64}$/i.test(String(authorization?.git_commit || '')))
224
+ blockers.push('release_real_skip_git_commit_missing');
225
+ if (!/^[a-f0-9]{64}$/i.test(String(authorization?.source_digest || '')))
189
226
  blockers.push('release_real_skip_current_source_digest_missing');
227
+ if (!Number.isInteger(authorization?.source_file_count) || Number(authorization?.source_file_count) <= 0)
228
+ blockers.push('release_real_skip_source_file_count_missing');
229
+ if (!/^[a-f0-9]{64}$/i.test(String(authorization?.package_files_sha256 || '')))
230
+ blockers.push('release_real_skip_package_files_digest_missing');
231
+ if (!Number.isInteger(authorization?.package_file_count) || Number(authorization?.package_file_count) <= 0)
232
+ blockers.push('release_real_skip_package_file_count_missing');
233
+ if (!/^[a-f0-9]{64}$/i.test(String(authorization?.release_gate_sha256 || '')))
234
+ blockers.push('release_real_skip_release_gate_digest_missing');
235
+ if (!/^[a-f0-9]{64}$/i.test(String(authorization?.dist_build_sha256 || '')))
236
+ blockers.push('release_real_skip_dist_digest_missing');
237
+ if (!Number.isInteger(authorization?.dist_file_count) || Number(authorization?.dist_file_count) <= 0)
238
+ blockers.push('release_real_skip_dist_file_count_missing');
239
+ if (!summaryAuthorization || typeof summaryAuthorization !== 'object') {
240
+ blockers.push('release_real_skip_full_summary_authorization_snapshot_missing');
241
+ }
242
+ else if (!sameReleaseAuthorizationSnapshot(summaryAuthorization, authorization)) {
243
+ for (const key of RELEASE_AUTHORIZATION_SNAPSHOT_KEYS) {
244
+ if (summaryAuthorization[key] !== authorization?.[key])
245
+ blockers.push(`release_real_skip_full_summary_authorization_mismatch:${key}`);
246
+ }
247
+ }
248
+ if (!/^[a-f0-9]{64}$/i.test(String(input.currentDistSourceDigest || '')))
249
+ blockers.push('release_real_skip_dist_source_digest_missing');
190
250
  if (!stamp || !stamp.source_digest)
191
251
  blockers.push('release_real_skip_dist_source_stamp_missing');
192
252
  if (stamp && !['sks.dist-build-stamp.v1', 'sks.dist-build.v2'].includes(String(stamp.schema || '')))
193
253
  blockers.push('release_real_skip_dist_source_stamp_schema_invalid');
194
- if (stamp?.source_digest && input.currentSourceDigest && stamp.source_digest !== input.currentSourceDigest)
195
- blockers.push('release_real_skip_source_digest_mismatch');
196
- if (!Number.isInteger(input.currentSourceFileCount) || !Number.isInteger(stamp?.source_file_count))
197
- blockers.push('release_real_skip_source_file_count_missing');
198
- if (Number.isInteger(input.currentSourceFileCount) && Number.isInteger(stamp?.source_file_count) && stamp.source_file_count !== input.currentSourceFileCount)
199
- blockers.push('release_real_skip_source_file_count_mismatch');
254
+ if (stamp?.source_digest && input.currentDistSourceDigest && stamp.source_digest !== input.currentDistSourceDigest)
255
+ blockers.push('release_real_skip_dist_source_digest_mismatch');
256
+ if (!Number.isInteger(input.currentDistSourceFileCount) || !Number.isInteger(stamp?.source_file_count))
257
+ blockers.push('release_real_skip_dist_source_file_count_missing');
258
+ if (Number.isInteger(input.currentDistSourceFileCount) && Number.isInteger(stamp?.source_file_count) && stamp.source_file_count !== input.currentDistSourceFileCount)
259
+ blockers.push('release_real_skip_dist_source_file_count_mismatch');
200
260
  if (!Number.isFinite(input.summaryMtimeMs) || !Number.isFinite(input.distStampMtimeMs))
201
261
  blockers.push('release_real_skip_proof_mtime_missing');
202
262
  if (Number.isFinite(input.summaryMtimeMs) && Number.isFinite(input.distStampMtimeMs) && Number(input.summaryMtimeMs) < Number(input.distStampMtimeMs))
@@ -207,15 +267,16 @@ export function validateReleaseRealSkipProof(input) {
207
267
  return {
208
268
  schema: RELEASE_REAL_SKIP_PROOF_SCHEMA,
209
269
  ok: blockers.length === 0,
210
- proof_source: 'latest_full_dag_receipt+current_dist_source_stamp',
270
+ proof_source: 'latest_full_dag_receipt+release_authorization_snapshot+current_dist_source_stamp',
211
271
  latest_summary_path: input.summaryPath,
212
272
  latest_summary_sha256: input.summarySha256,
213
273
  run_id: summary?.run_id || null,
214
274
  selected_gates: summary?.selected_gates ?? null,
215
275
  completed: summary?.completed ?? null,
216
276
  failed: summary?.failed ?? null,
217
- source_digest: input.currentSourceDigest,
218
- source_file_count: input.currentSourceFileCount,
277
+ ...authorization,
278
+ dist_source_digest: input.currentDistSourceDigest,
279
+ dist_source_file_count: input.currentDistSourceFileCount,
219
280
  dist_stamp_path: input.distStampPath,
220
281
  dist_stamp_source_digest: stamp?.source_digest || null,
221
282
  summary_mtime_ms: input.summaryMtimeMs,
@@ -225,6 +286,22 @@ export function validateReleaseRealSkipProof(input) {
225
286
  blockers: unique(blockers)
226
287
  };
227
288
  }
289
+ export function validateReleaseRealTaskIds(taskIds) {
290
+ const raw = taskIds.map(String).filter(Boolean);
291
+ const actual = unique(raw);
292
+ const expected = [...RELEASE_REAL_CHECK_IDS];
293
+ const missing = expected.filter((id) => !actual.includes(id));
294
+ const unexpected = actual.filter((id) => !expected.includes(id));
295
+ const duplicates = unique(raw.filter((id, index) => raw.indexOf(id) !== index));
296
+ return {
297
+ ok: missing.length === 0 && unexpected.length === 0 && duplicates.length === 0,
298
+ expected_ids: expected,
299
+ actual_ids: actual,
300
+ missing_ids: missing,
301
+ unexpected_ids: unexpected,
302
+ duplicate_ids: duplicates
303
+ };
304
+ }
228
305
  export function parseReleaseRealJsonOutput(stdout, stderr) {
229
306
  const stdoutEnvelope = bestJsonEnvelope(stdout);
230
307
  const stderrEnvelope = bestJsonEnvelope(stderr);
@@ -409,6 +486,9 @@ function countOutcomes(rows) {
409
486
  function unique(values) {
410
487
  return [...new Set(values)];
411
488
  }
489
+ function sameStringList(left, right) {
490
+ return left.length === right.length && left.every((value, index) => value === right[index]);
491
+ }
412
492
  function tail(value, limit = 4000) {
413
493
  const text = String(value || '');
414
494
  return text.length <= limit ? text : text.slice(-limit);
@@ -1,158 +1,46 @@
1
1
  import { nowIso } from './fsx.js';
2
- export const RELEASE_PARALLEL_FULL_COVERAGE_SCHEMA = 'sks.release-parallel-full-coverage.v1';
3
- export const RELEASE_1_17_GATE_SNAPSHOT = Object.freeze([
4
- 'build',
5
- 'runtime:no-src-mjs',
6
- 'runtime:ts-source-of-truth',
7
- 'architecture:guard',
8
- 'runtime:dist-parity',
9
- 'routes:proof-artifact-structure',
10
- 'agent:codex-app-cockpit',
11
- 'agent:janitor',
12
- 'agent:multi-project-isolation',
13
- 'verification:parallel-engine',
14
- 'typecheck',
15
- 'schema:check',
16
- 'release:metadata',
17
- 'release:readiness'
18
- ]);
19
- export const RELEASE_1_18_REQUIRED_GATES = Object.freeze([
20
- 'super-search:provider-interface',
21
- 'source-intelligence:policy',
22
- 'source-intelligence:all-modes',
23
- 'codex-web:adapter',
24
- 'goal-mode:official-default',
25
- 'agent:main-no-scout',
26
- 'agent:worker-scout-limited',
27
- 'agent:background-terminals',
28
- 'agent:zellij-runtime',
29
- 'agent:dynamic-pool',
30
- 'agent:backfill-replenishment',
31
- 'agent:scheduler-proof',
32
- 'agent:session-generation',
33
- 'agent:terminal-generations',
34
- 'mad-sks:zellij-launch',
35
- 'agent:dynamic-cockpit',
36
- 'agent:source-intelligence-propagation',
37
- 'agent:goal-mode-propagation',
38
- 'agent:visual-consistency',
39
- 'release:parallel-full-coverage',
40
- 'priority:full-closure',
41
- 'release:native-agent-backend',
42
- 'agent:legacy-multiagent-removed',
43
- 'all-features:completion',
44
- 'all-features:deep-completion',
45
- 'json-schema:recursive-check',
46
- 'evidence:flagship-coverage',
47
- 'image-fidelity:check',
48
- 'imagegen:capability',
49
- 'imagegen:gpt-image-2-request-validator',
50
- 'ux-review:run-wires-imagegen',
51
- 'ux-review:extract-wires-real-extractor',
52
- 'ux-review:patch-diff-recheck',
53
- 'ux-review:imagegen-blackbox',
54
- 'ux-review:real-loop-fixture',
55
- 'ux-review:generate-callouts-fixture',
56
- 'ux-review:extract-real-callouts-fixture',
57
- 'ux-review:patch-handoff-fixture',
58
- 'ux-review:recapture-recheck-fixture',
59
- 'ux-review:no-text-fallback',
60
- 'ux-review:no-fake-callouts',
61
- 'ux-review:image-voxel-relations',
62
- 'ppt:imagegen-review-fixture',
63
- 'ppt:full-e2e-blackbox',
64
- 'ppt:full-e2e-artifact-graph',
65
- 'ppt:real-export-adapter',
66
- 'ppt:real-imagegen-wiring',
67
- 'ppt:reexport-rereview',
68
- 'ppt:imagegen-blackbox',
69
- 'ux-ppt:structured-extraction',
70
- 'ppt:slide-export-fixture',
71
- 'ppt:no-text-fallback',
72
- 'ppt:no-mock-as-real',
73
- 'ppt:issue-extraction-fixture',
74
- 'ppt:image-voxel-relations',
75
- 'ppt:proof-trust-fixture',
76
- 'dfix:fixture',
77
- 'dfix:fast-kernel',
78
- 'dfix:blackbox-fast',
79
- 'dfix:performance',
80
- 'dfix:patch-handoff',
81
- 'dfix:verification-recommendation',
82
- 'dfix:verification',
83
- 'hooks:strict-subset-check',
84
- 'hooks:latest-schema-check',
85
- 'hooks:trust-state-check',
86
- 'hooks:trust-warning-zero',
87
- 'hooks:subagent-events-check',
88
- 'hooks:no-unsupported-handlers',
89
- 'hooks:actual-parity-check',
90
- 'hooks:actual-parity-v2',
91
- 'hooks:official-hash-parity',
92
- 'hooks:official-hash-oracle',
93
- 'hooks:managed-install-fixture',
94
- 'hooks:runtime-replay-warning-zero',
95
- 'hooks:runtime-replay-warning-zero-v2',
96
- 'codex-lb:persistence-truth',
97
- 'codex-lb:setup-truthfulness',
98
- 'computer-use:visual-route-fixture',
99
- 'computer-use:live-evidence',
100
- 'codex:0.133-compat',
101
- 'codex:output-schema-fixture',
102
- 'codex:exec-syntax-parity',
103
- 'codex:0.133-official-compat',
104
- 'flagship:proof-graph-v3',
105
- 'flagship:proof-graph-v4',
106
- 'mad-sks:permission-model',
107
- 'mad-sks:immutable-harness',
108
- 'mad-sks:write-guard',
109
- 'mad-sks:audit-proof',
110
- 'mad-sks:no-harness-modification',
111
- 'mad-sks:actual-executor',
112
- 'mad-sks:file-write-executor',
113
- 'mad-sks:shell-executor',
114
- 'mad-sks:package-executor',
115
- 'mad-sks:service-executor',
116
- 'mad-sks:db-executor',
117
- 'mad-sks:rollback-apply',
118
- 'mad-sks:live-guard-smoke',
119
- 'mad-sks:executor-proof-graph',
120
- 'memory-summary:rebuild-check',
121
- 'loop-blocker:check',
122
- 'docs:truthfulness',
123
- 'official-docs:compat',
124
- 'blackbox:matrix:contract',
125
- 'test:blackbox',
126
- 'rust:check',
127
- 'rust:smoke',
128
- 'release:dist-freshness',
129
- 'perf:gate'
130
- ]);
2
+ import { RELEASE_GATE_CONTRACT_IDS, releaseGateContractSnapshot } from './release/release-gate-contract.js';
3
+ export const RELEASE_PARALLEL_FULL_COVERAGE_SCHEMA = 'sks.release-parallel-full-coverage.v2';
4
+ // Compatibility export: the independent, versioned contract is now the full
5
+ // release preset, not a self-authorizing critical subset.
6
+ export const RELEASE_DAG_CRITICAL_GATES = RELEASE_GATE_CONTRACT_IDS;
131
7
  export function evaluateReleaseParallelFullCoverage(currentGateIds) {
132
- const current = [...new Set(currentGateIds)];
133
- const previousMissing = RELEASE_1_17_GATE_SNAPSHOT.filter((gate) => !current.includes(gate));
134
- const requiredMissing = RELEASE_1_18_REQUIRED_GATES.filter((gate) => !current.includes(gate));
8
+ const raw = currentGateIds.map(String).filter(Boolean);
9
+ const current = [...new Set(raw)].sort();
10
+ const contract = releaseGateContractSnapshot();
11
+ const missingCritical = contract.ids.filter((gate) => !current.includes(gate));
12
+ const unexpectedGates = current.filter((gate) => !contract.ids.includes(gate));
13
+ const duplicateGateIds = [...new Set(raw.filter((id, index) => raw.indexOf(id) !== index))].sort();
135
14
  const independentGroups = {
136
- source_intelligence: current.filter((gate) => /source-intelligence|xai|codex-web|goal-mode/.test(gate)),
137
- agent_runtime: current.filter((gate) => /agent:/.test(gate)),
138
- release_readiness: current.filter((gate) => /release:|priority:/.test(gate)),
139
- baseline: current.filter((gate) => RELEASE_1_17_GATE_SNAPSHOT.includes(gate))
15
+ release_integrity: current.filter((gate) => /^(?:architecture:|policy:|release:|typecheck$|schema:check$)/.test(gate)),
16
+ official_subagents: current.filter((gate) => /official-subagent|native-agent|naruto:/.test(gate)),
17
+ runtime_recovery: current.filter((gate) => /codex-lb|runtime-recovery|responses:/.test(gate)),
18
+ feature_closure: current.filter((gate) => /all-features|feature|research:/.test(gate))
140
19
  };
141
20
  return {
142
21
  schema: RELEASE_PARALLEL_FULL_COVERAGE_SCHEMA,
143
22
  generated_at: nowIso(),
144
- ok: previousMissing.length === 0 && requiredMissing.length === 0,
145
- previous_gate_count: RELEASE_1_17_GATE_SNAPSHOT.length,
23
+ ok: current.length > 0
24
+ && current.length <= 200
25
+ && missingCritical.length === 0
26
+ && unexpectedGates.length === 0
27
+ && duplicateGateIds.length === 0,
28
+ authoritative_source: 'src/core/release/release-gate-contract.ts',
29
+ manifest_source: 'release-gates.v2.json',
30
+ release_gate_contract: contract,
31
+ legacy_runner_snapshot_retired: true,
32
+ critical_gate_count: RELEASE_DAG_CRITICAL_GATES.length,
146
33
  current_gate_count: current.length,
147
- previous_gate_snapshot: [...RELEASE_1_17_GATE_SNAPSHOT],
148
34
  current_gate_list: current,
149
- missing_previous_gates: previousMissing,
150
- missing_1_18_required_gates: requiredMissing,
151
- coverage_regression: previousMissing.length > 0,
35
+ missing_critical_gates: missingCritical,
36
+ unexpected_release_gates: unexpectedGates,
37
+ duplicate_gate_ids: duplicateGateIds,
38
+ gate_budget_ok: current.length > 0 && current.length <= 200,
39
+ coverage_regression: missingCritical.length > 0 || unexpectedGates.length > 0,
152
40
  independent_groups: independentGroups,
153
41
  speedup_summary: {
154
42
  parallel_groups: Object.values(independentGroups).filter((rows) => rows.length > 0).length,
155
- estimated_speedup: current.length > 1 ? 'parallel DAG preserves baseline coverage and adds independent 1.18 groups' : 'none'
43
+ execution_model: 'manifest-backed parallel DAG'
156
44
  }
157
45
  };
158
46
  }
@@ -34,11 +34,6 @@ export function validateClaimEvidenceMatrix(matrix, sourceLedger = null, falsifi
34
34
  const normalized = normalizeClaimEvidenceMatrix(matrix);
35
35
  const claimIds = new Set(normalized.claims.map((claim) => claim.id));
36
36
  const sourceIds = sourceIdSet(sourceLedger);
37
- const counterIds = new Set([
38
- ...Array.from(sourceIds).filter((id) => /counter/i.test(id)),
39
- ...(Array.isArray(sourceLedger?.counterevidence_sources) ? sourceLedger.counterevidence_sources.map((row) => String(row?.id || '')).filter(Boolean) : []),
40
- ...(Array.isArray(falsificationLedger?.cases) ? falsificationLedger.cases.flatMap((row) => [row?.id, ...(Array.isArray(row?.counterevidence_source_ids) ? row.counterevidence_source_ids : []), ...(Array.isArray(row?.source_ids) ? row.source_ids : [])]).map(String).filter(Boolean) : [])
41
- ]);
42
37
  const blockers = [];
43
38
  for (const id of normalized.key_claim_ids)
44
39
  if (!claimIds.has(id))
@@ -53,8 +48,25 @@ export function validateClaimEvidenceMatrix(matrix, sourceLedger = null, falsifi
53
48
  if (!sourceIds.has(sourceId))
54
49
  blockers.push(`claim_source_unknown:${claim.id}:${sourceId}`);
55
50
  for (const counterId of claim.counterevidence_ids)
56
- if (!counterIds.has(counterId))
51
+ if (!sourceIds.has(counterId))
57
52
  blockers.push(`claim_counterevidence_unknown:${claim.id}:${counterId}`);
53
+ const linkedCounterIds = new Set(claim.counterevidence_links
54
+ .filter((link) => link.target_claim_id === claim.id && link.contradiction_rationale.trim())
55
+ .map((link) => link.source_id));
56
+ for (const counterId of claim.counterevidence_ids) {
57
+ if (!linkedCounterIds.has(counterId))
58
+ blockers.push(`claim_counterevidence_link_missing:${claim.id}:${counterId}`);
59
+ }
60
+ for (const link of claim.counterevidence_links) {
61
+ if (link.target_claim_id !== claim.id)
62
+ blockers.push(`claim_counterevidence_target_mismatch:${claim.id}:${link.source_id}`);
63
+ if (!sourceIds.has(link.source_id))
64
+ blockers.push(`claim_counterevidence_link_source_unknown:${claim.id}:${link.source_id}`);
65
+ if (!claim.counterevidence_ids.includes(link.source_id))
66
+ blockers.push(`claim_counterevidence_link_unlisted:${claim.id}:${link.source_id}`);
67
+ if (!link.contradiction_rationale.trim())
68
+ blockers.push(`claim_counterevidence_rationale_missing:${claim.id}:${link.source_id}`);
69
+ }
58
70
  if (claim.claim_type === 'hypothesis' && !claim.test_or_probe.trim())
59
71
  blockers.push(`hypothesis_probe_missing:${claim.id}`);
60
72
  }
@@ -99,6 +111,11 @@ export function buildClaimEvidenceMatrixFromLedgers(input = {}) {
99
111
  importance: index < 2 ? 'critical' : 'high',
100
112
  source_ids: sourceIds.length ? sourceIds : fallbackSourceIds.slice(0, 2),
101
113
  counterevidence_ids: counterIds.length ? counterIds : fallbackCounterIds.slice(0, 1),
114
+ counterevidence_links: (counterIds.length ? counterIds : fallbackCounterIds.slice(0, 1)).map((sourceId) => ({
115
+ source_id: sourceId,
116
+ target_claim_id: id,
117
+ contradiction_rationale: `The structured counterevidence row challenges ${id}.`
118
+ })),
102
119
  triangulation: {
103
120
  source_layers: sourceLayersForSourceIds(input.sourceLedger, sourceIds.length ? sourceIds : fallbackSourceIds),
104
121
  independent_confirmation_count: Math.max(1, sourceIds.length || fallbackSourceIds.length),
@@ -131,6 +148,7 @@ function normalizeClaim(value) {
131
148
  source_ids: normalizeStringList(value?.source_ids),
132
149
  local_evidence_ids: normalizeStringList(value?.local_evidence_ids),
133
150
  counterevidence_ids: normalizeStringList(value?.counterevidence_ids),
151
+ counterevidence_links: normalizeCounterevidenceLinks(value?.counterevidence_links),
134
152
  triangulation: {
135
153
  source_layers: normalizeStringList(value?.triangulation?.source_layers),
136
154
  independent_confirmation_count: Math.max(0, Math.floor(Number(value?.triangulation?.independent_confirmation_count || 0))),
@@ -141,6 +159,23 @@ function normalizeClaim(value) {
141
159
  test_or_probe: String(value?.test_or_probe || '').trim()
142
160
  };
143
161
  }
162
+ function normalizeCounterevidenceLinks(value) {
163
+ const rows = Array.isArray(value) ? value : [];
164
+ const seen = new Set();
165
+ return rows.map((row) => ({
166
+ source_id: String(row?.source_id || '').trim(),
167
+ target_claim_id: String(row?.target_claim_id || '').trim(),
168
+ contradiction_rationale: String(row?.contradiction_rationale || '').trim()
169
+ })).filter((row) => {
170
+ if (!row.source_id || !row.target_claim_id || !row.contradiction_rationale)
171
+ return false;
172
+ const key = `${row.source_id}\0${row.target_claim_id}`;
173
+ if (seen.has(key))
174
+ return false;
175
+ seen.add(key);
176
+ return true;
177
+ });
178
+ }
144
179
  function sourceIdSet(sourceLedger) {
145
180
  return new Set([
146
181
  ...(Array.isArray(sourceLedger?.sources) ? sourceLedger.sources : []),