fix(pi): refresh drifted AGENTS.md in the system prompt instead of reprinting it on every compaction - #7
Merged
Conversation
…printing it on every compaction Pi reads AGENTS.md once at process start. When a firstmate self-update lands while the primary is alive, fm-session-start.sh bridged the stale copy by printing the complete current AGENTS.md (about 25k tokens) into every post-compaction digest for the rest of the session, which fed the compaction loop it was trying to recover from. The Pi extension now compares every <project_instructions> block in the system prompt against the file on disk at before_agent_start and returns a refreshed prompt only when one drifted, so the running session always carries the current instructions without touching the conversation. It launches the digest with FM_SESSIONSTART_AGENTS_LIVE=1, and a drifted compaction then prints a three-line notice instead of the whole file. The full-file path stays in place for any launcher that does not set the flag. Tests: tests/fm-sessionstart-nudge.test.sh proves the swap, the unchanged-block and missing-file cases, the per-prompt recompute, and the flag reaching the runner; tests/fm-session-start.test.sh proves the notice replaces the file under the flag and that the plain path is unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AdHwuy8oJniNyAZUKeP381
…erver-setup-ckvbs1
The model-display merge (#6) went in while its Lint job was still running; that job then failed on SC2034 for assignments nothing reads (FM_MODEL_SOURCE_PENDING, recorded, HARNESS, a loop counter) and one constant that only sourcing callers read. Remove the dead ones and mark the shared constant as an output global, so main lints clean again. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AdHwuy8oJniNyAZUKeP381
…ixtures The guard now imports lib/fm-agents-refresh.ts, so the two fixtures in tests/fm-turnend-guard.test.sh that load the extension under node must copy it alongside fm-operational-input.ts; CI's serial-2 shard caught the missing copy. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AdHwuy8oJniNyAZUKeP381
This was referenced Sep 5, 2026
Valentino-Sole
added a commit
that referenced
this pull request
Sep 8, 2026
…printing it on every compaction (#7) * fix(pi): refresh drifted AGENTS.md in the system prompt instead of reprinting it on every compaction Pi reads AGENTS.md once at process start. When a firstmate self-update lands while the primary is alive, fm-session-start.sh bridged the stale copy by printing the complete current AGENTS.md (about 25k tokens) into every post-compaction digest for the rest of the session, which fed the compaction loop it was trying to recover from. The Pi extension now compares every <project_instructions> block in the system prompt against the file on disk at before_agent_start and returns a refreshed prompt only when one drifted, so the running session always carries the current instructions without touching the conversation. It launches the digest with FM_SESSIONSTART_AGENTS_LIVE=1, and a drifted compaction then prints a three-line notice instead of the whole file. The full-file path stays in place for any launcher that does not set the flag. Tests: tests/fm-sessionstart-nudge.test.sh proves the swap, the unchanged-block and missing-file cases, the per-prompt recompute, and the flag reaching the runner; tests/fm-session-start.test.sh proves the notice replaces the file under the flag and that the plain path is unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AdHwuy8oJniNyAZUKeP381 * fix(bin): drop the unused variables CI lint flagged after #6 landed The model-display merge (#6) went in while its Lint job was still running; that job then failed on SC2034 for assignments nothing reads (FM_MODEL_SOURCE_PENDING, recorded, HARNESS, a loop counter) and one constant that only sourcing callers read. Remove the dead ones and mark the shared constant as an output global, so main lints clean again. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AdHwuy8oJniNyAZUKeP381 * test(pi): stage fm-agents-refresh.ts in the turnend-guard extension fixtures The guard now imports lib/fm-agents-refresh.ts, so the two fixtures in tests/fm-turnend-guard.test.sh that load the extension under node must copy it alongside fm-operational-input.ts; CI's serial-2 shard caught the missing copy. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AdHwuy8oJniNyAZUKeP381 --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
bin/fm-session-start.shbridged the stale copy by printing the complete current AGENTS.md (about 25k tokens) into every post-compaction digest for the rest of the session.<project_instructions>block in the system prompt against the file on disk atbefore_agent_startand returns a refreshed prompt only when one drifted (.pi/extensions/lib/fm-agents-refresh.ts), so the running session always carries the current instructions without touching the conversation.FM_SESSIONSTART_AGENTS_LIVE=1; a drifted compaction then prints a three-line notice instead of the whole file. The full-file path stays in place for any launcher that does not set the flag.Test plan
tests/fm-sessionstart-nudge.test.sh: newtest_pi_before_agent_start_refreshes_drifted_project_instructionsproves the swap, the unchanged-block and missing-file cases, the per-prompt recompute, and the flag reaching the digest runnertests/fm-session-start.test.sh: newtest_live_refreshing_pi_compact_prints_a_notice_instead_of_the_fileproves the notice replaces the file under the flag and the plain path is unchangedbin/fm-lint.sh(ShellCheck 0.11.0) cleanbin/fm-doc-audience-check.shokNote: like #6, this PR is raised outside the no-mistakes pipeline, so the "PR must be raised via no-mistakes" attestation check cannot pass until the home's
originpoints at this fork.🤖 Generated with Claude Code
https://claude.ai/code/session_01AdHwuy8oJniNyAZUKeP381
Generated by Claude Code