Repository navigation
Mark a Bot unread for a friend's line, say who is talking on first contact, and list per-Bot friendships - #432
Merged
Conversation
…hinkFlowLab#420) A friend's line lands in the receiving Bot's own chat (social.md invariant 8), so DSH's completion mark did not flag it. The host now stamps the Bot with friendLineAt and the first line from a sender with remote.firstContact; the client marks the Bot unread when a newer stamp arrives while its chat is not open, and shows a quiet first-contact line. social/overview asks the home and every member identity, so per-Bot friendships and requests are listed.
…nread # Conflicts: # patches/ds-bot/0003-flybot-api-client.patch # patches/ds-bot/0008-client-bundle.patch
Collaborator
Author
Self-review (Birfy, owner's Bot)I read the full diff at the tip, including the merge of main Findings:
Verdict: PASS |
This was referenced Oct 19, 2026
Merged
Birfy
added a commit
to Birfy/FlyBot
that referenced
this pull request
Oct 20, 2026
…inboxes fast while a window is on screen (ThinkFlowLab#505) Fixes ThinkFlowLab#497 **Root cause.** Nothing on FlyBot's live path regressed since ThinkFlowLab#432. On a two-home bench at main `a7adfe0` (local Bot Social + mock model, browser on A's Chief chat), B's first line, the held reply's **Waiting for approval** card, the Inbox count and the badge all show without a reload. They just show late: the social plugin reads a Bot's Bot Social inbox only on its idle timer (`inboxPollMs`, 15 s), and the card also waits for the model's reply. ThinkFlowLab#432 never fixed acceptance item 1; its PR said it found no cause and pointed at the 15 s poll. The self-test logs match: B sent at 12:39:26, A delivered at 12:39:34 (+8.5 s), and the card arrived at 12:39:41 (+15 s). Someone watching for about 8 s sees nothing and then reloads. **What changes** - Client (`index.js`): the roster poll sends `watching: !document.hidden` with each `state` call. - Host (`channel.js`, `hooks.js`): `state` notes when a window on screen last read the team. A hidden window does not count; an older client that sends nothing does. That is `rt.watched()` (8 s), offered to plugins as `flybot.watched()`. Process-local, nothing saved. - Social (`social.js`): while a window watches, a second timer reads the inbox at the live cadence (`facePollMs`, 4 s). It skips ticks the shared timer already covers (a live face room) and ticks within half a period of the last read. With no window open nothing changes (15 s). - Docs: core-host, core-client, plugin-runtime, social. Changelog fragment. **Measured on the two-home bench** (B sends, until the line is in A's open Chief chat, 5 lines each): main 7.7–12.5 s, this branch 1.3–3.1 s. The card and the Inbox count follow on the same host revision, after the mock model's reply. **Tests** - `core/test/flybot.test.js` ThinkFlowLab#497: a window that keeps polling with `since` gets the friend's first line (`friendLineAt`), then the held reply (`pendingCount` 1, `heldReplies` pending on the turn it answers), with no reload. Also `flybot.watched()`: hidden does not count, it expires after 8 s, and an older client counts. The second test fails on main. - `plugins/social/test/social.test.js` ThinkFlowLab#497: with no window the live timer reads nothing. With a window, B's first line is delivered on the first 4 s tick. Once the window is gone it stops. Fails on main. Ran: `ARCH_DOCS_BASE=origin/main TZ=UTC npm run verify` at the tip, passes (arch-docs OK; plugin lint OK; core 1079, social 297, tree 80, timeline 83, scripts 93, interop 37, live-e2e 16; 0 failures). Two-home live bench (local Bot Social at 6a97ba0, mock model, headless and headful Chrome) before and after. Not run: prod Bot Social, real model, the Mac instances, the Desktop app, smoke bench. Risk tier: T2 (estimate; the controller sets the label) Co-authored-by: Birfy <15378933+Birfy@users.noreply.github.com>
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.
Fixes #420
A friend's line in one of my Bots' own chats no longer slips by unnoticed, and
social/overviewlists per-Bot friendships. This follows the owner-delegated decision on the issue: a grantee's lines stay in the Bot's own chat (social.md invariant 8), there is no thread per person, and a friend with no Bot shared to me gets no row.What changes
delivery.js): a friend's line that reaches a Bot's own chat setsfriendLineAton that Bot. The stamp goes out with the roster, and the save moves the revision so open windows read it. The host also remembers which senders it has seen per Bot (state.remoteContacts, host only, capped at 200, removed when the Bot is deleted). A sender's first line carriessource.remote.firstContact. Group lines, refused sends and re-deliveries (deferred / resumed / retried / resent) leave no stamp.friend-lines.js,index.js): the browser saves the last stamp it showed for each Bot (ds-bot:friend-lines). When a newer stamp arrives and that Bot's chat is not open, the Bot is marked unread the same way Mark as Unread does. The row shows the blue dot until the chat is opened, and this also works when the line came while FlyBot was closed. Stamps are compared only with stamps, not with the browser's clock. A browser with no saved record treats what is already there as seen. Another member's shared Bot and a friend's Bot chat are skipped. The Main Bot tile now shows the same dot (before, a tile showed no unread mark at all).cells.jsFirstContact): a sender's first line gets one muted line above it, e.g.SelfB1238 is talking to Chief through Bot Social. It names the person for a typed line andBot (owner)for a Bot's line. zh copy added.friendsOverview): it askslist_friendsfor the home and for every active member identity (assetAutoAcceptalready does) and lists each relationship once. A row found through a member carriesbotId/botName. Pending requests come in the same way, so Add friend shows per-Bot requests. If one member can't be read, only that member's rows are missing; if the home read fails, the call still fails.Live first line (acceptance item 1): I could not find a FlyBot-side cause in the code for "the first line only showed after a reload", and I could not reproduce it without two live homes. Delivery goes through the same
agent.followuppath as lines 2 to 5, which did show live. Inbox polling is 15 s and the line showed after about 25 s, so the reload may just have happened right after the line arrived. If the next self-test still sees it, it needs its own issue with a timed repro.Not in this PR: #275 (the NEW divider stays during the visit). The divider uses the per-visit
seen/enteredclock, while this change uses its own stamp, so a fix for #275 does not come out of this one.Tests:
core/test/friend-lines.test.js(marking, seen live, no record, remote/other member skipped),core/test/flybot.test.js#420 (stamp, revision, first contact once per sender, contacts not in view),core/test/inbound-ui.test.js#420 (first-contact line for person and Bot), social #420 overview (per-Bot friendship + request, dedupe, home + member asked once each, failed member read).Ran:
ARCH_DOCS_BASE=origin/main TZ=UTC npm run verifyat the tip, passes (arch-docs OK; core, social, tree, timeline, scripts, interop, live-e2e all 0 failures).Not run: smoke bench, two-home live run against prod Bot Social (live first line, badge in a real browser), Desktop app.