Skip to content

fix(ci): restore green master (TUI test drift, rustfmt, clippy, warning budget, ratchet baselines) - #1964

Open
ianalitis wants to merge 8 commits into
1jehuang:masterfrom
ianalitis:fix/restore-green-master
Open

ianalitis wants to merge 8 commits into
1jehuang:masterfrom
ianalitis:fix/restore-green-master

Conversation

@ianalitis

@ianalitis ianalitis commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Status: all 13 checks green on 8c4f71731 (Build & Test on ubuntu/macos/windows, Quality Guardrails, Format, and the rest). This is the first fully green head in this stack.

Master is currently red at 4bb16b96c, tracked in #1907. CI run 40140561404 failed in three jobs, and every failure is mechanical drift rather than a behavioral bug. This branch restores those gates.

What failed and why

Build & Test (ubuntu-latest) — "Run TUI library tests (Linux only)": 2968 passed; 6 failed. All six are assertion drift from recent, intentional production changes:

Test Cause
test_finalize_reload_reconnect_mentions_persisted_background_task 90ee50330 replaced the background-handoff copy (bg action="status"/"output") with BACKGROUND_WAIT_GUIDANCE
test_reload_persisted_background_tasks_note_mentions_running_task same
test_preview_structured_messages_stay_left_aligned ff31b8bba / 59eabc409 collapse finished todo cards to status dots, so the fixture's completed/verified todo renders no card line
test_remote_jcode_subscription_catalog_is_not_augmented_with_local_auth_routes claude-sonnet-4-6 is now in the shipped subscription catalog
render_system_message_drops_emoji_variation_selectors compact cache-miss notices render as a one-line summary, without the warning glyph
notification_spans_include_recent_flicker_warning_and_log_hint copy badge renders [<alt label>⇧Z]; assert through the production helper copy_badge_alt_label()

Each assertion update carries a comment naming the commit that changed the production behavior.

Build & Test (macos-latest) — "Enforce warning budget" and Quality Guardrails — warning budget: current=1 baseline=0, the single warning being function format_todo_completion_confidence is never used. That helper is pub(super) with no callers, so it is removed.

Quality Guardrails — clippy: cargo clippy --locked --all-targets --all-features -- -D warnings is red. Fixes are mechanical only: three collapsible_if let-chains, two needless_borrow, one unwrap after is_some in the Changes widget, and two unused imports (one of them a redundant use super::* in the reload-render test module, where the parent module already glob-imports).

Format — "check formatting": rustfmt reflow in jcode-config-types's compaction config test.

Ratchet baselines, now included here

The four ratchet gates clear only via each script's own --update, which records new baselines. Those baselines were last refreshed by 89e46951b ("fix(ci): restore green master for v0.99.1", 2026-10-22). 150 commits and 3 merge commits landed after that, so all four gates fail identically on master tip and therefore on every open PR, which is why several recent PRs all report the same guardrail failure (#547, #692, #1796, #1907 are the same pattern).

The baselines are refreshed in the last commit of this branch, and only through --update (no hand edits):

Baseline Change
check_code_size_budget.py tracked 120 → 121 files, +4013 LOC
check_test_size_budget.py tracked 49 → 50 files, +3914 LOC
check_panic_budget.py 174 → 195 occurrences, 61 → 67 files
check_swallowed_error_budget.py 3961 → 3997 occurrences, 563 → 569 files

Four files that shrank were ratcheted down, not left flat: app/remote.rs 2278 → 2233, provider-anthropic-runtime/lib.rs 2788 → 2770, tool/bash.rs 1590 → 1576, ui_input.rs 3026 → 3021.

Two entries carry real debt and are the reason the growth is not free. They are recorded, not hidden:

  • tool/todo.rs 2853 → 3543 (+690)
  • ui_messages/tests.rs 3653 → 4643 (+990)

All five checks pass locally on this head: check_code_size_budget.py, check_test_size_budget.py, check_panic_budget.py, check_swallowed_error_budget.py, check_module_files.py.

The recurrence cause is that nothing refreshes the baselines at release time. A --update step in the release automation, or a scheduled job that opens a refresh PR when a gate drifts, would stop this from re-accumulating. Not done here, since it is a workflow decision rather than a CI unblock.

Two more reds found by running the whole suite, not just the failing names

The failing test names above came from CI logs. Running the same suites locally turned up two more stale assertions that CI could not report, because neither one is gated on the platform where CI runs it:

jcode-provider-gemini-runtime — build_tools_keeps_required_when_the_object_declares_no_properties fails (39 passed; 1 failed). 7e6dec1e6 ("Fix todo add schema rejected by Gemini") taught prune_dangling_required in jcode-schema-dialect that an object with no properties map declares no names, so a dangling required entry is dropped rather than preserved. The test asserted the removed behavior. It is renamed to build_tools_drops_required_when_the_object_declares_no_properties, asserts required is absent, and carries the causing commit plus the #655 rationale. This target does not run in CI at all (the ubuntu job only compiles it via --lib --bins --no-run), which is why it stayed red unnoticed.

jcode-tui — idle_hibernation_frozen_frames_do_not_repopulate_prepared_caches asserts the frozen frame contains private mem, but hibernation_notice only prints a figure when process_memory::snapshot() returns one, and that implementation is Linux and Windows only: elsewhere it returns ProcessMemorySnapshot::default() and the notice is 💤 Hibernated · type to resume. CI runs the TUI library target on Linux only, so this was green there and red for every macOS developer. The assertion now checks the notice shape the platform can actually produce. This is the same defect as #1897. That issue asks for a macOS snapshot() implementation instead (task_info, MACH_TASK_BASIC_INFO + TASK_VM_INFO), which #1880 attempts; process_memory.rs is deliberately untouched here and #1897 should stay open. The gate is a capability check rather than a relaxation: whenever private_memory_bytes() returns a value the test still demands private mem, so once #1880 lands the macOS branch is exercised exactly as it was written. If the maintainer prefers to keep the assertion unconditional in the meantime, ff9d12d9c is isolated and can be dropped without touching anything else here.

Separately, the TUI library suite still cannot be run in parallel: cargo test --workspace deadlocks locally in the jcode-tui test binary with many idle threads, which is the shared-process-state problem the workflow comment and #592 already describe. The serial CI command is the honest signal, and that is what was run below.

Verification

  • COLORTERM=truecolor cargo test -p jcode-tui --lib -- --test-threads=1 --skip test_prompt_entry_shimmer_color_moves_across_positions --skip right_fact_stack_uses_neutral_gray_except_for_context_usage (the exact CI command) → 2968 passed; 0 failed; 19 ignored.
  • cargo test -p jcode-provider-gemini-runtime --lib → 40 passed; 0 failed.
  • cargo test -p jcode-schema-dialect --lib → 39 passed; 0 failed.
  • cargo clippy --locked --all-targets --all-features -- -D warnings → clean (previously 9+ findings).
  • cargo fmt --all -- --check → clean.
  • scripts/check_warning_budget.sh → Warning budget OK: current=0 baseline=0.
  • scripts/check_wildcard_reexport_budget.py → passes.
  • cargo test --locked --lib --bins --no-run → all test targets compile.

CI feedback on the first push, and the fix

CI on 03e9b2ccb cleared Format, the TypeScript SDK, and the Linux/windows cross-target checks, and found one real mistake in this branch that local macOS runs could not see. The dead-import cleanup dropped use std::path::Path; from src/cli/cloud_managed_tests.rs; its only two users sit inside mod shell, which is #[cfg(all(target_os = "linux", target_arch = "x86_64"))]. On macOS the import is genuinely unused, so clippy flagged it and the removal looked correct, but on Linux it is required and both Quality Guardrails (steps 7-8) and Build & Test (ubuntu-latest) (step 7) failed with E0425/E0433: cannot find type Path in this scope at lines 47 and 387.

d738d1707 moves the import inside the gated module, so it exists where it is used and does not exist where it would be dead. Verified by temporarily widening that module's cfg to unix locally so its body actually compiles: cargo check --locked --bins --tests is clean, and with the cfg restored cargo clippy --locked --all-targets --all-features -- -D warnings is clean on macOS. The lesson for this PR is that a macOS-only clippy signal is not evidence about cfg-gated code, so any further cleanup in a platform-gated module needs the same treatment.

CI on c4063c77f, before the ratchet commit

Run 40153071531, every job except one green:

Job Result
Format, Setup Friction Eval, Release Automation, TypeScript SDK, PowerShell Syntax, Windows Cross-Target Check, Windows ARM64 Release Configuration success
Build & Test (ubuntu-latest) success
Build & Test (macos-latest) success
Build & Test (windows-latest) success
Cloud Acceptance (separate run) success
Quality Guardrails failure, and only the four ratchet steps

This is the first commit in the whole sequence where the ubuntu cohort chain actually reached the end. On master the job died at "Run TUI library tests", so deterministic retention readiness, secret-input pty, browser liveness, embedding numeric stability, stdin forwarding, provider matrix, e2e, warning budget and security preflight had never run. All of them pass here.

The four ratchet steps (Enforce oversized-file ratchet, oversized-test, panic-prone usage, swallowed-error usage) were the only remaining reds on that head. 8c4f71731 refreshes their baselines; run 40163310188 on it is green on all 13 checks.

Interaction with the other open red-master PRs

Two other PRs touch overlapping files, and both are blocked by this one rather than by their own content. Landing order that keeps everyone's work intact:

  • fix: restore fmt, clippy, and budget gates on master #1906 (fix: restore fmt, clippy, and budget gates on master) refreshes the same four baselines, but against be64b54af. Master tip needs one more tracked file (jcode-provider-openai/src/stream.rs at 1212 LOC) and +1766 code LOC over its table, so its ratchets will fail again after a rebase. Its ubuntu job is red in Security preflight (Linux) only, from two advisories published 2026-10-23 (RUSTSEC-2026-0387 crypto-bigint 0.5.5, RUSTSEC-2026-0385 ctutils 0.4.2) that a current lockfile no longer resolves. Its unique value (cargo-machete dependency removal, large-enum boxing, wider clippy set) is not needed to turn master green and is best re-scoped on top of this branch.
  • tui tests: isolate flicker-history and picker-catalog state across parallel tests #1961 (tui tests: isolate flicker-history and picker-catalog state) fixes genuine cross-test state leakage, which this branch does not address. It needs a rebase afterwards; only its test_size_budget.json numbers should move.

— Jcode agent (automated triage), on behalf of @1jehuang

Master's TUI library suite has been red since three intentional
production changes landed. Each assertion below drifted because the
production behavior changed on purpose, not because of a logic bug:

- remote_events_reload_03: 90ee503 replaced the background-handoff copy
  (`bg action="status"/"output"`) with BACKGROUND_WAIT_GUIDANCE, which
  also asks the model to "make progress on other useful work". Assert
  that phrase alongside "Do not rerun those commands".
- session_picker_tests: ff31b8b and 59eabc4 collapse finished todo
  cards to status dots, so the fixture used a completed/verified todo
  that no longer renders a structured card line. Keep the card in a
  non-terminal state (in_progress/validated).
- ui_messages: compact cache-miss notices render as a one-line summary,
  so the assertion no longer sees the warning glyph.
- frame_flicker: the copy badge renders `[<alt label>⇧Z]`, so assert via
  the production helper `copy_badge_alt_label()` instead of a literal.
- remote_startup_input_02: claude-sonnet-4-6 is in the subscription
  catalog shipped by the current model list.

Verified: cargo test -p jcode-tui --lib remote_events_reload_03 /
remote_startup_input_02 / session_picker / ui_messages / frame_flicker
(6 previously failing tests now pass).
`cargo fmt --all -- --check` fails on master because this `let` was
wrapped across lines in a way rustfmt reflows. Rejoin it so the Format
job passes again; no behavior change.
`cargo clippy --locked --all-targets --all-features -- -D warnings` is
red on master. All findings are mechanical; no behavior change:

- collapsible_if: collapse nested `if`/`if let` into let-chains in
  jcode-todo-policy followup, jcode-tui-tool-display, and the cloud
  ephemeral request builder.
- needless_borrow: drop `&` on a `&Reply` argument and on a `format!`
  passed to `set_status_notice`.
- unwrap-after-is_some: bind `dual_git_info` with `if let Some(...)` in
  the Changes widget instead of `is_some()` + `unwrap()`.
- unused imports: drop redundant `use super::*` in the reload-render
  test module (the parent module already glob-imports it) and an unused
  `std::path::Path` in the cloud managed tests.
- dead_code: remove `format_todo_completion_confidence`, a `pub(super)`
  helper with no callers.

Closes the clippy step of the Quality Guardrails job.
Removing the top-level `use std::path::Path;` was wrong: the only users
of `Path` (lines 47 and 387) sit inside `mod shell`, which is
`#[cfg(all(target_os = "linux", target_arch = "x86_64"))]`. On macOS
the import was therefore unused (clippy-fatal), but on Linux removing it
breaks `cargo check --all-targets` with E0425/E0433, which is what CI
reported in both the Quality Guardrails and ubuntu Build & Test jobs.

Move the import into the gated module so it is present where it is used
and absent where it would be dead. Verified by temporarily widening the
module cfg to `unix` locally: `cargo check --locked --bins --tests`
compiles the module body clean, and with the cfg restored
`cargo clippy --locked --all-targets --all-features -- -D warnings` is
clean on macOS.
7e6dec1 changed prune_dangling_required to treat a missing properties map
as no declared names instead of returning early, so a required name with
nothing to declare it is now pruned. That is the shape Gemini rejected in
1jehuang#655, and such a schema cannot be satisfied by any input, so the pruning is
the intended behavior. Rename the test to match what it now asserts and name
the commit that changed it, so the next reader can tell drift from regression.

Refs 1jehuang#1951
…notice

idle_hibernation_frozen_frames_do_not_repopulate_prepared_caches asserted
the frozen frame contains "private mem", but hibernation_notice only
reports a figure when process_memory::snapshot() returns one. That
implementation is Linux and Windows only; every other platform gets
ProcessMemorySnapshot::default() and renders "type to resume" instead.

CI runs the TUI library target on Linux only, so the assertion was green
there and red for every macOS developer. Assert the notice shape the
platform can actually produce, and name the cause.

Verified: full serial suite (the exact CI command) 2968 passed, 0 failed.
…gling_required

The rule from 7e6dec1 is that Gemini rejects a required entry it cannot
resolve to a property, and an object with no properties map has no
resolvable names at all, so its entire required list goes. The one-line
doc comment read as if only individually dangling names were dropped,
which is how the stale gemini-runtime test came to assert the opposite.
@ianalitis

Copy link
Copy Markdown
Contributor Author

CI on the current head is in. Run 40153071531: Build & Test green on ubuntu, macOS and Windows; Format, TypeScript SDK, cross-target, ARM64 config and Cloud Acceptance green; Quality Guardrails red on the four ratchet steps only (check, clippy, fmt, module declarations, warning budget, dependency boundaries, SDK parity, wildcard reexports and unused deps all pass).

The ubuntu job reached the end of the cohort chain for the first time in this sequence. On master it stops at Run TUI library tests, so retention readiness, secret-input pty, browser liveness, embedding stability, stdin forwarding, provider matrix, e2e, warning budget and security preflight had never been exercised since the red started; they all pass here.

Nothing new to decide. The ratchets still need your call on --update versus splitting commands.rs, and #1897 records the one option to drop ff9d12d9c if you would rather keep the hibernation assertion unconditional until #1880.


— Jcode agent (automated triage), on behalf of @1jehuang

The four ratchet baselines were last refreshed by 89e4695 ("fix(ci):
restore green master for v0.99.1") on 2026-10-22. 150 commits have landed
since, and Quality Guardrails now fails on all four budgets at 4bb16b9.
Because the same four steps fail identically on the master tip, every
open PR is red on a check no branch can influence.

Refresh with the scripts' own --update path, following the convention
already used by c59700f, aa8786b and 89e4695:

- code-size:  120 -> 121 tracked files, +4013 LOC
- test-size:   49 ->  50 tracked files, +3914 LOC
- panic:      174 -> 195 occurrences, 61 -> 67 files
- swallowed: 3961 -> 3997 occurrences, 563 -> 569 files

No policy change: threshold_loc stays 1200, the scripts keep identical
semantics, and four files that shrank were ratcheted down rather than
left flat (remote.rs -45, anthropic-runtime/lib.rs -18, bash.rs -14,
ui_input.rs -5). All five checks now exit 0 at 4bb16b9:

  check_code_size_budget.py      PASS
  check_test_size_budget.py      PASS
  check_panic_budget.py          PASS
  check_swallowed_error_budget.py PASS
  check_module_files.py          PASS

Refs 1jehuang#1907
@ianalitis ianalitis changed the title fix(ci): restore green master (6 TUI test drift, rustfmt, clippy, warning budget) fix(ci): restore green master (TUI test drift, rustfmt, clippy, warning budget, ratchet baselines) Oct 25, 2026

This branch has not been deployed

No deployments
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