Skip to content
Merged
8 changes: 3 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -192,16 +192,14 @@ jobs:
tests-portable-serial:
name: Behavior portable serial ${{ matrix.shard }}
runs-on: ubuntu-latest
# Refreshed timings plus conservative hints for grown tests estimate ~84 min
# of serial work, balanced over six runners at ~14 min each. Keep the cap
# as a hang tripwire with runner-load margin; refresh hints per
# docs/fm-test-portable-shards.md when a shard approaches it.
# Keep this cap as a hang tripwire; when a shard approaches it, follow the
# balance evidence and refresh procedure in docs/fm-test-portable-shards.md.
timeout-minutes: 20
strategy:
# Every shard reports so one failure never hides another shard's result.
fail-fast: false
matrix:
shard: [1, 2, 3, 4, 5, 6]
shard: [1, 2, 3, 4, 5, 6, 7]
steps:
- uses: actions/checkout@v6
with:
Expand Down
320 changes: 166 additions & 154 deletions bin/fm-test-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,9 @@ JOBS_MAX=8

# How many separate-runner shards the portable serial remainder splits into.
# One owner: CI lane names carry this count and are refused when they disagree.
PORTABLE_SERIAL_SHARDS=6
PORTABLE_SERIAL_SHARDS=7

# Balance hint for a portable-serial script with no measured duration, close to
# the measured per-script mean so a newly added test neither starves nor
# overloads the shard it lands in.
# Fallback balance hint for a portable-serial script with no measured duration.
PORTABLE_SERIAL_DEFAULT_WEIGHT_MS=20000

usage() {
Expand Down Expand Up @@ -375,165 +373,179 @@ list_portable_serial() {
done < <(all_repo_tests)
}

# Portable-serial duration hints in milliseconds, from CI artifacts, completed
# log records, and conservative estimates documented in docs/fm-test-portable-shards.md.
# Portable-serial measured duration hints in milliseconds; source evidence is
# documented in docs/fm-test-portable-shards.md.
# These affect balance only: the shard partition stays complete and disjoint, so a
# stale hint costs balance rather than coverage. That doc owns the refresh
# procedure.
portable_serial_weight_hints() {
cat <<'EOF'
tests/fm-afk-inject-e2e.test.sh 26008
tests/fm-afk-pi-herdr-return-e2e.test.sh 47
tests/fm-afk-return.test.sh 1517
tests/fm-ask-user-authority.test.sh 138
tests/fm-backend-cmux-smoke.test.sh 30
tests/fm-backend-cmux.test.sh 2950
tests/fm-backend-herdr-focus-flash-e2e.test.sh 21
tests/fm-backend-herdr-server-detach.test.sh 90000
tests/fm-backend-orca.test.sh 19416
tests/fm-backend-tmux-smoke.test.sh 315
tests/fm-backend-zellij-smoke.test.sh 14
tests/fm-backend-zellij.test.sh 5188
tests/fm-backend.test.sh 19862
tests/fm-backlog-atomicity.test.sh 78496
tests/fm-backlog-handoff.test.sh 3343
tests/fm-bearings-snapshot.test.sh 66118
tests/fm-boat-lifecycle.test.sh 52034
tests/fm-boat-omp-auth.test.sh 58941
tests/fm-boat-routing.test.sh 200000
tests/fm-bootstrap.test.sh 62184
tests/fm-busy-adapter-wiring.test.sh 17306
tests/fm-busy-state.test.sh 2821
tests/fm-calm-pi-extension.test.sh 260
tests/fm-check-unregister.test.sh 356
tests/fm-classify-decision-key.test.sh 703
tests/fm-claude-stop-autoarm-live-e2e.test.sh 17
tests/fm-claude-stop-autoarm.test.sh 60519
tests/fm-cleanup-skill.test.sh 72
tests/fm-codex-continuity-live-e2e.test.sh 19
tests/fm-daemon.test.sh 61329
tests/fm-devin-adapter.test.sh 280
tests/fm-devin-herdr-live-e2e.test.sh 13
tests/fm-dispatch-resolve.test.sh 3995
tests/fm-documentation-audiences.test.sh 708
tests/fm-ext-bridge.test.sh 35693
tests/fm-fleet-snapshot-view.test.sh 13508
tests/fm-fleet-sync.test.sh 32815
tests/fm-gate-refuse.test.sh 9270
tests/fm-gitignore-config.test.sh 25
tests/fm-gotmp.test.sh 713
tests/fm-grok-continuity-live-e2e.test.sh 12
tests/fm-grok-stop-live-e2e.test.sh 21
tests/fm-guard-stale-banner.test.sh 4698
tests/fm-herdr-session-cleanup.test.sh 4832
tests/fm-herdr-submit-confirm-live-e2e.test.sh 21
tests/fm-hermes-harness.test.sh 146669
tests/fm-hermes-live-e2e.test.sh 28
tests/fm-idle-sleep-watch.test.sh 8000
tests/fm-idle-sleep.test.sh 15000
tests/fm-inbox-result.test.sh 7377
tests/fm-inbox.test.sh 7022
tests/fm-kimi-harness.test.sh 16139
tests/fm-omp-branch-bash.test.sh 44
tests/fm-omp-branch-live-e2e.test.sh 12
tests/fm-omp-branch-supervision.test.sh 4373
tests/fm-omp-branch-types.test.sh 24
tests/fm-afk-inject-e2e.test.sh 26538
tests/fm-afk-pi-herdr-return-e2e.test.sh 76
tests/fm-afk-return.test.sh 1524
tests/fm-ask-user-authority.test.sh 154
tests/fm-backend-cmux-smoke.test.sh 34
tests/fm-backend-cmux.test.sh 3751
tests/fm-backend-herdr-focus-flash-e2e.test.sh 22
tests/fm-backend-herdr-server-detach.test.sh 2649
tests/fm-backend-orca.test.sh 19716
tests/fm-backend-tmux-smoke.test.sh 250
tests/fm-backend-zellij-smoke.test.sh 22
tests/fm-backend-zellij.test.sh 7129
tests/fm-backend.test.sh 23256
tests/fm-backlog-atomicity.test.sh 63215
tests/fm-backlog-handoff.test.sh 3410
tests/fm-bearings-snapshot.test.sh 81131
tests/fm-boat-lane-runner.test.sh 119102
tests/fm-boat-lifecycle.test.sh 44937
tests/fm-boat-omp-auth.test.sh 62445
tests/fm-boat-routing.test.sh 26287
tests/fm-bootstrap.test.sh 71450
tests/fm-busy-adapter-wiring.test.sh 19619
tests/fm-busy-state.test.sh 2879
tests/fm-calm-pi-extension.test.sh 265
tests/fm-check-unregister.test.sh 436
tests/fm-classify-decision-key.test.sh 501
tests/fm-claude-stop-autoarm-live-e2e.test.sh 20
tests/fm-claude-stop-autoarm.test.sh 60780
tests/fm-cleanup-skill.test.sh 74
tests/fm-codex-continuity-live-e2e.test.sh 20
tests/fm-daemon.test.sh 60677
tests/fm-devin-adapter.test.sh 349
tests/fm-devin-herdr-live-e2e.test.sh 21
tests/fm-dispatch-resolve.test.sh 8747
tests/fm-documentation-audiences.test.sh 878
tests/fm-ext-ask.test.sh 48724
tests/fm-ext-bridge.test.sh 82962
tests/fm-ext-decision.test.sh 161682
tests/fm-ext-plugin-dest.test.sh 7190
tests/fm-ext-thread-context.test.sh 18046
tests/fm-ext-topic-threads.test.sh 100660
tests/fm-ext-waiting-pin.test.sh 103172
tests/fm-ext-watch.test.sh 7522
tests/fm-fleet-snapshot-view.test.sh 12998
tests/fm-fleet-sync.test.sh 36580
tests/fm-gate-refuse.test.sh 11343
tests/fm-gitignore-config.test.sh 29
tests/fm-gotmp.test.sh 1168
tests/fm-grok-continuity-live-e2e.test.sh 19
tests/fm-grok-stop-live-e2e.test.sh 20
tests/fm-guard-stale-banner.test.sh 5898
tests/fm-herdr-session-cleanup.test.sh 6849
tests/fm-herdr-submit-confirm-live-e2e.test.sh 22
tests/fm-hermes-harness.test.sh 151616
tests/fm-hermes-live-e2e.test.sh 44
tests/fm-idle-sleep-watch.test.sh 4560
tests/fm-idle-sleep.test.sh 13959
tests/fm-inbox-result.test.sh 9828
tests/fm-inbox.test.sh 9840
tests/fm-kimi-harness.test.sh 18045
tests/fm-landing.test.sh 43476
tests/fm-main-ci-watch.test.sh 46302
tests/fm-merge-local.test.sh 2502
tests/fm-omp-branch-bash.test.sh 41
tests/fm-omp-branch-live-e2e.test.sh 20
tests/fm-omp-branch-supervision.test.sh 37015
tests/fm-omp-branch-types.test.sh 21
tests/fm-omp-compact-adviser-live-e2e.test.sh 20
tests/fm-omp-compact-adviser.test.sh 298
tests/fm-omp-fleet-hooks.test.sh 2407
tests/fm-omp-harness.test.sh 1764
tests/fm-omp-herdr-exit-live-e2e.test.sh 16
tests/fm-omp-compact-adviser.test.sh 1697
tests/fm-omp-fleet-hooks.test.sh 2743
tests/fm-omp-harness.test.sh 66500
tests/fm-omp-herdr-exit-live-e2e.test.sh 19
tests/fm-omp-herdr-live-e2e.test.sh 19
tests/fm-omp-primary-live-e2e.test.sh 18
tests/fm-omp-primary.test.sh 45746
tests/fm-omp-relaunch-guard.test.sh 4276
tests/fm-omp-relaunch-tmux-live-e2e.test.sh 21
tests/fm-omp-secondmate-live-e2e.test.sh 21
tests/fm-omp-secondmate.test.sh 600000
tests/fm-omp-task-inbox-doorbell.test.sh 20577
tests/fm-omp-update.test.sh 448
tests/fm-omp-worker-tmux-live-e2e.test.sh 17
tests/fm-on.test.sh 9627
tests/fm-opencode-primary-live-e2e.test.sh 16
tests/fm-operational-input.test.sh 176
tests/fm-pending-reply-sleep-reconcile.test.sh 243
tests/fm-pending-reply.test.sh 19949
tests/fm-pi-compatible-family.test.sh 56
tests/fm-omp-primary-live-e2e.test.sh 19
tests/fm-omp-primary.test.sh 61283
tests/fm-omp-relaunch-guard.test.sh 5534
tests/fm-omp-relaunch-tmux-live-e2e.test.sh 14
tests/fm-omp-secondmate-live-e2e.test.sh 20
tests/fm-omp-secondmate.test.sh 113332
tests/fm-omp-task-inbox-doorbell.test.sh 20456
tests/fm-omp-update.test.sh 689
tests/fm-omp-worker-tmux-live-e2e.test.sh 20
tests/fm-on.test.sh 9816
tests/fm-opencode-primary-live-e2e.test.sh 20
tests/fm-operational-input.test.sh 154
tests/fm-pending-reply-sleep-reconcile.test.sh 229
tests/fm-pending-reply.test.sh 15024
tests/fm-pi-compatible-family.test.sh 70
tests/fm-pi-primary-live-e2e.test.sh 21
tests/fm-pi-watch-extension.test.sh 22031
tests/fm-pr-check-handoff.test.sh 42228
tests/fm-pr-check-security.test.sh 158907
tests/fm-prepush-guard.test.sh 19208
tests/fm-procevent-when.test.sh 24358
tests/fm-procevent.test.sh 61916
tests/fm-public-followup.test.sh 35559
tests/fm-quota-array-dispatch-live-e2e.test.sh 12
tests/fm-receipt-check.test.sh 11636
tests/fm-receipt.test.sh 1331
tests/fm-reflect-skill.test.sh 372
tests/fm-remote-backlog-handoff.test.sh 15173
tests/fm-remote-doctor.test.sh 6203
tests/fm-remote-entrypoint.test.sh 208
tests/fm-remote-job.test.sh 48694
tests/fm-remote-reply.test.sh 99366
tests/fm-remote-secondmate-lifecycle-e2e.test.sh 700000
tests/fm-remote-secondmate-parent-binding.test.sh 15892
tests/fm-remote-secondmate-sleep-reconcile.test.sh 3000
tests/fm-remote-secondmate-trace-context.test.sh 49391
tests/fm-runpod-lifecycle.test.sh 56695
tests/fm-runpod-omp-auth.test.sh 1012
tests/fm-runpod-pod-boot.test.sh 45589
tests/fm-runpod-routing.test.sh 28030
tests/fm-secondmate-harness.test.sh 151987
tests/fm-secondmate-lifecycle-e2e.test.sh 5372
tests/fm-secondmate-liveness.test.sh 20126
tests/fm-secondmate-restart.test.sh 31003
tests/fm-secondmate-safety.test.sh 55903
tests/fm-secondmate-sync.test.sh 17159
tests/fm-send-inbox-doorbell-live-e2e.test.sh 18
tests/fm-send-inbox.test.sh 37394
tests/fm-send-resolve-key.test.sh 12632
tests/fm-send-secondmate-marker-herdr-e2e.test.sh 48
tests/fm-send-secondmate-marker.test.sh 4320
tests/fm-send-turn-start.test.sh 11143
tests/fm-session-lock-ancestry.test.sh 1284
tests/fm-session-start.test.sh 77942
tests/fm-sessionstart-nudge.test.sh 284
tests/fm-shared-captain-inheritance.test.sh 4259
tests/fm-spawn-dispatch-profile.test.sh 193113
tests/fm-spawn-pool-base-freshen.test.sh 35139
tests/fm-spawn-relaunch-dead-endpoint.test.sh 31467
tests/fm-spawn-worktree-settle.test.sh 5788
tests/fm-pi-watch-extension.test.sh 22125
tests/fm-pr-check-handoff.test.sh 15330
tests/fm-pr-check-security.test.sh 163835
tests/fm-prepush-guard.test.sh 19861
tests/fm-procevent-when.test.sh 21536
tests/fm-procevent.test.sh 69535
tests/fm-public-followup.test.sh 47380
tests/fm-quota-array-dispatch-live-e2e.test.sh 19
tests/fm-receipt-check.test.sh 6254
tests/fm-receipt.test.sh 1854
tests/fm-reflect-skill.test.sh 473
tests/fm-remote-backlog-handoff.test.sh 20170
tests/fm-remote-doctor.test.sh 5787
tests/fm-remote-entrypoint.test.sh 263
tests/fm-remote-job.test.sh 48956
tests/fm-remote-omp-update-restart-live-e2e.test.sh 20
tests/fm-remote-reply.test.sh 82089
tests/fm-remote-secondmate-lifecycle-e2e.test.sh 657637
tests/fm-remote-secondmate-parent-binding.test.sh 15757
tests/fm-remote-secondmate-sleep-reconcile.test.sh 1287
tests/fm-remote-secondmate-trace-context.test.sh 59252
tests/fm-remote-secondmate-update-restart.test.sh 30187
tests/fm-runpod-lifecycle.test.sh 58778
tests/fm-runpod-omp-auth.test.sh 1192
tests/fm-runpod-pod-boot.test.sh 43135
tests/fm-runpod-routing.test.sh 37449
tests/fm-secondmate-harness.test.sh 170105
tests/fm-secondmate-lifecycle-e2e.test.sh 6278
tests/fm-secondmate-liveness.test.sh 20034
tests/fm-secondmate-restart.test.sh 36334
tests/fm-secondmate-safety.test.sh 58742
tests/fm-secondmate-sync.test.sh 40216
tests/fm-send-inbox-doorbell-live-e2e.test.sh 22
tests/fm-send-inbox.test.sh 40199
tests/fm-send-resolve-key.test.sh 22866
tests/fm-send-secondmate-marker-herdr-e2e.test.sh 49
tests/fm-send-secondmate-marker.test.sh 4337
tests/fm-send-turn-start.test.sh 11083
tests/fm-session-lock-ancestry.test.sh 1513
tests/fm-session-start.test.sh 65773
tests/fm-sessionstart-nudge.test.sh 303
tests/fm-shared-captain-inheritance.test.sh 13503
tests/fm-spawn-dispatch-profile.test.sh 249954
tests/fm-spawn-pool-base-freshen.test.sh 35286
tests/fm-spawn-relaunch-dead-endpoint.test.sh 35039
tests/fm-spawn-worktree-settle.test.sh 11488
tests/fm-stall-recovery.test.sh 48
tests/fm-startup-memory-budget.test.sh 7593
tests/fm-subagent-pretool-check.test.sh 709
tests/fm-supervision-events.test.sh 462
tests/fm-tangle-guard.test.sh 8797
tests/fm-task-delivery.test.sh 9829
tests/fm-task-inbox.test.sh 37450
tests/fm-teardown-endpoint-safety.test.sh 1797
tests/fm-teardown.test.sh 107078
tests/fm-test-fixture-cleanup.test.sh 542
tests/fm-test-isolation-proof.test.sh 426
tests/fm-todo-project.test.sh 6065
tests/fm-trace-context-lib.test.sh 1424
tests/fm-trace-context-spawn.test.sh 46250
tests/fm-treehouse-orphan-recovery.test.sh 125
tests/fm-treehouse-status-read-only.test.sh 225
tests/fm-treehouse-sweep.test.sh 4886
tests/fm-turnend-guard.test.sh 20258
tests/fm-update.test.sh 10591
tests/fm-vendor-auth-probe.test.sh 42632
tests/fm-wake-daemon-lifecycle-e2e.test.sh 19948
tests/fm-wake-drain-open-decisions-cursor.test.sh 22217
tests/fm-wake-drain-open-decisions.test.sh 3443
tests/fm-wake-drain-unread-status.test.sh 14508
tests/fm-wake-queue.test.sh 72347
tests/fm-watch-arm.test.sh 66052
tests/fm-watch-checkpoint.test.sh 4768
tests/fm-watch-recovery-loop.test.sh 67796
tests/fm-watch-triage.test.sh 407955
tests/fm-watcher-lock.test.sh 38168
tests/fm-startup-memory-budget.test.sh 6514
tests/fm-subagent-pretool-check.test.sh 968
tests/fm-supervision-events.test.sh 628
tests/fm-tangle-guard.test.sh 10406
tests/fm-task-delivery.test.sh 19399
tests/fm-task-inbox.test.sh 37373
tests/fm-tasks-axi.test.sh 18227
tests/fm-teardown-endpoint-safety.test.sh 30883
tests/fm-teardown.test.sh 137584
tests/fm-test-fixture-cleanup.test.sh 681
tests/fm-test-isolation-proof.test.sh 588
tests/fm-todo-project.test.sh 9125
tests/fm-trace-context-lib.test.sh 1997
tests/fm-trace-context-spawn.test.sh 45140
tests/fm-treehouse-orphan-recovery.test.sh 111
tests/fm-treehouse-status-read-only.test.sh 223
tests/fm-treehouse-sweep.test.sh 4347
tests/fm-turnend-guard.test.sh 21290
tests/fm-update.test.sh 9518
tests/fm-vendor-auth-probe.test.sh 42927
tests/fm-wake-daemon-lifecycle-e2e.test.sh 69696
tests/fm-wake-drain-open-decisions-cursor.test.sh 26536
tests/fm-wake-drain-open-decisions.test.sh 12358
tests/fm-wake-drain-unread-status.test.sh 30489
tests/fm-wake-queue.test.sh 85314
tests/fm-watch-arm.test.sh 85430
tests/fm-watch-checkpoint.test.sh 5858
tests/fm-watch-recovery-loop.test.sh 66814
tests/fm-watch-triage.test.sh 428164
tests/fm-watcher-lock.test.sh 46975
EOF
}

Expand Down
Loading
Loading