diff --git a/docs/verification/runtime-backends.md b/docs/verification/runtime-backends.md index f48bf9b535e..910375246b4 100644 --- a/docs/verification/runtime-backends.md +++ b/docs/verification/runtime-backends.md @@ -2210,6 +2210,25 @@ FM_TEST_END 2026-08-29T01:01:01Z tests/fm-pi-branch-live-e2e.test.sh exit=0 dura The focused extension suite also exercised the installed Pi 0.84.4 picker and outcome-renderer consumers; [`calm-mode-feasibility.md`](../calm-mode-feasibility.md#2026-08-28-pi-0844-outcome-renderer-compatibility-verification) owns the version-scoped renderer evidence. +### 2026-10-05 Pi Calm export compatibility + +Verified on Linux x86_64 with Node v22.23.2, Chromium 152.0.7977.82, and Pi 0.99.2 plus a scratch-installed Pi 1.0.3. +For each installation, `FM_PI_PACKAGE_DIR` selected its importable package and `PATH` selected its matching CLI before running: + +```sh +bash bin/fm-test-run.sh tests/fm-calm-pi-extension.test.sh tests/fm-calm-pi-queue-retention-live-e2e.test.sh +``` + +Both versions passed the renderer assertions, real interactive `/export`, rendered export DOM, and queue-retention live guard with no skipped gates. +The export fixture supplies both Pi's legacy `getToolDefinition` lookup and the `getToolRenderers` lookup used by 1.0.3, preserving the positive export assertion and the non-submit negative assertion against each installed implementation. +The Calm extension requires no change for this lookup rename. +The version-specific live-guard output was: + +```text +ok - Pi 0.99.2 exposes every queue-retention member Calm preflights before hiding queued Firstmate rows +ok - Pi 1.0.3 exposes every queue-retention member Calm preflights before hiding queued Firstmate rows +``` + ### 2026-08-29 deterministic captain-outcome delivery The credential-free live guard, focused extension suite, store suite, and strict typecheck were run against the locally installed `@earendil-works/pi-coding-agent` 0.84.3 package. diff --git a/tests/fm-calm-pi-extension.test.sh b/tests/fm-calm-pi-extension.test.sh index 287c5de2b0e..d6e77906afe 100755 --- a/tests/fm-calm-pi-extension.test.sh +++ b/tests/fm-calm-pi-extension.test.sh @@ -1664,6 +1664,8 @@ async function assertStockHtmlRendering(command, submitData) { terminalInputHandler(submitData); const htmlRenderer = createToolHtmlRenderer({ getToolDefinition: (name) => tools.find((tool) => tool.name === name), + // Newer Pi uses getToolRenderers; older Pi still uses getToolDefinition. + getToolRenderers: (name) => tools.find((tool) => tool.name === name), theme, cwd: process.cwd(), }); @@ -1695,6 +1697,7 @@ editorText = "/export remapped.html"; terminalInputHandler("\r"); const unmatchedRenderer = createToolHtmlRenderer({ getToolDefinition: (name) => tools.find((tool) => tool.name === name), + getToolRenderers: (name) => tools.find((tool) => tool.name === name), theme, cwd: process.cwd(), }); diff --git a/tests/fm-pi-branch-extension.test.sh b/tests/fm-pi-branch-extension.test.sh index eb3f48e63a6..b634219fd52 100644 --- a/tests/fm-pi-branch-extension.test.sh +++ b/tests/fm-pi-branch-extension.test.sh @@ -5278,8 +5278,8 @@ if (JSON.stringify(actualRow.render(100)) !== JSON.stringify(stockRow.render(100 } pi.events.emit("firstmate:calm-presentation", { active: true, stockExportRendering: true }); -const stockHtml = createToolHtmlRenderer({ getToolDefinition: () => stockDefinition, theme, cwd: process.cwd() }); -const actualHtml = createToolHtmlRenderer({ getToolDefinition: () => actualDefinition, theme, cwd: process.cwd() }); +const stockHtml = createToolHtmlRenderer({ getToolDefinition: () => stockDefinition, getToolRenderers: () => stockDefinition, theme, cwd: process.cwd() }); +const actualHtml = createToolHtmlRenderer({ getToolDefinition: () => actualDefinition, getToolRenderers: () => actualDefinition, theme, cwd: process.cwd() }); const stockCall = stockHtml.renderCall("stock-html", "fm_branch_outcomes", args); const actualCall = actualHtml.renderCall("actual-html", "fm_branch_outcomes", args); const stockResult = stockHtml.renderResult("stock-html", "fm_branch_outcomes", result.content, result.details, false);