Skip to content

fix(fleet): cap published doing/status text to the measured card-fit budget - #8

Merged
brchue-ux merged 3 commits into
mainfrom
fm/fleet-doing-summary-quality
Aug 8, 2026
Merged

fix(fleet): cap published doing/status text to the measured card-fit budget#8
brchue-ux merged 3 commits into
mainfrom
fm/fleet-doing-summary-quality

Conversation

@brchue-ux

@brchue-ux brchue-ux commented Aug 7, 2026

Copy link
Copy Markdown
Owner

What Changed

  • Added a shared FM_DOING_CHAR_CAP (59 chars, sourced from measured card-fit data) and a bash fm_doing_truncate helper in bin/fm-classify-lib.sh that collapses whitespace and truncates at a word boundary (falling back to a hard cut only when the boundary would drop more than 40% of the budget), pinned to a UTF-8 locale so multi-byte characters truncate at codepoint boundaries rather than mid-character.
  • Added a matching jq doing_trunc($n) helper in bin/fm-fleet-snapshot.sh and bin/fm-bearings-snapshot.sh, replacing the previous flat trunc(90|120) calls on doing/status-detail fields so JSON-path output truncates identically to the bash path.
  • Wired fm-fleet-snapshot.sh's crew_state_json to run detail text through fm_doing_truncate before emitting it, and added tests/fm-doing-cap.test.sh covering both the bash truncation behavior and end-to-end fm-fleet-snapshot.sh --json capping.

Risk Assessment

✅ Low: The only prior finding (locale-dependent byte-vs-codepoint truncation mismatch between the bash and jq twins) is now fixed by pinning local LC_ALL=C.UTF-8 inside fm_doing_truncate; verified by re-running bash and jq truncation on multi-byte UTF-8 text (including under an ambient LANG=C/LC_ALL=C shell) and confirming byte-identical, codepoint-safe output, with no shellcheck/syntax regressions and no other changes since the prior round.

Testing

Targeted tests for the doing/status-text card-fit cap all pass, and a manual locale-independence check confirms the second commit's UTF-8 pin actually fixes a real multibyte-splitting bug rather than being a no-op change; no issues found.

Pipeline

Updates from git push no-mistakes

⏭️ **intent** - skipped

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 1 issue found → auto-fixed ✅
  • ⚠️ bin/fm-classify-lib.sh:436 - fm_doing_truncate (bin/fm-classify-lib.sh, new function) uses ${#collapsed} and ${collapsed:0:cap} without pinning a UTF-8 locale, so length/substring are locale-dependent: in a non-UTF-8 locale (e.g. LANG=C, common in minimal cron/container environments) bash counts and slices by byte, not codepoint, while the jq twin doing_trunc (used in bin/fm-fleet-snapshot.sh and bin/fm-bearings-snapshot.sh) always operates on Unicode codepoints. If a status/doing string contains any multi-byte UTF-8 character near the cap boundary, the bash path can slice mid-character, producing invalid UTF-8 that is then fed into jq -n --arg detail "$detail" — which can fail or corrupt the surrounding JSON — while the jq-side callers of the same field would truncate cleanly. This diverges from the file's own stated goal of keeping the three implementations in sync (see the comment on fm_doing_truncate).

🔧 Fix: Pin fm_doing_truncate to UTF-8 locale for codepoint-safe truncation
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • bash tests/fm-doing-cap.test.sh (7/7 pass: fm_doing_truncate direct behavior + fm-fleet-snapshot.sh --json end-to-end capping)
  • bash tests/fm-bearings-snapshot.test.sh (full existing suite, all pass — confirms jq doing_trunc in fm-bearings-snapshot.sh didn't regress prior expectations)
  • Manual repro: fm_doing_truncate on a 70-char multibyte (é) string under LC_ALL=C — pre-fix code produced invalid UTF-8 (split codepoint at byte 58), post-fix code (with local LC_ALL=C.UTF-8) produced valid UTF-8 output
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

Bchue added 2 commits August 7, 2026 18:08
…budget

Firstmate published a worker's current-state detail (the "doing" text
surfaced by fm-fleet-snapshot.sh and fm-bearings-snapshot.sh) with no length
discipline at the source and only ad hoc, ungrounded jq trunc() ceilings
downstream, leaving a rendering surface to elide text that was simply
written too long.

Add FM_DOING_CHAR_CAP (59 chars) to bin/fm-classify-lib.sh, sourced from
data/herdr-card-iteration-2/report.md's measured fit ladder: at 11.5px
Medium 500, all ten sampled real doing strings fit their card column with
zero elision, and the longest is 59 characters. Enforce it at the true
publish point (fm-fleet-snapshot.sh's crew_state_json) with a word-boundary-
aware bash truncation (fm_doing_truncate), and apply the same budget via a
matching jq helper (doing_trunc) at every downstream doing field in
fm-fleet-snapshot.sh and fm-bearings-snapshot.sh so nothing re-lengthens it.
@brchue-ux
brchue-ux force-pushed the fm/fleet-doing-summary-quality branch from a649ac6 to d081bc5 Compare August 8, 2026 01:26
@brchue-ux
brchue-ux merged commit 198388f into main Aug 8, 2026
10 checks passed
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