Confirmed by experiment: how a picker can assign skills per agent, and where the boundary is

This commit is contained in:
Sam
2026-11-11 08:58:23 +11:00
parent 47aacfd6d1
commit e44b0dff51
6 changed files with 527 additions and 0 deletions

View File

@@ -490,3 +490,88 @@ deliberately small.
`GET /api/agents/{id}/task-sessions` maps task → session file and working directory, so option
1 and 2 both have a reliable index and neither needs guessing.
---
# Confirmed: what the picker emulation needs, and what it can actually do
Researched by doing it, on this machine, with the board key. Everything below returned 200 or
201 unless it says otherwise.
## The gap, measured
| Set | Where | Count |
|---|---|---|
| what the pi-config picker lists | `~/.agents/skills` | **21** (archify, caveman, nixos-workflow, tuios, …) |
| what Paperclip can assign | `GET /api/companies/{id}/skills` | **9** (agentmail, obsidian-cli, paperclip, project-docs, system-architect, …) |
So eleven skills a person can see in the picker cannot be given to a Paperclip agent today,
because Paperclip has never heard of them. That is the whole problem, and it is smaller than
it looked.
## What works, in order
1. **Copy the skill into the company's managed directory.** A local import is refused from
anywhere else — `POST …/skills/import` with a path under `~/.agents` returned **403
`skill_workspace_boundary_denied`**, "Import from a configured Paperclip workspace or the
company managed-skill directory". Copying to
`~/.paperclip/instances/default/skills/<companyId>/<name>` and importing that path returned
**201**:
```
{"key": "local/9a9eba3826/nixos-workflow", "slug": "nixos-workflow", …}
```
2. **Assign it to one agent, and only that agent**:
```
POST /api/agents/{agentId}/skills/sync
{"mode": "add", "desiredSkills": ["local/9a9eba3826/nixos-workflow"]} → 200
```
Verified on `Documenter`: its list went from three skills to four and back to three after a
`remove`. Different agents, different lists — as expected.
3. **Extensions have no Paperclip equivalent.** `~/.agents/extensions` holds them; Paperclip's
skill model does not. The per-agent lever is `adapterConfig.command`, which defaults to `pi`
and is appended to by the adapter. A wrapper per agent that passes `--extension …` and then
`exec pi "$@"` is the equivalent of `pi-config` for a Paperclip run.
## So the emulation is this, and nothing more
A picker that does what `pi-config`'s does, for Paperclip agents:
- **reads** `~/.agents/skills` and `~/.agents/extensions` (the same source the picker uses),
the company skill list, and the chosen agent's `desiredSkills`;
- **marks** each entry: available but not in Paperclip · in Paperclip · on this agent;
- **on choosing** an unavailable skill: copy it into the managed directory, import it, then
`skills/sync` it onto that agent;
- **on removing**: `skills/sync` with `remove`;
- **for an extension**: add it to that agent's wrapper file and point
`adapterConfig.command` at the wrapper.
That is a small command or one panel, not a new subsystem, and every step above is already
verified.
## A change made while checking this
`nixos-workflow` was copied into the company's managed directory and imported, so it is now in
Paperclip's list and can be assigned to any agent. It is assigned to nobody. Nothing else was
changed; `Documenter`'s skills were put back exactly as they were.
## Pi history — the cheap answer is probably enough
The instinct is right. Every run is already a file:
```
~/.pi/paperclips/<timestamp>-<agentId>.jsonl 178 of them here
```
`GET /api/agents/{id}/task-sessions` maps a task to its session file and folder. So the
cheapest useful thing is a tool-pane entry that opens `~/.pi/paperclips` in Yazi, or a pane
running `pi --resume` that lists sessions and opens one with Pi's own interface. Both are
minutes of work and neither invents anything.
A transcript tab inside `Agents>agents` is the integration option: read the JSONL, draw the
messages, no second process. Worth doing only if the file browser feels like a detour after a
week of use. Recommendation: do the cheap one now, decide later.