10 Commits
Author SHA1 Message Date
zeekayandHanzo Dev ea1506e5c2 builder: value-typed ListBuilder + fix latent zap/v1 breakage
StartList returns ListBuilder by value (mirrors the value-typed ObjectBuilder):
Add*/Finish keep pointer receivers, every caller binds to an addressable local so
Go auto-addresses it. Dropped the dead elemSize field (never read — stride is
implicit in which Add* is called). Byte-identical wire (golden+fuzz+all round-trips
green). NOTE: not a measured alloc win — escape analysis already stack-allocated
the &ListBuilder{} at all 9 call sites (composite stays 583ns/5allocs, the 5 being
mandatory writeEnvelopePrefix pool-egress copies). Value is code-cleanliness +
consistency.

Also fixes zap/v1 subpackage: v1.2.4's ObjectBuilder value change left v1/*.go
referencing *zap.ObjectBuilder → the subpackage didn't build (latent; only the
root package is imported downstream so it went unnoticed). Converted to the value
type. Full module (root + v1) builds + tests green.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-14 14:06:56 -07:00
zeekayandHanzo Dev f9909a847a builder: eager-reserve + value ObjectBuilder — zero-defer, zero OB alloc
Decomplect that unlocks a perf win. SetBytes deferred its data into an offsets
[]offsetEntry slice replayed in Finish — machinery that recorded intentions to
replay later, and heap-allocated a slice per object-with-a-bytes-field. Replace
it with directness: StartObject RESERVES the fixed section eagerly, so SetBytes
appends its tail + patches its own pointer on the spot; Finish just returns the
offset. Removing the offsets field makes ObjectBuilder's methods mutate only
ob.b (through the pointer) and never ob itself — so ObjectBuilder becomes a
VALUE type and StartObject stops heap-allocating &ObjectBuilder per call (it was
65% of composite-build allocs).

Byte-identical wire (golden + fuzz + pool byte-equality + nested-proof suites all
green). Real X-tx wire composite: 922ns/11allocs -> 655ns/5allocs (1.4x, <half
the allocs); vs the original byte-blob 2551ns/37allocs that's 3.9x / 7.4x fewer
allocs. Speeds EVERY zap object build node-wide, not just X.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-14 09:34:28 -07:00
zeekayandHanzo Dev b4ad489eff builder: zero-copy SetBytes + exported Builder pool (write-path hot fix)
SetBytes was heap-copying every payload (append([]byte(nil), v...)) at every
nesting level — the dominant cost of deep wire composition (X-chain tx build
runs ~11 nested builders). It now retains the caller's slice; the caller keeps
it valid until Finish (every in-tree constructor builds+finishes in one frame).
Byte output is unchanged: Finish writes payloads in the same SetBytes order.

GetBuilder/PutBuilder: exported sync.Pool for Builders (write-side counterpart
to the read bufpool). Reuse is unconditionally byte-safe — ensureField zero-
fills every extended span and align zero-fills padding; proven by
TestBuilderPool_ByteIdentical (dirty pooled builder emits bytes identical to a
fresh one). go.sum: re-record luxfi/pq v1.0.3 (upstream re-tag drifted content).

Micro: sample object build 354ns/9allocs -> 257ns/6allocs; the real win
compounds in utxo/wire + xvm envelope composition (next commits).

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-13 03:39:31 -07:00
zeekay 1939302660 v1/codegen: emit REPEATED nested objects (repeated message, zero-copy)
The repeated-message wire shape: a list whose elements carry their own
variable-length tails (string/bytes/nested), which the fixed-stride inline
List cannot hold. Completes proto field-shape coverage in the runtime —
map<k,v> reduces to a repeated {key,value} entry, so this is its keystone too.

Composition, not a new wire concept: ListNested = List ∘ NestedAt. The list
slots are a contiguous stride-4 object-pointer array; each pointer is
followed exactly as a singular nested pointer to an out-of-line tailed View.

Runtime:
- builder.go: ListBuilder.AddObjectPtr(targetPos) — appends a signed 4-byte
  relative object pointer (the repeated-message element kind).
- v1/list_nested.go: ListNested[N] (Len/At/All/IsZero), ListNestedAt[S,N]
  (read), WriteListNested[S,N] + NestedElemSetter[N] (write). Same audited
  bounds discipline as Object.Object / ListStride (RED-HIGH-1/2 inherited).

Codegen:
- elemIsTailed: a list element with a string/bytes/nested/list sub-field
  auto-routes to ListNested/WriteListNested/ListNestedAt; scalar-only
  elements stay in the tighter inline List/WriteList/ListAt. One Elem
  declaration, the generator picks the correct encoding.

Proven end-to-end: runtime roundtrip (3 elements each with its OWN string
tail, via At and All, + empty), emit routing test (tailed->ListNested,
scalar-only->List), and a generated-code wire roundtrip (testpkg/repeatwire).
Root zap + full v1+codegen suite green; scalar listwire unchanged (no regression).
2026-06-23 16:38:05 -07:00
zeekay e457893743 rename v2 -> v1: the typed-view API + codegen is the canonical 1.0 (no v2, ever)
There is one perfected typed ZAP layer and it lives at github.com/luxfi/zap/v1 —
forwards-only, no backwards-compat baggage, never a breaking major. Mechanical,
behavior-preserving: v2/ -> v1/ (git mv), package zapv2 -> zapv1, import path
.../zap/v2 -> .../zap/v1 (incl. the codegen's emitted banner + import so
generated files reference /v1). Codegen golden tests pass; typed layer vets
clean. (Pre-existing CGO 'resolv' link failures in the root package are
unrelated env noise.)
2026-06-23 15:05:15 -07:00
Hanzo AI f42cdb6618 feat(zap): v2 generic API, bufpool, transport allocator + UMA/RDMA cgo
Three orthogonal additions, one wire format.

v2 package — generic ad-hoc schema dispatch (~/work/lux/zap/v2):
- README + IMPOSSIBILITY + BENCH_RESULTS document the v1↔v2 split.
- builder/field/iter/list/pool/registry/schema/view + codegen package
  emit v1-equivalent fast paths from declarative .zap sources.
- _compile_fail_test/ + examples/ cover negative and positive cases.
- v2_test.go exercises the generic dispatch path.
- doc.go in v1 marks v1 deprecated for *new* schema authoring; existing
  v1 buffers stay parseable by both v1 and v2.

bufpool — pooled read slabs (bufpool.go + bufpool_test.go):
- Message gains optional *bufRef; Release() returns the slab to its
  pool when sourced from the pooled read path, GC-managed otherwise.
- ParseHeader returns (data, rootOffset) without allocating *Message,
  used by zapv2 to avoid two allocations per parse.
- bench_read_test.go + node_quic_stream_test.go cover both paths.

Transport allocator + UMA/RDMA cgo (transport/*):
- Transport.Caps()/Buffer interface: capability + slab-typed buffer
  contract. Bytes() vs DevicePtr() decoupled so UMA and GPUDirect
  can share the same call surface.
- DPDK PMD + GPUDirect RDMA + CUDA UMA real cgo backends gated behind
  build tags; stub paths remain default on darwin / non-Linux.
- transport_test.go covers Caps reporting + Buffer lifecycle on the
  default transport.

LLM.md + go.mod follow the additions.
2026-06-04 17:06:59 -07:00
Hanzo AI 9d86b95754 fix(zap): close LP-023 v3.1 Red round 2 wire gaps (HIGH-1, HIGH-2, MEDIUM-1)
RED-HIGH-1: Object.List length is now clamped against len(data) at parse.
Attacker-set length=0xFFFFFFFF used to flow through to consumers, where
`for i := 0; i < l.Len()` would iterate 4G times.

RED-HIGH-2: Object.Object, Object.List, and Object.Bytes now reject any
absOffset < HeaderSize. A negative relOffset can no longer alias the wire
header (Magic/Version/Flags/RootOffset/Size). The signed-cast remains so
honest builders can finalize nested items before their parent.

RED-MEDIUM-1: bump wire Version from 1 to 2 (Version1 still accepted at
Parse for backward compat). NewBuilder emits Version2 by default;
NewBuilderV1 is kept for explicit-legacy paths. Message.Version() exposes
the parsed version so v3 platformvm Wrap*Tx accessors can gate on
Version2 to reject v1-vs-v2 schema confusion (e.g. NetworkID=11 byte 0
collision with TxKindBaseFull).

RED-V18: Parse now rejects size < HeaderSize. A buffer with size=0
previously slipped through and panicked on subsequent Root()/Flags().

Regression tests pinned in-tree at zap_test.go:
  TestRedRound2_HIGH1_UncappedListLength
  TestRedRound2_HIGH2_BackwardListPointer
  TestRedRound2_HIGH2_BackwardObjectPointer
  TestRedRound2_HIGH2_BackwardBytesPointer
  TestRedRound2_MEDIUM1_VersionParse
  TestRedRound2_MEDIUM1_NewBuilderEmitsV2
  TestRedRound2_V18_SizeZeroRejected
  TestRedRound2_F1_NegativeBitPatternSweep

Originals at /tmp/red_zap_attacks/*_test.go.
2026-06-02 15:11:11 -07:00
Hanzo AI 7148d32d20 fix: gofmt -s across repo (CI format check) 2026-06-02 11:38:38 -07:00
Zach Kelling 37424a4ba9 Fix SetText/SetBytes: write deferred data and patch relative offsets
ObjectBuilder.SetText/SetBytes stored deferred entries but Finish()
never wrote the actual text/bytes data or patched the relative offsets.
Now Finish() writes deferred data after the fixed section and patches
each field's relative offset correctly.

Adds 3 round-trip tests: single text, multiple text, nested objects
with text fields.
2026-02-15 17:18:20 -08:00
Zach Kelling 22a2a4c72d ZAP: Zero-Allocation Protocol for high-performance AI agent communication
- Zero-copy binary serialization (2.9ns parse, 0 allocations)
- 17x faster than MCP JSON-RPC, 11x less memory, 29x fewer allocations
- mDNS peer discovery with automatic mesh networking
- Request/response correlation for async RPC calls
- MCP bridge for auto-discovering and accelerating MCP servers
- 20 example tools (file, search, code, git, API)
- Consensus reaching agreement in ~450µs
- Environmental: 96% energy reduction at scale (~91 tonnes CO2/year saved)

Benchmarks (Apple M1 Max):
  BenchmarkZAPParse:     2.9 ns/op, 0 B/op, 0 allocs/op
  BenchmarkZAPToolCall:  322 ns/op, 256 B/op, 2 allocs/op
  BenchmarkMCPToolCall:  5579 ns/op, 2826 B/op, 58 allocs/op
2026-01-26 12:09:33 -08:00