Skip to content

refactor(cli,config)!: withdraw --trace-output and --mode explain (OX-H5) - #36

Merged
ojassug merged 1 commit into
mainfrom
audit/lane-a-h5
Aug 23, 2026
Merged

refactor(cli,config)!: withdraw --trace-output and --mode explain (OX-H5)#36
ojassug merged 1 commit into
mainfrom
audit/lane-a-h5

Conversation

@ojassug

@ojassug ojassug commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Audit OX-H5, decided as withdraw rather than implement. DECISIONS §62.

Both knobs were parsed, validated against an enum, threaded through the file → env → CLI precedence
chain, frozen onto ResolvedConfig — and read by nothing. traceOutput appears at ten sites in
src/; every one is a write or a type declaration. The trace is emitted by a literal:

io.stderr.write(JSON.stringify(result.trace, null, 2));

So --trace-output stdout accepted the value, validated it, stored it, and the trace went to
stderr. A user setting it to capture a trace in a pipe concluded the tool had ignored them. It had.
Nothing branched on appMode === 'explain' at all.

This is the defect audit H4 already removed three flags for (--max-output-tokens,
--max-latency-ms, --risk-tolerance, README "removed in 1.2.0"). These two survived that sweep
only because they sit on ResolvedConfig rather than OptimizationBudget.

Withdrawn on H4's terms

The surfaces go, the model fields stayResolvedConfig.appMode and
ResolvedConfig.traceOutput remain with Unconsumed doc comments, because ARCHITECTURE.md pins
the model as frozen and a field awaiting an implementation is not the same defect as a dial that
reports success. If traceOutput is ever implemented, cli/main.ts reads the field first and the
surfaces come back after — never the reverse.

Implementing it would have been two lines. The argument against: the only caller in this
repository that passed the flag — tools/corpus-harness/measure.js, with --trace-output stderr
has been reading stderr correctly the whole time while passing a flag that did nothing. The sole
user asked for the default.

--mode is narrowed by value, not removed

--mode bench rewrites the command:

if (value === 'bench') { command = 'bench'; }

That is a live effect — and it lives in the parser, not in anything that reads appMode. An
earlier pass through this finding concluded "appMode has no consumers, so remove --mode
entirely": true about the field, false about the flag, and it would have deleted a working route to
bench. The distinction is why this was checked rather than assumed, and both halves are pinned.

What changes for existing setups

  • --trace-output is now Unknown argument. TOKENDAMPER_TRACE_OUTPUT is simply not read,
    matching how the H4 variables were retired.
  • --mode explain, TOKENDAMPER_APP_MODE=explain and app.mode: "explain" are hard errors,
    per the rule 1.6.0 set for the TOKENDAMPER_* enums. Nothing that took effect stops taking
    effect, because none of it ever did.
  • A config file still carrying traceOutput keeps loading. The key is no longer validated or
    read, and unknown keys were always ignored — withdrawing a knob must not turn a file that loaded
    yesterday into a hard error.
  • The trace has not moved. stderr, as always.
  • tools/corpus-harness/measure.js is updated in the same commit; leaving it would have turned the
    measurement harness into a parse error.

Also corrected in passing

The comment above COMMON_FLAGS claimed --target-reduction-ratio is "nearly as inert — the
planner reads it only as > 0". False since DECISIONS §48, which resolves the ratio into an
absolute token ceiling both pruning:topology-pruner and compression:token-hashing respect, with
§50 narrowing the adherence gap via sub-region elision. The README's environment-variable table
carried the same stale claim. Comments record decisions here; one recording a superseded decision
argues for undoing the fix.

Verification

Six withdrawal cases confirmed failing against the unfixed tree first; three "deliberately
kept" cases pin the halves that survive. Verified end to end on the built binary — the harness's
new invocation exits 0 and its trace still parses out of stderr, --trace-output is rejected, and
--mode explain reports Accepted values: optimize, bench.

npm run typecheck, npm run lint, npm run build and npx vitest run all pass: 84 files /
778 tests
.

🤖 Generated with Claude Code

Audit OX-H5, DECISIONS §62.

Both were parsed, validated against an enum, threaded through the
file -> env -> CLI precedence chain, frozen onto ResolvedConfig -- and
read by nothing. traceOutput appears at ten sites in src/; every one is a
write or a type declaration. The trace is emitted by a literal
io.stderr.write(...), so `--trace-output stdout` reported success and
changed nothing, and a caller redirecting it to capture a trace in a pipe
concluded the tool had ignored them. It had. Nothing branched on
`explain` at all.

This is the defect audit H4 already removed three flags for. These two
survived that sweep only because they sit on ResolvedConfig rather than
OptimizationBudget. Withdrawn on H4's terms: the surfaces go, the model
fields stay, documented as unconsumed, because ARCHITECTURE.md pins the
model as frozen and a field awaiting an implementation is not the same
defect as a dial that reports success.

Withdraw rather than implement, though implementing would have been two
lines: the only caller in this repo that passed the flag --
tools/corpus-harness/measure.js, with `--trace-output stderr` -- has been
reading stderr correctly the whole time while passing a flag that did
nothing. The sole user asked for the default.

--mode is narrowed by value, not removed. `--mode bench` rewrites the
command, which is a live effect; it lives in the parser rather than in
anything that reads appMode. An earlier pass concluded "appMode has no
consumers, so remove --mode" -- true about the field, false about the
flag, and it would have deleted a working route to bench.

BREAKING (nominally): --trace-output is now `Unknown argument`, and
`explain` is rejected rather than ignored from all three surfaces, per
the rule 1.6.0 set for the TOKENDAMPER_* enums. Nothing that took effect
stops taking effect, because none of it ever did. A config file still
carrying a traceOutput key keeps loading -- the key is no longer
validated or read, and withdrawing a knob must not turn a file that
loaded yesterday into a hard error. The trace itself has not moved.

measure.js was updated in the same change; leaving it would have turned
the measurement harness into a parse error. Verified end to end after the
change: the file route exits 0 and its trace still parses out of stderr.

Also corrects a superseded claim found in the same comment block:
--target-reduction-ratio was documented as "nearly as inert -- the
planner reads it only as > 0", false since §48 made it a real ceiling.
The README carried it too.

Verified: typecheck, lint and build clean, 84 files / 778 tests. The six
withdrawal cases were confirmed failing against the unfixed tree first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ojassug
ojassug merged commit 9e13dd0 into main Aug 23, 2026
3 checks 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.

1 participant