Skip to content

[travsr-plugin-host, travsr-daemon, travsr-mcp, travsr-cli] derive the Phase B warning classes from one source - #792

Open
ritikpal1122 wants to merge 2 commits into
Travsr-com:masterfrom
ritikpal1122:fix/760-phase-b-warning-classes
Open

[travsr-plugin-host, travsr-daemon, travsr-mcp, travsr-cli] derive the Phase B warning classes from one source#792
ritikpal1122 wants to merge 2 commits into
Travsr-com:masterfrom
ritikpal1122:fix/760-phase-b-warning-classes

Conversation

@ritikpal1122

Copy link
Copy Markdown
Collaborator

Closes #760.

What changed

Ten Phase B warning classes were written in one place and restated in three: the CLI status renderer, the MCP decoder, and the test meant to keep them in step. PhaseBWarningClass is now the single definition; the daemon formats from it and each consumer's guard iterates ALL.

Proof it works (the whole point)

Added an eleventh class to the producer and taught no consumer. Both guards fail:

travsr-cli   every_phase_b_warning_class_the_daemon_writes_is_rendered ... FAILED
  class "probe_eleventh" is written by the daemon but `travsr status` says
  nothing about it, so the language is degraded with no visible reason

travsr-mcp   phase_b_warning_classes_match_the_cli ... FAILED

Before this, that eleventh class would have been invisible: the guard was a third hand-written list with nothing to disagree with. zero_nodes and needs_consent really sat in that hole until #752 read the producer against the consumers by hand.

It found a live bug

Turning the CLI guard on immediately failed on an existing class: needs_approval was downgrading the semantic: field to "not run" while printing no explanation at all. Fixed and now pinned.

Not a breaking change

The ten tags are byte-identical to what the daemon wrote before, so phase_b_warnings meta in an existing index still decodes:

crashed  zero_nodes  no_references  version_mismatch  needs_approval
needs_consent  skipped_unregistered  untrusted_corpus  skipped_no_analyzer
skipped_no_compdb

Why travsr-plugin-host holds it

Every variant is one field of PhaseBOutcome, which that crate produces, and it is the only crate all three surfaces already depend on. travsr-daemon depends on travsr-mcp, so the daemon cannot hold a definition travsr-mcp reads. No dependency invariant from CLAUDE.md is crossed and no cycle is introduced.

Deliberately excluded

scip_unification_misses is a whole-index missed rate, not a language's status, and neither consumer treats it as one. Making it a variant would force both guards to assert something false.

Verification

cargo build --workspace                                   clean
cargo test -p travsr-daemon -p travsr-mcp -p travsr-cli
             -p travsr-plugin-host                        0 failures
cargo clippy --workspace --all-targets                    clean
cargo fmt --all -- --check                                clean
check-em-dash.sh                                          OK
check-plugin-hashes.sh                                    OK (regenerated)

6 files, no unrelated changes.

…e Phase B warning classes from one source

Ten warning classes were written in one place and restated in three: the CLI
status renderer, the MCP decoder, and the test meant to keep them in step. The
test was a third hand-written list, so a class missing from both a consumer and
that list was invisible to it. zero_nodes and needs_consent sat in that hole
until Travsr-com#752 read the producer against the consumers by hand.

An unhandled class is not a cosmetic loss. It falls through to the availability
ladder and can surface as a terminal `done`, telling the user a language
succeeded when it did not.

PhaseBWarningClass is now the one definition. The daemon formats entries from
it, and each consumer's guard iterates ALL and asserts that consumer handles
every variant, so adding a class without teaching both fails the build and
there is no third list to maintain.

It lives in travsr-plugin-host because that is where the classes come from:
every variant is one field of PhaseBOutcome, which this crate produces. It is
also the only crate all three surfaces already depend on. travsr-daemon depends
on travsr-mcp, so the daemon cannot hold a definition travsr-mcp reads.

The ten tags are byte-identical to the strings the daemon wrote before, so
stored phase_b_warnings meta from an existing index still decodes.

scip_unification_misses is deliberately not a variant: it is a whole-index
missed rate, not a language's status, and neither consumer treats it as one.
Including it would force both guards to assert something false.

Turning the CLI guard on found a live bug it now pins: needs_approval was
downgrading the `semantic:` field to "not run" while printing no explanation,
so the language was degraded with nothing on screen saying why.
@ritikpal1122
ritikpal1122 requested a review from raj-rkv as a code owner August 24, 2026 09:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant