The 22 per-tracker ISSUES.md files carried both their open items and a
full FIXED / FALSE ALARM / NOT A BUG audit history. The 57 still-open
items have been migrated to GitHub issues #706-#762 with a 2.14-aligned
label taxonomy (area:* / type:* / priority:* / topic:*), so open work
now lives in the issue tracker instead of in-tree Markdown.
The closed/audit history of every tracker is preserved here in git
history (this commit's parent); nothing is lost.
Open items migrated by tracker:
mux/src/ (1) -> #706
mux/lib/ (10) -> #707-#716
mux/modules/engine/ (18) -> #717-#734
mux/ganl/ (10) -> #735-#744
mux/modules/sqlslave/ (9) -> #745-#753
testcases/ (4) -> #754-#757
client/tf/ + client/ (5) -> #758-#762
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
parser/ISSUES.md flagged the escape oracle corpus as hand-curated with
no automated cross-check against a real engine, letting stale rows
accumulate. Add parser/validate_live_oracle.sh, which runs every row
of escape_oracle_cases.txt through mux/game/bin/muxscript via `think
<expr>`, extracts the value, and compares it against the mux214
column. Rows where live_status != confirmed are also flagged.
First run surfaced five drifted rows — plain_single_unknown,
plain_double_unknown, plain_single_known, plain_double_known,
plain_triple_known. Reviewing mux2.13_13/src/eval.cpp confirmed that
line 2439-2460 (backslash handler) and 1680-1699 (percent handler
under EV_EVAL off) compute the live-engine values, not the values the
corpus had for those rows. The earlier "Confirmed on real 2.13 via
traced @pemit output" notes were wrong. Updated the corpus to the
ground-truth values; live mux2.14 and 2.13 both match it now.
parser/eval.cpp's own theoretical model is intentionally left alone.
./eval and test_eval.sh describe what the study evaluator believes,
and lining those up with live engine behavior across the FN_NOEVAL
two-pass mechanics is a much bigger task. The validator is the
authoritative cross-check whenever either side changes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Console hydra_connection.cpp: reconnect path now uses cached
termWidth_/termHeight_ instead of hardcoded 80x24.
- mail_mod.cpp, comsys_mod.cpp: g_cComponents and g_cServerLocks
changed from uint32_t to std::atomic<uint32_t> for thread safety.
- parser/mux_parse.h: token_name() changed from static to inline,
eliminating -Wunused-function warning under -Wall -Wextra.
- Update ISSUES.md trackers; close debian stubslave as intentional.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Systematic code review identifying ~55 issues: buffer overflows and
signal safety in mux/src/, unchecked COM acquisitions in modules,
client credential storage and reconnect regressions, test brittleness
and coverage gaps, outdated Docker/Debian packaging, and release
script error handling.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause confirmed via debugger: 2.13's mux_exec() backslash handler
(eval.cpp line 2439) has no EV_EVAL guard — it runs unconditionally on
every pass. When brace-group arguments go through FN_NOEVAL functions
like switch(), the text passes through mux_exec() twice: once for noeval
arg collection (stripping one backslash layer) and once for evaluation.
This two-pass behavior turns \\% into \% then into literal %.
The 2.14 AST scanner tokenizes once greedily — \\ becomes one ESC token
and % becomes one SUBST token, evaluated independently. This produces
\<space> instead of % for the bboard case.
Fix: add noevalPass() and evalNoevalArg() to the parser prototype.
For brace-group args to FN_NOEVAL functions, strip one backslash layer
via noevalPass(), re-tokenize, then evaluate. This replicates 2.13's
unconditional backslash consumption.
Changes:
- docs/parser-percent-matrix.md: complete semantic matrix of all %
forms across 2.13, 2.14, and PennMUSH with confirmed root cause
- parser/eval.cpp: full % substitution coverage (pronouns, color stubs,
caller, objid, moniker, hash forms, etc.), noevalPass/evalNoevalArg
for two-pass brace-group handling in if/switch/case
- parser/mux_parse.h: tokenizer support for hash forms (##/#@/#$),
Penn %$ stack vars, %w attrs, %iL, angle-bracket helper
- parser/test_eval.sh: 123 tests (was 86), cross-profile escape+percent
tests including the confirmed bboard divergence case
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. db/Makefile: Fix SQLite path (../mux/src/sqlite → ../mux/sqlite)
and add -I for sqlite3.h in C++ compile rules.
2. mux/src/Makefile.am: Fix version stamping — target
netmux-version.o (Automake's per-program prefix) instead of
version.o, so MUX_BUILD_DATE/MUX_BUILD_NUM actually reach
the linker.
3. mux/lib/Makefile.am: Add -MMD -MF to .lo pattern rules and
-include the generated .d files. Header changes in mux/include/
now trigger correct incremental rebuilds of libmux.so.
4. mux/modules/engine/Makefile.am: Same -MMD -MF treatment for .eo
pattern rules. engine.so now tracks header dependencies.
5. parser/Makefile: Add mux_parse.h as explicit dependency for all
three standalone tools.
Verified: touching mux/include/hir.h correctly triggers rebuild of
all engine .eo files that include it.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- hir_opt.cpp: Normalize commutative binary ops (ADD, MUL, etc.) in CSE to improve redundancy detection.
- parser/eval.cpp: Add IF and EVAL support to study tool for better Issue 2 verification.
- hir_opt.cpp: Replace O(N^2) CSE scan with unordered_map hash table.
- dbt_compile.cpp: Add dbt_compile_cleanup() to release persistent JIT state.
- dbt_compile.cpp: Expand JIT guest memory to 512KB and output scratch ring to 32 slots (256KB).
- engine_com.cpp: Call dbt_compile_cleanup() during server shutdown.
- parser/eval.cpp: Implement EV_FCHECK stripping and mandatory eval logic to match engine.
Evaluator now respects EV_EVAL, EV_FCHECK, EV_FMAND, EV_NOFCHECK,
and EV_STRIP_CURLY flags matching mux_exec behavior:
- %-substitutions only resolved when EV_EVAL set
- Function calls only dispatched when EV_FCHECK set
- [...] brackets force EV_FCHECK | EV_FMAND on contents
- {...} braces pass through raw when EV_STRIP_CURLY not set
- {...} with EV_STRIP_CURLY strips braces, disables EV_FCHECK
82 tests passing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extract duplicated tokenizer, parser, and AST code from three study
tools into a shared header. Each tool is now a thin main() wrapper.
Added ast_raw_text() utility for source reconstruction. No behavioral
changes — 78 tests still pass.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rework control flow functions (if, switch, case, cand, cor, iter, lit,
@@) to use deferred evaluation: handlers receive unevaluated AST
subtrees and call eval() selectively. This eliminates the need for
replace_tokens() and ##/#@/#$ text substitution.
Key proof: iter(10 20 30,[add(%i0,1)]) correctly produces "11 21 31"
by pushing %i0 onto the iterator stack and evaluating the body subtree
per item. Nested iterators work via %i0/%i1 stack depth.
Add PARSER_REPLACE.md design document for mux_exec replacement
architecture. 78 tests passing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Stage 3 of parser study: tree-walking evaluator that demonstrates
pure-expression MUX softcode CAN be evaluated from an AST. Implements
arithmetic, string, list, comparison, boolean, register, and control
flow functions. Includes 64-test harness.
Key finding: FN_NOEVAL functions (iter, switch, if) need deferred
argument evaluation — the evaluator must pass unevaluated AST subtrees
rather than pre-evaluated strings. Solvable but requires a different
dispatch mechanism than simple string-in/string-out handlers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Stage 2 of parser study: recursive-descent parser that builds an AST
from the token stream. Handles static function calls, dynamic/computed
calls (DynCall), eval brackets, brace groups, and nested arglists.
Enhanced tokenizer with full L2 %-substitution coverage. Added test
corpus covering all major expression patterns.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document the three-layer parser architecture (command, expression,
lock) in docs/PARSER.md with analysis of mux_exec internals, the
backwards function name recognition challenge, and a staged plan
for potential AST generation. Include a standalone tokenizer CLI
tool in parser/ for studying MUX expression structure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>