From 468c3d73e91c6737bf821c60217347edd091fa62 Mon Sep 17 00:00:00 2001 From: Guilhem Lemouel Date: Tue, 21 Jul 2026 08:30:20 +0200 Subject: [PATCH] test(ai): pin the owned-URI namespace and its disjointness from editor URIs Covers computeOwnedUri for scripts, flow modules, runnables and app files, and asserts the load-bearing invariant: an owned URI is always under the reserved root and never equal to the editor URI for the same code, and the same path in two workspaces yields two distinct owned models. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/lib/components/lint/monacoUri.test.ts | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/frontend/src/lib/components/lint/monacoUri.test.ts b/frontend/src/lib/components/lint/monacoUri.test.ts index 87390b65c2..86a6367b17 100644 --- a/frontend/src/lib/components/lint/monacoUri.test.ts +++ b/frontend/src/lib/components/lint/monacoUri.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest' import { scriptLangToEditorLang } from '$lib/scripts' -import { computeModelPath, computeModelUri } from './monacoUri' +import { computeModelPath, computeModelUri, computeOwnedUri, OWNED_ROOT } from './monacoUri' // Mirrors what Editor.svelte does: path -> filePath -> uri. function uriFor(path: string | undefined, scriptLang: string) { @@ -41,3 +41,68 @@ describe('computeModelUri', () => { expect(computeModelPath('', 'bun')).not.toBe('') }) }) + +describe('computeOwnedUri', () => { + const cell = ( + over: Partial<{ workspace: string; itemKind: string; storagePath: string }> = {} + ) => ({ + workspace: 'guilhem', + itemKind: 'script', + storagePath: 'u/admin/foo', + ...over + }) + + it.each([ + [cell(), undefined, 'bun', 'file:///__wmlint__/guilhem/script/u/admin/foo.ts'], + // a flow module / app runnable is a sub-path within the cell + [ + cell({ itemKind: 'flow', storagePath: 'u/admin/flow' }), + 'a', + 'bun', + 'file:///__wmlint__/guilhem/flow/u/admin/flow/a.ts' + ], + [ + cell({ itemKind: 'app', storagePath: 'u/admin/app' }), + 'runnable_1', + 'bun', + 'file:///__wmlint__/guilhem/app/u/admin/app/runnable_1.ts' + ], + // an app frontend file keeps its extension + [ + cell({ itemKind: 'app', storagePath: 'u/admin/app' }), + 'index.tsx', + 'tsx', + 'file:///__wmlint__/guilhem/app/u/admin/app/index.tsx' + ], + // a fork is a different cell → a different owned URI + [ + cell({ workspace: 'wm-fork-x' }), + undefined, + 'bun', + 'file:///__wmlint__/wm-fork-x/script/u/admin/foo.ts' + ] + ])('%o + %s (%s) -> %s', (c, subPath, scriptLang, expected) => { + expect(computeOwnedUri(c, subPath, scriptLang, scriptLangToEditorLang(scriptLang as any))).toBe( + expected + ) + }) + + // The load-bearing invariant: an owned URI can never equal the editor URI for the same + // code, so a headless model can never occupy a model an editor owns. + it('is always disjoint from the editor URI', () => { + for (const scriptLang of ['bun', 'bunnative', 'nativets', 'tsx', 'jsx', 'javascript']) { + const editorLang = scriptLangToEditorLang(scriptLang as any) + const owned = computeOwnedUri(cell(), undefined, scriptLang, editorLang) + const editor = computeModelUri('u/admin/foo', scriptLang, editorLang) + expect(owned).not.toBe(editor) + expect(owned.startsWith(`file:///${OWNED_ROOT}/`)).toBe(true) + expect(editor.startsWith(`file:///${OWNED_ROOT}/`)).toBe(false) + } + }) + + it('separates the same path across workspaces (no cross-workspace collision)', () => { + const a = computeOwnedUri(cell({ workspace: 'guilhem' }), undefined, 'bun', 'typescript') + const b = computeOwnedUri(cell({ workspace: 'wm-fork-x' }), undefined, 'bun', 'typescript') + expect(a).not.toBe(b) + }) +})