Skip to content

feat(context): enforce explicit context sharing across owners (#53) - #101

Merged
hsliuustc0106 merged 1 commit into
mainfrom
fix-53-context-sharing
Oct 15, 2026
Merged

hsliuustc0106 merged 1 commit into
mainfrom
fix-53-context-sharing

Conversation

@hsliuustc0106

@hsliuustc0106 hsliuustc0106 commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

Why

On a host with member sessions, private context leaked across owners through four seams: a member Bot's group Session began with its owner's own-chat brief whoever else sat in the room; the memory review read every attributed human as a peer and could publish team memory out of another owner's room (any room admin could, and still can on single-owner rooms); list_bots disclosed other owners' workDir and instructions; and a dsh-session: reference chip copied any Session's snapshot to every recipient of the message. #53's acceptance: markers in each owner's private context are unreachable from another owner's requests and shared-room context without an explicit authorized share.

Stacked on #94 (fix-52-approval-binding, f87ed85) — this branch bases on it; retarget to main after #94 merges. Host mechanism only: the share has no room-UI toggle yet (documented), and previously received messages are not retroactively unseen (the issue says to document exactly that).

What

  • Brief gate (src/host/groups.js): the own-chat brief enters a group Session only for a single-owner room, or where the Bot's owner shared it — share-brief endpoint → rt.setBriefShare (src/host/room-membership.js), a briefShared flag on the room participant (leaving drops it; owner-checked, not admin-checked). Enforcement off = shipped single-human behavior.
  • Memory review (src/host/memory.js): isUserLine reads the member Bot's owner as "the user" (retention + read-back anchor) and another owner's human as a named peer; teamAllowedFrom refuses team-scope writes out of a room with more than one owner — entries land in the Bot's own memory.
  • Roster (src/host/tools.js): list_bots shows another owner's Bot by name, role, model; its folder and instructions stay private.
  • References (src/host/channel.js): dsh-session: chips in send and room-post must resolve through sessionOwnedBy for the author (bot/forbidden otherwise); authz allows the new share-brief for any signed-in actor (the owner check is on the record).

Fixes #53

Verification (updated: rebase + review round 1)

Tips: 58fdae3 (initial, Verifier FAIL on packaging + narrative) → 775bae1 (current; branch rewritten as ONE commit Share private context across owners only by an explicit share (#53) directly on the rebased #94 tip 985c82e, which sits on origin/main 1736161).

Ran at 775bae1:

  • `npm run verify` (pipeline gate) — exit 0.
  • Red-at-base at `985c82e` + only the two test files: context-sharing 5 fail / 1 pass — the 5 feature tests fail for the right reasons (brief present cross-owner; bot/not-found: Unknown endpoint share-brief on the owner-share and foreign-share tests — so the round-1 "2 passing guards" claim was wrong: the foreign-share guard fails at base too, via bot/not-found rather than bot/forbidden); memory 2 fail — the classification test fails on the batch text, and the team-gate test fails with nothing written at all (base never writes b3's MEMORY.md from this fixture), not a cross-owner team write.
  • `node --test` on the two files at the tip: 66/66 across both files (8 new).
  • Smoke: ports 3094/8794 — all 40 steps passed; bench stopped, data removed.

Round-1 findings → fixes

  1. Patches block — fixed: context-sharing.test.js joined topic 0002, patches regenerated in-commit.
  2. Narrative — corrected above (5/1, and the memory base failure mode stated exactly).
  3. Remote owners — fixed: a granted remote Bot's handle now counts as another owner in both briefAllowed (groups.js) and teamAllowedFrom (memory.js); a remote participant in an otherwise single-owner room suppresses the brief (new test).
  4. Chip gates beyond send/room-post — follow-up filed as Chip resolution: bot-to-bot sends / own-chat followups not author-checked or stripped (remainder of #106) #106; noted in team.md as not-done-here.

Fixes #53

Docs-not-needed: #53 context-sharing narrative lives in docs/subsystems/team.md (Context sharing foundation) with core-host.md cross-ref; merge-queue squash must retain this trailer.

@hsliuustc0106

Copy link
Copy Markdown
Collaborator Author

Review round 1 (independent Verifier) — verdict FAIL at 58fdae3; fixed on the rewritten tip 775bae1 (branch rebased onto the new-main #94 tip 985c82e, collapsed to one commit per the squash contract):

  1. Patches block — context-sharing.test.js had not joined topics.json, so the committed patches never produced it. Fixed in-commit; patches check ok.
  2. Red-at-base narrative overstated — corrected in the PR body: 5 fail / 1 pass on context-sharing (the foreign-share guard fails at base via bot/not-found), and the memory team-gate test fails at base with nothing written, not a cross-owner write. Fail-without-change still holds for all 8 new tests.
  3. Remote owners — a granted remote Bot's handle now counts as another owner in the brief gate and the memory team gate (new test: remote in an otherwise single-owner room suppresses the brief).
  4. Chip resolution beyond send/room-post — follow-up Chip resolution: bot-to-bot sends / own-chat followups not author-checked or stripped (remainder of #106) #106 (includes the schedule-create body.target vs body.sessionId observation); documented as not-done-here in team.md.

Gates at 775bae1: npm run verify exit 0 · 66/66 on the two seam test files · smoke 40/40 · patches ok · arch-docs ok. Re-review of the new tip requested.

@hsliuustc0106
hsliuustc0106 force-pushed the fix-52-approval-binding branch from 985c82e to 364e3ba Compare October 15, 2026 16:27
@hsliuustc0106
hsliuustc0106 force-pushed the fix-53-context-sharing branch from 775bae1 to d464235 Compare October 15, 2026 16:33
@hsliuustc0106

Copy link
Copy Markdown
Collaborator Author

Rebased onto the #94 tip (364e3ba, which carries the conflict-marker doc fix and the newest-main rebase). New tip: d464235 — one commit, cherry-picked cleanly; the corrupted-doc lineage is gone from this branch too.

  • npm run verify exit 0 · 66/66 on the two seam test files · smoke 3092/8792 40/40 · patches ok (new format: files/test/context-sharing.test.js) · arch-docs OK (34 files).
  • The round-2 PASS was at 775bae1; this rebase voids it — delta re-review requested at d464235 (delta should be: doc-fix inheritance + new-format patches + main's incoming work only).

@hsliuustc0106

Copy link
Copy Markdown
Collaborator Author

Review round 3 (final delta) — verdict PASS on d464235.

  • Delta vs the PASSed round-2 tip is zero for this PR's own files (groups.js / memory.js / channel.js / authz.js / room-membership.js / tools.js / both test files byte-identical); the rebase delta is exactly the expected file set (the doc fix inherited from feat(approvals): bind delegated requests and decisions to the owning human (#52) #94, patches in the new files/ format, main's incoming work).
  • Gates re-run by the Verifier at the tip: npm run verify exit 0 · patches ok in the new format · arch-docs OK · conflict-marker sweep clean · all CI checks green, including the round-2 social flake.
  • Non-blocking note: the one-sentence [Team] Isolate private context from shared room context #53 summary that used to sit in ds-bot-core.md invariant 5 was dropped by the base-side doc split; the full mechanism stays documented in team.md (byte-identical, verified) + CHANGELOG — optional docs-only follow-up when the PR retargets to main.

Verdict history: 58fdae3 FAIL → 775bae1 PASS → d464235 PASS. Implementer agrees on d464235. Reminder noted: retargeting to main after #94 merges produces a new tip and voids this verdict until re-reviewed — I'll run that re-review then. Ready for maintainer review; no merge action from my side.

@Birfy

Birfy commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator

Design review against the owner's sharing model (per-Bot grants, no publish; a granted Bot is a child Bot that manages only its own downstream; every human in a group can talk to and operate it within that group; Bot Social holds are approved in-chat by the owner only). Read-only review of d464235, no UI run. No conflict in core/src with the grant model, but please change these before this lands:

  1. list_bots (tools.js:64) hides only workDir and instructions. It still lists every other owner's Bots by name, role and model, which contradicts "nobody browses others' Bots". Restrict it to the requester's own Bots, Bots granted to the same owner, and Bots in the current room.
  2. foreign compares the Bot's owner, not the requester. A granted child Bot triggered by a grantee or friend shows the whole owner roster with workDir and instructions. Scope it to that Bot's own subtree.
  3. briefAllowed (groups.js:130) withholds the owner's own-chat brief in any multi-owner room, including face-to-face rooms where someone brings their own Bot, and share-brief has no UI. Tie the share to the grant (a flag on state.grants or the room-scoped grant) instead of a participant flag that is lost on leave or rejoin, and add a room-membership check in setBriefShare (room-membership.js:648).
  4. isUserLine (memory.js:1147, :1161) labels a grantee's lines as 'bot'; they should be 'peer'.
  5. teamAllowedFrom (memory.js:495) does not check authzEnforced, so team-scope memory writes are blocked in any room with a friend's Bot, including single-human hosts. Please confirm that is intended.
  6. The branch is based on the now-closed feat(approvals): bind delegated requests and decisions to the owning human (#52) #94 branch; it will need a rebase onto main with patches/ds-bot/0001-core-fixes.patch regenerated.

Follow-ups from #94 (not blockers): social/approvals returns every Bot Social hold, text included, to any signed-in member; non-owner room members cannot see local holds (origin.audience is stamped but unused, a redacted status/sender-only view would fit); deleteBot skips invalidateFor for remote chats (hooks.js:175).

@hsliuustc0106 hsliuustc0106 reopened this Oct 15, 2026
Base automatically changed from fix-52-approval-binding to main October 15, 2026 17:07
@hsliuustc0106
hsliuustc0106 force-pushed the fix-53-context-sharing branch from d464235 to 2657bf8 Compare October 15, 2026 17:28
@hsliuustc0106

Copy link
Copy Markdown
Collaborator Author

Review round 4 (independent Verifier, rebase onto main after #94) — verdict PASS on 2657bf8.

Codex unreachable from this box (Cloudflare 403 on chatgpt.com/backend-api/codex and workspace routing discovery failed) — same blocker as prior Magpie notes. This round is the mechanical delta re-review the round-3 note promised after retarget.

Verdict history: 58fdae3 FAIL → 775bae1 PASS → d464235 PASS → 2657bf8 PASS (rebase delta). Ready for squash auto-merge onto main.

@hsliuustc0106
hsliuustc0106 added this pull request to the merge queue Oct 15, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 15, 2026
@hsliuustc0106
hsliuustc0106 added this pull request to the merge queue Oct 15, 2026
On a host with member sessions, a member Bot's group Session began with
its owner's own-chat brief whoever else sat in the room, the memory
review read every human as 'the user' and could publish team memory
from another owner's room, list_bots disclosed other owners' folders
and instructions, and a chat reference chip copied any Session's
snapshot to every recipient.

Now the own-chat brief rides into a room with more than one owner only
when the Bot's owner shares it there (share-brief, a per-room
briefShared flag on the participant that leaving drops); a review that
reads a cross-owner room keeps entries in the Bot's own memory and
reads only its own owner as the user; list_bots shows another owner's
Bot by name, role and model only; and reference chips in send and
room-post must resolve through sessionOwnedBy for the author.
Previously received messages are not retroactively unseen; the secrets
surface stays blocked-shared.

Team mode stays disabled; this is the context half of the authority
contract (docs/subsystems/team.md).

Fixes #53
@hsliuustc0106
hsliuustc0106 removed this pull request from the merge queue due to a manual request Oct 15, 2026
@hsliuustc0106
hsliuustc0106 force-pushed the fix-53-context-sharing branch from 2657bf8 to f1b034c Compare October 15, 2026 17:38
@hsliuustc0106

Copy link
Copy Markdown
Collaborator Author

Follow-up (arch-docs / merge-queue): tip moved 2657bf8 → f1b034c.

Merge-queue run 38778004985 failed arch-docs because the queue squash commit message is built from the PR body (repo setting PR_BODY) and did not carry the git Docs-not-needed: trailer.

Fix: updated docs/subsystems/core-host.md with an explicit #53 context-sharing cross-ref to team.md (owned host modules named). Local arch-docs: OK (18 changed file(s)) at f1b034c without needing a trailer. Re-queueing after CI green.

@hsliuustc0106
hsliuustc0106 added this pull request to the merge queue Oct 15, 2026
@hsliuustc0106

Copy link
Copy Markdown
Collaborator Author

Review round 4b (delta) — verdict PASS on f1b034c (voids round-4 tip 2657bf8 only for the doc delta).

  • Sole code/doc delta vs 2657bf8: docs/subsystems/core-host.md [Team] Isolate private context from shared room context #53 cross-ref bullet (no JS change). Required so merge-queue squash arch-docs stays green without depending on a commit-message trailer.
  • arch-docs: OK (18 changed file(s)) at the tip; PR CI re-run required before re-queue.

Merged via the queue into main with commit 8479441 Oct 15, 2026
6 checks passed
@hsliuustc0106
hsliuustc0106 deleted the fix-53-context-sharing branch October 15, 2026 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Team] Isolate private context from shared room context

2 participants