Skip to content

Add native Cactus and Needle runtime - #116

Merged
gabewillen merged 166 commits into
mainfrom
feat/cact-needle-runtime
Sep 5, 2026
Merged

gabewillen merged 166 commits into
mainfrom
feat/cact-needle-runtime

Conversation

@gabewillen

@gabewillen gabewillen commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • add native zero-copy Cactus container loading, Needle model binding/tokenizer loading, and public machine aliases
  • add exact CQ2/CQ3/CQ4 kernels plus native Needle graph execution, explicit W4/f32 and W4A8 routes, and scheduler-owned parallel projection waves
  • add JAX logits/tokenizer/heldout parity fixtures, Needle decode/prefill benchmarks, and hardened public validation for spans, aliases, arithmetic, callbacks, ISA selection, graph lifetime, and concurrent dispatch
  • enforce a repository-wide hard memory envelope for maintained build, gate, benchmark, profile, setup, lint, and check entrypoints

Verification

  • focused CQ + Needle graph proof: 79 cases / 372,648 assertions passed
  • CQ regressions: 42 cases / 314,551 assertions passed
  • graph construction factory regressions: 4 cases / 36 assertions passed
  • tokenizer routing regressions: SPM 8 cases / 43 assertions; raw-fragment choice 1 case / 8 assertions
  • heldout native runtime: 287 rows, tokenizer mismatch rows 0, domain 0.8397 (0.840 at comparison precision), effort 0.7631
  • focused decode, Needle, matmul, and speech tests passed
  • final blind rules/security/completeness/engineering/HSM review at published head 5cd1570c is Proven-for with empty findings
  • Needle request validation and lifecycle proof: 8 cases / 1,569 assertions passed before the final output-lifetime regression; final illegal-dispatch/output invalidation proof passed 1 case / 2,906 assertions
  • authenticated benchmark contract proof: 2 cases / 29 assertions passed, covering exact request metadata, marker/metric ownership, and diagnostic emission

Scheduler cutover

  • the custom fork_join_lane_pool path is removed and the scheduler cutover to upstream SML is complete at a6f1ec0923114dbb007b27896047097a23378562
  • upstream stateforward.SML is pinned exactly to 67f898e6e19d516bb445841263fd35db3f3cd3c3
  • focused upstream scheduler and co_sm thread-pool tests passed
  • emel scheduler filters passed 14 cases / 49 assertions and 5 cases / 23 assertions; affected parallel matmul passed 15 cases / 352 assertions
  • /tmp/probe7 passed 10/10 consecutive contention runs
  • the scheduler proof covers the three upstream races and decode action routing repairs; no compatibility shim or custom pool remains

Runtime diagnostics: native EMEL and Cactus

Maintained live diagnostics on the same host and model artifact:

Runtime Wall Prefill Decode
native EMEL 1.379 s 279.472 tok/s 217.784 tok/s
Cactus engine 1.547 s 185.325 tok/s 138.550 tok/s

These diagnostics are comparable=false: the runtime workloads and measurement contracts are not equivalent. Native EMEL is observed to beat the Cactus engine in these maintained runs, but this PR makes no ratio, latency-equivalence, or kernel-equivalence claim. The earlier 435 tok/s figure is retained only as theoretical roofline/stretch context, not a required acceptance gate.

Authenticated request contract

  • full normalized envelopes are transported without truncation and compared structurally
  • Cactus worker execution authenticates the installed package tree and native library, disables telemetry, and publishes output through private secure staging
  • benchmark parsing enforces thread_count, thread_contract, prompt_rows, max_new_tokens, lane-specific sampling/stop identifiers, and strict marker/metric field ownership
  • wall, prefill, and decode metrics are aggregated independently; token/envelope instability and fixture token drift fail closed before publication
  • illegal Needle request lifecycle events return internal_error, suppress stale success callbacks, and invalidate all prior public outputs as required by the event lifetime contract
  • authenticated diagnosis showed identical rendered input token sequences, including BOS totals 412/335/384/216; Cactus then applies closed constrained enum-selection and validation semantics unavailable through its public API, so output and timing equivalence remain unclaimed

Memory safety contract

  • Linux maintained entrypoints execute in an authenticated systemd user cgroup-v2 scope.
  • MemoryMax is at most 50% of effective memory, where effective memory is physical RAM limited by the minimum finite memory.max across ancestor cgroups.
  • MemorySwapMax=0.
  • Scope identity is verified by exact equality between systemd ControlGroup and unified cgroup membership.
  • Missing systemd/cgroup-v2 enforcement fails closed; there is no uncapped override.
  • macOS intentionally fails closed because it has no supported native aggregate descendant memory controller; sampled RSS watchdogs and Linux-artifact containers are not represented as equivalent enforcement.
  • focused memory contracts passed 9 cases / 75 assertions; a live harmless scope observed memory.max=53687091200, memory.swap.max=0, and exact ControlGroup membership.

Gate note

Aggregate gates were attempted but cannot run in the current environment because zig is absent (error: zig not found); no green aggregate-gate claim is made. Earlier aggregate attempts built successfully and completed the heldout lane, but stopped or failed in unrelated lint/prerequisite lanes; repeated OOM/container crashes prohibit another aggregate rerun. The focused behavioral proofs, documentation generation check, shell syntax checks, live memory-envelope proof, scheduler proof, and blind reviews are recorded above.

Merge

PR #116 remains open; merge is authority-gated and no merge is claimed.


Note

Medium Risk
Large native inference surface (loaders, kernels, graph execution) plus build-gate and callback contract changes affect every maintainer workflow; memory-envelope fail-closed behavior can block local runs on unsupported hosts.

Overview
Publishes the native Cactus/Needle runtime lane for review on PR #116: terminal planning/handoff state, verification summaries, and new architecture docs (plus Mermaid) for the .cact loader, Needle model/graph/tokenizer, and CQ/engram/rope/SWA kernel state machines.

Build and test wiring adds EMEL_ENABLE_NEEDLE_EVAL, the maintained heldout evaluator under tools/needle_eval, Needle request SML in the emel library, and doctest coverage for Cactus loading, Needle binding/graph parity, Needle tokenizer loading, and the new kernel suites. CTest shards split the old generator_and_runtime bucket into text_generator, embeddings, and logits_and_token; model_and_batch now includes tests/cact/*. Stateforward.SML is pinned to 67f898e6e19d516bb445841263fd35db3f3cd3c3 (upstream thread-pool scheduler fixes). CMakePresets drops bundled build/test presets.

Operator policy updates AGENTS.md, README.md, and benchmarking/determinism docs: maintained scripts must run through scripts/build_jobs.sh with a verified Linux systemd cgroup-v2 memory cap (50% effective RAM, swap off) and fail closed on macOS; parallel matmul documentation refers to thread_pool_scheduler instead of the removed custom fork/join lane pool. Needle vs Cactus benchmark rows are documented as diagnostic-only (comparable=false).

Public API tightening: emel::callback thunks and from() factories now require noexcept callables, matching stricter runtime validation on hot paths.

Reviewed by Cursor Bugbot for commit 6d64446. Subsequent review findings were repaired through current head 5cd1570c and independently re-reviewed with empty HSM and metadata-contract findings. Bugbot is set up for automated code reviews on this repo. Configure here.

EMEL Worker added 30 commits August 30, 2026 03:21
…pinned fixture

- rename loader SM symbols to state_/guard_/effect_ prefixes per AGENTS.md
- wire tests/cact/ into model_and_batch ctest shard
- add tests/cact/loader_tests.cpp: lifecycle, malformed-image rejection
  (bad tag, truncated directory, out-of-bounds and unaligned offsets),
  bind/parse ordering, and 405-record directory parity vs the committed
  CSV fixture generated from route-w4-qat.cact
- pin tests/models/route-w4-qat.cact fixture
…ader

- src/emel/model/needle: SML binder mapping the cact loader's positional
  tensor table onto a named contract (embedding, per-layer runs, mHC stack,
  engram sites, final_norm, probe heads, tokenizer blob) validated against
  header geometry; every validation outcome is a guard-dispatched _error.
- src/emel/text/tokenizer/needle: SML loader parsing the trailing RAW
  SentencePiece-BPE dump into the shared text/tokenizer vocab (SPM
  preprocessor/encoder consume it unchanged).
- tests: doctest units with SML introspection, pinned-fixture happy paths,
  rejection paths, and tokenizer piece parity vs a committed CSV fixture
  generated by scripts/gen_cact_tokenizer_csv.py.
…xture

Inverts export.py _tensors() emission back into the reference params tree from
the pinned route-w4-qat.cact (exact QAT operands, not the fp32 checkpoint) and
runs the maintained decode._forward_cached prefill + 2 greedy decode steps per
case. Full 8192-float logits per step, manifest with prompt ids and greedy
tokens. Phase-4 C++ parity tests consume these files.
SML graph actor under model/needle/graph consuming the phase-2 contract and
the stage kernels: init decodes fp16 scales + precomputes RoPE + clears
state; each prefill/decode token is one allocation-free RTC step chain with
guard-routed CQ route (scalar/AVX2), engram-site vs plain layers, and
growing vs full sliding-window states. Parity vs the committed 3-case JAX
fixture: greedy tokens match all cases; worst rel err 9.28e-4 (<= 1e-3).
…chmark markers

The f32 vector mul_mat guard honored a forced-true runtime NEON flag on
builds with no NEON codegen (x86 hosts), tripping the route-exclusivity
test in the kernel_and_graph coverage lane. Gate it behind the same
compile-time support predicate pattern as the f16/conv/q8 routes. Also
switch the new kernel sm.hpp benchmark markers to the recognized
'scaffold' tier (bench.sh only accepts scaffold|designed|ready).
New needle_graph bench_runner suite driving the native graph strictly
through public events (init/prefill/decode) on the pinned
tests/models/route-w4-qat.cact via the maintained loader chain.
Decode measures steady-state single-core steps after a ~100-token
context prefill; prefill measures a 512-token prompt. Explicit
tokens_per_second in both snapshot and compare output.

The closed-source libneedle 2.0.3 engine cannot be linked; its lane is
recorded documented constants (145 decode / 180 prefill tok/s,
user-supplied single-core measurement on this host class). All rows
carry proof_status=measurement_only markers so the snapshot/compare
gates skip them until baselines are approved (no snapshot consent yet).

Dependency manifest gains the needle_graph records; baseline refreshed
via --write-dependency-manifest (check reports fresh).
emel_needle_eval drives the maintained chain end to end (cact loader ->
needle binder -> tokenizer blob -> shared SPM tokenizer -> native graph
public events) and reproduces the JAX reference eval protocol
(greedy, 80 new tokens, EOS stop, <tool_call> arguments parse) on
/shared/effortless/train/heldout.jsonl for comparison vs the
0.840 domain / 0.760 effort reference.

scripts/gen_needle_heldout_eval.py renders prompts exactly like
finetune.render_example and encodes them with the byte-level
export.py RefTokenizer from the pinned .cact blob; the C++ tool
prefills those reference ids and reports per-row emel-tokenizer id
parity separately (currently mismatching on chat-marker prompts —
reported, not hidden).

Probe heads (contrastive/confidence manifest codes) are not part of the
reference accuracy path: the confidence head is uncalibrated for tuned
weights and the contrastive head embeds tool schemas; domain/effort
accuracy is a generation metric per eval_jax.py.
@gabewillen

Copy link
Copy Markdown
Contributor Author

Scheduler cutover is now complete and published at HEAD a6f1ec0923114dbb007b27896047097a23378562 on feat/cact-needle-runtime. The custom fork_join_lane_pool path is removed; upstream stateforward.SML is pinned exactly to 67f898e6e19d516bb445841263fd35db3f3cd3c3. Focused upstream scheduler/co_sm thread-pool tests, emel scheduler filters (14/49 and 5/23), affected parallel matmul (15/352), and /tmp/probe7 contention (10/10) passed, covering the three upstream races and decode action routing repairs. PR remains open and merge is authority-gated. Aggregate gates are not claimed green: they cannot run here because zig is absent (error: zig not found), with prior OOM/container-crash reruns intentionally omitted. Runtime comparisons remain comparable=false; no ratio/equivalence claim.

Comment thread src/emel/model/needle/graph/context.hpp
@gabewillen

Copy link
Copy Markdown
Contributor Author

Final authenticated Needle/Cactus diagnostic work is published at 6d644465.

Current live diagnostic smoke on the same model and four canonical requests:

  • EMEL wall: 1.418 s/request; Cactus wall: 1.524 s/request
  • EMEL prefill/decode: 259.895 / 207.711 tok/s
  • Cactus prefill/decode: 188.575 / 142.475 tok/s
  • normalized envelopes: mismatch
  • wall and phase metrics: comparable=false; no ratio or equivalence claim

The mismatch is now characterized rather than hidden. Authenticated NEEDLE_DEBUG showed identical rendered input token sequences (including BOS totals 412/335/384/216) and the same first greedy argmax for the investigated row. Cactus then applies a closed constrained enum-selection and validation/negation stage that its public API does not expose; its sampling and stop semantics are also unverified. EMEL remains the source-owned greedy-argmax/EOS-or-max80 route. Exact cross-runtime output or timing comparability is therefore not claimed.

The diagnostic path now:

  • preserves and validates all four full normalized envelopes;
  • authenticates the installed Needle package tree and native library;
  • forces Cactus telemetry off in the sanitized worker;
  • uses private staged output with secure atomic publication;
  • aggregates wall/prefill/decode independently and rejects token/envelope instability;
  • verifies live benchmark prompt token IDs against the pinned fixture before timing;
  • strictly validates the public Needle request tool schema and generated route-call JSON without dispatch-time allocation.

Focused proof at the published head:

  • request actor: 7/7 cases, 1504/1504 assertions;
  • benchmark regressions: 2/2 cases, 13/13 assertions;
  • security regressions for aggregation, staged output, telemetry isolation, and symlink handling: 4/4 cases, 16/16 assertions;
  • authenticated live compare exited successfully and emitted only noncomparable diagnostics;
  • final blind HSM, rules/security, and completeness lanes returned empty findings.

snapshots/quality_gates/timing.txt remains unrelated modified local state and was not committed. PR remains open; no merge claim.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6d64446. Configure here.

Comment thread src/emel/model/needle/request/actions.hpp
Comment thread tools/bench/model/needle/cactus_reference.py
EMEL Worker added 4 commits September 4, 2026 17:24
Reject EMEL request rows whose thread contract, prompt count, or token limit diverges from the canonical workload while preserving lane-specific sampling and stop metadata.
Keep marker metadata authoritative by accepting only the canonical metric key set and rejecting cross-row key collisions before records are merged. Add boundary regressions for masked thread contracts, general metadata collisions, unexpected metric metadata, and duplicate metric tokens.
@gabewillen
gabewillen merged commit 90a91b1 into main Sep 5, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants