diff --git a/.github/workflows/gc-moving-witnesses.yml b/.github/workflows/gc-moving-witnesses.yml index dd7f2899b8..9eb0967d9e 100644 --- a/.github/workflows/gc-moving-witnesses.yml +++ b/.github/workflows/gc-moving-witnesses.yml @@ -214,7 +214,7 @@ jobs: # The filter exists only to spare docs-only PRs a compiler build. If # the listing is empty or the API failed, `set -e` already aborted, so # the job cannot silently fall through to "not relevant". - if grep -qE '^(crates/|scripts/gc_repsel_matrix\.sh$|test-files/test_gap_gc_|test-parity/gc_repsel_|Cargo\.(toml|lock)$|\.node-version$|\.github/workflows/gc-moving-witnesses\.yml$)' changed.txt; then + if grep -qE '^(crates/|scripts/gc_repsel_matrix\.sh$|scripts/gc_matrix_fixture_env(_test)?\.py$|test-files/test_gap_gc_|test-parity/gc_repsel_|Cargo\.(toml|lock)$|\.node-version$|\.github/workflows/gc-moving-witnesses\.yml$)' changed.txt; then echo "run=true" >> "$GITHUB_OUTPUT" echo "Change touches collector-relevant paths; running the witnesses." else @@ -253,6 +253,10 @@ jobs: # drop out of the gate silently. node-version-file: .node-version + - name: Check witness settings reach compilation and execution + if: steps.relevance.outputs.run == 'true' + run: bash scripts/gc_repsel_matrix.sh --self-test-fixture-env + - name: Build perry and the runtime archives if: steps.relevance.outputs.run == 'true' env: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 87006b4deb..a7b0f3e90e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3005,7 +3005,7 @@ jobs: # --------------------------------------------------------------------------- # gap-suite (was `conformance-smoke`): the gap suite, sharded. Runs in every - # tier -- 6 fast-mode shards on a PR, 3 in the sweep, 12 auto-optimize shards + # tier -- 12 fast-mode shards on a PR, 3 in the sweep, 24 auto-optimize shards # in the full tier (scripts/ci_plan.py GAP_SUITE). The `gate` fan-in below is # what branch protection requires; a single shard's red bubbles up through it. # --------------------------------------------------------------------------- @@ -3086,7 +3086,7 @@ jobs: # protection requires. 2026-08-16: in the harness's default (auto-optimize) # mode 96% of a shard's wall time was ~10 tests at ~200 s each -- the # feature-stripped runtime rebuild per distinct feature set, redone in - # every shard. That mode is now the full tier's 12-shard arm; PR and sweep + # every shard. That mode is now the full tier's 24-shard arm; PR and sweep # tiers use `fast` mode against one prebuilt release build (~1.5 s/test). strategy: fail-fast: false @@ -3148,7 +3148,7 @@ jobs: # auto-optimize, which rebuilds a feature-stripped runtime per # distinct feature set (~200 s each; measured 96% of a shard's # wall time). It is the arm that sees auto-optimize-only bugs, - # so it stays in the nightly/release tier at 8 shards, and never + # so it stays in the nightly/release tier at 24 shards, and never # downloads a shared build. # Both compare against the SAME committed Linux snapshot; a divergence # between them is a real auto-optimize-specific finding, not noise. diff --git a/changelog.d/11756-full-gap-budget-headroom.md b/changelog.d/11756-full-gap-budget-headroom.md new file mode 100644 index 0000000000..099a6959ec --- /dev/null +++ b/changelog.d/11756-full-gap-budget-headroom.md @@ -0,0 +1,5 @@ +Split the full auto-optimize gap suite into twenty-four shards after nine +of twelve workers hit the existing 110-minute limit. Split the fast PR +arm into twelve shards after its six-way shard 1 also exhausted that bound. +Each previous slice is partitioned into two without dropping fixtures or +changing compilation, snapshots, acceptance thresholds or smoke workers. diff --git a/changelog.d/11756-gc-witness-fixture-env.md b/changelog.d/11756-gc-witness-fixture-env.md new file mode 100644 index 0000000000..e4ed6beaf3 --- /dev/null +++ b/changelog.d/11756-gc-witness-fixture-env.md @@ -0,0 +1,9 @@ +### Fixed + +- Apply declared GC witness settings during both compilation and execution of + the moving loop-poll arm, so seeded and protected witnesses select the matching + instrumented runtime. Validate the settings as literal GC assignments, keep + the compiled group separate from the safepoint control, and record the actual + compile and run settings. Exercise routing failure controls in the witness + workflow. Preserve the other arms, witness workloads, triage and movement + requirements. diff --git a/changelog.d/11756-windows-thread-global-effects.md b/changelog.d/11756-windows-thread-global-effects.md new file mode 100644 index 0000000000..936f3fda24 --- /dev/null +++ b/changelog.d/11756-windows-thread-global-effects.md @@ -0,0 +1,8 @@ +### Fixed + +- Refresh the Windows classifications of `js_thread_global_materialize` and + `js_thread_global_publish` from the generated table produced by the documented + Windows archive classifier at the reviewed CI repair head. Materialization is + `AllocOnly` and publication is `Leaf` on this target. Preserve every other + table entry and all classifier rules and seeds, removing two conservative + drifts that fail the strict full-tier check. diff --git a/changelog.d/11767-thread-global-e2e-routing.md b/changelog.d/11767-thread-global-e2e-routing.md new file mode 100644 index 0000000000..4e466f1b66 --- /dev/null +++ b/changelog.d/11767-thread-global-e2e-routing.md @@ -0,0 +1 @@ +Register the immutable thread-global codegen IR suite in the CI source-to-suite map. This removes the unclassified-suite planner failure introduced when the suite landed and runs its three tests on codegen source changes, preserving mapped-suite timeouts and coverage independent of the named-suite cap. diff --git a/docs/src/testing/ci-tiers.md b/docs/src/testing/ci-tiers.md index 0c9fca9525..f580c0aff6 100644 --- a/docs/src/testing/ci-tiers.md +++ b/docs/src/testing/ci-tiers.md @@ -14,20 +14,23 @@ python3 scripts/ci_plan.py --self-test # the policy's own invariants |---|---|---|---| | **pr** | every `pull_request` push | the required gate. Small, fast, must be green on `main`. | `pr-gate` — **the only required status context** | | **sweep** | every `push` to `main` (coalesced) **+ a two-hourly cron backstop** | post-merge truth for `main`: the PR tier unscoped plus the medium-weight jobs that do not fit the PR budget | `main-gate` | -| **full** | nightly `schedule`, `v*` tags, `workflow_dispatch`, PRs labelled `run-extended-tests` | everything, incl. parity, compile-smoke, doc-tests, package smokes, the 12-shard auto-optimize gap suite | `full-suite-gate` — what `release-packages.yml` waits for | +| **full** | nightly `schedule`, `v*` tags, `workflow_dispatch`, PRs labelled `run-extended-tests` | everything, incl. parity, compile-smoke, doc-tests, package smokes, the 24-shard auto-optimize gap suite | `full-suite-gate` — what `release-packages.yml` waits for | ## The job × tier matrix Generated by `python3 scripts/ci_plan.py --table`; the `lint` job checks that this copy is current. -The full gap tier uses twelve shards with auto-optimize enabled. Compile-smoke +The PR gap tier uses twelve fast-mode shards after a six-way shard exhausted +the 110-minute job bound. The full gap tier uses twenty-four shards with +auto-optimize enabled. Both retain every fixture and the existing snapshot +acceptance gate; CI timings must establish the new margin. Compile-smoke partitions the complete top-level `test-files/*.ts` inventory into four stable round-robin shards, with at most two smoke shards running concurrently. Each file is assigned once before the existing platform exclusions are applied. Every shard retains the default compiler invocation and failure markers; `full-suite-gate` requires the matrix job's aggregate result. These splits -address current eight-way gap jobs reaching their 110-minute bound and the +address twelve-way gap jobs reaching their 110-minute bound and the unsharded smoke job reaching the hosted six-hour limit. Actual CI durations must still establish the new margin. @@ -38,7 +41,7 @@ must still establish the new margin. | `warnings` | yes | yes | yes | | `cargo-test` | yes | yes | yes | | `cargo-test-perry` | | | yes | -| `gap-suite` | 6x fast | 3x fast | 12x full | +| `gap-suite` | 12x fast | 3x fast | 24x full | | `gc-call-effects` | yes | yes | yes | | `gc-stress` | 1x pr | 4x all | 4x all | | `e2e-scoped` | yes | | | diff --git a/scripts/ci_plan.py b/scripts/ci_plan.py index b93a14ea75..f3c3e7b09c 100755 --- a/scripts/ci_plan.py +++ b/scripts/ci_plan.py @@ -31,7 +31,7 @@ `await-tests` dispatches this and waits for the `full-suite-gate` job), and PRs carrying the `run-extended-tests` label. The sweep plus the slow/opt-in suites (parity, compile-smoke, doc-tests, package smokes, - the gap suite in its 12-shard auto-optimize mode). + the gap suite in its 24-shard auto-optimize mode). PR SCOPE -------- @@ -121,12 +121,16 @@ # it is ~28 min, level with gc-stress, for ~170 job-minutes -- against 480 for # the old 8 x auto-optimize shards. GAP_SUITE = { - "pr": {"mode": "fast", "total": 6}, + # Fast PR shard 1 in run36981459549 exhausted its 110-minute bound. + # Twelve modulo slices halve each former six-way slice; the worker and + # no-new-untriaged snapshot gate retain the same complete corpus. + "pr": {"mode": "fast", "total": 12}, "sweep": {"mode": "fast", "total": 3}, - # Current 8-way full runs hit the 110-minute bound while still compiling - # (e.g. run36914319295, shard1 reached137/152). Preserve auto-optimize - # coverage and distribute the complete corpus across more workers. - "full": {"mode": "full", "total": 12}, + # Twelve-way run 36967233926 still hit the 110-minute job bound: + # shard 3 completed only 79/102 fixtures and shard 4 only 82/102. + # Doubling the modulo partition halves each existing slice without + # dropping fixtures or changing auto-optimize and snapshot acceptance. + "full": {"mode": "full", "total": 24}, } # Parity: full tier only, sharded. The unsharded job was killed by GitHub's @@ -420,7 +424,7 @@ def check(name: str, cond: bool): check("core PR: windows off", not core["jobs"]["windows_build"]) check("core PR: parity off", not core["jobs"]["parity"]) check("core PR: security-audit off (no deps change)", not core["jobs"]["security_audit"]) - check("core PR: 6 fast gap shards", core["gap"] == {"mode": "fast", "total": 6, "shards": [1, 2, 3, 4, 5, 6], "update_snapshot": False}) + check("core PR: 12 fast gap shards", core["gap"] == {"mode": "fast", "total": 12, "shards": list(range(1, 13)), "update_snapshot": False}) check("core PR: cargo-test scoped", core["cargo_test_scope"] == "pr") deps = plan("pull_request", "refs/pull/1/merge", changed=["Cargo.lock"]) @@ -463,7 +467,7 @@ def check(name: str, cond: bool): "shards": list(range(1, PERRY_INTEGRATION_SHARDS + 1)), }, ) - check("full: 12 auto-optimize gap shards", full["gap"] == {"mode": "full", "total": 12, "shards": list(range(1, 13)), "update_snapshot": False}) + check("full: 24 auto-optimize gap shards", full["gap"] == {"mode": "full", "total": 24, "shards": list(range(1, 25)), "update_snapshot": False}) check("full: parity sharded (6h-cap kill, 2026-08-16)", full["parity"]["total"] >= 2 and full["parity"]["shards"][0] == 1) check("full: full GC matrix has four shards", full["gc_stress"] == {"mode": "all", "total": 4, "shards": [1, 2, 3, 4]}) diff --git a/test-files/test_gap_gc_container_value_rooting.ts b/test-files/test_gap_gc_container_value_rooting.ts index 93834de786..fec0ab7258 100644 --- a/test-files/test_gap_gc_container_value_rooting.ts +++ b/test-files/test_gap_gc_container_value_rooting.ts @@ -1,3 +1,4 @@ +// parity-env: PERRY_GC_MOVING_LOOP_POLLS=1 PERRY_GC_SCHEDULE_SEED=7949 PERRY_GC_SCHEDULE_RATE=1 PERRY_GC_SCHEDULE_ALLOC_KB=4 PERRY_GC_PROTECT_FROMSPACE=1 PERRY_GC_VERIFY_EVACUATION=1 // #7949: JS values retained in ordinary Rust containers across allocating calls. // // `Object.groupBy` / `Map.groupBy` accumulate every `(key, item)` pair into a