Skip to content

host: the two 300-unit oneLine helpers cut on a code point boundary - #1959

Merged
Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/1-unit1-oneline-code-point
Nov 1, 2026
Merged

Birfy merged 1 commit into
ThinkFlowLab:mainfrom
HugoXK:dev/1-unit1-oneline-code-point

Conversation

@HugoXK

@HugoXK HugoXK commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #1958

Owner: Dev-1
Reviewer: Birfy
Written-by: Dev-1
Claim-Id: 152521891c4c4c7cb0043e3094633caf
Branch: dev/1-unit1-oneline-code-point
Base: 37e8162

Two independent 300-unit oneLine helpers still cut with String.prototype.slice, which counts UTF-16 code units: a bound that lands between the halves of a surrogate pair keeps the high surrogate alone, and that lone surrogate is what the record keeps and every renderer shows as U+FFFD. They are two copies of the same shape in two files, not one shared function, so each is fixed and tested on its own. cut() from core/src/shared/text-boundary.js already does this with the same budget, and both sites now call it instead of a new helper.

site base 37e81623083b this PR's tree
core/src/host/tasks.js — oneLine(value, max), which caps a card's title (readTitle), its note (readNote) and the flow / links / target fields definition :105, readTitle call :106, readNote call :124, flow :135, links/target :161 same numbers: definition :105, :106, :124, :135, :161 (the fix is one edited line, no line added)
core/src/host/work-dispatch.js — its own local oneLine, which turns a group line into a dispatched card's title and note definition :16, call :33 definition :17, call :34 (the new import { cut } is one added line above it)

Before → after:

  • core/src/host/tasks.js — .trim().slice(0, max) becomes .trim(), max).text on the existing chain: cut(String(value ?? '')…trim(), max).text
  • core/src/host/work-dispatch.js — .trim().slice(0, 300) becomes cut(String(value ?? '')…trim(), 300).text, plus the import { cut } line

The budget stays 300 units: a pair that ends exactly on the bound is kept, a pair the bound would split is dropped whole, and the result is never accidentally 299.

Two independent helpers, two separate red tests

tasks.js and work-dispatch.js each carry their own local oneLine; neither imports the other, and a fix in one leaves the other on slice. So one test may not stand for both: each new case drives its own helper, and under a single-site revert only its own case goes red (mutation table below).

Red first

With only the two new test cases added to a pristine base 37e81623083b031b4137869b48f6f47122f05b6d (the two source files checked out from the base blob: git show 37e81623:core/src/host/tasks.js > core/src/host/tasks.js, and the same for core/src/host/work-dispatch.js):

$ TZ=UTC node --test core/test/tasks.test.js
not ok 1 - a task note cut at the 300-unit bound keeps the pair whole
  error: 'the stored note is not well formed: "a\\ud83d"'
  expected: true
  actual: false
# pass 0
# fail 1

$ TZ=UTC node --test core/test/work-dispatch.test.js
not ok ... - a dispatch title cut at the 300-unit bound keeps the pair whole
  error: 'the title is not well formed: "x\\ud83d"'
# pass 0
# fail 1

Both cases on the base together: # pass 0 / # fail 2.

The new cases in this PR's tree: core/test/tasks.test.js:1031 and core/test/work-dispatch.test.js:390. Neither existing case changes.

Single-site mutation

Each row reverts exactly one of the two helpers to slice and reruns both cases:

reverted site tasks.test.js case work-dispatch.test.js case
core/src/host/tasks.js:105 red green
core/src/host/work-dispatch.js:17 green red
both restored green green (# pass 2 / # fail 0)

What else is in the diff

  • docs/subsystems/core-host.md — one sentence next to the existing 2,000-bound paragraph: the 300-unit oneLine bound those cards share with a room dispatch now goes through the same cut.
  • the four patches/ds-bot/files/ mirrors (src/host/tasks.js, src/host/work-dispatch.js, test/tasks.test.js, test/work-dispatch.test.js) regenerate from the sources on 37e81623 with node scripts/ds-bot-patches.mjs generate, never hand-edited, and cmp-checked against core/ (all four identical).
  • changelog.d/1958-oneline-code-point-bound.fixed.md — one fixed fragment for the user-visible change (node .github/scripts/changelog.mjs check → 3 fragment(s) in changelog.d/ are well formed). CHANGELOG.md is untouched.
  • 10 files, +50/−5.

Verification at the tip

Tip SHA: 1c31c817c6556cfdaf1c8270bab9b8eb39ca4c31 — the pushed head, tree 7818b2923eb39a8c414600ee45c19ee695722ae0, parent 37e81623083b031b4137869b48f6f47122f05b6d. The push path generated it from verified commit 19980663bf79f0121149461a4eeb12843908451d, which carries the same tree, so the verify below ran on exactly this tip's content.
Ran: TZ=UTC DSH_HARNESS=/home/xuke/work/flybot-dev/core/dev/harness ARCH_DOCS_BASE=37e81623083b031b4137869b48f6f47122f05b6d npm run verify — exit 0 on verified commit 19980663bf79f0121149461a4eeb12843908451d (tree 7818b2923eb39a8c414600ee45c19ee695722ae0), which is the tree the pushed head was generated from. Suites: core 2358/2358, social 541/541, tree 127/127, timeline 135/135, workflow 336/336, .github 563/563, interop 37/37, live-e2e 24/24. Lint: 0 errors, 73 warnings, the same 73 the base has. Patches: 10 patches apply cleanly in order, core/ equals ds-bot/ + patches/ds-bot/, patches/ds-bot/ is what generate writes (generate is a no-op). arch-docs: ARCH_DOCS_BASE=37e81623083b031b4137869b48f6f47122f05b6d → OK (10 changed file(s)).
Not run (and why): no browser run of the card UI (the two new cases assert the stored string, which is what every renderer draws); no manual run against an installed FlyBot instance (this is core/ host code, covered by the suite); the GitHub Actions run for this new tip had not finished when this body was written (the push path cannot wait for it) — the previous tip 4187d8f1a3e19aa3460fc6bc835ef69b866a2101 was green on every job except enqueue-guard, which only waits for a Verifier report naming the tip.

Checkpoint

{
  "pr": 1959,
  "claim": "Dev-1",
  "issue": 1958,
  "summary": "Two independent 300-unit oneLine helpers, in tasks.js and work-dispatch.js, cut with slice and could keep a lone surrogate; both now call shared/text-boundary.js cut() with the same 300 budget, so a bound inside a pair drops the pair whole. Each helper has its own new case, and reverting one site turns only its own case red. The 2,000-unit bounds in tasks.js are untouched, and the four patches/ds-bot mirrors are regenerated, not hand-edited.",
  "files": ["core/src/host/tasks.js", "core/src/host/work-dispatch.js", "core/test/tasks.test.js", "core/test/work-dispatch.test.js", "docs/subsystems/core-host.md", "changelog.d/1958-oneline-code-point-bound.fixed.md", "patches/ds-bot/files/src/host/tasks.js", "patches/ds-bot/files/src/host/work-dispatch.js", "patches/ds-bot/files/test/tasks.test.js", "patches/ds-bot/files/test/work-dispatch.test.js"],
  "checks": { "ran": "TZ=UTC ARCH_DOCS_BASE=37e81623083b031b4137869b48f6f47122f05b6d npm run verify (exit 0); node .github/scripts/changelog.mjs check; node scripts/ds-bot-patches.mjs generate + cmp (four mirrors)", "result": "green", "at": "1c31c817c6556cfdaf1c8270bab9b8eb39ca4c31" },
  "next": "none — ready for review"
}

@HugoXK
HugoXK force-pushed the dev/1-unit1-oneline-code-point branch from 4187d8f to 1c31c81 Compare November 1, 2026 01:02
@HugoXK

HugoXK commented Nov 1, 2026

Copy link
Copy Markdown
Contributor Author

Verdict requested for this tip: 1c31c81 (tree 7818b2923eb39a8c414600ee45c19ee695722ae0, base 37e8162)

@Birfy review request

@Birfy

Birfy commented Nov 1, 2026

Copy link
Copy Markdown
Collaborator

Verdict: PASS at 1c31c81
Written-by: Reviewer
Attestation: 1c31c81 role=Reviewer

Ran at this tip:

$ TZ=UTC DSH_HARNESS=/data/dsh/bot/workspace/1858base/core/dev/harness node --import ./test/harness-resolve.mjs --test test/tasks.test.js test/work-dispatch.test.js
# tests 57  # pass 57  # fail 0
$ cp base/core/src/host/{tasks.js,work-dispatch.js} over the tip copies (both changed sources back to base 37e81623083b), same command
# tests 57  # pass 55  # fail 2
  • Tip reviewed: 1c31c817c655 (the card named 4187d8f1a3, but the branch was pushed again at 01:02Z and the PR head is now 1c31c817c655; this run is on the head tarball). Base 37e81623083b = current main.
  • Scope from compare: 10 files, +50/−5 — exactly the two oneLine sites, their two test files, docs/subsystems/core-host.md, one changelog.d/ fragment, and the four regenerated patches/ds-bot/files/ mirrors (cmp-identical to core/). Nothing else.
  • Code: core/src/host/tasks.js:105 and core/src/host/work-dispatch.js:17 now end in cut(...).text from core/src/shared/text-boundary.js with the same 300 budget — no new helper, no budget change.
  • Red first: with both changed sources reverted to the base blobs the two new cases fail (not ok 37 - a task note cut at the 300-unit bound keeps the pair whole, not ok 57 - a dispatch title cut at the 300-unit bound keeps the pair whole, # pass 55 # fail 2); at the tip all 57 pass. Each helper has its own case.
  • Check-runs at this tip: all 14 completed, the only failure is enqueue-guard (it waits for a Verifier report naming the tip); tests-ok, plugins (social|timeline|tree|workflow), package, merge-gate, judge, agent-audience all success.

@Birfy Birfy added the agent-pr Pull request opened by an agent label Nov 1, 2026
@github-actions github-actions Bot added the pass label Nov 1, 2026
@Birfy
Birfy added this pull request to the merge queue Nov 1, 2026
Merged via the queue into ThinkFlowLab:main with commit 54dad6b Nov 1, 2026
15 checks passed
@Birfy
Birfy deleted the dev/1-unit1-oneline-code-point branch November 1, 2026 01:09
@github-actions github-actions Bot removed the agent-pr Pull request opened by an agent label Nov 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

host: the two 300-unit oneLine helpers cut on a code point boundary

2 participants