sneakoscope 2.0.2 → 2.0.4
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 +1 -1
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/.sks-build-stamp.json +4 -4
- package/dist/bin/sks.js +1 -1
- package/dist/build-manifest.json +21 -8
- package/dist/core/agents/agent-orchestrator.js +70 -4
- package/dist/core/agents/agent-patch-proof.js +5 -0
- package/dist/core/agents/agent-proof-evidence.js +26 -0
- package/dist/core/codex-control/codex-fake-sdk-adapter.js +20 -0
- package/dist/core/codex-control/codex-output-schemas.js +5 -1
- package/dist/core/codex-control/gpt-final-arbiter.js +160 -0
- package/dist/core/codex-control/gpt-final-context-compressor.js +17 -0
- package/dist/core/codex-control/gpt-final-proof-pack.js +120 -0
- package/dist/core/codex-control/gpt-final-review-schema.js +71 -0
- package/dist/core/commands/local-model-command.js +16 -1
- package/dist/core/commands/naruto-command.js +77 -5
- package/dist/core/commands/run-command.js +5 -1
- package/dist/core/doctor/doctor-readiness-matrix.js +15 -0
- package/dist/core/feature-fixtures.js +4 -0
- package/dist/core/fsx.js +1 -1
- package/dist/core/git-simple.js +143 -4
- package/dist/core/local-llm/local-collaboration-policy.js +93 -0
- package/dist/core/local-llm/local-llm-config.js +15 -0
- package/dist/core/pipeline/final-gpt-patch-stage.js +31 -0
- package/dist/core/pipeline/final-gpt-review-stage.js +5 -0
- package/dist/core/safety/mutation-guard.js +2 -0
- package/dist/core/update-check.js +60 -25
- package/dist/core/version.js +1 -1
- package/dist/scripts/codex-sdk-team-naruto-agent-pipeline-check.js +2 -1
- package/dist/scripts/gpt-final-arbiter-check.js +63 -0
- package/dist/scripts/gpt-final-arbiter-performance-check.js +36 -0
- package/dist/scripts/local-collab-gpt-final-availability-check.js +58 -0
- package/dist/scripts/local-collab-no-local-only-final-check.js +27 -0
- package/dist/scripts/local-collab-policy-check.js +17 -0
- package/package.json +8 -3
- package/schemas/local-llm/local-collaboration-policy.schema.json +57 -0
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Set up this agent project with Sneakoscope Codex. Use [[mandarange/Sneakoscope-C
|
|
|
16
16
|
|
|
17
17
|
## Current Release
|
|
18
18
|
|
|
19
|
-
SKS **2.0.
|
|
19
|
+
SKS **2.0.4** is a P0 Codex App Fast UI and MAD Zellij worker-pane closure patch on top of the 2.0 execution layer. `sks --mad` now relies on launch-time Fast/high overrides instead of user-level Codex config rewrites, safe Fast UI repair runs through `sks doctor --fix`, provider badges read env/auth/config.toml consistently, and interactive MAD worker panes attach to the real Zellij session as scheduler slots spawn.
|
|
20
20
|
|
|
21
21
|
What changed:
|
|
22
22
|
|
|
@@ -4,7 +4,7 @@ use std::io::{self, Read, Seek, SeekFrom};
|
|
|
4
4
|
fn main() {
|
|
5
5
|
let mut args = std::env::args().skip(1);
|
|
6
6
|
match args.next().as_deref() {
|
|
7
|
-
Some("--version") => println!("sks-rs 2.0.
|
|
7
|
+
Some("--version") => println!("sks-rs 2.0.4"),
|
|
8
8
|
Some("compact-info") => {
|
|
9
9
|
let mut input = String::new();
|
|
10
10
|
let _ = io::stdin().read_to_string(&mut input);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "sks.dist-build-stamp.v1",
|
|
3
3
|
"package_name": "sneakoscope",
|
|
4
|
-
"package_version": "2.0.
|
|
5
|
-
"source_digest": "
|
|
6
|
-
"source_file_count":
|
|
7
|
-
"built_at_source_time":
|
|
4
|
+
"package_version": "2.0.4",
|
|
5
|
+
"source_digest": "bd67ddf989e2e0b702453d422e2cf991e8ca397d3d4afc14fdfa06b4610452c9",
|
|
6
|
+
"source_file_count": 1879,
|
|
7
|
+
"built_at_source_time": 1780569940553
|
|
8
8
|
}
|
package/dist/bin/sks.js
CHANGED
package/dist/build-manifest.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "sks.dist-build.v2",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"package_version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
|
+
"package_version": "2.0.4",
|
|
5
5
|
"typescript": true,
|
|
6
6
|
"mjs_runtime_files": 0,
|
|
7
|
-
"compiled_file_count":
|
|
8
|
-
"compiled_js_count":
|
|
7
|
+
"compiled_file_count": 949,
|
|
8
|
+
"compiled_js_count": 949,
|
|
9
9
|
"compiled_dts_count": 0,
|
|
10
|
-
"source_digest": "
|
|
11
|
-
"source_file_count":
|
|
12
|
-
"source_files_hash": "
|
|
13
|
-
"source_list_hash": "
|
|
10
|
+
"source_digest": "bd67ddf989e2e0b702453d422e2cf991e8ca397d3d4afc14fdfa06b4610452c9",
|
|
11
|
+
"source_file_count": 1879,
|
|
12
|
+
"source_files_hash": "c43d09b591370ad58937365d6bbfca2be0b60fcf04a43fdbb9a56d9288752814",
|
|
13
|
+
"source_list_hash": "c43d09b591370ad58937365d6bbfca2be0b60fcf04a43fdbb9a56d9288752814",
|
|
14
14
|
"src_mjs_runtime_files": 0,
|
|
15
15
|
"dist_stamp_schema": "sks.dist-build-stamp.v1",
|
|
16
16
|
"files": [
|
|
@@ -212,6 +212,10 @@
|
|
|
212
212
|
"core/codex-control/codex-sdk-sandbox-policy.js",
|
|
213
213
|
"core/codex-control/codex-task-runner.js",
|
|
214
214
|
"core/codex-control/codex-thread-registry.js",
|
|
215
|
+
"core/codex-control/gpt-final-arbiter.js",
|
|
216
|
+
"core/codex-control/gpt-final-context-compressor.js",
|
|
217
|
+
"core/codex-control/gpt-final-proof-pack.js",
|
|
218
|
+
"core/codex-control/gpt-final-review-schema.js",
|
|
215
219
|
"core/codex-control/schemas/agent-worker-result.schema.js",
|
|
216
220
|
"core/codex-exec-output-schema.js",
|
|
217
221
|
"core/codex-hooks/codex-hook-actual-discovery.js",
|
|
@@ -357,6 +361,8 @@
|
|
|
357
361
|
"core/init.js",
|
|
358
362
|
"core/json-schema-validator.js",
|
|
359
363
|
"core/language-preference.js",
|
|
364
|
+
"core/local-llm/local-collaboration-policy.js",
|
|
365
|
+
"core/local-llm/local-llm-config.js",
|
|
360
366
|
"core/loop-blocker.js",
|
|
361
367
|
"core/mad-sks/audit-ledger.js",
|
|
362
368
|
"core/mad-sks/authorization-manifest.js",
|
|
@@ -398,6 +404,8 @@
|
|
|
398
404
|
"core/pipeline.js",
|
|
399
405
|
"core/pipeline/active-context.js",
|
|
400
406
|
"core/pipeline/agent-stage-policy.js",
|
|
407
|
+
"core/pipeline/final-gpt-patch-stage.js",
|
|
408
|
+
"core/pipeline/final-gpt-review-stage.js",
|
|
401
409
|
"core/pipeline/pipeline-plan-writer.js",
|
|
402
410
|
"core/pipeline/plan-schema.js",
|
|
403
411
|
"core/pipeline/prompt-context-answer.js",
|
|
@@ -763,6 +771,8 @@
|
|
|
763
771
|
"scripts/flagship-proof-graph-v4-check.js",
|
|
764
772
|
"scripts/git-precommit-fixture-check.js",
|
|
765
773
|
"scripts/goal-mode-official-default-check.js",
|
|
774
|
+
"scripts/gpt-final-arbiter-check.js",
|
|
775
|
+
"scripts/gpt-final-arbiter-performance-check.js",
|
|
766
776
|
"scripts/gpt-image-2-real-file-smoke.js",
|
|
767
777
|
"scripts/gpt-image-2-request-validator-check.js",
|
|
768
778
|
"scripts/hooks-0.134-context-parity-check.js",
|
|
@@ -792,6 +802,9 @@
|
|
|
792
802
|
"scripts/lib/real-codex-parallel-gate.js",
|
|
793
803
|
"scripts/lib/real-codex-parallel-proof-fixture.js",
|
|
794
804
|
"scripts/lib/valid-png-fixture.js",
|
|
805
|
+
"scripts/local-collab-gpt-final-availability-check.js",
|
|
806
|
+
"scripts/local-collab-no-local-only-final-check.js",
|
|
807
|
+
"scripts/local-collab-policy-check.js",
|
|
795
808
|
"scripts/loop-blocker-check.js",
|
|
796
809
|
"scripts/mad-preflight-blocks-unreadable-config-check.js",
|
|
797
810
|
"scripts/mad-sks-actual-executor-blackbox.js",
|
|
@@ -49,6 +49,9 @@ import { writeNativeCliSessionProof } from './native-cli-session-proof.js';
|
|
|
49
49
|
import { writeNoSubagentScalingPolicy } from './no-subagent-scaling-policy.js';
|
|
50
50
|
import { runCodexTask } from '../codex-control/codex-control-plane.js';
|
|
51
51
|
import { CODEX_AGENT_WORKER_RESULT_SCHEMA_ID, codexAgentWorkerResultSchema } from '../codex-control/schemas/agent-worker-result.schema.js';
|
|
52
|
+
import { resolveLocalCollaborationPolicy, localCollaborationParticipated } from '../local-llm/local-collaboration-policy.js';
|
|
53
|
+
import { runFinalGptReviewStage } from '../pipeline/final-gpt-review-stage.js';
|
|
54
|
+
import { selectFinalGptPatchSource } from '../pipeline/final-gpt-patch-stage.js';
|
|
52
55
|
export async function runNativeAgentOrchestrator(opts = {}) {
|
|
53
56
|
const root = path.resolve(opts.root || process.cwd());
|
|
54
57
|
const prompt = String(opts.prompt || 'Native agent run');
|
|
@@ -369,15 +372,51 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
369
372
|
});
|
|
370
373
|
const noSubagentScalingPolicy = await writeNoSubagentScalingPolicy(ledgerRoot, { nativeProof: nativeCliSessionProof });
|
|
371
374
|
const fastModePropagation = await writeFastModePropagationProof(ledgerRoot, { policy: fastModePolicy, backend, results });
|
|
375
|
+
const localCollaborationPolicy = resolveLocalCollaborationPolicy();
|
|
376
|
+
await writeJsonAtomic(path.join(ledgerRoot, 'local-collaboration-policy.json'), localCollaborationPolicy);
|
|
377
|
+
const localParticipated = localCollaborationParticipated(results);
|
|
378
|
+
const candidatePatchEnvelopes = results.flatMap((result) => Array.isArray(result.patch_envelopes) ? result.patch_envelopes : []);
|
|
379
|
+
const gptFinalArbiter = localParticipated
|
|
380
|
+
? await runFinalGptReviewStage({
|
|
381
|
+
schema: 'sks.gpt-final-arbiter-input.v1',
|
|
382
|
+
route,
|
|
383
|
+
mission_id: missionId,
|
|
384
|
+
local_mode: localCollaborationPolicy.mode,
|
|
385
|
+
local_outputs: results.map((result) => ({
|
|
386
|
+
worker_id: result.agent_id,
|
|
387
|
+
backend: result.backend_router_report?.selected_backend || result.backend || backend,
|
|
388
|
+
status: result.status,
|
|
389
|
+
summary: result.summary,
|
|
390
|
+
patch_envelopes: result.patch_envelopes || [],
|
|
391
|
+
proof: result.verification?.status || '',
|
|
392
|
+
blockers: result.blockers || [],
|
|
393
|
+
changed_files: result.changed_files || []
|
|
394
|
+
})),
|
|
395
|
+
candidate_diff: '',
|
|
396
|
+
candidate_patch_envelopes: candidatePatchEnvelopes,
|
|
397
|
+
verification_results: results.map((result) => result.verification || { status: result.status || 'unknown' }),
|
|
398
|
+
side_effect_report: { schema: 'sks.agent-side-effect-summary.v1', ok: true, route, mutation_owner: 'parent_agent_orchestrator' },
|
|
399
|
+
mutation_ledger: { parallel_write_policy: parallelWritePolicy, result_count: results.length },
|
|
400
|
+
rollback_plan: { verification_rollback_dag: strategyCompiled.verification_rollback_dag || null }
|
|
401
|
+
}, { cwd: root, mutationLedgerRoot: path.join(ledgerRoot, 'gpt-final-arbiter') })
|
|
402
|
+
: null;
|
|
403
|
+
const finalGptPatchStage = localParticipated
|
|
404
|
+
? selectFinalGptPatchSource(gptFinalArbiter, candidatePatchEnvelopes)
|
|
405
|
+
: null;
|
|
406
|
+
const resultsForPatchSwarm = localParticipated && finalGptPatchStage?.ok === true && gptFinalArbiter?.result?.status === 'modified'
|
|
407
|
+
? withFinalGptPatchEnvelopes(results, finalGptPatchStage.patch_envelopes)
|
|
408
|
+
: results;
|
|
372
409
|
const patchSwarm = await runAgentPatchSwarmRuntime(root, ledgerRoot, {
|
|
373
410
|
missionId,
|
|
374
411
|
route,
|
|
375
412
|
routeCommand,
|
|
376
413
|
writeCapable,
|
|
377
|
-
results,
|
|
414
|
+
results: resultsForPatchSwarm,
|
|
378
415
|
parallelWritePolicy,
|
|
379
416
|
verificationRollbackDag: strategyCompiled.verification_rollback_dag,
|
|
380
|
-
dryRun: opts.dryRunPatches === true || opts.applyPatches !== true
|
|
417
|
+
dryRun: opts.dryRunPatches === true || opts.applyPatches !== true || (localParticipated && gptFinalArbiter?.ok !== true),
|
|
418
|
+
gptFinalArbiter,
|
|
419
|
+
finalGptPatchStage
|
|
381
420
|
});
|
|
382
421
|
const stale = await detectStaleAgentSessions(ledgerRoot);
|
|
383
422
|
if (!stale.ok)
|
|
@@ -403,6 +442,8 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
403
442
|
...(nativeCliSessionProof.ok ? [] : nativeCliSessionProof.blockers),
|
|
404
443
|
...(noSubagentScalingPolicy.ok ? [] : noSubagentScalingPolicy.blockers),
|
|
405
444
|
...(fastModePropagation.ok ? [] : fastModePropagation.blockers),
|
|
445
|
+
...(localParticipated && gptFinalArbiter?.ok !== true ? gptFinalArbiter?.blockers || ['gpt_final_arbiter_not_ok'] : []),
|
|
446
|
+
...(localParticipated && finalGptPatchStage?.ok === false ? finalGptPatchStage.blockers || ['final_gpt_patch_stage_not_ok'] : []),
|
|
406
447
|
...(patchSwarm.ok ? [] : patchSwarm.blockers),
|
|
407
448
|
...(janitor.ok ? [] : janitor.blockers)
|
|
408
449
|
];
|
|
@@ -438,7 +479,10 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
438
479
|
fastModePolicy,
|
|
439
480
|
fastModePropagation,
|
|
440
481
|
triwikiContext,
|
|
441
|
-
selectedCoreSkill
|
|
482
|
+
selectedCoreSkill,
|
|
483
|
+
localCollaborationPolicy,
|
|
484
|
+
gptFinalArbiter,
|
|
485
|
+
finalGptPatchStage
|
|
442
486
|
});
|
|
443
487
|
await writeAgentCodexCockpitArtifacts(dir, { missionId, projectHash: namespace.root_hash });
|
|
444
488
|
await setCurrent(root, { mission_id: missionId, mode: 'AGENT', phase: proof.ok ? 'AGENT_NATIVE_KERNEL_DONE' : 'AGENT_NATIVE_KERNEL_BLOCKED', native_agent_backend: backend, updated_at: nowIso() });
|
|
@@ -478,10 +522,30 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
478
522
|
no_subagent_scaling_policy: noSubagentScalingPolicy,
|
|
479
523
|
fast_mode_policy: fastModePolicy,
|
|
480
524
|
fast_mode_propagation: fastModePropagation,
|
|
525
|
+
local_collaboration_policy: localCollaborationPolicy,
|
|
526
|
+
gpt_final_arbiter: gptFinalArbiter,
|
|
527
|
+
final_gpt_patch_stage: finalGptPatchStage,
|
|
481
528
|
patch_swarm: patchSwarm,
|
|
482
529
|
proof
|
|
483
530
|
};
|
|
484
531
|
}
|
|
532
|
+
function withFinalGptPatchEnvelopes(results, patchEnvelopes = []) {
|
|
533
|
+
const byAgent = new Map();
|
|
534
|
+
for (const envelope of patchEnvelopes) {
|
|
535
|
+
const agentId = String(envelope?.agent_id || 'gpt-final-arbiter');
|
|
536
|
+
byAgent.set(agentId, [...(byAgent.get(agentId) || []), envelope]);
|
|
537
|
+
}
|
|
538
|
+
let assigned = false;
|
|
539
|
+
const next = results.map((result) => {
|
|
540
|
+
const envelopes = byAgent.get(String(result.agent_id || '')) || [];
|
|
541
|
+
if (envelopes.length)
|
|
542
|
+
assigned = true;
|
|
543
|
+
return { ...result, patch_envelopes: envelopes };
|
|
544
|
+
});
|
|
545
|
+
if (!assigned && patchEnvelopes.length && next[0])
|
|
546
|
+
next[0] = { ...next[0], patch_envelopes: patchEnvelopes };
|
|
547
|
+
return next;
|
|
548
|
+
}
|
|
485
549
|
async function legacyCodexExecBlockedRun(input) {
|
|
486
550
|
const blockers = ['legacy_codex_exec_runtime_removed'];
|
|
487
551
|
const ledgerRoot = path.join(input.dir, 'agents');
|
|
@@ -706,7 +770,9 @@ async function runAgentPatchSwarmRuntime(root, ledgerRoot, input) {
|
|
|
706
770
|
verification: verificationResults.results.map((result) => result.status),
|
|
707
771
|
parallelWritePolicy: input.parallelWritePolicy,
|
|
708
772
|
conflictRebase,
|
|
709
|
-
verificationRollbackDag: input.verificationRollbackDag
|
|
773
|
+
verificationRollbackDag: input.verificationRollbackDag,
|
|
774
|
+
gptFinalArbiter: input.gptFinalArbiter,
|
|
775
|
+
finalGptPatchStage: input.finalGptPatchStage
|
|
710
776
|
};
|
|
711
777
|
const initialProof = buildAgentPatchProof(proofInput);
|
|
712
778
|
await writeJsonAtomic(path.join(ledgerRoot, 'agent-patch-proof.json'), initialProof);
|
|
@@ -50,6 +50,8 @@ export function buildAgentPatchProof(input = {}) {
|
|
|
50
50
|
...journalBlockers,
|
|
51
51
|
...rebaseBlockers,
|
|
52
52
|
...parallelGroupBlockers,
|
|
53
|
+
...(input.gptFinalArbiter && input.gptFinalArbiter.ok !== true ? input.gptFinalArbiter.blockers || ['gpt_final_arbiter_not_ok'] : []),
|
|
54
|
+
...(input.finalGptPatchStage && input.finalGptPatchStage.ok !== true ? input.finalGptPatchStage.blockers || ['final_gpt_patch_stage_not_ok'] : []),
|
|
53
55
|
...applyResults.flatMap((applyResult) => applyResult.ok ? [] : (applyResult.violations || ['patch_apply_failed']))
|
|
54
56
|
].map(String);
|
|
55
57
|
const changedFilesByAgent = changedFilesGroupedByAgent(applyResults);
|
|
@@ -71,6 +73,9 @@ export function buildAgentPatchProof(input = {}) {
|
|
|
71
73
|
verification_node_coverage: strictWiring.verification_node_coverage,
|
|
72
74
|
rollback_node_coverage: strictWiring.rollback_node_coverage,
|
|
73
75
|
parallel_patch_apply_verified: hasParallelGroup,
|
|
76
|
+
gpt_final_arbiter: input.gptFinalArbiter ? 'gpt-final-arbiter/gpt-final-arbiter.json' : null,
|
|
77
|
+
gpt_final_status: input.gptFinalArbiter?.result?.status || null,
|
|
78
|
+
final_patch_source: input.finalGptPatchStage?.final_patch_source || null,
|
|
74
79
|
patch_conflict_count: Number(input.merge?.conflicts?.length || 0),
|
|
75
80
|
serial_bottleneck_count: Number(input.merge?.serial_conflicts?.length || 0),
|
|
76
81
|
changed_files_by_agent: changedFilesByAgent,
|
|
@@ -8,6 +8,7 @@ import { assertAgentSessionGenerationsClosed } from './agent-session-generation.
|
|
|
8
8
|
import { readZellijLaneSupervisor } from './zellij-lane-supervisor.js';
|
|
9
9
|
import { writeFakeRealProofPolicyReport } from '../proof/fake-real-proof-policy.js';
|
|
10
10
|
import { buildRuntimeTruthMatrix, writeRuntimeTruthMatrix } from '../proof/runtime-truth-matrix.js';
|
|
11
|
+
import { evaluateLocalCollaborationFinalGate, localCollaborationParticipated, resolveLocalCollaborationPolicy } from '../local-llm/local-collaboration-policy.js';
|
|
11
12
|
export async function writeAgentProofEvidence(root, input) {
|
|
12
13
|
const lifecycle = await assertAllAgentSessionsClosed(root);
|
|
13
14
|
const terminal = await assertAgentTerminalSessionsClosed(root);
|
|
@@ -28,6 +29,18 @@ export async function writeAgentProofEvidence(root, input) {
|
|
|
28
29
|
const patchRollbackProof = await readJson(path.join(root, 'agent-patch-rollback-proof.json'), null);
|
|
29
30
|
const patchProof = await readJson(path.join(root, 'agent-patch-proof.json'), null);
|
|
30
31
|
const patchSwarm = input.patchSwarm || await readJson(path.join(root, 'agent-patch-swarm-runtime.json'), null);
|
|
32
|
+
const localCollaborationPolicy = input.localCollaborationPolicy || await readJson(path.join(root, 'local-collaboration-policy.json'), null) || resolveLocalCollaborationPolicy();
|
|
33
|
+
const gptFinalArbiter = input.gptFinalArbiter || await readJson(path.join(root, 'gpt-final-arbiter', 'gpt-final-arbiter.json'), null);
|
|
34
|
+
const localParticipated = localCollaborationParticipated(input.results || []) || Number(gptFinalArbiter?.local_outputs_count || 0) > 0;
|
|
35
|
+
const finalGptPatchStage = input.finalGptPatchStage || null;
|
|
36
|
+
const localFinalGate = gptFinalArbiter?.final_gate || evaluateLocalCollaborationFinalGate({
|
|
37
|
+
policy: localCollaborationPolicy,
|
|
38
|
+
localParticipated,
|
|
39
|
+
gptFinalStatus: gptFinalArbiter?.result?.status || null,
|
|
40
|
+
gptFinalAvailable: Boolean(gptFinalArbiter),
|
|
41
|
+
gptFinalBackend: gptFinalArbiter?.backend || null,
|
|
42
|
+
applyPatches: parallelWritePolicy?.apply_patches === true
|
|
43
|
+
});
|
|
31
44
|
const nativeCliSessionProof = input.nativeCliSessionProof || await readJson(path.join(root, 'native-cli-session-proof.json'), null);
|
|
32
45
|
const noSubagentScalingPolicy = input.noSubagentScalingPolicy || await readJson(path.join(root, 'no-subagent-scaling-policy.json'), null);
|
|
33
46
|
const fastModePropagation = input.fastModePropagation || await readJson(path.join(root, 'fast-mode-propagation-proof.json'), null);
|
|
@@ -161,6 +174,9 @@ export async function writeAgentProofEvidence(root, input) {
|
|
|
161
174
|
...(patchSwarm && !patchApplyOk ? ['patch_apply_not_ok'] : []),
|
|
162
175
|
...(patchSwarm && !patchVerificationOk ? ['patch_verification_not_ok'] : []),
|
|
163
176
|
...(patchSwarm && !patchRollbackOk ? ['patch_rollback_not_ok'] : []),
|
|
177
|
+
...(localParticipated && localFinalGate.ok !== true ? localFinalGate.blockers || ['gpt_final_arbiter_gate_not_ok'] : []),
|
|
178
|
+
...(localParticipated && gptFinalArbiter?.ok !== true ? gptFinalArbiter?.blockers || ['gpt_final_arbiter_not_ok'] : []),
|
|
179
|
+
...(localParticipated && finalGptPatchStage?.ok === false ? finalGptPatchStage.blockers || ['final_gpt_patch_stage_not_ok'] : []),
|
|
164
180
|
...agentChangedFileLeaseViolations(input.results || [], input.partition?.leases || [])
|
|
165
181
|
];
|
|
166
182
|
const evidence = {
|
|
@@ -197,6 +213,15 @@ export async function writeAgentProofEvidence(root, input) {
|
|
|
197
213
|
parallel_write_apply_patches: parallelWritePolicy?.apply_patches === true,
|
|
198
214
|
parallel_write_dry_run_patches: parallelWritePolicy?.dry_run_patches === true,
|
|
199
215
|
parallel_write_max_write_agents: Number(parallelWritePolicy?.max_write_agents || 0),
|
|
216
|
+
local_collaboration_policy: 'local-collaboration-policy.json',
|
|
217
|
+
local_collaboration_mode: localCollaborationPolicy.mode || null,
|
|
218
|
+
local_collaboration_participated: localParticipated,
|
|
219
|
+
gpt_final_arbiter: gptFinalArbiter ? 'gpt-final-arbiter/gpt-final-arbiter.json' : null,
|
|
220
|
+
gpt_final_status: gptFinalArbiter?.result?.status || (localParticipated ? 'missing' : 'not_required_no_local_outputs'),
|
|
221
|
+
gpt_final_backend: gptFinalArbiter?.backend || null,
|
|
222
|
+
gpt_final_patch_source: finalGptPatchStage?.final_patch_source || (localParticipated ? 'blocked' : 'not_applicable'),
|
|
223
|
+
gpt_final_gate_ok: localFinalGate.ok === true,
|
|
224
|
+
gpt_final_gate: localFinalGate,
|
|
200
225
|
patch_swarm_runtime: patchSwarm ? 'agent-patch-swarm-runtime.json' : null,
|
|
201
226
|
patch_queue: patchSwarm ? 'agent-patch-queue.json' : null,
|
|
202
227
|
patch_queue_events: patchSwarm ? 'agent-patch-queue-events.jsonl' : null,
|
|
@@ -329,6 +354,7 @@ export async function writeAgentProofEvidence(root, input) {
|
|
|
329
354
|
'strategy-gate.json': strategyGate,
|
|
330
355
|
'agent-patch-proof.json': patchProof,
|
|
331
356
|
'agent-patch-swarm-runtime.json': patchSwarm,
|
|
357
|
+
'gpt-final-arbiter/gpt-final-arbiter.json': gptFinalArbiter,
|
|
332
358
|
'native-cli-session-proof.json': nativeCliSessionProof,
|
|
333
359
|
'no-subagent-scaling-policy.json': noSubagentScalingPolicy,
|
|
334
360
|
'fast-mode-propagation-proof.json': fastModePropagation
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { nowIso, randomId } from '../fsx.js';
|
|
2
|
+
import { GPT_FINAL_ARBITER_RESULT_SCHEMA_ID } from './gpt-final-review-schema.js';
|
|
2
3
|
export function fakeCodexSdkAllowed() {
|
|
3
4
|
return process.env.NODE_ENV === 'test'
|
|
4
5
|
|| process.env.SKS_CODEX_SDK_FAKE === '1'
|
|
@@ -25,6 +26,25 @@ export async function runFakeCodexSdkTask(input) {
|
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
28
|
function fakeStructuredOutput(input) {
|
|
29
|
+
if (input.outputSchemaId === GPT_FINAL_ARBITER_RESULT_SCHEMA_ID) {
|
|
30
|
+
const unsafe = /\b(truncate|delete all|drop table|credential)\b/i.test(input.prompt || '');
|
|
31
|
+
return {
|
|
32
|
+
schema: GPT_FINAL_ARBITER_RESULT_SCHEMA_ID,
|
|
33
|
+
status: unsafe ? 'rejected' : 'approved',
|
|
34
|
+
summary: unsafe
|
|
35
|
+
? 'Fake Codex SDK GPT final arbiter rejected an unsafe candidate for hermetic verification.'
|
|
36
|
+
: 'Fake Codex SDK GPT final arbiter approved the candidate for hermetic verification.',
|
|
37
|
+
gpt_review_findings: unsafe ? [{ severity: 'high', message: 'unsafe candidate rejected' }] : [],
|
|
38
|
+
accepted_patch_envelopes: unsafe ? [] : [],
|
|
39
|
+
modified_patch_envelopes: [],
|
|
40
|
+
rejected_patch_envelopes: unsafe ? [{ reason: 'unsafe candidate' }] : [],
|
|
41
|
+
required_followup_work: unsafe ? [{ blocker: 'unsafe_candidate_patch' }] : [],
|
|
42
|
+
verification_plan: ['schema validation', 'local collaboration final gate'],
|
|
43
|
+
rollback_notes: [],
|
|
44
|
+
blockers: unsafe ? ['unsafe_candidate_patch'] : [],
|
|
45
|
+
confidence: unsafe ? 'medium' : 'high'
|
|
46
|
+
};
|
|
47
|
+
}
|
|
28
48
|
return {
|
|
29
49
|
status: 'done',
|
|
30
50
|
summary: `Fake Codex SDK task completed for ${input.workItemId || input.route}.`,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CODEX_AGENT_WORKER_RESULT_SCHEMA_ID, codexAgentWorkerResultSchema } from './schemas/agent-worker-result.schema.js';
|
|
2
|
+
import { GPT_FINAL_ARBITER_RESULT_SCHEMA_ID, gptFinalArbiterResultSchema } from './gpt-final-review-schema.js';
|
|
2
3
|
export const CODEX_OUTPUT_SCHEMA_IDS = [
|
|
3
4
|
CODEX_AGENT_WORKER_RESULT_SCHEMA_ID,
|
|
4
5
|
'sks.patch-envelope-result.v1',
|
|
@@ -6,11 +7,14 @@ export const CODEX_OUTPUT_SCHEMA_IDS = [
|
|
|
6
7
|
'sks.research-digest.v1',
|
|
7
8
|
'sks.release-failure-analysis.v1',
|
|
8
9
|
'sks.ux-ppt-review-result.v1',
|
|
9
|
-
'sks.core-skill-heldout-validation.v1'
|
|
10
|
+
'sks.core-skill-heldout-validation.v1',
|
|
11
|
+
GPT_FINAL_ARBITER_RESULT_SCHEMA_ID
|
|
10
12
|
];
|
|
11
13
|
export function resolveCodexOutputSchema(schemaId, fallback) {
|
|
12
14
|
if (schemaId === CODEX_AGENT_WORKER_RESULT_SCHEMA_ID)
|
|
13
15
|
return codexAgentWorkerResultSchema;
|
|
16
|
+
if (schemaId === GPT_FINAL_ARBITER_RESULT_SCHEMA_ID)
|
|
17
|
+
return gptFinalArbiterResultSchema;
|
|
14
18
|
if (fallback && typeof fallback === 'object')
|
|
15
19
|
return fallback;
|
|
16
20
|
return {
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { nowIso, readJson, writeJsonAtomic } from '../fsx.js';
|
|
3
|
+
import { validateJsonSchemaRecursive } from '../json-schema-validator.js';
|
|
4
|
+
import { evaluateLocalCollaborationFinalGate, resolveLocalCollaborationPolicy } from '../local-llm/local-collaboration-policy.js';
|
|
5
|
+
import { runCodexTask } from './codex-control-plane.js';
|
|
6
|
+
import { GPT_FINAL_ARBITER_INPUT_SCHEMA, GPT_FINAL_ARBITER_RESULT_SCHEMA_ID, gptFinalArbiterResultSchema, normalizeGptFinalArbiterResult } from './gpt-final-review-schema.js';
|
|
7
|
+
import { compressGptFinalContext } from './gpt-final-context-compressor.js';
|
|
8
|
+
export const GPT_FINAL_ARBITER_RUN_SCHEMA = 'sks.gpt-final-arbiter-run.v1';
|
|
9
|
+
export async function runGptFinalArbiter(input, opts = {}) {
|
|
10
|
+
const started = Date.now();
|
|
11
|
+
const cwd = path.resolve(opts.cwd || process.cwd());
|
|
12
|
+
const root = path.resolve(opts.mutationLedgerRoot || path.join(cwd, '.sneakoscope', 'tmp', 'gpt-final-arbiter', safeName(input.mission_id || 'mission')));
|
|
13
|
+
const policy = resolveLocalCollaborationPolicy({ mode: input.local_mode });
|
|
14
|
+
const compressed = compressGptFinalContext(input);
|
|
15
|
+
if (policy.local_only_draft) {
|
|
16
|
+
return finalize(root, input, policy, compressed, blockedResult('needs_gpt_final_review', 'Local-only draft mode cannot produce final accepted proof.'), started, opts);
|
|
17
|
+
}
|
|
18
|
+
if (opts.forceUnavailable || process.env.SKS_GPT_FINAL_ARBITER_UNAVAILABLE === '1') {
|
|
19
|
+
return finalize(root, input, policy, compressed, blockedResult('gpt_final_arbiter_unavailable', 'GPT final arbiter backend is unavailable.'), started, opts);
|
|
20
|
+
}
|
|
21
|
+
let codexTask = null;
|
|
22
|
+
let parsed = null;
|
|
23
|
+
try {
|
|
24
|
+
codexTask = await runCodexTask({
|
|
25
|
+
route: String(input.route || '$Pipeline'),
|
|
26
|
+
tier: 'orchestrator',
|
|
27
|
+
missionId: String(input.mission_id || ''),
|
|
28
|
+
workItemId: 'gpt-final-arbiter',
|
|
29
|
+
slotId: 'gpt-final-arbiter',
|
|
30
|
+
generationIndex: 1,
|
|
31
|
+
sessionId: `gpt-final-${safeName(input.mission_id || 'mission')}`,
|
|
32
|
+
cwd,
|
|
33
|
+
prompt: buildArbiterPrompt(input, compressed),
|
|
34
|
+
inputFiles: [],
|
|
35
|
+
inputImages: [],
|
|
36
|
+
outputSchemaId: GPT_FINAL_ARBITER_RESULT_SCHEMA_ID,
|
|
37
|
+
outputSchema: gptFinalArbiterResultSchema,
|
|
38
|
+
sandboxPolicy: 'read-only',
|
|
39
|
+
requestedScopeContract: {
|
|
40
|
+
id: `gpt-final:${input.mission_id || 'mission'}`,
|
|
41
|
+
route: String(input.route || '$Pipeline'),
|
|
42
|
+
read_only: true,
|
|
43
|
+
allowed_paths: [],
|
|
44
|
+
write_paths: [],
|
|
45
|
+
user_confirmed_full_access: false,
|
|
46
|
+
mad_sks_authorized: process.env.SKS_MAD_SKS_ACTIVE === '1'
|
|
47
|
+
},
|
|
48
|
+
mutationLedgerRoot: root,
|
|
49
|
+
reliabilityPolicy: {
|
|
50
|
+
maxEmptyResultRetries: 1,
|
|
51
|
+
timeoutClass: 'standard'
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
parsed = parseFinalResponse(codexTask.finalResponse);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
return finalize(root, input, policy, compressed, blockedResult('gpt_final_arbiter_unavailable', error instanceof Error ? error.message : String(error)), started, opts);
|
|
58
|
+
}
|
|
59
|
+
const normalized = normalizeGptFinalArbiterResult(parsed);
|
|
60
|
+
const validation = validateJsonSchemaRecursive(normalized, gptFinalArbiterResultSchema);
|
|
61
|
+
const taskBlockers = Array.isArray(codexTask?.blockers) ? codexTask.blockers.map(String) : [];
|
|
62
|
+
const result = {
|
|
63
|
+
...normalized,
|
|
64
|
+
blockers: [
|
|
65
|
+
...normalized.blockers,
|
|
66
|
+
...(codexTask?.ok === true ? [] : ['gpt_final_arbiter_unavailable']),
|
|
67
|
+
...taskBlockers,
|
|
68
|
+
...(validation.ok ? [] : ['gpt_final_result_schema_invalid', ...validation.issues.map((issue) => `schema:${issue}`)])
|
|
69
|
+
]
|
|
70
|
+
};
|
|
71
|
+
return finalize(root, input, policy, compressed, result, started, opts, codexTask);
|
|
72
|
+
}
|
|
73
|
+
function finalize(root, input, policy, compressed, result, started, opts, codexTask) {
|
|
74
|
+
const latencyMs = Math.max(0, Date.now() - started);
|
|
75
|
+
const gate = evaluateLocalCollaborationFinalGate({
|
|
76
|
+
policy,
|
|
77
|
+
localParticipated: true,
|
|
78
|
+
gptFinalStatus: result.status,
|
|
79
|
+
gptFinalAvailable: !result.blockers.includes('gpt_final_arbiter_unavailable'),
|
|
80
|
+
gptFinalBackend: codexTask ? 'codex-sdk' : null,
|
|
81
|
+
applyPatches: false
|
|
82
|
+
});
|
|
83
|
+
const artifact = {
|
|
84
|
+
schema: GPT_FINAL_ARBITER_RUN_SCHEMA,
|
|
85
|
+
generated_at: nowIso(),
|
|
86
|
+
ok: gate.ok && result.blockers.length === 0,
|
|
87
|
+
input_schema: input.schema || GPT_FINAL_ARBITER_INPUT_SCHEMA,
|
|
88
|
+
route: input.route,
|
|
89
|
+
mission_id: input.mission_id,
|
|
90
|
+
local_mode: policy.mode,
|
|
91
|
+
backend: codexTask ? 'codex-sdk' : 'unavailable',
|
|
92
|
+
backend_family: codexTask ? 'remote-gpt' : 'none',
|
|
93
|
+
local_outputs_count: Array.isArray(input.local_outputs) ? input.local_outputs.length : 0,
|
|
94
|
+
proof_pack: compressed.proof_pack,
|
|
95
|
+
latency_budget: {
|
|
96
|
+
...compressed.latency_budget,
|
|
97
|
+
latency_ms: latencyMs
|
|
98
|
+
},
|
|
99
|
+
result,
|
|
100
|
+
final_gate: gate,
|
|
101
|
+
codex_task: codexTask ? {
|
|
102
|
+
ok: codexTask.ok === true,
|
|
103
|
+
sdk_thread_id: codexTask.sdkThreadId || null,
|
|
104
|
+
sdk_run_id: codexTask.sdkRunId || null,
|
|
105
|
+
stream_event_count: codexTask.streamEventCount || 0,
|
|
106
|
+
structured_output_valid: codexTask.structuredOutputValid === true,
|
|
107
|
+
worker_result_path: codexTask.workerResultPath || null,
|
|
108
|
+
blockers: codexTask.blockers || []
|
|
109
|
+
} : null,
|
|
110
|
+
blockers: [
|
|
111
|
+
...result.blockers,
|
|
112
|
+
...gate.blockers,
|
|
113
|
+
...compressed.blockers
|
|
114
|
+
]
|
|
115
|
+
};
|
|
116
|
+
artifact.ok = artifact.blockers.length === 0 && (result.status === 'approved' || result.status === 'modified');
|
|
117
|
+
if (opts.writeArtifact !== false)
|
|
118
|
+
return writeArtifact(root, artifact);
|
|
119
|
+
return artifact;
|
|
120
|
+
}
|
|
121
|
+
async function writeArtifact(root, artifact) {
|
|
122
|
+
await writeJsonAtomic(path.join(root, 'gpt-final-arbiter.json'), artifact);
|
|
123
|
+
return artifact;
|
|
124
|
+
}
|
|
125
|
+
function blockedResult(blocker, summary) {
|
|
126
|
+
return normalizeGptFinalArbiterResult({
|
|
127
|
+
status: 'needs_more_work',
|
|
128
|
+
summary,
|
|
129
|
+
blockers: [blocker],
|
|
130
|
+
confidence: 'low',
|
|
131
|
+
required_followup_work: [{ blocker }]
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
function parseFinalResponse(value) {
|
|
135
|
+
if (typeof value !== 'string')
|
|
136
|
+
return value || {};
|
|
137
|
+
try {
|
|
138
|
+
return JSON.parse(value);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return {};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function buildArbiterPrompt(input, compressed) {
|
|
145
|
+
return [
|
|
146
|
+
'You are the GPT Final Arbiter for an SKS local collaboration run.',
|
|
147
|
+
'Local model outputs are drafts only. Review the proof pack, candidate diff, patch envelopes, verification results, side effects, mutation ledger, and rollback plan.',
|
|
148
|
+
'Approve or modify only when the candidate is safe and supported. Reject unsafe local patches. Return only the requested structured JSON schema.',
|
|
149
|
+
JSON.stringify({
|
|
150
|
+
route: input.route,
|
|
151
|
+
mission_id: input.mission_id,
|
|
152
|
+
local_mode: input.local_mode,
|
|
153
|
+
proof_pack: compressed.proof_pack
|
|
154
|
+
})
|
|
155
|
+
].join('\n');
|
|
156
|
+
}
|
|
157
|
+
function safeName(value) {
|
|
158
|
+
return String(value || 'unknown').replace(/[^a-zA-Z0-9_.-]+/g, '-').slice(0, 80);
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=gpt-final-arbiter.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { buildGptFinalLatencyBudgetReport, buildGptFinalProofPack } from './gpt-final-proof-pack.js';
|
|
2
|
+
export function compressGptFinalContext(input, opts = {}) {
|
|
3
|
+
const proofPack = buildGptFinalProofPack(input, opts);
|
|
4
|
+
const latencyBudget = buildGptFinalLatencyBudgetReport({
|
|
5
|
+
workerCount: proofPack.worker_count,
|
|
6
|
+
tokenBudgetEstimate: proofPack.token_budget_estimate,
|
|
7
|
+
latencyMs: opts.latencyMs ?? null
|
|
8
|
+
});
|
|
9
|
+
return {
|
|
10
|
+
schema: 'sks.gpt-final-context-compressor.v1',
|
|
11
|
+
ok: latencyBudget.ok,
|
|
12
|
+
proof_pack: proofPack,
|
|
13
|
+
latency_budget: latencyBudget,
|
|
14
|
+
blockers: latencyBudget.ok ? [] : ['gpt_final_context_budget_exceeded']
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=gpt-final-context-compressor.js.map
|