Commit 8954e53
Knowledge: layout-bridge assessment, OGAR Machine plan, hydrate dependency note (#6)
* Core vertical slice: docs/abi.md contract, native/lgj-abi, Java facade
Ships the fully verified core of the Panama x ndarray::simd x Valhalla
vertical slice (Phases A-E of the mission plan):
- docs/abi.md: the normative Rust<->Java ABI contract, written before
either side was implemented so both could be checked against one
frozen doc instead of each other.
- Five new ndarray::simd primitives (eq_u32_to_mask, gt_i32_to_mask,
mask_and/mask_or(_assign), masked_sum_i32), added under ndarray's own
W1a consumer contract.
- native/lgj-abi: the Rust ABI crate. Generation-checked handle
registry, generic SoA fixture, bulk kernels routed exclusively
through ndarray::simd, 14-symbol extern "C" surface. 72/72 tests
green, clippy/fmt clean, and the registry's core safety check was
disable-verified (short-circuited, confirmed exactly the two
guarding tests go red, restored).
- java/: the Panama membrane (internal/ffm, never exposed publicly)
and the public semantic facade (NativePattern/View/Predicate/
Pattern/Mask). 132/132 checks green across 8 suites, including a
reflection-enforced ApiSurfaceTest that mechanically proves zero FFM
types ever reach a public signature, and a LazinessTest that
empirically proves the thesis: building a chain costs zero
crossings, evaluating it costs exactly one, independent of row
count up to 1,000,000.
- .claude/: a 6-agent ensemble, 6 knowledge docs, and a full board
(LATEST_STATE/STATUS_BOARD/AGENT_LOG/EPIPHANIES/TECH_DEBT/ISSUES/
PR_ARC_INVENTORY/INTEGRATION_PLANS/CODEX_REVIEW_CHECKLIST), all
scoped to this repo's actual seams.
A mechanical audit (D-LGJ-AUDIT) found and fixed the one real rule
violation before this commit: kernels.rs::simd_popcount was calling
the internal ndarray::hpc::bitwise path instead of the sanctioned
ndarray::simd re-export.
Deliberately NOT included: the Valhalla lab (valhalla-lab/) and the
Vector API benchmark harness (bench/) — still in flight, tracked as
open STATUS_BOARD.md rows, to land in a follow-up PR once reviewed
with the same rigor as this slice.
Generated by [Claude Code](https://claude.ai/code)
* Valhalla lab: three-truths method, causal isolation, 3 real reproducers
Completes D-LGJ-F. One experiment source (src/shared/), compiled twice
against real JDKs -- stable JDK 26 GA (record) and the official JEP 401
early-access binary (value record) -- via a self-verifying run.sh that
mechanically diffs the two Vocab.java files modulo the 'value' keyword
before trusting the A/B is honest.
Experiments: IdentityExperiment (semantic truth -- is identity actually
unobservable), FootprintExperiment (real per-object/array/field bytes
via allocation-delta + JOL where available), FfmAddressingExperiment
(is the wrapper free where it touches native memory), ThesisExperiment
(the mandatory headline: 65,536 rows as one native lane vs hydrated
Java objects, on both platforms).
Causal isolation via three additional run.sh passes: escape analysis
off, and UseArrayFlattening/UseFieldFlattening toggled independently --
isolates which flag actually drives the measured difference rather than
inferring it.
Three real Valhalla limitations reproduced and filed under
reproducers/, none of which changed the production API:
- R1: @NullRestricted field on an identity class is a VerifyError
(javac's fault -- no source form expresses the required strict-field
init order relative to super())
- R2: array flattening has a hard 8-byte payload cliff, confirmed via
-XX:+PrintFlatArrayLayout. LaneId/Ordinal/MaskId (<=8B) flatten;
RowRange/Row (16B) do not. This turns "Valhalla helps descriptors,
not entities" from a hand-wave into a measured VM cutoff -- and
RowRange landing on the wrong side is flagged as the one place the
expectation was too optimistic.
- R3: the densest null-restricted array form is jdk.internal-only and
generics erase flattening entirely; Foo! null-restricted type syntax
confirmed not to parse, matching the earlier archaeology finding.
One real defect found and fixed before landing: IdentityExperiment and
the stable Platform called Class::isValue() directly on four vocabulary
types with a comment incorrectly claiming it was "final API on JDK 26"
-- it does not exist there at all, confirmed by a real javac failure.
Fixed by routing every query through Platform.isValueClass(Class<?>),
answered honestly per platform.
Generated by [Claude Code](https://claude.ai/code)
* Vector API bench: real JMH, cross-checked; the crossing does not always win
Completes D-LGJ-G, the mission's mandated "where does execution belong"
comparison -- measured, not assumed to favor the Rust crossing.
Real JMH 1.37 (fork+warmup+compiler-blackholes confirmed in the log, not
a hand-rolled loop -- that lives in valhalla-lab and is labelled as
such there). Four components, cost kept strictly separate per the
mission brief: A_DowncallOverhead (bare crossing, no work), B_SegmentAccess
(raw native-memory read throughput), C_ExecutionBoundary (native fused
plan vs Java Vector API vs Java scalar, swept 64 to 4,194,304 rows),
E_FusionAndPlanning (fused vs unfused vs the scalar reference kernel vs
plan-construction-only, swept 1-8 predicates). 50/50 rows, 0 failures.
Data.crossCheck() runs in @setup and throws if the three kernels
disagree on count or sum, so a faster-but-wrong Vector kernel could not
have won the comparison undetected.
The headline complicates the thesis honestly: for a single predicate
over one native lane, the Java Vector API -- reading the SAME native
MemorySegment zero-copy via IntVector.fromMemorySegment, no byte[], no
bounce buffer -- beats the native crossing at EVERY row count tested,
56.4x at small sizes down to 1.3-1.4x at 4M rows. A second crossover is
also real: native beats a plain Java scalar loop only past roughly
4,096-16,384 rows. Component E shows why this doesn't overturn the
project's premise: SIMD-vs-scalar is the largest lever measured
anywhere in this suite (10.8x-31.1x, growing with predicate count),
and fused/unfused land within this harness's own ~10% noise floor of
each other at 65,536 rows -- the fused plan's real value is the
structural one-crossing guarantee (already proven by LazinessTest),
not a large measured time saving at this scale. Verdict: the crossing
is worth paying for composed, multi-predicate work, not for reading
one predicate off one lane, where Java on the same memory is simply
faster.
RESULTS.md was hand-written from the raw CSV, then independently
cross-checked against summarise.sh -- a script the same PR ships that
mechanically regenerates every table from results/jmh-results.csv, so
a re-run's numbers can never silently drift from a hand-transcribed
table. Both productions agreed to 3 decimal places on every cell
checked.
Generated by [Claude Code](https://claude.ai/code)
* Phase I synthesis docs + fusion-sweep 256-row re-run + board hygiene
Four synthesis docs close D-LGJ-I: architecture.md (the four layers and
what each is provably responsible for), panama.md (manifest-over-header,
belt-and-braces ownership, restricted-method discipline), valhalla-lab.md
(three-truths synthesis, the 8-byte flattening cliff, zero API adoption),
execution-boundary.md (the measured crossover picture + three structural
hot-path facts, each checked rather than assumed).
The fusion sweep was re-run with a 256-row arm after the first pass's
'fusion does nothing' finding proved true only at 65,536 rows: at 256
rows x 8 predicates unfused/fused reaches 2.99x. RESULTS.md is rewritten
from jmh-results-merged.csv; TABLES.md is mechanically generated from
the same file so the two cannot drift.
MultiLaneColumn (ndarray::simd_soa) evaluated for the fixture kernels
and declined on two concrete API mismatches (64-byte-multiple constraint,
no u32 lane); earmarked for the future 512-byte row-store slice where it
fits by construction. Operator layout reference recorded on the board.
PR_ARC_INVENTORY backfilled for merged PRs 1-3; the lapse is owned in
the file itself.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Pud4qpxFHwqyqDjSabQbs
* Board: PR #4 arc entry (post-merge)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Pud4qpxFHwqyqDjSabQbs
* SoA row store: 512B rows, 32 facet lanes, ABI minor 2 (W1+W2)
The lance-graph-shaped substrate, wired end to end. The flat three-lane
fixture was always scaffolding (docs/abi.md 10, architecture.md said so
from PR #1); this is the layout the stack actually converges on:
64K x 512-byte rows, 32 facet lanes of 16 bytes = 4-byte LE classid +
12-byte payload, the V3 content-blind facet.
Rust (native/lgj-abi):
- rowstore.rs: one Arc<[u8]>, two readings (row-major chunks and strided
facet columns), zero copies, normative SplitMix64 generator.
- LGJ_RESOURCE_ROWSTORE + lgj_rowstore_open; facet lanes described
through the UNCHANGED LgjLaneDesc (stride_bytes carried this since
minor 1); lgj_op_eq_classid produces ordinary masks that compose with
the existing algebra; lgj_row_facet_match writes per-row 32-bit facet
sets into a caller-owned buffer via MultiLaneColumn (Arc refcount bump,
no copy).
- byte_len tightened to the exact covered span (len-1)*stride +
elem_bytes: a full-stride final window would let Java bound a segment
past the allocation's end on a facet lane.
- ABI minor 1 -> 2; docs/abi.md gains 11 and its symbol count is
corrected (the 14 was drift; the list already enumerated 15, and the
real number is now 18 per nm -D).
Gates: cargo test 84/84, clippy -D warnings clean, fmt clean, release
build exports 18/18 symbols. Both new kernels are parity-checked against
independent scalar references over 10 row counts x 2 seeds x 4 facets x
4 needles, then cross-checked a third way against RowStore::classid_at;
a two-sided falsifier proves payload bytes never satisfy a classid match
and that a real match does fire.
Docs: .claude/plans/lgj-soa-substrate-v1.md (W1-W5 waves) + one plan per
consumer example (world-trades / bricks-analytics / graph-traversal),
.claude/knowledge/soa-row-store-layout.md, and the board triple ledger.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Pud4qpxFHwqyqDjSabQbs
* Board: PR #5 arc entry (post-merge)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Pud4qpxFHwqyqDjSabQbs
* Knowledge: assess the archived layout-bridge discussion; name W6
The operator's pre-build ChatGPT discussion is assessed once, in
.claude/knowledge/prior-art-and-the-layout-bridge-claim.md, so it is
never re-mined or cited naively. Verdict: it converged independently on
the architecture this repo then built and measured. Kept: the
callability-vs-shared-executable-layout positioning, the schema-key-as-
join-point extractable (now the named W6 consideration: an explicit
schema/classid field on the descriptors when ClassView lands), and the
baseline-dependent claims discipline for W5 comparisons. Pinned: its
page-descriptor sketch has no liveness story (the registry's whole job),
its native-always-wins assumption is measured false (Component C), and
its ndarray paragraph describes upstream crates.io ndarray, not the
AdaWorldAPI fork whose ndarray::simd polyfill this stack mandates.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Pud4qpxFHwqyqDjSabQbs
* Plans: OGAR Machine (exploratory) + lance-graph-hydrate dependency note
Captures the operator's second archived context as
.claude/plans/ogar-machine-v1.md — a genuinely new workload for the
shipped substrate, not convergent confirmation: one row = one machine
STATE, control flow as population masks over 64K execution contexts,
Ghidra P-code as the normalized guest ISA (repo attached and cloned),
differential migration testing (legacy XOR replacement across 65,536
worlds) as the killer demo, Lance as the time machine. Strong claim vs
weak claim separated per the discussion's own discipline; gated on W3 +
one W5 example + Ghidra archaeology + a tiny falsifiable probe (P-M1).
Also records lance-graph #957 (merged: lance-graph-hydrate, the generic
SoA->S3->volume->Lance hydration crate minted for consumers to inherit)
and #958 (its open hardening fast-follow) in the substrate plan: when
this repo's persistence slice arrives, hydration is inherited from
lance-graph-hydrate, never re-derived here.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Pud4qpxFHwqyqDjSabQbs
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>1 parent 78aa60e commit 8954e53
5 files changed
Lines changed: 284 additions & 0 deletions
File tree
- .claude
- board
- knowledge
- plans
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
1 | 18 | | |
2 | 19 | | |
3 | 20 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
11 | 40 | | |
12 | 41 | | |
13 | 42 | | |
| |||
Lines changed: 109 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
| 35 | + | |
35 | 36 | | |
36 | 37 | | |
37 | 38 | | |
38 | 39 | | |
39 | 40 | | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
40 | 53 | | |
41 | 54 | | |
42 | 55 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
0 commit comments