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
42 changes: 42 additions & 0 deletions .claude/board/EPIPHANIES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,45 @@
## E-THE-PIN-THAT-CLAIMED-ONE-PLACE-CREATED-A-SECOND-1 (2026-09-05)

**Finding.** The first CI gate this repo ever had went red on its first
run, and the two causes were both "the same thing is declared twice, and
cargo silently picks the nearer one."

`rust-toolchain.toml` was added at the repository root carrying the
sentence *"the pin lives in exactly ONE place"* — while
`native/lgj-abi/rust-toolchain.toml` already existed, pinning `1.97.1`.
Cargo reads whichever file is nearest the working directory, so the root
file governed a command run from the root and the crate file governed a
command run from the crate. Two files, one toolchain, disagreeing by where
you happened to stand. The root file is removed; the crate file is the
authority, bumped to `1.98.1`, and it sits beside `.cargo/config.toml`,
which cargo resolves the same way.

That bump is forced, not cosmetic: `ndarray` 0.17.2 now declares
`rust-version = "1.98"`, so a 1.97.1 resolve of this crate fails outright.
The same upstream move turned every MSRV job in `AdaWorldAPI/tract` red on
the same afternoon.

**The second cause is the more interesting one, because a test caught it.**
`native/lgj-abi/.cargo/config.toml` pins `-Ctarget-cpu=x86-64-v4`, and
`abi::tests::the_x86_64_build_has_a_vector_baseline` exists to turn a lost
baseline into a test failure instead of a SIGILL inside a JVM downcall.
The workflow ran cargo from the repository root with `--manifest-path`
pointing into the crate — and **cargo reads `.cargo/config.toml` from the
working directory's ancestry, never from the manifest's directory.** The
baseline was therefore never applied, the manifest reported the scalar
backend, and the test fired exactly as designed. `--manifest-path` is not
equivalent to running in the crate directory, and this is the failure that
proves it.

**Consequence.** The jobs now run with `working-directory` set to the
crate, and CI additionally exports `CARGO_BUILD_RUSTFLAGS=-Ctarget-cpu=
x86-64-v3`, because GitHub-hosted runners do not guarantee AVX-512 and a
v4 build would die on them with the very SIGILL that config comment
describes. v3 still satisfies the test's `AVX2 | AVX512` assertion, so the
gate is retargeted rather than weakened. Verified locally on both sides:
the old invocation reproduces the failure, the new one passes 138 tests
plus the G11 fence, with fmt and clippy clean.

## E-THE-GUARD-YOU-WIRE-IS-NOT-THE-GUARD-YOU-NAMED-1 (2026-08-28)

**Finding.** A wave chartered as "wire the epoch re-check" cannot deliver
Expand Down
60 changes: 60 additions & 0 deletions .claude/board/LATEST_STATE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,63 @@
## 2026-09-05 — storno: the gate's own first run corrected two claims above

Corrects the entry immediately below, which is left in place per the
storno rule. Two of its statements were wrong when written:

- *"adds `rust-toolchain.toml` (this repo had none)"* — one already
existed at `native/lgj-abi/rust-toolchain.toml`, pinning `1.97.1`.
- *"the pin has exactly one spelling"* — adding the root file made two,
and cargo reads whichever is nearest the working directory.

The root file is removed and the crate-level file is bumped to `1.98.1`
(forced: `ndarray` 0.17.2 declares `rust-version = "1.98"`). The three
jobs now run with `working-directory` set to the crate rather than
`--manifest-path` from the root, because `.cargo/config.toml` is read
from the working directory's ancestry and the v4 target-cpu baseline was
being dropped — which is what `the_x86_64_build_has_a_vector_baseline`
caught on the gate's first run. CI exports the v3 baseline explicitly,
since GitHub-hosted runners do not guarantee AVX-512. Full account:
`EPIPHANIES.md` `E-THE-PIN-THAT-CLAIMED-ONE-PLACE-CREATED-A-SECOND-1`.

## 2026-09-05 — first CI lint gate: fmt + clippy + rust-test, Rust pinned to 1.98.1

**Branch `claude/ci-lint-gate`, PR #77.** This repo has never had a
`.github/workflows/` directory — every gate documented in `CLAUDE.md` (the
G11 contract-import fence, the epoch-recheck falsifiers, `ApiSurfaceTest`,
the L1/L2 semantic-leak pins) has only ever run when a session happened to
invoke `cargo test` by hand. Adds `.github/workflows/lint.yml`, three jobs
scoped to `native/lgj-abi` (the repo's only Cargo crate): `format`
(`cargo fmt --check`), `clippy` (`--all-targets -- -D warnings`), and
`rust-test` (`--all-targets`, which is what finally makes
`tests/g11_contract_import_fence.rs` run anywhere but a session's own shell —
the same gap `CLAUDE.md` names for G11 itself: "prose until 2026-09-03"
because nothing ran the test that enforces it).

`lgj-abi` path-deps `ndarray`, `lance-graph`'s `lance-graph-contract`, and
(optional, off by default) `OGAR`'s `ogar-class-view`. Cargo resolves the
full graph including inactive optional path deps, so `clippy`/`rust-test`
check out all three siblings — the identical shape `lance-graph`'s own
`style.yml` already uses (self + each sibling into its own named
subdirectory under one runner workspace root).

Also adds `rust-toolchain.toml` (this repo had none) pinning
`channel = "1.98.1"`, joining the sweep `ndarray`/`lance-graph`/`OGAR`
already carry. `setup-rust-toolchain@v1` is invoked with no `toolchain:`
input, so the pin has exactly one spelling.

**Java is deliberately out of scope.** `java/` holds only `README.md` +
`.gitignore` — no Maven, no Gradle, no source. The README says so directly
("no Maven, no Gradle... `javac` and `java` are the entire Java toolchain").
Nothing to wire a CI job against yet; filed as a named follow-up rather than
guessed at.

**Not measured in this PR:** whether `clippy --all-targets -- -D warnings`
is actually clean on `lgj-abi` today. Disk constraints (a large dependency
tree through the contract crate) ruled out a local `cargo build`/`clippy`
run, so this PR's own CI run is the first real measurement — if it comes
back red on pre-existing debt, the follow-up is this workspace's own tiered
posture (`continue-on-error: true` + a named `TECH_DEBT.md` line), not a
bundled auto-fix.

## 2026-09-04 — lgj_hop: the conjunction is one truth-table pass, and the lane is read as a lane (5×)

**Branch `claude/pr-294-ragged-path-validation-170zcy`**, lgj-abi only — no
Expand Down
60 changes: 60 additions & 0 deletions .claude/board/PR_ARC_INVENTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,66 @@
> anti-pattern the imported board rules name. Backfilled below in one
> pass rather than left stale; PR #4 onward gets its entry at merge time.

## PR #77 — first CI lint gate: fmt + clippy + rust-test, Rust pinned to 1.98.1 (opened 2026-09-05, head `6d4b1a2`)

**Added.** `.github/workflows/lint.yml` (three jobs: `format`, `clippy`,
`rust-test`, all scoped to `native/lgj-abi` via `--manifest-path`);
`rust-toolchain.toml` pinning `channel = "1.98.1"` + `rustfmt`/`clippy`
components (this repo had neither a workflow directory nor a toolchain pin
before this PR).

**Locked.** The G11 contract-import fence (`tests/g11_contract_import_fence.rs`)
now runs on every push/PR via `rust-test`, closing the exact gap
Comment thread
coderabbitai[bot] marked this conversation as resolved.
`CLAUDE.md` names for G11 itself ("prose until 2026-09-03" — a rule
enforced by a test nothing ever ran). `clippy`/`rust-test` check out all
three path-dep siblings (`ndarray`, `lance-graph`, `OGAR`) because Cargo
resolves the full dependency graph including the inactive optional
`ogar-classview` feature's path dep — mirroring `lance-graph`'s own
`style.yml` checkout shape exactly.

**Deferred.** A Java CI job — `java/` has no build system at all (no
Maven, no Gradle, no source), per its own README; wiring a job against a
build system that doesn't exist would guess at a command with nothing to
verify it against. Whether `-D warnings` is clean on `lgj-abi` today is
also unmeasured locally (disk constraints); this PR's own CI run is the
first real measurement, with the tiered `continue-on-error` +
`TECH_DEBT.md` fallback named in the PR body if it comes back red on
pre-existing debt.

**Correction (2026-09-05, head `1ea5c85`).** Appended per the append-only
rule rather than edited above; the original lines stay as written.

- *"this repo had neither a workflow directory nor a toolchain pin before
this PR"* — the workflow half is right, the toolchain half is not.
`native/lgj-abi/rust-toolchain.toml` already pinned `1.97.1`. Adding a
second file at the repository root made two pins for one toolchain, and
cargo reads whichever is nearest the working directory. The root file is
removed; the crate-level file is the authority, now `1.98.1` — forced,
since `ndarray` 0.17.2 declares `rust-version = "1.98"`.
- *"runs on every push/PR"* — the `push` trigger is limited to `main`, so
the accurate statement is every pull request and every push to `main`.
- *"all scoped to `native/lgj-abi` via `--manifest-path`"* — that scoping
is what broke the first run. Cargo reads `.cargo/config.toml` from the
working directory's ancestry, never from the manifest's directory, so
the crate's `-Ctarget-cpu` baseline was dropped and
`the_x86_64_build_has_a_vector_baseline` failed exactly as designed. The
jobs now set `working-directory` to the crate, and CI exports the v3
baseline explicitly because GitHub-hosted runners do not guarantee
AVX-512. Each `setup-rust-toolchain` step also gained `rust-src-dir`:
`defaults.run.working-directory` governs `run:` steps only, so without it
the action reads no toolchain file and falls back to `stable`.
- *"whether `-D warnings` is clean on `lgj-abi` today is unmeasured"* — now
measured locally: clippy and fmt clean, 138 unit tests plus the G11 fence
passing, under the same commands CI runs.

**Docs.** `LATEST_STATE.md` entry; this entry.

**Confidence.** High that the workflow shape is correct (it is a direct
transplant of `lance-graph`'s own proven `style.yml` checkout pattern,
adapted to this repo's single-crate layout). Unmeasured whether the
`clippy`/`rust-test` jobs pass clean on first run — that is what the CI
run itself is for.

## PR #68 — mask-risc-lowering v1 → v4: SPEC completion, the 5+3 council, voxelmasking (merged 2026-09-03 as `dfb4ab1`, head `4ad9377`)

**Added.** Four commits on `.claude/plans/mask-risc-lowering-v1.md`, plan-only — no kernel, no ABI symbol, no mint, no production code. `51dcffc` completed SPEC v1 to the council bar (non-goals, pre-registered gates G1–G8, per-savant question sets); `00570a0` draft v2 (5 savants, 40 findings, 24 amendments); `0212d21` ratified v3 (3 reviewers, 2 BLOCK + 14 FIX, 2 external Codex P1s); `4ad9377` the v4 amendment — §14 voxelmasking, §3c reuse map, §15 two probes. `STATUS_BOARD` rows `D-MRL-0f` and `D-MRL-0g`.
Expand Down
187 changes: 187 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
name: Lint

on:
pull_request:
push:
branches:
- main

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

# Least-privilege: these jobs only read the repo (checkout + build + lint).
permissions:
contents: read

env:
CARGO_TERM_COLOR: always

jobs:
# lgj-abi path-deps ndarray and lance-graph-contract (crates/lance-graph-contract
# in the AdaWorldAPI/lance-graph sibling), and optionally (feature `ogar-classview`,
# off by default) ogar-class-view in the AdaWorldAPI/OGAR sibling. Cargo resolves
# the full dependency graph — including inactive optional path deps — so all three
# siblings must exist on disk even though only two are compiled into the default
# build. Checked out under the runner's top-level workspace, sibling to this repo's
# own checkout, exactly as `../../../<repo>` from native/lgj-abi/Cargo.toml expects
# (matches AdaWorldAPI/lance-graph's own .github/workflows/style.yml pattern).
format:
runs-on: ubuntu-latest
timeout-minutes: 15
defaults:
run:
working-directory: lance-graph-java/native/lgj-abi
steps:
- uses: actions/checkout@v4
with:
path: lance-graph-java
- uses: actions-rust-lang/setup-rust-toolchain@v1
Comment thread
coderabbitai[bot] marked this conversation as resolved.
with:
# `defaults.run.working-directory` applies to `run:` steps only, NOT
# to action steps: this action executes from GITHUB_WORKSPACE, where
# the checkout is a subdirectory and no toolchain file is visible. It
# would silently fall back to `stable` instead of the pin. `rust-src-dir`
# is the input that points it at the crate — which is also where
# `rust-toolchain.toml` lives, beside `.cargo/config.toml`.
rust-src-dir: lance-graph-java/native/lgj-abi
# The baseline goes HERE, not in a `CARGO_BUILD_RUSTFLAGS` env var.
# This action exports `RUSTFLAGS` from its own `rustflags` input
# (default `-D warnings`), and `RUSTFLAGS` overrides
# `build.rustflags` — which is what `CARGO_BUILD_RUSTFLAGS` sets, so a
# baseline put there is silently discarded. The first run proved it:
# the crate's own SIGILL-guard test was reached with no target-cpu at
# all. The action's default is kept alongside the baseline, not
# replaced.
#
# v3 rather than the crate's own v4: `.cargo/config.toml` pins AVX-512
# because the production artifact is built for one known host, and
# GitHub-hosted runners do not guarantee it. That file names v3 as the
# remedy for a machine without AVX-512, and AVX2 is what
# `the_x86_64_build_has_a_vector_baseline` requires — so this
# retargets the gate rather than weakening it.
rustflags: -D warnings -Ctarget-cpu=x86-64-v3
# No `toolchain:` input — the action reads `rust-toolchain.toml`, so the
# pinned version lives in exactly ONE place.
components: rustfmt, clippy
- name: Check formatting (lgj-abi)
run: cargo fmt -- --check

clippy:
runs-on: ubuntu-latest
timeout-minutes: 30
defaults:
run:
working-directory: lance-graph-java/native/lgj-abi
steps:
- uses: actions/checkout@v4
with:
path: lance-graph-java
- name: Checkout AdaWorldAPI/ndarray (sibling dependency)
uses: actions/checkout@v4
with:
repository: AdaWorldAPI/ndarray
path: ndarray
- name: Checkout AdaWorldAPI/lance-graph (sibling dependency, lance-graph-contract)
uses: actions/checkout@v4
with:
repository: AdaWorldAPI/lance-graph
path: lance-graph
- name: Checkout AdaWorldAPI/OGAR (sibling dependency, optional ogar-classview feature)
uses: actions/checkout@v4
with:
repository: AdaWorldAPI/OGAR
path: OGAR
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
# `defaults.run.working-directory` applies to `run:` steps only, NOT
# to action steps: this action executes from GITHUB_WORKSPACE, where
# the checkout is a subdirectory and no toolchain file is visible. It
# would silently fall back to `stable` instead of the pin. `rust-src-dir`
# is the input that points it at the crate — which is also where
# `rust-toolchain.toml` lives, beside `.cargo/config.toml`.
rust-src-dir: lance-graph-java/native/lgj-abi
# The baseline goes HERE, not in a `CARGO_BUILD_RUSTFLAGS` env var.
# This action exports `RUSTFLAGS` from its own `rustflags` input
# (default `-D warnings`), and `RUSTFLAGS` overrides
# `build.rustflags` — which is what `CARGO_BUILD_RUSTFLAGS` sets, so a
# baseline put there is silently discarded. The first run proved it:
# the crate's own SIGILL-guard test was reached with no target-cpu at
# all. The action's default is kept alongside the baseline, not
# replaced.
#
# v3 rather than the crate's own v4: `.cargo/config.toml` pins AVX-512
# because the production artifact is built for one known host, and
# GitHub-hosted runners do not guarantee it. That file names v3 as the
# remedy for a machine without AVX-512, and AVX2 is what
# `the_x86_64_build_has_a_vector_baseline` requires — so this
# retargets the gate rather than weakening it.
rustflags: -D warnings -Ctarget-cpu=x86-64-v3
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
with:
workspaces: lance-graph-java/native/lgj-abi
- name: Clippy lgj-abi
run: cargo clippy --all-targets -- -D warnings

rust-test:
runs-on: ubuntu-latest
timeout-minutes: 30
defaults:
run:
working-directory: lance-graph-java/native/lgj-abi
steps:
- uses: actions/checkout@v4
with:
path: lance-graph-java
- name: Checkout AdaWorldAPI/ndarray (sibling dependency)
uses: actions/checkout@v4
with:
repository: AdaWorldAPI/ndarray
path: ndarray
- name: Checkout AdaWorldAPI/lance-graph (sibling dependency, lance-graph-contract)
uses: actions/checkout@v4
with:
repository: AdaWorldAPI/lance-graph
path: lance-graph
- name: Checkout AdaWorldAPI/OGAR (sibling dependency, optional ogar-classview feature)
uses: actions/checkout@v4
with:
repository: AdaWorldAPI/OGAR
path: OGAR
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
# `defaults.run.working-directory` applies to `run:` steps only, NOT
# to action steps: this action executes from GITHUB_WORKSPACE, where
# the checkout is a subdirectory and no toolchain file is visible. It
# would silently fall back to `stable` instead of the pin. `rust-src-dir`
# is the input that points it at the crate — which is also where
# `rust-toolchain.toml` lives, beside `.cargo/config.toml`.
rust-src-dir: lance-graph-java/native/lgj-abi
# The baseline goes HERE, not in a `CARGO_BUILD_RUSTFLAGS` env var.
# This action exports `RUSTFLAGS` from its own `rustflags` input
# (default `-D warnings`), and `RUSTFLAGS` overrides
# `build.rustflags` — which is what `CARGO_BUILD_RUSTFLAGS` sets, so a
# baseline put there is silently discarded. The first run proved it:
# the crate's own SIGILL-guard test was reached with no target-cpu at
# all. The action's default is kept alongside the baseline, not
# replaced.
#
# v3 rather than the crate's own v4: `.cargo/config.toml` pins AVX-512
# because the production artifact is built for one known host, and
# GitHub-hosted runners do not guarantee it. That file names v3 as the
# remedy for a machine without AVX-512, and AVX2 is what
# `the_x86_64_build_has_a_vector_baseline` requires — so this
# retargets the gate rather than weakening it.
rustflags: -D warnings -Ctarget-cpu=x86-64-v3
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
with:
workspaces: lance-graph-java/native/lgj-abi
# Runs every #[test] in lgj-abi, including tests/g11_contract_import_fence.rs
# — the fence CLAUDE.md's "Enforcement" section names as structural: it walks
# src/ and rejects any `lance_graph_contract::` module outside the four-name
# allowlist. Per this repo's own history, "G11 was prose until 2026-09-03"
# because nothing ran the test that enforces it; this job is what runs it.
- name: Test lgj-abi
run: cargo test --all-targets
Loading
Loading