quack: two-world frontend — describe once, resolve once, canonicalize once, execute numeric - #1328
Conversation
A developer-facing binder in front of Quack's numeric IR:
table("users").where_eq("smtp", "alice@x.de").count()
.bind(&binder) -> Query { and([Plane(live), Cmp(Col, EqU32(id))]), Count }
- quack::bind (the crate's only text-bearing module): Draft / FieldRef /
Literal / Op, the Binder trait (catalog + codebook, never mints), and
BindError in the developer's vocabulary. quack::Query is already the
resolved form, so no ResolvedQuery type is added.
- Schema follows the same lifecycle: create_table(..).width(..) ->
Registrar -> ResolvedTable { id, width }. No crate owns a table catalog
or allocation yet; Registrar has only a test implementation.
- tests/string_fence.rs: lib.rs (the executable IR and lowering) holds no
text types; bind.rs is the only other module.
- Consumers keep their identity contracts behind the same frontend:
report/tests/quack_bind.rs (CAM ordinal survives a label rename),
dir-sim/tests/quack_bind.rs (ValueId exact vs KeyId comparison; the
key-bound query lowers to exactly key_eq_program).
- Board entry: the two-world contract, the storage/query/schema
lifecycle table, and the Java / SAP / IAM / SQL / DDL seams.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg
|
Warning Review limit reachedYour organization has reached its usage spending cap. Adjust your spending cap in the billing tab. Next included review available in 24 minutes. View limit detailsLimit details: You’ve used all 2 included reviews currently available. Your 54 included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (8)
Warning Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption. Comment |
Bugbot couldn't run - usage limit reachedBugbot 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: 968ab1ee-c745-443e-b271-15e24c91ec6b) |
Known-vector falsifier: Cmp::EqU32Strided(0x12345678) matches exactly the records holding [0x78,0x56,0x34,0x12] and never the byte-swapped spelling, through the executor (ndarray kernel) and the reference interpreter, for a contiguous and a strided lane, in both the 16-lane group path and the tail. Literal byte fixtures, so the test does not pass merely on an LE host. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg
… tie Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg
The resolution membrane also fixes the physical representation: Quack's Query stays semantic numeric IR (no Endian field, no ResolvedQuery), and byte order exists only where a fixed-width integer meets raw bytes, where it is little-endian. Byte arrays (Dn128, facet pattern/care) are order- neutral. Documented in quack::bind and the board entry, with the byte- boundary audit: every production reader is explicit LE; FacetCascade's compute-lens reinterpret is fenced by a compile-time LE guard and reported, not changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg
|
Generated by Claude Code |
The upload step already sets fail_ci_if_error: false, but a TLS handshake failure inside codecov-action itself throws before the uploader runs and still failed the job (EPROTO, SSL alert 40, on #1327 and #1328) after every test had passed. continue-on-error makes the step non-blocking as intended; test failures still fail the cargo llvm-cov step above. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg
… durable commit, storage supplies capabilities Architecture-only follow-up to #1328. Records the read boundary (a backend binds once before execution and never approximates Quack semantics), the write boundary (Rubicon amortizes transient folds into one durable sparse commit; 64k parallelism and Kanban are never storage requirements), NodeGuid × Version vs backend physical history, the existing seams that already bind before execution (quack::lower, mask-risc validate, Activation::resolve_for_context), and non-binding backend mappings for Lance/MOCA, RocksDB, Iceberg, DuckDB and S3. Flags an open conflict: the proposed durable field-granular merge-on-read write is not what contract::alpha implements (row-granular claims, unclaimed = None never base, discardable). Not renamed or resolved here. No code, no trait, no backend. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg
This is a follow-up to #1327 and #1326. It is not an IAM change: no consumer's identity model or numeric substrate moves.
What a developer writes
bindproduces exactly what a substrate expert would write by hand:Byte order is never something the developer writes, and neither is
ENDIAN LITTLEin a futureCREATE TABLE users WIDTH 512.Design
ResolvedQuery.quack::Queryis already the resolved form:Filter,Cmp,ColandAggare all fixed-width. The new layer exists only in front of it.Queryremains semantic numeric IR; endian handling belongs only at raw-byte and storage boundaries.Cmp::EqU32(0x12345678)is a number and carries noEndianfield.EqU32Stridedreads it from the bytes[0x78, 0x56, 0x34, 0x12].Dn128, facet pattern/care bytes) are order-neutral.Register128stays four little-endianu32words.quack::bindis the crate's only text-bearing module.tests/string_fence.rschecks that the executable IR and its lowering inlib.rshold no text types. That scan covers over 1,000 lines and has a can-fire half.Binderis the consumer's resolution membrane: catalog, live plane and codebook. Its codebook never mints. Quack is ID-agnostic after binding. A report CAM ordinal, an IAMValueId/KeyIdand a SAP code all arrive asEqU32(u32), and their meaning stays with the binder.create_table("users").width(512)→Registrar→ResolvedTable { id, width }, with no name kept. No crate owns a table catalog or allocation yet, soRegistrarhas only a test implementation. This is the missing actuator.SlabDeclaration → resolve_for_context → ResolvedReading. The shared rule is the lifecycle (external ambiguity → once → resolved semantic contract + canonical physical contract); the resolved types stay domain-specific. The full table and the byte-boundary audit are in the board entry.Byte-boundary audit
Every production reader that turns raw bytes into an integer is already explicit little-endian:
eq_u32_strided_to_maskand the group sum;aperture_facet_strided;Register128, and theNodeGuidaccessors.NodeRowis all[u8; N], so its pointer casts are order-neutral.There is one reinterpret:
FacetCascade::as_bytes/ref_from_bytes, a compute lens over a nativeu32. It is not stored (NodeRow::edgesis[u8; 16]), and a compile-timetarget_endian = "little"assertion fences it. It is reported, not changed. No production ABI is intentionally native-endian, so nothing persisted was rewritten.Proofs (each disable-verified red, then restored)
bind::a_text_literal_binds_once_to_the_query_an_expert_writesQueryandProgram==the hand-written onesbind::a_typed_descriptor_binds_to_the_same_queryFieldRefand names bind identically; the dead row is excludedbind::binding_fails_in_the_developers_vocabulary_and_never_mintsUnknownTable/Field/Value,KindMismatch,OutOfRange,WrongTablereport/tests/quack_bind.rsCatalog+CamLabelsas a binder: 1 CAM lookup; after a label rename, the new label binds to the identical query and the old one is unknowndir-sim/tests/quack_bind.rsKeyIdfield: two spellings → one query;ValueIdfield: two spellings → two queries; the key query lowers to exactlykey_eq_program(key)quack/tests/string_fence.rsStringfield tolib.rsquack/tests/canonical_le.rsEqU32Strided(0x12345678)matches exactly the records holding[0x78,0x56,0x34,0x12], never the swapped spelling (strides 4 and 16, group path and tail); executor and reference agree;Register128::from_wordsbytes are read back. Literal byte fixtures, so it cannot pass merely on an LE hostfrom_be_bytes; reference reader →from_be_bytesThe reference-reader disable first came back green. Equal LE and BE row counts let the count comparison tie, so the fixture is now asymmetric.
Totals: quack, report and dir-sim tests pass; contract
register128and mask-risc tests pass. fmt and clippy-D warningsare clean.Deliberately not here
SELECT COUNT(*) FROM users WHERE smtp = '…'would parse into the sameDraft.View.where→Binder→quack::Query, which retiresplan_lower. Answer parity is already proven bylowering_convergence.Binder::code.users_with_keycan becomewhere_eqover the IAM binder in the test.Endianenum, no universal ABI scalar wrapper, no serialization layer, no shared dictionary implementation, noContentIdmove, no persisted catalog.🤖 Generated with Claude Code
https://claude.ai/code/session_01G22yT6htkcdyXsihxxXdrg