Skip to content

Commit 699b0f2

Browse files
AliceLJYclaude
andcommitted
fix: align getScopeFilter bypass semantics with isAccessible for undefined agentId (#288, #231)
Root cause: isAccessible(scope, undefined) used bypass mode (any valid scope returns true), but getScopeFilter(undefined) returned only explicitly defined scopes (["global"]), excluding implicit agent scopes like "agent:main". This caused memory_update to reject accessible memories while recall/forget worked. Changes: - scopes.ts: getScopeFilter now returns undefined (full bypass) when agentId is missing, matching isAccessible's existing bypass behavior - tools.ts: memory_update uses runtimeContext.scopeManager instead of context.scopeManager, consistent with recall/forget - test: updated scope-access-undefined assertions to match new bypass semantics Note: beta.10's resolveRuntimeAgentId already ensures agentId defaults to "main" in normal operation. This fix is defensive — prevents the same bug from recurring if any future code path passes undefined agentId. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 41c8f8c commit 699b0f2

File tree

3 files changed

+8
-6
lines changed

3 files changed

+8
-6
lines changed

src/scopes.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,10 @@ export class MemoryScopeManager implements ScopeManager {
220220
* and `[]` only when they intend reads to match nothing.
221221
*/
222222
getScopeFilter(agentId?: string): string[] | undefined {
223-
if (isSystemBypassId(agentId)) {
224-
// Internal system tasks bypass store-level scope filtering entirely.
223+
if (!agentId || isSystemBypassId(agentId)) {
224+
// No agent specified or internal system tasks bypass store-level scope
225+
// filtering entirely. This aligns with isAccessible(scope, undefined)
226+
// which also uses bypass semantics for missing agentId.
225227
return undefined;
226228
}
227229
return this.getAccessibleScopes(agentId);

src/tools.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1069,7 +1069,7 @@ export function registerMemoryUpdateTool(
10691069

10701070
// Determine accessible scopes
10711071
const agentId = resolveRuntimeAgentId(runtimeContext.agentId, runtimeCtx);
1072-
const scopeFilter = resolveScopeFilter(context.scopeManager, agentId);
1072+
const scopeFilter = resolveScopeFilter(runtimeContext.scopeManager, agentId);
10731073

10741074
// Resolve memoryId: if it doesn't look like a UUID, try search
10751075
let resolvedId = memoryId;

test/scope-access-undefined.test.mjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ describe("MemoryScopeManager - System & Reflection Scopes", () => {
6262
]);
6363
});
6464

65-
it("does not bypass the store filter for empty or nullish agentId", () => {
66-
assert.deepStrictEqual(manager.getScopeFilter(""), manager.getAllScopes());
67-
assert.deepStrictEqual(manager.getScopeFilter(undefined), manager.getAllScopes());
65+
it("bypasses the store filter for empty or nullish agentId (consistent with isAccessible)", () => {
66+
assert.strictEqual(manager.getScopeFilter(""), undefined);
67+
assert.strictEqual(manager.getScopeFilter(undefined), undefined);
6868
});
6969

7070
it("rejects whitespace-padded reserved bypass ids extracted from session keys", () => {

0 commit comments

Comments
 (0)