From e7674f89d7877f2069c6dd34c35f2368fda404c6 Mon Sep 17 00:00:00 2001 From: Surma Date: Thu, 12 Nov 2026 12:28:52 +0000 Subject: [PATCH] Use extension content hashes in dependent test fixtures --- host/js/events-test-bundle.js | 8 ++------ host/js/events-test.ts | 9 +++++---- host/js/messages-test-bundle.js | 2 +- host/js/messages-test.ts | 2 +- host/js/subagents-test-bundle.js | 2 +- host/js/subagents-test.ts | 2 +- host/js/watchdog-test-bundle.js | 16 ++++++++-------- host/js/watchdog-test.ts | 4 ++-- host/js/workspaces-test-bundle.js | 6 +++--- host/js/workspaces-test.ts | 6 +++--- 10 files changed, 27 insertions(+), 30 deletions(-) diff --git a/host/js/events-test-bundle.js b/host/js/events-test-bundle.js index 6b97757..3f95968 100644 --- a/host/js/events-test-bundle.js +++ b/host/js/events-test-bundle.js @@ -38429,17 +38429,13 @@ import {defineEvent} from '@earendil-works/sausage-events'; const Seen=defineDoc({kind:'test.seen',scope:'conversation',version:1,history:'latest',fork:'initial',checkpointWhen:()=>false,initial:()=>({shas:[]})}); export default host=>{globalThis.eventHosts.receiver=host;globalThis.receiverVersion=${version};host.react('counter',[defineEvent('test.landed')],async(tx,event)=>{(await tx.doc(Seen,ROOT)).shas.push(event.data.sha);});return {name:'receiver'};};`; await fs.write(`${repo}/extensions/receiver/server.ts`, receiver(1)); - await git(repo, "add", "."); - await git(repo, "commit", "--no-gpg-sign", "-m", "events"); const loader = await loadExtensions(harness, registry, storage, models, BACKGROUND_CONTEXT); try { await harness.commit((tx) => globalThis.eventHosts.emitter.emit(tx, Landed, { sha: "world-a" }), BACKGROUND_CONTEXT); await until2(async () => (await read2(Seen)).length === 1); + const before = loader.state().good; await fs.write(`${repo}/extensions/receiver/server.ts`, receiver(2)); - await git(repo, "add", "."); - await git(repo, "commit", "--no-gpg-sign", "-m", "reload"); - const sha = await git(repo, "rev-parse", "HEAD"); - await until2(() => loader.state().good === sha); + await until2(() => loader.state().good !== before && !loader.state().error); await harness.commit((tx) => globalThis.eventHosts.emitter.emit(tx, Landed, { sha: "world-b" }), BACKGROUND_CONTEXT); await until2(async () => (await read2(Seen)).length === 2); equal(await read2(Seen), ["world-a", "world-b"]); diff --git a/host/js/events-test.ts b/host/js/events-test.ts index e816b8e..4ce56b9 100644 --- a/host/js/events-test.ts +++ b/host/js/events-test.ts @@ -4,7 +4,7 @@ import { Harness,createRegistry,defineDoc,ROOT_CONVERSATION_ID as ROOT } from '@ import { createModels } from '@earendil-works/pi-ai/models'; import { openStorage } from './sqlite'; import { defineEvent,eventLog,EventFeed,EVENT_FEED_SIZE } from './events'; -import { loadExtensions,fs,git } from './extensions'; +import { loadExtensions,fs } from './extensions'; const assert=(value:any,message:string)=>{if(!value)throw new Error(message);}; const equal=(a:any,b:any)=>assert(JSON.stringify(a)===JSON.stringify(b),`Expected ${JSON.stringify(b)}, got ${JSON.stringify(a)}`); const until=async(test:()=>any)=>{const deadline=Date.now()+15000;while(!await test()){if(Date.now()>deadline)throw new Error('Event deadline');await new Promise(r=>setTimeout(r,0));}}; @@ -32,13 +32,14 @@ if(globalThis.eventsMode==='emit') { import {defineEvent} from '@earendil-works/sausage-events'; const Seen=defineDoc({kind:'test.seen',scope:'conversation',version:1,history:'latest',fork:'initial',checkpointWhen:()=>false,initial:()=>({shas:[]})}); export default host=>{globalThis.eventHosts.receiver=host;globalThis.receiverVersion=${version};host.react('counter',[defineEvent('test.landed')],async(tx,event)=>{(await tx.doc(Seen,ROOT)).shas.push(event.data.sha);});return {name:'receiver'};};`; - await fs.write(`${repo}/extensions/receiver/server.ts`,receiver(1));await git(repo,'add','.');await git(repo,'commit','--no-gpg-sign','-m','events'); + await fs.write(`${repo}/extensions/receiver/server.ts`,receiver(1)); const loader=await loadExtensions(harness,registry,storage,models,context); try { await harness.commit(tx=>globalThis.eventHosts.emitter.emit(tx,Landed,{sha:'world-a'}),context); await until(async()=>(await read(Seen)).length===1); - await fs.write(`${repo}/extensions/receiver/server.ts`,receiver(2));await git(repo,'add','.');await git(repo,'commit','--no-gpg-sign','-m','reload'); - const sha=await git(repo,'rev-parse','HEAD');await until(()=>loader.state().good===sha); + const before=loader.state().good; + await fs.write(`${repo}/extensions/receiver/server.ts`,receiver(2)); + await until(()=>loader.state().good!==before && !loader.state().error); await harness.commit(tx=>globalThis.eventHosts.emitter.emit(tx,Landed,{sha:'world-b'}),context); await until(async()=>(await read(Seen)).length===2);equal(await read(Seen),['world-a','world-b']);assert(globalThis.receiverVersion===2,'Replaced receiver'); globalThis.eventHosts.emitter.notice('Notice');globalThis.eventHosts.emitter.notice('Notice'); diff --git a/host/js/messages-test-bundle.js b/host/js/messages-test-bundle.js index c3eea60..b7446e4 100644 --- a/host/js/messages-test-bundle.js +++ b/host/js/messages-test-bundle.js @@ -38449,7 +38449,7 @@ var route = (transcript) => { faux.setResponses([route]); var loader = await loadExtensions(harness, registry, storage, models, BACKGROUND_CONTEXT, [held2, worker]); assert(!loader.state().error, `Extension load: ${loader.state().error}`); -var snapshot = await fs.read("/src/sausage/.git/sausage-last-good"); +var snapshot = loader.state().good; var base = `file:///run/sausage/extensions/${snapshot}/extensions`; var { Started: Started2 } = await import(`${base}/messages/addresses.ts`); var { Roots } = await import(`${base}/lineage/api.ts`); diff --git a/host/js/messages-test.ts b/host/js/messages-test.ts index a256f23..130f36d 100644 --- a/host/js/messages-test.ts +++ b/host/js/messages-test.ts @@ -51,7 +51,7 @@ const route = (transcript: any): any => { faux.setResponses([route]); const loader = await loadExtensions(harness, registry, storage, models, context, [held, worker]); assert(!loader.state().error, `Extension load: ${loader.state().error}`); -const snapshot = await fs.read('/src/sausage/.git/sausage-last-good'); +const snapshot = loader.state().good; const base = `file:///run/sausage/extensions/${snapshot}/extensions`; const {Started} = await import(`${base}/messages/addresses.ts`); const {Roots} = await import(`${base}/lineage/api.ts`); diff --git a/host/js/subagents-test-bundle.js b/host/js/subagents-test-bundle.js index 947ee68..0cc96e4 100644 --- a/host/js/subagents-test-bundle.js +++ b/host/js/subagents-test-bundle.js @@ -38474,7 +38474,7 @@ var route = (transcript) => { faux.setResponses([route]); var loader = await loadExtensions(harness, registry, storage, models, BACKGROUND_CONTEXT, [held2]); assert(!loader.state().error, `Extension load: ${loader.state().error}`); -var snapshot = await fs.read("/src/sausage/.git/sausage-last-good"); +var snapshot = loader.state().good; var { Subagents } = await import(`file:///run/sausage/extensions/${snapshot}/extensions/subagents/api.ts`); var chain = conversationChains(harness, BACKGROUND_CONTEXT); var children = async () => Object.values((await harness.snapshot(Subagents, root.id, BACKGROUND_CONTEXT))?.agents ?? {}); diff --git a/host/js/subagents-test.ts b/host/js/subagents-test.ts index d5a1934..f11b330 100644 --- a/host/js/subagents-test.ts +++ b/host/js/subagents-test.ts @@ -31,7 +31,7 @@ const route=(transcript:any):any=>{ faux.setResponses([route]); const loader=await loadExtensions(harness,registry,storage,models,context,[held]); assert(!loader.state().error,`Extension load: ${loader.state().error}`); -const snapshot=await fs.read('/src/sausage/.git/sausage-last-good'); +const snapshot=loader.state().good; const {Subagents}=await import(`file:///run/sausage/extensions/${snapshot}/extensions/subagents/api.ts`); const chain=conversationChains(harness,context); const children=async()=>Object.values((await harness.snapshot(Subagents,root.id,context))?.agents??{}) as any[]; diff --git a/host/js/watchdog-test-bundle.js b/host/js/watchdog-test-bundle.js index a3ab5e6..4a19f41 100644 --- a/host/js/watchdog-test-bundle.js +++ b/host/js/watchdog-test-bundle.js @@ -3563,8 +3563,8 @@ function resolveUri(ref, base2) { } } function documentOf(uri) { - const hash = uri.indexOf("#"); - return hash < 0 ? uri : uri.slice(0, hash); + const hash2 = uri.indexOf("#"); + return hash2 < 0 ? uri : uri.slice(0, hash2); } // node_modules/@earendil-works/pi-schema/dist/shared.js @@ -37209,8 +37209,8 @@ async function loadExtensions(harness2, registry2, storage2, models2, context, b }; await walk(""); const digest = await crypto.subtle.digest("SHA-256", encoder4.encode(JSON.stringify(files))); - const hash = Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join(""); - return { hash, files }; + const hash2 = Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join(""); + return { hash: hash2, files }; }; const mkdir = async (path) => { try { @@ -37219,8 +37219,8 @@ async function loadExtensions(harness2, registry2, storage2, models2, context, b if (error.code !== "already_exists") throw error; } }; - const snapshot = async ({ hash, files }) => { - const base2 = `/run/sausage/extensions/${hash}`; + const snapshot = async ({ hash: hash2, files }) => { + const base2 = `/run/sausage/extensions/${hash2}`; for (const path of ["/run/sausage", "/run/sausage/extensions", base2, `${base2}/extensions`]) await mkdir(path); for (const [name, bytes2] of files) { let parent = `${base2}/extensions`; @@ -38406,8 +38406,8 @@ var route = (transcript) => { faux.setResponses([route]); var loader = await loadExtensions(harness, registry, storage, models, BACKGROUND_CONTEXT); assert(!loader.state().error, `Extension load: ${loader.state().error}`); -var sha = await fs.read("/src/sausage/.git/sausage-last-good"); -var base = `file:///run/sausage/extensions/${sha}/extensions`; +var hash = loader.state().good; +var base = `file:///run/sausage/extensions/${hash}/extensions`; var { MainAgent } = await import(`${base}/subagents/api.ts`); var { Messages } = await import(`${base}/messages/api.ts`); var { diagnose } = await import(`${base}/watchdog/server.ts`); diff --git a/host/js/watchdog-test.ts b/host/js/watchdog-test.ts index ab40052..21f0e94 100644 --- a/host/js/watchdog-test.ts +++ b/host/js/watchdog-test.ts @@ -24,8 +24,8 @@ const route = (transcript: any): any => { faux.setResponses([route]); const loader = await loadExtensions(harness, registry, storage, models, context); assert(!loader.state().error, `Extension load: ${loader.state().error}`); -const sha = await fs.read('/src/sausage/.git/sausage-last-good'); -const base = `file:///run/sausage/extensions/${sha}/extensions`; +const hash = loader.state().good; +const base = `file:///run/sausage/extensions/${hash}/extensions`; const {MainAgent} = await import(`${base}/subagents/api.ts`); const {Messages} = await import(`${base}/messages/api.ts`); const {diagnose} = await import(`${base}/watchdog/server.ts`); diff --git a/host/js/workspaces-test-bundle.js b/host/js/workspaces-test-bundle.js index 00a3009..c37484b 100644 --- a/host/js/workspaces-test-bundle.js +++ b/host/js/workspaces-test-bundle.js @@ -38434,7 +38434,7 @@ var call = async (tool, args) => { return result; }; var submit = async (id) => { - const { Started: Started2 } = await import(`file:///run/sausage/extensions/${await fs.read("/src/sausage/.git/sausage-last-good")}/extensions/messages/addresses.ts`); + const { Started: Started2 } = await import(`file:///run/sausage/extensions/${loader.state().good}/extensions/messages/addresses.ts`); await harness.commit(async (tx) => { (await tx.doc(Started2, id)).by = root.id; }, BACKGROUND_CONTEXT); @@ -38445,7 +38445,7 @@ var submit = async (id) => { return JSON.parse(result.content.filter((part) => part.type === "text").map((part) => part.text).join("")); }; var children = async () => { - const { Subagents } = await import(`file:///run/sausage/extensions/${await fs.read("/src/sausage/.git/sausage-last-good")}/extensions/subagents/api.ts`); + const { Subagents } = await import(`file:///run/sausage/extensions/${loader.state().good}/extensions/subagents/api.ts`); return Object.values((await harness.snapshot(Subagents, root.id, BACKGROUND_CONTEXT)).agents); }; var waitQueue = async () => { @@ -38458,7 +38458,7 @@ var waitQueue = async () => { }; var reports = async (id) => (await (await harness.conversation(id, BACKGROUND_CONTEXT)).context(BACKGROUND_CONTEXT)).entries.filter((entry2) => entry2.kind === "workspaces.lander-report"); var notes = async () => { - const { Messages } = await import(`file:///run/sausage/extensions/${await fs.read("/src/sausage/.git/sausage-last-good")}/extensions/messages/api.ts`); + const { Messages } = await import(`file:///run/sausage/extensions/${loader.state().good}/extensions/messages/api.ts`); const deadline = Date.now() + 3e4; for (; ; ) { const notes2 = (await harness.snapshot(Messages, root.id, BACKGROUND_CONTEXT)).messages.filter((message) => message.text.startsWith("[lander] Submission") && message.text.includes(" landed as ")); diff --git a/host/js/workspaces-test.ts b/host/js/workspaces-test.ts index 685adbc..e1f60f7 100644 --- a/host/js/workspaces-test.ts +++ b/host/js/workspaces-test.ts @@ -56,7 +56,7 @@ const call=async(tool:string,args:any)=>{ return result; }; const submit=async(id:number)=>{ - const {Started}=await import(`file:///run/sausage/extensions/${await fs.read('/src/sausage/.git/sausage-last-good')}/extensions/messages/addresses.ts`); + const {Started}=await import(`file:///run/sausage/extensions/${loader.state().good}/extensions/messages/addresses.ts`); await harness.commit(async(tx:any)=>{(await tx.doc(Started,id)).by=root.id},context); const child=await harness.conversation(id,context); await(await child.submit({type:'input',content:`CALL ${JSON.stringify({tool:'workspace',args:{action:'submit',divergence:'None'}})}`},context)).wait(context); @@ -65,7 +65,7 @@ const submit=async(id:number)=>{ return JSON.parse(result.content.filter((part:any)=>part.type==='text').map((part:any)=>part.text).join('')); }; const children=async()=>{ - const {Subagents}=await import(`file:///run/sausage/extensions/${await fs.read('/src/sausage/.git/sausage-last-good')}/extensions/subagents/api.ts`); + const {Subagents}=await import(`file:///run/sausage/extensions/${loader.state().good}/extensions/subagents/api.ts`); return Object.values((await harness.snapshot(Subagents,root.id,context)).agents) as any[]; }; const waitQueue=async()=>{ @@ -78,7 +78,7 @@ const waitQueue=async()=>{ }; const reports=async(id:number)=>(await(await harness.conversation(id,context)).context(context)).entries.filter((entry:any)=>entry.kind==='workspaces.lander-report'); const notes=async()=>{ - const {Messages}=await import(`file:///run/sausage/extensions/${await fs.read('/src/sausage/.git/sausage-last-good')}/extensions/messages/api.ts`); + const {Messages}=await import(`file:///run/sausage/extensions/${loader.state().good}/extensions/messages/api.ts`); const deadline=Date.now()+30000; for(;;) { const notes=((await harness.snapshot(Messages,root.id,context)).messages as any[]).filter(message=>message.text.startsWith('[lander] Submission')&&message.text.includes(' landed as '));