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.
- package/README.md +35 -11
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/fast-inline.js +18 -9
- package/dist/bin/sks-dispatch.js +2 -2
- package/dist/cli/args.js +2 -0
- package/dist/cli/command-manifest-lite.js +2 -3
- package/dist/cli/command-registry.js +3 -4
- package/dist/cli/help-fast.js +1 -1
- package/dist/cli/install-helpers.js +116 -306
- package/dist/cli/install-tool-helpers.js +287 -0
- package/dist/cli/router.js +40 -4
- package/dist/commands/codex-lb.js +51 -20
- package/dist/commands/codex.js +39 -1
- package/dist/commands/doctor.js +242 -20
- package/dist/commands/tmux.js +5 -1
- package/dist/commands/zellij-monitor-pane.js +2 -0
- package/dist/commands/zellij-viewport-pane.js +3 -1
- package/dist/commands/zellij.js +1 -1
- package/dist/config/skills-manifest.json +59 -59
- package/dist/core/agent-bridge/agent-manifest.js +48 -0
- package/dist/core/agents/agent-command-surface.js +2 -1
- package/dist/core/agents/agent-effort-policy.js +38 -35
- package/dist/core/agents/agent-plan.js +100 -21
- package/dist/core/agents/agent-role-config.js +43 -46
- package/dist/core/agents/agent-runner-codex-exec.js +16 -3
- package/dist/core/agents/agent-schema.js +3 -2
- package/dist/core/agents/native-cli-session-swarm.js +1 -1
- package/dist/core/agents/zellij-right-lane-cockpit.js +2 -2
- package/dist/core/codex/agent-config-file-repair.js +94 -193
- package/dist/core/codex/codex-cli-update.js +723 -0
- package/dist/core/codex/codex-config-guard.js +185 -9
- package/dist/core/codex/codex-config-readability.js +21 -8
- package/dist/core/codex/codex-config-toml.js +14 -11
- package/dist/core/codex/codex-project-config-policy.js +3 -6
- package/dist/core/codex/codex-startup-config-postcheck.js +52 -42
- package/dist/core/codex-adapter.js +35 -22
- package/dist/core/codex-app/codex-agent-role-sync.js +13 -54
- package/dist/core/codex-app/codex-app-launcher.js +48 -17
- package/dist/core/codex-app/codex-app-restart.js +23 -2
- package/dist/core/codex-app/mcp-manager.js +679 -0
- package/dist/core/codex-app/sks-menubar.js +533 -8
- package/dist/core/codex-control/codex-0139-image-path-real-probe.js +15 -4
- package/dist/core/codex-control/codex-0139-web-search-probe.js +17 -6
- package/dist/core/codex-control/codex-lb-launch-recovery.js +293 -0
- package/dist/core/codex-control/codex-reliability-shield.js +89 -29
- package/dist/core/codex-control/codex-sdk-adapter.js +44 -8
- package/dist/core/codex-control/codex-task-runner.js +62 -9
- package/dist/core/codex-control/python-codex-sdk-adapter.js +30 -3
- package/dist/core/codex-exec-output-schema.js +35 -6
- package/dist/core/codex-lb/codex-lb-env.js +1 -1
- package/dist/core/codex-lb/codex-lb-tool-output-recovery.js +291 -0
- package/dist/core/codex-native/codex-native-feature-broker.js +9 -16
- package/dist/core/codex-native/codex-native-repair-transaction.js +1 -1
- package/dist/core/codex-native/core-skill-manifest.js +8 -4
- package/dist/core/codex-runtime/codex-desktop-config-policy.js +2 -3
- package/dist/core/commands/agent-bridge-command.js +23 -2
- package/dist/core/commands/agent-command.js +19 -5
- package/dist/core/commands/basic-cli.js +47 -6
- package/dist/core/commands/command-utils.js +1 -1
- package/dist/core/commands/mad-sks-command.js +76 -10
- package/dist/core/commands/menubar-command.js +94 -0
- package/dist/core/commands/naruto-command.js +645 -1156
- package/dist/core/commands/research-command.js +293 -231
- package/dist/core/commands/run-command.js +100 -23
- package/dist/core/commands/team-command.js +2 -3
- package/dist/core/commands/team-legacy-observe-command.js +94 -359
- package/dist/core/commands/wiki-command.js +11 -5
- package/dist/core/db-safety.js +2 -2
- package/dist/core/decision-lattice.js +6 -6
- package/dist/core/doctor/codex-startup-config-repair.js +8 -3
- package/dist/core/doctor/doctor-codex-startup-repair.js +6 -141
- package/dist/core/feature-fixture-executor.js +71 -7
- package/dist/core/feature-fixture-runner.js +53 -12
- package/dist/core/feature-fixtures.js +47 -14
- package/dist/core/feature-registry.js +28 -27
- package/dist/core/fsx.js +1 -0
- package/dist/core/harness-conflicts.js +18 -9
- package/dist/core/hooks-runtime/code-pack-freshness-preflight.js +14 -8
- package/dist/core/hooks-runtime/hook-io.js +8 -4
- package/dist/core/hooks-runtime/light-turn.js +70 -0
- package/dist/core/hooks-runtime/naruto-decision-gate.js +184 -0
- package/dist/core/hooks-runtime/payload-signals.js +270 -0
- package/dist/core/hooks-runtime/stop-repeat-guard.js +89 -0
- package/dist/core/hooks-runtime/team-digest.js +0 -1
- package/dist/core/hooks-runtime/tool-output-quarantine.js +93 -0
- package/dist/core/hooks-runtime.js +438 -354
- package/dist/core/init/skills.js +16 -30
- package/dist/core/init.js +144 -36
- package/dist/core/managed-assets/managed-assets-manifest.js +566 -10
- package/dist/core/mission.js +24 -1
- package/dist/core/pipeline-internals/runtime-core.js +570 -177
- package/dist/core/pipeline-internals/runtime-gates.js +174 -48
- package/dist/core/preflight/parallel-preflight-engine.js +66 -4
- package/dist/core/proof/route-adapter.js +1 -1
- package/dist/core/proof/route-proof-gate.js +7 -2
- package/dist/core/proof/selftest-proof-fixtures.js +3 -5
- package/dist/core/proof-field.js +1 -1
- package/dist/core/provider/model-router.js +42 -31
- package/dist/core/recallpulse/policy.js +12 -28
- package/dist/core/recallpulse.js +11 -6
- package/dist/core/release/npm-pack-proof.js +247 -0
- package/dist/core/release/package-dist-snapshot.js +151 -0
- package/dist/core/release/package-size-budget.js +4 -1
- package/dist/core/release/release-authorization-snapshot.js +115 -0
- package/dist/core/release/release-gate-affected-selector.js +14 -2
- package/dist/core/release/release-gate-cache-v2.js +30 -0
- package/dist/core/release/release-gate-contract.js +161 -0
- package/dist/core/release/release-gate-dag.js +1 -0
- package/dist/core/release/release-real-contract.js +90 -10
- package/dist/core/release-parallel-full-coverage.js +31 -143
- package/dist/core/research/claim-evidence-matrix.js +41 -6
- package/dist/core/research/experiment-plan.js +14 -10
- package/dist/core/research/falsification.js +9 -2
- package/dist/core/research/implementation-blueprint-densifier.js +82 -60
- package/dist/core/research/implementation-blueprint.js +32 -26
- package/dist/core/research/mock-result.js +122 -11
- package/dist/core/research/replication-pack.js +15 -8
- package/dist/core/research/research-adversarial-review.js +1068 -0
- package/dist/core/research/research-claim-builder.js +69 -17
- package/dist/core/research/research-claim-synthesizer.js +343 -0
- package/dist/core/research/research-cycle-runner.js +53 -3
- package/dist/core/research/research-falsification-runner.js +176 -0
- package/dist/core/research/research-final-reviewer.js +44 -125
- package/dist/core/research/research-plan-markdown.js +123 -0
- package/dist/core/research/research-realistic-report.js +14 -6
- package/dist/core/research/research-review-artifact-digest.js +66 -0
- package/dist/core/research/research-source-evidence.js +144 -0
- package/dist/core/research/research-source-layer-catalog.js +68 -0
- package/dist/core/research/research-source-ledger-merge.js +250 -12
- package/dist/core/research/research-source-shards.js +26 -70
- package/dist/core/research/research-stage-runner.js +237 -247
- package/dist/core/research/research-super-search.js +188 -0
- package/dist/core/research/research-synthesis-prompt.js +20 -1
- package/dist/core/research/research-synthesis-writer.js +86 -5
- package/dist/core/research/research-work-graph.js +25 -18
- package/dist/core/research/source-quality-report.js +21 -0
- package/dist/core/research.js +424 -390
- package/dist/core/retention.js +70 -2
- package/dist/core/routes/constants.js +1 -1
- package/dist/core/routes/dollar-manifest-lite.js +11 -11
- package/dist/core/routes.js +149 -69
- package/dist/core/runtime/task-profile.js +66 -0
- package/dist/core/runtime/verification-budget.js +12 -0
- package/dist/core/security/high-risk-contracts.js +6 -6
- package/dist/core/stop-gate/stop-gate-check.js +49 -12
- package/dist/core/subagents/agent-catalog.js +287 -0
- package/dist/core/subagents/model-policy.js +259 -0
- package/dist/core/subagents/naruto-help-contract.js +47 -0
- package/dist/core/subagents/official-subagent-config.js +488 -0
- package/dist/core/subagents/official-subagent-preparation.js +297 -0
- package/dist/core/subagents/official-subagent-prompt.js +159 -0
- package/dist/core/subagents/official-subagent-runner.js +129 -0
- package/dist/core/subagents/subagent-evidence.js +663 -0
- package/dist/core/subagents/terminology.js +16 -0
- package/dist/core/subagents/thread-budget.js +21 -0
- package/dist/core/subagents/triwiki-attention.js +168 -0
- package/dist/core/super-search/runtime-helpers.js +173 -19
- package/dist/core/super-search/runtime.js +140 -15
- package/dist/core/super-search/source-records.js +49 -8
- package/dist/core/team-review-policy.js +15 -0
- package/dist/core/triwiki/code-pack-head-freshness.js +291 -0
- package/dist/core/triwiki/triwiki-module-card.js +1 -1
- package/dist/core/triwiki-wrongness/wrongness-ledger.js +9 -2
- package/dist/core/version-manager.js +51 -1
- package/dist/core/version.js +1 -1
- package/dist/core/work-order-ledger.js +40 -1
- package/dist/core/zellij/zellij-fake-adapter.js +3 -1
- package/dist/core/zellij/zellij-launcher.js +49 -10
- package/dist/core/zellij/zellij-layout-builder.js +14 -5
- package/dist/core/zellij/zellij-official-subagent-activity.js +477 -0
- package/dist/core/zellij/zellij-official-subagent-telemetry.js +264 -0
- package/dist/core/zellij/zellij-pane-proof.js +9 -1
- package/dist/core/zellij/zellij-slot-pane-renderer.js +17 -5
- package/dist/core/zellij/zellij-slot-telemetry.js +15 -3
- package/dist/core/zellij/zellij-ui-mode.js +1 -1
- package/dist/core/zellij/zellij-update.js +14 -1
- package/dist/core/zellij/zellij-viewport-binder.js +3 -0
- package/dist/scripts/agent-role-config-repair-check.js +14 -16
- package/dist/scripts/architecture-guard-check.js +8 -1
- package/dist/scripts/canonical-test-runner.js +7 -1
- package/dist/scripts/check-route-modularity.js +0 -1
- package/dist/scripts/check-ts-contracts.js +1 -1
- package/dist/scripts/codex-control-all-pipelines-check.js +7 -3
- package/dist/scripts/codex-control-tool-output-continuity-audit-check.js +27 -0
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +11 -1
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +9 -2
- package/dist/scripts/codex-lb-gpt56-fast-profile-check.js +13 -2
- package/dist/scripts/codex-native-agent-role-content-check.js +27 -7
- package/dist/scripts/codex-native-repair-transaction-check.js +3 -1
- package/dist/scripts/codex-sdk-all-pipelines-check.js +7 -4
- package/dist/scripts/codex-sdk-backend-router-check.js +2 -0
- package/dist/scripts/codex-sdk-research-pipeline-check.js +30 -8
- package/dist/scripts/db-route-materialization-check.js +33 -0
- package/dist/scripts/docs-truthfulness-check.js +3 -1
- package/dist/scripts/doctor-codex-startup-repair-check.js +12 -15
- package/dist/scripts/doctor-fix-production-blackbox.js +12 -2
- package/dist/scripts/doctor-startup-config-repair-blackbox.js +8 -2
- package/dist/scripts/doctor-startup-config-repair-check.js +12 -2
- package/dist/scripts/install-update-preserves-config-check.js +6 -1
- package/dist/scripts/lib/codex-sdk-gate-lib.js +4 -0
- package/dist/scripts/mad-sks-app-ui-no-mutation-check.js +0 -1
- package/dist/scripts/managed-role-manifest-parity-check.js +5 -4
- package/dist/scripts/naruto-codex-e2e-check.js +14 -7
- package/dist/scripts/naruto-shadow-clone-swarm-check.js +4 -201
- package/dist/scripts/npm-publish-performance-check.js +20 -12
- package/dist/scripts/official-subagent-workflow-check.js +145 -0
- package/dist/scripts/package-published-contract-check.js +6 -29
- package/dist/scripts/packlist-performance-check.js +18 -21
- package/dist/scripts/parallel-verification-engine-check.js +2 -2
- package/dist/scripts/prepublish-release-check-or-fast.js +23 -86
- package/dist/scripts/python-codex-sdk-all-pipelines-check.js +8 -0
- package/dist/scripts/release-affected-selector-check.js +74 -1
- package/dist/scripts/release-check-stamp.js +153 -248
- package/dist/scripts/release-dag-full-coverage-check.js +7 -15
- package/dist/scripts/release-dynamic-presets-check.js +2 -1
- package/dist/scripts/release-gate-dag-runner-check.js +0 -1
- package/dist/scripts/release-gate-dag-runner.js +12 -1
- package/dist/scripts/release-gate-existence-audit.js +1 -2
- package/dist/scripts/release-parallel-full-coverage-check.js +12 -6
- package/dist/scripts/release-parallel-speed-budget-check.js +18 -2
- package/dist/scripts/release-real-check.js +26 -4
- package/dist/scripts/release-registry-check.js +61 -16
- package/dist/scripts/research-blueprint-densifier-check.js +2 -2
- package/dist/scripts/research-real-cycle-no-legacy-final-md-check.js +11 -7
- package/dist/scripts/sizecheck.js +2 -2
- package/dist/scripts/sks-3-1-4-directive-check-lib.js +8 -2
- package/dist/scripts/sks-3-1-5-directive-check-lib.js +3 -2
- package/dist/scripts/sks-3-1-6-directive-check-lib.js +5 -3
- package/dist/scripts/sks-menubar-install-check.js +14 -1
- package/dist/scripts/super-search-provider-interface-check.js +31 -18
- package/dist/scripts/trust-fixture-check.js +32 -10
- package/dist/scripts/wrongness-fixture-check.js +1 -1
- package/dist/scripts/zellij-layout-valid-check.js +5 -5
- package/dist/scripts/zellij-spawn-on-demand-layout-check.js +3 -3
- package/docs/demo.tape +1 -1
- package/infra-harness-gates.json +1486 -0
- package/package.json +15 -10
- package/release-gates.v2.json +4060 -0
- package/runtime-required-scripts.json +9 -0
- package/dist/commands/db.js +0 -6
- package/dist/core/commands/db-command.js +0 -146
- package/dist/core/research/prompt.js +0 -15
- package/dist/scripts/codex-0139-feature-probes-check.js +0 -30
- package/dist/scripts/codex-0139-marketplace-source-check.js +0 -13
- package/dist/scripts/codex-control-tool-call-sequence-repair-check.js +0 -14
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { nowIso, readJson } from '../fsx.js';
|
|
3
|
+
import { runCodexTask } from '../codex-control/codex-task-runner.js';
|
|
4
|
+
import { THINKING_SUBAGENT_MODEL, SUBAGENT_EFFORT } from '../subagents/model-policy.js';
|
|
5
|
+
export async function runResearchFalsification(input) {
|
|
6
|
+
const result = await runCodexTask({
|
|
7
|
+
route: '$Research',
|
|
8
|
+
tier: 'orchestrator',
|
|
9
|
+
missionId: String(input.plan?.mission_id || 'research-falsification'),
|
|
10
|
+
workItemId: 'research_falsification',
|
|
11
|
+
cwd: input.root,
|
|
12
|
+
prompt: buildResearchFalsificationPrompt(input),
|
|
13
|
+
inputFiles: [path.join(input.dir, 'claim-evidence-matrix.json'), path.join(input.dir, 'source-ledger.json')],
|
|
14
|
+
outputSchema: researchFalsificationOutputSchema,
|
|
15
|
+
outputSchemaId: 'sks.falsification-ledger.v1',
|
|
16
|
+
sandboxPolicy: 'read-only',
|
|
17
|
+
requestedScopeContract: {
|
|
18
|
+
id: 'research-falsification',
|
|
19
|
+
route: '$Research',
|
|
20
|
+
read_only: true,
|
|
21
|
+
allowed_paths: [`.sneakoscope/missions/${input.plan?.mission_id || ''}/`],
|
|
22
|
+
write_paths: [],
|
|
23
|
+
allowed_write_prefixes: [`.sneakoscope/missions/${input.plan?.mission_id || ''}/`],
|
|
24
|
+
source_mutation_allowed: false
|
|
25
|
+
},
|
|
26
|
+
backendPreference: input.backendPreference || ['codex-sdk', 'python-codex-sdk'],
|
|
27
|
+
allowLocalLlm: false,
|
|
28
|
+
localLlmPolicy: { mode: 'disabled', requiresGptFinal: true },
|
|
29
|
+
mutationLedgerRoot: path.join(input.dir, 'research', 'falsification-codex-control'),
|
|
30
|
+
reliabilityPolicy: {
|
|
31
|
+
timeoutClass: 'standard',
|
|
32
|
+
idleTimeoutMs: input.timeoutMs,
|
|
33
|
+
hardTimeoutMs: input.timeoutMs,
|
|
34
|
+
...(input.deadlineMs === undefined ? {} : { deadlineEpochMs: input.deadlineMs })
|
|
35
|
+
},
|
|
36
|
+
model: THINKING_SUBAGENT_MODEL,
|
|
37
|
+
reasoningEffort: SUBAGENT_EFFORT,
|
|
38
|
+
modelReasoningEffort: SUBAGENT_EFFORT,
|
|
39
|
+
serviceTier: 'fast'
|
|
40
|
+
});
|
|
41
|
+
const worker = await readJson(result.workerResultPath, null);
|
|
42
|
+
const normalized = normalizeResearchFalsification(worker, input.claimMatrix, input.sourceLedger);
|
|
43
|
+
const blockers = unique([
|
|
44
|
+
...(Array.isArray(result.blockers) ? result.blockers.map(String) : []),
|
|
45
|
+
...normalized.blockers
|
|
46
|
+
]);
|
|
47
|
+
return {
|
|
48
|
+
...normalized,
|
|
49
|
+
blockers,
|
|
50
|
+
worker_result_path: typeof result.workerResultPath === 'string' ? result.workerResultPath : null
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export function normalizeResearchFalsification(value, claimMatrix, sourceLedger) {
|
|
54
|
+
const knownClaimIds = new Set((Array.isArray(claimMatrix?.claims) ? claimMatrix.claims : []).map((claim) => String(claim?.id || '')).filter(Boolean));
|
|
55
|
+
const knownSourceIds = new Set([
|
|
56
|
+
...(Array.isArray(sourceLedger?.sources) ? sourceLedger.sources : []),
|
|
57
|
+
...(Array.isArray(sourceLedger?.counterevidence_sources) ? sourceLedger.counterevidence_sources : [])
|
|
58
|
+
].map((source) => String(source?.id || '')).filter(Boolean));
|
|
59
|
+
const blockers = normalizeStrings(value?.blockers);
|
|
60
|
+
const cases = (Array.isArray(value?.cases) ? value.cases : []).map((row, index) => {
|
|
61
|
+
const id = String(row?.id || `falsification-${index + 1}`).trim();
|
|
62
|
+
const targetClaim = String(row?.target_claim || row?.claim_id || '').trim();
|
|
63
|
+
const sourceIds = normalizeStrings(row?.source_ids).filter((sourceId) => knownSourceIds.has(sourceId));
|
|
64
|
+
const result = ['survives', 'weakened', 'refuted', 'inconclusive'].includes(row?.result) ? row.result : 'inconclusive';
|
|
65
|
+
if (!knownClaimIds.has(targetClaim))
|
|
66
|
+
blockers.push(`falsification_target_claim_unknown:${id}:${targetClaim || 'missing'}`);
|
|
67
|
+
for (const sourceId of normalizeStrings(row?.source_ids)) {
|
|
68
|
+
if (!knownSourceIds.has(sourceId))
|
|
69
|
+
blockers.push(`falsification_source_unknown:${id}:${sourceId}`);
|
|
70
|
+
}
|
|
71
|
+
if (!String(row?.attack || '').trim())
|
|
72
|
+
blockers.push(`falsification_attack_missing:${id}`);
|
|
73
|
+
if (!sourceIds.length)
|
|
74
|
+
blockers.push(`falsification_source_missing:${id}`);
|
|
75
|
+
if (!String(row?.next_decisive_test || '').trim())
|
|
76
|
+
blockers.push(`falsification_next_test_missing:${id}`);
|
|
77
|
+
return {
|
|
78
|
+
id,
|
|
79
|
+
target_claim: targetClaim,
|
|
80
|
+
attack: String(row?.attack || '').trim(),
|
|
81
|
+
source_ids: sourceIds,
|
|
82
|
+
result,
|
|
83
|
+
reasoning: String(row?.reasoning || '').trim(),
|
|
84
|
+
limitations: normalizeStrings(row?.limitations),
|
|
85
|
+
next_decisive_test: String(row?.next_decisive_test || '').trim()
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
const unresolvedFailures = cases
|
|
89
|
+
.filter((row) => row.result !== 'survives')
|
|
90
|
+
.map((row) => `${row.target_claim}:${row.result}`);
|
|
91
|
+
if (cases.length < 4)
|
|
92
|
+
blockers.push('falsification_cases_below_contract');
|
|
93
|
+
if (new Set(cases.map((row) => row.target_claim)).size < Math.min(4, knownClaimIds.size))
|
|
94
|
+
blockers.push('falsification_claim_coverage_below_contract');
|
|
95
|
+
if (unresolvedFailures.length)
|
|
96
|
+
blockers.push(...unresolvedFailures.map((row) => `falsification_unresolved:${row}`));
|
|
97
|
+
return {
|
|
98
|
+
schema_version: 1,
|
|
99
|
+
schema: 'sks.falsification-ledger.v1',
|
|
100
|
+
created_at: String(value?.created_at || nowIso()),
|
|
101
|
+
execution_class: 'real',
|
|
102
|
+
cases,
|
|
103
|
+
unresolved_failures: unresolvedFailures,
|
|
104
|
+
next_decisive_tests: unique(cases.map((row) => row.next_decisive_test).filter(Boolean)),
|
|
105
|
+
blockers: unique(blockers)
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function buildResearchFalsificationPrompt(input) {
|
|
109
|
+
return [
|
|
110
|
+
'Attempt to falsify the key claims in this Research mission before manuscript synthesis.',
|
|
111
|
+
'This is a judgment-heavy task: use GPT-5.6 Sol with max reasoning.',
|
|
112
|
+
'Return exactly one JSON object matching sks.falsification-ledger.v1.',
|
|
113
|
+
'Do not mark a claim as surviving by default. Compare the written claim with actual source notes/content and counterevidence.',
|
|
114
|
+
'Use only known claim IDs and source IDs. A generic attack with no source-linked reasoning is invalid.',
|
|
115
|
+
'Allowed result values are survives, weakened, refuted, and inconclusive.',
|
|
116
|
+
'If evidence is missing, use inconclusive and identify the decisive next test.',
|
|
117
|
+
`Mission: ${input.plan?.mission_id || 'unknown'}`,
|
|
118
|
+
`Question: ${input.plan?.prompt || ''}`,
|
|
119
|
+
'',
|
|
120
|
+
'Claim matrix and evidence:',
|
|
121
|
+
JSON.stringify({
|
|
122
|
+
claims: input.claimMatrix?.claims || [],
|
|
123
|
+
sources: [
|
|
124
|
+
...(Array.isArray(input.sourceLedger?.sources) ? input.sourceLedger.sources : []),
|
|
125
|
+
...(Array.isArray(input.sourceLedger?.counterevidence_sources) ? input.sourceLedger.counterevidence_sources : [])
|
|
126
|
+
].map((source) => ({
|
|
127
|
+
id: source.id,
|
|
128
|
+
layer: source.layer,
|
|
129
|
+
title: source.title,
|
|
130
|
+
locator: source.locator,
|
|
131
|
+
publisher_or_author: source.publisher_or_author,
|
|
132
|
+
credibility: source.credibility,
|
|
133
|
+
stance: source.stance,
|
|
134
|
+
notes: source.notes,
|
|
135
|
+
content_artifact: source.content_artifact || null,
|
|
136
|
+
content_sha256: source.content_sha256 || null
|
|
137
|
+
}))
|
|
138
|
+
}, null, 2).slice(0, 30000)
|
|
139
|
+
].join('\n');
|
|
140
|
+
}
|
|
141
|
+
function normalizeStrings(value) {
|
|
142
|
+
return unique((Array.isArray(value) ? value : value == null ? [] : [value]).map((entry) => String(entry || '').trim()).filter(Boolean));
|
|
143
|
+
}
|
|
144
|
+
function unique(values) {
|
|
145
|
+
return [...new Set(values)];
|
|
146
|
+
}
|
|
147
|
+
export const researchFalsificationOutputSchema = {
|
|
148
|
+
type: 'object',
|
|
149
|
+
additionalProperties: false,
|
|
150
|
+
required: ['schema', 'cases', 'unresolved_failures', 'next_decisive_tests', 'blockers'],
|
|
151
|
+
properties: {
|
|
152
|
+
schema: { const: 'sks.falsification-ledger.v1' },
|
|
153
|
+
cases: {
|
|
154
|
+
type: 'array',
|
|
155
|
+
items: {
|
|
156
|
+
type: 'object',
|
|
157
|
+
additionalProperties: false,
|
|
158
|
+
required: ['id', 'target_claim', 'attack', 'source_ids', 'result', 'reasoning', 'limitations', 'next_decisive_test'],
|
|
159
|
+
properties: {
|
|
160
|
+
id: { type: 'string' },
|
|
161
|
+
target_claim: { type: 'string' },
|
|
162
|
+
attack: { type: 'string' },
|
|
163
|
+
source_ids: { type: 'array', items: { type: 'string' } },
|
|
164
|
+
result: { enum: ['survives', 'weakened', 'refuted', 'inconclusive'] },
|
|
165
|
+
reasoning: { type: 'string' },
|
|
166
|
+
limitations: { type: 'array', items: { type: 'string' } },
|
|
167
|
+
next_decisive_test: { type: 'string' }
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
unresolved_failures: { type: 'array', items: { type: 'string' } },
|
|
172
|
+
next_decisive_tests: { type: 'array', items: { type: 'string' } },
|
|
173
|
+
blockers: { type: 'array', items: { type: 'string' } }
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
//# sourceMappingURL=research-falsification-runner.js.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { nowIso, readJson, readText, writeJsonAtomic } from '../fsx.js';
|
|
3
|
-
import { runCodexTask } from '../codex-control/codex-task-runner.js';
|
|
4
3
|
import { analyzeResearchReportQuality } from './research-report-quality.js';
|
|
5
4
|
import { validateClaimEvidenceMatrix } from './claim-evidence-matrix.js';
|
|
6
5
|
import { validateImplementationBlueprint } from './implementation-blueprint.js';
|
|
7
6
|
import { validateExperimentPlan } from './experiment-plan.js';
|
|
8
7
|
import { validateReplicationPack } from './replication-pack.js';
|
|
9
8
|
import { validateFalsificationCoverage } from './falsification.js';
|
|
9
|
+
import { RESEARCH_ADVERSARIAL_REVIEW_ARTIFACT, RESEARCH_CONVERGENCE_GATE_ARTIFACT } from './research-adversarial-review.js';
|
|
10
10
|
export const RESEARCH_FINAL_REVIEW_ARTIFACT = 'research-final-review.json';
|
|
11
11
|
export const RESEARCH_STATIC_FINAL_REVIEW_ARTIFACT = 'research-final-review.static.json';
|
|
12
12
|
export const RESEARCH_CODEX_FINAL_REVIEW_ARTIFACT = 'research-final-review.codex.json';
|
|
@@ -80,69 +80,54 @@ export async function runResearchCodexFinalReviewer(input) {
|
|
|
80
80
|
await writeJsonAtomic(path.join(input.dir, RESEARCH_CODEX_FINAL_REVIEW_ARTIFACT), skipped);
|
|
81
81
|
return skipped;
|
|
82
82
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
allowed_paths: [`.sneakoscope/missions/${input.plan?.mission_id || ''}/`],
|
|
118
|
-
write_paths: [],
|
|
119
|
-
allowed_write_prefixes: [`.sneakoscope/missions/${input.plan?.mission_id || ''}/`],
|
|
120
|
-
source_mutation_allowed: false
|
|
121
|
-
},
|
|
122
|
-
backendPreference: input.backendPreference || ['codex-sdk', 'python-codex-sdk'],
|
|
123
|
-
localLlmPolicy: { mode: 'disabled', requiresGptFinal: true },
|
|
124
|
-
allowLocalLlm: false,
|
|
125
|
-
mutationLedgerRoot: path.join(input.dir, 'research', 'final-review-codex-control'),
|
|
126
|
-
reliabilityPolicy: {
|
|
127
|
-
timeoutClass: 'standard',
|
|
128
|
-
idleTimeoutMs: input.timeoutMs || 120000
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
const worker = await readJson(result.workerResultPath, null);
|
|
132
|
-
const review = normalizeCodexReview(worker, result);
|
|
83
|
+
const convergence = await readJson(path.join(input.dir, RESEARCH_CONVERGENCE_GATE_ARTIFACT), null);
|
|
84
|
+
const ledger = await readJson(path.join(input.dir, RESEARCH_ADVERSARIAL_REVIEW_ARTIFACT), null);
|
|
85
|
+
const finalCycle = Array.isArray(ledger?.review_cycles) ? ledger.review_cycles.at(-1) : null;
|
|
86
|
+
const reviewers = Array.isArray(finalCycle?.reviewers) ? finalCycle.reviewers : [];
|
|
87
|
+
const objections = reviewers.flatMap((reviewer) => [
|
|
88
|
+
...(Array.isArray(reviewer?.critical_objections) ? reviewer.critical_objections : []),
|
|
89
|
+
...(Array.isArray(reviewer?.major_objections) ? reviewer.major_objections : [])
|
|
90
|
+
]);
|
|
91
|
+
const requiredRevisions = [...new Set([
|
|
92
|
+
...reviewers.flatMap((reviewer) => Array.isArray(reviewer?.required_revisions) ? reviewer.required_revisions : []),
|
|
93
|
+
...objections.map((objection) => objection?.required_revision).filter(Boolean),
|
|
94
|
+
...(Array.isArray(convergence?.blockers) ? convergence.blockers : [])
|
|
95
|
+
].map(String))];
|
|
96
|
+
const approved = convergence?.passed === true;
|
|
97
|
+
const review = {
|
|
98
|
+
schema: 'sks.research-codex-final-review.v1',
|
|
99
|
+
reviewed_at: nowIso(),
|
|
100
|
+
verdict: approved ? 'approve' : 'revise',
|
|
101
|
+
unsupported_claim_ids: [...new Set(objections.flatMap((objection) => Array.isArray(objection?.claim_ids) ? objection.claim_ids.map(String) : []))],
|
|
102
|
+
missing_evidence: objections.filter((objection) => !Array.isArray(objection?.source_ids) || objection.source_ids.length === 0).map((objection) => String(objection?.id || 'unknown')),
|
|
103
|
+
blueprint_findings: approved ? ['official subagent reviewers accepted the evidence-bound implementation handoff'] : [],
|
|
104
|
+
falsification_findings: reviewers.map((reviewer) => String(reviewer?.strongest_challenge || '')).filter(Boolean),
|
|
105
|
+
template_like_prose: objections.some((objection) => /template|boilerplate|repet/i.test(String(objection?.reason || ''))),
|
|
106
|
+
source_density_ok: approved,
|
|
107
|
+
implementation_concreteness_ok: input.staticReview?.checks?.implementation_blueprint?.ok === true,
|
|
108
|
+
evidence_bound_synthesis_ok: approved,
|
|
109
|
+
required_revisions: requiredRevisions,
|
|
110
|
+
confidence: approved ? 'high' : reviewers.length ? 'medium' : 'low',
|
|
111
|
+
official_subagent_review: true,
|
|
112
|
+
reviewer_count: reviewers.length,
|
|
113
|
+
review_cycles: Number(convergence?.review_cycles || 0),
|
|
114
|
+
unresolved_critical_objections: Number(convergence?.unresolved_critical_objections || 0),
|
|
115
|
+
...(input.mock === true ? { mock: true } : {})
|
|
116
|
+
};
|
|
133
117
|
await writeJsonAtomic(path.join(input.dir, RESEARCH_CODEX_FINAL_REVIEW_ARTIFACT), review);
|
|
134
118
|
return review;
|
|
135
119
|
}
|
|
136
120
|
export async function runResearchFinalReviewer(dir, input = {}) {
|
|
137
121
|
const staticReview = await runResearchStaticFinalReview(dir, input);
|
|
138
122
|
const existingCodex = await readJson(path.join(dir, RESEARCH_CODEX_FINAL_REVIEW_ARTIFACT), null);
|
|
139
|
-
const codexReview = existingCodex ||
|
|
123
|
+
const codexReview = existingCodex || await runResearchCodexFinalReviewer({
|
|
140
124
|
root: input.root || process.cwd(),
|
|
141
125
|
dir,
|
|
142
126
|
plan: input.plan || await readJson(path.join(dir, 'research-plan.json'), null),
|
|
143
127
|
staticReview,
|
|
144
|
-
mock: true
|
|
145
|
-
})
|
|
128
|
+
mock: input.mock === true
|
|
129
|
+
});
|
|
130
|
+
const adversarialGate = await readJson(path.join(dir, RESEARCH_CONVERGENCE_GATE_ARTIFACT), null);
|
|
146
131
|
const codexApproved = codexReview?.verdict === 'approve';
|
|
147
132
|
const codexRequired = input.codexRequired !== false;
|
|
148
133
|
const blockers = [
|
|
@@ -153,86 +138,20 @@ export async function runResearchFinalReviewer(dir, input = {}) {
|
|
|
153
138
|
...(codexReview && codexReview.source_density_ok === false ? ['research_codex_source_density_not_ok'] : []),
|
|
154
139
|
...(codexReview && codexReview.implementation_concreteness_ok === false ? ['research_codex_implementation_concreteness_not_ok'] : []),
|
|
155
140
|
...(codexReview && codexReview.evidence_bound_synthesis_ok === false ? ['research_codex_evidence_bound_synthesis_not_ok'] : []),
|
|
156
|
-
...(Array.isArray(codexReview?.required_revisions) ? codexReview.required_revisions.map((revision) => `codex_revision:${revision}`) : [])
|
|
141
|
+
...(Array.isArray(codexReview?.required_revisions) ? codexReview.required_revisions.map((revision) => `codex_revision:${revision}`) : []),
|
|
142
|
+
...(adversarialGate?.passed === true ? [] : ['research_adversarial_convergence_not_passed'])
|
|
157
143
|
];
|
|
158
144
|
const review = {
|
|
159
145
|
schema: 'sks.research-final-reviewer.v2',
|
|
160
146
|
reviewed_at: nowIso(),
|
|
161
|
-
approved: staticReview?.approved === true && (!codexRequired || codexApproved) && blockers.length === 0,
|
|
147
|
+
approved: staticReview?.approved === true && adversarialGate?.passed === true && (!codexRequired || codexApproved) && blockers.length === 0,
|
|
162
148
|
blockers: [...new Set(blockers)],
|
|
163
149
|
static_review: staticReview,
|
|
164
150
|
codex_review: codexReview,
|
|
165
|
-
|
|
151
|
+
adversarial_convergence: adversarialGate,
|
|
152
|
+
reviewer: 'research_final_reviewer_static_plus_official_subagents'
|
|
166
153
|
};
|
|
167
154
|
await writeJsonAtomic(path.join(dir, RESEARCH_FINAL_REVIEW_ARTIFACT), review);
|
|
168
155
|
return review;
|
|
169
156
|
}
|
|
170
|
-
function buildResearchFinalReviewPrompt(plan, staticReview) {
|
|
171
|
-
return [
|
|
172
|
-
'You are the Codex/GPT final reviewer for an SKS Research package.',
|
|
173
|
-
`Mission: ${plan?.mission_id || 'unknown'}`,
|
|
174
|
-
`Prompt: ${plan?.prompt || ''}`,
|
|
175
|
-
'',
|
|
176
|
-
'Review the mission artifacts read-only. Reject if claims lack evidence, blueprint steps are template-like, falsification is missing, or the package is only a short summary.',
|
|
177
|
-
'Reject repeated paragraphs, template-like prose, unsupported synthesis, source IDs that do not exist in source-ledger, and implementation blueprints that lack concrete files/tests.',
|
|
178
|
-
'Set template_like_prose=true for repeated or boilerplate reports. Set source_density_ok=false for sparse source ids. Set implementation_concreteness_ok=false for weak file/test/rollback plans. Set evidence_bound_synthesis_ok=false when recommendations are not tied to evidence.',
|
|
179
|
-
'Return only JSON matching sks.research-codex-final-review.v1 with verdict approve, revise, or reject.',
|
|
180
|
-
'',
|
|
181
|
-
`Static review summary:\n${JSON.stringify(staticReview, null, 2).slice(0, 12000)}`
|
|
182
|
-
].join('\n');
|
|
183
|
-
}
|
|
184
|
-
function normalizeCodexReview(worker, result) {
|
|
185
|
-
if (!result?.ok) {
|
|
186
|
-
return {
|
|
187
|
-
schema: 'sks.research-codex-final-review.v1',
|
|
188
|
-
reviewed_at: nowIso(),
|
|
189
|
-
verdict: 'revise',
|
|
190
|
-
unsupported_claim_ids: [],
|
|
191
|
-
missing_evidence: [],
|
|
192
|
-
blueprint_findings: [],
|
|
193
|
-
falsification_findings: [],
|
|
194
|
-
template_like_prose: false,
|
|
195
|
-
source_density_ok: false,
|
|
196
|
-
implementation_concreteness_ok: false,
|
|
197
|
-
evidence_bound_synthesis_ok: false,
|
|
198
|
-
required_revisions: Array.isArray(result?.blockers) ? result.blockers : ['codex_final_reviewer_unavailable'],
|
|
199
|
-
confidence: 'low',
|
|
200
|
-
worker_result_path: result?.workerResultPath || null
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
return {
|
|
204
|
-
schema: 'sks.research-codex-final-review.v1',
|
|
205
|
-
reviewed_at: nowIso(),
|
|
206
|
-
verdict: ['approve', 'revise', 'reject'].includes(worker?.verdict) ? worker.verdict : 'revise',
|
|
207
|
-
unsupported_claim_ids: Array.isArray(worker?.unsupported_claim_ids) ? worker.unsupported_claim_ids.map(String) : [],
|
|
208
|
-
missing_evidence: Array.isArray(worker?.missing_evidence) ? worker.missing_evidence.map(String) : [],
|
|
209
|
-
blueprint_findings: Array.isArray(worker?.blueprint_findings) ? worker.blueprint_findings.map(String) : [],
|
|
210
|
-
falsification_findings: Array.isArray(worker?.falsification_findings) ? worker.falsification_findings.map(String) : [],
|
|
211
|
-
template_like_prose: worker?.template_like_prose === true,
|
|
212
|
-
source_density_ok: worker?.source_density_ok === true,
|
|
213
|
-
implementation_concreteness_ok: worker?.implementation_concreteness_ok === true,
|
|
214
|
-
evidence_bound_synthesis_ok: worker?.evidence_bound_synthesis_ok === true,
|
|
215
|
-
required_revisions: Array.isArray(worker?.required_revisions) ? worker.required_revisions.map(String) : [],
|
|
216
|
-
confidence: ['low', 'medium', 'high'].includes(worker?.confidence) ? worker.confidence : 'medium',
|
|
217
|
-
worker_result_path: result.workerResultPath
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
export const researchCodexFinalReviewSchema = {
|
|
221
|
-
type: 'object',
|
|
222
|
-
required: ['schema', 'verdict', 'unsupported_claim_ids', 'missing_evidence', 'blueprint_findings', 'falsification_findings', 'template_like_prose', 'source_density_ok', 'implementation_concreteness_ok', 'evidence_bound_synthesis_ok', 'required_revisions', 'confidence'],
|
|
223
|
-
properties: {
|
|
224
|
-
schema: { const: 'sks.research-codex-final-review.v1' },
|
|
225
|
-
verdict: { enum: ['approve', 'revise', 'reject'] },
|
|
226
|
-
unsupported_claim_ids: { type: 'array' },
|
|
227
|
-
missing_evidence: { type: 'array' },
|
|
228
|
-
blueprint_findings: { type: 'array' },
|
|
229
|
-
falsification_findings: { type: 'array' },
|
|
230
|
-
template_like_prose: { type: 'boolean' },
|
|
231
|
-
source_density_ok: { type: 'boolean' },
|
|
232
|
-
implementation_concreteness_ok: { type: 'boolean' },
|
|
233
|
-
evidence_bound_synthesis_ok: { type: 'boolean' },
|
|
234
|
-
required_revisions: { type: 'array' },
|
|
235
|
-
confidence: { enum: ['low', 'medium', 'high'] }
|
|
236
|
-
}
|
|
237
|
-
};
|
|
238
157
|
//# sourceMappingURL=research-final-reviewer.js.map
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
export function renderResearchPlanMarkdown(plan, helpers) {
|
|
2
|
+
const lines = [];
|
|
3
|
+
lines.push('# SKS Research Plan');
|
|
4
|
+
lines.push('');
|
|
5
|
+
lines.push(`Prompt: ${plan.prompt}`);
|
|
6
|
+
lines.push(`Depth: ${plan.depth}`);
|
|
7
|
+
lines.push(`Methodology: ${plan.methodology}`);
|
|
8
|
+
lines.push(`Research paper: ${helpers.researchPaperArtifactForPlan(plan)}`);
|
|
9
|
+
if (plan.codex_app_execution_profile) {
|
|
10
|
+
lines.push(`Execution profile: ${plan.codex_app_execution_profile.mode}; agent role strategy ${plan.codex_app_execution_profile.agent_role_strategy}`);
|
|
11
|
+
}
|
|
12
|
+
if (plan.execution_policy) {
|
|
13
|
+
lines.push(`Execution: ${plan.execution_policy.normal_run}; default cycle timeout ${plan.execution_policy.default_cycle_timeout_minutes} minutes`);
|
|
14
|
+
if (plan.execution_policy.default_max_cycles)
|
|
15
|
+
lines.push(`Adversarial review loop: run three independent official research_reviewer threads, revise on any objection, then run a fresh three-thread cycle; default safety cap ${plan.execution_policy.default_max_cycles} cycles`);
|
|
16
|
+
lines.push(`Mock policy: ${plan.execution_policy.mock_policy}`);
|
|
17
|
+
}
|
|
18
|
+
if (plan.mutation_policy)
|
|
19
|
+
lines.push(`Mutation policy: ${plan.mutation_policy.rule}`);
|
|
20
|
+
lines.push('');
|
|
21
|
+
if (plan.quality_contract) {
|
|
22
|
+
const contract = plan.quality_contract;
|
|
23
|
+
lines.push('## Quality Contract');
|
|
24
|
+
lines.push(`- minimum sources: ${contract.min_sources_total}`);
|
|
25
|
+
lines.push(`- minimum source layers covered: ${contract.min_source_layers_covered}`);
|
|
26
|
+
lines.push(`- minimum counterevidence sources: ${contract.min_counterevidence_sources}`);
|
|
27
|
+
lines.push(`- minimum key claims: ${contract.min_key_claims}`);
|
|
28
|
+
lines.push(`- minimum triangulated claims: ${contract.min_trianguled_claims}`);
|
|
29
|
+
lines.push(`- minimum blueprint sections: ${contract.min_implementation_blueprint_sections}`);
|
|
30
|
+
lines.push(`- minimum falsification cases: ${contract.min_falsification_cases}`);
|
|
31
|
+
lines.push(`- minimum experiment steps: ${contract.min_experiment_steps}`);
|
|
32
|
+
lines.push(`- minimum report words: ${contract.min_report_words}`);
|
|
33
|
+
lines.push('');
|
|
34
|
+
}
|
|
35
|
+
if (plan.native_agent_plan) {
|
|
36
|
+
lines.push('## Official Subagent Review Plan');
|
|
37
|
+
lines.push(`Backend: ${plan.native_agent_plan.backend}`);
|
|
38
|
+
lines.push(`Sessions: ${plan.native_agent_plan.session_count}`);
|
|
39
|
+
lines.push(`AutoResearch batches: ${plan.native_agent_plan.autoresearch_cycle_policy?.uses_agent_batches ? 'enabled' : 'disabled'}`);
|
|
40
|
+
for (const persona of plan.native_agent_plan.personas || []) {
|
|
41
|
+
lines.push(`- ${persona.id}: ${persona.role}; outputs ${(persona.outputs || []).join(', ')}`);
|
|
42
|
+
}
|
|
43
|
+
for (const batch of plan.native_agent_plan.batches || []) {
|
|
44
|
+
lines.push(`- batch ${batch.id}: ${(batch.agents || []).join(', ')} -> ${(batch.outputs || []).join(', ')}`);
|
|
45
|
+
}
|
|
46
|
+
lines.push('');
|
|
47
|
+
}
|
|
48
|
+
lines.push('## Rules');
|
|
49
|
+
for (const rule of plan.rules)
|
|
50
|
+
lines.push(`- ${rule}`);
|
|
51
|
+
lines.push('');
|
|
52
|
+
if (plan.research_council?.agents?.length) {
|
|
53
|
+
lines.push('## Genius Agent Council');
|
|
54
|
+
lines.push(`Policy: ${plan.research_council.policy}`);
|
|
55
|
+
for (const agent of plan.research_council.agents)
|
|
56
|
+
lines.push(`- ${helpers.researchAgentAgentName(agent)}: ${agent.persona || agent.role} - ${agent.mandate} (${agent.persona_boundary || 'persona-inspired lens only'})`);
|
|
57
|
+
lines.push('');
|
|
58
|
+
}
|
|
59
|
+
if (plan.web_research_policy) {
|
|
60
|
+
lines.push('## Web Research Policy');
|
|
61
|
+
lines.push(`Mode: ${plan.web_research_policy.mode}`);
|
|
62
|
+
lines.push(`Requirement: ${plan.web_research_policy.requirement}`);
|
|
63
|
+
if (plan.web_research_policy.source_tool_routing)
|
|
64
|
+
lines.push(`Source tool routing: ${plan.web_research_policy.source_tool_routing.mode}`);
|
|
65
|
+
for (const querySet of plan.web_research_policy.query_sets || [])
|
|
66
|
+
lines.push(`- query set: ${querySet}`);
|
|
67
|
+
if (plan.web_research_policy.skill_creator?.artifact)
|
|
68
|
+
lines.push(`- source skill artifact: ${plan.web_research_policy.skill_creator.artifact}`);
|
|
69
|
+
for (const layer of plan.web_research_policy.source_layers || []) {
|
|
70
|
+
lines.push(`- layer ${layer.id}: ${layer.purpose}`);
|
|
71
|
+
}
|
|
72
|
+
lines.push('');
|
|
73
|
+
}
|
|
74
|
+
lines.push('## Outcome Rubric');
|
|
75
|
+
for (const item of plan.outcome_rubric || [])
|
|
76
|
+
lines.push(`- ${item.id}: ${item.description}`);
|
|
77
|
+
lines.push('');
|
|
78
|
+
lines.push('## Phases');
|
|
79
|
+
for (const phase of plan.phases)
|
|
80
|
+
lines.push(`- ${phase.id}: ${phase.goal}`);
|
|
81
|
+
lines.push('');
|
|
82
|
+
lines.push('## Required Artifacts');
|
|
83
|
+
for (const artifact of plan.required_artifacts)
|
|
84
|
+
lines.push(`- ${artifact}`);
|
|
85
|
+
lines.push('');
|
|
86
|
+
return `${lines.join('\n')}\n`;
|
|
87
|
+
}
|
|
88
|
+
export function renderResearchSourceSkillMarkdown(plan, defaultLayers) {
|
|
89
|
+
const layers = plan?.web_research_policy?.source_layers?.length ? plan.web_research_policy.source_layers : defaultLayers;
|
|
90
|
+
const lines = [];
|
|
91
|
+
lines.push('# Research Source Layer Skill');
|
|
92
|
+
lines.push('');
|
|
93
|
+
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.');
|
|
94
|
+
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.');
|
|
95
|
+
lines.push('');
|
|
96
|
+
lines.push('## Trigger');
|
|
97
|
+
lines.push('- Any `$Research` run that must collect broad public evidence before synthesis, adversarial review, falsification, or paper writing.');
|
|
98
|
+
lines.push('');
|
|
99
|
+
lines.push('## Source Layers');
|
|
100
|
+
for (const layer of layers) {
|
|
101
|
+
lines.push(`- ${layer.id}: ${layer.purpose}`);
|
|
102
|
+
lines.push(` Examples: ${(layer.examples || []).join(', ')}`);
|
|
103
|
+
lines.push(` Query templates: ${(layer.query_templates || []).join(' | ')}`);
|
|
104
|
+
}
|
|
105
|
+
lines.push('');
|
|
106
|
+
lines.push('## Output Contract');
|
|
107
|
+
lines.push('- Fill source-ledger.json with `source_layers`, `sources[].layer`, `counterevidence_sources[].layer`, `citation_coverage`, `triangulation.cross_layer_checks`, and `blockers`.');
|
|
108
|
+
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.');
|
|
109
|
+
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.');
|
|
110
|
+
lines.push('- If a layer cannot be searched with the available runtime or credentials, record the blocker and keep research-gate.json unpassed.');
|
|
111
|
+
lines.push('- Do not modify repository source code or generated harness files during Research; write only route-local mission artifacts.');
|
|
112
|
+
lines.push('');
|
|
113
|
+
lines.push('## Official Reviewer Use');
|
|
114
|
+
lines.push('- Only source-ledger ids with correlated verified-content Super Search proof may support a real-run reviewer finding or Eureka idea.');
|
|
115
|
+
lines.push('- Run exactly three independent official `research_reviewer` threads on GPT-5.6 Sol Max: Einstein, von Neumann, and Skeptic composite lenses.');
|
|
116
|
+
lines.push('- The skeptic lens must challenge the strongest claim using counterevidence or source-quality downgrades.');
|
|
117
|
+
lines.push('- Any objection triggers a mission-local `research_synthesizer` revision followed by a fresh three-thread review cycle; do not launch a custom scheduler or debate pool.');
|
|
118
|
+
lines.push('- `agent-ledger.json` and `debate-ledger.json` are compatibility projections from official reviewer outcomes. Canonical convergence requires three trustworthy parent outcomes and zero unresolved objections.');
|
|
119
|
+
lines.push('- Synthesis keeps only claims that survive cross-layer triangulation and falsification.');
|
|
120
|
+
lines.push('');
|
|
121
|
+
return `${lines.join('\n')}\n`;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=research-plan-markdown.js.map
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { REQUIRED_RESEARCH_REPORT_HEADINGS } from './research-report-quality.js';
|
|
2
2
|
export function buildRealisticResearchReport(input) {
|
|
3
3
|
const plan = input.plan || {};
|
|
4
|
-
const claims = normalizeClaims(input.claims);
|
|
4
|
+
const claims = normalizeClaims(prioritizeKeyClaims(input.claims, input.keyClaimIds));
|
|
5
5
|
const sourceIds = normalizeIds(input.sourceIds).length ? normalizeIds(input.sourceIds) : fallbackIds('source', 14);
|
|
6
6
|
const counterIds = normalizeIds(input.counterevidenceIds).length ? normalizeIds(input.counterevidenceIds) : fallbackIds('counter', 2);
|
|
7
7
|
const sections = Array.isArray(input.blueprint?.sections) ? input.blueprint.sections : [];
|
|
8
8
|
const experimentSteps = Array.isArray(input.experimentPlan?.steps) ? input.experimentPlan.steps : [];
|
|
9
9
|
const falsificationCases = Array.isArray(input.falsificationLedger?.cases) ? input.falsificationLedger.cases : [];
|
|
10
10
|
const claimBullets = claims.slice(0, 8).map((claim, index) => {
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
|
|
11
|
+
const linkedSources = normalizeIds(claim.source_ids);
|
|
12
|
+
const linkedCounterevidence = normalizeIds(claim.counterevidence_ids);
|
|
13
|
+
const citedSources = (linkedSources.length ? linkedSources : [sourceIds[index % sourceIds.length], sourceIds[(index + 3) % sourceIds.length]]).filter(Boolean).slice(0, 3);
|
|
14
|
+
const citedCounterevidence = (linkedCounterevidence.length ? linkedCounterevidence : [counterIds[index % counterIds.length]]).filter(Boolean).slice(0, 2);
|
|
15
|
+
return `- ${claim.id}: ${claim.claim} Claim-local support: ${citedSources.join(', ')}. Claim-local counterevidence: ${citedCounterevidence.join(', ')}. Falsifiable probe: "${claim.test_or_probe || 'the next listed validation probe'}".`;
|
|
15
16
|
});
|
|
16
17
|
const blueprintTargets = [...new Set(sections.flatMap((section) => Array.isArray(section?.target_paths) ? section.target_paths : []))].slice(0, 12);
|
|
17
18
|
return [
|
|
@@ -95,7 +96,7 @@ export function buildRealisticResearchReport(input) {
|
|
|
95
96
|
].join('\n\n');
|
|
96
97
|
}
|
|
97
98
|
export function buildRealisticResearchPaper(input) {
|
|
98
|
-
const claims = normalizeClaims(input.claims);
|
|
99
|
+
const claims = normalizeClaims(prioritizeKeyClaims(input.claims, input.keyClaimIds));
|
|
99
100
|
const sourceIds = normalizeIds(input.sourceIds).length ? normalizeIds(input.sourceIds) : fallbackIds('source', 14);
|
|
100
101
|
const counterIds = normalizeIds(input.counterevidenceIds).length ? normalizeIds(input.counterevidenceIds) : fallbackIds('counter', 2);
|
|
101
102
|
return [
|
|
@@ -128,6 +129,13 @@ export function buildRealisticResearchPaper(input) {
|
|
|
128
129
|
''
|
|
129
130
|
].join('\n');
|
|
130
131
|
}
|
|
132
|
+
function prioritizeKeyClaims(claims, keyClaimIds) {
|
|
133
|
+
const rows = Array.isArray(claims) ? claims : [];
|
|
134
|
+
const byId = new Map(rows.map((claim) => [String(claim?.id || ''), claim]));
|
|
135
|
+
const prioritized = normalizeIds(keyClaimIds).map((id) => byId.get(id)).filter(Boolean);
|
|
136
|
+
const prioritizedIds = new Set(prioritized.map((claim) => String(claim?.id || '')));
|
|
137
|
+
return [...prioritized, ...rows.filter((claim) => !prioritizedIds.has(String(claim?.id || '')))];
|
|
138
|
+
}
|
|
131
139
|
export function requiredResearchReportHeadings() {
|
|
132
140
|
return [...REQUIRED_RESEARCH_REPORT_HEADINGS];
|
|
133
141
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import fsp from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { nowIso, sha256 } from '../fsx.js';
|
|
4
|
+
export const RESEARCH_REVIEW_DIGEST_SCHEMA = 'sks.research-review-artifact-digest.v1';
|
|
5
|
+
export async function buildResearchReviewArtifactDigest(dir, plan) {
|
|
6
|
+
const artifacts = researchReviewArtifactNames(plan);
|
|
7
|
+
const blockers = [];
|
|
8
|
+
const rows = await Promise.all(artifacts.map(async (artifact) => {
|
|
9
|
+
const file = path.join(dir, artifact);
|
|
10
|
+
const content = await fsp.readFile(file).catch(() => null);
|
|
11
|
+
if (!content) {
|
|
12
|
+
blockers.push(`research_review_artifact_missing:${artifact}`);
|
|
13
|
+
return { artifact, sha256: null, bytes: 0 };
|
|
14
|
+
}
|
|
15
|
+
if (content.length === 0)
|
|
16
|
+
blockers.push(`research_review_artifact_empty:${artifact}`);
|
|
17
|
+
return {
|
|
18
|
+
artifact,
|
|
19
|
+
sha256: sha256(content),
|
|
20
|
+
bytes: content.length
|
|
21
|
+
};
|
|
22
|
+
}));
|
|
23
|
+
return {
|
|
24
|
+
schema: RESEARCH_REVIEW_DIGEST_SCHEMA,
|
|
25
|
+
generated_at: nowIso(),
|
|
26
|
+
artifacts: rows,
|
|
27
|
+
bundle_sha256: sha256(JSON.stringify(rows.map(({ artifact, sha256: digest, bytes }) => ({ artifact, sha256: digest, bytes })))),
|
|
28
|
+
blockers: [...new Set(blockers)]
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function validateResearchReviewArtifactDigest(recorded, current) {
|
|
32
|
+
const blockers = [];
|
|
33
|
+
if (recorded?.schema !== RESEARCH_REVIEW_DIGEST_SCHEMA)
|
|
34
|
+
blockers.push('research_review_artifact_digest_schema_invalid');
|
|
35
|
+
if (!String(recorded?.bundle_sha256 || '').trim())
|
|
36
|
+
blockers.push('research_review_artifact_bundle_sha256_missing');
|
|
37
|
+
if (String(recorded?.bundle_sha256 || '') !== current.bundle_sha256)
|
|
38
|
+
blockers.push('research_review_artifact_bundle_sha256_mismatch');
|
|
39
|
+
const recordedRows = new Map((Array.isArray(recorded?.artifacts) ? recorded.artifacts : [])
|
|
40
|
+
.map((row) => [String(row?.artifact || ''), row]));
|
|
41
|
+
for (const currentRow of current.artifacts) {
|
|
42
|
+
const recordedRow = recordedRows.get(currentRow.artifact);
|
|
43
|
+
if (!recordedRow) {
|
|
44
|
+
blockers.push(`research_review_artifact_digest_entry_missing:${currentRow.artifact}`);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (String(recordedRow?.sha256 || '') !== String(currentRow.sha256 || '')) {
|
|
48
|
+
blockers.push(`research_review_artifact_sha256_mismatch:${currentRow.artifact}`);
|
|
49
|
+
}
|
|
50
|
+
if (Number(recordedRow?.bytes || 0) !== currentRow.bytes) {
|
|
51
|
+
blockers.push(`research_review_artifact_size_mismatch:${currentRow.artifact}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
blockers.push(...current.blockers);
|
|
55
|
+
return [...new Set(blockers)];
|
|
56
|
+
}
|
|
57
|
+
export function researchReviewArtifactNames(plan) {
|
|
58
|
+
const configuredPaper = plan?.artifacts?.research_paper || plan?.paper_artifact || 'research-paper.md';
|
|
59
|
+
return [
|
|
60
|
+
'research-report.md',
|
|
61
|
+
path.basename(String(configuredPaper)),
|
|
62
|
+
'source-ledger.json',
|
|
63
|
+
'claim-evidence-matrix.json'
|
|
64
|
+
];
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=research-review-artifact-digest.js.map
|