Skip to content

Release v1.9.0: net/disk mirrored chart sections - #61

Merged
binlecode merged 1 commit into
mainfrom
release-v1.9.0
Aug 13, 2026
Merged

binlecode merged 1 commit into
mainfrom
release-v1.9.0

Conversation

@binlecode

Copy link
Copy Markdown
Owner

Summary

Net and disk I/O rates shipped in 1.8.0 as two plain text rows tacked onto the bottom of the Memory box — the only telemetry in the dashboard with no history rendering, and mis-filed (network throughput is not a memory metric). They now own two sibling sections, each drawing a mirrored in-over-out chart pair whose seam reads as a shared zero axis (btop/vnstat convention).

╭─ Network ─────────────────────────────╮╭─ Disk ────────────────────────────────╮
│ ↓ In 29.8 KB/s   avg 5.5 · max 29.8   ││ ↓ Read 6.2 MB/s   avg 782 KB · max 6.2│
│ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀  ││ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀  │
│ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⢀  ││ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸  │  ← up-trace anchored at the seam
│ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠃⠀⠁⠈  ││ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠁⠹⠸  │  ← down-trace hanging from it
│ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀  ││ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀  │
│ ↑ Out 40.4 KB/s  avg 33.1 · max 186.4 ││ ↑ Write 3.2 MB/s  avg 875 KB · max 3.2│
╰───────────────────────────────────────╯╰───────────────────────────────────────╯

Six content rows — identical height to two separate label+chart stacks, and each direction keeps its own avg · max. No axis row is drawn: the seam is the axis.

Behavior change

  • Grid gains a third paired row (Network | Disk); Power keeps its full-width span beneath. Each section hides itself entirely when the platform reports no counters, so Power closes the gap on a machine without them.
  • Charts are always auto-scaled. There is no SoC reference throughput for a NIC or NVMe controller, so --power-scale profile has no analogue here. New L2 helper analytics.io_rate_percent() divides by max(floor, rolling_peak x1.25), reusing the multiplier --power-scale auto already uses. Both directions of a box share one denominator, so an upload trickle never renders as tall as a saturating download.
  • New floors NET_RATE_FLOOR_BPS (1 MB/s) and DISK_RATE_FLOOR_BPS (10 MB/s) stop idle background chatter (mDNS keepalives, APFS journaling) from dividing by itself and painting a full-scale chart.
  • BrailleChart gains fill. down anchors the trace at the top edge via a second cumulative bit table — exact in dots; in block the downward half quantizes to 2 levels/row, since Block Elements ships only ▀/█ as upper fills and the quarter-blocks at U+1FB82/U+1FB85 are missing from many terminal fonts. A coarser trace that always draws beats a finer one that renders as tofu.
  • No alert threshold added — neither bus has a knowable ceiling to saturate against, so AlertEngine is untouched.
  • Export output is unchanged. Presentation only; --json / --serve fields are identical.
  • Cover page: version badge and footer (both carried a doubled v — vv1.7.0), plus a net/disk feature card.

Tested

Ventura-era macOS 15 (Darwin 25.5.0) + Apple M4 Max (4E+12P+40GPU).

.venv/bin/python -m ruff check --fix . && .venv/bin/python -m ruff format .
.venv/bin/python -m actop.actop --help
.venv/bin/pytest -q          # 149 passed

Rendered live against real hardware at 130x46 (grid, 4 rows, paired boxes bottom-aligned) and 88x44 (grid correctly auto-degrading to scrolling stack under the 96-col threshold). Both I/O sections populate from live counters; the floors visibly damp idle chatter as designed.

Tests

Three new functional tests, all driving public surfaces:

  • test_down_fill_hangs_the_trace_from_the_top_edge — a partial reading fills the top rows in down mode and the bottom rows in up. Catches the mirror silently inverting into two identical traces with a gap down the middle; nothing else looks at fill direction.
  • test_down_fill_block_mode_uses_upper_block_glyphs — pins the ▀/█ ramp so a future move to the legacy-computing quarter-blocks has to be deliberate rather than a silent tofu regression.
  • test_io_rate_percent_floor_keeps_idle_chatter_off_full_scale — the noise-amplification failure the floors exist to prevent.

test_net_disk_sections_show_rates_and_scaled_charts_when_available now drives two samples and asserts the chart carries percents against the shared peak-based denominator (80% → 20%), catching a chart wired to the native-unit deque instead of the percent deque.

Docs

docs/SPEC-system.md §6.1 (grid row composition), §6.2 (fill direction + block tradeoff), §6.5 (rewritten for the mirror, including the asymmetric-availability behavior); CLAUDE.md module table and data-flow paragraph (five → seven sections); help overlay metric labels and grid description; CHANGELOG.md; docs/ROADMAP.md N2.

🤖 Generated with Claude Code

Promote the net/disk I/O rates out of the Memory box into their own
Network and Disk sections, each drawing a mirrored in-over-out chart
pair sharing an implicit zero axis at the seam.

- analytics: io_rate_percent() + NET/DISK_RATE_FLOOR_BPS. Charts are
  always auto-scaled (no SoC reference throughput exists for a NIC or
  NVMe controller); both directions of a box share one rolling-peak
  denominator so the traces stay comparable, floored so idle chatter
  does not paint full scale.
- BrailleChart: fill="down" renders a top-anchored mirror via a second
  cumulative bit table. Exact in dots mode; block mode quantizes to
  2 levels/row, since Block Elements ships only the half and full upper
  fills and the U+1FB82/U+1FB85 quarter-blocks are missing from many
  terminal fonts.
- Each direction carries its own avg/max, replacing the combined suffix.
- Sections hide themselves when the platform reports no counters.
- Cover page: version badge and footer (both had a doubled "v"), plus a
  net/disk feature card.

Export output is unchanged — presentation only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@binlecode
binlecode merged commit 046394f into main Aug 13, 2026
5 checks passed
@binlecode
binlecode deleted the release-v1.9.0 branch August 13, 2026 00:06
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