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.
This commit is contained in:
@@ -501,6 +501,71 @@ instructions under `--system-prompt`; they have to be in the prompt text.
|
||||
|
||||
---
|
||||
|
||||
## 23. Skills need a tool literally named `read`, so a domain-only agent cannot use them
|
||||
|
||||
Section 1 recorded that `--no-tools` disables skills. The real rule is narrower and
|
||||
worse: `formatSkillsForPrompt` runs only when a tool **named `read`** is active.
|
||||
|
||||
```js
|
||||
const customPromptHasRead = !selectedTools || selectedTools.includes("read");
|
||||
if (customPromptHasRead && skills.length > 0) {
|
||||
prompt += formatSkillsForPrompt(skills);
|
||||
}
|
||||
```
|
||||
|
||||
Measured with a probe registering three tools and loading one skill:
|
||||
|
||||
| active tools | `--system-prompt` | skills section | skill names |
|
||||
|---|---|---|---|
|
||||
| `probe_read`, `query_library`, … | yes | **true** | `[…, curator-core]` |
|
||||
| `probe_read`, `query_library`, … | no | true | `[…, curator-core]` |
|
||||
| `query_library`, `lookup_online`, `counts` | yes | **false** | `[]` |
|
||||
| `query_library`, `lookup_online`, `counts` | no | **false** | `[]` |
|
||||
|
||||
So it is not about `--system-prompt` and not about `--no-tools`. An agent whose
|
||||
tools are all domain-specific gets **nothing** from `--skill`, silently.
|
||||
|
||||
memo-inbox is unaffected because it registers a path-restricted `read` override.
|
||||
Curator has no `read` and no reason to invent one, so its `--skill` arguments were
|
||||
discarded and the plan's split into `curator-core` / `video-arr` / `books-ingest`
|
||||
was inert before it was written. The policy stays in `APPEND_SYSTEM.md`, which is
|
||||
unconditional.
|
||||
|
||||
`PiLaunchConfig._read_reachable` used to assume `no_builtin_tools` implied an
|
||||
extension supplying `read`. It no longer guesses: `extension_registers_read` must
|
||||
be set explicitly, and loading skills without it logs a warning.
|
||||
|
||||
A side benefit of not using skills: on-demand injection varies the prompt, and a
|
||||
varying prefix defeats provider prompt caching. See section 24.
|
||||
|
||||
## 24. A long-lived session is worth far more than the process startup it saves
|
||||
|
||||
Measured on Curator's conversation path, same question, same model:
|
||||
|
||||
| turn | cache read / billed input |
|
||||
|---|---|
|
||||
| first turn of a new session | 0% |
|
||||
| continuing session | **99.97%** |
|
||||
|
||||
The saving is not the ~1-2 s of process startup, it is that the whole system
|
||||
prompt and prior history are re-read from cache instead of re-charged.
|
||||
|
||||
The practical constraints that follow:
|
||||
|
||||
- **Nothing may vary at the front of the prompt.** The tool list is generated into
|
||||
the system prompt once (section 22) rather than injected per turn, and
|
||||
per-request restatements of "which adapters exist" were removed.
|
||||
- **Rotation is a cost.** Each rotation resets the cache, so rotate on explicit
|
||||
bounds (`rotate_after_prompts`, `rotate_after_messages`) rather than eagerly.
|
||||
- **Session files must persist.** Curator keys the session id on a uuid5 of the
|
||||
chat id, so a service restart resumes the same session and keeps the cache warm.
|
||||
- **Idle processes must still be reclaimed.** A process per chat that is never
|
||||
stopped is 100-200 MB and several tasks; the set has to be swept on a TTL or it
|
||||
grows until `MemoryMax` or `TasksMax` produces an unexplained failure to start a
|
||||
new conversation.
|
||||
|
||||
---
|
||||
|
||||
## Re-verification
|
||||
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user