Skip to content

build(deps): bump @effect/platform-node-shared from 4.0.0-rc.112 to 4.0.0-rc.115 - #15

Closed
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/npm_and_yarn/effect/platform-node-shared-4.0.0-rc.114
Closed

dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/npm_and_yarn/effect/platform-node-shared-4.0.0-rc.114

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Bumps @effect/platform-node-shared from 4.0.0-rc.112 to 4.0.0-rc.115.

Release notes

Sourced from @​effect/platform-node-shared's releases.

@​effect/platform-node-shared@​4.0.0-rc.115

Patch Changes

@​effect/platform-node-shared@​4.0.0-rc.114

Patch Changes

Commits

@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code labels Sep 14, 2026
@dependabot dependabot Bot changed the title build(deps): bump @effect/platform-node-shared from 4.0.0-rc.112 to 4.0.0-rc.114 chore(deps): bump @effect/platform-node-shared from 4.0.0-rc.112 to 4.0.0-rc.115 Sep 15, 2026
@dependabot
dependabot Bot force-pushed the dependabot/npm_and_yarn/effect/platform-node-shared-4.0.0-rc.114 branch 5 times, most recently from 2ca6cb0 to 4233d14 Compare September 17, 2026 16:27
@dependabot dependabot Bot changed the title chore(deps): bump @effect/platform-node-shared from 4.0.0-rc.112 to 4.0.0-rc.115 build(deps): bump @effect/platform-node-shared from 4.0.0-rc.112 to 4.0.0-rc.115 Sep 18, 2026
@dependabot
dependabot Bot force-pushed the dependabot/npm_and_yarn/effect/platform-node-shared-4.0.0-rc.114 branch 5 times, most recently from 36babbc to a082e65 Compare September 20, 2026 00:05
Bumps [@effect/platform-node-shared](https://github.com/Effect-TS/effect/tree/HEAD/packages/platform-node-shared) from 4.0.0-rc.112 to 4.0.0-rc.115.
- [Release notes](https://github.com/Effect-TS/effect/releases)
- [Commits](https://github.com/Effect-TS/effect/commits/@effect/platform-node-shared@4.0.0-rc.115/packages/platform-node-shared)

---
updated-dependencies:
- dependency-name: "@effect/platform-node-shared"
  dependency-version: 4.0.0-rc.114
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot
dependabot Bot force-pushed the dependabot/npm_and_yarn/effect/platform-node-shared-4.0.0-rc.114 branch from a082e65 to d0e485a Compare September 20, 2026 00:32
@dependabot @github

dependabot Bot commented on behalf of github Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #59.

@dependabot dependabot Bot closed this Sep 20, 2026
@dependabot
dependabot Bot deleted the dependabot/npm_and_yarn/effect/platform-node-shared-4.0.0-rc.114 branch September 20, 2026 00:34
systemfsoftware-maker added a commit that referenced this pull request Oct 13, 2026
Fixes full-path receipt finding #15 (heavy-suites-judge-every-main-commit)
on a359a82.

The group was bench-${{ github.sha }} for both triggers, so a
workflow_dispatch on main's head shared, and could replace, the pending
push run for that commit. A push now groups by github.sha and a
dispatch by github.run_id, with cancel-in-progress false, as the rule's
Concurrency bullet requires. Why side A is HEAD^1 rather than the last
green commit is stated in the lane's cost header (#14). Plan:
docs/plans/2026-10-13-0416-ci-bench-off-pr-plan.md U11.
systemfsoftware-maker added a commit that referenced this pull request Oct 13, 2026
Fixes full-path receipt finding #14 (heavy-lanes-state-their-daily-minutes)
on a359a82.

bench.yml now opens with the cost header the rule asks for:
- the daily figure, about 267 runner-min/day (241-319), priced on the
  run every push to main starts;
- that run's shape, the full corpus against the first parent, and why
  side A is HEAD^1 rather than the last green commit (the corpus is a
  fixed workload; an older base selects no smaller workload and would
  credit several pushes' change to one commit), which also answers #15;
- the per-run cost, 15.3-20.3 job-min, with the seven run ids;
- the 7-day first-parent merge count, 110 in 2026-10-06T01:54Z to
  2026-10-13T01:54Z (15.71/day);
- whether the lane can starve PR CI, from the same week's job
  timestamps: only once about 40 jobs are already running; the replay
  without the pull_request Bench lowers hours at 40+ jobs from 11.98 to
  11.45.

Every figure is from GitHub Actions job timestamps already reported in
the PR's Bench cost section; nothing was rerun. Plan:
docs/plans/2026-10-13-0416-ci-bench-off-pr-plan.md U12.
ryanleecode pushed a commit that referenced this pull request Oct 13, 2026
* ci(bench)!: bench each main commit against its first parent

The bench leaves the pull-request path. bench.yml runs on push to main
(docs-only pushes excluded) and on workflow_dispatch, with concurrency
bench-${{ github.sha }} and no cancel, so no PR pays for or waits on it.

- Side A is the first parent, side B the pushed commit; both are worktrees
  under RUNNER_TEMP with their own released tarballs and frozen install,
  and the checkout holds only the harness.
- Every in-process deadline is gone: BENCH_DEADLINE_MS, the setup budget,
  the run deadline, BENCH_RUN_TIMEOUT_MS, and the setup-timed-out,
  budget-exceeded, timed-out and timeout shapes. Every timeout-minutes is
  60; that job timeout is the only kill.
- The report carries the leg's wall time (from JOB_STARTED_AT) against a
  10-minute target, never enforced, and schemaVersion moves to 2.0.
- Only a leg's total decides a regression (non-overlapping samples and
  |delta| >= max(3% of A, 10 ms)). The regression block names the commit,
  its parent, total then every regressed phase, and the next action: a
  revert PR or root-fix P0 on main, speed evidence only elsewhere.
- Every run executes from RUNNER_TEMP/bench-run, so both sides record the
  same project root, inputs digest and mutant ids. Bench configs reference
  plugins relative to the config file so they survive the move.

Plan: docs/plans/2026-10-12-1800-ci-bench-off-pr-plan.md (layer 1; the
enterprise install is layer 2).

BREAKING CHANGE: bench-report.json schemaVersion 2.0 drops the
setup-timed-out and budget-exceeded abort codes and the timed-out run exit,
and adds ref, leg and the regression block.

* docs(bench): say an environment-incomplete abort writes no report

Review finding (correctness, P3): the README said every aborted leg uploads
its report, but main.ts publishes environment-incomplete without writing
bench-report.json or the step summary.

* ci(bench): drop the hand-written path filter from the main trigger

Root amendment 2026-10-12: no change classifier where Turbo can do the job.
paths-ignore (**/*.md, docs/**) skipped none of 11 sampled main commits;
turbo query affected skips three of them. Every push now benches every
leg until layer 1b scopes legs with turbo query affected.

Plan: docs/plans/2026-10-12-1854-ci-bench-off-pr-plan.md supersedes the
1800 plan and records the turbo-query evidence and rule-4 reasons.

* docs(plan): bench every main SHA; defer Turbo affected-only leg selection

Sub-conductor ruling 2026-10-12: the acceptance is a comparison per main
SHA, so Turbo's affected-packages answer stays evidence, not a leg filter.
The 1926 plan supersedes 1854: layer 1b is dropped, KD10 keeps Turbo as
the owner of builds and cache and adds no classifier, KD11 defers
affected-only selection to root.

* fix(bench): name phase-only slowdowns instead of claiming no phase changed

A summarized report with no regression said "no project/phase changed past
the signal threshold" even when its table showed a phase that regressed under
an unchanged total. The notice is now titled "Bench phase-only slowdown", says
no leg total crossed the regression threshold, and lists each such cell as a
phase-only slowdown. A new law drives a check-only slowdown through
summarizeBench and renderBenchReport.

The plan moves to docs/plans/2026-10-12-2032-ci-bench-off-pr-plan.md
(supersedes 1926) and adds the CONST-W3 declaration for the bench.yml edits,
the corrected cause of the stream-undecodable PR runs (#298 changes the
stream contract), and that case as a known limit.

* docs(plan): list every bench.yml edit in the CONST-W3 waiver and scope the PR-run evidence

Review of eec5cfa found that the waiver called side B the checkout (it is the bench-b worktree) and left out the checkout ref, Turbo cache and harness install edits. Run 38284821646 also had a budget-exceeded abort on one leg, so the Problem Frame now scopes stream-undecodable to the other three legs.

* test(e2e-core): move the bench decision checks beside their workflows as laws

bench-decisions.integration.test.ts fed hand-written NDJSON lines and
report text to the pure readBenchRun and coveringTestFiles workflows and
asserted their decision fields. Under root's 2026-10-12 testing law an
integration test drives the real product and asserts only observable
outcomes, and a pure decision gets property laws beside it (CONST-T12,
CONST-T14). This layer had to change the file (ReadBenchRunCommand's
exit field), so it is deleted rather than carried.

The behaviours no other suite pinned are now laws over the production
schemas: testsExecuted sums every drawn MutantCost, the first undecodable
line is named by its 1-based number among blank and decodable lines, a
verdict count other than one is stream-invalid, verdict phase durations
are carried as reported or refused when absent, covering test files are
the sorted distinct holders, and a non-JSON report is refused. The
legacy-line decode stays pinned by the cli-contract wire-line suite.

The plan moves to docs/plans/2026-10-12-2154-ci-bench-off-pr-plan.md
(supersedes 2032) with the widened edit scope and test admission rows.

* refactor(bench): keep the bench's new decisions in test/bench

Root's 2026-10-13 scope law puts no new code in test/e2e-core. The
layer's four new modules and their laws move to test/bench/src, which is
their only consumer: run-path.schema, plan-run-path and settle-run-path
(the fixed run path) and measure-leg (the leg wall time). e2e-core's
mod.ts is back to main.

measureLeg now decides a bench-local LegClock (LegElapsed or
LegClockBehind) that main.ts maps onto the report's LegTime:
make-body-purity forbids a decision from constructing a class imported
from another package, and e2e-core cannot import test/bench.

test/bench gains a test lane shaped like test/checker-parity: a test
script, a vitest config with inSourceSchemaLaws, tsconfig.test.json and
lint:tsgo over it. The plan moves to
docs/plans/2026-10-13-0223-ci-bench-off-pr-plan.md (supersedes 2154).

* fix(bench): abort an outside-tree run path as a defect

Review of f1da499 (MiniMax lenses, report-only) found two defects in
the bench's run path:

- planRunPath's identity law drew cwd and CLI tails of length one or
  more, so the enterprise shape (cwd equal to the tree) was never
  generated. Dropping the `path === tree` operand left the law green;
  with empty tails allowed it now fails.
- A cwd or CLI outside its side's tree aborted as run-path-move-failed,
  whose next action says to fix the runner. It is a bench bug, so it
  now aborts as defect. The README lists that case.

The plan moves to docs/plans/2026-10-13-0238-ci-bench-off-pr-plan.md
(supersedes 0223) with an accurate split of the e2e-core law files.

* fix(bench): name both causes in the run-path-move-failed action

63ba7bb sent an outside-tree run path to `defect`. Review of that head
found two problems: it contradicted KTD3, and `defect`'s next action asks
for a stack trace, which a typed failure does not have. So the outside-tree
case aborts as run-path-move-failed again. That code's next action, which
this layer added, now names both causes. An OS error needs a runner fix; a
path outside the tree is a bug in side setup. The README matches.

The plan moves to docs/plans/2026-10-13-0258-ci-bench-off-pr-plan.md
(supersedes 0238), with U4 brought back in line with KTD3.

* docs(plan): plan the pack-violation fixes for the bench lane

Supersedes the 0258 plan. Root (2026-10-13) requires every confirmed pack
violation in the a359a82 full-path receipt to be fixed, not waived.
Adds KD12-KD15 and units U7-U12, the e2e-core boundary (one in-source
refusal block per refined e2e-core file, LegTime as a data union), and
test-admission rows for the refusal properties and the settle law.

* fix(bench): carry run-path settle outcomes as tagged causes

Fixes full-path receipt findings #8 (four-channel-contracts) and #11
(tagged-unions-over-state-by-presence) on a359a82.

The settle command took restoreError and runFailure as nullable
Cause.pretty strings and decided on their presence. It now takes two
tagged unions, RunPathMoveBack (MovedBack | MoveBackFailed { cause }) and
RunPathRunEnd (RunSucceeded | RunFailed { cause }), and matches on the
move-back. RunPathUnrestored carries cause: S.optional(S.Unknown) and the
run's end instead of strings; the service passes each Exit's Cause as is.
Text is rendered once, in the error's message, when the report's reason
is built.

The settle law draws the production SettleRunPathCommand and asserts
unrestored iff the move-back failed, with both causes carried by
identity. Plan: docs/plans/2026-10-13-0416-ci-bench-off-pr-plan.md U7.

* fix(bench): make the report's leg time plain data

Fixes full-path receipt finding #9 (data-only-schema-classes) on a359a82.

LegMeasured and LegNotMeasured were TaggedClass variants carrying a
LegTime type id that no Workflow.make checks; LegTime is only a field of
BenchReport. LegTime is now an S.TaggedUnion of the same two cases, so
bench-report.schema.ts declares two fewer classes and no type id, and the
encoded shape is unchanged. main.ts and the render law construct through
LegTime.cases.

Evidence: tsc, oxlint and lint:tsgo clean in test/e2e-core and
test/bench; vitest 364/364 in test/e2e-core (the 3 fewer tests are the
generated codec laws of the two deleted classes; LegTime's own laws
remain) and 39/39 in test/bench. Plan:
docs/plans/2026-10-13-0416-ci-bench-off-pr-plan.md U8.

* fix(bench): refine the leg's elapsed time and the report's ref

Fixes full-path receipt finding #10 (invariants-as-refinements) on
a359a82, both fields named by root.

- LegElapsed.wallMs was S.Finite, so a negative elapsed time decoded as
  the "clock advanced" variant. It is now finite and >= 0, with the
  invariant stated in the check's message.
- BenchReport.ref was S.String while SummarizeBenchCommand.ref is
  S.NonEmptyString. It is now S.NonEmptyString, and main.ts reads
  BENCH_REF with Config.NonEmptyString, so an empty value takes the
  existing environment-incomplete path (main.ts program, UNKNOWN_REF)
  instead of failing at BenchReport.make.

Evidence: tsc, oxlint and lint:tsgo clean in test/e2e-core and
test/bench; vitest 364/364 and 39/39. The refusal properties for these
refinements land with #12. Plan:
docs/plans/2026-10-13-0416-ci-bench-off-pr-plan.md U9.

* fix(bench): state the refusal boundary of every refinement this PR adds

Fixes full-path receipt finding #12 (refusals-beside-generated-laws) on
a359a82.

The generated schema laws draw only accepted values. Each refined schema
the PR adds or changes now states its refusals in its own file, in one
import.meta.vitest block whose subject is a private predicate. Each
block draws the unrefined base, appends boundary values to every draw,
and compares acceptance with a predicate written from the domain:

- test/bench: run-path.schema.ts (all ten path fields), leg-clock.schema.ts
  (elapsed ms finite and >= 0), and the commands of plan-run-path,
  settle-run-path and measure-leg.
- test/e2e-core, the narrowest arrangement under root's scope law (plan
  KD13: no new file, export, dependency, config or helper):
  bench-report.schema.ts (LegTargetMs, ref, abort codes = the codes with a
  next action, rendered exit 0|1), bench-summary.schema.ts (RegressedMetric
  and PhaseRegression fields), bench-run.schema.ts (failure codes without
  timeout, exitCode a safe integer, never null) and summarize-bench (ref).

Evidence: tsc, oxlint and lint:tsgo clean in both packages; vitest
44/44 in test/bench (+5) and 375/375 in test/e2e-core (+11). The pack's
widen-once check is not run: root forbids hand-applied probes. Plan:
docs/plans/2026-10-13-0416-ci-bench-off-pr-plan.md U10.

* ci(bench): give each dispatch its own concurrency group

Fixes full-path receipt finding #15 (heavy-suites-judge-every-main-commit)
on a359a82.

The group was bench-${{ github.sha }} for both triggers, so a
workflow_dispatch on main's head shared, and could replace, the pending
push run for that commit. A push now groups by github.sha and a
dispatch by github.run_id, with cancel-in-progress false, as the rule's
Concurrency bullet requires. Why side A is HEAD^1 rather than the last
green commit is stated in the lane's cost header (#14). Plan:
docs/plans/2026-10-13-0416-ci-bench-off-pr-plan.md U11.

* ci(bench): state the lane's measured runner-minutes in its header

Fixes full-path receipt finding #14 (heavy-lanes-state-their-daily-minutes)
on a359a82.

bench.yml now opens with the cost header the rule asks for:
- the daily figure, about 267 runner-min/day (241-319), priced on the
  run every push to main starts;
- that run's shape, the full corpus against the first parent, and why
  side A is HEAD^1 rather than the last green commit (the corpus is a
  fixed workload; an older base selects no smaller workload and would
  credit several pushes' change to one commit), which also answers #15;
- the per-run cost, 15.3-20.3 job-min, with the seven run ids;
- the 7-day first-parent merge count, 110 in 2026-10-06T01:54Z to
  2026-10-13T01:54Z (15.71/day);
- whether the lane can starve PR CI, from the same week's job
  timestamps: only once about 40 jobs are already running; the replay
  without the pull_request Bench lowers hours at 40+ jobs from 11.98 to
  11.45.

Every figure is from GitHub Actions job timestamps already reported in
the PR's Bench cost section; nothing was rerun. Plan:
docs/plans/2026-10-13-0416-ci-bench-off-pr-plan.md U12.

* docs(plan): record the landed concurrency, settle law and header shape

Supersedes the 0416 plan. R3, U1 and the CONST-W3 list now carry the
push-sha/dispatch-run-id concurrency group from 7d962fc. U7's test
sentence matches the landed settle law (it draws the production command
and asserts the carried causes, not message text, whose oracle would
copy Cause.pretty). U12 records that the HEAD^1 rationale lives in the
cost header.

* docs(plan): say where the HEAD^1 rationale lives in U11

Supersedes the 0434 plan. U11 no longer claims an inline comment; the rationale is in the cost header (U12).

* docs(plan): plan the fixes for every confirmed row of the b30908c receipt

Supersedes the 0435 plan. Root's merge bar (2026-10-13) requires a fixing
commit on the reported head for every confirmed pack violation and accepted
finding. Adds KD16 (push runs scoped from the last green main commit, legs
selected by Turbo's affected set), KD17-KD19 and units U13-U18.

* fix(bench): build the report-unwritable fallback with the report builder

Fixes b30908c full-path receipt finding #5 (maintainability: the fallback
hand-rebuilt every BenchReport field). reportOf now takes report runs, and
writeReport's fallback calls it with the report's own fields.

Plan: docs/plans/2026-10-13-0554-ci-bench-off-pr-plan.md U13.

* fix(bench): walk the phase verdicts once in the report renderer

Fixes b30908c full-path receipt finding #4 (maintainability: two
near-identical verdict walks). One traversal yields each improved or slower
phase change; the improved and phase-only lists filter it. Only lines this
PR added change.

Plan: docs/plans/2026-10-13-0554-ci-bench-off-pr-plan.md U14.

* fix(bench): move the corpus schema into test/bench and state its refusals

Fixes b30908c full-path receipt finding #2 (testing: the corpus empty-repo
refusal lost its only test when bench-decisions.integration.test.ts was
deleted).

bench-corpus.schema.ts is consumed only by the bench, so it moves from
test/e2e-core/src to test/bench/src, unchanged, and e2e-core's mod.ts drops
its export. Beside it, one in-source refusal block states every refinement
the corpus carries: each text field refuses only the empty string, and each
list (repo, mutate, testFiles) refuses only the empty list. The repo list's
refusal is the empty-repo case the deleted test covered; the bench aborts
such a corpus as corpus-unreadable.

test/bench: 54 tests (44 + 2 refusal properties + 8 generated codec laws);
test/e2e-core: 367 (375 less the moved schema's 8 codec laws).

Plan: docs/plans/2026-10-13-0554-ci-bench-off-pr-plan.md U15 (amended in
the next plan revision: a move, not a workflow).

* fix(bench): decide every run-path abort in a lawed workflow

Fixes b30908c full-path receipt finding #1 (testing: the three run-path
abort codes were produced only in run-bench.service.ts, which no test
reaches).

Each way the run path can fail is now a tagged failure carrying its cause:
RunPathUnlisted, RunPathOutsideTree, RunPathOccupied, RunPathMoveInFailed
and RunPathUnrestored (run-path.schema.ts). abortRunPath
(abort-run-path.workflow.ts) decides the abort for each: occupied ->
run-path-occupied, unrestored -> run-path-unrestored, the rest ->
run-path-move-failed, with a reason that names the side and the paths.
run-bench.service.ts keeps only the listing, the two renames and the run,
and routes every failure through the decision.

The law draws RunPathFailure from its production schema and checks the code
and that the reason names the side and paths. In-source refusal properties
cover the new path fields and each abort variant's code. An in-process test
of the renames is refused by the gates (tests/ may import only a package's
public surface, and the bench has none), so the A/A dispatch remains the
evidence for the rename order. test/bench: 68 tests.

Plan: docs/plans/2026-10-13-0554-ci-bench-off-pr-plan.md U16 (amended in
the next plan revision: a lawed decision, not an integration test).

* refactor(bench): call side A the base, not the parent

Side A is no longer always the first parent: on a push it is the lane's
last green main commit. SummarizeBenchCommand.parentSha and
PhaseRegression.parentSha become baseSha, and the regression annotation,
the step-summary table header and the regression section say "base".
Every renamed line is one this PR added (origin/main has no parentSha or
"parent" wording in these files), so the e2e-core boundary holds.

Plan: docs/plans/2026-10-13-0554-ci-bench-off-pr-plan.md KD18.

* fix(bench): bench a push from the lane's last green main commit, affected legs only

Fixes b30908c full-path receipt finding #7 (ci-wall-clock
heavy-suites-judge-every-main-commit: bench.yml compared each push with
HEAD^1 instead of the lane's last green commit).

A plan job now picks side A and the legs before any bench job starts:

- selectLegs (select-legs.workflow.ts) is the decision. On a push, side A is
  the newest main commit whose push-triggered Bench run concluded success and
  which is an ancestor of the pushed commit. A leg runs when Turbo's affected
  set holds the package containing its entry or an engine directory every leg
  builds. The full corpus runs on a dispatch, when no green ancestor exists
  (side A is then the first parent), and when the lane's own inputs changed
  (test/bench, bench.yml, the released-tarballs action, the flake pin). A
  commit with no green ancestor and no first parent is refused as NoBenchBase.
- plan-legs.service.ts gathers the inputs: the lane's green push runs (gh api),
  ancestry and the diff (git), and `turbo query affected --packages`. It fails
  when the checkout has uncommitted changes, because Turbo adds them to the
  affected set (seen locally: a dirty test/bench marked every leg affected).
- plan.ts writes `base` and `legs` to GITHUB_OUTPUT and the choice to the step
  summary; bench.yml's plan job runs it with `actions: read`, the bench job
  uses its base for side A and BENCH_BASE_SHA, and it is skipped when no leg
  is selected.
- engine-dirs.ts holds the engine directories, now shared by prepare-side and
  the plan; command.service.ts holds the command runner, moved out of
  prepare-side so the plan reuses it.

Laws: select-legs covers dispatch, no green ancestor, lane inputs changed, and
affected-only selection (drawing a prefix-without-slash path; the law refutes a
`startsWith` without the `/` boundary). In-source refusal laws cover the new
schemas. Smoke: the real plan program on this checkout (push, dispatch) and,
with a gh shim naming the parent as green, on 3cb1342, ddeb67a and 61d40db.

Plan: docs/plans/2026-10-13-0554-ci-bench-off-pr-plan.md U17, KD16.

* docs(plan): record how U15-U17 landed

Supersedes the 0554 plan. U15 moves the corpus schema into test/bench with
its refusals instead of adding a resolveTarget workflow; U16 decides every
run-path abort in a lawed workflow, because the gates refuse an integration
test of a package with no public surface; U17 adds plan-legs.service.ts
(refusing a dirty checkout, since Turbo counts uncommitted changes) and moves
the command runner into command.service.ts. The edit scope records the one
file that leaves e2e-core, and the test admission table records the refused
and withdrawn tests.

* ci(bench): price the cost header for affected-only push runs

Keeps b30908c receipt row #14 (heavy-lanes-state-their-daily-minutes)
true after #7's selection changed the run shape.

The header now states the plan-job-then-selected-legs shape, each leg's
median job-minutes (range) over the seven dispatch runs, the plan job's
0.40-0.71 min (the same setup steps as timed in those runs, plus the plan
step timed locally), and the week's price: the real plan program run over
all 110 first-parent main commits of 2026-10-06T01:54Z..2026-10-13T01:54Z,
each with its parent as side A, picks no leg for 16, one for 2 and four for
92 (64 for changed lane inputs), so 1,655 job-min (1,333-1,948), about 236
runner-min/day (190-278). The PR CI replay stays as measured for the
full-corpus shape; the selection only removes jobs from it.

Plan: docs/plans/2026-10-13-0629-ci-bench-off-pr-plan.md U18.

* docs(plan): plan the fixes for the c0cf821b review's confirmed findings

Supersedes the 0629 plan. Fixes c0cf821b #4 (KTD2 named a
run-path.service.ts that never landed) and the plan half of #6 (R13 and the
summary still said first-parent side A).

KD20 records root's merge bar for this round: every confirmed finding of the
c0cf821b review of 5a088c6 gets a fixing commit, and the final receipt is a
new full-path review of the head that holds them. U19-U26 plan one fix per
confirmed finding group: the package description, an escaped plan-job
annotation, the plan job's wall time in its step summary, Turbo's wire decoded
into paths, driver modules off the reserved *.service.ts suffix, a lawed
green-ancestor choice, and the run's regression as a tagged union.

* docs(bench): describe the green-ancestor side A in the package description

Fixes c0cf821b #1, #3 and #6 (correctness, project-standards and
maintainability, all confirmed): test/bench/package.json still said each
push is benched against its first parent. It now states the rule the plan
job applies, the same one README.md and the bench.yml header state.

Plan: docs/plans/2026-10-13-0658-ci-bench-off-pr-plan.md U20.

* fix(bench): escape the plan job's ::error annotation

Fixes c0cf821b #5 (maintainability, confirmed): failWith printed
`::error title=<title>::<message>` raw, and a refusal's message can hold
multi-line command output (git status, gh's error body), which breaks the
single-line workflow command. The title is now escaped as a property (%,
CR, LF, colon, comma) and the message as data (%, CR, LF), the same
replacement set e2e-core's renderer uses; that helper is private and KD13
forbids a new e2e-core export, so plan.ts keeps its own copy.

Smoke: a plan run against a repository gh cannot find prints one
`::error title=Bench plan failed::...%0A...` line.

Plan: docs/plans/2026-10-13-0658-ci-bench-off-pr-plan.md U21.

* fix(bench): write the plan job's wall time to its step summary

Fixes c0cf821b #13 (ci-wall-clock one-stuck-job-backstop, confirmed): the
plan job had the 60-minute backstop but wrote no wall time to its step
summary, so a stuck plan job could not be told from a slow one.

The plan job's first step now records JOB_STARTED_AT, as the bench job's
does, and plan.ts appends the job's wall time in a finalizer, so the line is
written after a selection, a refusal and an incomplete environment alike.

Smoke: the plan program on a dispatch (exit 0), on an unknown repository
(exit 1) and with no GITHUB_SHA (exit 1) each appended
"**Plan job wall time:** N s through the plan step".

Plan: docs/plans/2026-10-13-0658-ci-bench-off-pr-plan.md U22.

* fix(bench): decode Turbo's affected-packages JSON into the paths the plan uses

Fixes c0cf821b #10 (schema-laws data-only-schema-classes) and #11
(schema-laws rich-type-over-foreign-encoded), both confirmed:
TurboAffectedPackage and TurboAffected were schema classes no contract
required, and plan-legs walked Turbo's data.affectedPackages.items envelope
itself.

The wire is now a private S.Struct, and TurboAffectedPaths decodes it with
S.decodeTo into ReadonlyArray<string>, so plan-legs receives the paths and
nothing of Turbo's envelope. The generated codec laws now cover
TurboAffectedPaths in place of the two classes.

Plan: docs/plans/2026-10-13-0658-ci-bench-off-pr-plan.md U23.

* refactor(bench): move the driver modules off the reserved *.service.ts suffix

Fixes c0cf821b #8 (cell-architecture service-and-layer-boundaries,
confirmed): command.service.ts and plan-legs.service.ts were driver-backed
modules (ChildProcessSpawner, gh, git, turbo) under the suffix the rule
reserves for a Context.Service contract, and test/bench declares no
Context.Service. They become command.ts and plan-legs.ts, names the rule
leaves free for a driver-backed module, and their three importers follow.
prepare-side.service.ts and run-bench.service.ts predate this PR and are
unchanged (the review ruled them pre-existing).

Plan: docs/plans/2026-10-13-0658-ci-bench-off-pr-plan.md U24.

* fix(bench): choose side A in a lawed decision, the newest green ancestor

Fixes c0cf821b #2 (testing, confirmed): the push-path side A choice lived
in plan-legs, which took the first SHA in the API's listing that git
called a strict ancestor. No test covered it, and the choice depended on
the API's list order.

chooseBase (new workflow) takes every green Bench push run on main
(GreenRun: SHA, creation time in epoch seconds, and whether it is an
ancestor of the pushed commit), the event and the first parent. On a
push it picks the newest run that is an ancestor and not the pushed
commit, else the first parent ('no-green-ancestor'); on a dispatch, the
first parent ('dispatch'); with no first parent, NoBenchBase. selectLegs
now takes that BaseChoice plus the diff against it and can no longer
fail. The base must be chosen before the diff is computed, so the choice
cannot live inside selectLegs as U25 first said; the plan amendment
follows.

plan-legs lists the runs through gh's --jq (created_at via
fromdateiso8601), decodes them with GreenRunsJson, asks git once per run
whether it is an ancestor, and computes the diff only for a GreenBase.

Laws: chooseBase's dispatch and push rules over drawn GreenRuns, with the
head drawn as a green run's SHA. Two mutants were refuted: taking the
first listed run, and not excluding the pushed commit. selectLegs' laws
are now keyed on the base they receive. Refusal laws cover GreenRun's
safe-integer seconds, FirstParentReason and both commands.

Plan: docs/plans/2026-10-13-0658-ci-bench-off-pr-plan.md U25.

* docs(plan): choose side A in its own decision before selecting legs

Supersedes the 0658 plan. U25 as written put the green-ancestor choice
inside selectLegs, but selectLegs reads the diff against side A, so the
base has to be chosen before that diff exists. U25 now names chooseBase
(new) as the decision; selectLegs takes its BaseChoice. The Test Admission
table splits the select-legs row, adds the choose-base law file with the
bugs it catches, and records the U25 smoke for plan-legs.

* fix(e2e-core): decide a run's regression as a tagged union, not NullOr

Fixes c0cf821b #12 (schema-laws tagged-unions-over-state-by-presence,
confirmed): BenchSummary.regression and the summarized report outcome were
S.NullOr(PhaseRegression), so "no leg regressed" was the absence of a
value, and the renderer probed it with Option.fromNullishOr.

Regression = S.TaggedUnion({ PhaseRegressed, NoLegRegressed }) replaces
PhaseRegression and its 'phase-regressed' code literal. summarizeBench
decides NoLegRegressed explicitly, and renderBenchReport matches the two
tags with Match.valueTags for both the annotation and the markdown block.
The annotation and block title stay 'phase-regressed', now a renderer
constant, so the rendered verdict line is unchanged. The refusal law on
the code literal becomes one on the discriminant: only the two tags
decode.

The law files lose their `=== null` / `!== null` checks, which still
compiled against the union but would have passed vacuously; each is now a
tag check. test/bench/README.md says the JSON report carries the tag.

origin/main has none of these lines, so every edited line is one this PR
added (KD13). report schema 2.0, bumped by this PR, covers the shape change.

Plan: docs/plans/2026-10-13-0711-ci-bench-off-pr-plan.md U26.

* docs(plan): plan the b2fe30db review's fixes and route two findings to root

Supersedes the 0711 plan. Fixes b2fe30db #2 (testing-confirmed: KD13 said
no e2e-core export was added, but the pack fixes added LegTargetMs,
LegTime, RegressedMetric, Regression and PhaseRegressed) and answers #1
(feb5085's subject is scoped e2e-core; rewriting it needs a force push,
and the squash merge carries only the PR title).

KD21 records the round. U27-U29 fix #12 (GreenRunsJson loses its
generated laws), #11 (corpus schemas as data classes) and #6 (two
stderr-tail helpers). #9 (pin Turbo's --packages output) and #3 (test
atRunPath's renames) ask for tests the admission gate refuses: a Turbo
pin spawns git and turbo, and atRunPath is a private executor helper. The
repository's real-Turbo pins live in scripts/ under PR #319, so both go
to root. The Turbo semantics the plan job relies on were measured on
2.10.12 in a scratch repository and are recorded in KD21.

* fix(bench): root the green-run listing codec at the schema vocabulary

Fixes b2fe30db #12 (schema-laws rich-type-over-foreign-encoded,
confirmed): GreenRunsJson was GreenRunListing.pipe(...), a chain rooted
at a module-local name, which effect-schema-discovery skips. The codec
the plan job decodes gh's output with therefore had no generated
round-trip or encode-stability law. It is now
S.Array(GreenRunListing).pipe(S.fromJsonString), and
∀x_GreenRunsJson_=x and ∀x_GreenRunsJsonEnc_=x run.

Plan: docs/plans/2026-10-13-0749-ci-bench-off-pr-plan.md U27.

* fix(bench): declare the bench corpus as plain data

Fixes b2fe30db #11 (schema-laws data-only-schema-classes, confirmed):
BenchRepoEntry, BenchEnterpriseCorpus and BenchCorpus were S.Class
declarations, though none is a Workflow.make command, a decision variant
or a tagged error; every consumer only reads their fields. They are now
S.Struct schemas with exported types. BenchCorpusJson keeps its S.*-rooted
chain, so its generated laws still run, and the refusal block is
unchanged.

Plan: docs/plans/2026-10-13-0749-ci-bench-off-pr-plan.md U28.

* refactor(bench): keep one stderr-tail helper for the bench's commands

Fixes b2fe30db #6 (maintainability, confirmed): command.ts kept a
4000-character tail over a CommandOutcome, and run-bench.service.ts a
second 4096-character tail over a string, both added by this PR.
command.ts now owns the one budget (4096, private) and exports
tailOf(text); runChecked, the interrupt message and runCli's stderr
collector all use it. A setup failure keeps 96 more characters of
output.

Smoke: a plan run whose gh exits 7 after 6000 bytes of stderr fails with
an annotation that carries the last 4096 characters.

Plan: docs/plans/2026-10-13-0749-ci-bench-off-pr-plan.md U29 (the plan
says both names are exported; only tailOf has an importer, so the budget
stays private).

* fix(bench): pin Turbo's affected-packages output in the repo scripts lane

Fixes b2fe30db #9 (P1, boundary-testing pin-dependency-semantics, E7):
the plan job's Turbo --packages output was pinned only by a measurement.

scripts/turbo-affected-packages.test.ts runs the plan job's own Turbo
arguments (turboAffectedArgs, now shared with plan-legs.ts) through
node_modules/.bin/turbo, the binary `pnpm exec turbo` resolves to, in
scratch pnpm workspaces, and decodes the output through TurboAffectedPaths,
the schema plan-legs.ts decodes with. It pins three facts: a changed package
reports its repo-relative directory (packages/a), a root file reports "",
and no change reports [].

TurboAffectedPaths moves to turbo-affected.schema.ts: the scripts lane
type-checks with Deno, which cannot resolve bench-plan.schema.ts's in-source
law block (@systemfsoftware/vitest, import.meta.vitest). Its generated codec
laws still run there.

scripts/deno.json takes #319's permission hunk byte for byte, plus an
effect/ import-map entry, and scripts/assert.ts is #319's file byte for
byte, so merging #319 later is a no-op for both. Deno applies the grant
only with -P, which ci.yml:137 does not pass yet; root's workflow owner
adds it in a separate PR. Until then these three tests fail in the Repo
scripts tests step with NotCapable, as #319's do.

Plan: docs/plans/2026-10-13-0954-ci-bench-off-pr-plan.md U31, KD22.

* ci(bench): give each Bench leg job a 20-minute timeout

Root's E10 ruling: per-SHA concurrency groups stay, because every main
SHA must be judged, and each leg job is capped at 20 minutes instead of
60. A leg's longest measured job is 7.68 job-minutes. The plan job keeps 60.

Plan: docs/plans/2026-10-13-0954-ci-bench-off-pr-plan.md U32, KD2.

* docs(plan): record root's resolution of E3-E11 and the 20-minute leg cap

Supersedes the 0749 plan. KD22 records root's rulings of 2026-10-13: #9
fixed by the scripts-lane Turbo pin (U31), inert until ci.yml passes -P in
a separate root-owned PR; E10's 20-minute leg cap (U32, KD2); E8 and E11
closed by A/A run 38375500452; #4 and E4 accepted; E9 satisfied by #335.

* docs(bench): state the 20-minute leg-job timeout in the package description and plan

Fixes the f13b992..aabe4c2 correctness lens finding #2 (P3, confirmed):
cf39161 lowered each Bench leg job's timeout to 20 minutes, but the
@systemfsoftware/stryker-bench description still said GitHub's 60-minute
job timeout is the only kill, and the 0954 plan's CONST-W3 caps bullet, R13
and the read-bench-run admission row still said 60 minutes. The plan job
keeps 60, so plan.ts's step-summary line is unchanged.

Plan: docs/plans/2026-10-13-0954-ci-bench-off-pr-plan.md U32, KD2.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants