Commit Graph
3 Commits
Author SHA1 Message Date
NamPDTandClaude Opus 5 f15557483f fix(ui): Monitoring Overview now reads like the wireframe, and the rail stops overlapping
Two problems, both only visible at the window size this machine actually opens
(1024×571 on a 1280×672 work area):

  * The rail drew the "GẦN ĐÂY" heading on top of the last nav row. nav and the
    bottom group have fixed heights, so a short window put the entire squeeze on
    RECENTS; once that hit zero the layout had nowhere left to give. The
    destinations and RECENTS now scroll together inside their own area, while
    the bottom group, Settings and the account row stay pinned.

  * Overview did not look like the drawing. Fixed, in the order the page draws
    them: sections are quiet caps headings with flat content instead of six
    bordered boxes; the four resource metrics sit ACROSS one row rather than
    stacked four deep; and "Hoạt động gần đây" moved from second place to the
    bottom beside the audit log, so the reading order is cost → machine →
    permissions → prices → what happened. At 1280×760 the page now reaches the
    price table on first screen; before it showed one and a half sections.

Two deliberate differences from the drawing, both because matching it would
remove information: the wireframe shows four KPI tiles where the app has five
real metrics plus the budget entry card, and it writes resources as one text
line where the app keeps the CPU/RAM gauges.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 14:25:18 +09:00
NamPDTandClaude Opus 5 b6dee044c9 feat(ui): adapt to the screen and its scaling, not to fixed pixels
Two things differ between machines and only one of them is width: a 4K panel
has more pixels, while a 125%/150% display has the same logical pixels holding
LESS, because every label and margin is taller. Breakpoints written as raw
pixels only hold on the machine they were tuned on.

  * ui_scale() derives a factor from font height (1.0 at the 15px line the
    layouts were measured against) and every narrow-guard threshold is
    multiplied by it, so panes fold when the content is cramped rather than
    when a number is crossed.
  * The window takes a share of the available screen (80% × 85%) with the old
    1180×760 as the floor, instead of opening at that size on any monitor.
  * Moving the window to another screen re-pins the assistant and re-decides
    the fold, since the new screen's work area and scaling may differ.

Found by tools/check_multi_screen.py, which walks 5 window sizes × 3 font
scales:

  * At 150%, Schedule was clipped on 1280 and 1366 screens and the window's
    own minimum grew to 1459px — wider than a 1280 laptop, so the app could
    not fit at all. The cause was not the lanes: the one-line lane-count
    summary in the header reported a sizeHint wide enough to set the minimum
    width of the entire window. It now yields first (its text stays in the
    tooltip); the window minimum drops 1459 → 752 and holds there at every
    scale.

Also: these checkers exited 0xC0000409 from a Qt teardown crash AFTER printing
their verdict. check_probes_bite decides whether a probe caught its mutation by
reading exit codes, so a crash would have counted as "caught" — the round could
have passed while proving nothing. They now flush and os._exit with the real
verdict, and round 5 still catches all six mutations.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 14:10:19 +09:00
NamPDTandClaude Opus 5 f381fd298a test(ui): five verification rounds, and two things they found
Five rounds, each looking from an angle the previous one cannot:

  1. text     — every "Thay đổi" bullet on the page vs a probe (existing)
  2. geometry — check_layout_geometry.py: reading order of the rail, section
                order down Monitoring, which side each pane is on, and the size
                relationships the design names (hero card, 26px dot)
  3. inventory— check_controls_alive.py: every control in controls.json still
                present in the built app, attributed to its owning CLASS via the
                baseline commit (a file holds several classes, so a per-file
                check reported eight dialog controls as missing)
  4. eyes     — rendered screens read against the wireframes
  5. adversarial — check_probes_bite.py: break one feature at a time and fail if
                the matching check still passes

What rounds 4 and 5 caught, which 1-3 could not:

  * Schedule showed six of seven lanes; the seventh needed a horizontal
    scroll. The design says "giữ đủ 7 lane, thu hẹp cho vừa một màn". Lane
    minimum width 190 → 150, so 7 × 150 + gaps fits a 1280 window. Round 2 now
    measures this instead of relying on someone noticing.

  * check_design_parity ALWAYS returned 0. It was a report, not a check: every
    probe in it was incapable of failing, so a regression would print on screen
    and still exit green. It now exits non-zero when anything is CHUA — which
    is what let round 5 detect the two mutations it had been sleeping through.

Also fixed in the harness itself: it rewrote line endings while restoring
mutated files (read_text/write_text translate both ways), and it compared the
tree against "clean" rather than against its own starting state.

All ten checkers green by exit code.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 13:55:47 +09:00