Warrior owns lowering — Triton/Neptune into trisha, silicon into its own folder
STATUS: S3 release repair in progress (2026-09-11). The audit found incomplete asset transfer and broken source CLI integration; warrior-release-repair.md supersedes the completion claim and release sequence below. Historical decisions remain recorded here.
One sentence: trident-lang is the language and its compilation harness — front end, TIR, optimizer, neural optimizer, cost framework, audit, LSP, nox lowering — and every other machine is a warrior that owns the last mile: TIR → its ISA, its verifier and cost model, run, prove, verify, deploy. The first and only such warrior is trisha, which absorbs everything that knows Triton or Neptune. The 28 native-silicon emitters leave the crate into one unpublished folder; no 28 warriors.
Audited facts (2026-09-09/10, agents + direct reads)
| fact | state |
|---|---|
| pipeline in CLAUDE.md | claims AST → TypeCheck → KIR → TIR → LIR → Target. Code: KIR = 30 lines of doc + create_kernel_lowering() → None; LIR = tir_to_lir is todo!(); nothing produces or consumes either. Two real paths: stack ast::File → TIRBuilder → optimize → TASM, tree ast::File → NoxCompiler → Noun |
| TIR | ir/tir: builder 3 318, optimize 712, stack model 522, encode (TIR → block tensors) 416, linker 248, neural hooks 305, lower 859 of which lower/triton.rs is 328 — the only file that knows TASM. create_stack_lowering(_) ignores its argument and always returns Triton |
| neural | compile(tir_ops: &[TIROp], baseline_tasm) → CompileResult. model 2 101 (GNN over the TIR graph), data/tir_graph 667 (zero Triton mentions), inference 547, training 1 567 (94 Triton hits: reward = cycles, oracle = cost/stack_verifier 1 170 LOC = a TASM block executor), output vocabulary = TASM tokens |
| nox path | NoxCompiler::compile_file(&ast::File) bypasses TIR; uses no typecheck output; TreeLowering impl is a stub nothing calls |
| dispatch | src/api/mod.rs::compile_with_options: if arch == Tree else stack; Arch::Register silently falls to Triton; duplicated in compile_project_with_options |
| Triton threaded elsewhere | 30 files: cli/bench.rs 61 hits, cli/train.rs, api/tests/{neptune,compile,prove,features}.rs, package/cache.rs, config/target/*, cli/audit.rs, cost/scorer.rs, deploy/*, typecheck/builtins.rs (xfield, Digest[5]), lsp/builtins.rs, cli/trisha.rs |
| assets | baselines/triton 10 755 lines .tasm, os/neptune 2 098 lines .tri, cost/model/triton.rs |
| silicon emitters | src/compile/ 14 379 LOC, 27 files, born 2026-03-29 in four commits; original home per nox-native-compile.md was nox/rs/compile/. Input = nox Reduction only, zero crate:: refs — a leaf. Phase-1 patterns only (0,1,4,5–14); hash/divine/cons/look → UnsupportedPattern. Emit text/bytes, no execution, no trace. Tests in 4 of 27 files. Only caller: trident compile (cli/compile.rs). mir2nox (720) is the inverse direction — rustc MIR JSON → nox — and duplicates the orphaned src/import/ (1 067, not in the module tree) |
| dead weight | src/gpu 325 LOC (no callers; sole reason for pollster), src/ir/kir, src/ir/lir; deps bytemuck petgraph statrs unused, blake3 benches-only; burn/wgpu imported directly by cli/{bench,build,train}.rs |
| trisha | ~/cyber/trisha: cli/ rs/ wgpu/ (accelerator 1 728) honeycrisp/ patches/; vendors triton-vm (68k); run/prove/verify/deploy over ProgramBundle; trisha#1 open: build broken (vendored twenty-first serde) |
Decision (proposed)
- One warrior = one binary = the last mile of its machine. trisha
gains
buildandcost: takes TIR, emits TASM, links, bills cycles; then run/prove/verify/deploy as today.trident build --target tritondelegates totrisha buildthe waytrident provealready delegates; the warrior is found by name fromvm/triton/target.toml. - The core keeps the harness. Criterion: a thing stays in the core if
it produces the core's representation or every warrior consumes it.
Front end, typecheck, TIR builder + optimizer + stack model + encode,
nox lowering (
ir/tree— nox is the semantics; the differential harness checks every other target against it), cost framework (cost/scorer,cost/model/mod), audit, LSP, package, MIR import. - The contract is TIR. Warrior-facing API of trident-lang:
trident::front::compile_to_tir(source, TerrainConfig) → Vec<TIROp>(+TerrainConfig,ModuleExports), documented inreference/warrior-api.md; semver, no serialization — trisha links trident-lang as it does today. A flat op list is a smaller surface than the recursive AST.create_stack_loweringand theStackLoweringtrait go: the core stops at TIR for stack targets. - neural is the harness; the target is a trait. Model, TIR graph,
inference, training loop stay in the core behind
neural::Target { vocabulary, verify_block, cost }. Triton implements it in trisha: TASM token vocabulary,stack_verifier(the TASM block executor), cycle cost. Core training/inference never names an ISA.burn/wgpustay core deps, gated behind a default-onneuralfeature socargo install trident-lang --no-default-featuresis light. - MIR import is core infrastructure.
mir2nox+ the orphanedsrc/import/merge into onesrc/import/whose output is trident's representation (AST → TIR; until then, nox as the semantics), so trisha gets Rust programs the same way it gets.triones. - Silicon leaves the crate into one folder.
src/compile/(minus mir2nox) +cli/compile.rs→trident/silicon/, a workspace cratetrident-silicon,publish = false, depends oncyber-noxonly, its ownsiliconbinary carrying today'scompileCLI. Not 28 warriors: the emitters have no execution and no trace, so they are sketches, and the folder says so. Later home may benox/— agit mvthen. - Target registry stays configuration in trident.
vm/*/target.tomlandos/*/target.tomlkeep declaring engines, unions and their warrior; a target whose warrior is absent is refused with the install hint.
What moves
| from (trident) | to | LOC |
|---|---|---|
src/ir/tir/lower/triton.rs, linker.rs, Triton arms of lower/mod.rs |
trisha/rs/lower/ — trisha build |
~700 |
src/cost/model/triton.rs, src/cost/stack_verifier/** |
trisha/rs/cost/, neural::Target impl |
~1 300 |
TASM vocabulary + cycle reward out of src/neural/{training,inference,data} |
trisha/rs/neural_target.rs |
~300 (est.) |
baselines/triton/**, benches/references TASM comparisons, cli/bench.rs Triton arms |
trisha/baselines/, trisha bench |
10 755 + ~600 |
os/neptune/** (.tri), src/api/tests/neptune.rs, Neptune parts of deploy/** |
trisha/os/neptune/, trisha tests |
2 098 + ~600 |
src/cli/trisha.rs, Triton arms of cli/{audit,build,mod}.rs |
trisha cli | ~500 |
src/compile/** (minus mir2nox), src/cli/compile.rs, Command::Compile |
trident/silicon/ |
13 659 + 240 |
src/compile/mir2nox.rs + src/import/** |
one src/import/ in the core (trident mir stays) |
720 + 1 067 |
src/ir/kir, src/ir/lir, src/gpu |
deleted (history keeps them) | ~1 200 |
bytemuck petgraph statrs pollster (blake3 → dev) |
out of [dependencies] |
— |
Rust actually leaving trident-lang for trisha: ~3.5k LOC plus the
.tasm/.tri assets. Stays, made generic: typecheck/builtins.rs and
lsp/builtins.rs read digest/xfield widths from TerrainConfig instead
of naming Triton; cost/scorer.rs scores in the target's unit. Miden
keeps sharing TIR in the core; its lowering is a future warrior's.
Arch::Register loses its dead LIR scaffold; the variant stays for the
registry.
Core deps after: clap ariadne tower-lsp tokio serde serde_json nox nebu hemera + burn wgpu rayon rkyv under neural.
Sequence
| step | scope | sessions | gate |
|---|---|---|---|
| S0 attic — DONE (PR TBD, 2026-09-10) | silicon/ workspace crate (25 emitters, own silicon binary); mir2nox merged into src/import/ (the orphaned mir.rs/structurize.rs/types.rs deleted — needed mir-format, a publish = false crate that can never be a trident-lang manifest dependency); deleted ir/kir, ir/lir (both dead), src/gpu (325 LOC, zero callers); dropped bytemuck/petgraph/statrs/pollster, blake3 → dev-deps; README + landing rewritten (25, not 28 — x64-sysv/ptx-parallel/ane-batch are CLI variants, not separate backends); trident compile removed from main binary |
1 (spent ~1) | 955+34+9+13+3+17 tests green, zero warnings, differential/nox_surface unchanged. Neural feature-gate deferred to S2 (bundling it with the neural::Target extraction avoids gating twice). Found, not fixed: silicon/old trident compile hangs on every invocation, reproduced identically on unmodified master — trident#32, pre-existing, out of scope here |
| S1 trisha builds — DONE (trident#34, trisha#2 #3, trisha#1 closed, 2026-09-10) | Root cause of trisha#1 was one manifest line: vendored twenty-first ships crate-type = ["cdylib", "rlib"], so rustc saw two versions of serde and rand (BFieldElement: Serialize is not satisfied, StandardUniform: Distribution unsatisfied, can't find crate for triton_isa). patches/apply.nu [T0] now rewrites it to a plain rlib, surviving re-vendoring. Three separate breakages also fixed: API drift (poseidon2→hemera, reads_state), triton missing from default (why the installed binary had no warrior CLI), and a cfg on a non-existent trisha-rs feature. Dead code removed. trident gained a default-on neural feature — build weight, not the fix |
½–1 (spent ~1½) | Full re-vendor → dev + release build the workspace, tests green, zero warnings outside .vendor/; release-installed warrior end to end on trident-built TASM: run 12 cycles → prove STARK 33 ms (padded height 256, 710 KB) → verify PASS. Triton side of the differential harness unblocked |
| S2 contract — DONE (trident#37, 2026-09-10) | reference/warrior-api.md: what a warrior may link (compile_to_bundle, build_tir/build_tir_project, runtime types+traits, TerrainConfig, hashing, proof sizing), the feature contract (default-features = false) and the stability promise (TIR is an in-process Rust contract, not a wire format; ProgramBundle JSON is the only crossing form and its round trip is lossy in a documented way). tests/warrior_api.rs makes it executable in both feature configurations. The contract functions already existed — they were undocumented, not missing. neural::Target deliberately deferred to S3: a trait with one implementation is what quality.md pass 10 forbids; it earns its place when vocab.rs (449) + grammar (721) + stack_verifier (1170) actually move |
1 (spent ~½) | Writing the test found a real hole: Diagnostic, the error type every documented entry point returns, was unreachable as trident::Diagnostic (privately imported in lib.rs) — now re-exported. 1039 tests green, zero warnings both ways |
| S3 the move — DONE (trident#44, trisha#6, 2026-09-11) | Full audit found the plan's ~3.5k LOC estimate was 2.5x too low: moved 8,795 LOC of Rust logic (ir/tir/lower/*+linker, the whole AET cost subsystem — a CostModel trait with exactly one impl, same shape as StackLowering — and src/neural/ in full, since its vocabulary literally is TASM tokens) + 10,755 lines of hand baselines + ~110 tests. Deleted as dead code found along the way: ir/tir/encode.rs, package/cache.rs, trident doc/--annotate, LSP cost hints — all built on the moved analyzer with no honest nox equivalent. Fixed: deploy::generate_artifact now takes the generic BundleCost (was wrongly typed to the Triton-only ProgramCost); trident build --target triton now actually delegates to the warrior |
5–7 (spent ~2) | 654 trident tests green (955 before — moved, not lost), 295 trisha tests green (179 moved), zero warnings both repos with and without --no-default-features (the neural feature no longer exists to gate — nothing left in core needs it). trisha build byte-identical to trident's old in-process output and to delegation output. Real end-to-end: trisha run/prove/verify round-trip (16 for input 5, proof 33ms, PASS), trisha build --costs prints a real report. Fresh grep audit: touched-file LOC dropped from 26,882/87 files to 12,069/43 files — the remainder is legitimately generic (target registry, doc comments, one known small gap: LSP asm-block syntax highlighting only knows Triton's instruction set) |
| S4 core cleanup | typecheck/lsp target-generic; CLAUDE.md pipeline line + Key Modules corrected; roadmap; CHANGELOG; trident-lang 0.3.0, trisha 0.2.0 | 1 | zero warnings, trident audit, docs sweep |
Total 5–7 sessions. Kelvin: restructuring, no language change — stack
temperature unchanged; trident-lang 0.3.0 because the CLI loses compile
and --target triton now needs trisha installed.
Release sequencing (the split's hard constraint)
trisha cannot be published to crates.io today, and that gates the whole move. Cargo's own verdicts, 2026-09-10:
cargo publish --dry-run -p trisha-rs→ "all dependencies must have a version requirement specified when publishing" — thetrident-langpath deps carry noversion =.- A fresh
git cloneof trisha does not even load its manifest:.vendor/is gitignored, so[patch.crates-io]points at nothing. Afternu patches/apply.nuthe vendor exists and the remaining error is the same missingversion =ontrident-lang. [patch.crates-io]never travels with a published crate anyway: a crates.io trisha would resolve triton-vm unpatched — no GPU overlay, noMerkleTree::from_nodes, nopubvisibility, no rlib-only fix — and fail to compile.
Meanwhile trident run --target triton already prints
cargo install trisha (src/cli/run.rs:100) — a promise no user can
keep. Today that only costs them a confusing message, because the core
still emits TASM. The moment S3 removes the lowering, it costs them the
target.
Three release points, in order:
| # | release | gate |
|---|---|---|
| R1 | trident-lang 0.3.0, joy 0.3.1 | Can go as soon as trident#40 is closed (we emit dup 24 — assembly that cannot execute on a 16-register machine; shipping a compiler that does that is the thing this repo's doctrine forbids). Nothing about the split is user-visible yet: the core still lowers to TASM, trisha stays optional. Breaking, and only this: trident compile → the silicon binary. joy must bump its trident-lang = "0.2" requirement in the same pass or its build breaks on the version bump |
| R2 | trisha installable at all | Not a crates.io release — a distribution decision. Minimum: version = on every trident-lang dep (so it resolves from crates.io outside the dev tree), .vendor/ reachable in a clone (commit it, or a build step that runs patches/apply.nu), then verify cargo install --git https://github.com/cyberia-to/trisha on a machine that has never seen this workspace. Fix src/cli/run.rs's hint to whatever that command actually is. If crates.io is wanted instead, the patched triton crates have to be published under our own names — which is the fork the "patches over forks" doctrine avoids, and a decision the owner should make deliberately |
| R3 | trident-lang 0.4.0 + trisha 0.2.0, together | Only after R2. This is the release where the core stops emitting TASM: trident build --target triton delegates, ~110 TASM-asserting tests live in trisha, trident::compile's default target is decided. Triton users need trisha from this version on, so it must be installable before this ships, not after |
The rule the three points encode: the split may not reach a user before the warrior does.
Verification (per repo rules)
Every step: cargo check zero warnings · cargo test · trident bench
(through trisha after S3) no regressions · trident audit · differential
triton×nox on benches/references (unblocked by S1) · fresh
cargo install trident-lang cyber-joy in /tmp. Branches feat/*, PRs,
no direct master commits. Two agents never share a directory: trident
side by syntax/ ast/+typecheck/ ir/ cost/+verify/ cli/ package/ lsp/ neural/ docs/, trisha side its own repo.
Open for the owner
silicon/in trident (proposed) vs straight intonox/now.neuralas a default-on feature (proposed) vs unconditional.
Settled
- Warriors own the last mile; one binary per machine. (owner, 2026-09-09)
- Neptune + Triton go to trisha. (owner, 2026-09-09)
- Emitters out of the crate into one folder, no 28 warriors. (owner, 2026-09-09)
- Shared infrastructure stays in the core; criterion: produces the core representation or consumed by every warrior. MIR import is core. (owner, 2026-09-10)
- TIR is the core's IR and the warrior contract; only
lower/triton.rsand the linker move. (owner, 2026-09-10) - neural harness (model, TIR graph, training, inference) is core; the
target-specific verifier, vocabulary and cost move behind
neural::Target. (owner, 2026-09-10)