Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 78 additions & 1 deletion .claude/board/ISSUES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## ISS-LGJ-CONSUMERS-HAVE-NO-CI-LINE (2026-09-22) — OPEN
## ISS-LGJ-CONSUMERS-HAVE-NO-CI-LINE (2026-09-22) — RESOLVED 2026-09-22 (job landed; dispatch proven by its own first run)

`main` was RED and nothing said so. `GraphHopTest` reported 1 FAILED / 65
passed at `bb81d80`, established by running it from a clean worktree, not
Expand Down Expand Up @@ -38,6 +38,83 @@ confirm the job goes red. A job that builds the consumers but never runs
their mains would pass, and would be the no-gate-with-extra-steps outcome
this entry exists to name.

---

**RESOLUTION (2026-09-22).** `java-suites` in `.github/workflows/lint.yml`:
twelve steps, same three-sibling checkout as `rust-test`, `cargo build
--release` for the artifact, then the four `javac`/`java` command strings
`java/README.md` documents, verbatim. No build tool was introduced — there
still is none, by design.

**The first task — acquisition — is ANSWERED, and by a different mechanism
than the local one, which is why this entry was right to refuse to generalise
from the container's ladder.** Chain, each link read from a primary source
rather than inferred:

1. `actions/setup-java`'s `normalizeVersion`: `if (version.endsWith('-ea')) {
... stable = false }` — so `java-version: '28-ea'` is not-stable.
2. its temurin installer: `const releaseType = this.stable ? 'ga' : 'ea'`.
3. Adoptium's API, queried live: `release_type=ea` + `version=[28,29)` +
linux/x64/jdk serves `jdk-28+16-ea-beta` — the same build this container
runs. And `/v3/info/available_releases` omits 28 while naming it
`most_recent_feature_version`, which is *why* the `-ea` suffix is load-bearing.

The container's blocker (gateway-blocked distribution hosts, hence the
GitHub-release download path) is a **this-container** constraint and never
applied to a runner. The version is deliberately NOT pinned to `+16`: internal
head pins are forbidden, and an upstream EA build is an external dependency
whose purpose is to move — what the suite needs is JEP 401 under preview, which
every 28 EA build carries.

**Two counts in the entry above were wrong, measured on `origin/main`
(`aef2382`) before the job was written:** it is **four** consumer mains, not
three (`trades` carries both `TradesAllocationTest` and `TradesParityTest`, and
running one of two would have been precisely the no-gate-with-extra-steps
outcome this entry names). The core suite is **612 checks / 17 suites**, which
this entry had right while root `CLAUDE.md` still briefed every session with
`409 / 16 suites / abi 0.11`. That drift is fixed in the same commit, and fixed
STRUCTURALLY: the live count now exists in exactly one dated place and every
other site had its number removed rather than re-pinned. One measurement
restated in eight places goes stale in eight places.

Measured, all four command strings run verbatim: core **612** (0 failures, abi
0.12, avx512, release), bricks **70**, graph **68**, trades **3** and **12** —
**765 checks across 5 entry points**, every one exit 0.

**FALSIFIER: RUN, red-then-green, in the shape this entry demanded.** The stale
`0` pin was re-introduced in `GraphHopTest` and the consumer step's `run:` body
— extracted VERBATIM from the committed workflow via a YAML parse, not retyped —
was executed under `bash -e`:

| run | mains reached | step exit |
|---|---|---|
| stale `0` pin | all four; `::error::consumer suites FAILED: …GraphHopTest` | **1** |
| restored | bricks 70, graph 68, trades 3 + 12, "all four consumer suites passed" | **0** |

Two properties, one run. It catches the exact defect that survived a merge
(`1 FAILED, 67 passed` — the `bb81d80` shape), AND it reaches every main
regardless: a bare `java` under `bash -e` aborts the step at the first red one,
so one broken consumer would have masked the other three and each CI round would
have revealed exactly one of them. `AllTests` does not behave that way either,
and now neither does this loop.

What a local run CANNOT prove is
dispatch: whether a runner starts the job and reaches JDK 28. **That is now
SETTLED by the first run (#86, `af58fbd`): `java-suites completed success`, all
13 steps.** The runner's own log closes the acquisition chain end to end —
`Downloading Java 28.0.0+16.0.ea (Temurin-Hotspot) from
.../adoptium/temurin28-binaries/releases/download/jdk-28%2B16-ea-beta/...`, the
exact release the Adoptium API named, resolved into
`/opt/hostedtoolcache/Java_Temurin-Hotspot_jdk/28.0.0-ea.16.0.ea/x64`.

It also MEASURED something that had only been reasoned about. The runner reports
`abi 0.12, simd ndarray::simd avx2 (x86-64-v3)` against this host's `avx512`,
and every count comes back byte-identical — core **612**, bricks **70**, graph
**68**, trades **3** and **12**. The `simdBackend()` "diagnostic only" rule was
asserted here from reading the tests (`AbiContractTest` asserts only that a
backend was reported, `FusionParityTest` notes it, `DoctrineFenceTest` counts
source lines); it is now observed across two different backends.

## ISS-LGJ-TOOLCHAIN-MUST-BE-JDK28-VALHALLA-PANAMA — UNBLOCKED; JDK 28 installed and the flip proven (2026-09-19)

⊘ The entry below says the migration is blocked because no JDK 28 can be
Expand Down
82 changes: 82 additions & 0 deletions .claude/board/LATEST_STATE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,85 @@
## 2026-09-22 — the Java gate is DISPATCHED, and one measurement stops being restated in eight places

`ISS-LGJ-CONSUMERS-HAVE-NO-CI-LINE` is RESOLVED. `java-suites` in
`.github/workflows/lint.yml` builds `liblgj_abi.so`, then runs the four
`javac`/`java` command strings `java/README.md` documents, verbatim — no build
tool was introduced, there still is none by design.

- **The issue's first task was acquisition, not the job**, and it resolves by a
mechanism this container does not use — which is why the entry was right to
refuse to generalise from the local ladder. Read from primary sources:
setup-java's `normalizeVersion` sets `stable = false` on an `-ea` suffix, its
temurin installer then asks `release_type=ea`, and Adoptium's API (queried
live) serves `jdk-28+16-ea-beta` — the same build this container runs. The
container's blocker was gateway-blocked distribution hosts; a runner never had
that constraint. NOT pinned to `+16`: internal head pins are forbidden, and
what the suite needs is JEP 401 under preview, which every 28 EA build carries.
- **Measured on `origin/main` (`aef2382`), every command verbatim:** core **612
checks / 17 suites / 0 failures** (abi 0.12, avx512, release), bricks **70**,
graph **68**, trades **3** and **12** — **765 checks across 5 entry points**,
all exit 0. All of it was gating nothing.
- **Two counts were wrong on the way in.** FOUR consumer mains, not three
(`trades` carries two; running one of two would have been the
no-gate-with-extra-steps outcome the issue names). And root `CLAUDE.md`
briefed every session with `409 / 16 suites / abi 0.11`. Fixed
**structurally**, not re-pinned: the live count now exists in exactly ONE
dated place and every other site had its number REMOVED. One measurement
restated in eight places goes stale in eight places — which is what had
happened. The three surviving 409s are dated historical measurements kept as
evidence; the Valhalla-flip comparison is only meaningful against its own
baseline and must not be restated forward.
- **Falsifier run, red-then-green, on the step body extracted from the
committed YAML rather than retyped.** Stale `0` pin: all four mains reached,
`::error::` named the culprit, exit 1. Restored: exit 0. Not fail-fast
deliberately — a bare `java` under `bash -e` aborts at the first red main, so
one broken consumer would mask three others and each round would reveal one.

**The one OPEN item CLOSED on the first run** (#86, `af58fbd`):
`java-suites completed success`, 13/13 steps. The runner downloaded
`Java 28.0.0+16.0.ea (Temurin-Hotspot)` from
`adoptium/temurin28-binaries/.../jdk-28+16-ea-beta` — the exact release the
Adoptium API had named, so the chain is closed by execution and not only by
reading. Bonus measurement: the runner reports `avx2 (x86-64-v3)` where this
host reports `avx512`, and all 765 counts are byte-identical, which turns the
backend-agnostic claim from something read out of the tests into something
observed across two backends.

**Review follow-up (`2a30039`), both findings CodeRabbit-confirmed.** Two real
defects, both mine:

- **Persisted checkout credentials** (zizmor `artipacked`). Fixed on ALL
THIRTEEN checkout steps, not the four named — `persist-credentials` appeared
nowhere in the file, every job runs `cargo`, so the `build.rs` read path was
identical in `format`/`clippy`/`rust-test`. Verified free first: nothing
pushes, `contents: read`, no secret read. **Verified at RUNTIME, not just in
YAML** — each of the four checkouts logs `persist-credentials: false`, then
`Setting up auth`, then `Removing auth` INSIDE the checkout step, so the
credential no longer spans the later `cargo build`. Without the flag there is
no in-step `Removing auth` and the config survives to post-job cleanup.
- **The documented suite command could not run.** My own pointer sentence aimed
at a JDK 25/26 command without the preview flags; measured `error: value
classes are a preview feature and are disabled by default`, exit 1. Fixing it
surfaced three more in the same block (`/usr/lib/jvm` now holds only Java 21
so `temurin-26-jdk-amd64` does not exist here; the block mixed working
directories and died on `find: 'java/src/main'`; `-Dlgj.library=$PWD/target/...`
named an incidental leftover `target/` that is a separate inode from what
step 1 builds) — and one I INTRODUCED, caught only by executing it:
`--manifest-path` instead of `cd` broke the toolchain, because rustup reads
`rust-toolchain.toml` from the CWD (`rustc 1.94.1 is not supported`, exit
101). The `cd` is load-bearing and is back in a subshell. Verified by
extracting the fenced block by PARSE and running it under `bash -e`: exit 0,
`ALL PASSED (612 checks)`.
I also nearly filed a FALSE finding — the two `.so` paths have different
mtimes, which read as a stale artifact; they are md5-identical. Checking
content instead of timestamps stopped it.

**OPEN:** nothing on this. The remaining gap is elsewhere and unchanged —
`lint.yml` fires `on: {pull_request, push}` for THIS repository only, so an
upstream-only merge in `lance-graph` or `ndarray` cannot start the workflow and
a sibling break stays invisible until someone pushes here. That is the trigger
gap `E-THE-CI-GAP-WAS-THE-TRIGGER-NOT-THE-COVERAGE-1` already names; this job
inherits it rather than fixing it, and now inherits it for the Java half too.

## 2026-09-22 — D-LGJ-FOLD-5: the consumer stops asking sixteen times, and a red pin on `main` gets root-caused

The consumer half of minor 12. `BricksQuery.sumBy()` was sixteen queries —
Expand Down
Loading
Loading