From d4666bea7f9148ddbd34b01760faa9347ab875aa Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 3 Jun 2026 13:47:02 -0400 Subject: [PATCH] feat(mcp): add multi-user sharing ACL guard to _INSTRUCTIONS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ACL constraint (scope every read/mutation by owner + shares via services/access.py) is a security-correctness invariant that should always be loaded, and it's FabledScribe-specific — so it belongs in Scribe's own contained _INSTRUCTIONS, not the cross-project FabledSword rulebook. The redundant rulebook rule will be retired once this ships to prod. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/fabledassistant/mcp/server.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/fabledassistant/mcp/server.py b/src/fabledassistant/mcp/server.py index e360897..e3cd3ae 100644 --- a/src/fabledassistant/mcp/server.py +++ b/src/fabledassistant/mcp/server.py @@ -122,6 +122,13 @@ X process" or otherwise references a saved process, call list_processes() / get_process(name) and follow the returned prompt verbatim, including any "clarify first" steps it contains. Author a new one with create_process(title, body); edit with update_process. + +When you are developing Scribe itself (not just using it as a data store), +honor the multi-user sharing ACL: every read or mutation of user data must +scope by owner + direct shares + group shares through services/access.py +(can_read_* / can_write_* / can_admin_*) — never assume a single operator. An +unscoped query (a fetch-by-id with no ownership check) is a cross-user data +leak; "works for one user" is not done. """