Headroom measured and blocked; Mouse-1 triage command built and run

This commit is contained in:
Sam
2026-11-11 18:39:38 +11:00
parent 70e1f55486
commit 7a2d4358d3
10 changed files with 1091 additions and 5 deletions

View File

@@ -85,3 +85,105 @@ Everything else in `docs/NEXT.md` is now marked done. Committed as `36abdc1`; th
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-omni-2026-11-11-04-06-03|Rich discovery: omni 2026-11-11 04:06:03]] - session: [[packs/paperclip-harness/80-sessions/rich-discovery-omni-2026-11-11-04-06-03|Rich discovery: omni 2026-11-11 04:06:03]]
- context: [[packs/paperclip-harness/20-context/omni|omni]] - context: [[packs/paperclip-harness/20-context/omni|omni]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|omni repository structure and configuration patterns]] - observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|omni repository structure and configuration patterns]]
---
## Update (2026-11-11 05:36:08)
## Rich discovery update (2026-11-11 05:36:08)
Four answers.
## 1. The cut-off text
The overlay drew each line and then clipped it to the box width — no wrapping at all. It wraps now, and the box is as wide as the screen allows:
```
╭─ close 1 session? ───────────────────────────────────────────────────────·focus· ╮
│ what happens these TUIOS sessions are closed and their panes end │
│ nothing in ~/.pi/paperclips is deleted; that is your Pi │
│ history │
│ this project's session and attached sessions are never touched │
│ y close them │
│ esc or n do nothing │
│ office-test-1-card-t3-cover-image-1x4e │
╰─────────────────────────────────────────────────────────────────────────────────╯
```
The text was also "cut off in chat" because I had truncated my own output with `sed`; the popup itself was the real fault and is fixed.
## 2. `verify.sh` — you are right, it was a hangover, and it is reframed
I had been describing it as "the thing that decides a task is finished". That is wrong, and it is exactly the wrongness you smelled. What actually decides a task is finished:
1. **the agent**, by setting the task's status — Paperclip's own model;
2. **a reviewer**, if a review stage is configured on the task;
3. **`ocr`**, at merge time, which can refuse the change.
A project-wide script cannot overrule any of those. So its honest job is a **regression check**, the same job a CI pipeline does: after a task's work is applied, does the project still build and pass its tests? `bin/merge` runs it in the task's worktree and again on `main`, and rolls the merge back if it fails.
Renamed accordingly: `bin/office` now writes **`.harness/check.sh`**, and the old `.harness/verify.sh` is still honoured so an adopted folder keeps working. The merge dialog now says `project check: …` or `no project check: the review decides`.
## 3. Headroom — the concrete version
Measured just now:
```
GET http://192.168.20.13:8787/v1/models → 200, 486 models (auto/best-coding, deepseek/…)
GET http://192.168.20.13:8787/health → healthy, compression on, memory off
upstream → http://192.168.20.13:20129/v1
```
The agents' `omni` provider already points at that same upstream, so headroom can sit in front of it. To use it for one agent, two steps, only the second per agent:
1. once, in `~/.pi/agent/settings.json`, add a provider:
```json
"headroom": { "baseUrl": "http://192.168.20.13:8787/v1",
"apiKey": "<the key the omni provider already uses>",
"api": "openai-completions" }
```
2. in `Agents>settings`, set **that agent's model** to `headroom/auto/best-coding`.
**Would it work.** The endpoint answers the OpenAI-style API that Pi's provider type speaks and lists the model ids Pi would ask for, so the pieces line up. It remains a hypothesis until one run goes through it: the unknowns are whether the proxy passes Pi's tool-calling requests unchanged, and what compression does to a prompt with large tool results. The measurement is one run, comparing cost, duration and result for the same task with and without.
**Per project is not possible.** The provider is chosen by the agent's model, and agents belong to the company, not a project. One agent is the finest granularity — which is what the model field already gives you.
## 4. Mouse-1 notes, read
They are precise and I have folded the facts into `docs/PLAN-INTERFACE.md`. The ones that shape the design:
- `POST https://api.mouse.dev/v1/decisions`, key already in the environment — no software to install, I was wrong about that.
- **Cold start is minutes**: first call after idle returned `503 engine_timeout` after 30 s; retry 200 in 13 s; warm ~489 ms.
- Stable answers at ~0.98 confidence. A classifier, not a writer.
- Proven useful for **failure routing** (redo / stronger model / environment / person), unblock triage, intake clarity, task sizing.
- Ruled out for the merge decision, judging test results, anything on a keystroke path, and as the only record of a decision.
The one place it earns its keep here: a failed run in `Agents>agents` offers `f`, asks one four-option question, and writes the recommendation, confidence and options onto the task — with the screen saying "asking, this can take half a minute", and a person still deciding.
Committed as `70e1f55`.
## Source paths observed
- `examples/extensions/custom-provider-anthropic`
- `../examples/extensions/custom-provider-anthropic`
- `8787/v1/models`
- `.pi/agent/settings.json`
- `headroom/auto/best-coding`
- `api.mouse.dev/v1/decisions`
## Evidence
- Confidence: 84%
- Reason: Update component/repository context with detailed discovered structure and configuration
## Related learned memories <!-- same-turn-2026-11-11 05:36:08 -->
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|Headroom proxy endpoint facts (192.168.20.13:8787)]]
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|Enable Headroom for one agent in paperclip-harness]]
- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|overlay wrap fix, check.sh rename, headroom/mouse notes commit 70e1f55]]
- session: [[packs/paperclip-harness/80-sessions/paperclip-harness-discovery-snapshot-overlay-check-sh-headro|paperclip-harness discovery snapshot: overlay, check.sh, headroom, mouse-1]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-8787-2026-11-11-05-36-08|Rich discovery: 8787 2026-11-11 05:36:08]]
- context: [[packs/paperclip-harness/20-context/omni|8787]]

View File

@@ -699,3 +699,98 @@ Follow-ups: MOUSE-1 (triage-only, needs software), project switching design (.27
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-omni-2026-11-11-04-06-03|Rich discovery: omni 2026-11-11 04:06:03]] - session: [[packs/paperclip-harness/80-sessions/rich-discovery-omni-2026-11-11-04-06-03|Rich discovery: omni 2026-11-11 04:06:03]]
- context: [[packs/paperclip-harness/20-context/omni|omni]] - context: [[packs/paperclip-harness/20-context/omni|omni]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|omni repository structure and configuration patterns]] - observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|omni repository structure and configuration patterns]]
---
## Update (2026-11-11 05:36:08)
In paperclip-harness/tui the close-session confirm overlay (frame.go) previously clipped long lines; fixed by wrapping (build error earlier was `" " + strings.Repeat(...) + wrapFirst(...)` mismatched string and []string in frame.go:299). Also renamed the project check script: `bin/office` now writes `.harness/check.sh` (old `.harness/verify.sh` still honoured for adopted folders; merge dialog says `project check: …` or `no project check: the review decides`). Merge gating job reframed as regression check, not completion gate. Committed as `70e1f55` — message: 'Wrap overlay text instead of cutting it; the project check is a regression check, renamed check.sh; concrete Headroom steps; Mouse-1 measured'. Headroom and Mouse-1 facts folded into docs/PLAN-INTERFACE.md.
## Detailed deliverable from completed turn
Four answers.
## 1. The cut-off text
The overlay drew each line and then clipped it to the box width — no wrapping at all. It wraps now, and the box is as wide as the screen allows:
```
╭─ close 1 session? ───────────────────────────────────────────────────────·focus· ╮
│ what happens these TUIOS sessions are closed and their panes end │
│ nothing in ~/.pi/paperclips is deleted; that is your Pi │
│ history │
│ this project's session and attached sessions are never touched │
│ y close them │
│ esc or n do nothing │
│ office-test-1-card-t3-cover-image-1x4e │
╰─────────────────────────────────────────────────────────────────────────────────╯
```
The text was also "cut off in chat" because I had truncated my own output with `sed`; the popup itself was the real fault and is fixed.
## 2. `verify.sh` — you are right, it was a hangover, and it is reframed
I had been describing it as "the thing that decides a task is finished". That is wrong, and it is exactly the wrongness you smelled. What actually decides a task is finished:
1. **the agent**, by setting the task's status — Paperclip's own model;
2. **a reviewer**, if a review stage is configured on the task;
3. **`ocr`**, at merge time, which can refuse the change.
A project-wide script cannot overrule any of those. So its honest job is a **regression check**, the same job a CI pipeline does: after a task's work is applied, does the project still build and pass its tests? `bin/merge` runs it in the task's worktree and again on `main`, and rolls the merge back if it fails.
Renamed accordingly: `bin/office` now writes **`.harness/check.sh`**, and the old `.harness/verify.sh` is still honoured so an adopted folder keeps working. The merge dialog now says `project check: …` or `no project check: the review decides`.
## 3. Headroom — the concrete version
Measured just now:
```
GET http://192.168.20.13:8787/v1/models → 200, 486 models (auto/best-coding, deepseek/…)
GET http://192.168.20.13:8787/health → healthy, compression on, memory off
upstream → http://192.168.20.13:20129/v1
```
The agents' `omni` provider already points at that same upstream, so headroom can sit in front of it. To use it for one agent, two steps, only the second per agent:
1. once, in `~/.pi/agent/settings.json`, add a provider:
```json
"headroom": { "baseUrl": "http://192.168.20.13:8787/v1",
"apiKey": "<the key the omni provider already uses>",
"api": "openai-completions" }
```
2. in `Agents>settings`, set **that agent's model** to `headroom/auto/best-coding`.
**Would it work.** The endpoint answers the OpenAI-style API that Pi's provider type speaks and lists the model ids Pi would ask for, so the pieces line up. It remains a hypothesis until one run goes through it: the unknowns are whether the proxy passes Pi's tool-calling requests unchanged, and what compression does to a prompt with large tool results. The measurement is one run, comparing cost, duration and result for the same task with and without.
**Per project is not possible.** The provider is chosen by the agent's model, and agents belong to the company, not a project. One agent is the finest granularity — which is what the model field already gives you.
## 4. Mouse-1 notes, read
They are precise and I have folded the facts into `docs/PLAN-INTERFACE.md`. The ones that shape the design:
- `POST https://api.mouse.dev/v1/decisions`, key already in the environment — no software to install, I was wrong about that.
- **Cold start is minutes**: first call after idle returned `503 engine_timeout` after 30 s; retry 200 in 13 s; warm ~489 ms.
- Stable answers at ~0.98 confidence. A classifier, not a writer.
- Proven useful for **failure routing** (redo / stronger model / environment / person), unblock triage, intake clarity, task sizing.
- Ruled out for the merge decision, judging test results, anything on a keystroke path, and as the only record of a decision.
The one place it earns its keep here: a failed run in `Agents>agents` offers `f`, asks one four-option question, and writes the recommendation, confidence and options onto the task — with the screen saying "
…[truncated]…
## Evidence
- Confidence: 90%
- Reason: Completed implementation with commit and renamed artifact; useful follow-up context.; enriched with final-answer detail because persistence should be reusable
## Related learned memories <!-- same-turn-2026-11-11 05:36:08 -->
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|Headroom proxy endpoint facts (192.168.20.13:8787)]]
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|Enable Headroom for one agent in paperclip-harness]]
- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|overlay wrap fix, check.sh rename, headroom/mouse notes commit 70e1f55]]
- session: [[packs/paperclip-harness/80-sessions/paperclip-harness-discovery-snapshot-overlay-check-sh-headro|paperclip-harness discovery snapshot: overlay, check.sh, headroom, mouse-1]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-8787-2026-11-11-05-36-08|Rich discovery: 8787 2026-11-11 05:36:08]]
- context: [[packs/paperclip-harness/20-context/omni|8787]]

View File

@@ -2896,3 +2896,363 @@ Committed as `e02b399`. `docs/SESSIONS.md` explains sessions versus daemons, `do
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-cleanup-now-asks-before-it-closes-anything-an|Rich discovery: cleanup-now-asks-before-it-closes-anything-and-the-three-que 2026-11-11 04:58:08]] - session: [[packs/paperclip-harness/80-sessions/rich-discovery-cleanup-now-asks-before-it-closes-anything-an|Rich discovery: cleanup-now-asks-before-it-closes-anything-and-the-three-que 2026-11-11 04:58:08]]
- context: [[packs/paperclip-harness/20-context/cleanup-now-asks-before-it-closes-anything-and-the-three-que|cleanup-now-asks-before-it-closes-anything-and-the-three-que]] - context: [[packs/paperclip-harness/20-context/cleanup-now-asks-before-it-closes-anything-and-the-three-que|cleanup-now-asks-before-it-closes-anything-and-the-three-que]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|cleanup-now-asks-before-it-closes-anything-and-the-three-que repository structure and configuration patterns]] - observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|cleanup-now-asks-before-it-closes-anything-and-the-three-que repository structure and configuration patterns]]
---
## Update (2026-11-11 05:36:08)
`GET http://192.168.20.13:8787/v1/models` → 200, 486 models (e.g. `auto/best-coding`, `auto/best-reasoning`, `deepseek/…`); `/health` → headroom-proxy healthy v0.24.0. Upstream is `http://192.168.20.13:20129/v1`, which the agents' `omni` provider (api `omni-prompt-tools`) already points at. Pi provider entries in `~/.pi/agent/settings.json` use OpenAI-style config; a `headroom` provider of api `openai-completions` with baseUrl `http://192.168.20.13:8787/v1` and the same key as omni can be added. Agent model field (`headroom/auto/best-coding`) is the finest per-agent granularity; per-project selection is impossible since agents belong to the company. Unknowns: whether proxy passes Pi tool-calling requests unchanged, and compression effects on large tool results — validate with one comparative run. (Do not persist the API keys seen in the turn.)
## Detailed observations from completed turn
Four answers.
## 1. The cut-off text
The overlay drew each line and then clipped it to the box width — no wrapping at all. It wraps now, and the box is as wide as the screen allows:
```
╭─ close 1 session? ───────────────────────────────────────────────────────·focus· ╮
│ what happens these TUIOS sessions are closed and their panes end │
│ nothing in ~/.pi/paperclips is deleted; that is your Pi │
│ history │
│ this project's session and attached sessions are never touched │
│ y close them │
│ esc or n do nothing │
│ office-test-1-card-t3-cover-image-1x4e │
╰─────────────────────────────────────────────────────────────────────────────────╯
```
The text was also "cut off in chat" because I had truncated my own output with `sed`; the popup itself was the real fault and is fixed.
## 2. `verify.sh` — you are right, it was a hangover, and it is reframed
I had been describing it as "the thing that decides a task is finished". That is wrong, and it is exactly the wrongness you smelled. What actually decides a task is finished:
1. **the agent**, by setting the task's status — Paperclip's own model;
2. **a reviewer**, if a review stage is configured on the task;
3. **`ocr`**, at merge time, which can refuse the change.
A project-wide script cannot overrule any of those. So its honest job is a **regression check**, the same job a CI pipeline does: after a task's work is applied, does the project still build and pass its tests? `bin/merge` runs it in the task's worktree and again on `main`, and rolls the merge back if it fails.
Renamed accordingly: `bin/office` now writes **`.harness/check.sh`**, and the old `.harness/verify.sh` is still honoured so an adopted folder keeps working. The merge dialog now says `project check: …` or `no project check: the review decides`.
## 3. Headroom — the concrete version
Measured just now:
```
GET http://192.168.20.13:8787/v1/models → 200, 486 models (auto/best-coding, deepseek/…)
GET http://192.168.20.13:8787/health → healthy, compression on, memory off
upstream → http://192.168.20.13:20129/v1
```
The agents' `omni` provider already points at that same upstream, so headroom can sit in front of it. To use it for one agent, two steps, only the second per agent:
1. once, in `~/.pi/agent/settings.json`, add a provider:
```json
"headroom": { "baseUrl": "http://192.168.20.13:8787/v1",
"apiKey": "<the key the omni provider already uses>",
"api": "openai-completions" }
```
2. in `Agents>settings`, set **that agent's model** to `headroom/auto/best-coding`.
**Would it work.** The endpoint answers the OpenAI-style API that Pi's provider type speaks and lists the model ids Pi would ask for, so the pieces line up. It remains a hypothesis until one run goes through it: the unknowns are whether the proxy passes Pi's tool-calling requests unchanged, and what compression does to a prompt with large tool results. The measurement is one run, comparing cost, duration and result for the same task with and without.
**Per project is not possible.** The provider is chosen by the agent's model, and agents belong to the company, not a project. One agent is the finest granularity — which is what the model field already gives you.
## 4. Mouse-1 notes, read
They are precise and I have folded the facts into `docs/PLAN-INTERFACE.md`. The ones that shape the design:
- `POST https://api.mouse.dev/v1/decisions`, key already in the environment — no software to install, I was wrong about that.
- **Cold start is minutes**: first call after idle returned `503 engine_timeout` after 30 s; retry 200 in 13 s; warm ~489 ms.
- Stable answers at ~0.98 confidence. A classifier, not a writer.
- Proven useful for **failure routing** (redo / stronger model / environment / person), unblock triage, intake clarity, task sizing.
- Ruled out for the merge decision, judging test results, anything on a keystroke path, and as the only record of a decision.
The one place it earns its keep here: a failed run in `Agents>agents` offers `f`, asks one four-option question, and writes the recommendation, confidence and options onto the task — with the screen saying "asking, this can take half a minute", and a person still deciding.
Committed as `70e1f55`.
## Evidence
- Confidence: 85%
- Reason: Measured, durable environment facts with endpoint/model counts and caveats.; enriched with final-answer detail because persistence should be reusable
---
## Update (2026-11-11 05:36:08)
Mouse-1 is reachable at `POST https://api.mouse.dev/v1/decisions` with key already in the environment (no install required). Cold start is minutes: first call after idle returned `503 engine_timeout` after 30 s; retry returned 200 in 13 s; warm ~489 ms. Stable answers at ~0.98 confidence; it is a classifier, not a writer. Proven uses: failure routing (redo / stronger model / environment / person), unblock triage, intake clarity, task sizing. Ruled out for: the merge decision, judging test results, anything on a keystroke path, and as the only record of a decision. Intended integration: a failed run in `Agents>agents` offers `f`, asks one four-option question, writes recommendation/confidence/options onto the task, with UI stating it can take ~30 s and human still decides.
## Detailed observations from completed turn
Four answers.
## 1. The cut-off text
The overlay drew each line and then clipped it to the box width — no wrapping at all. It wraps now, and the box is as wide as the screen allows:
```
╭─ close 1 session? ───────────────────────────────────────────────────────·focus· ╮
│ what happens these TUIOS sessions are closed and their panes end │
│ nothing in ~/.pi/paperclips is deleted; that is your Pi │
│ history │
│ this project's session and attached sessions are never touched │
│ y close them │
│ esc or n do nothing │
│ office-test-1-card-t3-cover-image-1x4e │
╰─────────────────────────────────────────────────────────────────────────────────╯
```
The text was also "cut off in chat" because I had truncated my own output with `sed`; the popup itself was the real fault and is fixed.
## 2. `verify.sh` — you are right, it was a hangover, and it is reframed
I had been describing it as "the thing that decides a task is finished". That is wrong, and it is exactly the wrongness you smelled. What actually decides a task is finished:
1. **the agent**, by setting the task's status — Paperclip's own model;
2. **a reviewer**, if a review stage is configured on the task;
3. **`ocr`**, at merge time, which can refuse the change.
A project-wide script cannot overrule any of those. So its honest job is a **regression check**, the same job a CI pipeline does: after a task's work is applied, does the project still build and pass its tests? `bin/merge` runs it in the task's worktree and again on `main`, and rolls the merge back if it fails.
Renamed accordingly: `bin/office` now writes **`.harness/check.sh`**, and the old `.harness/verify.sh` is still honoured so an adopted folder keeps working. The merge dialog now says `project check: …` or `no project check: the review decides`.
## 3. Headroom — the concrete version
Measured just now:
```
GET http://192.168.20.13:8787/v1/models → 200, 486 models (auto/best-coding, deepseek/…)
GET http://192.168.20.13:8787/health → healthy, compression on, memory off
upstream → http://192.168.20.13:20129/v1
```
The agents' `omni` provider already points at that same upstream, so headroom can sit in front of it. To use it for one agent, two steps, only the second per agent:
1. once, in `~/.pi/agent/settings.json`, add a provider:
```json
"headroom": { "baseUrl": "http://192.168.20.13:8787/v1",
"apiKey": "<the key the omni provider already uses>",
"api": "openai-completions" }
```
2. in `Agents>settings`, set **that agent's model** to `headroom/auto/best-coding`.
**Would it work.** The endpoint answers the OpenAI-style API that Pi's provider type speaks and lists the model ids Pi would ask for, so the pieces line up. It remains a hypothesis until one run goes through it: the unknowns are whether the proxy passes Pi's tool-calling requests unchanged, and what compression does to a prompt with large tool results. The measurement is one run, comparing cost, duration and result for the same task with and without.
**Per project is not possible.** The provider is chosen by the agent's model, and agents belong to the company, not a project. One agent is the finest granularity — which is what the model field already gives you.
## 4. Mouse-1 notes, read
They are precise and I have folded the facts into `docs/PLAN-INTERFACE.md`. The ones that shape the design:
- `POST https://api.mouse.dev/v1/decisions`, key already in the environment — no software to install, I was wrong about that.
- **Cold start is minutes**: first call after idle returned `503 engine_timeout` after 30 s; retry 200 in 13 s; warm ~489 ms.
- Stable answers at ~0.98 confidence. A classifier, not a writer.
- Proven useful for **failure routing** (redo / stronger model / environment / person), unblock triage, intake clarity, task sizing.
- Ruled out for the merge decision, judging test results, anything on a keystroke path, and as the only record of a decision.
The one place it earns its keep here: a failed run in `Agents>agents` offers `f`, asks one four-option question, and writes the recommendation, confidence and options onto the task — with the screen saying "asking, this can take half a minute", and a person still deciding.
Committed as `70e1f55`.
## Evidence
- Confidence: 90%
- Reason: Measured operational characteristics and design constraints for a planned integration.; enriched with final-answer detail because persistence should be reusable
---
## Update (2026-11-11 05:36:08)
A task is finished by (1) the agent setting the task status (Paperclip model), (2) a reviewer if a review stage is configured, or (3) `ocr` at merge time refusing the change. `bin/merge` runs the project check (`check.sh`) in the task worktree and again on `main`, rolling back on failure — a regression check like CI, not a completion gate.
## Detailed observations from completed turn
Four answers.
## 1. The cut-off text
The overlay drew each line and then clipped it to the box width — no wrapping at all. It wraps now, and the box is as wide as the screen allows:
```
╭─ close 1 session? ───────────────────────────────────────────────────────·focus· ╮
│ what happens these TUIOS sessions are closed and their panes end │
│ nothing in ~/.pi/paperclips is deleted; that is your Pi │
│ history │
│ this project's session and attached sessions are never touched │
│ y close them │
│ esc or n do nothing │
│ office-test-1-card-t3-cover-image-1x4e │
╰─────────────────────────────────────────────────────────────────────────────────╯
```
The text was also "cut off in chat" because I had truncated my own output with `sed`; the popup itself was the real fault and is fixed.
## 2. `verify.sh` — you are right, it was a hangover, and it is reframed
I had been describing it as "the thing that decides a task is finished". That is wrong, and it is exactly the wrongness you smelled. What actually decides a task is finished:
1. **the agent**, by setting the task's status — Paperclip's own model;
2. **a reviewer**, if a review stage is configured on the task;
3. **`ocr`**, at merge time, which can refuse the change.
A project-wide script cannot overrule any of those. So its honest job is a **regression check**, the same job a CI pipeline does: after a task's work is applied, does the project still build and pass its tests? `bin/merge` runs it in the task's worktree and again on `main`, and rolls the merge back if it fails.
Renamed accordingly: `bin/office` now writes **`.harness/check.sh`**, and the old `.harness/verify.sh` is still honoured so an adopted folder keeps working. The merge dialog now says `project check: …` or `no project check: the review decides`.
## 3. Headroom — the concrete version
Measured just now:
```
GET http://192.168.20.13:8787/v1/models → 200, 486 models (auto/best-coding, deepseek/…)
GET http://192.168.20.13:8787/health → healthy, compression on, memory off
upstream → http://192.168.20.13:20129/v1
```
The agents' `omni` provider already points at that same upstream, so headroom can sit in front of it. To use it for one agent, two steps, only the second per agent:
1. once, in `~/.pi/agent/settings.json`, add a provider:
```json
"headroom": { "baseUrl": "http://192.168.20.13:8787/v1",
"apiKey": "<the key the omni provider already uses>",
"api": "openai-completions" }
```
2. in `Agents>settings`, set **that agent's model** to `headroom/auto/best-coding`.
**Would it work.** The endpoint answers the OpenAI-style API that Pi's provider type speaks and lists the model ids Pi would ask for, so the pieces line up. It remains a hypothesis until one run goes through it: the unknowns are whether the proxy passes Pi's tool-calling requests unchanged, and what compression does to a prompt with large tool results. The measurement is one run, comparing cost, duration and result for the same task with and without.
**Per project is not possible.** The provider is chosen by the agent's model, and agents belong to the company, not a project. One agent is the finest granularity — which is what the model field already gives you.
## 4. Mouse-1 notes, read
They are precise and I have folded the facts into `docs/PLAN-INTERFACE.md`. The ones that shape the design:
- `POST https://api.mouse.dev/v1/decisions`, key already in the environment — no software to install, I was wrong about that.
- **Cold start is minutes**: first call after idle returned `503 engine_timeout` after 30 s; retry 200 in 13 s; warm ~489 ms.
- Stable answers at ~0.98 confidence. A classifier, not a writer.
- Proven useful for **failure routing** (redo / stronger model / environment / person), unblock triage, intake clarity, task sizing.
- Ruled out for the merge decision, judging test results, anything on a keystroke path, and as the only record of a decision.
The one place it earns its keep here: a failed run in `Agents>agents` offers `f`, asks one four-option question, and writes the recommendation, confidence and options onto the task — with the screen saying "asking, this can take half a minute", and a person still deciding.
Committed as `70e1f55`.
## Evidence
- Confidence: 85%
- Reason: Architectural decision clarified in the turn; durable semantics.; enriched with final-answer detail because persistence should be reusable
---
## Update (2026-11-11 05:36:08)
## Structural/configuration observations (2026-11-11 05:36:08)
Four answers.
## 1. The cut-off text
The overlay drew each line and then clipped it to the box width — no wrapping at all. It wraps now, and the box is as wide as the screen allows:
```
╭─ close 1 session? ───────────────────────────────────────────────────────·focus· ╮
│ what happens these TUIOS sessions are closed and their panes end │
│ nothing in ~/.pi/paperclips is deleted; that is your Pi │
│ history │
│ this project's session and attached sessions are never touched │
│ y close them │
│ esc or n do nothing │
│ office-test-1-card-t3-cover-image-1x4e │
╰─────────────────────────────────────────────────────────────────────────────────╯
```
The text was also "cut off in chat" because I had truncated my own output with `sed`; the popup itself was the real fault and is fixed.
## 2. `verify.sh` — you are right, it was a hangover, and it is reframed
I had been describing it as "the thing that decides a task is finished". That is wrong, and it is exactly the wrongness you smelled. What actually decides a task is finished:
1. **the agent**, by setting the task's status — Paperclip's own model;
2. **a reviewer**, if a review stage is configured on the task;
3. **`ocr`**, at merge time, which can refuse the change.
A project-wide script cannot overrule any of those. So its honest job is a **regression check**, the same job a CI pipeline does: after a task's work is applied, does the project still build and pass its tests? `bin/merge` runs it in the task's worktree and again on `main`, and rolls the merge back if it fails.
Renamed accordingly: `bin/office` now writes **`.harness/check.sh`**, and the old `.harness/verify.sh` is still honoured so an adopted folder keeps working. The merge dialog now says `project check: …` or `no project check: the review decides`.
## 3. Headroom — the concrete version
Measured just now:
```
GET http://192.168.20.13:8787/v1/models → 200, 486 models (auto/best-coding, deepseek/…)
GET http://192.168.20.13:8787/health → healthy, compression on, memory off
upstream → http://192.168.20.13:20129/v1
```
The agents' `omni` provider already points at that same upstream, so headroom can sit in front of it. To use it for one agent, two steps, only the second per agent:
1. once, in `~/.pi/agent/settings.json`, add a provider:
```json
"headroom": { "baseUrl": "http://192.168.20.13:8787/v1",
"apiKey": "<the key the omni provider already uses>",
"api": "openai-completions" }
```
2. in `Agents>settings`, set **that agent's model** to `headroom/auto/best-coding`.
**Would it work.** The endpoint answers the OpenAI-style API that Pi's provider type speaks and lists the model ids Pi would ask for, so the pieces line up. It remains a hypothesis until one run goes through it: the unknowns are whether the proxy passes Pi's tool-calling requests unchanged, and what compression does to a prompt with large tool results. The measurement is one run, comparing cost, duration and result for the same task with and without.
**Per project is not possible.** The provider is chosen by the agent's model, and agents belong to the company, not a project. One agent is the finest granularity — which is what the model field already gives you.
## 4. Mouse-1 notes, read
They are precise and I have folded the facts into `docs/PLAN-INTERFACE.md`. The ones that shape the design:
- `POST https://api.mouse.dev/v1/decisions`, key already in the environment — no software to install, I was wrong about that.
- **Cold start is minutes**: first call after idle returned `503 engine_timeout` after 30 s; retry 200 in 13 s; warm ~489 ms.
- Stable answers at ~0.98 confidence. A classifier, not a writer.
- Proven useful for **failure routing** (redo / stronger model / environment / person), unblock triage, intake clarity, task sizing.
- Ruled out for the merge decision, judging test results, anything on a keystroke path, and as the only record of a decision.
The one place it earns its keep here: a failed run in `Agents>agents` offers `f`, asks one four-option question, and writes the recommendation, confidence and options onto the task — with the screen saying "asking, this can take half a minute", and a person still deciding.
Committed as `70e1f55`.
## Source paths observed
- `examples/extensions/custom-provider-anthropic`
- `../examples/extensions/custom-provider-anthropic`
- `8787/v1/models`
- `.pi/agent/settings.json`
- `headroom/auto/best-coding`
- `api.mouse.dev/v1/decisions`
## Evidence
- Confidence: 82%
- Reason: Captured factual repo structure/configuration patterns from rich discovery
## Related learned memories <!-- same-turn-2026-11-11 05:36:08 -->
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|Headroom proxy endpoint facts (192.168.20.13:8787)]]
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|Enable Headroom for one agent in paperclip-harness]]
- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|overlay wrap fix, check.sh rename, headroom/mouse notes commit 70e1f55]]
- session: [[packs/paperclip-harness/80-sessions/paperclip-harness-discovery-snapshot-overlay-check-sh-headro|paperclip-harness discovery snapshot: overlay, check.sh, headroom, mouse-1]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-8787-2026-11-11-05-36-08|Rich discovery: 8787 2026-11-11 05:36:08]]
- context: [[packs/paperclip-harness/20-context/omni|8787]]

View File

@@ -957,3 +957,195 @@ Committed as `3ec960e`; `docs/NEXT.md` updated with what is done and what remain
- context: [[packs/paperclip-harness/20-context/config|.config]] - context: [[packs/paperclip-harness/20-context/config|.config]]
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|.config deployment operations]] - runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|.config deployment operations]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|.config repository structure and configuration patterns]] - observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|.config repository structure and configuration patterns]]
---
## Update (2026-11-11 05:36:08)
Trigger: want to try Headroom compression for a single agent. Prerequisites: `~/.pi/agent/settings.json` editable. Steps:
1. Once, add provider to `~/.pi/agent/settings.json`: `"headroom": { "baseUrl": "http://192.168.20.13:8787/v1", "apiKey": "<same key the omni provider uses>", "api": "openai-completions" }`.
2. In `Agents>settings`, set that agent's model to `headroom/auto/best-coding`.
3. Validate: run the same task with and without headroom, compare cost, duration, result; watch for tool-calling breakage and compression effects on large tool results.
Rollback: restore the agent's model to the prior provider model; remove the provider entry if unused. Caveat: per-project selection is impossible — agent model is the finest granularity.
## Detailed procedure from completed turn
Four answers.
## 1. The cut-off text
The overlay drew each line and then clipped it to the box width — no wrapping at all. It wraps now, and the box is as wide as the screen allows:
```
╭─ close 1 session? ───────────────────────────────────────────────────────·focus· ╮
│ what happens these TUIOS sessions are closed and their panes end │
│ nothing in ~/.pi/paperclips is deleted; that is your Pi │
│ history │
│ this project's session and attached sessions are never touched │
│ y close them │
│ esc or n do nothing │
│ office-test-1-card-t3-cover-image-1x4e │
╰─────────────────────────────────────────────────────────────────────────────────╯
```
The text was also "cut off in chat" because I had truncated my own output with `sed`; the popup itself was the real fault and is fixed.
## 2. `verify.sh` — you are right, it was a hangover, and it is reframed
I had been describing it as "the thing that decides a task is finished". That is wrong, and it is exactly the wrongness you smelled. What actually decides a task is finished:
1. **the agent**, by setting the task's status — Paperclip's own model;
2. **a reviewer**, if a review stage is configured on the task;
3. **`ocr`**, at merge time, which can refuse the change.
A project-wide script cannot overrule any of those. So its honest job is a **regression check**, the same job a CI pipeline does: after a task's work is applied, does the project still build and pass its tests? `bin/merge` runs it in the task's worktree and again on `main`, and rolls the merge back if it fails.
Renamed accordingly: `bin/office` now writes **`.harness/check.sh`**, and the old `.harness/verify.sh` is still honoured so an adopted folder keeps working. The merge dialog now says `project check: …` or `no project check: the review decides`.
## 3. Headroom — the concrete version
Measured just now:
```
GET http://192.168.20.13:8787/v1/models → 200, 486 models (auto/best-coding, deepseek/…)
GET http://192.168.20.13:8787/health → healthy, compression on, memory off
upstream → http://192.168.20.13:20129/v1
```
The agents' `omni` provider already points at that same upstream, so headroom can sit in front of it. To use it for one agent, two steps, only the second per agent:
1. once, in `~/.pi/agent/settings.json`, add a provider:
```json
"headroom": { "baseUrl": "http://192.168.20.13:8787/v1",
"apiKey": "<the key the omni provider already uses>",
"api": "openai-completions" }
```
2. in `Agents>settings`, set **that agent's model** to `headroom/auto/best-coding`.
**Would it work.** The endpoint answers the OpenAI-style API that Pi's provider type speaks and lists the model ids Pi would ask for, so the pieces line up. It remains a hypothesis until one run goes through it: the unknowns are whether the proxy passes Pi's tool-calling requests unchanged, and what compression does to a prompt with large tool results. The measurement is one run, comparing cost, duration and result for the same task with and without.
**Per project is not possible.** The provider is chosen by the agent's model, and agents belong to the company, not a project. One agent is the finest granularity — which is what the model field already gives you.
## 4. Mouse-1 notes, read
They are precise and I have folded the facts into `docs/PLAN-INTERFACE.md`. The ones that shape the design:
- `POST https://api.mouse.dev/v1/decisions`, key already in the environment — no software to install, I was wrong about that.
- **Cold start is minutes**: first call after idle returned `503 engine_timeout` after 30 s; retry 200 in 13 s; warm ~489 ms.
- Stable answers at ~0.98 confidence. A classifier, not a writer.
- Proven useful for **failure routing** (redo / stronger model / environment / person), unblock triage, intake clarity, task sizing.
- Ruled out for the merge decision, judging test results, anything on a keystroke path, and as the only record of a decision.
The one place it earns its keep here: a failed run in `Agents>agents` offers `f`, asks one four-option question, and writes the recommendation, confidence and options onto the task — with the screen saying "asking, this can take half a minute", and a person still deciding.
Committed as `70e1f55`.
## Evidence
- Confidence: 85%
- Reason: Concrete repeatable procedure with rollback and validation.; enriched with final-answer detail because persistence should be reusable
---
## Update (2026-11-11 05:36:08)
## Deployment/runbook details discovered (2026-11-11 05:36:08)
Four answers.
## 1. The cut-off text
The overlay drew each line and then clipped it to the box width — no wrapping at all. It wraps now, and the box is as wide as the screen allows:
```
╭─ close 1 session? ───────────────────────────────────────────────────────·focus· ╮
│ what happens these TUIOS sessions are closed and their panes end │
│ nothing in ~/.pi/paperclips is deleted; that is your Pi │
│ history │
│ this project's session and attached sessions are never touched │
│ y close them │
│ esc or n do nothing │
│ office-test-1-card-t3-cover-image-1x4e │
╰─────────────────────────────────────────────────────────────────────────────────╯
```
The text was also "cut off in chat" because I had truncated my own output with `sed`; the popup itself was the real fault and is fixed.
## 2. `verify.sh` — you are right, it was a hangover, and it is reframed
I had been describing it as "the thing that decides a task is finished". That is wrong, and it is exactly the wrongness you smelled. What actually decides a task is finished:
1. **the agent**, by setting the task's status — Paperclip's own model;
2. **a reviewer**, if a review stage is configured on the task;
3. **`ocr`**, at merge time, which can refuse the change.
A project-wide script cannot overrule any of those. So its honest job is a **regression check**, the same job a CI pipeline does: after a task's work is applied, does the project still build and pass its tests? `bin/merge` runs it in the task's worktree and again on `main`, and rolls the merge back if it fails.
Renamed accordingly: `bin/office` now writes **`.harness/check.sh`**, and the old `.harness/verify.sh` is still honoured so an adopted folder keeps working. The merge dialog now says `project check: …` or `no project check: the review decides`.
## 3. Headroom — the concrete version
Measured just now:
```
GET http://192.168.20.13:8787/v1/models → 200, 486 models (auto/best-coding, deepseek/…)
GET http://192.168.20.13:8787/health → healthy, compression on, memory off
upstream → http://192.168.20.13:20129/v1
```
The agents' `omni` provider already points at that same upstream, so headroom can sit in front of it. To use it for one agent, two steps, only the second per agent:
1. once, in `~/.pi/agent/settings.json`, add a provider:
```json
"headroom": { "baseUrl": "http://192.168.20.13:8787/v1",
"apiKey": "<the key the omni provider already uses>",
"api": "openai-completions" }
```
2. in `Agents>settings`, set **that agent's model** to `headroom/auto/best-coding`.
**Would it work.** The endpoint answers the OpenAI-style API that Pi's provider type speaks and lists the model ids Pi would ask for, so the pieces line up. It remains a hypothesis until one run goes through it: the unknowns are whether the proxy passes Pi's tool-calling requests unchanged, and what compression does to a prompt with large tool results. The measurement is one run, comparing cost, duration and result for the same task with and without.
**Per project is not possible.** The provider is chosen by the agent's model, and agents belong to the company, not a project. One agent is the finest granularity — which is what the model field already gives you.
## 4. Mouse-1 notes, read
They are precise and I have folded the facts into `docs/PLAN-INTERFACE.md`. The ones that shape the design:
- `POST https://api.mouse.dev/v1/decisions`, key already in the environment — no software to install, I was wrong about that.
- **Cold start is minutes**: first call after idle returned `503 engine_timeout` after 30 s; retry 200 in 13 s; warm ~489 ms.
- Stable answers at ~0.98 confidence. A classifier, not a writer.
- Proven useful for **failure routing** (redo / stronger model / environment / person), unblock triage, intake clarity, task sizing.
- Ruled out for the merge decision, judging test results, anything on a keystroke path, and as the only record of a decision.
The one place it earns its keep here: a failed run in `Agents>agents` offers `f`, asks one four-option question, and writes the recommendation, confidence and options onto the task — with the screen saying "asking, this can take half a minute", and a person still deciding.
Committed as `70e1f55`.
## Source paths observed
- `examples/extensions/custom-provider-anthropic`
- `../examples/extensions/custom-provider-anthropic`
- `8787/v1/models`
- `.pi/agent/settings.json`
- `headroom/auto/best-coding`
- `api.mouse.dev/v1/decisions`
## Evidence
- Confidence: 83%
- Reason: Extracted repeatable deploy/configuration procedure from rich discovery
## Related learned memories <!-- same-turn-2026-11-11 05:36:08 -->
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|Headroom proxy endpoint facts (192.168.20.13:8787)]]
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|Enable Headroom for one agent in paperclip-harness]]
- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|overlay wrap fix, check.sh rename, headroom/mouse notes commit 70e1f55]]
- session: [[packs/paperclip-harness/80-sessions/paperclip-harness-discovery-snapshot-overlay-check-sh-headro|paperclip-harness discovery snapshot: overlay, check.sh, headroom, mouse-1]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-8787-2026-11-11-05-36-08|Rich discovery: 8787 2026-11-11 05:36:08]]
- context: [[packs/paperclip-harness/20-context/omni|8787]]

View File

@@ -0,0 +1,39 @@
---
type: session
id: session.paperclip-harness.paperclip-harness-discovery-snapshot-overlay-check-sh-headro
title: paperclip-harness discovery snapshot: overlay, check.sh, headroom, mouse-1
status: active
source_of_truth: false
freshness: current
last_reviewed: 2026-11-11
tags:
- pack/paperclip-harness
- agent-memory/session
- paperclip-harness
- headroom
- mouse-1
- check.sh
- session
---
# paperclip-harness discovery snapshot: overlay, check.sh, headroom, mouse-1
Discovery in paperclip-harness/tui and docs. Fixes: overlay wrap in frame.go (close-session dialog), `.harness/verify.sh` → `.harness/check.sh` rename by `bin/office` with backward compat. Docs updated: docs/PLAN-INTERFACE.md (headroom steps, mouse-1 measured facts, mouse-1 corrected section), project check section. Committed 70e1f55. Environment: headroom-proxy at 192.168.20.13:8787 (486 models, healthy, upstream :20129), omni provider already points there; pi settings providers: omni, deepseek, openrouter, opencode-go, google. Mouse-1: api.mouse.dev, cold start minutes, 0.98 confidence classifier, use for failure routing only — not merge/test/keystroke/sole-record. (Turn revealed live API keys in provider output — not persisted.)
## Evidence
- Confidence: 80%
- Reason: Rich sanitized snapshot tying together the turn's durable discoveries.
## Related
- [[packs/paperclip-harness/00-system/pi-agent/memory-manifest|Memory Manifest]]
## Related learned memories <!-- same-turn-2026-11-11 05:36:08 -->
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|Headroom proxy endpoint facts (192.168.20.13:8787)]]
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|Enable Headroom for one agent in paperclip-harness]]
- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|overlay wrap fix, check.sh rename, headroom/mouse notes commit 70e1f55]]
- session: [[packs/paperclip-harness/80-sessions/paperclip-harness-discovery-snapshot-overlay-check-sh-headro|paperclip-harness discovery snapshot: overlay, check.sh, headroom, mouse-1]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-8787-2026-11-11-05-36-08|Rich discovery: 8787 2026-11-11 05:36:08]]
- context: [[packs/paperclip-harness/20-context/omni|8787]]

View File

@@ -0,0 +1,121 @@
---
type: session
id: session.paperclip-harness.rich-discovery-8787-2026-11-11-05-36-08
title: Rich discovery: 8787 2026-11-11 05:36:08
status: active
source_of_truth: false
freshness: current
last_reviewed: 2026-11-11
tags:
- pack/paperclip-harness
- agent-memory/session
- autolearn
- rich-discovery
- repo/8787
---
# Rich discovery: 8787 2026-11-11 05:36:08
Sanitized rich discovery snapshot captured automatically from the completed turn.
## Source paths observed
- `examples/extensions/custom-provider-anthropic`
- `../examples/extensions/custom-provider-anthropic`
- `8787/v1/models`
- `.pi/agent/settings.json`
- `headroom/auto/best-coding`
- `api.mouse.dev/v1/decisions`
## Final answer snapshot
Four answers.
## 1. The cut-off text
The overlay drew each line and then clipped it to the box width — no wrapping at all. It wraps now, and the box is as wide as the screen allows:
```
╭─ close 1 session? ───────────────────────────────────────────────────────·focus· ╮
│ what happens these TUIOS sessions are closed and their panes end │
│ nothing in ~/.pi/paperclips is deleted; that is your Pi │
│ history │
│ this project's session and attached sessions are never touched │
│ y close them │
│ esc or n do nothing │
│ office-test-1-card-t3-cover-image-1x4e │
╰─────────────────────────────────────────────────────────────────────────────────╯
```
The text was also "cut off in chat" because I had truncated my own output with `sed`; the popup itself was the real fault and is fixed.
## 2. `verify.sh` — you are right, it was a hangover, and it is reframed
I had been describing it as "the thing that decides a task is finished". That is wrong, and it is exactly the wrongness you smelled. What actually decides a task is finished:
1. **the agent**, by setting the task's status — Paperclip's own model;
2. **a reviewer**, if a review stage is configured on the task;
3. **`ocr`**, at merge time, which can refuse the change.
A project-wide script cannot overrule any of those. So its honest job is a **regression check**, the same job a CI pipeline does: after a task's work is applied, does the project still build and pass its tests? `bin/merge` runs it in the task's worktree and again on `main`, and rolls the merge back if it fails.
Renamed accordingly: `bin/office` now writes **`.harness/check.sh`**, and the old `.harness/verify.sh` is still honoured so an adopted folder keeps working. The merge dialog now says `project check: …` or `no project check: the review decides`.
## 3. Headroom — the concrete version
Measured just now:
```
GET http://192.168.20.13:8787/v1/models → 200, 486 models (auto/best-coding, deepseek/…)
GET http://192.168.20.13:8787/health → healthy, compression on, memory off
upstream → http://192.168.20.13:20129/v1
```
The agents' `omni` provider already points at that same upstream, so headroom can sit in front of it. To use it for one agent, two steps, only the second per agent:
1. once, in `~/.pi/agent/settings.json`, add a provider:
```json
"headroom": { "baseUrl": "http://192.168.20.13:8787/v1",
"apiKey": "<the key the omni provider already uses>",
"api": "openai-completions" }
```
2. in `Agents>settings`, set **that agent's model** to `headroom/auto/best-coding`.
**Would it work.** The endpoint answers the OpenAI-style API that Pi's provider type speaks and lists the model ids Pi would ask for, so the pieces line up. It remains a hypothesis until one run goes through it: the unknowns are whether the proxy passes Pi's tool-calling requests unchanged, and what compression does to a prompt with large tool results. The measurement is one run, comparing cost, duration and result for the same task with and without.
**Per project is not possible.** The provider is chosen by the agent's model, and agents belong to the company, not a project. One agent is the finest granularity — which is what the model field already gives you.
## 4. Mouse-1 notes, read
They are precise and I have folded the facts into `docs/PLAN-INTERFACE.md`. The ones that shape the design:
- `POST https://api.mouse.dev/v1/decisions`, key already in the environment — no software to install, I was wrong about that.
- **Cold start is minutes**: first call after idle returned `503 engine_timeout` after 30 s; retry 200 in 13 s; warm ~489 ms.
- Stable answers at ~0.98 confidence. A classifier, not a writer.
- Proven useful for **failure routing** (redo / stronger model / environment / person), unblock triage, intake clarity, task sizing.
- Ruled out for the merge decision, judging test results, anything on a keystroke path, and as the only record of a decision.
The one place it earns its keep here: a failed run in `Agents>agents` offers `f`, asks one four-option question, and writes the recommendation, confidence and options onto the task — with the screen saying "asking, this can take half a minute", and a person still deciding.
Committed as `70e1f55`.
## Evidence
- Confidence: 86%
- Reason: Preserve full sanitized discovery detail from a rich investigation turn
## Related
- [[packs/paperclip-harness/00-system/pi-agent/memory-manifest|Memory Manifest]]
## Related learned memories <!-- same-turn-2026-11-11 05:36:08 -->
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|Headroom proxy endpoint facts (192.168.20.13:8787)]]
- runbook: [[packs/paperclip-harness/70-runbooks/tmp-deployment-operations|Enable Headroom for one agent in paperclip-harness]]
- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|overlay wrap fix, check.sh rename, headroom/mouse notes commit 70e1f55]]
- session: [[packs/paperclip-harness/80-sessions/paperclip-harness-discovery-snapshot-overlay-check-sh-headro|paperclip-harness discovery snapshot: overlay, check.sh, headroom, mouse-1]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-8787-2026-11-11-05-36-08|Rich discovery: 8787 2026-11-11 05:36:08]]
- context: [[packs/paperclip-harness/20-context/omni|8787]]

145
bin/triage Executable file
View File

@@ -0,0 +1,145 @@
#!/usr/bin/env python3
"""Ask Mouse-1 one four-option question about a task, and record the answer.
bin/triage AUD-171 # what does this task need next
bin/triage AUD-171 --ask redo # a different question set
Mouse-1 answers a typed multiple-choice question about a state you describe. It
does not write code, run tools, or decide whether work is finished. It labels a
situation, and the label is written on the task so a person can see why a machine
suggested something.
The cold start is real: the first call after an idle period answers 503 after
about thirty seconds, and the retry succeeds. This retries exactly once, says so,
and never pretends the first call worked.
"""
import json
import os
import sys
import time
import urllib.error
import urllib.request
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "lib"))
import harness as h # noqa: E402
ENDPOINT = "https://api.mouse.dev/v1/decisions"
QUESTIONS = {
"next": {
"instructions": "This Paperclip task has reached the state described. What does it need next?",
"criteria": {
"merge": "the work is complete, its checks pass, and it should be merged now",
"person": "a person has to decide or look at it; a machine should not continue",
"redo": "the work is wrong or incomplete, and the same agent should try again",
"environment": "something outside the code is wrong: a missing tool, a service, a path or a permission",
},
},
"failure": {
"instructions": "This run failed. What does the failure need?",
"criteria": {
"redo": "the work is incomplete or wrong; another attempt with the same agent is likely to succeed",
"stronger_model": "the task needs more capability than this model has",
"environment": "something outside the code is wrong: a missing tool, a service, a path",
"person": "a decision only the person can make",
},
},
}
def mouse_key():
key = os.environ.get("MOUSE_API_KEY", "")
if key:
return key
path = os.path.expanduser("~/.config/environment.d/10-secrets.conf")
if os.path.isfile(path):
for line in open(path):
if line.startswith("MOUSE_API_KEY="):
return line.split("=", 1)[1].strip().strip('"').strip("'")
return ""
def ask(state, question):
key = mouse_key()
if not key:
raise h.Refused(2, "no MOUSE_API_KEY in the environment or ~/.config/environment.d/10-secrets.conf")
body = json.dumps({"model": "mouse-1", "state": state,
"questions": {"q": dict(type="choice", **question)}}).encode()
for attempt in (1, 2):
started = time.time()
req = urllib.request.Request(ENDPOINT, data=body, method="POST",
headers={"Authorization": "Bearer " + key,
"Content-Type": "application/json"})
try:
with urllib.request.urlopen(req, timeout=180) as r:
return json.loads(r.read().decode()), time.time() - started, attempt
except urllib.error.HTTPError as e:
detail = e.read().decode()[:300]
if e.code == 503 and attempt == 1:
h.say(" the model was idle; it takes minutes to start. retrying once…")
continue
raise h.Refused(3, "Mouse-1 answered %d: %s" % (e.code, detail))
def main():
args = [a for a in sys.argv[1:] if not a.startswith("--")]
if not args:
h.say("usage: bin/triage <task> [--ask next|failure]")
return 2
which = "next"
if "--ask" in sys.argv:
which = sys.argv[sys.argv.index("--ask") + 1]
if which not in QUESTIONS:
raise h.Refused(2, "no question set called %r" % which)
issue = h.find_issue(args[0])
worktree, branch, base = (None, "", "")
try:
worktree, branch, base = h.worktree_of(issue)
except h.Refused:
pass
runs = h.api("GET", "/api/issues/%s/runs" % issue["id"])
last = runs[0] if runs else {}
state = {
"task": issue["identifier"] + ": " + issue["title"],
"description": (issue.get("description") or "")[:1500],
"status": issue.get("status"),
"last_run": {k: last.get(k) for k in ("status", "invocationSource", "errorCode", "finishedAt")},
"worktree": worktree or "none",
"branch": branch or "none",
}
if not last.get("errorCode") and last.get("status") in ("failed", "cancelled"):
last_status = last.get("status")
state["last_run"]["status"] = last_status
h.say("%s %s" % (issue["identifier"], issue["title"]))
h.say(" asking Mouse-1: %s" % which)
answer, seconds, attempt = ask(state, QUESTIONS[which])
a = (answer.get("answers") or {}).get("q") or {}
choice = a.get("choice", "?")
confidence = a.get("confidence", 0)
probs = a.get("probabilities") or {}
h.say(" answer: %s (confidence %.2f, %.1fs, attempt %d)" % (choice, confidence, seconds, attempt))
for option, p in sorted(probs.items(), key=lambda kv: -kv[1]):
h.say(" %-14s %.2f %s" % (option, p, QUESTIONS[which]["criteria"].get(option, "")))
lines = ["## Triage (Mouse-1)", "",
"Question: %s" % QUESTIONS[which]["instructions"], "",
"- answer: **%s**" % choice,
"- confidence: %.2f" % confidence,
"- took %.1fs on attempt %d" % (seconds, attempt), "",
"| option | probability | what it means |",
"|---|---|---|"]
for option, p in sorted(probs.items(), key=lambda kv: -kv[1]):
lines.append("| `%s` | %.2f | %s |" % (option, p, QUESTIONS[which]["criteria"].get(option, "")))
lines += ["", "The model labelled the situation. It did not change anything, and it does not decide a merge."]
h.comment(issue["id"], "\n".join(lines))
h.say(" written on the task as a comment")
return 0
if __name__ == "__main__":
h.main_guard(main)

View File

@@ -113,12 +113,20 @@ The one place it would earn its keep here: a failed run in `Agents>agents` offer
asks "what does this failure need" with four options and records the answer, the confidence and asks "what does this failure need" with four options and records the answer, the confidence and
the options on the task. A person still decides, and it never decides a merge. the options on the task. A person still decides, and it never decides a merge.
## Done: Headroom ## Headroom: blocked, with a measured reason
A provider entry in `~/.pi/agent/settings.json` pointing at `http://192.168.20.13:8787/v1`, and A provider entry was added, tested and removed. Headroom answers `502 proxy_error` to OpenAI
an agent's model set to `headroom/<model>`. Per agent, because the model is per agent; per chat requests and `401 invalid x-api-key` to Anthropic ones: its backend is Anthropic and this
project is not possible. The exact steps and the one unknown to measure are in machine has no Anthropic credential. It cannot sit in front of the agents until either headroom
`docs/PLAN-INTERFACE.md`. accepts the omni router's key, or the agents move to an Anthropic-shaped provider. The detail is
in `docs/PLAN-INTERFACE.md`.
## Done: Mouse-1 triage
`bin/triage <task> [--ask next|failure]` asks Mouse-1 one four-option question about a task and
writes the answer, the confidence and the option meanings onto the task as a comment. Measured
on `AUD-162`: 0.5 s warm, answer `person` at 0.97 confidence. The cold start reproduces: `503`
after 30.5 s, then `200` in 21.7 s, so the command retries exactly once and says so.
## Unproven, and worth a test ## Unproven, and worth a test

View File

@@ -640,6 +640,30 @@ without the provider.
to the company, not to a project. The finest granularity is one agent, which is what the to the company, not to a project. The finest granularity is one agent, which is what the
`Agents>settings` model field already gives. `Agents>settings` model field already gives.
### Measured afterwards: it does not work yet, and why
A provider entry was added and removed again after testing, because requests fail:
```
POST http://192.168.20.13:8787/v1/chat/completions → 502 {"code":"proxy_error"}
POST http://192.168.20.13:8787/v1/messages → 401 "invalid x-api-key" (Anthropic shape)
POST http://192.168.20.13:20129/v1/chat/completions → 400 (the router's own model naming)
```
Headroom's backend is `anthropic`: it speaks the Anthropic Messages API and authenticates with
an Anthropic key, which this machine does not have. The omni router uses an OpenAI-shaped API
with its own key. So headroom cannot be put in front of the agents as things stand.
To use it, one of these is needed:
1. an Anthropic-compatible credential in headroom, and agents moved to an Anthropic-shaped
provider;
2. or headroom configured to accept the omni router's OpenAI API and key;
3. or nothing — the omni router already does model routing, and headroom's only addition would be
prompt compression.
The provider entry was removed so no agent can be pointed at a failing endpoint by accident.
## Mouse-1, measured ## Mouse-1, measured
The person supplied `docs/MOUSE-1-NOTES.md`, written from measurements on 2026-11-08/09. The The person supplied `docs/MOUSE-1-NOTES.md`, written from measurements on 2026-11-08/09. The