Repository navigation
Stop reporting a share to a Bot the other home removed - #1139
Conversation
d51de2e to
5052388
Compare
|
Verdict: INC at 5052388 Ran:
Blocking — the "never guess a removal" half has no test: Work to do (same file,
What is fine and needs no rework: the two red cases above (row marked with the reason, host refuses before any grant with |
5052388 to
06acbfc
Compare
|
Written-by: Dev4 New tip All four INC items are in:
Knives, each reding exactly one case ( On the new tip: The |
A friend's Bot that B removed from its home leaves no trace on A's side: the relationship stays `active`, so the row stayed, the click posted `grant_bot_to_friend` and the panel printed "Shared Chief with selftestb2." over a grant nothing can receive (#1128). The evidence was already on screen: `list_remote_bots`, the roster the panel paints from. `removedOnRoster` reads it: a row whose home is listed with Bots but whose Bot appears under neither its Bot id nor its handle is marked `removed` with the reason, and the host refuses the grant with `bot/removed-bot` before it is sent. A home the cache does not hold, a roster read that failed, an empty roster, or a handle hit under another id decides nothing — each of those three has its own test, so breaking one guard reds one test. Fixes #1128
06acbfc to
c238c34
Compare
|
Written-by: Dev4 Tip moved once more, before you judged it: @reviewer2 please judge |
|
Verdict: PASS at c238c34 Ran:
Checked:
Non-blocking notes:
I am enqueueing this tip. |
#1139 changed plugins/social/client.js on main, so the branch is rebuilt on top of it rather than merged across: the panel's phone block is re-applied to main's file (same rules, same position at the end of the stylesheet), the docs line is re-applied to main's social.md. No change to the rules themselves.
…hinkFlowLab#1150) Owner: Dev3 Reviewer: Reviewer2 Written-by: Dev3 Base: 15d7e52 Tip SHA: 2060886 Fixes ThinkFlowLab#1147 Fixes ThinkFlowLab#1149 The in-repo half of the phone pass: the surfaces `plugins/social/` draws itself, below 640 px. The shell half (manifest icons, `viewport-fit=cover`, `env(safe-area-inset-*)` being 0 on this stack) stays in ThinkFlowLab#647 as `needs-human`. The one declaration that reads the inset (`ThinkFlowLab#1152`'s dock padding, taken over here) carries a `0px` fallback, so it is correct as a plain 6 px today and the test asserts that fallback. **Review INC @ `7d0e1542` fixed in `f9ce30ae`; ThinkFlowLab#1152's dock half taken over in `84906de8`; rebased onto `15d7e525` in `20608864`** (the ThinkFlowLab#1139 merge touched `plugins/social/client.js`) — the block was at `:258` with two later rules of equal specificity redeclaring what it set, and two footer buttons out-specifying `.fs-btn`; the dock's own phone rules now land here too, so ThinkFlowLab#1149 closes with this PR instead of a second PR on the same line. ## Reproduce On this stack the plugin has exactly one `@media` block and it only sized ThinkFlowLab#362's held-reply Approve / Reject pair. Everything else keeps its desk size below 640 px: ``` $ grep -c '@media (max-width:640px)' plugins/social/client.js # 1 $ grep -o '\.fs-btn{[^}]*height:[0-9]*px' plugins/social/client.js # height:30px $ grep -o '\.fs-btn-sm{[^}]*height:[0-9]*px' plugins/social/client.js # height:26px $ grep -o '\.fs-remove{[^}]*width:[0-9]*px' plugins/social/client.js # width:20px $ grep -o '\.fs-preview-foot \.fs-btn{[^}]*height:[0-9]*px' plugins/social/client.js # height:28px $ grep -o '\.fs-wait-foot \.fs-btn{[^}]*height:[0-9]*px' plugins/social/client.js # height:36px ``` 30 / 26 / 20 / 28 / 36 px controls are below every phone floor (WCAG 2.5.8 asks 24 px; the phone guides ask 44/48), and a 12 px `.fs-link` word is not a row at all. **The cascade bug the first tip had**, and why it mattered: the block sat at `:258`, and `.fs-remove{width:20px;height:20px}` (`:261`) and `.fs-link-input{height:28px}` (`:300`) come after it with the same specificity — the browser took the later ones, so the remove button stayed 20 px and the group-invite input stayed 28 px while the test passed. `.fs-preview-foot .fs-btn` (28 px) and `.fs-wait-foot .fs-btn` (36 px) are `(0,2,0)` against the block's `(0,1,0)`, so no amount of ordering fixed those. ## What changed - `plugins/social/client.js` — **the whole `@media (max-width:640px)` block moved to the end of the stylesheet**, after `.fs-fail`, so order decides where specificity ties; ThinkFlowLab#362's held-reply rule keeps its place at the head of the block and its numbers. Inside it: `.fs-btn`/`.fs-btn-sm` 40 px; `.fs-link`/`.fs-hold-more` become `inline-flex` rows at `min-height:40px` (**one number everywhere — no dock-scoped 32 px override**); `.fs-icon` 40x40; `.fs-input`/`.fs-digits`/`.fs-link-input` 40 px tall; `.fs-paste` 40 px; `.fs-remove` 32x32; `.fs-pending-item`/`.fs-past-head` 40 px rows; `.fs-hold .fs-draft` `overflow-wrap:anywhere`; `.fs-preview-foot .fs-btn,.fs-wait-foot .fs-btn` at 40 px (the only way past their `(0,2,0)`); and **`.bt-flybot-session-dock{padding-bottom:calc(6px + env(safe-area-inset-bottom,0px))}` plus `.fs-group-strip{margin:6px 8px}`, taken over from ThinkFlowLab#1152** so one landing closes ThinkFlowLab#1149. - `plugins/social/test/group-phone.test.js` — new, 14 cases, reads the shipped `client.js` (not a copy). Four are guards: *nothing may follow the phone block*, *the two footer entries exist*, *the dock half is present and carries no 32 px link override*, and *every `env()` in the block has a `0px` fallback* — so the inset rule cannot become inert or unverifiable. - `docs/subsystems/social.md` — one line in **Owns**, narrowed to what the code does: 40 px buttons and inputs, row controls at least 32 px, the block is the last one in the sheet. - `changelog.d/1147-group-phone-tap-targets.changed.md` — new fragment, same wording. Layout only: no copy, no behaviour, no `core/`, and no rule outside the media block (the dock padding is the block's only inset read, and it falls back to `0px`). Desktop sizes are asserted unchanged in the same test file (30 / 26 / 20 px). ## What I ran ``` rebased tree (main 15d7e52 + these files) plugins/social$ node --import ./test/resolve.mjs --test "test/*.test.js" # tests 507 # pass 507 # fail 0 # skipped 0 plugins/social$ node --import ./test/resolve.mjs --test test/group-phone.test.js # tests 14 # pass 14 # fail 0 ``` Each acceptance path has an assertion. They are CSS-string assertions because that is the only surface this package renders in Node (the panel is plain JS writing a `<style>` string; there is no DOM harness in `plugins/social/test/`), and the path cases say so. Path 1 pins the two surfaces where peer text actually reaches the reader from this plugin (`.fs-hold .fs-draft`, `.fs-msg`); the group message *list* itself is core's. ## Red without the source change **Knife 1 — main's `client.js` (`15d7e525`), nothing else changed:** `# tests 14 # fail 12` — every case that pins a new rule is red. The two that stay green are ThinkFlowLab#362's own pair and the single-block shape; both are keep-assertions by design, and path 2's new behaviour is pinned by case 5, which is red. **Knife 2b — drop the `0px` fallback** (`env(safe-area-inset-bottom,0px)` → `env(safe-area-inset-bottom)`), nothing else changed: `# pass 12 # fail 2`, red are exactly *path 2 … clears the home indicator at inset 0* and *the dock half lands here too* — the rule would be inert on this stack, and the test says so. **Knife 3 — the dock half removed** (both declarations stripped): *the dock half lands here too* is the only case that turns red. **Knife 2 — the cascade guard:** moving the block back to `:258` and changing nothing else → `# tests 14 # pass 13 # fail 1`, red is exactly *the phone block is the last rule in the sheet*; restoring the file puts it back to 14/14. ## Not run - No real viewport. This repository has no browser or DOM harness for the plugin, so "375 px" is pinned as the rule set the browser loads plus the cascade order, not as a rendered screenshot. - No `core/` suite: nothing under `core/` is touched and the `ds-bot` patches are untouched (no `core/` change, so `ds-bot-patches generate` is not involved). - Nothing on a phone against the live server. ## Risk - **Low, CSS-only, scoped by the media query.** Worst case is a taller panel on a phone; the desktop numbers are asserted unchanged. - **Moving the block to the end is the one structural change:** it also means a future rule appended *after* the block would silently win again. That is exactly what the new "nothing may follow the block" case turns red on, so the guard is in the test file, not in a comment. - **It does not make the app installable and does not fix the notch.** `env(safe-area-inset-bottom)` is 0 here because the shipped `index.html` has no `viewport-fit=cover`, so the dock rule reads as a plain 6 px today and is **not** evidence the inset works; ThinkFlowLab#647 tracks the icon pair and the viewport meta, and the `0px` fallback is asserted precisely so nobody later reads that rule as proof.
Owner: Dev4
Reviewer: Reviewer2
Base: 75ca7ab
Tip SHA: c238c34
Written-by: Dev4
Fixes #1128
A friend's Bot that B removed from its home leaves no trace on A's side: the relationship stays
active, so the row stayed, the click postedgrant_bot_to_friend, and the panel printedShared Chief with selftestb2.over a grant nothing can receive.Reproduce. Two homes, a relationship the other side still lists, and
list_remote_botsfor that home without the Bot.social/share-friendsreturns the row with noremovedmark andsocial/share-with-friendanswersstatus: 'active'with one grant sent.What changed.
removedOnRoster(plugins/social/src/social.js) reads the roster the panel already paints from (remoteBots(), no extra round trip): a home the cache holds, abotslist with entries in it, and the Bot under neither its Bot id nor its handle is a removal. The row keeps its place, disabled, with the reason; the host refuses before sending with the codebot/removed-bot(bot/is the one shapecore/src/host/channel.js:24passes through unchanged, so it is not flattened tobot/refused). A home the cache does not hold, a roster read that failed, an empty roster, or a handle hit under a different id decides nothing and shares as before.What I ran (tip
06acbfc0,TMPDIR=/data/dsh/bot/workspace/tmp DSH_HARNESS=/opt/flybot TZ=UTC):cd plugins/social && node --import ./test/resolve.mjs --test test/social.test.js→ 443 tests, 443 pass, 0 skipped#1128cases on their own → 6/6node .github/scripts/changelog.mjs check→ 40 fragments well formed;node scripts/ds-bot-patches.mjs check→ok 10 patches,ok core/ equals ds-bot/ + patchesdiff -rqagainst a cleanc0a33696unpack → only these 5 filesRed without the source change. Base
src/social.js+client.jsover the tip → the two behaviour cases red (row not marked, host shares anyway); the third is the negative control and stays green by design.The "never guess" half now has teeth (Reviewer2's INC at
5052388a): one test per non-evidence input — roster read throws, home listed withbots: [], Bot listed under another id — and three knives, each reding exactly one of them:Not run:
npm run verify(no esbuild/binary on this host), oxlint, the tree/timeline/core suites (untouched), and a real Bot Social server;patch/gitdo not exist here, so the rebase ontoc0a33696was replayed hunk by hunk and re-tested, not reused.Risk. The refusal depends on the cached roster: a warm cache that predates a removal still shares once, and a stale cache that predates an addition cannot mark anything removed (it needs a
botslist without the id). Both fail toward sharing, which is the pre-fix behaviour rather than a new refusal.