fix(fleet): cap published doing/status text to the measured card-fit budget - #8
Merged
Merged
Conversation
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.
…int-safe truncation
brchue-ux
force-pushed
the
fm/fleet-doing-summary-quality
branch
from
August 8, 2026 01:26
a649ac6 to
d081bc5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Changed
FM_DOING_CHAR_CAP(59 chars, sourced from measured card-fit data) and a bashfm_doing_truncatehelper inbin/fm-classify-lib.shthat 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.doing_trunc($n)helper inbin/fm-fleet-snapshot.shandbin/fm-bearings-snapshot.sh, replacing the previous flattrunc(90|120)calls ondoing/status-detail fields so JSON-path output truncates identically to the bash path.fm-fleet-snapshot.sh'screw_state_jsonto run detail text throughfm_doing_truncatebefore emitting it, and addedtests/fm-doing-cap.test.shcovering both the bash truncation behavior and end-to-endfm-fleet-snapshot.sh --jsoncapping.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-8inside 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 twindoing_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 intojq -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.