diff --git a/src/plugins/contracts/boundary-invariants.test.ts b/src/plugins/contracts/boundary-invariants.test.ts index cbc1eb9d4ac..d0c8ada819e 100644 --- a/src/plugins/contracts/boundary-invariants.test.ts +++ b/src/plugins/contracts/boundary-invariants.test.ts @@ -46,6 +46,24 @@ const BUNDLED_TYPED_HOOK_REGISTRATION_GUARDS = { (typeof BUNDLED_TYPED_HOOK_REGISTRATION_FILES)[number], readonly string[] >; +const BUNDLED_LIVE_CONFIG_HOOK_GUARDS = { + "extensions/active-memory/index.ts": [ + 'resolvePluginConfigObject(api.runtime.config.loadConfig(), "active-memory")', + "api.runtime.config.loadConfig()", + ], + "extensions/memory-lancedb/index.ts": [ + 'resolvePluginConfigObject(runtimeConfig, "memory-lancedb")', + "api.runtime.config?.loadConfig?.()", + ], + "extensions/skill-workshop/index.ts": [ + 'resolvePluginConfigObject(runtimeConfig, "skill-workshop")', + "api.runtime.config?.loadConfig?.()", + ], + "extensions/thread-ownership/index.ts": [ + 'resolvePluginConfigObject(currentConfig, "thread-ownership")', + "api.runtime.config?.loadConfig?.() ?? api.config", + ], +} as const satisfies Record; type FileFilter = { excludeTests?: boolean; @@ -213,4 +231,16 @@ describe("plugin contract boundary invariants", () => { const offenders = files.filter((file) => /\bregisterHook\(/u.test(readRepoSource(file))); expect(offenders).toEqual([]); }); + + it("keeps long-lived bundled hook handlers on live runtime config lookups", () => { + const missingGuards = Object.entries(BUNDLED_LIVE_CONFIG_HOOK_GUARDS).flatMap( + ([file, requiredSnippets]) => { + const source = readRepoSource(file); + return requiredSnippets + .filter((snippet) => !source.includes(snippet)) + .map((snippet) => `${file}: ${snippet}`); + }, + ); + expect(missingGuards).toEqual([]); + }); });