Files
pi-agent-config/README.md
T
Kai cf61a72bd2 feat(curator): deploy the phase-0 system prompt, and correct a misleading README figure
The workspace now holds .pi/SYSTEM.md and .pi/APPEND_SYSTEM.md and nothing else.

SYSTEM.md is rewritten for what is actually deployed. The version committed in
07dd648 described five tools that will not exist until phase 3; shipping it would
have invited the model to call tools it does not have. The capability section now
states plainly that the agent has no tools and that every fact arrives in the
request. The phase-3 target, including the full tool-bearing launch contract, is
recorded in the plan as §4b together with why each part cannot be enabled sooner.

profile.toml likewise describes the deployed configuration rather than the target,
so that deploy-scenario.sh validates against reality and the path check means
something.

Recovered from the retired SKILL.md and folded into SYSTEM.md: the rule that the
current request's schema and length limits override everything else, and that a
JSON task returns exactly one JSON value with no fences. Phase 0's four prompt
types all depend on it, and it was the one part of that file not already covered.

Measured before and after on the real workspace, with flags read from the code
rather than transcribed (docs/evidence/2026-08-27-curator-phase0-prompt.md):

- expert coding assistant framing: present -> gone
- pointer to pi's own documentation: present -> gone
- the 64-line media policy: absent -> present
- workspace AGENTS.md: loaded -> blocked
- parent-directory AGENTS.md: LEAKED -> blocked
- <available_skills>: absent both times

Two things this confirms on the production configuration rather than a synthetic
probe. --skill was genuinely a no-op: it pointed at a real 64-line SKILL.md and
the skills block was still absent, because pi emits it only when a tool named
read is active and --no-tools deactivates everything. And --no-context-files is
the only switch that stops parent-directory pollution: a marker planted in
/home/claw/pi-workspaces/AGENTS.md reached the prompt before and not after.

Deleting the now-dead AGENTS.md and SKILL.md from the workspace changed the
prompt length by zero bytes, which is the proof that they were dead.

README corrected. Its table cited 960 characters as Curator's system prompt after
the change; that figure came from a few-line stub SYSTEM.md in the isolation
probe, and the real prompt is 3539 -- larger, not smaller. Presenting the stub
measurement as Curator's was misleading, and "72% smaller" was wrong. The prompt
grew because roughly 1.9 KB of pi scaffolding was replaced by domain policy that
had never loaded at all. The mechanism claim is unaffected.
2026-08-27 23:09:20 -07:00

138 lines
5.6 KiB
Markdown

# pi-agent-config
Authoritative configuration for every [Pi](https://pi.dev) agent on this host:
the user-level Pi runtime, plus one directory per dedicated agent scenario.
The live locations (`~/.pi/agent`, `~/pi-workspaces/*`) are **runtime copies**.
Changes are made here and pushed out with `scripts/deploy-*.sh`, never the other
way round — except for scenarios explicitly marked `deploy = "mirror"`, which
record what a running service already does.
Verified against **pi 0.84.3**. Re-run the probes after every `pi update`.
## Scenarios
| Scenario | Purpose | Service | Status |
|---|---|---|---|
| [`curator`](scenarios/curator/) | Book / film / TV / music curation agent | `curator.service` | target config written, **not yet deployed** |
| [`memo-inbox`](scenarios/memo-inbox/) | Routes Telegram/WeChat messages to Calendar, Obsidian todo or journal | `pi-memo-telegram.service` | **mirror** of live config, zero behaviour change |
| [`pi-grok`](scenarios/pi-grok/) | Interactive Grok 4.6 coding agent | none (manual) | registered only |
## Start here
| Document | Contents |
|---|---|
| [`docs/pi-runtime-notes.md`](docs/pi-runtime-notes.md) | pi 0.84.3 mechanics that the official docs understate, each verified against source or a live probe |
| [`docs/isolation-baseline.md`](docs/isolation-baseline.md) | The four isolation layers and the flag set every scenario should use |
| [`docs/personality-layering.md`](docs/personality-layering.md) | How to choose between `SYSTEM.md`, `APPEND_SYSTEM.md`, `AGENTS.md`, `SKILL.md` and the request |
| [`docs/gateway-patterns.md`](docs/gateway-patterns.md) | Ten patterns for hosting an agent behind a long-running service |
| [`docs/plans/`](docs/plans/) | Active work plans |
## The finding that motivated this repository
pi emits the `<available_skills>` block **only when a tool named `read` is
active** (`dist/core/system-prompt.js:59,113`). The Curator service ran with
`--no-tools --skill …` for its entire lifetime, so:
- its 64-line media policy never reached the model,
- `--skill` was a no-op,
- and both the README and the deployment runbook described a mechanism that was
not happening.
Measured on the real workspace, before and after
([evidence](docs/evidence/2026-08-27-curator-phase0-prompt.md)):
| | before | after |
|---|---|---|
| system prompt | 2548 chars | 3539 chars |
| `expert coding assistant` framing | present | **gone** |
| pointer to pi's own documentation | present | **gone** |
| the 64-line media policy | **absent** | present |
| `<available_skills>` | absent | absent |
| workspace `AGENTS.md` | loaded | blocked |
| parent-directory `AGENTS.md` | **leaked** | blocked |
The prompt got *larger*, and that is the fix rather than its cost: of the
original 2548 characters roughly 1.9 KB was pi's coding-assistant scaffolding and
a pointer telling the agent to read pi's documentation and follow its
cross-references — noise for a media agent, and a ready-made escalation path for
injected text — while none of it was Curator's own policy. All 3539 characters
now are.
A mechanism demonstration with a stub `SYSTEM.md` is in
[`docs/evidence/2026-08-27-isolation-probe.md`](docs/evidence/2026-08-27-isolation-probe.md);
its 960-character figure measures the stub, not Curator.
Reproduce either with [`docs/evidence/probe-harness/`](docs/evidence/probe-harness/)
— zero model tokens, because a single RPC `get_state` starts the agent, fires
`session_start` and exits without contacting the provider.
## Layout
```
docs/ mechanics, baselines, plans, reproducible evidence
runtime/agent/ ~/.pi/agent — settings, models.json.template, extensions, prompts
shared/ cross-scenario code
lib/py/pi_rpc.py long-lived RPC client with rotation and budgets
extensions/pi-guard-base.ts path containment, restricted read, capability guard
scenarios/<name>/
profile.toml single source of truth for the launch contract
workspace/ what gets installed into the live workspace
eval/ recorded golden transcripts
scripts/ diff, deploy, backup, restore, secret guard
secrets/ host-local, untracked
```
## Usage
```bash
# What differs between this repository and the host?
scripts/pi-diff.sh
scripts/pi-diff.sh curator
# Push configuration out (dry run first; neither restarts a service)
scripts/deploy-runtime.sh
scripts/deploy-runtime.sh --apply
scripts/deploy-scenario.sh curator --apply
# Back up the live installation (archives land outside this repository)
scripts/pi-backup.sh
scripts/pi-restore.sh --from <backup dir>
# Verify the mechanics still hold after a pi upgrade
docs/evidence/probe-harness/collect-evidence.sh
shared/extensions/tests/run-guard-checks.sh
python3 shared/lib/py/tests/test_pi_rpc_smoke.py
```
## Secrets
Nothing real ever enters this repository. `models.json`, `auth.json`,
`trust.json` and every `*.env` are ignored; `secrets/` accepts only `.gitkeep`,
`README.md`, `*.example` and `*.template`.
`scripts/verify-no-secrets.sh` enforces this as a pre-commit hook. Install it in
a fresh clone:
```bash
ln -sf ../../scripts/verify-no-secrets.sh .git/hooks/pre-commit
scripts/verify-no-secrets.sh --all
```
Backups contain plaintext credentials and are written outside the work tree;
`pi-backup.sh` refuses any destination that resolves inside it.
## First-time setup on a new host
```bash
git clone gitea-45:kai/pi-agent-config.git && cd pi-agent-config
ln -sf ../../scripts/verify-no-secrets.sh .git/hooks/pre-commit
cp secrets/zenmux.env.example secrets/zenmux.env
chmod 600 secrets/zenmux.env && $EDITOR secrets/zenmux.env
npm install -g @earendil-works/pi-coding-agent@0.84.3
scripts/deploy-runtime.sh --apply
scripts/deploy-scenario.sh <scenario> --apply
```