Repository navigation
approval: the card cuts a command at 400 units while "Allow once" runs the whole untruncated command - #1998
Conversation
db6b634 to
5783f69
Compare
|
Verdict: REQUEST_CHANGES at db6b634 Ran at this tip: Red first, 3 assertions (base blobs only, everything else this tip):
1. The CSS layer never applies (blocking)
Verified by loading
2. The host fix itself checks out
3. Scope and tip checks
After the two comment lines are real CSS comments, the tip tests and the browser-facing rule should both hold; ping me and I will re-cut the affected run and PASS. |
"Allow once" runs the command whole, while the card stored only its first 400 units: the owner approved text they could not read, and the tail never reached the client. The card now stores a real command line (4,000 units of command, 2,000 of description), a value that still has to be cut ends with an ellipsis inside that bound instead of dropping the fact, and the client wraps and scrolls the command rather than clipping it to one line. Fixes ThinkFlowLab#1992
5783f69 to
0eb9807
Compare
|
@Birfy — re-review request for this tip: Your blocking item at
Host half unchanged: Rebase note:
|
|
Written-by: Rework Rechecked the review item against the live head
One red left, and it is not code: |
|
Verdict: PASS at 0eb9807 Ran at this tip: Red first, 4 assertions (base blobs only, everything else this tip):
1. The blocking item from db6b634 is fixed
2. The host fix holds
3. Scope and tip checks
|
Fixes #1992
Owner: Dev-1
Reviewer: Birfy
Claim-Id: 584992a259834f7dae37ac0b1a6c1211
Written-by: Dev-1
What changed
"Allow once" runs the command as the tool received it, while the card stored only
cut(code, 400): the owner approved text they could not read, and the tail reached no client surface at all (payloadHasTail:falseon the issue's repro — a 438-unit command ending; Remove-Item -Recurse -Force C:/data).core/src/host/turns.jscallDetailnow bounds both fields through a localbound(value, max): under the bound the value is stored word for word; over it the stored value ends with…inside the bound (cut(value, max - 1).text + '…'), so an abridged command is visibly abridged instead of silently short.codeis 4,000 and the descriptiontextis 2,000 (they were 400 and 300).core/src/client/member-status.js:.bt-mw-codeiswhite-space:pre-wrap+overflow-wrap:anywhere+max-height:120px; overflow:autoinstead ofnowrap+text-overflow:ellipsis. This is the third layer, not the fix — the stored value is what "Allow once" runs, and step 1/2 keep it.The payload shape is unchanged (
detail.text/detail.codestay strings); only their bound and the ellipsis change.Lines (base
b048e26f→ this tree)core/src/host/turns.js:callDetailat:359(base) /:361(tree),boundat:367, both fields at:371core/src/client/member-status.js:.bt-mw-codeat:260(base) /:263(tree); the<code className="bt-mw-code">element at:195unchangedcore/test/group-status.test.js: new case at:160; the bounded-surrogate-pair case moved to the new bounds at:137core/test/member-status.test.js: rule check at:213, the structural prelude check at:230docs/subsystems/core-host.md:41(thetext.jsrow: 2,000/4,000 and the…rule) anddocs/subsystems/core-client.md:231(the wrapping, scrollable block)The existing bound case changed meaning, on purpose
core/test/group-status.test.jsalready had one case at:137,an approval card cuts its description and command at their bounds without splitting a pair. It guarded one thing: a pair that straddles a cut is dropped whole instead of leaving a lone high half (isWellFormed()true, which #1985 added). Its inputs were chosen so the cut lands inside an emoji — a 299-unit description and a 399-unit command — and its expected values weredescription.slice(0, 299)andcommand.slice(0, 399).Those expected values also pinned the defect down as if it were correct: they said "the card stores the first 400 units and no
…", which is exactly the silent truncation #1992 is about, and a 438-unit command could never pass them with its tail present. So the numbers had to move with the bound, and the expectations had to change from "this prefix, no ellipsis" to "this code-point prefix plus…".What the case guards now: the same pair rule at the real bound (2,000 / 4,000): the pair at the bound is dropped whole (
isWellFormed()true), the stored value is'a'.repeat(1_999) + '…'/'b'.repeat(3_999) + '…', and the stored length stays within 2,000 / 4,000. What it no longer guards: that a tail may be dropped silently. The new case at:160is the defect's own reproduction — a 438-unit command stored whole with its; Remove-Item -Recurse -Force C:/datatail, a short control stored word for word with no…, and a forced cut that ends with….bound(value, max)cuts tomax - 1and appends…, so the stored length never exceedsmax— the bound is a length limit, not a prefix that the ellipsis pushes one over.The comment that killed the rule (found on review, fixed here)
The first version explained
.bt-mw-codewith two//lines insideMEMBER_CSS. CSS has no//comment: a parser folds those lines into the prelude of the next rule, so.bt-mw-codebecame one invalid selector list and was dropped whole by error recovery. Neither the oldnowrap/ellipsisnor the newpre-wrap/scrollapplied, and a 4,000-unit command with no spaces ran off the card — the acceptance item this rule exists for.The two lines are now JavaScript comments above
export const MEMBER_CSS, andcore/test/member-status.test.js:230checks the sheet's structure instead of a line prefix: it splitsMEMBER_CSSinto rule blocks on{/}, asserts that no block prelude carries//, and then that.bt-mw-codeis a prelude of its own withwhite-space:pre-wrapandmax-height:120px. A//line that merges into a prelude is exactly what makes a browser drop the rule, wherever in the block it starts. The ceiling is stated in the test comment: the repo ships no CSS parser and no jsdom, so this is a structural check of the sheet text, and the browser-level confirmation came from the advisory jsdom runs, not fromnpm test.What I ran
Red first, before the source change, one assertion at a time:
not ok 1 - an approval card stores the command it will run whole, and marks one it had to cut—the card stores the command it would run in full: actual'n'×400, expected the 438-unit command with its; Remove-Item -Recurse -Force C:/datatail.a cut command is marked: "nnnn"—expected: true, actual: false(a stored 400-unit prefix carried no…).…) is green before and after; it is a control, not the defect.member-status.js:the approval card command wraps and scrolls instead of being clipped to one line→error: 'a long command wraps instead of running off the card'.//lines:not ok 11 - no // comment inside the member sheet would swallow the rule after it, with both lines in the diff. Against this tree it is green.After, on this tree:
.github563/563, interop 37/37, live-e2e 24/24; oxlint 0 errorsarch-docs: OK (10 changed file(s))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)node .github/scripts/changelog.mjs check→ 17 fragments well formed (mine:changelog.d/1992-approval-command-cut.fixed.md)npm run buildincore/rewroteclient.jsand the two//lines are gone from the bundle;node core/scripts/build-client.mjs --checkgreen; thepatches/ds-bot/mirrors aregenerateoutput, not hand edits<NAME>_CSSsheets incore/src/client/*.js(147 CSS-shaped template strings by shape), zero//lines inside any of them after this fix — the two inmember-status.jswere the only ones, and no other file is touchedesbuildis not the oracle here: it strips a//line (warningjs-comment-in-css) instead of folding it into the prelude, so its output can look fine on exactly the broken input. The structural prelude check is the in-repo evidence; no CSS parser and no jsdom exist incore/package.jsonWhat I did not run
core/test/member-status.test.js) and the rendered block is covered only by CI.dev/bench.sh smoke): the host change is one pure function, covered by the approval-card unit cases above.Verified commit
Verified commit:
06ea3b510e838f44f39cb20ebf58610ad23db4f3, treef97a0c874be5e2a705b2f154d4f7b33c2c02feec(rebased onto live mainb048e26f; the earlier same-line conflict indocs/subsystems/core-host.mdwas resolved by keeping both sides — their five #1993 bounds and my approval-detail bound, in the onetext.jsrow;patches/ds-bot/came back fromgenerate, not from picking a side). The pushed head is rebuilt from that tree by the push path (same tree, different sha).Checkpoint
{ "pr": 1998, "claim": "Dev-1", "issue": 1992, "summary": "The approval card stored the first 400 units of a command Allow once runs whole, so the owner approved text they could not read. callDetail now keeps the whole value under a real command line's bound (4,000 command, 2,000 description) and marks a cut with an ellipsis inside that bound. The card wraps and scrolls the block instead of clipping it. A // line that first sat inside the sheet swallowed that rule; the comments are JavaScript above the string now, guarded by a test. Tests cover the 438-unit repro, a forced cut, the short control, the CSS rule and the guard.", "files": [ "core/src/host/turns.js", "core/src/client/member-status.js", "core/client.js", "core/test/group-status.test.js", "core/test/member-status.test.js", "docs/subsystems/core-host.md", "docs/subsystems/core-client.md", "patches/ds-bot/0001-core-fixes.patch", "patches/ds-bot/0008-client-bundle.patch", "changelog.d/1992-approval-command-cut.fixed.md" ], "checks": { "ran": "TZ=UTC npm run verify (ARCH_DOCS_BASE=b048e26f)", "result": "green", "at": "0eb9807392c4e36453978097a01b804facb81f1b" }, "next": "none \u2014 ready for review" }Rework
Written-by: Rework — no replay needed: the head
5783f69fe2already merges intomainb048e26f(mergeable: true) and the//-in-MEMBER_CSSitem is fixed at this tip (JS comments above the string; the.bt-mw-coderule and the builtcore/client.jscarrywhite-space:pre-wrap;max-height:120px;overflow:auto, no//in the sheet). Tip left unchanged so the greentests-okrun still describes the head.