Repository navigation
[Team] Gate cross-owner agent routes by per-Bot grants (default deny; superseded the publication gate) #51
Description
Planning ID: TODO-F (revised 2026-10-16: access is per-Bot grants, default deny, Chief included. This replaces the earlier publication gate and "Chief published by default" model; see #90, #91, #138).
Proposed issue / PR title: feat(routing): gate cross-owner agent routes by per-Bot grants.
Goal: server-enforced protection against direct access to another owner's Bots. There is no global published flag. A Bot is reachable from another owner only through an explicit per-Bot grant (one of my Bots → one grantee, optionally scoped to a room). Default deny, Chief included.
Model:
- A grant is created when someone accepts "Invite to this Bot", or implicitly when the owner brings their own Bot into a face-to-face room by its 6-digit number ([Feature] Face-to-face group: Bots join one room by entering the same 6-digit number #83): that grant is reachable for that room only, and only while the Bot is a member.
- A grantee is a friend home, a remote handle, a team member id or a local Bot id. A Bot whose owner is not a team member has no grants.
- Grants live in
state.grants[botId].
Scope: one owner- and grant-aware policy used by direct bot sends, group dispatch and room fan-out, plugin transports, schedules, deferred delivery and resumed/retried messages. Check current membership and the grant at delivery time. Reject cross-owner targets without a matching grant regardless of aliases or transport. Revoking a grant, removing a Bot or replacing a Chief immediately changes route eligibility.
Out of scope: social-server deployment and recursive tree redesign.
Dependencies: #49 (done), #50 (done), #90 / #91 (per-Bot grants, merged).
Done on main (566f1e6):
core/src/host/reach.jsis the single reach policy. It sits outside the plugin send chain, so a plugin'salloworbypassverdict cannot skip it.hooks.jsruns it beforebot.send, again when an approved hold is released, and on resumed, retried, deferred and re-sent deliveries that carry a sender.- Rules for remote → local, local → remote and local → local (same owner allowed; other owner needs matching grants on both sides or current room membership).
- Unit tests in
core/test/reach-policy.test.js.
Left to do:
- Face-to-face: a human's message to a room's friend Bot is blocked with 'Chief has no grant to that Bot' #143 / fix(social): a human's message to a room's friend Bot no longer goes through Chief (#143) #144: a human's message to a room's friend Bot is blocked with "Chief has no grant to that Bot" (fix in fix(social): a human's message to a room's friend Bot no longer goes through Chief (#143) #144).
- Team-mode gates [Team] Recover task handoffs without duplicate work #55–[Team] Verify the real two-human team pilot end to end #58: task handoff recovery, loop and resource bounds, authorization and task audit trail, real two-human pilot.
- Confirm every entry point in the matrix below has a test, and report the missing ones.
Acceptance and tests: explicit allow/deny matrix covers every entry point. A remote sender can reach Bob's Bots that carry a matching grant (Chief or not) and cannot reach Bob's Bots without one, nor Bots deep in a tree. Room traffic is checked per author and per recipient. A plugin cannot skip owner policy through an ordinary allow/bypass flag. Removed owners, revoked grants and former Chiefs cannot use queued, retried or resumed sends.
Delivery
One focused implementation PR for this issue. This is planned work, not a claim of shipped multi-human support. Preserve the pristine upstream pin and generated patch/client boundaries. Keep team mode disabled until the documented authorization gates pass. Record exact tested head, executed checks, missing checks and independent review. No production credentials or live deployment are part of this issue.
Activity
[-][Team] Gate every cross-owner agent route through Chiefs[/-][+][Team] Gate cross-owner agent routes by publication (published Bots reachable, unpublished private)[/+]Published Bots: only published Bots are reachable from outside (#51)
Merge pull request #87 from Birfy/51-published-reach
feat(social): Published to friends toggle for set-published (ThinkFlo…
feat(social): join a face-to-face room by a 6-digit number
feat(social): Published to friends toggle for set-published (ThinkFlo…
Birfy commentedon Oct 15, 2026
Design update from the owner: no Bot is published by default, the Chief included. Publishing is always an explicit owner action (the per-Bot toggle). The
reach()policy is unchanged. Tracked in #90 (scope C). Upgrading makes existing Chiefs unpublished until the owner turns the toggle on.Birfy commentedon Oct 15, 2026
Superseded by the owner's latest design (see #90): the
publishedgate is being removed in favour of independent per-Bot grants, default deny.[-][Team] Gate cross-owner agent routes by publication (published Bots reachable, unpublished private)[/-][+][Team] Gate cross-owner agent routes by per-Bot grants (default deny; superseded the publication gate)[/+]Birfy commentedon Oct 16, 2026
Ordered plan for the remaining team-mode gates (2026-10-16). No separate team-mode flag; the documented gate flips after #58 passes. Team mode is built on groups with per-Bot grants; the real gap is that the task layer (#54) is passive (nothing drives tasks, requester-only authority, tasks live on one host).
responsibleOwnerId),FLYBOT-TASKenvelope so both homes see the task,workBotIdassignment (the S part of Task lifecycle: stamp meta.taskId on held sends; clarification state + workBotId (remainder of #111, needs #55) #111), and audit events start being emitted.task_ask) and room task card (M).uncertainstate for owner reconciliation, resume re-checks grants/membership (L).state.audit, scoped read endpoint, timeline on the task card (M).core/test/pilot.test.js(one host with two members, then two hosts) plus manual UI checklist (L). Only after it passes, updatedocs/subsystems/team.mdand flip the gate wording.Agent inbox: show failed turns and a latest-activity line on each card (
Remind about approvals waiting 15 min, switch each notification kind,…
Birfy commentedon Oct 20, 2026
Triaged: this is team-via-groups work, and the team mode contract is not shipped (AGENTS.md: team mode stays disabled until the authorization gates in
docs/subsystems/team.mdpass; issue #16 is resolved as Option B and must not be re-opened).So it is not
agent-ready: it waits for the owner to explicitly turn team work on. Labeledneeds-human; automation leaves it alone and writes no code for it.Consume Bot Social's hold_reason, and let the face-room switch still …
fix(issue-ref): read a bare ThinkFlowLab#1234 only when the number st…