|
| 1 | +# D-QR-SAP: ClassView-guided QR256 for deterministic CATS mappings |
| 2 | + |
| 3 | +**Date:** 2026-10-21. **Status:** LAB PLAN / PREREGISTERED PROBES, unimplemented. Rust 1.99. **No SAP connectivity or writes.** |
| 4 | + |
| 5 | +## Thesis |
| 6 | + |
| 7 | +Reuse `lance_graph_contract::class_view::{ClassView, FieldMask, WideFieldMask}` as the structural map of stable CATS DTO field positions, then compile existing positional mappings into a **borrowed QR projection**, not a new SAP evaluator or edge store. QR256 is a typed, bit-packed **256×256 = 8 KiB Boolean relation tile**, only when the demand has two 256-slot domains; a single 23-field mask or 23×row selection should stay a direct mask when cheaper. Store/address metadata is counted separately. |
| 8 | + |
| 9 | +**Existing truths to preserve** (read from main): `lance-graph-sap/src/schema.rs` has 23 append-only `FIELDS`; `bind.rs::CatsBatch` binds cold, keeps null validity and borrowed `LaneRef` execution; `binder.rs::CatsBinder` resolves field names once into Quack; `edge.rs` has `HASH_ORDINALS` (16), `BAPI_ORDINALS` (8), distinct hash profiles, `bapi_sink` as a legitimate explicit wire-boundary materializer. |
| 10 | + |
| 11 | +## Mapping contract |
| 12 | + |
| 13 | +- `ClassView::fields(ClassId)` selects an existing canonical ordered field basis; the original `ClassView` trait is not edited. A separately validated table `SchemaSeal / ClassId / FieldRef.ordinal` ensures `FIELDS[i]` corresponds to the declared ClassView position. If no truthful field identity exists, **refuse** rather than invent one. |
| 14 | +- `FieldMask` or `WideFieldMask::full_for(23)` expresses **structural field presence only**, not column data, permission, foreign keys, BAPI order, or Boolean graph relationships. The 23-field case remains in `WideFieldMask::Small` without allocation. Append-only bit positions are immutable. |
| 15 | +- **Authorization is independent**: `effective = present ∩ allowed(class) ∩ requested` (cf. #1558 `visible_fields`), but a field mask alone is *not* evidence of an allowed query or cross-table identity. |
| 16 | +- One `ProjectionSpec` (working name, not an API) binds source `ClassId`, predicate/method palette identity, `&[FieldOrdinal]` (e.g. 16 HASH or 8 BAPI), schema generation and source batch generation. The format-string metaphor `"{0}{1}" -f $laneA[$i],$laneB[$i]` selects **positions**, never builds strings in the hot path. |
| 17 | +- Keep `HASH_ORDINALS` and `BAPI_ORDINALS` as **independent output orders and semantic profiles**. A QR transpose or field permutation cannot rewrite hash normalization, Unicode handling or notes(50) rules. Only the actual hash/BAPI terminal formats strings. |
| 18 | + |
| 19 | +## Falsifier probes (S0→S5) |
| 20 | + |
| 21 | +| Probe | Positive oracle | Mandatory refusal / counterexample | |
| 22 | +|---|---|---| |
| 23 | +| S0 Census | compare `FIELDS`, `CatsSchema::resolve`, `ClassView`, `HASH_ORDINALS`, `BAPI_ORDINALS` | field renumbering or absent identity claim | |
| 24 | +| S1 ClassView presence | 23 bits mapped in canonical order, `WideFieldMask::full_for(23)`, two nullable fields kept distinct | NULL != empty != 0; field mask never authorizes a read | |
| 25 | +| S2 Ordered projector | 16-position hash and 8-position BAPI read original `CatsBatch` lanes by witnessed ordinals; byte-for-byte compare with `edge.rs` sinks | reorder one field: parity must break; no silent generated edge | |
| 26 | +| S3 Profile laws | canonical hash text and HMAC-SHA512 match **each** independent existing profile | different decimal separators, Unicode uppercase, short/non-ASCII notes refuse where existing code refuses | |
| 27 | +| S4 QR choice | projected Boolean membership for 64 and 256 local slots agrees with scalar direct masks; measure cold projection + hot reuse | 8 KiB staging when a single 64-bit field mask suffices is a **negative** cost result | |
| 28 | +| S5 Boundary | equivalent `Count/Exists` from Quack+mask-RISC; wire `BapiCatsInsert` only at sink | foreign positional gather during PREPARE forbidden under ADMISSION B | |
| 29 | + |
| 30 | +## Work order and gates |
| 31 | + |
| 32 | +1. S0 inspect #1659 borrowed `Run` + `Side`, #1660 QR and `ClassView` declarations, EXO-119 position-template proposal. Claim no other session's API. |
| 33 | +2. S1 prototype a **lab-only** field-lens descriptor over existing CATS `LaneRef`, no new `Vec<Row>` or String runtime formatter. |
| 34 | +3. S2 run independent exact oracles against existing `edge.rs` and `query.rs` behaviors. Prove masks/fields stable for optional fields. |
| 35 | +4. S3 test QR materialization only for repeated 2-axis questions; compare direct mask, QR64 and QR256 where their axes mean the same thing. |
| 36 | +5. S4 measure bind/build, cold dictionary work, index bytes, hot ns/µs mask folds, bytes emitted, and parity; failed ms hot-fold gate is **failed**, not a success. |
| 37 | +6. S5 submit measured ADOPT / KEEP-DIRECT / REJECT finding to EXO-50 and update the capstone, **without** production writeback. |
| 38 | + |
| 39 | +**Boundary:** Do not create fake cross-system SAP identifiers, a new SAP graph model, a second evaluator, a new relationship opcode, or speculative BAPI output. No HMAC signing without its existing authorized sink. |
| 40 | + |
| 41 | +**References:** [#1659](https://github.com/AdaWorldAPI/lance-graph/pull/1659), [#1660](https://github.com/AdaWorldAPI/lance-graph/pull/1660), [EXO-119](https://linear.app/exo-red/issue/EXO-119), [EXO-120](https://linear.app/exo-red/issue/EXO-120), [EXO-50](https://linear.app/exo-red/issue/EXO-50), [ClassView](https://github.com/AdaWorldAPI/lance-graph/blob/main/crates/lance-graph-contract/src/class_view.rs). |
| 42 | + |
| 43 | + |
| 44 | +## Cross-PR physical coordinate hypothesis: 6×(PART_OF8:ISA8) |
| 45 | + |
| 46 | +The [capstone mapping](https://github.com/AdaWorldAPI/lance-graph/blob/research/qr-abi-classview-capstone-20261021/.claude/plans/d-qr-abi-classview-rails-capstone-v1.md) proposes reusing the *existing*, content-blind `FacetCascade` 16-byte `facet_classid(4) | 6×(hi:lo)` representation as a **candidate mapping view**, with `hi=part_of`, `lo=is_a` only where the ClassView declares that interpretation. SAP's 23 ordered fields have stable field ordinals but are **not** naturally ISA/PART_OF graph edges; the default is direct `WideFieldMask` field projection. An HHTL16 16×8-bit ISA zipper and separate 16×8-bit PART_OF zipper remain **proposed logical views**, not new stored SAP fields. Test a synthetic typed employee→activity→organizational-unit relationship *only* after source identity and predicate facts are supplied by fixtures. Do not invent these edges from CATS field presence. |
| 47 | + |
| 48 | +**Rail negative oracle:** swapping a field ordinal and a part_of coordinate may yield identical bytes but must fail type checking; full 256-palette identity only within a sealed local codebook; no global ID alias. The 12 bytes of six 8:8 coordinates are not the 8-KiB Boolean QR truth state. |
0 commit comments