renderProjectContext in packages/pi-subagents/src/session/project-context.ts still emits pi ≤0.85's <project_context> shape, so the block a relocated or portable child renders for itself no longer matches the one pi ≥0.86 writes — while its doc comment claims it does, "byte for byte".
Current behavior
The replica produces an extra blank line below the opening tag and another above the closing tag:
<project_context>
Project-specific instructions and guidelines:
<project_instructions path="/parent/AGENTS.md">
# AGENTS
Parent house rules.
</project_instructions>
</project_context>
pi 0.86.1 writes neither. Its renderProjectContext joins the lead-in and each <project_instructions> block with "\n\n" and the section wrapper contributes the surrounding newlines, so the real block is:
<project_context>
Project-specific instructions and guidelines:
<project_instructions path="/parent/AGENTS.md">
# AGENTS
Parent house rules.
</project_instructions>
</project_context>
I generated that from the 0.86.1 dist directly:
pnpm view @earendil-works/pi-coding-agent@0.86.1 dist.tarball
# then, against a scratch install of 0.86.1:
node -e 'import("./node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js")
.then(m => console.log(m.buildSystemPrompt({
cwd: "/parent",
customPrompt: "x",
contextFiles: [{ path: "/parent/AGENTS.md", content: "# AGENTS\n\nParent house rules." }],
})))'
Expected behavior
The replica renders whichever shape the running pi writes, or the doc comment stops claiming byte-identity it no longer has.
Why it matters
The module's doc comment is the contract:
Render context files as Pi's <project_context> block, byte for byte.
Pi writes a lead-in sentence and separates each <project_instructions> block with a blank line; matching it exactly is what keeps a block this package renders indistinguishable from one buildSystemPrompt wrote.
That is now false on 0.86, which is the version the peer range (>=0.81.0, unbounded) admits and the one I am running.
The consumers are exactly the two children ADR 0010 and ADR 0009 route here: a child a WorkspaceProvider relocated, and a portable child. Nothing anchors on the extra blank lines today — projectContextStart's lead-in guard tolerates both offsets — so I read this as low severity. It is a correctness claim that has quietly gone stale rather than an observed failure, and I would rather fix the claim than discover later what was relying on it.
Relationship to #958
Same root cause — pi 0.86's prompt reshape — but a different code path. #958 is about the anchors that read an inherited prompt; this is about the block this package writes. Keeping them separate so #958's fix stays reviewable.
Environment
- pi 0.86.1 (
pi --version)
packages/pi-subagents devDependency pinned at @earendil-works/pi-coding-agent@0.84.4
- Peer range
>=0.81.0
renderProjectContextinpackages/pi-subagents/src/session/project-context.tsstill emits pi ≤0.85's<project_context>shape, so the block a relocated orportablechild renders for itself no longer matches the one pi ≥0.86 writes — while its doc comment claims it does, "byte for byte".Current behavior
The replica produces an extra blank line below the opening tag and another above the closing tag:
pi 0.86.1 writes neither. Its
renderProjectContextjoins the lead-in and each<project_instructions>block with"\n\n"and the section wrapper contributes the surrounding newlines, so the real block is:I generated that from the 0.86.1 dist directly:
Expected behavior
The replica renders whichever shape the running pi writes, or the doc comment stops claiming byte-identity it no longer has.
Why it matters
The module's doc comment is the contract:
That is now false on 0.86, which is the version the peer range (
>=0.81.0, unbounded) admits and the one I am running.The consumers are exactly the two children ADR 0010 and ADR 0009 route here: a child a
WorkspaceProviderrelocated, and aportablechild. Nothing anchors on the extra blank lines today —projectContextStart's lead-in guard tolerates both offsets — so I read this as low severity. It is a correctness claim that has quietly gone stale rather than an observed failure, and I would rather fix the claim than discover later what was relying on it.Relationship to #958
Same root cause — pi 0.86's prompt reshape — but a different code path. #958 is about the anchors that read an inherited prompt; this is about the block this package writes. Keeping them separate so #958's fix stays reviewable.
Environment
pi --version)packages/pi-subagentsdevDependency pinned at@earendil-works/pi-coding-agent@0.84.4>=0.81.0