How to use
- Copy the installation command and review the source package before installing it in your own agent environment.
- Check the source document for required tools, credentials and supported hosts.
- Describe your input and desired deliverable; review the output against the source material.
npx skills add https://github.com/tenstorrent/tt-emule --skill workaroundsBefore you start
- Installation does not include a model subscription, API allowance or permission to access your files.
- Repository stars and installation counts describe activity, not an independent quality or security test.
Rendered from the source repository. Headings, examples, code, tables, links, and referenced images are preserved.
Workarounds registry
This file is the single, explicit list of deliberate workarounds in tt-emule.
A workaround here is a change we knowingly accepted that is not the correct fix — it papers over a problem to make a test pass while the real fix lives elsewhere (usually an upstream kernel, a tt-metal runtime bug, or a missing emule model we did not have time to build properly).
These entries are not a template for how to develop. They exist precisely so that a hack does not silently become precedent. The default tt-emule rules still hold (see .claude/CLAUDE.md): be faithful to silicon, keep a single code path, and surface caller bugs rather than mask them. Every entry below violates one of those on purpose, is documented as such, and has a tracked path to removal.
Rules for this registry
- Adding a workaround is a last resort. First try the faithful fix (model the
real behavior; fix the actual bug upstream). Only fall back to a workaround when that is blocked, and say so explicitly in review.
- Every workaround must be registered here with: what it is, why it is a hack
(how it can fail / what rule it bends), the real root cause (file + line), the proper fix, and a tracking link (issue/PR).
- Link from the code to this file. The workaround's code site must carry a
comment pointing here (e.g. // WORKAROUND: see .claude/skills/workarounds), so anyone editing it knows it is a known hack, not load-bearing design.
- Workarounds are removed, not grown. When the real fix lands, delete the
workaround and its entry. Do not extend one hack to cover a new case — add the faithful fix instead.
WA-1 — fabric mux kernel replaced with a no-op (n300/p300 CCL)
Code site: tt-metal …/impl/emulation/emulated_program_runner.cpp, jit_compile_kernel preprocess step — when the kernel source basename is tt_fabric_mux.cpp, emule writes a no-op kernel_main instead of compiling the real source (search "emule no-op stub for ttfabricmux.cpp").
What it does: the fabric MUX kernel (a persistent worker-side kernel that aggregates worker packets onto ethernet links and forwards them) is not compiled or run. The CCL workers' WorkerToFabricMuxSender teleports each packet straight to its final destination instead (the same direct path the no-mux num_workers_per_link=1 configuration uses).
Why it is a workaround (bends a rule):
- It special-cases a specific kernel by filename and substitutes a no-op,
rather than modeling the kernel or providing a general "transport kernel" hook.
- It is functionally faithful (the data + semaphore effects are identical — the
teleport delivers to the same destination the mux would have forwarded to), but it does not model the mux's flow-control / buffer back-pressure. emule is a functional (not cycle-accurate) emulator, so this is acceptable for correctness, but it is a divergence from the silicon code path.
Real root cause (emule scope, not a bug): the mux is part of the fabric transport layer (worker → mux → ethernet → router → dest), which emule deliberately collapses into the synchronous teleport (see docs/fabric-ccl-emulation.md). The real mux additionally pulls in erisc firmware headers emule does not model and is a persistent loop that would never terminate under emule's run-to-completion join.
Proper fix (removes this workaround): if mux fidelity is ever required (e.g. modeling link contention), model the mux faithfully — workers write packets into the mux core's L1 channels and a mux execution context drains + teleports them — behind a general transport-kernel mechanism rather than a filename special-case. Until then the no-op stub is the correct functional model.
Tracking: #227 (WA-1 faithful-transport removal path) and #231 (reduce the fabric shim surface: real packet header + faithful mux); also documented in docs/fabric-ccl-emulation.md.




