From 1bbe16b93e2d36f816811629ee2791d73c960d15 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Thu, 23 Jul 2026 23:30:23 -0400 Subject: [PATCH] fix(core): preserve global instructions across read races --- packages/core/src/instruction-discovery.ts | 7 ++-- .../core/test/instruction-discovery.test.ts | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/packages/core/src/instruction-discovery.ts b/packages/core/src/instruction-discovery.ts index 910e92f802..8f2b765bb9 100644 --- a/packages/core/src/instruction-discovery.ts +++ b/packages/core/src/instruction-discovery.ts @@ -66,7 +66,10 @@ export const layer = (options?: Options) => Layer.effect( fs.resolve, ), ) - const paths = Array.dedupe([yield* fs.resolve(join(global.config, "AGENTS.md")), ...discovered]) + const globalPath = yield* fs.resolve(join(global.config, "AGENTS.md")) + const observed = new Set(discovered) + if (yield* fs.exists(globalPath)) observed.add(globalPath) + const paths = Array.dedupe([globalPath, ...discovered]) const files = yield* Effect.forEach( paths, (path) => @@ -79,7 +82,7 @@ export const layer = (options?: Options) => Layer.effect( ), { concurrency: "unbounded" }, ) - if (files.some((file, index) => file === undefined && discovered.has(paths[index]))) + if (files.some((file, index) => file === undefined && observed.has(paths[index]))) return Instructions.unavailable return files.filter((file): file is File => file !== undefined) }) diff --git a/packages/core/test/instruction-discovery.test.ts b/packages/core/test/instruction-discovery.test.ts index aa5c759b63..b1460d4204 100644 --- a/packages/core/test/instruction-discovery.test.ts +++ b/packages/core/test/instruction-discovery.test.ts @@ -199,6 +199,42 @@ describe("InstructionDiscovery", () => { }), ) + it.effect("preserves admitted instructions when the global file disappears before read", () => + Effect.gen(function* () { + const file = AbsolutePath.make("/global/AGENTS.md") + const racingFS = Layer.effect( + FSUtil.Service, + FSUtil.Service.pipe( + Effect.map((fs) => + FSUtil.Service.of({ + ...fs, + exists: () => Effect.succeed(true), + up: () => Effect.succeed([]), + readFileStringSafe: () => Effect.succeed(undefined), + }), + ), + ), + ).pipe(Layer.provide(LayerNode.compile(FSUtil.node))) + const context = yield* InstructionDiscovery.Service.pipe( + Effect.flatMap((service) => service.load()), + Effect.provide( + instructionLayer({ + config: "/global", + filesystemLayer: racingFS, + locationServiceLayer: Layer.succeed( + Location.Service, + Location.Service.of(location({ directory: AbsolutePath.make("/repo") })), + ), + }), + ), + ) + + expect( + (yield* readUpdate(context, state({ "core/instructions": [{ path: file, content: "old" }] }))).changed, + ).toBe(false) + }), + ) + it.effect("canonicalizes upward discovery boundaries", () => Effect.gen(function* () { let observed: { targets: string[]; start: string; stop?: string } | undefined