sneakoscope 1.18.1 → 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 +6 -4
- 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 +15 -9
- package/dist/commands/image-ux-review.d.ts +51 -2
- package/dist/commands/ppt.d.ts +51 -2
- package/dist/core/agents/agent-command-surface.d.ts +4 -0
- package/dist/core/agents/agent-command-surface.js +6 -2
- package/dist/core/agents/agent-follow-up-work-items.d.ts +20 -0
- package/dist/core/agents/agent-follow-up-work-items.js +115 -0
- package/dist/core/agents/agent-janitor.d.ts +3 -0
- package/dist/core/agents/agent-janitor.js +7 -1
- package/dist/core/agents/agent-orchestrator.d.ts +51 -2
- package/dist/core/agents/agent-orchestrator.js +104 -9
- package/dist/core/agents/agent-output-validator.d.ts +51 -0
- package/dist/core/agents/agent-output-validator.js +34 -0
- package/dist/core/agents/agent-proof-evidence.d.ts +32 -1
- package/dist/core/agents/agent-proof-evidence.js +77 -3
- package/dist/core/agents/agent-runner-codex-exec.d.ts +1 -0
- package/dist/core/agents/agent-runner-fake.js +20 -0
- package/dist/core/agents/agent-runner-process.js +16 -1
- package/dist/core/agents/agent-runner-tmux.d.ts +1 -1
- package/dist/core/agents/agent-runner-tmux.js +44 -7
- package/dist/core/agents/agent-scheduler.d.ts +2 -0
- package/dist/core/agents/agent-scheduler.js +20 -2
- package/dist/core/agents/agent-schema.d.ts +18 -0
- package/dist/core/agents/agent-task-graph.d.ts +52 -0
- package/dist/core/agents/agent-task-graph.js +193 -0
- package/dist/core/agents/agent-terminal-session.d.ts +11 -0
- package/dist/core/agents/agent-terminal-session.js +48 -0
- package/dist/core/agents/agent-trust-report.d.ts +12 -0
- package/dist/core/agents/agent-trust-report.js +21 -0
- package/dist/core/agents/agent-work-partition.d.ts +15 -1
- package/dist/core/agents/agent-work-partition.js +23 -2
- package/dist/core/agents/agent-work-queue.js +11 -5
- package/dist/core/agents/agent-worker-pipeline.js +7 -1
- package/dist/core/agents/agent-wrongness.d.ts +1 -1
- package/dist/core/agents/agent-wrongness.js +2 -0
- package/dist/core/agents/route-collaboration-ledger.d.ts +51 -2
- package/dist/core/agents/tmux-lane-supervisor.d.ts +54 -0
- package/dist/core/agents/tmux-lane-supervisor.js +253 -0
- package/dist/core/agents/work-partition/task-slicer.d.ts +4 -0
- package/dist/core/agents/work-partition/task-slicer.js +18 -1
- package/dist/core/commands/agent-command.js +10 -3
- package/dist/core/commands/command-utils.js +2 -1
- package/dist/core/commands/image-ux-review-command.d.ts +51 -2
- package/dist/core/commands/ppt-command.d.ts +51 -2
- package/dist/core/commands/qa-loop-command.js +9 -3
- package/dist/core/commands/research-command.js +7 -2
- package/dist/core/commands/team-command.js +17 -3
- package/dist/core/fsx.d.ts +1 -1
- package/dist/core/fsx.js +1 -1
- package/dist/core/routes.js +2 -2
- package/dist/core/team-live.js +6 -0
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/package.json +20 -2
- package/schemas/codex/agent-result.schema.json +30 -0
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
|
|
@@ -19,10 +19,12 @@ sks mad-sks proof --json
|
|
|
19
19
|
sks mad-sks rollback-apply --rollback-plan <path> --yes --json
|
|
20
20
|
sks features complete --json
|
|
21
21
|
sks agent status latest --json
|
|
22
|
-
sks agent run "release review" --agents 8 --concurrency 4 --mock --json
|
|
22
|
+
sks agent run "release review" --agents 8 --work-items 16 --concurrency 4 --mock --json
|
|
23
23
|
npm run source-intelligence:all-modes
|
|
24
24
|
npm run agent:background-terminals
|
|
25
|
-
npm run agent:tmux-
|
|
25
|
+
npm run agent:tmux-lane-no-flicker
|
|
26
|
+
npm run agent:backfill-route-blackbox
|
|
27
|
+
npm run team:actual-route-backfill
|
|
26
28
|
npm run release:readiness
|
|
27
29
|
```
|
|
28
30
|
|
|
@@ -612,7 +614,7 @@ npm run release:check
|
|
|
612
614
|
npm run publish:dry
|
|
613
615
|
```
|
|
614
616
|
|
|
615
|
-
`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.
|
|
616
618
|
|
|
617
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.
|
|
618
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
|
-
"compiled_file_count":
|
|
8
|
-
"compiled_js_count":
|
|
9
|
-
"compiled_dts_count":
|
|
10
|
-
"source_digest": "
|
|
11
|
-
"source_file_count":
|
|
12
|
-
"source_files_hash": "
|
|
13
|
-
"source_list_hash": "
|
|
7
|
+
"compiled_file_count": 864,
|
|
8
|
+
"compiled_js_count": 432,
|
|
9
|
+
"compiled_dts_count": 432,
|
|
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": [
|
|
@@ -198,6 +198,8 @@
|
|
|
198
198
|
"core/agents/agent-consensus.js",
|
|
199
199
|
"core/agents/agent-effort-policy.d.ts",
|
|
200
200
|
"core/agents/agent-effort-policy.js",
|
|
201
|
+
"core/agents/agent-follow-up-work-items.d.ts",
|
|
202
|
+
"core/agents/agent-follow-up-work-items.js",
|
|
201
203
|
"core/agents/agent-gate.d.ts",
|
|
202
204
|
"core/agents/agent-gate.js",
|
|
203
205
|
"core/agents/agent-heartbeat.d.ts",
|
|
@@ -242,6 +244,8 @@
|
|
|
242
244
|
"core/agents/agent-session-generation.js",
|
|
243
245
|
"core/agents/agent-session-rows.d.ts",
|
|
244
246
|
"core/agents/agent-session-rows.js",
|
|
247
|
+
"core/agents/agent-task-graph.d.ts",
|
|
248
|
+
"core/agents/agent-task-graph.js",
|
|
245
249
|
"core/agents/agent-task-slicer.d.ts",
|
|
246
250
|
"core/agents/agent-task-slicer.js",
|
|
247
251
|
"core/agents/agent-terminal-session.d.ts",
|
|
@@ -262,6 +266,8 @@
|
|
|
262
266
|
"core/agents/route-collaboration-ledger.js",
|
|
263
267
|
"core/agents/scout-policy.d.ts",
|
|
264
268
|
"core/agents/scout-policy.js",
|
|
269
|
+
"core/agents/tmux-lane-supervisor.d.ts",
|
|
270
|
+
"core/agents/tmux-lane-supervisor.js",
|
|
265
271
|
"core/agents/tmux-right-lane-cockpit.d.ts",
|
|
266
272
|
"core/agents/tmux-right-lane-cockpit.js",
|
|
267
273
|
"core/agents/work-partition/conflict-detector.d.ts",
|
|
@@ -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: {
|
|
@@ -436,6 +438,16 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
436
438
|
lease_count: number;
|
|
437
439
|
blockers: string[];
|
|
438
440
|
};
|
|
441
|
+
task_graph: {
|
|
442
|
+
target_active_slots: number;
|
|
443
|
+
total_work_items: number;
|
|
444
|
+
generated_from_route: string;
|
|
445
|
+
work_items_exceed_active_slots: boolean;
|
|
446
|
+
};
|
|
447
|
+
requested_work_items: number;
|
|
448
|
+
actual_total_work_items: number;
|
|
449
|
+
target_active_slots: number;
|
|
450
|
+
minimum_work_items: number;
|
|
439
451
|
scheduler: {
|
|
440
452
|
schema: string;
|
|
441
453
|
ok: boolean;
|
|
@@ -549,12 +561,24 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
549
561
|
terminal_sessions_closed: any;
|
|
550
562
|
terminal_close_report: string;
|
|
551
563
|
target_active_slots: any;
|
|
564
|
+
total_work_items: any;
|
|
565
|
+
pending_count: any;
|
|
566
|
+
active_slot_count: any;
|
|
567
|
+
completed_count: any;
|
|
552
568
|
max_observed_active_slots: any;
|
|
553
569
|
backfill_count: any;
|
|
570
|
+
expected_backfill_count: any;
|
|
554
571
|
pending_queue_drained: any;
|
|
555
572
|
generation_count: any;
|
|
556
573
|
tmux_attach_command: string | null;
|
|
557
574
|
tmux_lane_manifest: string;
|
|
575
|
+
tmux_lane_persistence: {
|
|
576
|
+
supervisor: string;
|
|
577
|
+
no_flicker_verified: boolean;
|
|
578
|
+
pane_survival_checked: boolean;
|
|
579
|
+
unexpected_close_count: number;
|
|
580
|
+
lane_count: number;
|
|
581
|
+
};
|
|
558
582
|
output_schema_ok: boolean;
|
|
559
583
|
output_tail_report: string;
|
|
560
584
|
output_tail_records: number;
|
|
@@ -569,7 +593,7 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
569
593
|
generated_at: string;
|
|
570
594
|
records: {
|
|
571
595
|
schema: string;
|
|
572
|
-
kind: "xai_available_not_used" | "context7_missing" | "codex_web_search_missing" | "recursion_attempt" | "lease_conflict" | "session_not_closed" | "terminal_missing" | "terminal_not_closed" | "scheduler_starvation" | "session_generation_missing" | "schema_invalid_output" | "stale_heartbeat" | "legacy_multiagent_runtime_usage_attempt";
|
|
596
|
+
kind: "xai_available_not_used" | "context7_missing" | "codex_web_search_missing" | "recursion_attempt" | "lease_conflict" | "session_not_closed" | "terminal_missing" | "terminal_not_closed" | "scheduler_starvation" | "tmux_lane_flicker" | "missing_follow_up_schema" | "session_generation_missing" | "schema_invalid_output" | "stale_heartbeat" | "legacy_multiagent_runtime_usage_attempt";
|
|
573
597
|
blocker: string;
|
|
574
598
|
created_at: string;
|
|
575
599
|
status: string;
|
|
@@ -582,6 +606,10 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
582
606
|
generated_at: string;
|
|
583
607
|
mission_id: string;
|
|
584
608
|
backend: string;
|
|
609
|
+
route: string;
|
|
610
|
+
route_command: string;
|
|
611
|
+
route_blackbox_kind: string;
|
|
612
|
+
real_route_command_used: boolean;
|
|
585
613
|
real_parallel_claim: boolean;
|
|
586
614
|
fake_backend_disclaimer: string | null;
|
|
587
615
|
agent_count: any;
|
|
@@ -597,21 +625,42 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
597
625
|
session_generation_count: number;
|
|
598
626
|
all_generations_closed: boolean;
|
|
599
627
|
scheduler_state: string;
|
|
600
|
-
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;
|
|
601
638
|
max_observed_active_slots: any;
|
|
602
639
|
pending_queue_drained: boolean;
|
|
603
640
|
backfill_count: any;
|
|
604
641
|
expected_backfill_count: any;
|
|
642
|
+
backfill_expected_for_route: boolean;
|
|
605
643
|
slot_count: any;
|
|
606
644
|
generation_count: number;
|
|
607
645
|
all_slots_closed_after_drain: boolean;
|
|
608
646
|
generated_work_item_count: any;
|
|
609
647
|
source_intelligence_generation_refs_ok: boolean;
|
|
610
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;
|
|
611
653
|
tmux_lane_manifest: string;
|
|
612
654
|
tmux_lane_manifest_ok: boolean;
|
|
655
|
+
tmux_lane_supervisor: string;
|
|
656
|
+
lane_supervisor_integrated: boolean;
|
|
657
|
+
tmux_lane_no_flicker_verified: boolean;
|
|
658
|
+
tmux_lane_survival_checked: boolean;
|
|
659
|
+
tmux_lane_unexpected_close_count: number;
|
|
660
|
+
tmux_lane_auto_reopen_count: number;
|
|
613
661
|
tmux_pane_launch_ledger: string;
|
|
614
662
|
tmux_pane_launch_count: number;
|
|
663
|
+
terminal_reports_match_generations: boolean;
|
|
615
664
|
ledger_hash_chain_ok: boolean;
|
|
616
665
|
no_overlap_ok: boolean;
|
|
617
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: {
|
|
@@ -288,6 +290,16 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
288
290
|
lease_count: number;
|
|
289
291
|
blockers: string[];
|
|
290
292
|
};
|
|
293
|
+
task_graph: {
|
|
294
|
+
target_active_slots: number;
|
|
295
|
+
total_work_items: number;
|
|
296
|
+
generated_from_route: string;
|
|
297
|
+
work_items_exceed_active_slots: boolean;
|
|
298
|
+
};
|
|
299
|
+
requested_work_items: number;
|
|
300
|
+
actual_total_work_items: number;
|
|
301
|
+
target_active_slots: number;
|
|
302
|
+
minimum_work_items: number;
|
|
291
303
|
scheduler: {
|
|
292
304
|
schema: string;
|
|
293
305
|
ok: boolean;
|
|
@@ -401,12 +413,24 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
401
413
|
terminal_sessions_closed: any;
|
|
402
414
|
terminal_close_report: string;
|
|
403
415
|
target_active_slots: any;
|
|
416
|
+
total_work_items: any;
|
|
417
|
+
pending_count: any;
|
|
418
|
+
active_slot_count: any;
|
|
419
|
+
completed_count: any;
|
|
404
420
|
max_observed_active_slots: any;
|
|
405
421
|
backfill_count: any;
|
|
422
|
+
expected_backfill_count: any;
|
|
406
423
|
pending_queue_drained: any;
|
|
407
424
|
generation_count: any;
|
|
408
425
|
tmux_attach_command: string | null;
|
|
409
426
|
tmux_lane_manifest: string;
|
|
427
|
+
tmux_lane_persistence: {
|
|
428
|
+
supervisor: string;
|
|
429
|
+
no_flicker_verified: boolean;
|
|
430
|
+
pane_survival_checked: boolean;
|
|
431
|
+
unexpected_close_count: number;
|
|
432
|
+
lane_count: number;
|
|
433
|
+
};
|
|
410
434
|
output_schema_ok: boolean;
|
|
411
435
|
output_tail_report: string;
|
|
412
436
|
output_tail_records: number;
|
|
@@ -421,7 +445,7 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
421
445
|
generated_at: string;
|
|
422
446
|
records: {
|
|
423
447
|
schema: string;
|
|
424
|
-
kind: "xai_available_not_used" | "context7_missing" | "codex_web_search_missing" | "recursion_attempt" | "lease_conflict" | "session_not_closed" | "terminal_missing" | "terminal_not_closed" | "scheduler_starvation" | "session_generation_missing" | "schema_invalid_output" | "stale_heartbeat" | "legacy_multiagent_runtime_usage_attempt";
|
|
448
|
+
kind: "xai_available_not_used" | "context7_missing" | "codex_web_search_missing" | "recursion_attempt" | "lease_conflict" | "session_not_closed" | "terminal_missing" | "terminal_not_closed" | "scheduler_starvation" | "tmux_lane_flicker" | "missing_follow_up_schema" | "session_generation_missing" | "schema_invalid_output" | "stale_heartbeat" | "legacy_multiagent_runtime_usage_attempt";
|
|
425
449
|
blocker: string;
|
|
426
450
|
created_at: string;
|
|
427
451
|
status: string;
|
|
@@ -434,6 +458,10 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
434
458
|
generated_at: string;
|
|
435
459
|
mission_id: string;
|
|
436
460
|
backend: string;
|
|
461
|
+
route: string;
|
|
462
|
+
route_command: string;
|
|
463
|
+
route_blackbox_kind: string;
|
|
464
|
+
real_route_command_used: boolean;
|
|
437
465
|
real_parallel_claim: boolean;
|
|
438
466
|
fake_backend_disclaimer: string | null;
|
|
439
467
|
agent_count: any;
|
|
@@ -449,21 +477,42 @@ export declare function run(command: any, args?: any): Promise<void | {
|
|
|
449
477
|
session_generation_count: number;
|
|
450
478
|
all_generations_closed: boolean;
|
|
451
479
|
scheduler_state: string;
|
|
452
|
-
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;
|
|
453
490
|
max_observed_active_slots: any;
|
|
454
491
|
pending_queue_drained: boolean;
|
|
455
492
|
backfill_count: any;
|
|
456
493
|
expected_backfill_count: any;
|
|
494
|
+
backfill_expected_for_route: boolean;
|
|
457
495
|
slot_count: any;
|
|
458
496
|
generation_count: number;
|
|
459
497
|
all_slots_closed_after_drain: boolean;
|
|
460
498
|
generated_work_item_count: any;
|
|
461
499
|
source_intelligence_generation_refs_ok: boolean;
|
|
462
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;
|
|
463
505
|
tmux_lane_manifest: string;
|
|
464
506
|
tmux_lane_manifest_ok: boolean;
|
|
507
|
+
tmux_lane_supervisor: string;
|
|
508
|
+
lane_supervisor_integrated: boolean;
|
|
509
|
+
tmux_lane_no_flicker_verified: boolean;
|
|
510
|
+
tmux_lane_survival_checked: boolean;
|
|
511
|
+
tmux_lane_unexpected_close_count: number;
|
|
512
|
+
tmux_lane_auto_reopen_count: number;
|
|
465
513
|
tmux_pane_launch_ledger: string;
|
|
466
514
|
tmux_pane_launch_count: number;
|
|
515
|
+
terminal_reports_match_generations: boolean;
|
|
467
516
|
ledger_hash_chain_ok: boolean;
|
|
468
517
|
no_overlap_ok: boolean;
|
|
469
518
|
consensus_ok: boolean;
|
|
@@ -4,6 +4,10 @@ export declare function parseAgentCommandArgs(command: string, args?: string[]):
|
|
|
4
4
|
prompt: string;
|
|
5
5
|
route: string;
|
|
6
6
|
agents: number;
|
|
7
|
+
targetActiveSlots: number;
|
|
8
|
+
desiredWorkItemCount: number;
|
|
9
|
+
minimumWorkItems: number;
|
|
10
|
+
maxQueueExpansion: number;
|
|
7
11
|
concurrency: number;
|
|
8
12
|
backend: string;
|
|
9
13
|
mock: boolean;
|
|
@@ -6,6 +6,10 @@ export function parseAgentCommandArgs(command, args = []) {
|
|
|
6
6
|
const rest = action === first ? args.slice(1) : args;
|
|
7
7
|
const json = hasFlag(args, '--json');
|
|
8
8
|
const agents = Number(readOption(args, '--agents', DEFAULT_AGENT_COUNT));
|
|
9
|
+
const targetActiveSlots = Number(readOption(args, '--target-active-slots', agents));
|
|
10
|
+
const desiredWorkItemCount = Number(readOption(args, '--work-items', targetActiveSlots));
|
|
11
|
+
const minimumWorkItems = Number(readOption(args, '--minimum-work-items', targetActiveSlots));
|
|
12
|
+
const maxQueueExpansion = Number(readOption(args, '--max-queue-expansion', 10));
|
|
9
13
|
const concurrency = Number(readOption(args, '--concurrency', Math.min(agents, 5)));
|
|
10
14
|
const backend = String(readOption(args, '--backend', hasFlag(args, '--mock') ? 'fake' : 'codex-exec'));
|
|
11
15
|
const route = String(readOption(args, '--route', '$Agent'));
|
|
@@ -13,14 +17,14 @@ export function parseAgentCommandArgs(command, args = []) {
|
|
|
13
17
|
const real = hasFlag(args, '--real');
|
|
14
18
|
const readonly = hasFlag(args, '--readonly') || hasFlag(args, '--read-only');
|
|
15
19
|
const codexApp = hasFlag(args, '--codex-app');
|
|
16
|
-
const positionals = positionalArgs(rest, new Set(['--agents', '--concurrency', '--backend', '--route', '--mission', '--mission-id', '--agent', '--lane']));
|
|
20
|
+
const positionals = positionalArgs(rest, new Set(['--agents', '--target-active-slots', '--work-items', '--minimum-work-items', '--max-queue-expansion', '--concurrency', '--backend', '--route', '--mission', '--mission-id', '--agent', '--lane']));
|
|
17
21
|
const missionDefault = action === 'run' || action === 'spawn' || action === 'plan' ? '' : 'latest';
|
|
18
22
|
const positionalMission = action === 'run' || action === 'spawn' || action === 'plan' ? '' : (positionals[0] || '');
|
|
19
23
|
const missionId = String(readOption(args, '--mission', readOption(args, '--mission-id', positionalMission || missionDefault)));
|
|
20
24
|
const lane = String(readOption(args, '--agent', readOption(args, '--lane', '')));
|
|
21
25
|
const promptPositionals = positionalMission ? positionals.slice(1) : positionals;
|
|
22
26
|
const prompt = promptPositionals.join(' ').trim() || 'Native agent run';
|
|
23
|
-
return { command, action, prompt, route, agents, concurrency, backend, mock, real, readonly, json, missionId, lane, codexApp };
|
|
27
|
+
return { command, action, prompt, route, agents, targetActiveSlots, desiredWorkItemCount, minimumWorkItems, maxQueueExpansion, concurrency, backend, mock, real, readonly, json, missionId, lane, codexApp };
|
|
24
28
|
}
|
|
25
29
|
function hasFlag(args, flag) {
|
|
26
30
|
return args.includes(flag);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface AgentFollowUpWorkItem {
|
|
2
|
+
id: string;
|
|
3
|
+
title: string;
|
|
4
|
+
description: string;
|
|
5
|
+
required_persona_category: string;
|
|
6
|
+
priority: number;
|
|
7
|
+
dependencies: string[];
|
|
8
|
+
lease_requirements: unknown[];
|
|
9
|
+
max_attempts: number;
|
|
10
|
+
reason: string;
|
|
11
|
+
source_agent_session_id?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface AgentFollowUpValidationResult {
|
|
14
|
+
accepted: AgentFollowUpWorkItem[];
|
|
15
|
+
blockers: string[];
|
|
16
|
+
}
|
|
17
|
+
export declare function normalizeAgentFollowUpWorkItems(rawItems: unknown, input?: {
|
|
18
|
+
originSessionId?: string | null;
|
|
19
|
+
}): AgentFollowUpValidationResult;
|
|
20
|
+
//# sourceMappingURL=agent-follow-up-work-items.d.ts.map
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { scanAgentTextForRecursion } from './agent-recursion-guard.js';
|
|
2
|
+
const FOLLOW_UP_KEYS = new Set([
|
|
3
|
+
'id',
|
|
4
|
+
'title',
|
|
5
|
+
'description',
|
|
6
|
+
'required_persona_category',
|
|
7
|
+
'priority',
|
|
8
|
+
'dependencies',
|
|
9
|
+
'lease_requirements',
|
|
10
|
+
'max_attempts',
|
|
11
|
+
'reason',
|
|
12
|
+
'source_agent_session_id'
|
|
13
|
+
]);
|
|
14
|
+
const PROTECTED_WRITE_PATH_RE = /^(?:\.codex|\.agents|AGENTS\.md|node_modules\/sneakoscope|\.sneakoscope\/.*policy.*\.json)(?:\/|$)/;
|
|
15
|
+
const MAIN_ROUTE_RECURSION_RE = /(?:\bsks\s+(?:team|agent|research|qa-loop|goal)\b|\$(?:Team|Goal|Research|QA-LOOP|Agent)\b|main\s+route\s+recursion)/i;
|
|
16
|
+
const GLOBAL_SCOUT_LEDGER_RE = /global\s+scout\s+ledger/i;
|
|
17
|
+
export function normalizeAgentFollowUpWorkItems(rawItems, input = {}) {
|
|
18
|
+
if (rawItems === undefined || rawItems === null)
|
|
19
|
+
return { accepted: [], blockers: [] };
|
|
20
|
+
if (!Array.isArray(rawItems))
|
|
21
|
+
return { accepted: [], blockers: ['follow_up_work_items_not_array'] };
|
|
22
|
+
const accepted = [];
|
|
23
|
+
const blockers = [];
|
|
24
|
+
rawItems.forEach((raw, index) => {
|
|
25
|
+
const result = normalizeAgentFollowUpWorkItem(raw, index, input.originSessionId || null);
|
|
26
|
+
if (result.item)
|
|
27
|
+
accepted.push(result.item);
|
|
28
|
+
blockers.push(...result.blockers);
|
|
29
|
+
});
|
|
30
|
+
return { accepted, blockers };
|
|
31
|
+
}
|
|
32
|
+
function normalizeAgentFollowUpWorkItem(raw, index, originSessionId) {
|
|
33
|
+
const blockers = [];
|
|
34
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
35
|
+
return { item: null, blockers: [`follow_up_work_item_${index + 1}_not_object`] };
|
|
36
|
+
}
|
|
37
|
+
const row = raw;
|
|
38
|
+
for (const key of Object.keys(row)) {
|
|
39
|
+
if (!FOLLOW_UP_KEYS.has(key))
|
|
40
|
+
blockers.push(`follow_up_work_item_${index + 1}_additional_property:${key}`);
|
|
41
|
+
}
|
|
42
|
+
const id = requiredString(row.id, 'id', index, blockers);
|
|
43
|
+
const title = requiredString(row.title, 'title', index, blockers);
|
|
44
|
+
const description = requiredString(row.description, 'description', index, blockers);
|
|
45
|
+
const requiredPersonaCategory = requiredString(row.required_persona_category, 'required_persona_category', index, blockers);
|
|
46
|
+
const reason = requiredString(row.reason, 'reason', index, blockers);
|
|
47
|
+
const priority = requiredInteger(row.priority, 'priority', index, blockers, 0);
|
|
48
|
+
const maxAttempts = requiredInteger(row.max_attempts, 'max_attempts', index, blockers, 1);
|
|
49
|
+
const dependencies = requiredStringArray(row.dependencies, 'dependencies', index, blockers);
|
|
50
|
+
const leaseRequirements = requiredArray(row.lease_requirements, 'lease_requirements', index, blockers);
|
|
51
|
+
const sourceAgentSessionId = typeof row.source_agent_session_id === 'string' && row.source_agent_session_id.trim()
|
|
52
|
+
? row.source_agent_session_id.trim()
|
|
53
|
+
: originSessionId || undefined;
|
|
54
|
+
const serialized = JSON.stringify(row);
|
|
55
|
+
const recursion = scanAgentTextForRecursion(serialized);
|
|
56
|
+
if (!recursion.ok || MAIN_ROUTE_RECURSION_RE.test(serialized))
|
|
57
|
+
blockers.push(`follow_up_work_item_${index + 1}_main_route_recursion_blocked`);
|
|
58
|
+
if (GLOBAL_SCOUT_LEDGER_RE.test(serialized))
|
|
59
|
+
blockers.push(`follow_up_work_item_${index + 1}_global_scout_ledger_blocked`);
|
|
60
|
+
for (const lease of leaseRequirements) {
|
|
61
|
+
const path = leasePath(lease);
|
|
62
|
+
if (path && PROTECTED_WRITE_PATH_RE.test(path))
|
|
63
|
+
blockers.push(`follow_up_work_item_${index + 1}_protected_core_target:${path}`);
|
|
64
|
+
}
|
|
65
|
+
if (blockers.length)
|
|
66
|
+
return { item: null, blockers };
|
|
67
|
+
return {
|
|
68
|
+
item: {
|
|
69
|
+
id,
|
|
70
|
+
title,
|
|
71
|
+
description,
|
|
72
|
+
required_persona_category: requiredPersonaCategory,
|
|
73
|
+
priority,
|
|
74
|
+
dependencies,
|
|
75
|
+
lease_requirements: leaseRequirements,
|
|
76
|
+
max_attempts: maxAttempts,
|
|
77
|
+
reason,
|
|
78
|
+
...(sourceAgentSessionId ? { source_agent_session_id: sourceAgentSessionId } : {})
|
|
79
|
+
},
|
|
80
|
+
blockers: []
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function requiredString(value, field, index, blockers) {
|
|
84
|
+
const text = typeof value === 'string' ? value.trim() : '';
|
|
85
|
+
if (!text)
|
|
86
|
+
blockers.push(`follow_up_work_item_${index + 1}_missing_${field}`);
|
|
87
|
+
return text;
|
|
88
|
+
}
|
|
89
|
+
function requiredInteger(value, field, index, blockers, min) {
|
|
90
|
+
const parsed = Number(value);
|
|
91
|
+
if (!Number.isFinite(parsed) || Math.floor(parsed) !== parsed || parsed < min)
|
|
92
|
+
blockers.push(`follow_up_work_item_${index + 1}_invalid_${field}`);
|
|
93
|
+
return Math.max(min, Number.isFinite(parsed) ? Math.floor(parsed) : min);
|
|
94
|
+
}
|
|
95
|
+
function requiredArray(value, field, index, blockers) {
|
|
96
|
+
if (!Array.isArray(value)) {
|
|
97
|
+
blockers.push(`follow_up_work_item_${index + 1}_missing_${field}`);
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
return value;
|
|
101
|
+
}
|
|
102
|
+
function requiredStringArray(value, field, index, blockers) {
|
|
103
|
+
const rows = requiredArray(value, field, index, blockers);
|
|
104
|
+
const out = rows.map((entry) => String(entry || '')).filter(Boolean);
|
|
105
|
+
if (out.length !== rows.length)
|
|
106
|
+
blockers.push(`follow_up_work_item_${index + 1}_invalid_${field}`);
|
|
107
|
+
return out;
|
|
108
|
+
}
|
|
109
|
+
function leasePath(lease) {
|
|
110
|
+
if (!lease || typeof lease !== 'object')
|
|
111
|
+
return '';
|
|
112
|
+
const row = lease;
|
|
113
|
+
return String(row.path || row.file || row.target_path || '').replace(/\\/g, '/').replace(/^\.?\//, '');
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=agent-follow-up-work-items.js.map
|
|
@@ -8,6 +8,9 @@ export interface AgentJanitorReport {
|
|
|
8
8
|
zombie_process_sessions: string[];
|
|
9
9
|
stale_tmux_sessions: string[];
|
|
10
10
|
active_generation_sessions: string[];
|
|
11
|
+
active_generation_count: number;
|
|
12
|
+
cleaned_generation_count: number;
|
|
13
|
+
skipped_active_generations: string[];
|
|
11
14
|
orphan_generation_dirs: string[];
|
|
12
15
|
slot_generation_cleanup: string[];
|
|
13
16
|
orphan_temp_dirs: string[];
|
|
@@ -34,7 +34,10 @@ export async function runAgentJanitor(input) {
|
|
|
34
34
|
statusBySession.set(String(row.session_id), status);
|
|
35
35
|
}
|
|
36
36
|
const zombieProcesses = await detectZombieProcessSessions(agentRoot, statusByAgent, statusBySession);
|
|
37
|
-
const
|
|
37
|
+
const rawStaleTmuxSessions = await detectStaleTmuxSessions(agentRoot, staleMs);
|
|
38
|
+
const activeGenerationSet = new Set(activeGenerationSessions);
|
|
39
|
+
const staleTmuxSessions = rawStaleTmuxSessions.filter((id) => !activeGenerationSet.has(id));
|
|
40
|
+
const skippedActiveGenerations = rawStaleTmuxSessions.filter((id) => activeGenerationSet.has(id));
|
|
38
41
|
const orphanGenerationDirs = await detectOrphanGenerationDirs(agentRoot, new Set(generationRows.map((row) => String(row.artifact_dir || ''))));
|
|
39
42
|
const orphanTempDirs = await scopedExistingPaths(Array.isArray(namespace?.orphan_temp_dirs) ? namespace.orphan_temp_dirs : [], projectHash);
|
|
40
43
|
const staleLocks = await scopedStaleLockPaths(namespace?.lock_dir ? [namespace.lock_dir] : [], projectHash, staleMs);
|
|
@@ -65,6 +68,9 @@ export async function runAgentJanitor(input) {
|
|
|
65
68
|
zombie_process_sessions: zombieProcesses,
|
|
66
69
|
stale_tmux_sessions: staleTmuxSessions,
|
|
67
70
|
active_generation_sessions: activeGenerationSessions,
|
|
71
|
+
active_generation_count: activeGenerationSessions.length,
|
|
72
|
+
cleaned_generation_count: cleaned.filter((entry) => entry.includes(`${path.sep}sessions${path.sep}`)).length,
|
|
73
|
+
skipped_active_generations: skippedActiveGenerations,
|
|
68
74
|
orphan_generation_dirs: orphanGenerationDirs,
|
|
69
75
|
slot_generation_cleanup: cleaned.filter((entry) => entry.includes(`${path.sep}sessions${path.sep}`)),
|
|
70
76
|
orphan_temp_dirs: orphanTempDirs,
|