feat: scenarios for curator/memo-inbox/pi-grok, deploy and backup tooling

Scenarios
- memo-inbox: mirrored by copying; the live directory was not moved or modified
  and the service was not restarted. All four tracked files match byte for byte
  (pi-diff.sh reports SAME). Marked deploy = "mirror" so deploy-scenario.sh
  refuses --apply: applying a mirror would invert the direction of truth and
  could change a service in daily use.
- curator: target configuration, not yet deployed. .pi/SYSTEM.md replaces pi's
  coding-assistant prompt; durable role text is in .pi/APPEND_SYSTEM.md;
  profile.toml is the single source of truth for the launch contract.
- pi-grok: registered only. It is genuinely a coding agent, so the isolation
  baseline does not apply in full.

Corrections to the documentation, found by testing rather than by reading
- AGENTS.override.md does NOT block parent-directory context files; it only
  shadows its own directory. Verified: with an override file in the workspace, a
  marker in /tmp/AGENTS.md still reached the system prompt. The only effective
  switch is --no-context-files, so durable role text must live in
  .pi/APPEND_SYSTEM.md, which is a system-prompt file and unaffected by -nc.
  Verified end state: no coding-assistant framing, no pi-docs block, own
  identity and role text present, no parent pollution, only own skills/tools.
- PI_CODING_AGENT_DIR isolates settings/models/auth/trust/extensions/skills/
  prompts/themes under the agent directory -- stronger than the --no-* flags
  because it also repoints credentials -- but does NOT cover ~/.agents/skills.
  Measured: find-skills, modsearch and summarize still leak. So it complements
  --no-skills rather than replacing it.
- --append-system-prompt accepts a file path, which pi-grok relies on.
- cwd is what anchors .pi discovery: a probe that forgot cwd silently lost
  .pi/SYSTEM.md and kept the coding-assistant persona.

Tooling (all dry-run by default; none of them restarts a service)
- pi-diff.sh: compares tracked config against the live install in both
  directions, with a key-redacted comparison for models.json
- deploy-scenario.sh: installs a workspace and renders profile.toml into
  .pi/launch.json, then checks that every referenced path exists
- deploy-runtime.sh: renders models.json from its template, refusing placeholder
  or missing keys. Verified byte-identical to the live file
- pi-backup.sh / pi-restore.sh: archives outside the repo, sha256 manifest
  verified before any restore, live paths preserved rather than overwritten

Fixed while testing: pi-backup.sh compared the destination against the repo root
literally, so a relative --dest ./backups wrote credential archives into the work
tree. Now canonicalised with realpath; ./backups, an absolute in-repo path and
./docs/../backups are all refused.
This commit is contained in:
Kai
2026-08-26 23:17:12 -07:00
parent 7b5e0b093d
commit 07dd648b5f
20 changed files with 2611 additions and 17 deletions
+82
View File
@@ -0,0 +1,82 @@
# Scenario: memo-inbox
Routes Kai's Telegram and WeChat messages into Google Calendar, today's Obsidian
todo list, or a journal memo — without requiring slash commands or confirmation.
Live service: `pi-memo-telegram.service` (user unit, active).
Live workspace: `/home/claw/pi-workspaces/memo-inbox`.
## Migration status
**Mirrored, not yet managed.** Migrated 2026-08-27 by copying; the live
directory was not moved or modified and the service was not restarted. All four
tracked files match production byte for byte.
| Tracked | Live target |
|---|---|
| `workspace/AGENTS.md` | `<workspace>/AGENTS.md` |
| `workspace/.pi/extensions/memo-guard.ts` | `<workspace>/.pi/extensions/memo-guard.ts` |
| `workspace/.agents/skills/pi-memo-inbox/SKILL.md` | `<workspace>/.agents/skills/pi-memo-inbox/SKILL.md` |
| `workspace/bin/journal-sync.sh` | `<workspace>/bin/journal-sync.sh` |
Verify at any time:
```bash
scripts/pi-diff.sh memo-inbox
```
## Deliberately not tracked
| Path | Why |
|---|---|
| `telegram-gateway/` | Application code (622 + 343 lines), not configuration. It also sits inside the agent's own cwd, which is a separate design problem — an agent's readable workspace should not contain the program that drives it. Relocating it is a follow-up. |
| `.ccgram-uploads/` | Runtime data: inbound Telegram voice notes, photos and documents. |
| `download.html` | Generated artefact. |
| `telegram-gateway/.venv/` | Toolchain. |
| `gateway.py.bak-20260818-wechat` | Stale backup. |
## Why this scenario matters to the others
memo-inbox is the **reference implementation** for three patterns that the
curator scenario lacks. See `docs/gateway-patterns.md` for the full comparison.
1. **Long-lived RPC process.** `gateway.py` starts `pi --mode rpc` once and
drives it turn by turn, with protocol-correct `\n`-only JSONL framing.
2. **Session rotation.** Rotates after 24 prompts, plus a `messageCount >= 60`
guard. pi has no session TTL and auto-compaction does not fire on a
1.05 M-token context window, so a gateway must do this itself.
3. **Deterministic write receipts.** The reply a user sees for a state change is
harvested from `tool_execution_end` on the mutation tools, not generated by
the model. This is the single most valuable pattern in the repository.
Its `memo-guard.ts` is also the origin of `shared/extensions/pi-guard-base.ts`:
path containment, the restricted `read` override, `setActiveTools`, and the
`tool_call` block.
## Known gaps
Recorded here rather than fixed, because this service is in daily use and the
migration was scoped to zero behaviour change. Tracked as plan phase 5.
| Gap | Effect |
|---|---|
| No `--no-extensions` / `--no-skills` / `--no-prompt-templates` / `--no-themes` | `~/.pi/agent/extensions/{herdr-agent-state,pi-memo-trust}.ts` and `~/.agents/skills/{find-skills,modsearch,summarize}` load into this agent. `find-skills` instructs the agent to discover and install further skills. |
| No `.pi/SYSTEM.md` | Runs on pi's default coding-assistant prompt, including the block of absolute paths to pi's own docs with an instruction to read them and follow cross-references. `AGENTS.md` corrects course from on top of that rather than replacing it. |
| Full environment inherited | `ASR_API_KEY` and anything else in the unit reaches the node process and every extension it loads. |
| No `--no-builtin-tools` | Built-ins are active at startup and are narrowed only once `session_start` fires and `setActiveTools` runs. The `tool_call` hook still blocks them, so this is a defence-in-depth gap rather than an open hole. |
| `--continue` instead of `--session-id` | Continuity depends on "most recent session for this cwd". A stray interactive `pi` run in the same directory could be continued by the service. |
| `allowed-tools:` in SKILL.md | Not consumed by pi 0.84.3. Harmless, but do not treat it as enforcement. |
## Applying changes
```bash
scripts/deploy-scenario.sh memo-inbox # dry run, shows the diff
scripts/deploy-scenario.sh memo-inbox --apply # then restart the unit yourself
```
The deploy script never restarts a service. For this scenario:
```bash
systemctl --user restart pi-memo-telegram.service
systemctl --user status pi-memo-telegram.service
```