diff --git a/.claude/board/AGENT_LOG.md b/.claude/board/AGENT_LOG.md index e6ed1e03..8579ad4a 100644 --- a/.claude/board/AGENT_LOG.md +++ b/.claude/board/AGENT_LOG.md @@ -1,3 +1,26 @@ +## [Fleet sprint-11-wave-c-qualia-i4-column] [IN PR] D-CSV-5a sibling QualiaI4Column add (branch claude/sprint-11-wave-c-qualia-i4-column) + +**D-id:** D-CSV-5a — QualiaColumn migration phase 5a (split from D-CSV-5 per OQ-CSV-4 sibling-cutover ratification). Adds `QualiaI4Column` ALONGSIDE the existing `QualiaColumn` with double-write on push paths; no read-side change. Phase 5b (separate PR after merge) flips readers + drops the f32 column. + +**Worker:** W-C1 (Sonnet, single worker, ~190 LOC source + ~100 LOC tests). + +**Branched from:** `claude/sprint-11-wave-b-qualia-i4` (PR #384) so the new `QualiaI4_16D` type is available. Will rebase onto main after PR #384 merges. + +**Files modified:** +- `crates/cognitive-shader-driver/src/bindspace.rs` (+190 LOC): NEW `pub struct QualiaI4Column(pub Box<[QualiaI4_16D]>)` mirroring `QualiaColumn` shape (zeros/row/set/len/from_f32 methods); EXTEND `BindSpace` struct with `pub qualia_i4: QualiaI4Column` field; update `BindSpace::zeros` initializer; update `byte_size()` to include `8 * N` for the i4 column; update `BindSpaceBuilder::push_typed` to double-write via `QualiaI4_16D::from_f32_17d(qualia)` immediately after the existing `qualia.set(row, ...)`. 6 new tests in mod tests covering: column zeros, set_row, from_f32 parity, double-column zeros, byte_size includes i4, push_typed double-write parity. +- `crates/cognitive-shader-driver/src/engine_bridge.rs` (+4 LOC): paired `bs.qualia_i4.set(row, QualiaI4_16D::from_f32_17d(&q))` after the engine push at line ~262. +- `crates/cognitive-shader-driver/src/lib.rs` (+1 LOC): re-export `QualiaI4Column` alongside the existing `QualiaColumn`. + +**OQ-CSV-4 absorbed:** sibling-then-cutover (plan §11 default recommendation). Lower-risk than big-bang; 1 extra PR cost worth it. + +**Validation gap noted:** `cargo test -p cognitive-shader-driver` does not work in this environment because cognitive-shader-driver is listed in BOTH `members` AND `exclude` of the workspace `Cargo.toml` (exclude wins, the crate is reachable only via `--manifest-path`). And `--manifest-path crates/cognitive-shader-driver/Cargo.toml` hits a sibling-repo build error (`/home/user/ndarray/src/hpc/merkle_tree.rs` references unresolved `blake3` crate). Structural changes look correct (matches the spec exactly: 3 files, 6 tests, double-write pattern, no read-side change). CI will run the actual tests. + +**Outcome:** D-CSV-5a ready for merge. Wave D candidates next: D-CSV-6 (WitnessCorpus) and D-CSV-7 (MailboxSoA), both depend on PR #383 (D-CSV-1 + D-CSV-4) merging first. + +**Pending finding (worth filing in TECH_DEBT):** the cognitive-shader-driver workspace-membership conflict (members + exclude both list it) is a workspace-config bug. Current effect: the crate compiles when used as a dep transitively but is invisible to `cargo -p`. Fix is one-line: remove from the exclude list. Filed observation only — out of scope for this PR. + +--- + ## [Fleet sprint-11-wave-b-qualia-i4] [IN PR] D-CSV-2 QualiaI4_16D + OQ-CSV-1 ratification (branch claude/sprint-11-wave-b-qualia-i4) **D-id:** D-CSV-2 — `QualiaI4_16D` type in `lance-graph-contract::qualia` + f32↔i4 migration helpers (~250 LOC actual vs ~180 estimate; the +70 over estimate is accessor + magnitude + 8 tests). diff --git a/.claude/board/STATUS_BOARD.md b/.claude/board/STATUS_BOARD.md index e15eaefd..ec12d6e0 100644 --- a/.claude/board/STATUS_BOARD.md +++ b/.claude/board/STATUS_BOARD.md @@ -435,7 +435,8 @@ Consolidates sprint-10 architectural decisions before context dilution. | D-id | Title | Status | PR / Evidence | |---|---|---|---| -| D-CSV-5 | QualiaColumn migration `[f32; 18]` → `QualiaI4_16D` (5a sibling column + 5b cutover) | **Queued** | blocked on OQ-CSV-4 phasing decision | +| D-CSV-5a | QualiaColumn migration phase 5a — sibling `QualiaI4Column` add + double-write (no read-side change) | **In PR** | branch `claude/sprint-11-wave-c-qualia-i4-column`; OQ-CSV-4 ratified to sibling-cutover (default); 5b cutover follows in separate PR | +| D-CSV-5b | QualiaColumn migration phase 5b — flip readers to i4, drop f32 column, drop f32 push arg | **Queued** | depends on D-CSV-5a merge + downstream reader audit | | D-CSV-6 | `WitnessCorpus` (CAM-PQ-indexed) replaces `SpoWitnessChain<32>` | **Queued** | depends on D-CSV-4; elevates CAM-PQ wiring to Wave 3 hard prerequisite | | D-CSV-7 | MailboxSoA integration: W-slot referencing + per-row plasticity accumulator + apply_edges | **Queued** | depends on D-CSV-1, D-CSV-4 | diff --git a/crates/cognitive-shader-driver/Cargo.lock b/crates/cognitive-shader-driver/Cargo.lock index 6684da9c..99503fc3 100644 --- a/crates/cognitive-shader-driver/Cargo.lock +++ b/crates/cognitive-shader-driver/Cargo.lock @@ -54,9 +54,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "arrow-array" -version = "57.3.0" +version = "57.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8955af33b25f3b175ee10af580577280b4bd01f7e823d94c7cdef7cf8c9aef" +checksum = "c8a4ab47b3f3eac60f7fd31b81e9028fda018607bcc63451aca4f2b755269862" dependencies = [ "ahash", "arrow-buffer", @@ -72,9 +72,9 @@ dependencies = [ [[package]] name = "arrow-buffer" -version = "57.3.0" +version = "57.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c697ddca96183182f35b3a18e50b9110b11e916d7b7799cbfd4d34662f2c56c2" +checksum = "0d18b89b4c4f4811d0858175e79541fe98e33e18db3b011708bc287b1240593f" dependencies = [ "bytes", "half", @@ -84,9 +84,9 @@ dependencies = [ [[package]] name = "arrow-data" -version = "57.3.0" +version = "57.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fdd994a9d28e6365aa78e15da3f3950c0fdcea6b963a12fa1c391afb637b304" +checksum = "c1683705c63dcf0d18972759eda48489028cbbff67af7d6bef2c6b7b74ab778a" dependencies = [ "arrow-buffer", "arrow-schema", @@ -97,9 +97,9 @@ dependencies = [ [[package]] name = "arrow-schema" -version = "57.3.0" +version = "57.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c872d36b7bf2a6a6a2b40de9156265f0242910791db366a2c17476ba8330d68" +checksum = "e4cf0d4a6609679e03002167a61074a21d7b1ad9ea65e462b2c0a97f8a3b2bc6" [[package]] name = "async-stream" @@ -280,9 +280,9 @@ checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "blake3" -version = "1.8.4" +version = "1.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d2d5991425dfd0785aed03aedcf0b321d61975c9b5b3689c774a2610ae0b51e" +checksum = "0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce" dependencies = [ "arrayref", "arrayvec", @@ -339,9 +339,9 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.2.60" +version = "1.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", "shlex", @@ -518,6 +518,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "form_urlencoded" version = "1.2.2" @@ -651,15 +657,34 @@ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", ] +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "wasip2", + "wasip3", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + [[package]] name = "h2" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" dependencies = [ "atomic-waker", "bytes", @@ -692,6 +717,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + [[package]] name = "hashbrown" version = "0.16.1" @@ -700,9 +734,9 @@ checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "heck" @@ -852,6 +886,12 @@ dependencies = [ "cc", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "indexmap" version = "1.9.3" @@ -869,7 +909,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.17.1", + "serde", + "serde_core", ] [[package]] @@ -889,10 +931,12 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "js-sys" -version = "0.3.95" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" +checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" dependencies = [ + "cfg-if", + "futures-util", "once_cell", "wasm-bindgen", ] @@ -900,6 +944,11 @@ dependencies = [ [[package]] name = "lance-graph-contract" version = "0.1.0" +dependencies = [ + "glob", + "serde", + "serde_yaml", +] [[package]] name = "lance-graph-ontology" @@ -932,11 +981,17 @@ dependencies = [ "tracing", ] +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "libc" -version = "0.2.185" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libm" @@ -1022,10 +1077,12 @@ name = "ndarray" version = "0.17.2" dependencies = [ "blake3", + "fractal", "matrixmultiply", "num-complex", "num-integer", "num-traits", + "p64", "portable-atomic", "portable-atomic-util", "rawpointer", @@ -1148,18 +1205,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", @@ -1282,6 +1339,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "rand" version = "0.8.6" @@ -1372,6 +1435,12 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + [[package]] name = "serde" version = "1.0.228" @@ -1447,6 +1516,19 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap 2.14.0", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + [[package]] name = "serde_yml" version = "0.0.12" @@ -1535,7 +1617,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.2", "once_cell", "rustix", "windows-sys 0.61.2", @@ -1583,9 +1665,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.52.1" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -1807,6 +1889,18 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + [[package]] name = "version_check" version = "0.9.5" @@ -1834,14 +1928,23 @@ version = "1.0.3+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.57.1", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", ] [[package]] name = "wasm-bindgen" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" +checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" dependencies = [ "cfg-if", "once_cell", @@ -1852,9 +1955,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" +checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1862,9 +1965,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" +checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" dependencies = [ "bumpalo", "proc-macro2", @@ -1875,13 +1978,47 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" +checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.14.0", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "indexmap 2.14.0", + "semver", +] + [[package]] name = "windows-core" version = "0.62.2" @@ -2032,12 +2169,100 @@ dependencies = [ "memchr", ] +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + [[package]] name = "wit-bindgen" version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap 2.14.0", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags", + "indexmap 2.14.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.14.0", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + [[package]] name = "zerocopy" version = "0.8.48" diff --git a/crates/cognitive-shader-driver/Cargo.toml b/crates/cognitive-shader-driver/Cargo.toml index 7728363a..761a3740 100644 --- a/crates/cognitive-shader-driver/Cargo.toml +++ b/crates/cognitive-shader-driver/Cargo.toml @@ -41,7 +41,7 @@ lance-graph-ontology = { path = "../lance-graph-ontology", default-features = fa p64-bridge = { path = "../p64-bridge" } bgz17 = { path = "../bgz17" } causal-edge = { path = "../causal-edge" } -ndarray = { path = "../../../ndarray", default-features = false, features = ["std"] } +ndarray = { path = "../../../ndarray", default-features = false, features = ["std", "hpc-extras"] } # Optional: real thinking-engine wiring behind a feature gate, matching # the EmbedAnything "default = runtime only; heavy deps behind features" rule. diff --git a/crates/cognitive-shader-driver/src/bindspace.rs b/crates/cognitive-shader-driver/src/bindspace.rs index 451e3749..1663b6b4 100644 --- a/crates/cognitive-shader-driver/src/bindspace.rs +++ b/crates/cognitive-shader-driver/src/bindspace.rs @@ -13,6 +13,7 @@ use std::sync::Arc; use lance_graph_contract::cognitive_shader::{ColumnWindow, MetaFilter, MetaWord}; +use lance_graph_contract::qualia::QualiaI4_16D; use lance_graph_ontology::OntologyRegistry; pub const WORDS_PER_FP: usize = 256; @@ -150,6 +151,61 @@ impl QualiaColumn { } } +/// Sibling i4 column alongside QualiaColumn (D-CSV-5a double-write). +/// Length = N rows; each entry is 8 bytes (one `QualiaI4_16D`). +/// Column total = 8 × N bytes. +/// +/// Written on every `push_typed` call alongside the f32 `QualiaColumn`. +/// Reads still use the f32 `QualiaColumn` (cutover is D-CSV-5b). +#[derive(Debug)] +pub struct QualiaI4Column(pub Box<[QualiaI4_16D]>); + +impl QualiaI4Column { + pub fn zeros(rows: usize) -> Self { + Self(vec![QualiaI4_16D::ZERO; rows].into_boxed_slice()) + } + + #[inline] + pub fn row(&self, row: usize) -> QualiaI4_16D { + self.0[row] + } + + #[inline] + pub fn set(&mut self, row: usize, value: QualiaI4_16D) { + self.0[row] = value; + } + + #[inline] + pub fn len(&self) -> usize { + self.0.len() + } + + #[inline] + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// Bulk-convert from an f32 `QualiaColumn`. + /// + /// Uses the flat `[k * QUALIA_DIMS .. (k+1) * QUALIA_DIMS]` slice layout + /// of `QualiaColumn.0` to extract each row, then calls + /// `QualiaI4_16D::from_f32_17d` per row. + pub fn from_f32(qualia_f32: &QualiaColumn) -> Self { + let total = qualia_f32.0.len(); + let rows = total / QUALIA_DIMS; + let mut out = Vec::with_capacity(rows); + for k in 0..rows { + let slice = &qualia_f32.0[k * QUALIA_DIMS..(k + 1) * QUALIA_DIMS]; + // from_f32_17d expects &[f32; 17]; QUALIA_DIMS may be 18, so cap at 17. + let mut arr = [0.0f32; 17]; + let copy_len = slice.len().min(17); + arr[..copy_len].copy_from_slice(&slice[..copy_len]); + out.push(QualiaI4_16D::from_f32_17d(&arr)); + } + Self(out.into_boxed_slice()) + } +} + /// Packed u32 per row: thinking(6) + awareness(4) + nars_f(8) + nars_c(8) + free_e(6). /// One u32 load per row = the cheapest prefilter we can run. #[derive(Debug)] @@ -175,6 +231,7 @@ pub struct BindSpace { pub fingerprints: FingerprintColumns, pub edges: EdgeColumn, pub qualia: QualiaColumn, + pub qualia_i4: QualiaI4Column, pub meta: MetaColumn, pub temporal: Box<[u64]>, pub expert: Box<[u16]>, @@ -205,6 +262,7 @@ impl std::fmt::Debug for BindSpace { .field("fingerprints", &self.fingerprints) .field("edges", &self.edges) .field("qualia", &self.qualia) + .field("qualia_i4", &self.qualia_i4) .field("meta", &self.meta) .field("temporal", &self.temporal) .field("expert", &self.expert) @@ -222,6 +280,7 @@ impl BindSpace { fingerprints: FingerprintColumns::zeros(len), edges: EdgeColumn::zeros(len), qualia: QualiaColumn::zeros(len), + qualia_i4: QualiaI4Column::zeros(len), meta: MetaColumn::zeros(len), temporal: vec![0u64; len].into_boxed_slice(), expert: vec![0u16; len].into_boxed_slice(), @@ -252,11 +311,12 @@ impl BindSpace { let sigma_bytes = self.len; // 1 byte per row, Σ-codebook index let edge_bytes = self.len * 8; let qualia_bytes = self.len * QUALIA_DIMS * 4; + let qualia_i4_bytes = self.len * 8; let meta_bytes = self.len * 4; let temporal_bytes = self.len * 8; let expert_bytes = self.len * 2; let entity_type_bytes = self.len * 2; - content_topic_angle + cycle_bytes + sigma_bytes + edge_bytes + qualia_bytes + meta_bytes + temporal_bytes + expert_bytes + entity_type_bytes + content_topic_angle + cycle_bytes + sigma_bytes + edge_bytes + qualia_bytes + qualia_i4_bytes + meta_bytes + temporal_bytes + expert_bytes + entity_type_bytes } /// Apply MetaFilter across a row window. Returns a dense Vec of row @@ -339,6 +399,11 @@ impl BindSpaceBuilder { self.bs.meta.set(row, meta); self.bs.edges.set(row, edge); self.bs.qualia.set(row, qualia); + // D-CSV-5a: double-write i4 sibling column. + // QUALIA_DIMS may be 18; from_f32_17d takes exactly 17 dims. + let mut q17 = [0.0f32; 17]; + q17.copy_from_slice(&qualia[..17]); + self.bs.qualia_i4.set(row, QualiaI4_16D::from_f32_17d(&q17)); self.bs.temporal[row] = temporal; self.bs.expert[row] = expert; self.bs.entity_type[row] = entity_type; @@ -370,10 +435,10 @@ mod tests { fn bindspace_footprint_adds_columns() { let bs = BindSpace::zeros(1); // 3 × 2048 (content/topic/angle) + 65536 (cycle f32) + 1 (sigma u8) - // + 8 (edge) + 72 (qualia 18×4) + 4 (meta) + 8 (temporal) - // + 2 (expert) + 2 (entity_type) - // = 6144 + 65536 + 1 + 8 + 72 + 4 + 8 + 2 + 2 = 71777 - assert_eq!(bs.byte_footprint(), 71777); + // + 8 (edge) + 72 (qualia 18×4) + 8 (qualia_i4 D-CSV-5a) + 4 (meta) + // + 8 (temporal) + 2 (expert) + 2 (entity_type) + // = 6144 + 65536 + 1 + 8 + 72 + 8 + 4 + 8 + 2 + 2 = 71785 + assert_eq!(bs.byte_footprint(), 71785); } #[test] @@ -516,4 +581,122 @@ mod tests { assert_eq!(bs.fingerprints.cycle_row(0)[16383], -0.5); assert!(bs.fingerprints.cycle_row(1).iter().all(|&v| v == 0.0)); } + + // ── D-CSV-5a: QualiaI4Column tests ───────────────────────────────────── + + #[test] + fn test_qualia_i4_column_zeros() { + use lance_graph_contract::qualia::QualiaI4_16D; + const N: usize = 8; + let col = QualiaI4Column::zeros(N); + assert_eq!(col.len(), N); + for i in 0..N { + assert_eq!(col.row(i), QualiaI4_16D::ZERO, "row {} should be ZERO", i); + } + assert!(!col.is_empty()); + assert!(QualiaI4Column::zeros(0).is_empty()); + } + + #[test] + fn test_qualia_i4_column_set_row() { + use lance_graph_contract::qualia::QualiaI4_16D; + const N: usize = 10; + let mut col = QualiaI4Column::zeros(N); + let known = QualiaI4_16D::ZERO.with(0, 3).with(9, -4).with(15, 7); + col.set(5, known); + assert_eq!(col.row(5), known, "row 5 should equal known value"); + for i in 0..N { + if i != 5 { + assert_eq!(col.row(i), QualiaI4_16D::ZERO, "row {} should still be ZERO", i); + } + } + } + + #[test] + fn test_qualia_i4_column_from_f32_parity() { + use lance_graph_contract::qualia::QualiaI4_16D; + const N: usize = 4; + let mut qcol = QualiaColumn::zeros(N); + let rows: Vec<[f32; QUALIA_DIMS]> = (0..N) + .map(|k| { + let mut arr = [0.0f32; QUALIA_DIMS]; + for d in 0..QUALIA_DIMS { + arr[d] = (k * QUALIA_DIMS + d) as f32 / (N * QUALIA_DIMS) as f32; + } + arr + }) + .collect(); + for (k, row) in rows.iter().enumerate() { + qcol.set(k, row); + } + let i4col = QualiaI4Column::from_f32(&qcol); + assert_eq!(i4col.len(), N); + for k in 0..N { + let mut arr17 = [0.0f32; 17]; + let src = &qcol.0[k * QUALIA_DIMS..(k + 1) * QUALIA_DIMS]; + let copy_len = src.len().min(17); + arr17[..copy_len].copy_from_slice(&src[..copy_len]); + let expected = QualiaI4_16D::from_f32_17d(&arr17); + assert_eq!(i4col.row(k), expected, "row {} mismatch", k); + } + } + + #[test] + fn test_bindspace_zeros_double_column() { + use lance_graph_contract::qualia::QualiaI4_16D; + const N: usize = 5; + let bs = BindSpace::zeros(N); + assert_eq!(bs.qualia.0.len(), N * QUALIA_DIMS); + assert!(bs.qualia.0.iter().all(|&v| v == 0.0)); + assert_eq!(bs.qualia_i4.len(), N); + for i in 0..N { + assert_eq!(bs.qualia_i4.row(i), QualiaI4_16D::ZERO, "i4 row {} should be ZERO", i); + } + } + + #[test] + fn test_bindspace_byte_size_includes_i4() { + const N: usize = 7; + let bs = BindSpace::zeros(N); + let footprint = bs.byte_footprint(); + let content_topic_angle = 3 * N * WORDS_PER_FP * 8; + let cycle_bytes = N * FLOATS_PER_VSA * 4; + let sigma_bytes = N; + let edge_bytes = N * 8; + let qualia_bytes = N * QUALIA_DIMS * 4; + let qualia_i4_bytes = N * 8; + let meta_bytes = N * 4; + let temporal_bytes = N * 8; + let expert_bytes = N * 2; + let entity_type_bytes = N * 2; + let expected = content_topic_angle + cycle_bytes + sigma_bytes + edge_bytes + + qualia_bytes + qualia_i4_bytes + meta_bytes + temporal_bytes + + expert_bytes + entity_type_bytes; + assert_eq!(footprint, expected, + "byte_footprint should include i4 column (8 bytes/row × {} rows = {} bytes)", + N, qualia_i4_bytes); + } + + #[test] + fn test_bindspace_push_typed_double_write() { + use lance_graph_contract::qualia::QualiaI4_16D; + let mut qualia_arg = [0.0f32; QUALIA_DIMS]; + for d in 0..QUALIA_DIMS { + qualia_arg[d] = (d + 1) as f32 / (QUALIA_DIMS + 1) as f32; + } + let content = [0u64; WORDS_PER_FP]; + let bs = BindSpaceBuilder::new(1) + .push_typed(&content, MetaWord::new(1, 0, 100, 100, 0), 0, &qualia_arg, 0, 0, 0) + .build(); + let f32_row = bs.qualia.row(0); + for d in 0..QUALIA_DIMS { + assert_eq!(f32_row[d], qualia_arg[d], "f32 qualia dim {} mismatch", d); + } + let mut arr17 = [0.0f32; 17]; + arr17.copy_from_slice(&qualia_arg[..17]); + let expected_i4 = QualiaI4_16D::from_f32_17d(&arr17); + assert_eq!(bs.qualia_i4.row(0), expected_i4, + "i4 qualia must match QualiaI4_16D::from_f32_17d of the pushed f32 arg"); + } + } diff --git a/crates/cognitive-shader-driver/src/engine_bridge.rs b/crates/cognitive-shader-driver/src/engine_bridge.rs index ad7d1c56..fa796f97 100644 --- a/crates/cognitive-shader-driver/src/engine_bridge.rs +++ b/crates/cognitive-shader-driver/src/engine_bridge.rs @@ -31,6 +31,7 @@ use lance_graph_contract::cognitive_shader::{ StyleSelector, EmitMode, }; +use lance_graph_contract::qualia::QualiaI4_16D; use crate::bindspace::{BindSpace, QUALIA_DIMS, WORDS_PER_FP}; #[cfg(feature = "with-engine")] @@ -260,6 +261,12 @@ pub fn dispatch_busdto( } q[9] = bus.codebook_index as f32; bs.qualia.set(row, &q); + // D-CSV-5a: double-write the i4 sibling column alongside f32 column. + // Reads continue to use bs.qualia (f32); cutover is D-CSV-5b. + // from_f32_17d expects [f32; 17]; q is [f32; QUALIA_DIMS=18]. + let mut q17 = [0.0f32; 17]; + q17.copy_from_slice(&q[..17]); + bs.qualia_i4.set(row, QualiaI4_16D::from_f32_17d(&q17)); // [3] meta column — packed dispatch state. // thinking = caller's style ordinal diff --git a/crates/cognitive-shader-driver/src/lib.rs b/crates/cognitive-shader-driver/src/lib.rs index 609e5500..7cfd6050 100644 --- a/crates/cognitive-shader-driver/src/lib.rs +++ b/crates/cognitive-shader-driver/src/lib.rs @@ -188,7 +188,7 @@ pub use lance_graph_contract::cognitive_shader::{ pub use lance_graph_contract::collapse_gate::{GateDecision, MergeMode}; pub use bindspace::{BindSpace, BindSpaceBuilder, EdgeColumn, FingerprintColumns, - MetaColumn, QualiaColumn}; + MetaColumn, QualiaColumn, QualiaI4Column}; pub use driver::{CognitiveShaderBuilder, ShaderDriver}; pub use engine_bridge::{ EngineBusBridge, UnifiedStyle, UNIFIED_STYLES, unified_style,