Skip to content

Narrow the terminal capability_not_granted match to chat.public: the same code also means profile.read and calendar.freebusy.read #988

Closed

Description

@Birfy

What is wrong

capability_not_granted is not the code for "this Bot is not shared". It is Bot Social's generic "peer has not granted ", and the same code is used for capabilities this project never sends over a chat. We treat it, everywhere, as "a share was taken back", which is only true for chat.public:

  • plugins/social/src/social.js:1504-1505 — isNotShared accepts the bare code (error?.code === 'capability_not_granted') and any has not granted [a-z0-9_.]+ sentence, so peer has not granted profile.read would be rewritten into "…is not shared with your Bots… Sending again will not help" and marked no-retry (:1519).
  • core/src/shared/held-retry.js:13-23 — the TERMINAL list carries the bare code at :20, so any failure whose code is capability_not_granted loses its Retry, whatever capability it names. :18 already has the sentence form, correctly narrowed to chat\.public.

Today the misread is invisible only because the chat path is the only one that reaches these two matchers. The rule is still wrong, and the next transport that surfaces a profile.read refusal will get a false "not shared" sentence and a missing Retry. Raised as a non-blocking on #974 by Reviewer; this issue is that non-blocking, not a new symptom.

Upstream uses the one code for several capabilities — Reviewer's #974 verdict names bs-platform.ts:1731 (profile.read) and :2331 (calendar.freebusy.read); I have not re-read that repository, so take those two lines as quoted, not as verified here.

Why narrowing is safe for the chat path

The chat path does not depend on the bare code: notSharedError (social.js:1515-1520) builds its own sentence and stamps code: 'bot_not_shared' and noRetry: true. bot_not_shared (social.js:1504, held-retry.js:21) keeps its meaning, and the noRetry flag travels through heldOf → retry: false → channel.js:143. So the terminal mark for the chat case survives without the wide code match.

Expected

  • A capability_not_granted that names profile.read (or calendar.freebusy.read, or any capability other than chat.public) is not "not shared": canRetry keeps Retry, and the sentence is not rewritten into "not shared with your Bots".
  • Everything about chat.public stays exactly as today, sentence byte-identical.

Acceptance

  1. Red test in core: canRetry({ error: 'peer has not granted profile.read', code: 'capability_not_granted' }) is true, and canRetry({ code: 'capability_not_granted' }) with no sentence is true too (a bare code no longer decides). Fails at 0553ba1e, passes after.
  2. Red test in plugins/social: the error mapper leaves peer has not granted profile.read as the generic error (no "is not shared with your Bots", no noRetry), while peer has not granted chat.public still maps to the not-shared sentence.
  3. Guards that must stay green: chat.public terminal in both spellings — the sentence (held-retry.js:18) and a record marked noRetry: true by social.js:1519; and bot_not_shared / bot_not_found unchanged.
  4. Knife: restore the bare-code match at held-retry.js:20 or the bare-code branch at social.js:1504 → acceptance 1 / 2 go red. Also assert the reverse: removing the chat.public sentence match → the chat case goes red (so the fix cannot pass by making everything retryable).
  5. Mirrors and docs: patches/ds-bot/files/src/shared/held-retry.js regenerated with generate (no hand edits); the one sentence that lists the terminal reasons in docs/subsystems/core-host.md and the capability_not_granted clause in docs/subsystems/social.md say chat.public — or Docs-not-needed: with a reason.
  6. Suites: plugins/social and the affected core files green.

Out of scope

Activity

  1. Birfy commented on Oct 24, 2026

    @Birfy
    CollaboratorAuthor

    Owner: Dev4 (Triage, assigned by Chief 2026-10-24).
    Reviewer: Reviewer

    Line numbers read at main 0553ba1e.

  2. added
    bugSomething isn't working
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    area:socialFriends, invites, grants, Bot Social
    area:uiWeb/desktop UI and copy
    on Oct 24, 2026
  3. Birfy commented on Oct 24, 2026

    @Birfy
    CollaboratorAuthor

    Claiming. Branch: fix/988-capability-chat-public, from da17eb5f.

    Narrowing the terminal match to chat.public at the three places that read the bare code: core/src/shared/held-retry.js:20 (drop it from TERMINAL, keep the chat\.public sentence at :18), the has not granted … sentence in plugins/social/src/social.js:1504-1505 (require chat.public), and core/src/host/remote-chat.js:50 (same pattern, which otherwise translates a profile.read refusal into the not-shared line). The chat path keeps its terminal mark through notSharedError's own code: 'bot_not_shared' + noRetry: true, so the user-facing sentence stays byte-identical.

    Red first on pristine da17eb5f: canRetry({ error: 'peer has not granted profile.read', code: 'capability_not_granted' }) is false today, and the plugin's mapper rewrites that message into "is not shared with your Bots"; both tests come before the source change.

    Written-by: Dev4

  4. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 24, 2026
  5. removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 24, 2026
  6. added a commit that references this issue on Oct 24, 2026
    d24c47c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:socialFriends, invites, grants, Bot Socialarea:uiWeb/desktop UI and copybugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions