sneakoscope 1.18.2 → 1.18.3
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 +3 -2
- 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 +6 -6
- package/dist/commands/image-ux-review.d.ts +27 -1
- package/dist/commands/ppt.d.ts +27 -1
- package/dist/core/agents/agent-orchestrator.d.ts +27 -1
- package/dist/core/agents/agent-orchestrator.js +62 -4
- package/dist/core/agents/agent-proof-evidence.d.ts +27 -1
- package/dist/core/agents/agent-proof-evidence.js +49 -1
- package/dist/core/agents/agent-runner-tmux.js +35 -1
- package/dist/core/agents/agent-schema.d.ts +2 -0
- package/dist/core/agents/route-collaboration-ledger.d.ts +27 -1
- package/dist/core/agents/tmux-lane-supervisor.d.ts +3 -0
- package/dist/core/agents/tmux-lane-supervisor.js +58 -2
- package/dist/core/commands/agent-command.js +1 -1
- package/dist/core/commands/image-ux-review-command.d.ts +27 -1
- package/dist/core/commands/ppt-command.d.ts +27 -1
- package/dist/core/commands/qa-loop-command.js +7 -3
- package/dist/core/commands/research-command.js +6 -3
- package/dist/core/commands/team-command.js +9 -1
- package/dist/core/fsx.d.ts +1 -1
- package/dist/core/fsx.js +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ SKS does not try to clone every other harness. It focuses on one thing: making C
|
|
|
10
10
|
|
|
11
11
|
## Current Release
|
|
12
12
|
|
|
13
|
-
SKS **1.18.
|
|
13
|
+
SKS **1.18.3** closes the route-truth Dynamic Worker Pool runtime: `agents=5` means five target active worker slots, while `--work-items N` controls the route work queue. Pending work backfills empty slots immediately, tmux lanes persist as worker-slot UI until scheduler drain, follow-up work items are schema-bound, and Agent/Team/Research/QA blackboxes now execute the actual route commands while proving task graph, work queue, scheduler, terminal, Source Intelligence, Goal, and tmux supervisor evidence.
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
sks mad-sks plan --target-root <path> --json
|
|
@@ -24,6 +24,7 @@ npm run source-intelligence:all-modes
|
|
|
24
24
|
npm run agent:background-terminals
|
|
25
25
|
npm run agent:tmux-lane-no-flicker
|
|
26
26
|
npm run agent:backfill-route-blackbox
|
|
27
|
+
npm run team:actual-route-backfill
|
|
27
28
|
npm run release:readiness
|
|
28
29
|
```
|
|
29
30
|
|
|
@@ -613,7 +614,7 @@ npm run release:check
|
|
|
613
614
|
npm run publish:dry
|
|
614
615
|
```
|
|
615
616
|
|
|
616
|
-
`release:check` runs the 1.18.
|
|
617
|
+
`release:check` runs the 1.18.3 route-truth dynamic scheduler closure DAG, writes a source digest stamp under `.sneakoscope/reports/`, then refreshes release readiness so publish commands can verify the same stamp. The DAG preserves the 1.18 baseline gates and adds task graph expansion, schema-bound follow-up work, actual Agent/Team/Research/QA route backfill blackboxes, scheduler proof hardening, persistent tmux lane supervisor integration, no-flicker lane proof, session generation, terminal generation, dynamic cockpit, Source Intelligence propagation, and Goal mode propagation checks. Broader live or historical gates remain explicit scripts such as `release:real-check`. Generate the human-readable registry with `sks features inventory --write-docs`. Plain `npm publish` uses the `latest` dist-tag. npm's `prepublishOnly` verifies the fresh release stamp instead of rerunning the full gate, and `prepack` only rebuilds `dist`; publish no longer repeats the expensive release suite during packaging. `npm run publish:dry` remains the explicit dry-run helper.
|
|
617
618
|
|
|
618
619
|
Version bumps are manual. Run `sks versioning bump` only when preparing release metadata; SKS will not create `.git/hooks/pre-commit` or auto-bump during ordinary commits.
|
|
619
620
|
|
|
@@ -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 1.18.
|
|
7
|
+
Some("--version") => println!("sks-rs 1.18.3"),
|
|
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": "1.18.
|
|
5
|
-
"source_digest": "
|
|
6
|
-
"source_file_count":
|
|
7
|
-
"built_at_source_time":
|
|
4
|
+
"package_version": "1.18.3",
|
|
5
|
+
"source_digest": "5aefcff7c0119b0c22dc3ca2d50edd2dbd5f069ea1a9838cee14700f0ede28de",
|
|
6
|
+
"source_file_count": 1370,
|
|
7
|
+
"built_at_source_time": 1779767703495
|
|
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": "1.18.
|
|
4
|
-
"package_version": "1.18.
|
|
3
|
+
"version": "1.18.3",
|
|
4
|
+
"package_version": "1.18.3",
|
|
5
5
|
"typescript": true,
|
|
6
6
|
"mjs_runtime_files": 0,
|
|
7
7
|
"compiled_file_count": 864,
|
|
8
8
|
"compiled_js_count": 432,
|
|
9
9
|
"compiled_dts_count": 432,
|
|
10
|
-
"source_digest": "
|
|
11
|
-
"source_file_count":
|
|
12
|
-
"source_files_hash": "
|
|
13
|
-
"source_list_hash": "
|
|
10
|
+
"source_digest": "5aefcff7c0119b0c22dc3ca2d50edd2dbd5f069ea1a9838cee14700f0ede28de",
|
|
11
|
+
"source_file_count": 1370,
|
|
12
|
+
"source_files_hash": "1807c675876cb62160e1f8e2fb69a846610ba2a34fa01154263805337a98c149",
|
|
13
|
+
"source_list_hash": "1807c675876cb62160e1f8e2fb69a846610ba2a34fa01154263805337a98c149",
|
|
14
14
|
"src_mjs_runtime_files": 0,
|
|
15
15
|
"dist_stamp_schema": "sks.dist-build-stamp.v1",
|
|
16
16
|
"files": [
|
|
@@ -385,6 +385,8 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
385
385
|
ok: boolean;
|
|
386
386
|
mission_id: any;
|
|
387
387
|
route: string;
|
|
388
|
+
route_command: string;
|
|
389
|
+
route_blackbox_kind: string;
|
|
388
390
|
backend: "tmux" | "fake" | "process" | "codex-exec";
|
|
389
391
|
ledger_root: string;
|
|
390
392
|
roster: {
|
|
@@ -442,6 +444,10 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
442
444
|
generated_from_route: string;
|
|
443
445
|
work_items_exceed_active_slots: boolean;
|
|
444
446
|
};
|
|
447
|
+
requested_work_items: number;
|
|
448
|
+
actual_total_work_items: number;
|
|
449
|
+
target_active_slots: number;
|
|
450
|
+
minimum_work_items: number;
|
|
445
451
|
scheduler: {
|
|
446
452
|
schema: string;
|
|
447
453
|
ok: boolean;
|
|
@@ -600,6 +606,10 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
600
606
|
generated_at: string;
|
|
601
607
|
mission_id: string;
|
|
602
608
|
backend: string;
|
|
609
|
+
route: string;
|
|
610
|
+
route_command: string;
|
|
611
|
+
route_blackbox_kind: string;
|
|
612
|
+
real_route_command_used: boolean;
|
|
603
613
|
real_parallel_claim: boolean;
|
|
604
614
|
fake_backend_disclaimer: string | null;
|
|
605
615
|
agent_count: any;
|
|
@@ -615,26 +625,42 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
615
625
|
session_generation_count: number;
|
|
616
626
|
all_generations_closed: boolean;
|
|
617
627
|
scheduler_state: string;
|
|
618
|
-
target_active_slots:
|
|
628
|
+
target_active_slots: number;
|
|
629
|
+
requested_work_items: number;
|
|
630
|
+
actual_total_work_items: number;
|
|
631
|
+
minimum_work_items: number;
|
|
632
|
+
task_graph_total_work_items: number;
|
|
633
|
+
work_queue_total_work_items: number;
|
|
634
|
+
scheduler_total_work_items: number;
|
|
635
|
+
task_graph_matches_cli_options: boolean;
|
|
636
|
+
work_queue_matches_task_graph: boolean;
|
|
637
|
+
scheduler_matches_work_queue: boolean;
|
|
619
638
|
max_observed_active_slots: any;
|
|
620
639
|
pending_queue_drained: boolean;
|
|
621
640
|
backfill_count: any;
|
|
622
641
|
expected_backfill_count: any;
|
|
642
|
+
backfill_expected_for_route: boolean;
|
|
623
643
|
slot_count: any;
|
|
624
644
|
generation_count: number;
|
|
625
645
|
all_slots_closed_after_drain: boolean;
|
|
626
646
|
generated_work_item_count: any;
|
|
627
647
|
source_intelligence_generation_refs_ok: boolean;
|
|
628
648
|
goal_mode_generation_refs_ok: boolean;
|
|
649
|
+
task_graph_source_refs_ok: any;
|
|
650
|
+
task_graph_goal_refs_ok: any;
|
|
651
|
+
work_queue_source_refs_ok: any;
|
|
652
|
+
work_queue_goal_refs_ok: any;
|
|
629
653
|
tmux_lane_manifest: string;
|
|
630
654
|
tmux_lane_manifest_ok: boolean;
|
|
631
655
|
tmux_lane_supervisor: string;
|
|
656
|
+
lane_supervisor_integrated: boolean;
|
|
632
657
|
tmux_lane_no_flicker_verified: boolean;
|
|
633
658
|
tmux_lane_survival_checked: boolean;
|
|
634
659
|
tmux_lane_unexpected_close_count: number;
|
|
635
660
|
tmux_lane_auto_reopen_count: number;
|
|
636
661
|
tmux_pane_launch_ledger: string;
|
|
637
662
|
tmux_pane_launch_count: number;
|
|
663
|
+
terminal_reports_match_generations: boolean;
|
|
638
664
|
ledger_hash_chain_ok: boolean;
|
|
639
665
|
no_overlap_ok: boolean;
|
|
640
666
|
consensus_ok: boolean;
|
package/dist/commands/ppt.d.ts
CHANGED
|
@@ -237,6 +237,8 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
237
237
|
ok: boolean;
|
|
238
238
|
mission_id: any;
|
|
239
239
|
route: string;
|
|
240
|
+
route_command: string;
|
|
241
|
+
route_blackbox_kind: string;
|
|
240
242
|
backend: "tmux" | "fake" | "process" | "codex-exec";
|
|
241
243
|
ledger_root: string;
|
|
242
244
|
roster: {
|
|
@@ -294,6 +296,10 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
294
296
|
generated_from_route: string;
|
|
295
297
|
work_items_exceed_active_slots: boolean;
|
|
296
298
|
};
|
|
299
|
+
requested_work_items: number;
|
|
300
|
+
actual_total_work_items: number;
|
|
301
|
+
target_active_slots: number;
|
|
302
|
+
minimum_work_items: number;
|
|
297
303
|
scheduler: {
|
|
298
304
|
schema: string;
|
|
299
305
|
ok: boolean;
|
|
@@ -452,6 +458,10 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
452
458
|
generated_at: string;
|
|
453
459
|
mission_id: string;
|
|
454
460
|
backend: string;
|
|
461
|
+
route: string;
|
|
462
|
+
route_command: string;
|
|
463
|
+
route_blackbox_kind: string;
|
|
464
|
+
real_route_command_used: boolean;
|
|
455
465
|
real_parallel_claim: boolean;
|
|
456
466
|
fake_backend_disclaimer: string | null;
|
|
457
467
|
agent_count: any;
|
|
@@ -467,26 +477,42 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
467
477
|
session_generation_count: number;
|
|
468
478
|
all_generations_closed: boolean;
|
|
469
479
|
scheduler_state: string;
|
|
470
|
-
target_active_slots:
|
|
480
|
+
target_active_slots: number;
|
|
481
|
+
requested_work_items: number;
|
|
482
|
+
actual_total_work_items: number;
|
|
483
|
+
minimum_work_items: number;
|
|
484
|
+
task_graph_total_work_items: number;
|
|
485
|
+
work_queue_total_work_items: number;
|
|
486
|
+
scheduler_total_work_items: number;
|
|
487
|
+
task_graph_matches_cli_options: boolean;
|
|
488
|
+
work_queue_matches_task_graph: boolean;
|
|
489
|
+
scheduler_matches_work_queue: boolean;
|
|
471
490
|
max_observed_active_slots: any;
|
|
472
491
|
pending_queue_drained: boolean;
|
|
473
492
|
backfill_count: any;
|
|
474
493
|
expected_backfill_count: any;
|
|
494
|
+
backfill_expected_for_route: boolean;
|
|
475
495
|
slot_count: any;
|
|
476
496
|
generation_count: number;
|
|
477
497
|
all_slots_closed_after_drain: boolean;
|
|
478
498
|
generated_work_item_count: any;
|
|
479
499
|
source_intelligence_generation_refs_ok: boolean;
|
|
480
500
|
goal_mode_generation_refs_ok: boolean;
|
|
501
|
+
task_graph_source_refs_ok: any;
|
|
502
|
+
task_graph_goal_refs_ok: any;
|
|
503
|
+
work_queue_source_refs_ok: any;
|
|
504
|
+
work_queue_goal_refs_ok: any;
|
|
481
505
|
tmux_lane_manifest: string;
|
|
482
506
|
tmux_lane_manifest_ok: boolean;
|
|
483
507
|
tmux_lane_supervisor: string;
|
|
508
|
+
lane_supervisor_integrated: boolean;
|
|
484
509
|
tmux_lane_no_flicker_verified: boolean;
|
|
485
510
|
tmux_lane_survival_checked: boolean;
|
|
486
511
|
tmux_lane_unexpected_close_count: number;
|
|
487
512
|
tmux_lane_auto_reopen_count: number;
|
|
488
513
|
tmux_pane_launch_ledger: string;
|
|
489
514
|
tmux_pane_launch_count: number;
|
|
515
|
+
terminal_reports_match_generations: boolean;
|
|
490
516
|
ledger_hash_chain_ok: boolean;
|
|
491
517
|
no_overlap_ok: boolean;
|
|
492
518
|
consensus_ok: boolean;
|
|
@@ -4,6 +4,8 @@ export declare function runNativeAgentOrchestrator(opts?: AgentRunOptions): Prom
|
|
|
4
4
|
ok: boolean;
|
|
5
5
|
mission_id: any;
|
|
6
6
|
route: string;
|
|
7
|
+
route_command: string;
|
|
8
|
+
route_blackbox_kind: string;
|
|
7
9
|
backend: "tmux" | "fake" | "process" | "codex-exec";
|
|
8
10
|
ledger_root: string;
|
|
9
11
|
roster: {
|
|
@@ -61,6 +63,10 @@ export declare function runNativeAgentOrchestrator(opts?: AgentRunOptions): Prom
|
|
|
61
63
|
generated_from_route: string;
|
|
62
64
|
work_items_exceed_active_slots: boolean;
|
|
63
65
|
};
|
|
66
|
+
requested_work_items: number;
|
|
67
|
+
actual_total_work_items: number;
|
|
68
|
+
target_active_slots: number;
|
|
69
|
+
minimum_work_items: number;
|
|
64
70
|
scheduler: {
|
|
65
71
|
schema: string;
|
|
66
72
|
ok: boolean;
|
|
@@ -219,6 +225,10 @@ export declare function runNativeAgentOrchestrator(opts?: AgentRunOptions): Prom
|
|
|
219
225
|
generated_at: string;
|
|
220
226
|
mission_id: string;
|
|
221
227
|
backend: string;
|
|
228
|
+
route: string;
|
|
229
|
+
route_command: string;
|
|
230
|
+
route_blackbox_kind: string;
|
|
231
|
+
real_route_command_used: boolean;
|
|
222
232
|
real_parallel_claim: boolean;
|
|
223
233
|
fake_backend_disclaimer: string | null;
|
|
224
234
|
agent_count: any;
|
|
@@ -234,26 +244,42 @@ export declare function runNativeAgentOrchestrator(opts?: AgentRunOptions): Prom
|
|
|
234
244
|
session_generation_count: number;
|
|
235
245
|
all_generations_closed: boolean;
|
|
236
246
|
scheduler_state: string;
|
|
237
|
-
target_active_slots:
|
|
247
|
+
target_active_slots: number;
|
|
248
|
+
requested_work_items: number;
|
|
249
|
+
actual_total_work_items: number;
|
|
250
|
+
minimum_work_items: number;
|
|
251
|
+
task_graph_total_work_items: number;
|
|
252
|
+
work_queue_total_work_items: number;
|
|
253
|
+
scheduler_total_work_items: number;
|
|
254
|
+
task_graph_matches_cli_options: boolean;
|
|
255
|
+
work_queue_matches_task_graph: boolean;
|
|
256
|
+
scheduler_matches_work_queue: boolean;
|
|
238
257
|
max_observed_active_slots: any;
|
|
239
258
|
pending_queue_drained: boolean;
|
|
240
259
|
backfill_count: any;
|
|
241
260
|
expected_backfill_count: any;
|
|
261
|
+
backfill_expected_for_route: boolean;
|
|
242
262
|
slot_count: any;
|
|
243
263
|
generation_count: number;
|
|
244
264
|
all_slots_closed_after_drain: boolean;
|
|
245
265
|
generated_work_item_count: any;
|
|
246
266
|
source_intelligence_generation_refs_ok: boolean;
|
|
247
267
|
goal_mode_generation_refs_ok: boolean;
|
|
268
|
+
task_graph_source_refs_ok: any;
|
|
269
|
+
task_graph_goal_refs_ok: any;
|
|
270
|
+
work_queue_source_refs_ok: any;
|
|
271
|
+
work_queue_goal_refs_ok: any;
|
|
248
272
|
tmux_lane_manifest: string;
|
|
249
273
|
tmux_lane_manifest_ok: boolean;
|
|
250
274
|
tmux_lane_supervisor: string;
|
|
275
|
+
lane_supervisor_integrated: boolean;
|
|
251
276
|
tmux_lane_no_flicker_verified: boolean;
|
|
252
277
|
tmux_lane_survival_checked: boolean;
|
|
253
278
|
tmux_lane_unexpected_close_count: number;
|
|
254
279
|
tmux_lane_auto_reopen_count: number;
|
|
255
280
|
tmux_pane_launch_ledger: string;
|
|
256
281
|
tmux_pane_launch_count: number;
|
|
282
|
+
terminal_reports_match_generations: boolean;
|
|
257
283
|
ledger_hash_chain_ok: boolean;
|
|
258
284
|
no_overlap_ok: boolean;
|
|
259
285
|
consensus_ok: boolean;
|
|
@@ -31,6 +31,8 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
31
31
|
const root = path.resolve(opts.root || process.cwd());
|
|
32
32
|
const prompt = String(opts.prompt || 'Native agent run');
|
|
33
33
|
const route = opts.route || '$Agent';
|
|
34
|
+
const routeCommand = String(opts.routeCommand || defaultRouteCommand(route));
|
|
35
|
+
const routeBlackboxKind = String(opts.routeBlackboxKind || defaultRouteBlackboxKind(route));
|
|
34
36
|
const backend = normalizeAgentBackend(opts.backend || (opts.mock ? 'fake' : 'codex-exec'));
|
|
35
37
|
const created = opts.missionId
|
|
36
38
|
? { id: opts.missionId, dir: missionDir(root, opts.missionId), mission: { id: opts.missionId, mode: 'agent', prompt } }
|
|
@@ -51,6 +53,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
51
53
|
}));
|
|
52
54
|
const targetActiveSlots = normalizeTargetActiveSlots(opts.targetActiveSlots ?? opts.agents ?? roster.agent_count);
|
|
53
55
|
const desiredWorkItemCount = normalizeDesiredWorkItemCount(opts.desiredWorkItemCount, opts.minimumWorkItems, targetActiveSlots);
|
|
56
|
+
const minimumWorkItems = normalizeMinimumWorkItems(opts.minimumWorkItems, targetActiveSlots);
|
|
54
57
|
const sourceIntelligence = await runSourceIntelligence({ root, missionDir: dir, route, query: prompt, offline: true, context7Available: true });
|
|
55
58
|
const sourceIntelligenceRef = {
|
|
56
59
|
artifact: 'source-intelligence-evidence.json',
|
|
@@ -72,7 +75,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
72
75
|
route,
|
|
73
76
|
targetActiveSlots,
|
|
74
77
|
desiredWorkItemCount,
|
|
75
|
-
|
|
78
|
+
minimumWorkItems,
|
|
76
79
|
sourceIntelligenceRefs: sourceIntelligenceRef,
|
|
77
80
|
goalModeRef
|
|
78
81
|
});
|
|
@@ -81,7 +84,7 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
81
84
|
await writeAgentTaskGraph(ledgerRoot, partition.task_graph);
|
|
82
85
|
await writeScoutPolicyArtifact(ledgerRoot);
|
|
83
86
|
await writeTmuxRightLaneCockpit(ledgerRoot, { missionId, sessionName: `sks-${missionId}`, agents: roster.roster });
|
|
84
|
-
await initializeTmuxLaneSupervisor(ledgerRoot, { missionId, sessionName: `sks-${missionId}`, targetActiveSlots });
|
|
87
|
+
await initializeTmuxLaneSupervisor(ledgerRoot, { missionId, sessionName: `sks-${missionId}`, targetActiveSlots, launchRealTmux: backend === 'tmux' && opts.real === true });
|
|
85
88
|
await writeAgentCodexCockpitArtifacts(dir, { missionId, projectHash: namespace.root_hash });
|
|
86
89
|
await writeJsonAtomic(path.join(ledgerRoot, 'agent-no-overlap-proof.json'), partition.no_overlap_proof || { schema: 'sks.agent-no-overlap-proof.v1', ok: false, blockers: ['missing_no_overlap_proof'] });
|
|
87
90
|
await writeAgentLifecyclePolicy(ledgerRoot);
|
|
@@ -95,12 +98,14 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
95
98
|
batch_count: 0,
|
|
96
99
|
target_active_slots: targetActiveSlots,
|
|
97
100
|
desired_work_items: desiredWorkItemCount,
|
|
101
|
+
minimum_work_items: minimumWorkItems,
|
|
102
|
+
requested_work_items: desiredWorkItemCount,
|
|
98
103
|
total_work_items: partition.task_graph?.total_work_items || partition.slices.length,
|
|
99
104
|
backpressure: 'dynamic scheduler maintains target active slots until the work queue drains',
|
|
100
105
|
rate_limit_delay_ms: backend === 'codex-exec' ? 250 : 0,
|
|
101
106
|
resource_pressure_warnings: roster.agent_count > roster.concurrency ? ['agents_exceed_concurrency_batches'] : []
|
|
102
107
|
});
|
|
103
|
-
await setCurrent(root, { mission_id: missionId, mode: 'AGENT', phase: 'AGENT_NATIVE_KERNEL_RUNNING', route_command:
|
|
108
|
+
await setCurrent(root, { mission_id: missionId, mode: 'AGENT', phase: 'AGENT_NATIVE_KERNEL_RUNNING', route_command: routeCommand, native_agent_backend: backend });
|
|
104
109
|
const scheduler = await runAgentScheduler({
|
|
105
110
|
root: ledgerRoot,
|
|
106
111
|
missionId,
|
|
@@ -210,7 +215,28 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
210
215
|
];
|
|
211
216
|
const trust = await writeAgentTrustReport(ledgerRoot, { missionId, backend, roster, partition, cleanup, outputTails, timeoutKill, backendReport, outputValidation, scheduler: scheduler.state, blockers });
|
|
212
217
|
const wrongness = await writeAgentWrongnessRecords(ledgerRoot, blockers);
|
|
213
|
-
const proof = await writeAgentProofEvidence(ledgerRoot, {
|
|
218
|
+
const proof = await writeAgentProofEvidence(ledgerRoot, {
|
|
219
|
+
missionId,
|
|
220
|
+
backend,
|
|
221
|
+
route,
|
|
222
|
+
routeCommand,
|
|
223
|
+
routeBlackboxKind,
|
|
224
|
+
requestedWorkItems: desiredWorkItemCount,
|
|
225
|
+
minimumWorkItems,
|
|
226
|
+
targetActiveSlots,
|
|
227
|
+
realParallel: backend === 'codex-exec' && opts.mock !== true,
|
|
228
|
+
roster,
|
|
229
|
+
partition,
|
|
230
|
+
consensus,
|
|
231
|
+
results,
|
|
232
|
+
cleanup,
|
|
233
|
+
janitor,
|
|
234
|
+
outputTails,
|
|
235
|
+
timeoutKill,
|
|
236
|
+
trust,
|
|
237
|
+
wrongness,
|
|
238
|
+
scheduler: scheduler.state
|
|
239
|
+
});
|
|
214
240
|
await writeAgentCodexCockpitArtifacts(dir, { missionId, projectHash: namespace.root_hash });
|
|
215
241
|
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() });
|
|
216
242
|
return {
|
|
@@ -218,11 +244,17 @@ export async function runNativeAgentOrchestrator(opts = {}) {
|
|
|
218
244
|
ok: proof.ok,
|
|
219
245
|
mission_id: missionId,
|
|
220
246
|
route,
|
|
247
|
+
route_command: routeCommand,
|
|
248
|
+
route_blackbox_kind: routeBlackboxKind,
|
|
221
249
|
backend,
|
|
222
250
|
ledger_root: path.relative(root, ledgerRoot),
|
|
223
251
|
roster,
|
|
224
252
|
partition: { ok: partition.ok, slice_count: partition.slices.length, lease_count: partition.leases.length, blockers: partition.blockers },
|
|
225
253
|
task_graph: partition.task_graph?.route_work_count_summary || null,
|
|
254
|
+
requested_work_items: desiredWorkItemCount,
|
|
255
|
+
actual_total_work_items: partition.task_graph?.total_work_items || partition.slices.length,
|
|
256
|
+
target_active_slots: targetActiveSlots,
|
|
257
|
+
minimum_work_items: minimumWorkItems,
|
|
226
258
|
scheduler,
|
|
227
259
|
source_intelligence: sourceIntelligenceRef,
|
|
228
260
|
goal_mode: goalModeRef,
|
|
@@ -247,6 +279,32 @@ function normalizeDesiredWorkItemCount(value, minimumValue, targetActiveSlots) {
|
|
|
247
279
|
return Math.max(1, Math.floor(fallback));
|
|
248
280
|
return Math.max(1, Math.floor(parsed));
|
|
249
281
|
}
|
|
282
|
+
function normalizeMinimumWorkItems(value, targetActiveSlots) {
|
|
283
|
+
const parsed = Number(value);
|
|
284
|
+
if (!Number.isFinite(parsed) || parsed < 1)
|
|
285
|
+
return Math.max(1, Math.floor(targetActiveSlots));
|
|
286
|
+
return Math.max(1, Math.floor(parsed));
|
|
287
|
+
}
|
|
288
|
+
function defaultRouteCommand(route) {
|
|
289
|
+
const normalized = String(route || '$Agent');
|
|
290
|
+
if (/team/i.test(normalized))
|
|
291
|
+
return 'sks team';
|
|
292
|
+
if (/research|autoresearch/i.test(normalized))
|
|
293
|
+
return 'sks research run';
|
|
294
|
+
if (/qa/i.test(normalized))
|
|
295
|
+
return 'sks qa-loop run';
|
|
296
|
+
return 'sks agent run';
|
|
297
|
+
}
|
|
298
|
+
function defaultRouteBlackboxKind(route) {
|
|
299
|
+
const normalized = String(route || '$Agent');
|
|
300
|
+
if (/team/i.test(normalized))
|
|
301
|
+
return 'actual_team_command';
|
|
302
|
+
if (/research|autoresearch/i.test(normalized))
|
|
303
|
+
return 'actual_research_command';
|
|
304
|
+
if (/qa/i.test(normalized))
|
|
305
|
+
return 'actual_qa_command';
|
|
306
|
+
return 'actual_agent_command';
|
|
307
|
+
}
|
|
250
308
|
function buildProvidedAgentRoster(input, opts = {}) {
|
|
251
309
|
const sourceRows = Array.isArray(input?.roster) ? input.roster : Array.isArray(input?.personas) ? input.personas : [];
|
|
252
310
|
if (!sourceRows.length)
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
export declare function writeAgentProofEvidence(root: string, input: {
|
|
2
2
|
missionId: string;
|
|
3
3
|
backend: string;
|
|
4
|
+
route?: string;
|
|
5
|
+
routeCommand?: string;
|
|
6
|
+
routeBlackboxKind?: string;
|
|
7
|
+
requestedWorkItems?: number;
|
|
8
|
+
minimumWorkItems?: number;
|
|
9
|
+
targetActiveSlots?: number;
|
|
4
10
|
realParallel?: boolean;
|
|
5
11
|
roster?: any;
|
|
6
12
|
partition?: any;
|
|
@@ -20,6 +26,10 @@ export declare function writeAgentProofEvidence(root: string, input: {
|
|
|
20
26
|
generated_at: string;
|
|
21
27
|
mission_id: string;
|
|
22
28
|
backend: string;
|
|
29
|
+
route: string;
|
|
30
|
+
route_command: string;
|
|
31
|
+
route_blackbox_kind: string;
|
|
32
|
+
real_route_command_used: boolean;
|
|
23
33
|
real_parallel_claim: boolean;
|
|
24
34
|
fake_backend_disclaimer: string | null;
|
|
25
35
|
agent_count: any;
|
|
@@ -35,26 +45,42 @@ export declare function writeAgentProofEvidence(root: string, input: {
|
|
|
35
45
|
session_generation_count: number;
|
|
36
46
|
all_generations_closed: boolean;
|
|
37
47
|
scheduler_state: string;
|
|
38
|
-
target_active_slots:
|
|
48
|
+
target_active_slots: number;
|
|
49
|
+
requested_work_items: number;
|
|
50
|
+
actual_total_work_items: number;
|
|
51
|
+
minimum_work_items: number;
|
|
52
|
+
task_graph_total_work_items: number;
|
|
53
|
+
work_queue_total_work_items: number;
|
|
54
|
+
scheduler_total_work_items: number;
|
|
55
|
+
task_graph_matches_cli_options: boolean;
|
|
56
|
+
work_queue_matches_task_graph: boolean;
|
|
57
|
+
scheduler_matches_work_queue: boolean;
|
|
39
58
|
max_observed_active_slots: any;
|
|
40
59
|
pending_queue_drained: boolean;
|
|
41
60
|
backfill_count: any;
|
|
42
61
|
expected_backfill_count: any;
|
|
62
|
+
backfill_expected_for_route: boolean;
|
|
43
63
|
slot_count: any;
|
|
44
64
|
generation_count: number;
|
|
45
65
|
all_slots_closed_after_drain: boolean;
|
|
46
66
|
generated_work_item_count: any;
|
|
47
67
|
source_intelligence_generation_refs_ok: boolean;
|
|
48
68
|
goal_mode_generation_refs_ok: boolean;
|
|
69
|
+
task_graph_source_refs_ok: any;
|
|
70
|
+
task_graph_goal_refs_ok: any;
|
|
71
|
+
work_queue_source_refs_ok: any;
|
|
72
|
+
work_queue_goal_refs_ok: any;
|
|
49
73
|
tmux_lane_manifest: string;
|
|
50
74
|
tmux_lane_manifest_ok: boolean;
|
|
51
75
|
tmux_lane_supervisor: string;
|
|
76
|
+
lane_supervisor_integrated: boolean;
|
|
52
77
|
tmux_lane_no_flicker_verified: boolean;
|
|
53
78
|
tmux_lane_survival_checked: boolean;
|
|
54
79
|
tmux_lane_unexpected_close_count: number;
|
|
55
80
|
tmux_lane_auto_reopen_count: number;
|
|
56
81
|
tmux_pane_launch_ledger: string;
|
|
57
82
|
tmux_pane_launch_count: number;
|
|
83
|
+
terminal_reports_match_generations: boolean;
|
|
58
84
|
ledger_hash_chain_ok: boolean;
|
|
59
85
|
no_overlap_ok: boolean;
|
|
60
86
|
consensus_ok: boolean;
|
|
@@ -15,6 +15,7 @@ export async function writeAgentProofEvidence(root, input) {
|
|
|
15
15
|
const laneSupervisor = await readTmuxLaneSupervisor(root);
|
|
16
16
|
const workQueue = await readJson(path.join(root, 'agent-work-queue.json'), null);
|
|
17
17
|
const scheduler = input.scheduler || await readJson(path.join(root, 'agent-scheduler-state.json'), null);
|
|
18
|
+
const taskGraph = input.partition?.task_graph || await readJson(path.join(root, 'agent-task-graph.json'), null);
|
|
18
19
|
const slots = await readJson(path.join(root, 'agent-worker-slots.json'), null);
|
|
19
20
|
const generationArtifact = await readJson(path.join(root, 'agent-session-generations.json'), null);
|
|
20
21
|
const schedulerEvents = await readTextSafe(path.join(root, 'agent-scheduler-events.jsonl'));
|
|
@@ -23,6 +24,25 @@ export async function writeAgentProofEvidence(root, input) {
|
|
|
23
24
|
const terminalCloseReportCount = terminal.total_sessions || 0;
|
|
24
25
|
const generationCount = generations.generation_count || 0;
|
|
25
26
|
const finalWorkItemCount = Number(scheduler?.completed_count || 0) + Number(scheduler?.failed_count || 0) + Number(scheduler?.blocked_count || 0);
|
|
27
|
+
const requestedWorkItems = Number(input.requestedWorkItems || taskGraph?.desired_work_items || taskGraph?.total_work_items || 0);
|
|
28
|
+
const taskGraphTotalWorkItems = Number(taskGraph?.total_work_items || 0);
|
|
29
|
+
const workQueueTotalWorkItems = Number(workQueue?.total_work_items || 0);
|
|
30
|
+
const schedulerTotalWorkItems = Number(scheduler?.total_work_items || 0);
|
|
31
|
+
const targetActiveSlots = Number(input.targetActiveSlots || scheduler?.target_active_slots || taskGraph?.target_active_slots || input.roster?.agent_count || 0);
|
|
32
|
+
const minimumWorkItems = Number(input.minimumWorkItems || taskGraph?.minimum_work_items || targetActiveSlots || 0);
|
|
33
|
+
const taskGraphMatchesCliOptions = Boolean(taskGraph) && requestedWorkItems === taskGraphTotalWorkItems && targetActiveSlots === Number(taskGraph.target_active_slots || 0);
|
|
34
|
+
const workQueueMatchesTaskGraph = Boolean(workQueue && taskGraph) && workQueueTotalWorkItems === taskGraphTotalWorkItems;
|
|
35
|
+
const schedulerMatchesWorkQueue = Boolean(scheduler && workQueue) && schedulerTotalWorkItems === workQueueTotalWorkItems;
|
|
36
|
+
const terminalReportsMatchGenerations = terminalCloseReportCount >= generationCount;
|
|
37
|
+
const taskGraphSourceRefsOk = Boolean(taskGraph?.work_items?.length) && taskGraph.work_items.every((item) => item.source_intelligence_refs);
|
|
38
|
+
const taskGraphGoalRefsOk = Boolean(taskGraph?.work_items?.length) && taskGraph.work_items.every((item) => item.goal_mode_ref);
|
|
39
|
+
const workQueueSourceRefsOk = Boolean(workQueue?.items?.length) && workQueue.items.every((item) => item.source_intelligence_refs);
|
|
40
|
+
const workQueueGoalRefsOk = Boolean(workQueue?.items?.length) && workQueue.items.every((item) => item.goal_mode_ref);
|
|
41
|
+
const route = String(input.route || taskGraph?.route_type || '$Agent');
|
|
42
|
+
const routeCommand = String(input.routeCommand || 'sks agent run');
|
|
43
|
+
const genericAgentRouteStandIn = !/\$?agent$/i.test(route) && /\bagent\s+run\b/i.test(routeCommand) && /--route/i.test(routeCommand);
|
|
44
|
+
const realRouteCommandUsed = !genericAgentRouteStandIn;
|
|
45
|
+
const laneSupervisorIntegrated = Boolean(laneSupervisor);
|
|
26
46
|
const blockers = [
|
|
27
47
|
...(lifecycle.ok ? [] : ['agent_lifecycle_not_all_closed']),
|
|
28
48
|
...(lifecycle.ok ? [] : lifecycle.open_sessions.map((id) => 'session_open:' + id)),
|
|
@@ -40,6 +60,14 @@ export async function writeAgentProofEvidence(root, input) {
|
|
|
40
60
|
...(scheduler && Number(scheduler.active_slot_count || 0) !== 0 ? ['scheduler_active_slots_not_zero_at_finalization'] : []),
|
|
41
61
|
...(scheduler && Number(scheduler.expected_backfill_count || 0) > Number(scheduler.backfill_count || 0) ? ['scheduler_backfill_count_below_expected'] : []),
|
|
42
62
|
...(scheduler && Number(scheduler.total_work_items || 0) >= Number(scheduler.target_active_slots || 0) && Number(scheduler.max_observed_active_slots || 0) !== Number(scheduler.target_active_slots || 0) ? ['scheduler_max_observed_active_slots_mismatch'] : []),
|
|
63
|
+
...(taskGraph && !taskGraphMatchesCliOptions ? ['task_graph_cli_options_mismatch'] : []),
|
|
64
|
+
...(workQueue && taskGraph && !workQueueMatchesTaskGraph ? ['work_queue_task_graph_mismatch'] : []),
|
|
65
|
+
...(scheduler && workQueue && !schedulerMatchesWorkQueue ? ['scheduler_work_queue_mismatch'] : []),
|
|
66
|
+
...(taskGraph && !taskGraphSourceRefsOk ? ['task_graph_source_refs_missing'] : []),
|
|
67
|
+
...(taskGraph && !taskGraphGoalRefsOk ? ['task_graph_goal_refs_missing'] : []),
|
|
68
|
+
...(workQueue && !workQueueSourceRefsOk ? ['work_queue_source_refs_missing'] : []),
|
|
69
|
+
...(workQueue && !workQueueGoalRefsOk ? ['work_queue_goal_refs_missing'] : []),
|
|
70
|
+
...(genericAgentRouteStandIn ? ['non_agent_route_used_generic_agent_run_route_standin'] : []),
|
|
43
71
|
...(generationCount < finalWorkItemCount ? ['session_generation_count_below_finished_work_items'] : []),
|
|
44
72
|
...(terminalCloseReportCount < generationCount ? ['terminal_close_report_count_below_generation_count'] : []),
|
|
45
73
|
...(slots && slots.all_slots_closed_after_drain !== true ? ['agent_worker_slots_not_closed_after_drain'] : []),
|
|
@@ -64,6 +92,10 @@ export async function writeAgentProofEvidence(root, input) {
|
|
|
64
92
|
generated_at: nowIso(),
|
|
65
93
|
mission_id: input.missionId,
|
|
66
94
|
backend: input.backend,
|
|
95
|
+
route,
|
|
96
|
+
route_command: routeCommand,
|
|
97
|
+
route_blackbox_kind: input.routeBlackboxKind || (realRouteCommandUsed ? 'actual_route_command' : 'generic_agent_route_standin'),
|
|
98
|
+
real_route_command_used: realRouteCommandUsed,
|
|
67
99
|
real_parallel_claim: input.realParallel === true && input.backend === 'codex-exec',
|
|
68
100
|
fake_backend_disclaimer: input.backend === 'fake' ? 'fixture only; no real parallel execution claim' : null,
|
|
69
101
|
agent_count: input.roster?.agent_count || input.results?.length || 0,
|
|
@@ -79,26 +111,42 @@ export async function writeAgentProofEvidence(root, input) {
|
|
|
79
111
|
session_generation_count: generations.generation_count,
|
|
80
112
|
all_generations_closed: generations.ok,
|
|
81
113
|
scheduler_state: 'agent-scheduler-state.json',
|
|
82
|
-
target_active_slots:
|
|
114
|
+
target_active_slots: targetActiveSlots,
|
|
115
|
+
requested_work_items: requestedWorkItems,
|
|
116
|
+
actual_total_work_items: taskGraphTotalWorkItems || schedulerTotalWorkItems,
|
|
117
|
+
minimum_work_items: minimumWorkItems,
|
|
118
|
+
task_graph_total_work_items: taskGraphTotalWorkItems,
|
|
119
|
+
work_queue_total_work_items: workQueueTotalWorkItems,
|
|
120
|
+
scheduler_total_work_items: schedulerTotalWorkItems,
|
|
121
|
+
task_graph_matches_cli_options: taskGraphMatchesCliOptions,
|
|
122
|
+
work_queue_matches_task_graph: workQueueMatchesTaskGraph,
|
|
123
|
+
scheduler_matches_work_queue: schedulerMatchesWorkQueue,
|
|
83
124
|
max_observed_active_slots: scheduler?.max_observed_active_slots || 0,
|
|
84
125
|
pending_queue_drained: scheduler?.pending_queue_drained === true,
|
|
85
126
|
backfill_count: scheduler?.backfill_count || 0,
|
|
86
127
|
expected_backfill_count: scheduler?.expected_backfill_count || 0,
|
|
128
|
+
backfill_expected_for_route: Number(scheduler?.expected_backfill_count || 0) > 0,
|
|
87
129
|
slot_count: slots?.slot_count || 0,
|
|
88
130
|
generation_count: generationCount,
|
|
89
131
|
all_slots_closed_after_drain: slots?.all_slots_closed_after_drain === true,
|
|
90
132
|
generated_work_item_count: scheduler?.generated_work_item_count || 0,
|
|
91
133
|
source_intelligence_generation_refs_ok: generations.missing_source_intelligence_refs.length === 0,
|
|
92
134
|
goal_mode_generation_refs_ok: generations.missing_goal_mode_refs.length === 0,
|
|
135
|
+
task_graph_source_refs_ok: taskGraphSourceRefsOk,
|
|
136
|
+
task_graph_goal_refs_ok: taskGraphGoalRefsOk,
|
|
137
|
+
work_queue_source_refs_ok: workQueueSourceRefsOk,
|
|
138
|
+
work_queue_goal_refs_ok: workQueueGoalRefsOk,
|
|
93
139
|
tmux_lane_manifest: 'agent-tmux-lanes.json',
|
|
94
140
|
tmux_lane_manifest_ok: tmuxLanes?.ok === true,
|
|
95
141
|
tmux_lane_supervisor: 'agent-tmux-lane-supervisor.json',
|
|
142
|
+
lane_supervisor_integrated: laneSupervisorIntegrated,
|
|
96
143
|
tmux_lane_no_flicker_verified: laneSupervisor?.no_flicker_verified === true,
|
|
97
144
|
tmux_lane_survival_checked: laneSupervisor?.pane_survival_checked === true,
|
|
98
145
|
tmux_lane_unexpected_close_count: laneSupervisor?.unexpected_close_count || 0,
|
|
99
146
|
tmux_lane_auto_reopen_count: laneSupervisor?.auto_reopen_count || 0,
|
|
100
147
|
tmux_pane_launch_ledger: 'agent-tmux-pane-launch-ledger.jsonl',
|
|
101
148
|
tmux_pane_launch_count: tmuxPaneLaunchCount,
|
|
149
|
+
terminal_reports_match_generations: terminalReportsMatchGenerations,
|
|
102
150
|
ledger_hash_chain_ok: ledger.ok,
|
|
103
151
|
no_overlap_ok: input.partition?.no_overlap_proof?.ok !== false,
|
|
104
152
|
consensus_ok: input.consensus?.ok === true,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import { appendJsonl, runProcess, writeJsonAtomic } from '../fsx.js';
|
|
2
|
+
import { appendJsonl, readJson, runProcess, writeJsonAtomic } from '../fsx.js';
|
|
3
3
|
import { validateAgentWorkerResult } from './agent-worker-pipeline.js';
|
|
4
4
|
export function buildTmuxAgentPanePlan(agent, slice = {}) {
|
|
5
5
|
const agentId = String(agent?.id || 'agent');
|
|
@@ -68,6 +68,13 @@ async function writeAgentTmuxReport(root, agent, report) {
|
|
|
68
68
|
async function launchTmuxPane(agent, slice, opts = {}) {
|
|
69
69
|
const root = opts.agentRoot || opts.cwd || process.cwd();
|
|
70
70
|
const sessionName = opts.tmuxSessionName || (opts.missionId ? `sks-${opts.missionId}` : 'sks-agent-runtime');
|
|
71
|
+
const supervisorEvidence = await recordSupervisorLaneEvidence(root, agent, slice, sessionName);
|
|
72
|
+
if (supervisorEvidence)
|
|
73
|
+
return supervisorEvidence;
|
|
74
|
+
if (opts.real === true) {
|
|
75
|
+
const blocked = fakeLaunch(agent, sessionName, '', ['tmux_lane_supervisor_missing_for_real_tmux']);
|
|
76
|
+
return { ...blocked, blockers: ['tmux_lane_supervisor_missing_for_real_tmux'] };
|
|
77
|
+
}
|
|
71
78
|
const title = `${agent.slot_id || agent.id} gen-${agent.generation_index || 1} ${slice?.id || 'work'}`;
|
|
72
79
|
const laneFile = path.join(root, 'lanes', String(agent.slot_id || agent.id), 'lane.md');
|
|
73
80
|
const drainFile = path.join(root, 'lanes', '.drain');
|
|
@@ -109,6 +116,33 @@ async function launchTmuxPane(agent, slice, opts = {}) {
|
|
|
109
116
|
await appendJsonl(path.join(root, 'agent-tmux-pane-launch-ledger.jsonl'), evidence);
|
|
110
117
|
return evidence;
|
|
111
118
|
}
|
|
119
|
+
async function recordSupervisorLaneEvidence(root, agent, slice, sessionName) {
|
|
120
|
+
const supervisor = await readJson(path.join(root, 'agent-tmux-lane-supervisor.json'), null);
|
|
121
|
+
const slotId = String(agent.slot_id || agent.id);
|
|
122
|
+
const lane = supervisor?.lanes?.find((row) => String(row.slot_id) === slotId);
|
|
123
|
+
if (!lane?.pane_id)
|
|
124
|
+
return null;
|
|
125
|
+
const evidence = {
|
|
126
|
+
schema: 'sks.agent-tmux-pane-launch.v1',
|
|
127
|
+
generated_at: new Date().toISOString(),
|
|
128
|
+
launch_mode: lane.launch_mode || 'supervisor_slot_lane',
|
|
129
|
+
agent_id: agent.id,
|
|
130
|
+
slot_id: slotId,
|
|
131
|
+
generation_index: agent.generation_index || 1,
|
|
132
|
+
session_id: agent.session_id,
|
|
133
|
+
session_name: supervisor.session_name || sessionName,
|
|
134
|
+
window_id: null,
|
|
135
|
+
pane_id: lane.pane_id,
|
|
136
|
+
command: lane.command,
|
|
137
|
+
attach_command: `tmux attach -t ${supervisor.session_name || sessionName}`,
|
|
138
|
+
persistent_slot_lane: true,
|
|
139
|
+
reused_persistent_slot_lane: true,
|
|
140
|
+
work_item_id: slice?.id || null,
|
|
141
|
+
blockers: lane.launch_error ? [`tmux_lane_launch_error:${lane.launch_error}`] : []
|
|
142
|
+
};
|
|
143
|
+
await appendJsonl(path.join(root, 'agent-tmux-pane-launch-ledger.jsonl'), evidence);
|
|
144
|
+
return evidence;
|
|
145
|
+
}
|
|
112
146
|
function fakeLaunch(agent, sessionName, command, warnings) {
|
|
113
147
|
const paneId = `fake-pane-${String(agent.slot_id || agent.id)}`;
|
|
114
148
|
return {
|
|
@@ -71,6 +71,8 @@ export interface AgentRunOptions {
|
|
|
71
71
|
desiredWorkItemCount?: number;
|
|
72
72
|
minimumWorkItems?: number;
|
|
73
73
|
maxQueueExpansion?: number;
|
|
74
|
+
routeCommand?: string;
|
|
75
|
+
routeBlackboxKind?: string;
|
|
74
76
|
refillDelayMs?: number;
|
|
75
77
|
roster?: unknown;
|
|
76
78
|
backend?: AgentBackend | string;
|
|
@@ -63,6 +63,8 @@ export declare function writeRouteCollaborationArtifacts(root: string, opts: {
|
|
|
63
63
|
ok: boolean;
|
|
64
64
|
mission_id: any;
|
|
65
65
|
route: string;
|
|
66
|
+
route_command: string;
|
|
67
|
+
route_blackbox_kind: string;
|
|
66
68
|
backend: "tmux" | "fake" | "process" | "codex-exec";
|
|
67
69
|
ledger_root: string;
|
|
68
70
|
roster: {
|
|
@@ -120,6 +122,10 @@ export declare function writeRouteCollaborationArtifacts(root: string, opts: {
|
|
|
120
122
|
generated_from_route: string;
|
|
121
123
|
work_items_exceed_active_slots: boolean;
|
|
122
124
|
};
|
|
125
|
+
requested_work_items: number;
|
|
126
|
+
actual_total_work_items: number;
|
|
127
|
+
target_active_slots: number;
|
|
128
|
+
minimum_work_items: number;
|
|
123
129
|
scheduler: {
|
|
124
130
|
schema: string;
|
|
125
131
|
ok: boolean;
|
|
@@ -278,6 +284,10 @@ export declare function writeRouteCollaborationArtifacts(root: string, opts: {
|
|
|
278
284
|
generated_at: string;
|
|
279
285
|
mission_id: string;
|
|
280
286
|
backend: string;
|
|
287
|
+
route: string;
|
|
288
|
+
route_command: string;
|
|
289
|
+
route_blackbox_kind: string;
|
|
290
|
+
real_route_command_used: boolean;
|
|
281
291
|
real_parallel_claim: boolean;
|
|
282
292
|
fake_backend_disclaimer: string | null;
|
|
283
293
|
agent_count: any;
|
|
@@ -293,26 +303,42 @@ export declare function writeRouteCollaborationArtifacts(root: string, opts: {
|
|
|
293
303
|
session_generation_count: number;
|
|
294
304
|
all_generations_closed: boolean;
|
|
295
305
|
scheduler_state: string;
|
|
296
|
-
target_active_slots:
|
|
306
|
+
target_active_slots: number;
|
|
307
|
+
requested_work_items: number;
|
|
308
|
+
actual_total_work_items: number;
|
|
309
|
+
minimum_work_items: number;
|
|
310
|
+
task_graph_total_work_items: number;
|
|
311
|
+
work_queue_total_work_items: number;
|
|
312
|
+
scheduler_total_work_items: number;
|
|
313
|
+
task_graph_matches_cli_options: boolean;
|
|
314
|
+
work_queue_matches_task_graph: boolean;
|
|
315
|
+
scheduler_matches_work_queue: boolean;
|
|
297
316
|
max_observed_active_slots: any;
|
|
298
317
|
pending_queue_drained: boolean;
|
|
299
318
|
backfill_count: any;
|
|
300
319
|
expected_backfill_count: any;
|
|
320
|
+
backfill_expected_for_route: boolean;
|
|
301
321
|
slot_count: any;
|
|
302
322
|
generation_count: number;
|
|
303
323
|
all_slots_closed_after_drain: boolean;
|
|
304
324
|
generated_work_item_count: any;
|
|
305
325
|
source_intelligence_generation_refs_ok: boolean;
|
|
306
326
|
goal_mode_generation_refs_ok: boolean;
|
|
327
|
+
task_graph_source_refs_ok: any;
|
|
328
|
+
task_graph_goal_refs_ok: any;
|
|
329
|
+
work_queue_source_refs_ok: any;
|
|
330
|
+
work_queue_goal_refs_ok: any;
|
|
307
331
|
tmux_lane_manifest: string;
|
|
308
332
|
tmux_lane_manifest_ok: boolean;
|
|
309
333
|
tmux_lane_supervisor: string;
|
|
334
|
+
lane_supervisor_integrated: boolean;
|
|
310
335
|
tmux_lane_no_flicker_verified: boolean;
|
|
311
336
|
tmux_lane_survival_checked: boolean;
|
|
312
337
|
tmux_lane_unexpected_close_count: number;
|
|
313
338
|
tmux_lane_auto_reopen_count: number;
|
|
314
339
|
tmux_pane_launch_ledger: string;
|
|
315
340
|
tmux_pane_launch_count: number;
|
|
341
|
+
terminal_reports_match_generations: boolean;
|
|
316
342
|
ledger_hash_chain_ok: boolean;
|
|
317
343
|
no_overlap_ok: boolean;
|
|
318
344
|
consensus_ok: boolean;
|
|
@@ -8,6 +8,8 @@ export interface TmuxLaneSupervisorLane {
|
|
|
8
8
|
lane_md: string;
|
|
9
9
|
lane_json: string;
|
|
10
10
|
command: string;
|
|
11
|
+
launch_mode: string;
|
|
12
|
+
launch_error: string | null;
|
|
11
13
|
opened_at: string;
|
|
12
14
|
closed_at: string | null;
|
|
13
15
|
unexpected_close_count: number;
|
|
@@ -37,6 +39,7 @@ export declare function initializeTmuxLaneSupervisor(root: string, input: {
|
|
|
37
39
|
missionId: string;
|
|
38
40
|
sessionName?: string;
|
|
39
41
|
targetActiveSlots: number;
|
|
42
|
+
launchRealTmux?: boolean;
|
|
40
43
|
}): Promise<TmuxLaneSupervisorState>;
|
|
41
44
|
export declare function updateTmuxLaneSupervisorFromSlots(root: string, input: {
|
|
42
45
|
missionId: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import { appendJsonl, ensureDir, nowIso, readJson, writeJsonAtomic, writeTextAtomic } from '../fsx.js';
|
|
2
|
+
import { appendJsonl, ensureDir, nowIso, readJson, runProcess, writeJsonAtomic, writeTextAtomic } from '../fsx.js';
|
|
3
3
|
export const TMUX_LANE_SUPERVISOR_SCHEMA = 'sks.tmux-lane-supervisor.v1';
|
|
4
4
|
export async function initializeTmuxLaneSupervisor(root, input) {
|
|
5
5
|
const now = nowIso();
|
|
@@ -17,7 +17,7 @@ export async function initializeTmuxLaneSupervisor(root, input) {
|
|
|
17
17
|
auto_reopen_count: 0,
|
|
18
18
|
all_lanes_closed_after_drain: false,
|
|
19
19
|
blockers: [],
|
|
20
|
-
lanes:
|
|
20
|
+
lanes: await createSupervisorLanes(root, input.missionId, sessionName, input.targetActiveSlots, now, input.launchRealTmux === true)
|
|
21
21
|
};
|
|
22
22
|
for (const lane of state.lanes)
|
|
23
23
|
await writeLaneRender(root, lane, null, null);
|
|
@@ -117,6 +117,8 @@ function createLane(missionId, sessionName, index, openedAt) {
|
|
|
117
117
|
lane_md: path.join(laneDir, 'lane.md'),
|
|
118
118
|
lane_json: path.join(laneDir, 'lane.json'),
|
|
119
119
|
command: buildPersistentLaneCommand(missionId, slotId),
|
|
120
|
+
launch_mode: 'fake_supervisor_lane',
|
|
121
|
+
launch_error: null,
|
|
120
122
|
opened_at: openedAt,
|
|
121
123
|
closed_at: null,
|
|
122
124
|
unexpected_close_count: 0,
|
|
@@ -128,11 +130,64 @@ function createLane(missionId, sessionName, index, openedAt) {
|
|
|
128
130
|
drained: false
|
|
129
131
|
};
|
|
130
132
|
}
|
|
133
|
+
async function createSupervisorLanes(root, missionId, sessionName, targetActiveSlots, openedAt, launchRealTmux) {
|
|
134
|
+
const lanes = [];
|
|
135
|
+
if (launchRealTmux)
|
|
136
|
+
await ensureTmuxSession(sessionName).catch(() => null);
|
|
137
|
+
for (let index = 1; index <= targetActiveSlots; index += 1) {
|
|
138
|
+
const lane = createLane(missionId, sessionName, index, openedAt);
|
|
139
|
+
if (launchRealTmux)
|
|
140
|
+
lanes.push(await launchPersistentSlotLane(root, lane, sessionName));
|
|
141
|
+
else
|
|
142
|
+
lanes.push(lane);
|
|
143
|
+
}
|
|
144
|
+
return lanes;
|
|
145
|
+
}
|
|
146
|
+
async function ensureTmuxSession(sessionName) {
|
|
147
|
+
await runProcess('tmux', ['has-session', '-t', sessionName], { timeoutMs: 1000, maxOutputBytes: 4096 }).catch(async () => {
|
|
148
|
+
await runProcess('tmux', ['new-session', '-d', '-s', sessionName, '-n', 'orchestrator', 'sleep 3600'], { timeoutMs: 2000, maxOutputBytes: 4096 });
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
async function launchPersistentSlotLane(root, lane, sessionName) {
|
|
152
|
+
const command = persistentLaneCommandForRoot(root, lane.slot_id);
|
|
153
|
+
try {
|
|
154
|
+
const pane = await runProcess('tmux', ['split-window', '-t', sessionName, '-P', '-F', '#{pane_id}', '-h', command], { timeoutMs: 2000, maxOutputBytes: 4096 });
|
|
155
|
+
const paneId = pane.stdout.trim() || `%${Date.now()}`;
|
|
156
|
+
await appendJsonl(path.join(root, 'agent-tmux-pane-launch-ledger.jsonl'), {
|
|
157
|
+
schema: 'sks.agent-tmux-pane-launch.v1',
|
|
158
|
+
generated_at: nowIso(),
|
|
159
|
+
launch_mode: 'real_tmux_supervisor_slot_lane',
|
|
160
|
+
slot_id: lane.slot_id,
|
|
161
|
+
generation_index: null,
|
|
162
|
+
session_id: null,
|
|
163
|
+
session_name: sessionName,
|
|
164
|
+
pane_id: paneId,
|
|
165
|
+
command,
|
|
166
|
+
persistent_slot_lane: true,
|
|
167
|
+
launched_by: TMUX_LANE_SUPERVISOR_SCHEMA,
|
|
168
|
+
blockers: []
|
|
169
|
+
});
|
|
170
|
+
return { ...lane, pane_id: paneId, command, launch_mode: 'real_tmux_supervisor_slot_lane', launch_error: null };
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
return {
|
|
174
|
+
...lane,
|
|
175
|
+
command,
|
|
176
|
+
launch_mode: 'real_tmux_supervisor_failed',
|
|
177
|
+
launch_error: err instanceof Error ? err.message : String(err)
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
131
181
|
function buildPersistentLaneCommand(missionId, slotId) {
|
|
132
182
|
const laneMd = path.join('agents', 'lanes', slotId, 'lane.md');
|
|
133
183
|
const drain = path.join('agents', 'lanes', '.drain');
|
|
134
184
|
return `while test ! -f ${JSON.stringify(drain)}; do clear; printf '%s\\n' ${JSON.stringify(`SKS ${missionId} ${slotId}`)}; test -f ${JSON.stringify(laneMd)} && cat ${JSON.stringify(laneMd)}; sleep 2; done`;
|
|
135
185
|
}
|
|
186
|
+
function persistentLaneCommandForRoot(root, slotId) {
|
|
187
|
+
const laneFile = path.join(root, 'lanes', slotId, 'lane.md');
|
|
188
|
+
const drainFile = path.join(root, 'lanes', '.drain');
|
|
189
|
+
return `while test ! -f ${JSON.stringify(drainFile)}; do clear; test -f ${JSON.stringify(laneFile)} && cat ${JSON.stringify(laneFile)}; sleep 2; done`;
|
|
190
|
+
}
|
|
136
191
|
async function writeLaneRender(root, lane, slot, state) {
|
|
137
192
|
const laneJson = {
|
|
138
193
|
schema: 'sks.tmux-lane-render.v1',
|
|
@@ -190,6 +245,7 @@ function summarizeSupervisor(state) {
|
|
|
190
245
|
all_lanes_closed_after_drain: state.lanes.length > 0 && state.lanes.every((lane) => lane.drained && Boolean(lane.closed_at)),
|
|
191
246
|
blockers: [
|
|
192
247
|
...(unexpected > 0 ? ['tmux_lane_unexpected_close_before_drain'] : []),
|
|
248
|
+
...(state.lanes.some((lane) => lane.launch_mode === 'real_tmux_supervisor_failed') ? ['tmux_lane_real_launch_failed'] : []),
|
|
193
249
|
...(state.lanes.some((lane) => lane.closed_at && !lane.drained) ? ['tmux_lane_closed_before_drain'] : [])
|
|
194
250
|
]
|
|
195
251
|
};
|
|
@@ -16,7 +16,7 @@ export async function agentCommand(commandOrArgs = 'agent', maybeArgs = []) {
|
|
|
16
16
|
return agentMissionAction(parsed);
|
|
17
17
|
}
|
|
18
18
|
async function agentRun(parsed) {
|
|
19
|
-
const result = await runNativeAgentOrchestrator(parsed);
|
|
19
|
+
const result = await runNativeAgentOrchestrator({ ...parsed, routeCommand: 'sks agent run', routeBlackboxKind: 'actual_agent_command' });
|
|
20
20
|
return emit(parsed, result, () => {
|
|
21
21
|
console.log('Native agent mission: ' + result.mission_id);
|
|
22
22
|
console.log('Backend: ' + result.backend);
|
|
@@ -385,6 +385,8 @@ export declare function imageUxReviewCommand(command: any, args?: any): Promise<
|
|
|
385
385
|
ok: boolean;
|
|
386
386
|
mission_id: any;
|
|
387
387
|
route: string;
|
|
388
|
+
route_command: string;
|
|
389
|
+
route_blackbox_kind: string;
|
|
388
390
|
backend: "tmux" | "fake" | "process" | "codex-exec";
|
|
389
391
|
ledger_root: string;
|
|
390
392
|
roster: {
|
|
@@ -442,6 +444,10 @@ export declare function imageUxReviewCommand(command: any, args?: any): Promise<
|
|
|
442
444
|
generated_from_route: string;
|
|
443
445
|
work_items_exceed_active_slots: boolean;
|
|
444
446
|
};
|
|
447
|
+
requested_work_items: number;
|
|
448
|
+
actual_total_work_items: number;
|
|
449
|
+
target_active_slots: number;
|
|
450
|
+
minimum_work_items: number;
|
|
445
451
|
scheduler: {
|
|
446
452
|
schema: string;
|
|
447
453
|
ok: boolean;
|
|
@@ -600,6 +606,10 @@ export declare function imageUxReviewCommand(command: any, args?: any): Promise<
|
|
|
600
606
|
generated_at: string;
|
|
601
607
|
mission_id: string;
|
|
602
608
|
backend: string;
|
|
609
|
+
route: string;
|
|
610
|
+
route_command: string;
|
|
611
|
+
route_blackbox_kind: string;
|
|
612
|
+
real_route_command_used: boolean;
|
|
603
613
|
real_parallel_claim: boolean;
|
|
604
614
|
fake_backend_disclaimer: string | null;
|
|
605
615
|
agent_count: any;
|
|
@@ -615,26 +625,42 @@ export declare function imageUxReviewCommand(command: any, args?: any): Promise<
|
|
|
615
625
|
session_generation_count: number;
|
|
616
626
|
all_generations_closed: boolean;
|
|
617
627
|
scheduler_state: string;
|
|
618
|
-
target_active_slots:
|
|
628
|
+
target_active_slots: number;
|
|
629
|
+
requested_work_items: number;
|
|
630
|
+
actual_total_work_items: number;
|
|
631
|
+
minimum_work_items: number;
|
|
632
|
+
task_graph_total_work_items: number;
|
|
633
|
+
work_queue_total_work_items: number;
|
|
634
|
+
scheduler_total_work_items: number;
|
|
635
|
+
task_graph_matches_cli_options: boolean;
|
|
636
|
+
work_queue_matches_task_graph: boolean;
|
|
637
|
+
scheduler_matches_work_queue: boolean;
|
|
619
638
|
max_observed_active_slots: any;
|
|
620
639
|
pending_queue_drained: boolean;
|
|
621
640
|
backfill_count: any;
|
|
622
641
|
expected_backfill_count: any;
|
|
642
|
+
backfill_expected_for_route: boolean;
|
|
623
643
|
slot_count: any;
|
|
624
644
|
generation_count: number;
|
|
625
645
|
all_slots_closed_after_drain: boolean;
|
|
626
646
|
generated_work_item_count: any;
|
|
627
647
|
source_intelligence_generation_refs_ok: boolean;
|
|
628
648
|
goal_mode_generation_refs_ok: boolean;
|
|
649
|
+
task_graph_source_refs_ok: any;
|
|
650
|
+
task_graph_goal_refs_ok: any;
|
|
651
|
+
work_queue_source_refs_ok: any;
|
|
652
|
+
work_queue_goal_refs_ok: any;
|
|
629
653
|
tmux_lane_manifest: string;
|
|
630
654
|
tmux_lane_manifest_ok: boolean;
|
|
631
655
|
tmux_lane_supervisor: string;
|
|
656
|
+
lane_supervisor_integrated: boolean;
|
|
632
657
|
tmux_lane_no_flicker_verified: boolean;
|
|
633
658
|
tmux_lane_survival_checked: boolean;
|
|
634
659
|
tmux_lane_unexpected_close_count: number;
|
|
635
660
|
tmux_lane_auto_reopen_count: number;
|
|
636
661
|
tmux_pane_launch_ledger: string;
|
|
637
662
|
tmux_pane_launch_count: number;
|
|
663
|
+
terminal_reports_match_generations: boolean;
|
|
638
664
|
ledger_hash_chain_ok: boolean;
|
|
639
665
|
no_overlap_ok: boolean;
|
|
640
666
|
consensus_ok: boolean;
|
|
@@ -237,6 +237,8 @@ export declare function pptCommand(command: any, args?: any): Promise<void | {
|
|
|
237
237
|
ok: boolean;
|
|
238
238
|
mission_id: any;
|
|
239
239
|
route: string;
|
|
240
|
+
route_command: string;
|
|
241
|
+
route_blackbox_kind: string;
|
|
240
242
|
backend: "tmux" | "fake" | "process" | "codex-exec";
|
|
241
243
|
ledger_root: string;
|
|
242
244
|
roster: {
|
|
@@ -294,6 +296,10 @@ export declare function pptCommand(command: any, args?: any): Promise<void | {
|
|
|
294
296
|
generated_from_route: string;
|
|
295
297
|
work_items_exceed_active_slots: boolean;
|
|
296
298
|
};
|
|
299
|
+
requested_work_items: number;
|
|
300
|
+
actual_total_work_items: number;
|
|
301
|
+
target_active_slots: number;
|
|
302
|
+
minimum_work_items: number;
|
|
297
303
|
scheduler: {
|
|
298
304
|
schema: string;
|
|
299
305
|
ok: boolean;
|
|
@@ -452,6 +458,10 @@ export declare function pptCommand(command: any, args?: any): Promise<void | {
|
|
|
452
458
|
generated_at: string;
|
|
453
459
|
mission_id: string;
|
|
454
460
|
backend: string;
|
|
461
|
+
route: string;
|
|
462
|
+
route_command: string;
|
|
463
|
+
route_blackbox_kind: string;
|
|
464
|
+
real_route_command_used: boolean;
|
|
455
465
|
real_parallel_claim: boolean;
|
|
456
466
|
fake_backend_disclaimer: string | null;
|
|
457
467
|
agent_count: any;
|
|
@@ -467,26 +477,42 @@ export declare function pptCommand(command: any, args?: any): Promise<void | {
|
|
|
467
477
|
session_generation_count: number;
|
|
468
478
|
all_generations_closed: boolean;
|
|
469
479
|
scheduler_state: string;
|
|
470
|
-
target_active_slots:
|
|
480
|
+
target_active_slots: number;
|
|
481
|
+
requested_work_items: number;
|
|
482
|
+
actual_total_work_items: number;
|
|
483
|
+
minimum_work_items: number;
|
|
484
|
+
task_graph_total_work_items: number;
|
|
485
|
+
work_queue_total_work_items: number;
|
|
486
|
+
scheduler_total_work_items: number;
|
|
487
|
+
task_graph_matches_cli_options: boolean;
|
|
488
|
+
work_queue_matches_task_graph: boolean;
|
|
489
|
+
scheduler_matches_work_queue: boolean;
|
|
471
490
|
max_observed_active_slots: any;
|
|
472
491
|
pending_queue_drained: boolean;
|
|
473
492
|
backfill_count: any;
|
|
474
493
|
expected_backfill_count: any;
|
|
494
|
+
backfill_expected_for_route: boolean;
|
|
475
495
|
slot_count: any;
|
|
476
496
|
generation_count: number;
|
|
477
497
|
all_slots_closed_after_drain: boolean;
|
|
478
498
|
generated_work_item_count: any;
|
|
479
499
|
source_intelligence_generation_refs_ok: boolean;
|
|
480
500
|
goal_mode_generation_refs_ok: boolean;
|
|
501
|
+
task_graph_source_refs_ok: any;
|
|
502
|
+
task_graph_goal_refs_ok: any;
|
|
503
|
+
work_queue_source_refs_ok: any;
|
|
504
|
+
work_queue_goal_refs_ok: any;
|
|
481
505
|
tmux_lane_manifest: string;
|
|
482
506
|
tmux_lane_manifest_ok: boolean;
|
|
483
507
|
tmux_lane_supervisor: string;
|
|
508
|
+
lane_supervisor_integrated: boolean;
|
|
484
509
|
tmux_lane_no_flicker_verified: boolean;
|
|
485
510
|
tmux_lane_survival_checked: boolean;
|
|
486
511
|
tmux_lane_unexpected_close_count: number;
|
|
487
512
|
tmux_lane_auto_reopen_count: number;
|
|
488
513
|
tmux_pane_launch_ledger: string;
|
|
489
514
|
tmux_pane_launch_count: number;
|
|
515
|
+
terminal_reports_match_generations: boolean;
|
|
490
516
|
ledger_hash_chain_ok: boolean;
|
|
491
517
|
no_overlap_ok: boolean;
|
|
492
518
|
consensus_ok: boolean;
|
|
@@ -121,15 +121,19 @@ async function qaLoopRun(args) {
|
|
|
121
121
|
}
|
|
122
122
|
const fallbackCycles = Number.parseInt(contract.answers?.MAX_QA_CYCLES, 10) || 8;
|
|
123
123
|
const maxCycles = readMaxCycles(args, fallbackCycles);
|
|
124
|
-
const
|
|
124
|
+
const requestedAgents = readBoundedIntegerFlag(args, '--agents', 3, 1, 20);
|
|
125
|
+
const targetActiveSlots = readBoundedIntegerFlag(args, '--target-active-slots', requestedAgents, 1, 20);
|
|
125
126
|
const desiredWorkItemCount = readBoundedIntegerFlag(args, '--work-items', targetActiveSlots, 1, 200);
|
|
127
|
+
const minimumWorkItems = readBoundedIntegerFlag(args, '--minimum-work-items', targetActiveSlots, 1, 200);
|
|
128
|
+
const maxQueueExpansion = readBoundedIntegerFlag(args, '--max-queue-expansion', 10, 0, 200);
|
|
126
129
|
const mock = flag(args, '--mock');
|
|
127
130
|
const qaGate = await readJson(path.join(dir, 'qa-gate.json'), {});
|
|
128
131
|
const reportFile = qaGate.qa_report_file;
|
|
129
132
|
await setCurrent(root, { mission_id: id, route: 'QALoop', route_command: '$QA-LOOP', mode: 'QALOOP', phase: 'QALOOP_RUNNING_NO_QUESTIONS', questions_allowed: false, stop_gate: 'qa-gate.json', reasoning_effort: 'high', reasoning_profile: 'sks-logic-high', reasoning_temporary: true });
|
|
130
133
|
await appendJsonlBounded(path.join(dir, 'events.jsonl'), { ts: nowIso(), type: 'qaloop.run.started', maxCycles, mock });
|
|
131
134
|
const nativeAgentPlan = await readJson(path.join(dir, 'qa-agent-plan.json'), null);
|
|
132
|
-
const
|
|
135
|
+
const nativeRoster = requestedAgents === 3 ? nativeAgentPlan : null;
|
|
136
|
+
const nativeAgentRun = await runNativeAgentOrchestrator({ root, missionId: id, route: '$QA-LOOP', prompt: mission.prompt || 'QA-LOOP run', backend: mock ? 'fake' : 'codex-exec', mock, agents: requestedAgents, targetActiveSlots, desiredWorkItemCount, minimumWorkItems, maxQueueExpansion, concurrency: Math.min(requestedAgents, 5), readonly: true, roster: nativeRoster, routeCommand: 'sks qa-loop run', routeBlackboxKind: 'actual_qa_command' });
|
|
133
137
|
await writeJsonAtomic(path.join(dir, 'qa-native-agent-run.json'), nativeAgentRun);
|
|
134
138
|
await appendJsonlBounded(path.join(dir, 'events.jsonl'), { ts: nowIso(), type: 'qaloop.native_agents.completed', backend: nativeAgentRun.backend, ok: nativeAgentRun.ok, proof: nativeAgentRun.proof?.status });
|
|
135
139
|
if (mock) {
|
|
@@ -146,7 +150,7 @@ async function qaLoopRun(args) {
|
|
|
146
150
|
const proof = await maybeFinalizeRoute(root, { missionId: id, route: '$QA-LOOP', gateFile: 'qa-gate.json', gate: gate.gate || gate, artifacts: ['agents/agent-proof-evidence.json', 'qa-native-agent-run.json', 'qa-gate.json', 'qa-ledger.json', reportFile, 'completion-proof.json'], visual: needsVisual, mock, command: { cmd: `sks qa-loop run ${id} --mock`, status: 0 } });
|
|
147
151
|
await setCurrent(root, { mission_id: id, mode: 'QALOOP', phase: gate.passed ? 'QALOOP_DONE' : 'QALOOP_PAUSED', questions_allowed: true });
|
|
148
152
|
if (flag(args, '--json'))
|
|
149
|
-
return console.log(JSON.stringify({ schema: 'sks.qa-loop-run.v1', ok: proof.ok, mission_id: id, gate, proof: proof.validation }, null, 2));
|
|
153
|
+
return console.log(JSON.stringify({ schema: 'sks.qa-loop-run.v1', ok: proof.ok, mission_id: id, gate, proof: proof.validation, native_agent_run: nativeAgentRun }, null, 2));
|
|
150
154
|
console.log(`Mock QA-LOOP done: ${id}`);
|
|
151
155
|
console.log(`Gate: ${gate.passed ? 'passed' : 'blocked'}`);
|
|
152
156
|
return;
|
|
@@ -112,14 +112,17 @@ async function researchRun(args) {
|
|
|
112
112
|
return;
|
|
113
113
|
}
|
|
114
114
|
const maxCycles = readMaxCycles(args, RESEARCH_DEFAULT_MAX_CYCLES);
|
|
115
|
-
const
|
|
115
|
+
const requestedAgents = readBoundedIntegerFlag(args, '--agents', plan.native_agent_plan?.session_count || 5, 1, 20);
|
|
116
|
+
const targetActiveSlots = readBoundedIntegerFlag(args, '--target-active-slots', requestedAgents, 1, 20);
|
|
116
117
|
const desiredWorkItemCount = readBoundedIntegerFlag(args, '--work-items', targetActiveSlots, 1, 200);
|
|
118
|
+
const minimumWorkItems = readBoundedIntegerFlag(args, '--minimum-work-items', targetActiveSlots, 1, 200);
|
|
119
|
+
const maxQueueExpansion = readBoundedIntegerFlag(args, '--max-queue-expansion', 10, 0, 200);
|
|
117
120
|
const cycleTimeoutMinutes = readResearchCycleTimeoutMinutes(args);
|
|
118
121
|
const cycleTimeoutMs = cycleTimeoutMinutes * 60 * 1000;
|
|
119
122
|
const mock = flag(args, '--mock');
|
|
120
123
|
await setCurrent(root, { mission_id: id, mode: 'RESEARCH', phase: 'RESEARCH_RUNNING_NO_QUESTIONS', questions_allowed: false, implementation_allowed: false, research_real_run_required: !mock, research_cycle_timeout_minutes: cycleTimeoutMinutes });
|
|
121
124
|
await appendJsonlBounded(path.join(dir, 'events.jsonl'), { ts: nowIso(), type: 'research.run.started', maxCycles, mock, cycleTimeoutMinutes, real_run_required: !mock });
|
|
122
|
-
const nativeAgentRun = await runNativeAgentOrchestrator({ root, missionId: id, route: flag(args, '--autoresearch') ? '$AutoResearch' : '$Research', prompt: mission.prompt || plan.prompt || 'Research run', backend: mock ? 'fake' : 'codex-exec', mock, agents:
|
|
125
|
+
const nativeAgentRun = await runNativeAgentOrchestrator({ root, missionId: id, route: flag(args, '--autoresearch') ? '$AutoResearch' : '$Research', prompt: mission.prompt || plan.prompt || 'Research run', backend: mock ? 'fake' : 'codex-exec', mock, agents: requestedAgents, targetActiveSlots, desiredWorkItemCount, minimumWorkItems, maxQueueExpansion, concurrency: Math.min(requestedAgents, 5), readonly: true, roster: plan.native_agent_plan, routeCommand: 'sks research run', routeBlackboxKind: 'actual_research_command' });
|
|
123
126
|
await writeJsonAtomic(path.join(dir, 'research-native-agent-run.json'), nativeAgentRun);
|
|
124
127
|
await appendJsonlBounded(path.join(dir, 'events.jsonl'), { ts: nowIso(), type: 'research.native_agents.completed', backend: nativeAgentRun.backend, ok: nativeAgentRun.ok, proof: nativeAgentRun.proof?.status });
|
|
125
128
|
if (mock) {
|
|
@@ -130,7 +133,7 @@ async function researchRun(args) {
|
|
|
130
133
|
const proof = await maybeFinalizeRoute(root, { missionId: id, route: '$Research', gateFile: 'research-gate.json', gate: gate.gate || gate, artifacts: ['agents/agent-proof-evidence.json', 'research-native-agent-run.json', 'research-gate.json', 'research-report.md', researchPaperArtifactForPlan(plan), 'source-ledger.json', 'agent-ledger.json', 'debate-ledger.json', 'completion-proof.json'], mock, command: { cmd: `sks research run ${id} --mock`, status: 0 } });
|
|
131
134
|
await setCurrent(root, { mission_id: id, mode: 'RESEARCH', phase: gate.passed ? 'RESEARCH_DONE' : 'RESEARCH_PAUSED', questions_allowed: true, implementation_allowed: false });
|
|
132
135
|
if (flag(args, '--json'))
|
|
133
|
-
return console.log(JSON.stringify({ schema: flag(args, '--autoresearch') ? 'sks.autoresearch-run.v1' : 'sks.research-run.v1', ok: proof.ok, mission_id: id, gate, proof: proof.validation, agent_batches: plan.agent_batches, autoresearch_cycle_policy: plan.autoresearch_cycle_policy }, null, 2));
|
|
136
|
+
return console.log(JSON.stringify({ schema: flag(args, '--autoresearch') ? 'sks.autoresearch-run.v1' : 'sks.research-run.v1', ok: proof.ok, mission_id: id, gate, proof: proof.validation, native_agent_run: nativeAgentRun, agent_batches: plan.agent_batches, autoresearch_cycle_policy: plan.autoresearch_cycle_policy }, null, 2));
|
|
134
137
|
console.log(`Mock research done: ${id}`);
|
|
135
138
|
console.log(`Gate: ${gate.passed ? 'passed' : 'blocked'}`);
|
|
136
139
|
return;
|
|
@@ -30,6 +30,8 @@ export async function team(args = []) {
|
|
|
30
30
|
const { prompt, agentSessions, roleCounts, roster } = opts;
|
|
31
31
|
const targetActiveSlots = readBoundedIntegerFlag(args, '--target-active-slots', roster.bundle_size, 1, 20);
|
|
32
32
|
const desiredWorkItemCount = readBoundedIntegerFlag(args, '--work-items', targetActiveSlots, 1, 200);
|
|
33
|
+
const minimumWorkItems = readBoundedIntegerFlag(args, '--minimum-work-items', targetActiveSlots, 1, 200);
|
|
34
|
+
const maxQueueExpansion = readBoundedIntegerFlag(args, '--max-queue-expansion', 10, 0, 200);
|
|
33
35
|
if (!prompt) {
|
|
34
36
|
console.error('Usage: sks team "task" [20:agents] [executor:5 reviewer:6 user:1] [--agents N] [--work-items N] [--target-active-slots N] [--no-open-tmux] [--json] [--mock]');
|
|
35
37
|
process.exitCode = 1;
|
|
@@ -81,8 +83,12 @@ export async function team(args = []) {
|
|
|
81
83
|
agents: roster.bundle_size,
|
|
82
84
|
targetActiveSlots,
|
|
83
85
|
desiredWorkItemCount,
|
|
86
|
+
minimumWorkItems,
|
|
87
|
+
maxQueueExpansion,
|
|
84
88
|
concurrency: Math.min(agentSessions, roster.bundle_size),
|
|
85
|
-
readonly: true
|
|
89
|
+
readonly: true,
|
|
90
|
+
routeCommand: 'sks team',
|
|
91
|
+
routeBlackboxKind: 'actual_team_command'
|
|
86
92
|
});
|
|
87
93
|
await appendTeamEvent(dir, {
|
|
88
94
|
agent: 'native_agent_orchestrator',
|
|
@@ -120,6 +126,8 @@ export async function team(args = []) {
|
|
|
120
126
|
bundle_size: roster.bundle_size,
|
|
121
127
|
target_active_slots: targetActiveSlots,
|
|
122
128
|
desired_work_items: desiredWorkItemCount,
|
|
129
|
+
minimum_work_items: minimumWorkItems,
|
|
130
|
+
max_queue_expansion: maxQueueExpansion,
|
|
123
131
|
role_counts: roleCounts,
|
|
124
132
|
questions: path.join(dir, 'questions.md'),
|
|
125
133
|
native_agent_run: nativeAgentRun,
|
package/dist/core/fsx.d.ts
CHANGED
package/dist/core/fsx.js
CHANGED
|
@@ -5,7 +5,7 @@ import os from 'node:os';
|
|
|
5
5
|
import crypto from 'node:crypto';
|
|
6
6
|
import { spawn } from 'node:child_process';
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
|
8
|
-
export const PACKAGE_VERSION = '1.18.
|
|
8
|
+
export const PACKAGE_VERSION = '1.18.3';
|
|
9
9
|
export const DEFAULT_PROCESS_TAIL_BYTES = 256 * 1024;
|
|
10
10
|
export const DEFAULT_PROCESS_TIMEOUT_MS = 30 * 60 * 1000;
|
|
11
11
|
export function nowIso() {
|
package/dist/core/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const PACKAGE_VERSION = "1.18.
|
|
1
|
+
export declare const PACKAGE_VERSION = "1.18.3";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/core/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const PACKAGE_VERSION = '1.18.
|
|
1
|
+
export const PACKAGE_VERSION = '1.18.3';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sneakoscope",
|
|
3
3
|
"displayName": "ㅅㅋㅅ",
|
|
4
|
-
"version": "1.18.
|
|
4
|
+
"version": "1.18.3",
|
|
5
5
|
"description": "Sneakoscope Codex: fast proof-first Codex trust layer with image-based Voxel TriWiki.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"homepage": "https://github.com/mandarange/Sneakoscope-Codex#readme",
|
|
@@ -238,11 +238,19 @@
|
|
|
238
238
|
"agent:follow-up-work-schema": "node ./scripts/agent-follow-up-work-schema-check.mjs",
|
|
239
239
|
"agent:dynamic-pool-route-blackbox": "node ./scripts/agent-dynamic-pool-route-blackbox.mjs",
|
|
240
240
|
"agent:backfill-route-blackbox": "node ./scripts/agent-backfill-route-blackbox.mjs",
|
|
241
|
+
"agent:cli-options-to-task-graph": "node ./scripts/agent-cli-options-to-task-graph-check.mjs",
|
|
242
|
+
"agent:route-truth-backfill": "node ./scripts/agent-route-truth-backfill-check.mjs",
|
|
241
243
|
"team:backfill-route-blackbox": "node ./scripts/team-backfill-route-blackbox.mjs",
|
|
244
|
+
"team:actual-route-backfill": "node ./scripts/team-actual-route-backfill-check.mjs",
|
|
242
245
|
"research:backfill-route-blackbox": "node ./scripts/research-backfill-route-blackbox.mjs",
|
|
246
|
+
"research:actual-route-backfill": "node ./scripts/research-actual-route-backfill-check.mjs",
|
|
243
247
|
"qa:backfill-route-blackbox": "node ./scripts/qa-backfill-route-blackbox.mjs",
|
|
248
|
+
"qa:actual-route-backfill": "node ./scripts/qa-actual-route-backfill-check.mjs",
|
|
244
249
|
"agent:tmux-lane-persistence": "node ./scripts/agent-tmux-lane-persistence-check.mjs",
|
|
245
250
|
"agent:tmux-lane-no-flicker": "node ./scripts/agent-tmux-lane-no-flicker-check.mjs",
|
|
251
|
+
"agent:tmux-supervisor-integrated": "node ./scripts/agent-tmux-supervisor-integrated-check.mjs",
|
|
252
|
+
"agent:tmux-slot-lane-runtime": "node ./scripts/agent-tmux-slot-lane-runtime-check.mjs",
|
|
253
|
+
"agent:proof-contract-reconciled": "node ./scripts/agent-proof-contract-reconciled-check.mjs",
|
|
246
254
|
"agent:scheduler-proof-hardening": "node ./scripts/agent-scheduler-proof-hardening-check.mjs",
|
|
247
255
|
"agent:dynamic-pool": "node ./scripts/agent-dynamic-pool-check.mjs",
|
|
248
256
|
"agent:backfill-replenishment": "node ./scripts/agent-backfill-replenishment-check.mjs",
|