Skip to content

D-WXS-3b: the L4 lane — and a disable probe that can itself be vacuous - #948

Merged
AdaWorldAPI merged 5 commits into
mainfrom
claude/jirak-math-theorems-harvest-rfii13
Aug 13, 2026
Merged

D-WXS-3b: the L4 lane — and a disable probe that can itself be vacuous#948
AdaWorldAPI merged 5 commits into
mainfrom
claude/jirak-math-theorems-harvest-rfii13

Conversation

@AdaWorldAPI

Copy link
Copy Markdown
Owner

Follow-up to #947 (merged). Branch restarted from main — a merged PR cannot track new work.

The lane (crates/weather-poc/src/lane.rs)

Pack/unpack one 16-byte facet under layout L4: a 4-byte classid prefix + 6 pairs of two separate bytes (u8:u8, never widened to u16), each byte one ERA5 field quantised by a CalibratedFloor.

33/33 crate-wide · fmt clean · clippy -D warnings clean.

The property the file exists to hold

le-contract §2, operator-ruled: labels and positions come from the ClassView, never from a slot in the payload. So the lane names no ERA5 variable in its own source — it asks the manifest for the slot and hands the entry back out through a caller-owned closure, which is where variable knowledge is allowed to live. A match on a variable name inside lane.rs would be precisely the defect the file was written to prevent.

Reserved slots are zero on pack and absent on unpack — not decoded to bucket_center(0). That distinction is the point: a reserved slot must not read back as a plausible number.

A plan gap found while filing

The lane had a worker in plan §6.2 but no D-id in §4's ladder — it jumped D-WXS-3 → D-WXS-4. Added as D-WXS-3b rather than folded silently into a neighbour. D-WXS-4 (the bake) is now annotated as blocked behind D-WXS-0, the classid mint.

Four disables, each verified to kill the expected tests and no others

break falls
lo/hi swapped the swap test
slot hard-coded instead of read from the manifest 3 tests, incl. the manifest-load-bearing one
version guard bypassed the version-mismatch test
unmapped slots made to emit values the reserved-slot test

The method finding underneath that table — E-A-DISABLE-PROBE-CAN-ITSELF-BE-VACUOUS-1

Three of my probes this session did not probe.

  1. Wrong symbol name. A probe searched for ManifestError::DuplicateSlot; the real variant is SlotCollision. The substitution aborted, the run that followed executed unmodified code, and reported 25 passed. Read casually: a passing disable-verification of a guard never touched.
  2. Dead code. A probe inserted an if computing lo/hi and discarding both. Applied cleanly, bound nothing. 25 passed.
  3. Wrong target. A probe changed raw to raw.max(1) to make reserved slots decode — but the unpack loop only visits manifest-resolved slots, so it could never reach one. 33 passed.

Instance 1 is the dangerous one: 2 and 3 at least ran.

This workspace already holds "an assertion implied by the code it tests is not a test" and "turning a knob that does not bind is not a disable"both stated about tests. The same failure applies to the verification probe, and is harder to see there, because a broken probe and a passing suite look identical.

The signature that separates them: a correct disable kills at least one test, usually a small nameable set. A disable that kills ZERO tests is more likely a broken probe than a missing guard — treat zero as re-check the probe, never as verified.

Mechanical fix now in use: every substitution asserts its pattern was found and that the file actually changed, so a wrong symbol name is an error instead of a green run.

Why this earns a board entry rather than a shrug: the whole disable-the-fix discipline exists to establish that a passing test could fail. An unchecked probe gives that discipline an unverified root and hands back exactly the confidence it was built to withdraw.

Board hygiene (same commit)

STATUS_BOARD gains D-WXS-3b + the D-WXS-4 blocker annotation; EPIPHANIES prepended, suffix-verified.

Still open, in order of hardness

  1. D-WXS-0 — the classid mint, OGAR-side and operator-gated. Until it resolves the bake must refuse to write: a dataset under 0x0000_0000 is indistinguishable from a bootstrap row. Not something this session can unblock.
  2. D-WXS-7 — the re-specified D-WXA-5, the actual gate. Never run; everything downstream hangs on it. Every arm below ρ ≈ 0.9 would be a substrate result, not a weather one.
  3. D-WXS-2a — row-major vs Morton. Until measured, §1.2's whole-byte-per-axis assignment is a stated deviation from the OGAR cascade doctrine, not a ruling.

Note on CI: weather-poc is workspace-EXCLUDED, so green CI means the main workspace is unaffected. The crate itself is gated separately via cargo test --manifest-path crates/weather-poc/Cargo.toml.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi


Generated by Claude Code

…be vacuous

The lane: pack/unpack ONE 16-byte facet under layout L4 -- a 4-byte classid
prefix plus 6 pairs of two SEPARATE bytes (u8:u8, never widened), each byte one
ERA5 field quantised by a CalibratedFloor. 33/33 crate-wide, fmt clean, clippy
-D warnings clean.

The property the file exists to hold is le-contract section 2: labels and
positions come from the ClassView, never from a slot in the payload. So the lane
names no ERA5 variable in its own source -- it asks the manifest for the slot
and hands the entry back out through a caller-owned closure, which is where
variable knowledge is allowed to live. A `match` on a variable name inside
lane.rs would be the defect the file was written to prevent.

Reserved slots are zero on pack and ABSENT on unpack -- not decoded to
bucket_center(0). That distinction is the point: a reserved slot must not read
back as a plausible number.

A plan gap found while filing: the lane had a worker in section 6.2 but NO D-id
in section 4's ladder, which jumped D-WXS-3 to D-WXS-4. Added as D-WXS-3b rather
than folded silently into a neighbour. D-WXS-4 (the bake) is annotated as
blocked behind D-WXS-0, the classid mint.

Four disables, each verified to kill the expected tests and no others:
lo/hi swapped -> the swap test; slot hard-coded -> 3 tests including the
manifest-load-bearing one; version guard bypassed -> the version test; unmapped
slots made to emit values -> the reserved-slot test.

EPIPHANIES E-A-DISABLE-PROBE-CAN-ITSELF-BE-VACUOUS-1 records the method finding
underneath that list. Three of my probes this session did not probe: one
searched for a variant name that does not exist (ManifestError::DuplicateSlot;
the real one is SlotCollision) so the substitution aborted and the run that
followed executed unmodified code and reported 25 passed; one inserted dead code
that applied cleanly and bound nothing; one targeted a code path the loop can
never reach for the case under test. The workspace already holds "an assertion
implied by the code it tests is not a test" and "turning a knob that does not
bind is not a disable" -- both stated about TESTS. The same failure applies to
the VERIFICATION PROBE, and is harder to see there, because a broken probe and a
passing suite look identical.

The signature that separates them: a correct disable kills at least one test,
usually a small nameable set. A disable that kills ZERO tests is more likely a
broken probe than a missing guard -- treat zero as re-check-the-probe, never as
verified. Mechanical fix now in use: every substitution asserts its pattern was
found and the file actually changed, so a wrong symbol name is an error instead
of a green run.

This matters because the whole disable-the-fix discipline exists to establish
that a passing test COULD fail. An unchecked probe gives that discipline an
unverified root and hands back exactly the confidence it was built to withdraw.

Board: STATUS_BOARD gains D-WXS-3b and the D-WXS-4 blocker annotation;
EPIPHANIES prepended, suffix-verified.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi
@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@AdaWorldAPI, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 85 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ae171c9c-ac42-4e4e-bc7b-9deb55f493c3

📥 Commits

Reviewing files that changed from the base of the PR and between 09f4c13 and 5169ff8.

📒 Files selected for processing (6)
  • .claude/board/EPIPHANIES.md
  • .claude/board/STATUS_BOARD.md
  • .claude/plans/weather-soa-bake-v1.md
  • crates/weather-poc/src/floor.rs
  • crates/weather-poc/src/lane.rs
  • crates/weather-poc/src/lib.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cursor

cursor Bot commented Aug 13, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_9b6190d9-8a52-4621-8a99-94f7a67beb85)

…e run

The bar, not the result. Committed first because that is the rule -- and because
this deliverable exists to settle a deviation I introduced, which makes writing
the bar afterwards exactly the failure mode the rule guards.

Split in two, because only one half is runnable today. Half A is pure key space
-- no ERA5 data, no classid, no bake -- and is what is pre-registered here.
Half B is the zeta stencil under each layout, gated on D-WXS-9 and therefore on
the classid mint; it inherits these metrics when it runs.

A correction to section 1.3a's own wording lands with it: I called the shipped
layout "row-major", which is imprecise. The key orders bytes as
[lat_tile, lon_tile, lat_hip, lon_hip], so lexicographic order is
tile-row-major and then row-major WITHIN a tile -- a two-level blocked order
that already has better locality than a flat row-major over 721x1440. Recorded
before measuring, so the comparison runs against what is actually shipped rather
than against the looser word I used.

Two metrics, both over key-order index: range count to cover a box EXACTLY with
no false positives (an over-reading scan that filters afterwards is a weaker
thing and does not count), and median neighbour distance over the 4-neighbourhood
with longitude wrapping.

Three arms: SHIPPED, MORTON (the OGAR-canon nibble-interleave), and CONTROL-BAD
(axis bytes reversed, deliberately locality-destroying).

The bar has both halves and a kill. Primary: MORTON must beat SHIPPED on BOTH
metrics. Control that can lose: CONTROL-BAD must be worse than both -- if a
deliberately bad order scores like the good ones, the metric is not measuring
locality and no verdict may be read off it. Stay-silent twin: on a TILE-ALIGNED
box, SHIPPED and MORTON must give exactly one range each, identical -- that is
section 1.2's actual load-bearing claim and it must show NO difference where the
plan claims none; a comparison that finds MORTON better everywhere, including
here, is measuring something other than what it says.

KILL: if MORTON does not win on both metrics, the deviation is harmless for this
workload, section 1.3a downgrades from "stated deviation owing a decision" to a
recorded note, and D-WXS-2a closes with no code change. A negative result is the
cheaper outcome -- it retires an open question instead of opening a migration.

Stated now so a green half A is not later misread as a mandate: half A can only
show whether a difference exists in key space at all. The stencil is where
locality is actually spent. If half A kills, half B is moot; if half A confirms,
half B still has to run before any migration.

Doc-only. No probe written yet, deliberately.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi
@AdaWorldAPI
AdaWorldAPI marked this pull request as ready for review August 13, 2026 10:10

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d83b4d3e38

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

level_hpa: entry.level_hpa,
})?;

bytes[slot_offset(pair, byte)] = floor.quantize(value);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject non-finite readings before quantizing

When the bake forwards Zarr values directly as Some(value), a missing ARCO-ERA5 chunk produces NaN values (the store behavior is documented in probes/weather-p1/README.md:47-54), but this call accepts them and CalibratedFloor::quantize ultimately casts the NaN bucket index to 0. The entire missing field is therefore written as valid low-bucket measurements and later unpacked as plausible numbers rather than producing MissingValue; reject non-finite values here or require the value source to return an error/None for them.

Useful? React with 👍 / 👎.

claude added 3 commits August 13, 2026 10:16
Codex found a real silent-corruption path in pack_facet. Verified on every
link before fixing, and it is worse than the review comment states.

The store: probes/weather-p1/README.md section 1 records ARCO-ERA5's
fill_value: NaN, that several variables 404 at the arc's OWN fixture timestep,
and that in Zarr v2 a missing chunk means all-fill_value -- so a 404 is valid
store semantics, not a fetch failure, and "any ingest must treat 404 as data".

The overlap: the 404-ing list at that timestep includes
mean_sea_level_pressure, 10m_v_component_of_wind, surface_pressure,
total_column_water_vapour and total_cloud_cover -- FIVE variables the W1 field
set actually packs (F0 pairs 0, 1, 3, 4). Not hypothetical.

The mechanism, measured rather than assumed: CalibratedFloor::quantize maps
non-finite input to a valid-looking bucket, silently. NaN -> 0, -inf -> 0,
+inf -> 255. Rust's float-to-int cast saturates and sends NaN to zero, and
f64::clamp PROPAGATES NaN rather than clamping it, so the clamp does not
catch it either.

Beyond the review comment: the guard must cover ALL non-finite, not only NaN.
+/-inf land on the rim buckets, which are legitimate saturation values and
therefore exactly as indistinguishable from a real reading.

Without the guard an entire missing field would be written as plausible
low-bucket measurements and read back through bucket_center as ordinary
numbers -- the same failure the reserved-slot rule ("a reserved slot must not
read back as a plausible number") exists to prevent, one level deeper and
harder to see.

Fix: LaneError::NonFiniteValue, and pack_facet refuses before quantize. The
guard sits in the lane because that is the boundary where an external value
enters the byte register. quantize itself is left alone -- it is a hot
primitive, changing its signature ripples, and calibrate already filters
is_finite (checked: it is clean, the hole was only in the pack path).

The test's third block is what makes it a test rather than a restatement of
the guard: it quantises the same non-finite values directly and asserts the
decoded result lands INSIDE [lo, hi] -- demonstrating in the suite what the
guard prevents. Can-fire covers NaN/+inf/-inf with only ONE field poisoned per
run, so a guard that fired on everything would fail the paired stay-silent
half, which packs the same slots with finite values.

Disable-verified: neutralising the guard fails exactly this test and no other.

34/34, clippy -D warnings clean, fmt clean.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi
…e metric

Following codex's lane.rs finding to its class rather than stopping at the
instance. The question after a review catch is never "is it fixed" but "was
that the only instance or the first one found". It was the first.

CalibratedFloor::saturation_of takes -- by its own doc -- "an ARBITRARY
external population" and quantised every value directly. quantize maps
non-finite to a RIM bucket silently (NaN -> 0, -inf -> 0, +inf -> 255), and rim
is exactly what saturation_of counts. So a NaN read as saturation.

This is worse than the lane hole, not equal to it. saturation_of is bar B2's
INSTRUMENT. A corrupted stored value is bad; a corrupted measurement is worse,
because every conclusion downstream inherits it and nothing looks wrong. An
all-NaN population -- valid ARCO-ERA5 store semantics for a missing chunk --
would have scored 1.0: "completely saturated" when the truth is "no data at
all". Those are opposite findings and the bare fraction could not tell them
apart.

Silently DROPPING the non-finite values would have been the other half of the
same mistake: the caller would never learn the population was partly or wholly
absent. So the fix reports rather than folds or drops, matching this crate's
standing shape (calibrate and decode both return None on a degenerate case
rather than inventing a number).

saturation_of now returns SaturationScore { fraction, finite, non_finite }.
The fraction is over the finite subset; non_finite is a fact about the DATA,
not about the floor, and the caller sees it. Both existing call sites updated
to assert non_finite == 0 on their all-finite fixtures, which also makes them
say out loud that their populations are clean.

The test's sharp block is the all-NaN case that would have scored 1.0. The
mixed block proves absent values do not move a genuinely low fraction AT ALL
(asserted equal, not merely close). +/-inf are covered separately because they
land on the rim buckets rather than bucket 0, so a NaN-only guard would have
missed them. The stay-silent twin holds clean data unaffected.

Disable-verified: folding non-finite back in -- the pre-fix behaviour -- fails
exactly this test and no other.

Also checked and CLEAN: calibrate already filters is_finite, so the hole never
reached the calibration path. Every quantize call site in the crate is now
either guarded or provably finite.

35/35, clippy -D warnings clean (two repeat().take() nits fixed), fmt clean.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi
Records the class behind the two NaN fixes, because the transferable part is
not the fix -- it is the shape.

CalibratedFloor::quantize is TOTAL: every input returns a valid-looking
bucket. It has no way to say "that was not a measurement". Measured: NaN -> 0
(f64::clamp PROPAGATES NaN rather than clamping it, then the float-to-int cast
saturates to zero), -inf -> 0, +inf -> 255. All three are legitimate buckets;
0 and 255 are the ordinary saturation values and bucket_center(0) is a real
number near lo. Nothing downstream can tell the result from a genuine reading.

Live, not theoretical: ARCO-ERA5 is sparse by design, a 404 chunk means
all-NaN and is valid store semantics, and five of the variables that 404 at
the arc's own fixture timestep are in the W1 field set.

Instance 1 (codex P1) was the STORE path. Instance 2, found by following the
first to its class, was the INSTRUMENT path -- and the sharpening is the entry's
point: a corrupted stored value is one wrong row; a corrupted instrument is
every conclusion drawn with it, each looking sound and carrying no trace of the
defect. When a finding lands on a total function, check its measurement call
sites before its storage call sites.

Also recorded: silently DROPPING invalid input is the other half of the same
mistake, so the fix reports (SaturationScore carries finite/non_finite),
matching calibrate and decode returning None rather than inventing a number.

The generalizable check the entry leaves behind: for every total function
mapping a wider domain onto a narrower one -- quantisers, clamps, `as` casts,
unwrap_or, saturating arithmetic -- ask what an invalid input returns and
whether that is distinguishable from a valid one. If it is a valid-looking
value, the function cannot refuse, and every call site is a corruption path
until one of them does.

STATUS_BOARD D-WXS-3 and D-WXS-3b annotated with their amendments; both are
Status-field rewrites of the same rows, no deletions (audited: 4 changed lines,
2 removals, each the row it replaced).

Doc-only.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi
@AdaWorldAPI
AdaWorldAPI merged commit cd2fd32 into main Aug 13, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants