Skip to content

Pi workers should not disable auto-compaction by mutating shared user settings #83

@tmustier

Description

@tmustier

Summary

Symphony's Pi runtime currently hard-disables Pi auto-compaction on every worker turn via RPC, and because Pi persists that RPC toggle to settings.json, the worker can mutate the operator's interactive Pi config.

This was introduced in the initial Pi RPC spike as a conservative simplification, but it now looks stale and actively harmful.

What I found

Original rationale

This behavior was introduced in the initial Pi worker spike:

  • 3c4f677Add Pi RPC worker spike runner
  • 635e5acDocument the Pi RPC worker contract
  • 68404ebAdd Pi worker adapter modules

The contract doc explicitly says:

Disable Pi-managed compaction for the initial spike

... compaction can be reintroduced later once multi-turn Pi worker behavior is stable

Relevant files:

  • docs/PI_RPC_CONTRACT.md
  • tools/pi-rpc-spike/client.ts
  • orchestrator/elixir/lib/symphony_elixir/pi/rpc_client.ex

Current behavior

On each worker turn, Symphony sends:

{"type":"set_auto_retry","enabled":false}
{"type":"set_auto_compaction","enabled":false}

Today, Pi implements those RPC commands by mutating and saving global settings, rather than treating them as session-local worker toggles.

So Symphony workers can end up rewriting the operator's interactive config.

Why this is a problem

1) Workers should not mutate shared interactive Pi settings

This is the immediate bug.

If the operator's ~/.pi/agent/settings.json is shared with their interactive Pi setup (or symlinked into a tracked repo, as on my machine), Symphony worker turns can silently flip:

  • compaction.enabled
  • retry.enabled

That leaks worker policy into the human operator environment.

2) The original "disable auto-compaction" rationale is likely stale

Symphony now runs multi-turn Pi workers (agent.max_turns > 1 in real workflows), which is exactly the kind of unattended / long-running process that benefits from auto-compaction.

I did not find evidence of a current concrete compaction bug that still justifies hard-disabling it.

3) Re-enabling auto-compaction is not just a one-line flip

There is one real lifecycle nuance to handle correctly:

Pi can do compaction after agent_end.

  • threshold compaction: agent_end -> compaction -> no auto-retry
  • overflow compaction: agent_end -> compaction -> auto-retry same prompt

Current Symphony WorkerRunner treats the first agent_end as final turn completion, so simply removing set_auto_compaction false may cause turn-boundary races / desync unless the worker runner learns to tolerate post-agent_end compaction/retry.

Relevant file:

  • orchestrator/elixir/lib/symphony_elixir/pi/worker_runner.ex

Proposed direction

Immediate safety fix

Do not let Pi workers share the operator's normal config dir.

When launching Pi workers, set a dedicated PI_CODING_AGENT_DIR for Symphony worker processes so any worker-scoped RPC settings cannot mutate the operator's interactive setup.

That isolates:

  • settings
  • auth/model metadata
  • package/config side effects

from the operator's main ~/.pi/agent.

Runtime fix

Stop hardcoding:

  • set_auto_compaction { enabled: false }

at least as an unconditional default.

Options:

  • remove it entirely once worker lifecycle is safe
  • or make it an explicit Symphony config option instead of a hardcoded spike artifact

Turn lifecycle fix

Before re-enabling compaction by default, make Pi worker turn completion robust to post-agent_end compaction.

Likely options:

  • after agent_end, poll get_state until isStreaming == false and isCompacting == false
  • and/or explicitly handle compaction_start / compaction_end
  • and treat compaction_end.willRetry == true as "turn still in progress"

Acceptance criteria

  • Symphony Pi workers no longer mutate the operator's interactive ~/.pi/agent/settings.json
  • Worker retry/compaction policy is isolated from the operator's normal Pi environment
  • The hardcoded set_auto_compaction false spike behavior is removed or made explicit/configurable
  • Worker turn completion correctly handles post-agent_end compaction / overflow-retry semantics
  • We can safely enable auto-compaction for unattended multi-turn Pi workers

Notes

Pi supports PI_CODING_AGENT_DIR explicitly, so Symphony should be able to isolate worker config without upstream Pi changes.

There is also a likely related leak for set_auto_retry, since Symphony sends that the same way and Pi persists it similarly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions