Skip to content

test: support Pi 1.0.1 in the Calm renderer contract - #6512

Closed
mremond wants to merge 2 commits into
kunchenguid:mainfrom
mremond:fm/fm-pi-101-calm-renderer-test
Closed

mremond wants to merge 2 commits into
kunchenguid:mainfrom
mremond:fm/fm-pi-101-calm-renderer-test

Conversation

@mremond

@mremond mremond commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Intent

Repair the upstream CI test "Pi calm renderer and lifecycle contract" (tests/fm-calm-pi-extension.test.sh, run in the Behavior portable serial 6 shard), which fails on main since the CI runner moved to Pi 1.0.1 and turns open PRs red, for example #6505 (failing run: https://github.com/kunchenguid/firstmate/actions/runs/37139608278). Keep the fix to that test/renderer compatibility. The maintainer merges.

Known evidence: the same lane fails identically on main and on unrelated PR heads after the runner upgrade from Pi 1.0.0 to 1.0.1. Pi 1.0.1's renderer expects a getToolRenderers hook where the test's fake session provides getToolDefinition (tests/fm-calm-pi-extension.test.sh around lines 1666 and 1697). No outside PR or issue covered this as of 2026-10-03.

What Changed

  • Update both Calm HTML-renderer fixtures to supply getToolRenderers for Pi 1.0.1 alongside the older getToolDefinition hook, sharing one registered-tool lookup and preserving existing assertions.
  • Document Pi 1.0.1 and 1.0.0 verification evidence, refresh commands, and updated evidence links.

Risk Assessment

✅ Low: The change narrowly repairs both renderer fixtures, preserves existing assertions and older compatibility, and leaves production behavior unchanged.

Testing

Reproduced the baseline failure; both version-specific Calm suites and the live keybinding guard passed. Retained native exports, terminal transcripts, and Chrome screenshots. Resolved a temporary-path wrapping issue and bounded Chrome cleanup. No broad suite, lint, remote CI, or publication was performed.

  • Live validation: ✅ go - 3 of 3 scenarios driven live against the product
Scenario Result Live Evidence
Run Calm validation on Pi 1.0.1 and export a real session: the suite passes and grep, find, and watcher call/result content survives export. ✅ pass live target-pi-1.0.1-short/test.log, actual calm-export.html, and Pi 1.0.1 screenshot; baseline-pi-1.0.1/test.log records the original failure.
Run the same validation and native export on Pi 1.0.0: the older renderer remains compatible. ✅ pass live pi-1.0.0/test.log, actual calm-export.html, and Pi 1.0.0 screenshot.
Remap submission to Alt+S and press Enter on an export command: no export occurs or hidden tool output appears; Alt+S then exports successfully. ✅ pass live live-guard/test.log, live-guard/remapped-enter.txt, and live-guard/export-settled.txt.
Evidence: Validation evidence and reproduction commands

Source: Validation evidence and reproduction commands

# Pi Calm renderer compatibility validation

Target: `02ea4dbf351251a3bfba31f81c979f3131a4e2a7`, tree `b9621b9ccdc42ab6a79780f571b407a162d38d29`.
Base: `1f3e769616fdf9f31f85f4c3e6a9f71606634238`.
Environment: macOS, Node v25.9.0, npm 11.17.0, Chrome 154.0.8037.97.

| Check | Result and evidence |
| --- | --- |
| Original test on Pi 1.0.1 | Reproduced `grep disappeared from /export calm.html HTML while calm mode was on`; [baseline transcript](baseline-pi-1.0.1/test.log). |
| Target on Pi 1.0.1 | Complete targeted Calm suite passed without skips, including real terminal sessions and export; [transcript](target-pi-1.0.1-short/test.log), [actual product export](target-pi-1.0.1-short/calm-export.html), [Chrome screenshot](pi-1.0.1-export.png). |
| Target on Pi 1.0.0 | Same suite and native checks passed without skips; [transcript](pi-1.0.0/test.log), [actual product export](pi-1.0.0/calm-export.html), [Chrome screenshot](pi-1.0.0-export.png). |
| Adversarial remapped input on Pi 1.0.1 | With Alt+S configured as submit, Enter left the command in the editor, wrote no HTML, and kept tool output hidden across 20 observations; Alt+S then exported successfully. [Transcript](live-guard/test.log), [after Enter](live-guard/remapped-enter.txt), [after Alt+S](live-guard/export-settled.txt). |

Native checks used the real Pi CLI, Calm extension, renderer, exporter, and Chrome on synthetic session data and provider responses, with isolated settings and test-owned 180x44 tmux terminals.
[Extracted output](export-tool-output.json) retains actual grep, find, and watcher call/result HTML from all three successful native exports.
Both screenshots were visually inspected and show that content.
The suite also passed component assertions for `/share`, non-submit input, and renderer/lifecycle behavior on both versions; those component assertions are supporting evidence, not live GitHub publication.

## Reproduction

Installed each version locally with:

`` `sh
npm install --global --prefix "$PWD/.no-mistakes/test-lab/pi-1.0.1" --cache "$PWD/.no-mistakes/test-lab/npm-cache" --no-audit --no-fund @earendil-works/pi-coding-agent@1.0.1
npm install --global --prefix "$PWD/.no-mistakes/test-lab/pi-1.0.0" --cache "$PWD/.no-mistakes/test-lab/npm-cache" --no-audit --no-fund @earendil-works/pi-coding-agent@1.0.0
`` `

The retained [collector](run.py) selects the same version via PATH and FM_PI_PACKAGE_DIR, isolates temporary/config paths, clears fleet overrides, and invokes `bash bin/fm-test-run.sh tests/fm-calm-pi-extension.test.sh`.
Its exact invocations were:

`` `sh
python3 .no-mistakes/test-lab/run.py 1.0.1 baseline-pi-1.0.1 tests/.fm-calm-pi-baseline.test.sh
python3 .no-mistakes/test-lab/run.py 1.0.1 target-pi-1.0.1 tests/fm-calm-pi-extension.test.sh
python3 .no-mistakes/test-lab/run.py 1.0.1 target-pi-1.0.1-short tests/fm-calm-pi-extension.test.sh
python3 .no-mistakes/test-lab/run.py 1.0.0 pi-1.0.0 tests/fm-calm-pi-extension.test.sh
python3 .no-mistakes/test-lab/run.py 1.0.1 live-guard tests/.fm-calm-pi-live-guard.test.sh
`` `

The baseline file came from `git show 1f3e769616fdf9f31f85f4c3e6a9f71606634238:tests/fm-calm-pi-extension.test.sh`.
The extra native guard was a disposable copy of the existing interactive test; its [exact patch](live-guard-driver.patch) adds the non-submit observation and selects that native scenario.
The [screenshot driver](screenshot.py) captures the real exported pages with isolated headless Chrome profiles.
No production code or permanent test was edited.

## Resolved setup issues and limits

The first target run exported successfully but its very long disposable path wrapped the confirmation after `Session exported to:`, failing the existing single-line string assertion.
The [terminal transcript](target-pi-1.0.1/export.txt) proves export completed.
Shortening the temporary root from `.no-mistakes/test-lab/tmp/` to `.v/`, still inside the workspace, fixed setup; the unchanged suite then passed on Pi 1.0.1 in 54.2 seconds and on Pi 1.0.0 in 53.9 seconds.
The initial standalone Chrome screenshot succeeded but Chrome remained running until its 35-second timeout; the final driver stops its own process after capture and succeeded for both versions.

Only the assigned test phase ran: no linters, static analysis, full repository suite, remote CI, publication, or merge.
Pi 0.85.1 was not retested; the required regression and predecessor axes were Pi 1.0.1 and 1.0.0.
The outer executor owns remaining phases and CI; the maintainer owns merging.
Disposable installations, caches, fixture homes, browser profiles, and temporary test scripts were cleaned up; evidence is retained here.
Evidence: Original Pi 1.0.1 failure reproduced

Source: Original Pi 1.0.1 failure reproduced

command: bash bin/fm-test-run.sh tests/.fm-calm-pi-baseline.test.sh
target: 02ea4dbf351251a3bfba31f81c979f3131a4e2a7
Pi: 1.0.1
Node: v25.9.0
FM_TEST_BEGIN 2026-10-03T18:44:55Z tests/.fm-calm-pi-baseline.test.sh family=unclassified expected_gate_skip=none
ok - Pi calm resolves its persistent home independently of Pi's launch directory
ok - Pi calm compatibility evidence never rejects a Pi version for being newer than 0.82.0, and still fails closed on a missing or malformed version
ok - a missing collapsed-thinking presentation API degrades only that Calm adapter with a clear skip reason, while the rest of Calm still registers
ok - missing Pi presentation class exports reach the independent adapter degradation path
ok - Calm hides queued Firstmate rows only on a session that can keep them, keeps hidden ones out of the editor on Escape, delivers them once in order, and leaves unsupported sessions and Calm off stock
ok - Calm registers none of its 7 built-in tool wrappers at load while config/calm is off, and all 7 synchronously at load while config/calm is on
ok - Calm's first same-session /calm activation claims every uncontested built-in, leaves a foreign bash tool fully intact and callable, warns prominently and logs the contested name, and only rows constructed before that activation - the documented bound - fail to retroactively collapse
not ok - Pi calm renderer and lifecycle contract failed: file://~/.no-mistakes/worktrees/acf4a767348a/01M41GZ8K0CW9VW3DVRVCQTVTP/.no-mistakes/test-lab/tmp/baseline-pi-1.0.1/fm-calm-pi-extension.KwYUyY/renderer/[eval1]:546
      throw new Error(`${name} disappeared from ${command} HTML while calm mode was on`);
            ^

Error: grep disappeared from /export calm.html HTML while calm mode was on
    at assertStockHtmlRendering (file://~/.no-mistakes/worktrees/acf4a767348a/01M41GZ8K0CW9VW3DVRVCQTVTP/.no-mistakes/test-lab/tmp/baseline-pi-1.0.1/fm-calm-pi-extension.KwYUyY/renderer/[eval1]:546:13)
    at file://~/.no-mistakes/worktrees/acf4a767348a/01M41GZ8K0CW9VW3DVRVCQTVTP/.no-mistakes/test-lab/tmp/baseline-pi-1.0.1/fm-calm-pi-extension.KwYUyY/renderer/[eval1]:553:7
    at process.processTicksAndRejections (node:internal/process/task_queues:104:5)

Node.js v25.9.0
FM_TEST_END 2026-10-03T18:45:00Z tests/.fm-calm-pi-baseline.test.sh exit=1 duration_ms=4818 gate_skip=false
FM_TEST_SUMMARY total=1 failed=1 skipped_gate=0 duration_ms=4880
FM_TEST_SUMMARY_FAMILY family=unclassified count=1 duration_ms=4818 failed=1
FM_TEST_SLOWEST rank=1 script=tests/.fm-calm-pi-baseline.test.sh duration_ms=4818

process_exit=1
Evidence: Non-submit Enter leaves export pending

Source: Non-submit Enter leaves export pending


 ▀▀█  v1.0.1
 █▀ █ escape to interrupt
 ctrl+c to clear
 ctrl+c twice to exit
 ctrl+d to exit (empty)
 ctrl+z to suspend
 ctrl+k to delete to end
 shift+tab to cycle thinking level
 ctrl+p/shift+ctrl+p to cycle models
 ctrl+l to select model
 ctrl+o to expand tools
 ctrl+t to expand thinking
 ctrl+g for external editor
 / for commands
 ! to run bash
 !! to run bash (no context)
 option+enter to queue follow-up
 option+up to edit all queued messages
 ctrl+v to paste files on macOS, images, or text
 drop files to attach

 Pi can explain its own features and look up its docs. Ask it how to use or extend Pi.

[Extensions]
  project
    ~/.no-mistakes/worktrees/acf4a767348a/01M41GZ8K0CW9VW3DVRVCQTVTP/.v/live-guard/fm-calm-pi-extension.jNWWs7/e2e-project/.pi/extensions/fm-calm-e2e-inject.ts
    ~/.no-mistakes/worktrees/acf4a767348a/01M41GZ8K0CW9VW3DVRVCQTVTP/.v/live-guard/fm-calm-pi-extension.jNWWs7/e2e-project/.pi/extensions/fm-calm.ts
    ~/.no-mistakes/worktrees/acf4a767348a/01M41GZ8K0CW9VW3DVRVCQTVTP/.v/live-guard/fm-calm-pi-extension.jNWWs7/e2e-project/.pi/extensions/fm-primary-pi-watch.ts
    ~/.no-mistakes/worktrees/acf4a767348a/01M41GZ8K0CW9VW3DVRVCQTVTP/.v/live-guard/fm-calm-pi-extension.jNWWs7/e2e-project/.pi/extensions/fm-primary-turnend-guard.ts


 Show a deterministic tool example.



 $ printf 'CALM_E2E_OUTPUT
 '

 CALM_E2E_OUTPUT



 grep /CALM_EXPORT_GREP/ in .

 sample.txt:1:CALM_EXPORT_GREP



 find CALM_EXPORT_FIND* in .

 CALM_EXPORT_FIND.txt



 FIRSTMATE WATCHER WAKE: can you explain this phrase?



 Captain quote: ⁣FIRSTMATE_OP: v1 watcher: QUOTED_CURRENT_NEAR_MISS



 FIRSTMATE_OP: v1 watcher: ASCII_ONLY_NEAR_MISS



 Ordinary captain text before ⁣FIRSTMATE_OP: v1 watcher: EMBEDDED_CURRENT_NEAR_MISS



 ⁣ordinary captain text after unrelated separator


 The deterministic tool example is complete.

 Warning: Could not restore model anthropic/claude-sonnet-4-5. Using calm-e2e/delayed

 Warning: tmux extended-keys is off. Modified Enter keys may not work. Add `set -g extended-keys on` to ~/.tmux.conf and restart tmux.

 Tool output: expanded

 Warning: CALM_TRANSIENT_DIAGNOSTIC

 Error: CALM_OPERATIONAL_E2E_ERROR
 If this looks like a pi bug, /bug sends a report to the developers.

 Error: CALM_OPERATIONAL_E2E_ERROR

 Error: CALM_OPERATIONAL_E2E_ERROR

 Error: CALM_OPERATIONAL_E2E_ERROR

 Error: CALM_OPERATIONAL_E2E_ERROR

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
/export ~/.no-mistakes/worktrees/acf4a767348a/01M41GZ8K0CW9VW3DVRVCQTVTP/.v/live-guard/fm-calm-pi-extension.jNWWs7/calm-export.html
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
~/.no-mistakes/worktrees/acf4a767348a/01M41GZ8K0CW9VW3DVRVCQTVTP/.v/live-guard/fm-calm-pi-extension.jNWWs7/e2e-project (main)
↑7 ↓4 44.9%/4.1k (auto)                                                                                                                                            operational-error

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • Live validation: ✅ go - 3 of 3 scenarios driven live against the product
Scenario Result Live Evidence
Run Calm validation on Pi 1.0.1 and export a real session: the suite passes and grep, find, and watcher call/result content survives export. ✅ pass live target-pi-1.0.1-short/test.log, actual calm-export.html, and Pi 1.0.1 screenshot; baseline-pi-1.0.1/test.log records the original failure.
Run the same validation and native export on Pi 1.0.0: the older renderer remains compatible. ✅ pass live pi-1.0.0/test.log, actual calm-export.html, and Pi 1.0.0 screenshot.
Remap submission to Alt+S and press Enter on an export command: no export occurs or hidden tool output appears; Alt+S then exports successfully. ✅ pass live live-guard/test.log, live-guard/remapped-enter.txt, and live-guard/export-settled.txt.
  • Workspace-local npm installations of @earendil-works/pi-coding-agent@1.0.1 and @1.0.0, selecting matching PATH and FM_PI_PACKAGE_DIR.
  • bash bin/fm-test-run.sh tests/.fm-calm-pi-baseline.test.sh using the base test on Pi 1.0.1: reproduced the reported HTML failure.
  • bash bin/fm-test-run.sh tests/fm-calm-pi-extension.test.sh on Pi 1.0.1 and 1.0.0: complete targeted suite passed without skips, including native TUI/export checks and supporting component assertions.
  • bash bin/fm-test-run.sh tests/.fm-calm-pi-live-guard.test.sh: disposable native test of Enter versus Alt+S submission.
  • Headless Chrome screenshots of both real exports, visual inspection, and extraction of generated tool HTML.
  • Cleanup verification: clean git status, unchanged target commit, and no remaining processes referencing disposable paths.
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@greptile-apps

greptile-apps Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Low risk] Test documentation updates for Pi renderer compatibility.

The PR appears safe to merge; no actionable issue was established in the changed test or documentation.

Reviews (1) · Last reviewed commit: "fix(document): Clarify Pi renderer verif..."

@mremond

mremond commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

Closing as superseded: #6530 fixed the same Pi 1.0.1 renderer-lookup break on main.

@mremond mremond closed this Oct 4, 2026
cloud-practitioner added a commit to cloud-practitioner/firstmate that referenced this pull request Oct 5, 2026
Supply getToolRenderers alongside getToolDefinition in both Calm HTML-renderer fixtures, and record the Pi 1.0.1 verification evidence.

Ported from upstream kunchenguid#6512 by @mremond.
Both upstream commits are combined into one; applied unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant