Commit Graph
3 Commits
Author SHA1 Message Date
Kai 943f631966 fix(pi_rpc): detect a dead pi process immediately, not at the turn deadline
When pi died mid-turn, _read_stdout saw EOF and logged it, but nothing woke
_consume -- it sat on the event queue until asyncio.timeout(budget) fired at the
turn deadline (180 s). A dead process at second 3 was therefore reported as "no
reply" at second 180, and the fallback that launched a fresh pi hid the death
entirely. To the user this read as a hard hang.

_read_stdout now enqueues a "_process_exited" sentinel on EOF, and _consume
raises PiRpcError on it, so the failure path (same-session fallback model, then
rotation, then a fresh process) starts within milliseconds.

Smoke-tested: SIGKILL the child during a command and the client reports it in
0.0 s instead of the full budget, with no orphan left behind.
2026-08-28 21:17:21 -07:00
Kai b5a29b05e1 docs: mark phase 3 complete, record the skills and caching findings
Two findings that changed the plan rather than confirming it:

  23. Skills require a tool literally named `read`. Curator's tools are all
      domain-specific, so every --skill argument was discarded in silence. The
      planned split into curator-core / video-arr / books-ingest was inert before
      it was written; the policy stays in APPEND_SYSTEM.md. memo-inbox is
      unaffected because it registers a restricted `read` override, which is why
      the earlier note generalised wrongly from it.

  24. A long-lived session is worth far more than the startup it saves: 99.97% of
      input read from cache on a continuing conversation against 0% on a new one.
      That is what makes the generated tool list necessary rather than merely
      tidy -- anything varying at the front of the prompt destroys it -- and it
      makes rotation a cost to be bounded rather than applied eagerly.

profile.toml now describes the phase-3 configuration that is actually deployed,
including that the empty `skills` list is a finding and not an oversight.
pi_rpc gains --system-prompt support and no longer guesses whether a `read` tool
will exist; extension_registers_read has to be stated.

harness-layering.md records what transfers from a widely-shared account of
building a personal coding harness on pi, and what does not. The layering frame
holds and the cache-hit figure was the useful part. Its central recommendation --
installing third-party packages -- is disqualifying for an unattended agent
holding tracker credentials, and its discipline layer (AGENTS.md) is precisely
what we block, because it is discovered from every parent directory.
2026-08-28 01:10:58 -07:00
Kai 65d2f5988b feat(shared): long-lived Pi RPC client extracted from the memo-inbox gateway
Generalises PiRPC from pi-workspaces/memo-inbox/telegram-gateway/gateway.py,
which has run this pattern in production since 2026-07, and closes the four gaps
both existing scenarios shared:

- explicit minimal env, so provider and backend API keys never reach the node
  process (verified: 6 variables, an injected secret is withheld)
- start_new_session plus killpg on stop, so a stuck node tree cannot outlive the
  turn (verified: no orphan after stop)
- the loading-isolation flags are part of the launch contract instead of
  something each caller has to remember
- a per-turn deadline enforced with RPC abort rather than by killing the process

Retains the original's proven mechanics: strict newline-only JSONL framing,
correlation by id, agent_settled as terminal event, and receipts harvested from
tool_execution_end rather than from model prose.

PiLaunchConfig warns when skills are configured but no 'read' tool can be
active, which is exactly the condition that silently disabled Curator's SKILL.md.

Includes a zero-token smoke test: it drives a real pi process with get_state
only, so no model call is billed.
2026-08-26 22:55:21 -07:00