php: witnesses, trait values, objects, counts and Close order under PHP (slice 3 of #64) #761

Closed
opened 2026-11-13 16:10:28 +00:00 by orion · 6 comments
Collaborator

Context

Step 4 of #64 (backend: PHP), slice 3 of docs/design/PHP.md section 6: the rest of the language, part 2. Step 3 (#735, PR #738, merged as f10e88a6) is on main: Variant, Tag, Switch, FixedArray, Closure, CallClosure, Cell, Projection, Read/Write through every PathStep, tools/php-output.sh, and the programs of tests/conformance/php.allow. It is the sibling of the JavaScript slice 3 (witnesses, TraitValue, Object, SharedObject, counts), whose choices it copies where the IR, not the host, decides.

Source

  • docs/design/PHP.md section 6 row 3, section 2.6 (witnesses as arrays of function names, CallWitness, Object, SharedObject, TraitValue), section 4 (Close, copy on write, identity), section 7 (the dispatch statement), and the paragraph "What slice 2 left out".
  • docs/design/JAVASCRIPT-BACKEND.md section 6 row 3 and "What slice 3 left out", sections 2.6 and 4.
  • docs/design/DESTRUCTORS.md section 2a (when exactly a release happens).

What

php: witnesses, trait values, objects, counts and Close order under PHP. Extend the PHP emitter, compiler only. What compiler/src/backend/php/body.trb reports as unsupported today and this issue makes work:

  • Witnesses: parametersOf ("a function with witness tables") and emitCall ("a call through witness tables") stop reporting. A witness table is a PHP array of function names, a static property of the generated class, members in the order of the trait; CallWitness is $m = $w[k]; $r = $m($self, ...) with the holder handed over as the JavaScript thunks do (payload for a plain member, the holder itself for a var self member, which is an object with ->v). drop and copy entries work on the payload. Only the tables a function names are written. New compiler/src/backend/php/witness.trb, modelled on backend/javascript/witness.trb.
  • TraitValue, Object, SharedObject: a trait-typed value is an object {v, w0, w1, ...} (payload and one table per bound), a call through bound i reads $o->w<i>, narrowing to a supertrait reads the nested entry. A shared type object is a generated class; isSame is === on the objects (PHP.md section 4, "Identity").
  • Counts and Close order: a type for which Closing.holds answers true carries rc (1 at construction); Retain is $x->rc++, Release is a call of a generated torb_release_<type>($x) that decrements and at zero runs close() and then releases the fields in reverse declaration order, a list or array element by element from the last to the first. No __destruct; a type that cannot hold a Close object gets no count and Retain/Release of it write nothing, as in the C back end. A program without a Close object has no such code in its output. New compiler/src/backend/php/count.trb, modelled on backend/javascript/count.trb.
  • Unreachable/Stop behaviour and every other report stay as on main; BoxNew, LazyForce, a Place capture and a Contents step stay named findings.

Decided by the loop

  • MakeUnique and a Write-driven rc are deferred to slice 4, as in the JavaScript record: Retain of an aggregate copies it in place since slice 2 (an eager copy), so two values never share storage and there is nothing to make unique. PHP.md row 3 and section 4 name MakeUnique; the implementer reads how backend/javascript/body.trb treats it, does the same, and amends row 3 and the section 4 text in this PR ("What slice 3 left out").
  • The move to backend/shared/ is limited to code that is the same text in both back ends and does not mention a host (for example the traversal that decides which types need a release function). The implementer moves exactly that and nothing else, the JavaScript output stays byte for byte as it was (the --js leg and compiler/tests prove it), and where nothing is the same text the PHP files simply sit beside the JavaScript ones. Refactor size is no argument (LOOP rule); churn in the JavaScript back end that changes its output is.
  • Witness form: the array of function names of PHP.md 2.6, not a class per witness with real methods, as the record fixed. The dispatch micro benchmark of 2.6 (array of names against a class with methods m3) is measured in the forge job and its figure goes into PHP.md section 7; the form changes only if the string dispatch is more than twice as slow, which the record already says. No owner question: all of it is a technical choice with no outward effect (recommendation test).
  • Lists, maps, sets and Shown values stay with slice 4 (ListStorage): programs that need them stay off php.allow.

Files

  • compiler/src/backend/php/{body,type,emit,writer}.trb, new witness.trb and count.trb; natives.trb only if a runtime helper is named; runtime/php/core.php for the release and witness support, included only for a program that reaches it (a program without them produces the PHP it did before, php_first.trb unchanged); compiler/src/backend/shared/ only as decided above.
  • tests/conformance/php.allow; a new tests/conformance/php-witnesses-close.trb with .expected, .stderr, .exit, modelled on js-witnesses-close.trb.
  • tools/php-dispatch.sh (or a .php script it runs): the dispatch micro benchmark, run by the conformance-php job on 8.4 and printing its figures; .forgejo/workflows/gates.yml for the call if needed.
  • docs/design/PHP.md (row 3 marked done, a "What slice 3 left out" paragraph, the dispatch figure in section 7); docs regenerated as torb docs requires.

Tests

  1. The existing programs that use only slice-3 constructs join php.allow once they pass on 5.6.40, 7.4.33 and 8.4 with the expected files of the C leg: start from the JavaScript list of slice 3 (js-witnesses-close, traits, trait-values, generics, implementation-trait-arguments, destructor-scope-end, destructor-conditional-temporaries, destructor-using). A program that also needs a list, a map, Show, a float or a task stays off, as on the JavaScript leg, and the PR names each one left off and why.
  2. php-witnesses-close.trb exercises each construct of "What" (a generic function with a witness, a trait value with two bounds and a supertrait narrowing, a shared type with isSame, Close order of fields and of scope end, a var self trait member) and prints the close() calls; the leak-style programs that count close() calls print the same lines as on the C leg.
  3. A check (in tools/php-output.sh) that the emitted file of a program with no Close object contains no rc and no torb_release_, and that no output of this slice contains __destruct, &$ or = &.

Acceptance criteria

  • php.allow grows by the slice-3 programs listed in the PR; none is removed; they pass on 5.6.40, 7.4.33 and 8.4 with the same .expected, .stderr and .exit files as the C, VM and JavaScript legs
  • Each construct of "What" has a conformance program (existing or php-witnesses-close.trb) passing on all four legs; the close() order matches docs/design/DESTRUCTORS.md section 2a
  • The output of a program without a Close object has no count or release code, php_first.trb output is unchanged, and no output contains __destruct
  • The JavaScript leg is unchanged: --js passes with the same js.allow and the emitted JavaScript of the conformance programs is byte for byte what main emits
  • The dispatch benchmark runs in conformance-php and its figure is in docs/design/PHP.md section 7; the witness form stays or the record says why it changed
  • BoxNew, LazyForce, a Place capture and a Contents step still fail torb build --target linux-php with a named finding and no output file
  • Row 3 of docs/design/PHP.md marked done with the "What slice 3 left out" paragraph; torb format --check and torb docs check green
  • tools/check-commits.sh clean; sh tools/gates.sh a and the conformance-php job green in forge CI (CI only, no local bootstrap or gates)

Seed

Compiler only: no syntax change, no new native, no new std name looked up by string, no new Architecture case, so the two-commit rule does not apply. One PR; one Conventional Commit per logical change (feat(php): ..., and a refactor: commit for any move to backend/shared/), confirmed by tools/check-commits.sh. The seed refresh stays Torben's.

Size

One PR. If a review cannot hold it, cut the counts and Close order into a second commit of the same PR (witnesses and trait values first); nothing is carved out into a new issue. Model: sonnet, thinking high (compiler work). Out of scope: slices 4 to 8 (kernel, UInt64, floats, storage, tasks, limits, subset and torb test), MakeUnique, a minifier.

Dependencies

Part of #64 (epic; do not close it).

## Context Step 4 of #64 (backend: PHP), slice 3 of `docs/design/PHP.md` section 6: the rest of the language, part 2. Step 3 (#735, PR #738, merged as f10e88a6) is on `main`: `Variant`, `Tag`, `Switch`, `FixedArray`, `Closure`, `CallClosure`, `Cell`, `Projection`, `Read`/`Write` through every `PathStep`, `tools/php-output.sh`, and the programs of `tests/conformance/php.allow`. It is the sibling of the JavaScript slice 3 (witnesses, `TraitValue`, `Object`, `SharedObject`, counts), whose choices it copies where the IR, not the host, decides. ## Source - `docs/design/PHP.md` section 6 row 3, section 2.6 (witnesses as arrays of function names, `CallWitness`, `Object`, `SharedObject`, `TraitValue`), section 4 (`Close`, copy on write, identity), section 7 (the dispatch statement), and the paragraph "What slice 2 left out". - `docs/design/JAVASCRIPT-BACKEND.md` section 6 row 3 and "What slice 3 left out", sections 2.6 and 4. - `docs/design/DESTRUCTORS.md` section 2a (when exactly a release happens). ## What *php: witnesses, trait values, objects, counts and `Close` order under PHP.* Extend the PHP emitter, compiler only. What `compiler/src/backend/php/body.trb` reports as unsupported today and this issue makes work: - **Witnesses**: `parametersOf` ("a function with witness tables") and `emitCall` ("a call through witness tables") stop reporting. A witness table is a PHP array of function names, a `static` property of the generated class, members in the order of the trait; `CallWitness` is `$m = $w[k]; $r = $m($self, ...)` with the holder handed over as the JavaScript thunks do (payload for a plain member, the holder itself for a `var self` member, which is an object with `->v`). `drop` and `copy` entries work on the payload. Only the tables a function names are written. New `compiler/src/backend/php/witness.trb`, modelled on `backend/javascript/witness.trb`. - **`TraitValue`, `Object`, `SharedObject`**: a trait-typed value is an object `{v, w0, w1, ...}` (payload and one table per bound), a call through bound `i` reads `$o->w<i>`, narrowing to a supertrait reads the `nested` entry. A `shared type` object is a generated class; `isSame` is `===` on the objects (PHP.md section 4, "Identity"). - **Counts and `Close` order**: a type for which `Closing.holds` answers true carries `rc` (1 at construction); `Retain` is `$x->rc++`, `Release` is a call of a generated `torb_release_<type>($x)` that decrements and at zero runs `close()` and then releases the fields in reverse declaration order, a list or array element by element from the last to the first. **No `__destruct`**; a type that cannot hold a `Close` object gets no count and `Retain`/`Release` of it write nothing, as in the C back end. A program without a `Close` object has no such code in its output. New `compiler/src/backend/php/count.trb`, modelled on `backend/javascript/count.trb`. - `Unreachable`/`Stop` behaviour and every other report stay as on `main`; `BoxNew`, `LazyForce`, a `Place` capture and a `Contents` step stay named findings. ## Decided by the loop - **`MakeUnique` and a `Write`-driven `rc`** are deferred to slice 4, as in the JavaScript record: `Retain` of an aggregate copies it in place since slice 2 (an eager copy), so two values never share storage and there is nothing to make unique. PHP.md row 3 and section 4 name `MakeUnique`; the implementer reads how `backend/javascript/body.trb` treats it, does the same, and amends row 3 and the section 4 text in this PR ("What slice 3 left out"). - **The move to `backend/shared/`** is limited to code that is the same text in both back ends and does not mention a host (for example the traversal that decides which types need a release function). The implementer moves exactly that and nothing else, the JavaScript output stays byte for byte as it was (the `--js` leg and `compiler/tests` prove it), and where nothing is the same text the PHP files simply sit beside the JavaScript ones. Refactor size is no argument (LOOP rule); churn in the JavaScript back end that changes its output is. - **Witness form**: the array of function names of PHP.md 2.6, not a class per witness with real methods, as the record fixed. The dispatch micro benchmark of 2.6 (array of names against a class with methods `m3`) is measured in the forge job and its figure goes into PHP.md section 7; the form changes only if the string dispatch is more than twice as slow, which the record already says. No owner question: all of it is a technical choice with no outward effect (recommendation test). - Lists, maps, sets and `Show`n values stay with slice 4 (`ListStorage`): programs that need them stay off `php.allow`. ## Files - `compiler/src/backend/php/{body,type,emit,writer}.trb`, new `witness.trb` and `count.trb`; `natives.trb` only if a runtime helper is named; `runtime/php/core.php` for the release and witness support, included only for a program that reaches it (a program without them produces the PHP it did before, `php_first.trb` unchanged); `compiler/src/backend/shared/` only as decided above. - `tests/conformance/php.allow`; a new `tests/conformance/php-witnesses-close.trb` with `.expected`, `.stderr`, `.exit`, modelled on `js-witnesses-close.trb`. - `tools/php-dispatch.sh` (or a `.php` script it runs): the dispatch micro benchmark, run by the `conformance-php` job on 8.4 and printing its figures; `.forgejo/workflows/gates.yml` for the call if needed. - `docs/design/PHP.md` (row 3 marked done, a "What slice 3 left out" paragraph, the dispatch figure in section 7); docs regenerated as `torb docs` requires. ## Tests 1. The existing programs that use only slice-3 constructs join `php.allow` once they pass on 5.6.40, 7.4.33 and 8.4 with the expected files of the C leg: start from the JavaScript list of slice 3 (`js-witnesses-close`, `traits`, `trait-values`, `generics`, `implementation-trait-arguments`, `destructor-scope-end`, `destructor-conditional-temporaries`, `destructor-using`). A program that also needs a list, a map, `Show`, a float or a task stays off, as on the JavaScript leg, and the PR names each one left off and why. 2. `php-witnesses-close.trb` exercises each construct of "What" (a generic function with a witness, a trait value with two bounds and a supertrait narrowing, a `shared type` with `isSame`, `Close` order of fields and of scope end, a `var self` trait member) and prints the `close()` calls; the leak-style programs that count `close()` calls print the same lines as on the C leg. 3. A check (in `tools/php-output.sh`) that the emitted file of a program with no `Close` object contains no `rc` and no `torb_release_`, and that no output of this slice contains `__destruct`, `&$` or `= &`. ## Acceptance criteria - [ ] `php.allow` grows by the slice-3 programs listed in the PR; none is removed; they pass on 5.6.40, 7.4.33 and 8.4 with the same `.expected`, `.stderr` and `.exit` files as the C, VM and JavaScript legs - [ ] Each construct of "What" has a conformance program (existing or `php-witnesses-close.trb`) passing on all four legs; the `close()` order matches `docs/design/DESTRUCTORS.md` section 2a - [ ] The output of a program without a `Close` object has no count or release code, `php_first.trb` output is unchanged, and no output contains `__destruct` - [ ] The JavaScript leg is unchanged: `--js` passes with the same `js.allow` and the emitted JavaScript of the conformance programs is byte for byte what `main` emits - [ ] The dispatch benchmark runs in `conformance-php` and its figure is in `docs/design/PHP.md` section 7; the witness form stays or the record says why it changed - [ ] `BoxNew`, `LazyForce`, a `Place` capture and a `Contents` step still fail `torb build --target linux-php` with a named finding and no output file - [ ] Row 3 of `docs/design/PHP.md` marked done with the "What slice 3 left out" paragraph; `torb format --check` and `torb docs check` green - [ ] `tools/check-commits.sh` clean; `sh tools/gates.sh a` and the `conformance-php` job green in forge CI (CI only, no local bootstrap or gates) ## Seed Compiler only: no syntax change, no new native, no new std name looked up by string, no new `Architecture` case, so the two-commit rule does not apply. One PR; one Conventional Commit per logical change (`feat(php): ...`, and a `refactor:` commit for any move to `backend/shared/`), confirmed by `tools/check-commits.sh`. The seed refresh stays Torben's. ## Size One PR. If a review cannot hold it, cut the counts and `Close` order into a second commit of the same PR (witnesses and trait values first); nothing is carved out into a new issue. Model: sonnet, thinking high (compiler work). Out of scope: slices 4 to 8 (kernel, `UInt64`, floats, storage, tasks, limits, subset and `torb test`), `MakeUnique`, a minifier. ## Dependencies - #735 (closed, PR #738 merged as f10e88a6 on `main`). Part of #64 (epic; do not close it).
Author
Collaborator

[loop:torbscript] claim implement by session:loop-torbscript-20261113 until 2026-11-14T01:10:00Z

[loop:torbscript] claim implement by session:loop-torbscript-20261113 until 2026-11-14T01:10:00Z
Author
Collaborator

[loop:torbscript] implement: PR #766, head 6319ee75, CI pending after ~30 min (commit messages, touches and pdisc green; gates and conformance-php still queued, runner queue congested), next: waiting (CI; nothing was built or run locally, so a red job is likely to need a fix pass: new count.trb and witness.trb are uncompiled).

Worker token estimate: about 1.5M (several context windows).

For the reviewer:

  • Deviation: isSame is a compile error on every back end today, so php-witnesses-close.trb pins identity with a shared Box and a write through two names.
  • Deviation: FixedArray release runs first to last, as in JS (the expected output requires it); the issue text says last to first.
  • php-witnesses-close.allocations is unbudgeted until the native count is measured in CI.
  • php.allow grew by 9 programs (nothing removed); the final membership is decided by CI, any program that fails will be named in the PR with its reason.
  • Dispatch figure: tools/php-dispatch.sh runs on 8.4 in conformance-php; PHP.md section 7 names it, the number goes in after the first green run (witness form stays an array of function names unless the ratio is above 2).
  • skills/ regeneration (torb docs skill) was not possible locally; CI decides whether it changes.
  • Out of scope, noted in PHP.md "What slice 3 left out": MakeUnique and Write-driven rc (slice 4), lists/maps/sets/Show (slice 4), recursion through witness parameters not depth-counted.
[loop:torbscript] implement: PR https://git.torb.dev/torbscript/language/pulls/766, head 6319ee75, CI pending after ~30 min (commit messages, touches and pdisc green; `gates` and `conformance-php` still queued, runner queue congested), next: waiting (CI; nothing was built or run locally, so a red job is likely to need a fix pass: new count.trb and witness.trb are uncompiled). Worker token estimate: about 1.5M (several context windows). For the reviewer: - Deviation: `isSame` is a compile error on every back end today, so `php-witnesses-close.trb` pins identity with a shared `Box` and a write through two names. - Deviation: `FixedArray` release runs first to last, as in JS (the expected output requires it); the issue text says last to first. - `php-witnesses-close.allocations` is `unbudgeted` until the native count is measured in CI. - `php.allow` grew by 9 programs (nothing removed); the final membership is decided by CI, any program that fails will be named in the PR with its reason. - Dispatch figure: `tools/php-dispatch.sh` runs on 8.4 in `conformance-php`; PHP.md section 7 names it, the number goes in after the first green run (witness form stays an array of function names unless the ratio is above 2). - `skills/` regeneration (`torb docs skill`) was not possible locally; CI decides whether it changes. - Out of scope, noted in PHP.md "What slice 3 left out": `MakeUnique` and Write-driven `rc` (slice 4), lists/maps/sets/`Show` (slice 4), recursion through witness parameters not depth-counted.
Author
Collaborator

[loop:torbscript] claim review-fix by session:loop-torbscript-20261113 until 2026-11-14T00:00:00Z

[loop:torbscript] claim review-fix by session:loop-torbscript-20261113 until 2026-11-14T00:00:00Z
Author
Collaborator

[loop:torbscript] review-fix: PR #766 was red only on format --check; fixed on the branch, CI re-running

  • What failed (run 2786, head d1e54275): ci / tier A (linux-x64) failed after 44 min with exactly one red gate, format --check: compiler/src/backend/php/body.trb and witness.trb "would change". All other tier A gates were green (compiler suite, std/example packages native and VM, docs, REPL/LSP/debug, packages, lock). ci / gates "after 0s" is not a runner problem: it is the reusable-workflow wrapper job of gates.yml (no steps of its own), red because tier-a was red.
  • What changed: formatted the two files as torb format lays them out (one closure-capture append in body.trb, one command call in witness.trb); layout only. The first attempt (552a2167, subject style(php): ...) went red on commit messages because style is not an allowed Conventional Commit type, so the commit was reworded to chore(php): torb format body.trb and witness.trb (b3687c5f, same tree) and pushed with --force-with-lease to loop/761-php-slice3.
  • Checked here: ran the torb of CI's compiler-linux-x64 artifact (run 2786) with format --check over the 10 .trb files this PR adds or changes: 0 of 10 would change. sh tools/check-commits.sh origin/main HEAD passes. No local C compiler, so no local build or gates beyond these.
  • CI state: new run on b3687c5f queued/pending (the old runs on 552a2167 were superseded). Tier A takes ~45 min. argus is requested as reviewer again.
  • Next: waiting (CI and review).

[loop:torbscript] release review-fix: done

[loop:torbscript] review-fix: PR #766 was red only on `format --check`; fixed on the branch, CI re-running - **What failed** (run 2786, head d1e54275): `ci / tier A (linux-x64)` failed after 44 min with exactly one red gate, `format --check`: `compiler/src/backend/php/body.trb` and `witness.trb` "would change". All other tier A gates were green (compiler suite, std/example packages native and VM, docs, REPL/LSP/debug, packages, lock). `ci / gates` "after 0s" is not a runner problem: it is the reusable-workflow wrapper job of `gates.yml` (no steps of its own), red because `tier-a` was red. - **What changed**: formatted the two files as `torb format` lays them out (one closure-capture append in `body.trb`, one command call in `witness.trb`); layout only. The first attempt (552a2167, subject `style(php): ...`) went red on `commit messages` because `style` is not an allowed Conventional Commit type, so the commit was reworded to `chore(php): torb format body.trb and witness.trb` (b3687c5f, same tree) and pushed with `--force-with-lease` to `loop/761-php-slice3`. - **Checked here**: ran the `torb` of CI's `compiler-linux-x64` artifact (run 2786) with `format --check` over the 10 `.trb` files this PR adds or changes: 0 of 10 would change. `sh tools/check-commits.sh origin/main HEAD` passes. No local C compiler, so no local build or gates beyond these. - **CI state**: new run on b3687c5f queued/pending (the old runs on 552a2167 were superseded). Tier A takes ~45 min. argus is requested as reviewer again. - **Next**: waiting (CI and review). [loop:torbscript] release review-fix: done
Author
Collaborator

[loop:torbscript] claim review-fix by session:loop-torbscript-20261114 until 2026-11-14T03:06:00Z

[loop:torbscript] claim review-fix by session:loop-torbscript-20261114 until 2026-11-14T03:06:00Z
Author
Collaborator

[loop:torbscript] review-fix: the red check on #766 is a flaky playground smoke test, not this PR; no code change, CI rerun queued, next: waiting (runner backlog, then merge gate)

  • Failing job: ci / the playground (torb as WebAssembly) on b3687c5f (run index 2804, job 32223). Everything before it passed: emcc build, 26.1 MB wasm, hello world, language server init, diagnostics, completion, hover, signature help, rename. The only failing step was a request Monaco cancels answers null in playground/smoke-test.mjs: it sends a hover, yields one setTimeout(0), then cancels and expects null. The hover answer had already come back (const names: List<String>), so the cancel landed too late. The test is a timing race by construction; the runner was slow (rename step 33 s, vs 31-32 s on #765/#771 where the same step passed and the cancel test took 0-2 ms).
  • Not caused by this PR: it changes only compiler/src/backend/{php,javascript,shared}, PHP tests/docs/tools and gates.yml; nothing in the language server, hover or the playground. In the same run tier A, tier B, conformance (PHP 5.6, 7.4 and 8.4), conformance (JavaScript under Node.js), every host emits the same C, bootstrap, VS Code extension and release-sync were all green; gates is red only as the aggregate of the playground job.
  • Action: no commit (nothing to fix in the diff). Reran the CI on the same head with ci-rerun.sh (close + reopen, no new SHA, argus is still the requested reviewer). After ~27 min no job of the rerun had started: the runner queue is backed up (#773, #769, #778, #777 also sit in pending), which is a backlog, not a failure.
  • Unverified: that the rerun's playground job is green (it has not run yet); the flake itself is inferred from the log and the test source, not reproduced. The test could be hardened (cancel deterministically instead of racing a 0 ms timer); that is a separate follow-up in playground/smoke-test.mjs, not part of this PR.

next: waiting (runner backlog), then argus's review.

[loop:torbscript] review-fix: the red check on #766 is a flaky playground smoke test, not this PR; no code change, CI rerun queued, next: waiting (runner backlog, then merge gate) - **Failing job:** `ci / the playground (torb as WebAssembly)` on b3687c5f (run index 2804, job 32223). Everything before it passed: emcc build, 26.1 MB wasm, hello world, language server init, diagnostics, completion, hover, signature help, rename. The only failing step was `a request Monaco cancels answers null` in `playground/smoke-test.mjs`: it sends a hover, yields one `setTimeout(0)`, then cancels and expects `null`. The hover answer had already come back (`const names: List<String>`), so the cancel landed too late. The test is a timing race by construction; the runner was slow (rename step 33 s, vs 31-32 s on #765/#771 where the same step passed and the cancel test took 0-2 ms). - **Not caused by this PR:** it changes only `compiler/src/backend/{php,javascript,shared}`, PHP tests/docs/tools and `gates.yml`; nothing in the language server, hover or the playground. In the same run tier A, tier B, `conformance (PHP 5.6, 7.4 and 8.4)`, `conformance (JavaScript under Node.js)`, `every host emits the same C`, bootstrap, VS Code extension and release-sync were all green; `gates` is red only as the aggregate of the playground job. - **Action:** no commit (nothing to fix in the diff). Reran the CI on the same head with `ci-rerun.sh` (close + reopen, no new SHA, argus is still the requested reviewer). After ~27 min no job of the rerun had started: the runner queue is backed up (#773, #769, #778, #777 also sit in `pending`), which is a backlog, not a failure. - **Unverified:** that the rerun's playground job is green (it has not run yet); the flake itself is inferred from the log and the test source, not reproduced. The test could be hardened (cancel deterministically instead of racing a 0 ms timer); that is a separate follow-up in `playground/smoke-test.mjs`, not part of this PR. next: waiting (runner backlog), then argus's review.
argus closed this issue 2026-11-14 06:38:56 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language#761
No description provided.