Graf compiler hardening — module identity and scalar values
September 14, 2026 — unreleased development work. Three compiler
corrections pass focused native regressions: distinct module function identity,
scalar values inferred from pointer indexing, and signed right-shift widening.
The initial repairs are committed locally as 1b7725fa and 2f6d70c6.
Full Graf validation exposed a dereference regression in the latter; its
follow-up is committed as 72a6003a after focused tests, source review, and
clean preflight. The retry produced a runnable Graf executable, but the native
Git consumer fixture fails at global -c options. Integration and consumer
qualification remain pending; no release is announced.
Module function identity — Gap 181
Section titled “Module function identity — Gap 181”Graf’s context/state.jan and matchmaker/state.jan both define appendSlice
with different parameter types. Basename-only internal naming collapsed them
into state__appendSlice, selecting incompatible parameter metadata. Graf
hit Gap48PointerToI64Alloca; a minimized pointer/integer pair also compiled
into a crashing program.
Commit 1b7725fa1d0716b12d0625012ee3cd73b41ad46f assigns each resolved import
a per-compilation identity before lowering its dependencies. Repeated aliases
and diamond imports reuse that identity. Ordinary calls, generic helpers,
re-exports, and generated runtime calls follow the alias mapping.
This restores the module contract. Import syntax and source aliases are unchanged. Internal prefixes are not a persistent module identifier or public ABI.
Pointer-index inference and signed shifts — Gaps 182 and 183
Section titled “Pointer-index inference and signed shifts — Gaps 182 and 183”The first repaired Graf build exposed four invalid LLVM pointer shifts in
git_import.parseObjectHeader, git_import.readOfsDistanceAt,
git_import.readRefDeltaBaseOid, and git_local.packParseHeader.
For pack: [*]const u8, var byte = pack[pos] loaded an i8, then stored an
inttoptr conversion in a pointer-typed local. Chained mask temporaries also
lost their scalar element type.
Commit 2f6d70c6188b355ae3695b6226120ac91773f243 preserves concrete scalar
pointee semantics before lowering the function body and through local pointer
bindings. This restores indexed value inference.
The negative signed-byte control exposed a separate defect: a narrow signed
operand was zero-extended to the wider shift-count type before AShr, turning
an i8 value of -16 shifted right by four into 15 instead of -1.
The same commit sign-extends that signed operand before the arithmetic shift.
See the bitwise operator contract.
Neither correction relaxes arithmetic typing or the pointer-store guard.
Focused native verification
Section titled “Focused native verification”On the Linux x86_64 development host, both regression scripts passed with the
compiler built from the matching 2f6d70c6 source tree. Its SHA-256 is:
38d1ebc4a0eef677aca5ab2e49a69b34b51684d923cd6eed532f259ce23715b8The module-identity suite builds and runs six executable fixtures: same-name modules, reversed import order, generic helpers, actor helpers, the existing Gap 163 canonical-alias fixture, and the Gap 140 CLI diamond fixture. Generated Katana test contexts and benchmark contexts also pass.
The scalar suite exercises a byte-decoding loop, chained masks, reassignment, negative signed bytes, immutable and explicit annotations, wider annotations, and local pointer binding/writeback. The existing Gap 160 signed/unsigned shift regression also compiles and exits successfully.
Reproduce the suites through the safe build wrapper:
./scripts/zb test-module-basename-identity test-mutable-pointer-index -j4 -Dtrace-gap163=trueRemaining limits
Section titled “Remaining limits”- Opaque pointer elements are tracked separately, Gap 184. The September
14 compiler loaded a byte of the stored pointer when indexing
[*]ptr.tests/regression/opaque_pointer_index.janpreserved the failure: expected exit 0, observed exit 7. It was outside the concrete-scalar correction. The September 17 correction below passes its bounded native regression; integration remains pending. - The actor fixture has a narrower scope. Adding root-level
pub const exported_load = persist.load_slots_u64produced E2010 for unresolved typepersistbefore lowering. That alias was removed; the generated persistence callback checks do not claim to fix it. - DebugAllocator leak diagnostics remain untriaged. Focused script success does not establish a clean compiler release.
Opaque-pointer element indexing follow-up — September 17, 2026
Section titled “Opaque-pointer element indexing follow-up — September 17, 2026”Verified locally; integration pending. The correction on
feature/codex/gap184-opaque-pointer-index preserves pointer-valued
storage when reading and writing elements of [*]ptr parameters. Its bounded
scope also includes inferred local aliases of those parameters and *ptr
dereferences. These operations restore existing behavior; they introduce no
new syntax, public API, or profile availability.
The original regression returned exit 7 because an indexed read loaded a byte instead of the stored pointer. The expanded regression now returns exit 0, including nonzero-index reads, write-back with neighboring slot preservation, inferred aliases, and dereference controls. The scalar pointer and module-identity targets also pass with the same rebuilt compiler. The protected compiler build and regression invocation exit 0. Debug allocator diagnostics remain untriaged.
The expanded fixture and new test target are on the compiler feature branch
at 94237fc7; they are not yet on the integration branch.
Local verification evidence:
- Compiler source revision:
94237fc74441f6d14beb02bbd42f7137c265a92b. - Compiler executable SHA-256:
5990bbf1d02ec50996f6c4ff103b0a0ad2d4dfd9f1ade10b5d4e08db2b060ced. - Tested profile and target:
x86_64 Linux, default build profile without overrides. - Native regression command (exit 0):
./scripts/zb test-opaque-pointer-index test-mutable-pointer-index test-module-basename-identity -j4. - Integration state: pending; no release or deployment is announced.
Generic [*]T instantiations, explicitly annotated local [*]ptr
declarations, and general pointer support are outside this bounded claim.
The regression is a standalone target; aggregate CI wiring remains a
separate follow-up, as for the earlier scalar and module-identity targets. This correction does not establish Graf Git
consumer compatibility, remove the documented -c blocker, or qualify Graf
recovery and network behavior. Those require their own consumer evidence.
Remaining Graf blocker
Section titled “Remaining Graf blocker”The build with the module-identity repair alone failed at four lshr ptr
instructions. The next protected build, at 2f6d70c6, passed those functions
but failed in adapt_cmd.entryInfo at a pointer-to-integer store guard.
The new scalar pointer semantics were retained on a dereferenced rvalue:
var end_pos = path_start.* inferred pointer storage instead of usize.
This remains a Gap 182 regression follow-up. Commit 72a6003a normalizes
the dereference Load to its pointee type and adds a byte-scan fixture with
*usize input and output stores. Combined module-identity, scalar, and Gap 160
targets pass on the matching compiler SHA-256:
1246131c1e99cf4835e197287e56384b9ac40866ce60979d3373273f2d216d25Independent source review found no blocking issue and local preflight was clean. The protected retry produced a Graf executable with SHA-256:
dc0c9894b687c7ae35e02f47645a7e396a87e6278db6285e3a8e4e5c5cc42836The protected build wrapper and harness exit successfully. The retained
executable includes its manifest and reports graf 0.7.0-alpha; git help
also runs. Compiler and source inputs remain unchanged during the build.
The harness still records compiler_source_match: unverified and
reproducibility: not_qualified, so the successful build does not by itself
close those provenance gates. DebugAllocator diagnostics remain untriaged.
The native Git consumer fixture returns failure (gate_b_fixture_pass: false).
All four ordinary root/subdirectory cases exit 2 because graf git treats
-c as a subcommand. The two unsupported-flag cases only satisfy a generic
nonzero-exit check; they do not establish flag-specific validation. The fixture
remains unchanged, no Git tripwire fires, and the separate Git oracle passes
for both directory scopes. Consumer integration, recovery, and network
transport remain unqualified.
These changes restore existing behavior. They introduce no syntax, public API, profile availability, or new language feature.
Annotated opaque-pointer locals — October 1, 2026
Section titled “Annotated opaque-pointer locals — October 1, 2026”Verified locally; integration pending. The September 17 parameter correction
is now integrated at 4f7a3ffc. Its local-alias follow-up preserves pointer
element metadata for var cursor: [*]ptr, let cursor: [*]const ptr, and
let cursor: *ptr. The LLVM layout converter now recognizes the exact builtin
ptr instead of treating it as an unknown name and falling back to an integer.
The existing pointer-to-integer store guard remains enabled.
The native regression checks nonzero indexing, pointer identity, indexed
write-back with the neighboring element unchanged, and dereferencing. The
first candidate failed compilation at the store guard; the corrected candidate
and existing mutable-pointer and module-identity controls all pass under
./scripts/zb test-opaque-pointer-index test-mutable-pointer-index test-module-basename-identity.
The compiler was built with Zig development build 2264 and LLVM 22.1.8 on
x86_64 Linux, using the protected portable toolchain wrapper without a
compilation deadline. Compiler SHA-256:
b5c628a74fc5fe64e0eb307c9fa4bf5b60e377af7eef33c04142f46275d0b7a0.
Compiler candidate: b45c24218dbf0bce5853b5e47b9ff5f653616802.
The fixture is compiler/qtjir/pointer_elements/tests/annotated_locals.jan.
This repairs existing syntax; generic element types, other architectures,
general pointer support and Graf consumer qualification remain outside this
result. Debug allocator leak diagnostics remain untriaged. No release or
deployment is announced.