Skip to content

fix(pi): refresh drifted AGENTS.md in the system prompt instead of reprinting it on every compaction - #7

Merged
Valentino-Sole merged 4 commits into
mainfrom
claude/firstname-pi-server-setup-ckvbs1
Sep 4, 2026
Merged

Valentino-Sole merged 4 commits into
mainfrom
claude/firstname-pi-server-setup-ckvbs1

Conversation

@Valentino-Sole

Copy link
Copy Markdown
Owner

Summary

  • Pi reads AGENTS.md once at process start. When a firstmate self-update lands while the primary is alive, bin/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.
  • 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 (.pi/extensions/lib/fm-agents-refresh.ts), so the running session always carries the current instructions without touching the conversation.
  • It launches the digest with 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: new test_pi_before_agent_start_refreshes_drifted_project_instructions proves the swap, the unchanged-block and missing-file cases, the per-prompt recompute, and the flag reaching the digest runner
  • tests/fm-session-start.test.sh: new test_live_refreshing_pi_compact_prints_a_notice_instead_of_the_file proves the notice replaces the file under the flag and the plain path is unchanged
  • bin/fm-lint.sh (ShellCheck 0.11.0) clean
  • bin/fm-doc-audience-check.sh ok

Note: 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 origin points at this fork.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AdHwuy8oJniNyAZUKeP381


Generated by Claude Code

…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
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
@Valentino-Sole
Valentino-Sole merged commit 8b078b4 into main Sep 4, 2026
13 of 14 checks passed
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>
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.

2 participants