Audit Coverage Map — TinyMUX 2.14 hardening
Living document. Feature-complete 2.14 work is review-and-fix only.
This map tracks where we have looked, when, and what to revisit.
We expect to re-audit slices already marked “done” — that is intentional.
Workflow (standing):
explore/read → file High/Medium issues → fix PR → Claude cross-review
(+ Windows when the path is Win32-only) → merge.
Prefs: server-first; Linux/FreeBSD primary; Windows must not lag;
clients/Hydra after server depth is comfortable.
How to use this map
- Pick the next slice ID from the queue (or re-queue a prior slice).
- Update that row’s Last pass / Status when you finish filing issues.
- After a fix PR merges, note issue ranges in Notes (optional).
- When revisiting, change Status to
revisit and bump Last pass.
Status values:
| Status |
Meaning |
deep |
Focused High/Medium pass completed this cycle |
partial |
Touched; known residual or thin coverage |
thin |
Spot-check only or only via related work |
deferred |
Out of current phase by design |
revisit |
Scheduled re-audit of a previously deep slice |
backlog |
Known work, not defect-driven |
Slice catalog
Rough line counts are order-of-magnitude (.c/.cpp/.h); they change.
A — Driver / network (server process: netmux)
| ID |
Slice |
Paths |
~Size |
Last pass |
Status |
Notes |
| A1 |
Driver bootstrap / COM |
mux/src/driver.cpp, driver_bridge.cpp, modules.cpp, muxcli.cpp |
med |
Pass 15 2026-07-31 |
deep |
engine.so via mux_AddModule; #1798 required COM iface fail-closed (Log/Platform/GameEngine/Notify/ObjectInfo/PlayerSession) before main loop |
| A2 |
GANL adapter / DESC |
mux/src/ganl_adapter.cpp, interface.h |
large |
Pass 15 2026-07-31 |
deep |
#1074 grace; #1800 WS GET preface split; #1802 SMTP buffer+deadline; #1803 zero-listener fail-closed; #1801 Win32 initiateConnect / @email (#1805) |
| A3 |
Net / output / idle |
mux/src/net.cpp, sitemon.cpp, bsd.cpp |
large |
Pass 15 2026-07-31 |
deep |
#1133–#1135/#1139; #1141 getpeername; #1806 CREATE max_players; #1808 find_oldest second session; #1809 SESSION/SOCKET full-width formats |
| A4 |
Telnet NVT |
mux/src/telnet.cpp |
med |
Pass 15 2026-07-31 |
deep |
#1126/#1128/#1131/#1132 held; #1811–#1814 dup option acks, NEW-ENVIRON next-var, USER sanitize, charset UTF-8 reset (#1816) |
| A5 |
WebSocket (netmux) |
mux/src/websocket.cpp, websocket_test.* |
med |
Pass 15 2026-07-31 |
deep |
#1081 mask; #1083 output_limit; #1800 GET preface; #1807 login input_tot; WS overflow log uses full-width SOCKET (#1809 residual) |
| A6 |
Signals / restart helpers |
mux/src/signals.cpp, restart bits in adapter/net |
med |
Pass 14 2026-07-29 |
deep |
#1127 g_bCanRestart armed from adapter path; panic-restart + dump reaps held; no new High/Medium |
| A7 |
Netaddr / site keys |
mux/src/netaddr.cpp, tests/netaddr/ |
small |
Pass 14 2026-07-29 |
deep |
#799/#800 held; #1774 CIDR prefix int truncation (PR #1776) |
| A8 |
Slave / stubslave |
mux/src/slave.cpp, stubslave.cpp, DNS channel in ganl_adapter |
small |
Pass 14 2026-07-29 |
deep |
#1220/#801/#1274/#1275 held; re-read no new High/Medium |
B — GANL library
| ID |
Slice |
Paths |
~Size |
Last pass |
Status |
Notes |
| B1 |
Epoll / select / kqueue / wselect / IOCP |
mux/ganl/src/*_network_engine.cpp |
med |
Pass 14 2026-07-29 |
deep |
#942–#947/#946/#943/#1290 V6ONLY held; maxEvents write-disarm guards held |
| B2 |
IOCP / wselect |
iocp_*, wselect_* |
med |
Pass 14 2026-07-29 |
deep |
#1070 accept+FD_SETSIZE close; re-read with B1 |
| B3 |
OpenSSL transport |
openssl_transport.cpp |
med |
Pass 14 2026-07-29 |
deep |
#948/#949/#1282 read-BIO cap + cipher pin held; TLS 1.2+; renegotiation disabled; no new High/Medium |
| B4 |
Schannel transport |
schannel_transport.cpp |
med |
Pass 14 2026-07-29 |
deep |
#1067/#1068/#950–#952/#1282 handshake+incomplete caps held; no new High/Medium |
| B5 |
Connection / buffers |
connection.cpp, io_buffer, types |
med |
Pass 14 2026-07-29 |
deep |
#794 high-water + try/catch in send_data; #953 kMaxBufferSize |
| B6 |
GANL tests |
mux/ganl/tests/ |
small |
Pass 14 2026-07-29 |
partial |
Locks #942–#947/#953/EMFILE + Win accept path; expand kqueue-only / soak |
C — Engine softcode & evaluation
| ID |
Slice |
Paths |
~Size |
Last pass |
Status |
Notes |
| C1 |
Classic eval / AST |
eval.cpp, ast.cpp, ast_scan.rl |
large |
Pass 14 2026-07-29 |
deep |
Survey docs/survey-eval-parser.md held: parse_to stack[32] bounded; #840 AST_PARSE_MAX_DEPTH; AST_EVAL_MAX_DEPTH=400; func_nest/invk lim; nest-- on all exits; no new High/Medium |
| C2 |
Function builtins |
mux/modules/engine/functions.cpp, funceval*.cpp, funmath.cpp, funcweb.cpp |
huge |
Pass 14 2026-07-29 |
deep |
#1106–#1124 closed; Pass 14: no raw sprintf/strcpy residual (mux_sprintf + BAN_LEGACY); family re-rotate still useful for logic |
| C3 |
Commands / hooks |
command.cpp, predicates.cpp, set.cpp (@include) |
large |
Pass 12 2026-07-26 |
deep |
#1279 @include as includer; #1280 NOEVAL footgun |
| C4 |
Match / wild |
match.cpp, wild.cpp |
med |
Pass 14 2026-07-29 |
deep |
Survey + #835–#837 held; invk limit; scenario wild_capture |
| C5 |
Speech / look / move |
speech.cpp, look.cpp, move.cpp, create.cpp, … |
large |
Pass 8 |
deep |
#1181, #1186–#1188 closed (map stale fixed Pass 14) |
| C6 |
Boolexp / locks |
boolexp.cpp |
med |
residual C6/G2/F4 |
deep |
#839 parse depth; oversize-key NUL (#1294); empty=open by design |
D — JIT / DBT / Lua
| ID |
Slice |
Paths |
~Size |
Last pass |
Status |
Notes |
| D1 |
JIT compiler / ECALL |
jit_compiler.cpp |
huge |
Pass 14 2026-07-29 |
deep |
Guest bounds, setq, watermarks, PIN_ARRAY, fargs; #1791 softcode post-entry no AST re-run after host ECALL (plan-softcode-post-entry-contract.md) |
| D2 |
HIR lower / codegen |
hir_*.cpp |
large |
Pass 7 + re-scout 2026-07-26 |
deep |
Highs #1143–#1146 → #1156; #1258–#1260 closed |
| D3 |
DBT backends |
dbt*.cpp, dbt_rt/ |
large |
Pass 7 + re-scout 2026-07-26 |
deep |
Highs closed; #1292 closed |
| D4 |
Lua module / bytecode |
lua_mod.cpp, lua_bytecode.*, hir_lower_lua.* |
med |
#1751 campaign 2026-07-29 |
deep |
Post-entry contract shipped (plan-lua-post-entry-contract.md); residual typed fidelity + mixed softcode/Lua corpus |
| D5 |
JIT oracles / fuzzer |
testcases/tools/jit_diff/, q-reg oracle |
— |
standing |
deep tooling |
Re-run soak regularly, not just on changes |
E — Persistence & queue
| ID |
Slice |
Paths |
~Size |
Last pass |
Status |
Notes |
| E1 |
SQLite / sqlitedb |
sqlitedb.cpp, sqlite_backend.cpp |
large |
Pass 14 scout 2026-07-29 |
deep |
Schema gate; blob OOM/oversize guards; ROLLBACK fail logged; re-deep residual held, no new High this hop |
| E2 |
Attr cache / write queue |
attrcache.cpp |
med |
Pass 14 2026-07-29 |
deep |
#1284 code-cache coalesce by source_hash; flush fail leaves queue; threshold 50; no new High/Medium |
| E3 |
Flatfile R/W |
db.cpp, db_rw.cpp |
large |
Pass 13 residual + Pass 14 stamp |
deep |
#806 gates; color migrate fail-closed; no new High this hop |
| E4 |
Command queue |
cque.cpp, timer.cpp, cron.cpp |
large |
Pass 14 2026-07-29 |
deep |
#1080/#1048/#1049/#1050 refund paths held; wait_que reverse-on-false; no new High/Medium |
| E5 |
Object / player / flags |
object.cpp, player*.cpp, flags.cpp, powers.cpp |
large |
Pass 14 2026-07-29 |
deep |
#1185 powers clear + IS_CLEAN powers; #1180 pcache_delete on destroy; decode_flags Hidden/CONNECTED; no new High/Medium |
F — Modules (loadable)
| ID |
Slice |
Paths |
~Size |
Last pass |
Status |
Notes |
| F1 |
comsys_mod |
mux/modules/comsys/ |
small |
Pass 14 2026-07-29 |
deep |
Channel locks via IPermissions (#1084 path); storage failures logged (#1630); dual-path with F3; no new High/Medium |
| F2 |
mail_mod |
mux/modules/mail/ |
med |
Pass 14 2026-07-29 |
deep |
MAIL_DB_LIMIT; #1192 body persist; storage AddRef; no new High/Medium |
| F3 |
Engine-in-tree comsys/mail |
engine/comsys.cpp, engine/mail.cpp |
large |
Pass 14 scout 2026-07-29 |
deep |
#1189–#1191 closed; SQLite reload when module owns state |
| F4 |
Module ABI / COM |
engine_com.cpp, modules.h |
large |
Pass 14 2026-07-29 |
deep |
#1295 nValueMax/out-param guards; AtrAddRaw privileged; IAttributeAccess/IPermissions in-process |
G — Convert / offline tools
| ID |
Slice |
Paths |
~Size |
Last pass |
Status |
Notes |
| G1 |
Omega / format convert |
mux/convert/* |
huge |
Pass 1, 3, #1087 |
deep |
sprintf class largely closed; re-scan new paths |
| G2 |
muxescape / script |
mux/muxescape/, mux/script/ |
med |
Pass 14 stamp 2026-07-29 |
deep |
#1296 input size limit; muxscript -p MarkConnected; generated muxescape.cpp |
| G3 |
announce |
mux/announce/ |
small |
Pass 14 2026-07-29 |
deep |
#1778 accept fd leak on getnameinfo fail; accept errors no longer _exit |
H — libmux / platform / unicode
| ID |
Slice |
Paths |
~Size |
Last pass |
Status |
Notes |
| H1 |
Alloc / string / time |
mux/lib/alloc.*, stringutil.*, timeutil.*, alarm.* |
med |
Pass 14 2026-07-29 |
deep |
#1290 freelist drop-one-not-wipe; alarm ms int64 clamp; i64FloorDivision INT64_MIN/-1 guard (#805); no new High/Medium |
| H2 |
Color / Ragel |
color_ops.rl, color path |
med |
Pass 14 stamp 2026-07-29 |
thin |
Edit .rl only; BAN_LEGACY / generated-files discipline |
| H3 |
UTF-8 / collation |
utf/, utf8tables.*, unicode_* |
large |
— |
deferred |
Generated tables; deep Unicode later |
| H4 |
Platform abstraction |
platform.cpp, design-platform-interface |
small |
Pass 14 scout 2026-07-29 |
partial |
BootHelper/Reap/Maximize used; RegisterSignalHandler incomplete (stored, never invoked; Win SetConsoleCtrl TODO); not product-breaking today — signals still in signals.cpp |
I — Hydra proxy
| ID |
Slice |
Paths |
~Size |
Last pass |
Status |
Notes |
| I1 |
Session / process manager |
session_manager.*, process_manager.* |
med |
Pass 4 |
deep |
#1091–#1102 closed |
| I2 |
gRPC / gRPC-web |
grpc_server.*, grpc_web.* |
med |
Pass 4 + Pass 10 |
deep |
#1265–#1269 closed |
| I3 |
Telnet bridge / stream |
telnet_bridge.*, telnet_stream.* |
med |
Pass 4 |
deep |
SB reassembly cap + disconnect |
| I4 |
Proxy WebSocket |
mux/proxy/websocket.* |
small |
Pass 4 |
deep |
#1093–#1095 closed |
| I5 |
Accounts / crypto / scrollback |
account_manager.*, crypto.*, scrollback.* |
med |
Pass 4 |
deep |
#1091–#1092, #1098, #1100 closed |
| I6 |
Proxy regression |
proxy_regression.cpp |
small |
Pass 14 2026-07-29 |
deep |
#1270 residual closed in-tree: #1265/#1266 subscriber+work-queue caps; convertInput helper for #1267-class |
J — Clients (Hydra family)
| ID |
Slice |
Paths |
~Size |
Last pass |
Status |
Notes |
| J1 |
Console client |
client/console/ |
med |
Pass 14 2026-07-29 |
partial |
IOCP+Schannel+Hydra; #1788 line caps (PR #1789); hydra pw in worlds.txt (chmod 600 Unix) |
| J2 |
Win32 GUI |
client/win32gui/ |
med |
Pass 14 2026-07-29 |
partial |
#1788 Hydra line reassembly cap; output scrollback MAX_LINES |
| J3 |
Web client |
client/web/ |
med |
Pass 14 2026-07-29 |
partial |
#1788 telnet line/SB + Hydra line + grpc-web frame caps; passwords sessionStorage |
| J4 |
Android Titan |
client/android/ |
large |
Pass 14 2026-07-29 |
partial |
#1788 TelnetParser/Hydra caps; resume path untested |
| J5 |
iOS Titan |
client/ios/ |
large |
Pass 14 2026-07-29 |
partial |
Keychain worlds/TOFU; #1788 caps (PR #1789); make test-ios units |
| J6 |
TinyFugue port |
client/tf/ |
med |
Pass 14 2026-07-29 |
partial |
#1788 line_buf_/sb_buf_ + Hydra lineBuf caps; MCCP preserved |
| J7 |
Shared client bits |
client/shared/ |
small |
Pass 14 2026-07-29 |
partial |
input_editor grapheme editing; MAX_HISTORY 500; no unbounded line defect (editor is local input) |
K — Tests, packaging, docs tooling
| ID |
Slice |
Paths |
~Size |
Last pass |
Status |
Notes |
| K1 |
Smoke suite |
testcases/ |
large |
every fix PR |
deep |
Grow when behavior changes; Lua seam TC061–078 on master |
| K2 |
Scenario / stress |
tests/scenario/, tests/stress/ |
med |
Pass 14 2026-07-29 |
partial |
run.sh: 9 drivers + trap cleanup (not just wild_capture); still opt-in via make test-scenario; stress/ separate |
| K3 |
Unit islands |
tests/alarm, netaddr, db, libmux |
small |
on change |
partial |
|
| K4 |
Packaging |
debian/, docker/, dounix.sh, win32/ |
med |
Pass 14 stamp 2026-07-29 |
thin |
Present; no defect this pass |
| K5 |
Parser research |
parser/ |
small |
— |
deferred |
Not production runtime |
| K6 |
Worldbuilder / tools |
tools/worldbuilder/ |
— |
— |
deferred |
|
| K7 |
Generated-file discipline |
see docs/generated-files.md |
— |
standing |
process |
Never hand-edit outputs |
L — Product backlog (not audit defects)
| ID |
Item |
Status |
| L1 |
#1027 in-game archive/restore via SQLite |
backlog |
Pass log (summary)
| Pass |
When |
Focus |
Outcome |
| Pass 1–13 |
2026-07 |
See historical changelog |
Many Highs/Mediums closed |
| Pass 14 |
2026-07-29 |
Dice loop A7 → full catalog + clients |
#1774 CIDR; #1778 announce; #1788 client buffer caps (all J*); #1791 softcode post-entry; residual re-deep A–I/F/H; no open product issues at closeout |
| Pass 15 |
2026-07-31 |
A1–A5 network / telnet / Win32 email |
#1798 COM fail-closed; #1800–#1803 WS/SMTP/listeners; #1801/#1805 Win32 initiateConnect; #1806–#1809 max_players, WS input_tot, find_oldest, SOCKET widths; #1811–#1814 NVT batch; board empty at closeout |
Also useful historical surveys:
docs/survey-*-pass-2026-06.md, docs/survey-ganl-networking.md, docs/survey-queue.md, etc.
Recommended rotation (next ~N passes)
Pass 15 closed (2026-07-31). Driver/network High/Mediums from the audit pass are filed and merged. Open product-bug board is empty; next High/Medium comes from a new audit dice or product goal.
| Next |
Slice(s) |
Why |
| Anytime |
D5 jit_diff soak; make test / make test-scenario |
Continuous confidence |
| Anytime |
Mixed softcode/Lua corpus + residual D* fidelity |
Product soak, not map restart |
| Later |
H4 RegisterSignalHandler; client password storage (J*) |
Non-blocking tech debt |
| Pass 16+ |
New dice start or product-driven slice |
Empty board — invent only with a goal |
When a pass is “empty” (no High/Medium), still record the pass and Status=deep with date — that prevents false “never looked” later.
Review lenses (apply every slice)
Use the same questions so re-audits stay consistent:
- Bounds — lengths, indexes, guest/host, stack buffers,
sprintf vs snprintf
- Lifetime cycle — alloc/free, COM refs, DESC/ws, queue entries, SQLite pins
- Permissions — executor vs thing, locks, unfindable, module vs engine
- Failure paths — OOM, partial init, reject/close, refund/quota
- Config sync — mudconf vs
g_dc, boot-only knobs
- Platform — Win32 vs POSIX, FD limits, TLS stack differences
- Generated files — source + regen present (
docs/generated-files.md)
Standing verification (every fix PR)
From docs/status-2.14.md and practice:
make install (or Windows netmux.sln when needed)
make test (smoke, ganl, netaddr, JIT oracle, iOS units if Darwin)
- Opt-in:
make test-scenario, testcases/tools/jit_diff/soak.sh
- Windows: Schannel/IOCP/wselect when the slice is Win32-heavy
Changelog (map document)
| Date |
Change |
| 2026-07-24 |
Initial map after Passes 1–3 |
| 2026-07-24–26 |
Passes 4–13; residual scouts (see git history) |
| 2026-07-26 |
Pass 13 residual (anti-cool): E3; #1411; #1408 family |
| 2026-07-29 |
Pass 14 dice loop: server residual complete; J1–J7 client portfolio — #1788 buffer caps across clients; H2/K4 thin stamps |
| 2026-07-29 |
Pass 14 closeout: #1790 remaining clients; #1791 softcode post-entry; D1/D4 stamps; rotation table closed; supersede docs PRs #1777/#1781–#1786 |
| 2026-07-31 |
Pass 15 closeout: A1–A5 network/telnet/Win32 email; #1798–#1815 range; #1801 Win32 initiateConnect; board empty |
Update this table when the map structure changes.