You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Found by an audit of where the Python port hand-rolls what Typer/Click already provides. This one is a real behavioural divergence, not a style point.
Two hand-written copies, already drifted
python/tan/commands/faultdecode_cmd.py:91 if os.environ.get("NO_COLOR"): # truthy check
python/tan/commands/size_cmd.py:404 os.environ.get("NO_COLOR") is not None # presence check
The Rust oracle is presence-based — crates/tan-cli/src/style.rs:27 uses var_os("NO_COLOR").is_none() — which is also what the NO_COLOR spec requires: any value, including empty, disables colour.
So size_cmd matches the oracle and the spec. faultdecode_cmd does not: with NO_COLOR= (set but empty) it evaluates falsey and tan faultdecode keeps emitting colour, where tan size and the Rust binary both suppress it.
The obvious fix is a worse bug — flagging it explicitly
The instinct is typer.Option(..., envvar="NO_COLOR"). Do not. Click's bool-envvar coercion is truthy-string parsing (1 / true / yes / on …), not presence detection. NO_COLOR= would then raise not a valid boolean and crash the command — a regression neither hand-rolled copy has today, introduced by "using the framework properly".
The safe consolidation is a single shared presence-check helper, or a callback= — not the bare envvar= kwarg — matching style.rs.
Why this is worth more than the one-line fix
Two independent copies of one environment contract is the shape that produced the drift. Any third command that adds colour will copy whichever it finds first. One helper removes the class.
Related, same audit, no bug
faultdecode_cmd.py:130-152's _check_elf_path / _check_file_path are called manually at :221-222 rather than wired to their typer.Option() declarations, and their docstrings literally say "click.Path(exists=True, dir_okay=False) equivalent". Moving them to callback= is a pure relocation with identical typer.BadParameter text and param_hints — the precedent is two files over at new_som_cmd.py:553,569. Zero observable change, so no oracle-parity risk. Same for the ten _parse_hexint(...) call sites.
What the same audit found NOT worth changing, recorded so it is not re-proposed
add_completion=True does not close Deferred: seven commands are entirely unported (scaffold, completion, diff, pinmux, inspect, trace, support-bundle) #260. The oracle's tan completion --shell {bash,zsh,fish} (crates/tan-cli/src/commands/completion.rs) is a subcommand emitting hand-captured static scripts with a test suite proving every clap flag round-trips; Typer's is --install-completion/--show-completion root flags driving Click's dynamic protocol. Flipping the flag adds a second, non-parity mechanism, changes root --help observably, and needs its own --format json interception (both are eager Click options that print and exit before root()).
no_args_is_help=True would flip bare tan from exit 2 to exit 0 — a documented oracle-parity break.
rich_help_panel= grouping: clap's help is equally flat, so grouping only the Python port's --help would itself be the divergence.
typer.confirm in bootstrap's workspace guard: deliberately absent, and the code says why — "NO PROMPT, ever, in this port … the oracle hung forever on exactly that."
cli.py:437-541's _TeeStderr / SystemExit machinery is load-bearing, not a gap: it folds a pre-dispatch usage error into the stdout envelope while still streaming stderr live, and typer==0.27.0's Click-alike hierarchy is private (typer._click.*), so scraping rendered text is the version-stable seam.
ALP_FLASH_FORCE env-only with no --force flag mirrors crates/tan-cli/src/commands/flash/mod.rs:171 exactly — deliberate on both sides.
Found by an audit of where the Python port hand-rolls what Typer/Click already provides. This one is a real behavioural divergence, not a style point.
Two hand-written copies, already drifted
The Rust oracle is presence-based —
crates/tan-cli/src/style.rs:27usesvar_os("NO_COLOR").is_none()— which is also what the NO_COLOR spec requires: any value, including empty, disables colour.So
size_cmdmatches the oracle and the spec.faultdecode_cmddoes not: withNO_COLOR=(set but empty) it evaluates falsey andtan faultdecodekeeps emitting colour, wheretan sizeand the Rust binary both suppress it.The obvious fix is a worse bug — flagging it explicitly
The instinct is
typer.Option(..., envvar="NO_COLOR"). Do not. Click's bool-envvar coercion is truthy-string parsing (1/true/yes/on…), not presence detection.NO_COLOR=would then raisenot a valid booleanand crash the command — a regression neither hand-rolled copy has today, introduced by "using the framework properly".The safe consolidation is a single shared presence-check helper, or a
callback=— not the bareenvvar=kwarg — matchingstyle.rs.Why this is worth more than the one-line fix
Two independent copies of one environment contract is the shape that produced the drift. Any third command that adds colour will copy whichever it finds first. One helper removes the class.
Related, same audit, no bug
faultdecode_cmd.py:130-152's_check_elf_path/_check_file_pathare called manually at:221-222rather than wired to theirtyper.Option()declarations, and their docstrings literally say "click.Path(exists=True, dir_okay=False) equivalent". Moving them tocallback=is a pure relocation with identicaltyper.BadParametertext andparam_hints — the precedent is two files over atnew_som_cmd.py:553,569. Zero observable change, so no oracle-parity risk. Same for the ten_parse_hexint(...)call sites.What the same audit found NOT worth changing, recorded so it is not re-proposed
add_completion=Truedoes not close Deferred: seven commands are entirely unported (scaffold, completion, diff, pinmux, inspect, trace, support-bundle) #260. The oracle'stan completion --shell {bash,zsh,fish}(crates/tan-cli/src/commands/completion.rs) is a subcommand emitting hand-captured static scripts with a test suite proving every clap flag round-trips; Typer's is--install-completion/--show-completionroot flags driving Click's dynamic protocol. Flipping the flag adds a second, non-parity mechanism, changes root--helpobservably, and needs its own--format jsoninterception (both are eager Click options that print and exit beforeroot()).no_args_is_help=Truewould flip baretanfrom exit 2 to exit 0 — a documented oracle-parity break.rich_help_panel=grouping: clap's help is equally flat, so grouping only the Python port's--helpwould itself be the divergence.typer.confirmin bootstrap's workspace guard: deliberately absent, and the code says why — "NO PROMPT, ever, in this port … the oracle hung forever on exactly that."cli.py:437-541's_TeeStderr/SystemExitmachinery is load-bearing, not a gap: it folds a pre-dispatch usage error into the stdout envelope while still streaming stderr live, andtyper==0.27.0's Click-alike hierarchy is private (typer._click.*), so scraping rendered text is the version-stable seam.ALP_FLASH_FORCEenv-only with no--forceflag mirrorscrates/tan-cli/src/commands/flash/mod.rs:171exactly — deliberate on both sides.