diff --git a/.pi/memory-vault/packs/paperclip-harness/20-context/omni.md b/.pi/memory-vault/packs/paperclip-harness/20-context/omni.md index 02ca80f..357ac4f 100644 --- a/.pi/memory-vault/packs/paperclip-harness/20-context/omni.md +++ b/.pi/memory-vault/packs/paperclip-harness/20-context/omni.md @@ -187,3 +187,184 @@ Committed as `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]] + + +--- + +## Update (2026-11-11 07:40:01) + +Two-machine lab (plus a router host) used for the Paperclip harness work. + +Machines measured (as of this turn): +- 192.168.20.27 (sam-4screen-desktop): Go 1.26.2 ✓, 98 Nerd Fonts ✓, pi 0.82.1, tuios 0.12.1 [pure-Go backend]. Considered the current/reference machine. +- 192.168.20.51 (sam-thinkpad): Go MISSING, 98 Nerd Fonts ✓, pi 0.87.1, tuios 0.12.1. +- 192.168.20.13: hosts the omni OpenAI-shaped router at :20129; pi 0.82.x. + +Provider topology (agent model providers are per-agent/model, NOT per-project): providers currently configured = ['omni', 'deepseek', 'openrouter', 'opencode-go', 'google']. The 'omni' provider speaks the OpenAI API with its own key/own model naming on :20129. A 'headroom' provider entry was added and removed this turn (see decision note). + +Lab tooling in the workspace: +- bin/triage [--ask next|failure] — asks one four-option question to Mouse-1 and comments the answer on the task. +- Repair > cleanup in the harness UI — closes stale sessions, now with a confirmation prompt. + +Known follow-ups/unknowns: .51 needs Go installed; pi version drift (0.87 on .51 vs 0.82 on .13/.27) should be aligned before agents run on .51. Headroom prompt-compression is unproven (no measurement showing it pays). + +## Detailed context from completed turn + +Two things were built and tested; one of them does not work, and I have the measurements. + +## Headroom: tested, and it cannot sit in front of your agents yet + +I added the provider, called it, and removed it again: + +``` +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 wants an Anthropic key, which this machine does not have. Your `omni` provider speaks the OpenAI API with its own key. So "headroom as an agent" is not a thing — and "headroom in front of an agent" does not work as configured. + +Three real options: + +1. **Give headroom an Anthropic credential** and move an agent to an Anthropic-shaped provider. Then one agent gets compression; per project still impossible, because the provider is chosen by the agent's model. +2. **Reconfigure headroom** to accept the omni router's OpenAI API and key. That is headroom's configuration, not ours. +3. **Do nothing.** The omni router already routes models. Headroom's only addition would be prompt compression for very long jobs, and you have no measurement showing it pays. + +My recommendation is 3 until you have a long job that hurts — the provider entry is removed so no agent can be pointed at a failing endpoint. + +## Mouse-1: built and run + +`bin/triage [--ask next|failure]` asks one four-option question and writes the answer on the task: + +``` +AUD-162 Tree render check — waits on the first + asking Mouse-1: next + answer: person (confidence 0.97, 0.5s, attempt 1) + person 0.98 a person has to decide or look at it; a machine should not continue + environment 0.02 something outside the code is wrong: … + redo 0.00 the work is wrong or incomplete, … + merge 0.00 the work is complete, its checks passed, … + written on the task as a comment +``` + +The cold start reproduced exactly as your notes said: `503` after 30.5 s, then `200` in 21.7 s. The command retries once and prints that it did. Mouse-1 cannot be an agent — it has no tools and writes nothing — but as a labeller it works, and the answer now lives on the task. + +## Machines + +Measured just now: + +| | `.27` sam-4screen-desktop | `.51` sam-thinkpad | +|---|---|---| +| Go | 1.26.2 ✓ | **missing** | +| Nerd Fonts | 98 ✓ | 98 ✓ | +| Pi | 0.82.1 | **0.87.1** | +| TUIOS | 0.12.1 | 0.12.1 | + +`.51` needs `go` in its configuration; `.27` is current. Pi differs between machines (0.87 on `.51`, 0.82 on `.13`/`.27`), which is worth aligning before agents run on `.51`. + +## The cleanup work — options, in the order I would do them + +1. **Old sessions.** `Repair>cleanup` is ready and now confirms before closing. 21 junk sessions remain (`harness-demo-card-*`, `office-test-1*`). I can tick and close them with you watching, or leave you to. +2. **Old harness and old project** (`~/paseo/harness`, `~/paseo/projects/tuios_coding_harness`). Options: leave as read-only reference; tar them into one archive and delete the trees; or delete outright. I would tar first — they are the only record of two earlier attempts. +3. **This build's leftovers**: duplicate shell panes, my test tasks (`AUD-161`, `AUD-162`, `AUD-166`–`171`), the `ocr`/`lazygit` panes I opened. The test tasks are real Paperclip records — I would mark them `cancelled` rather than delete, so the history stays honest. +4. **Documentation with the project-docs skill** — README, Obsidian note, architecture diagram, and a task record. That is a deliberate pass, not a by-product. +5. **Two clean tests**: a brand-new project in a fresh folder (create → task → run → merge), and adopting an existing folder (the harness repo itself). Both are worth a written result. +6. **Handover document** — `docs/HANDOVER.md`: what exists, why each decision was made, what is unproven, and where everything lives. + +Say which of those six you want first, and whether I should close the junk sessions myself. + +## Evidence + +- Confidence: 80% +- Reason: Durable component/infrastructure overview discovered this turn: machine specs, provider topology, and lab CLI tooling that a future agent will need.; enriched with final-answer detail because persistence should be reusable + + +--- + +## Update (2026-11-11 07:40:01) + +## Rich discovery update (2026-11-11 07:40:01) + +Two things were built and tested; one of them does not work, and I have the measurements. + +## Headroom: tested, and it cannot sit in front of your agents yet + +I added the provider, called it, and removed it again: + +``` +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 wants an Anthropic key, which this machine does not have. Your `omni` provider speaks the OpenAI API with its own key. So "headroom as an agent" is not a thing — and "headroom in front of an agent" does not work as configured. + +Three real options: + +1. **Give headroom an Anthropic credential** and move an agent to an Anthropic-shaped provider. Then one agent gets compression; per project still impossible, because the provider is chosen by the agent's model. +2. **Reconfigure headroom** to accept the omni router's OpenAI API and key. That is headroom's configuration, not ours. +3. **Do nothing.** The omni router already routes models. Headroom's only addition would be prompt compression for very long jobs, and you have no measurement showing it pays. + +My recommendation is 3 until you have a long job that hurts — the provider entry is removed so no agent can be pointed at a failing endpoint. + +## Mouse-1: built and run + +`bin/triage [--ask next|failure]` asks one four-option question and writes the answer on the task: + +``` +AUD-162 Tree render check — waits on the first + asking Mouse-1: next + answer: person (confidence 0.97, 0.5s, attempt 1) + person 0.98 a person has to decide or look at it; a machine should not continue + environment 0.02 something outside the code is wrong: … + redo 0.00 the work is wrong or incomplete, … + merge 0.00 the work is complete, its checks passed, … + written on the task as a comment +``` + +The cold start reproduced exactly as your notes said: `503` after 30.5 s, then `200` in 21.7 s. The command retries once and prints that it did. Mouse-1 cannot be an agent — it has no tools and writes nothing — but as a labeller it works, and the answer now lives on the task. + +## Machines + +Measured just now: + +| | `.27` sam-4screen-desktop | `.51` sam-thinkpad | +|---|---|---| +| Go | 1.26.2 ✓ | **missing** | +| Nerd Fonts | 98 ✓ | 98 ✓ | +| Pi | 0.82.1 | **0.87.1** | +| TUIOS | 0.12.1 | 0.12.1 | + +`.51` needs `go` in its configuration; `.27` is current. Pi differs between machines (0.87 on `.51`, 0.82 on `.13`/`.27`), which is worth aligning before agents run on `.51`. + +## The cleanup work — options, in the order I would do them + +1. **Old sessions.** `Repair>cleanup` is ready and now confirms before closing. 21 junk sessions remain (`harness-demo-card-*`, `office-test-1*`). I can tick and close them with you watching, or leave you to. +2. **Old harness and old project** (`~/paseo/harness`, `~/paseo/projects/tuios_coding_harness`). Options: leave as read-only reference; tar them into one archive and delete the trees; or delete outright. I would tar first — they are the only record of two earlier attempts. +3. **This build's leftovers**: duplicate shell panes, my test tasks (`AUD-161`, `AUD-162`, `AUD-166`–`171`), the `ocr`/`lazygit` panes I opened. The test tasks are real Paperclip records — I would mark them `cancelled` rather than delete, so the history stays honest. +4. **Documentation with the project-docs skill** — README, Obsidian note, architecture diagram, and a task record. That is a deliberate pass, not a by-product. +5. **Two clean tests**: a brand-new project in a fresh folder (create → task → run → merge), and adopting an existing folder (the harness repo itself). Both are worth a written result. +6. **Handover document** — `docs/HANDOVER.md`: what exists, why each decision was made, what is unproven, and where everything lives. + +Say which of those six you want first, and whether I should close the junk sessions myself. + +## Source paths observed + +- `8787/v1/chat/completions` +- `8787/v1/messages` +- `20129/v1/chat/completions` +- `paseo/projects/tuios_coding_harness` + +## Evidence + +- Confidence: 84% +- Reason: Update component/repository context with detailed discovered structure and configuration + +## Related learned memories + +- context: [[packs/paperclip-harness/20-context/omni|Paperclip harness lab: machine fleet, agent provider topology, and lab tooling]] +- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|Mouse-1 provider behavior: Anthropic-shaped key issue, cold-start 503→200, 401 shape]] +- decision: [[packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li|Do not put headroom in front of agents yet; remove the headroom provider entry]] +- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|Built and ran bin/triage (Mouse-1 labeller) and measured headroom provider]] +- session: [[packs/paperclip-harness/80-sessions/paperclip-harness-session-snapshot-provider-feasibility-tria|Paperclip harness session snapshot: provider feasibility + triage tooling]] +- session: [[packs/paperclip-harness/80-sessions/rich-discovery-itself-2026-11-11-07-40-01|Rich discovery: itself 2026-11-11 07:40:01]] diff --git a/.pi/memory-vault/packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups.md b/.pi/memory-vault/packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups.md index 74c6622..097b564 100644 --- a/.pi/memory-vault/packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups.md +++ b/.pi/memory-vault/packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups.md @@ -794,3 +794,34 @@ The one place it earns its keep here: a failed run in `Agents>agents` offers `f` - 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]] + + +--- + +## Update (2026-11-11 07:40:01) + +Completed work this turn: + +1. Headroom provider test then removal: added the headroom provider to config, called it (502 on /v1/chat/completions, 401 'invalid x-api-key' on /v1/messages, 400 on omni router), diagnosed it as Anthropic-shaped needing an Anthropic key, then removed the provider entry. Final providers: ['omni','deepseek','openrouter','opencode-go','google']. + +2. Built bin/triage [--ask next|failure]: asks one four-option question to Mouse-1, retries once on 503, prints per-option probabilities/reasons with confidence and latency, and writes the answer as a comment on the task (via Paperclip). Verified end-to-end on AUD-162 ('Tree render check'): answer person (confidence 0.97, 0.5s, attempt 1). + +3. Machine audit: measured .27 and .51 for Go/Nerd Fonts/pi/tuios (see context note). + +Validation: syntax check 'syntax ok'; triage run produced a written task comment; commit 7a2d435 'Headroom measured and blocked; Mouse-1 triage command built and run'. + +Follow-up offered (not yet done): close 21 junk sessions (harness-demo-card-*, office-test-1*); archive/delete ~/paseo/harness and ~/paseo/projects/tuios_coding_harness; clean up test tasks AUD-161/162/166–171 (mark cancelled, not delete); docs pass; two clean tests; write docs/HANDOVER.md. + +## Evidence + +- Confidence: 85% +- Reason: Structured deliverable summary with artifacts, validation, commit, and follow-ups. + +## Related learned memories + +- context: [[packs/paperclip-harness/20-context/omni|Paperclip harness lab: machine fleet, agent provider topology, and lab tooling]] +- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|Mouse-1 provider behavior: Anthropic-shaped key issue, cold-start 503→200, 401 shape]] +- decision: [[packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li|Do not put headroom in front of agents yet; remove the headroom provider entry]] +- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|Built and ran bin/triage (Mouse-1 labeller) and measured headroom provider]] +- session: [[packs/paperclip-harness/80-sessions/paperclip-harness-session-snapshot-provider-feasibility-tria|Paperclip harness session snapshot: provider feasibility + triage tooling]] +- session: [[packs/paperclip-harness/80-sessions/rich-discovery-itself-2026-11-11-07-40-01|Rich discovery: itself 2026-11-11 07:40:01]] diff --git a/.pi/memory-vault/packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li.md b/.pi/memory-vault/packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li.md index e90c4c1..92187ed 100644 --- a/.pi/memory-vault/packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li.md +++ b/.pi/memory-vault/packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li.md @@ -286,3 +286,35 @@ 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]] - 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]] + + +--- + +## Update (2026-11-11 07:40:01) + +Decision: remove the 'headroom' provider entry from the agent config and do not route any agent through it until there is evidence it pays. + +Context: headroom at 192.168.20.13:8787 speaks the Anthropic Messages API and needs an Anthropic credential this machine lacks; omni speaks the OpenAI API with its own key. So 'headroom as an agent' is not a thing, and 'headroom in front of an agent' does not work as configured. + +Options considered: +1. Give headroom an Anthropic credential and move an agent to an Anthropic-shaped provider — gives one agent compression, still no per-project control, because provider is chosen by the agent's model. +2. Reconfigure headroom to accept the omni router's OpenAI API and key — that is headroom's config, not ours. +3. Do nothing — the omni router already routes models; headroom's only addition is prompt compression for very long jobs, and there is no measurement showing it pays. + +Rationale/consequence: Recommendation is option 3 until a long job hurts. Provider entry was removed so no agent can be pointed at a failing endpoint (401/502). + +Review caveat: revisit if a long-running job shows measurable latency/cost benefit from compression, or if an Anthropic credential is made available. + +## Evidence + +- Confidence: 85% +- Reason: Architectural/config decision with rationale, alternatives, and consequences — durable for future agents. + +## Related learned memories + +- context: [[packs/paperclip-harness/20-context/omni|Paperclip harness lab: machine fleet, agent provider topology, and lab tooling]] +- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|Mouse-1 provider behavior: Anthropic-shaped key issue, cold-start 503→200, 401 shape]] +- decision: [[packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li|Do not put headroom in front of agents yet; remove the headroom provider entry]] +- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|Built and ran bin/triage (Mouse-1 labeller) and measured headroom provider]] +- session: [[packs/paperclip-harness/80-sessions/paperclip-harness-session-snapshot-provider-feasibility-tria|Paperclip harness session snapshot: provider feasibility + triage tooling]] +- session: [[packs/paperclip-harness/80-sessions/rich-discovery-itself-2026-11-11-07-40-01|Rich discovery: itself 2026-11-11 07:40:01]] diff --git a/.pi/memory-vault/packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns.md b/.pi/memory-vault/packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns.md index e909590..99990b3 100644 --- a/.pi/memory-vault/packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns.md +++ b/.pi/memory-vault/packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns.md @@ -3256,3 +3256,121 @@ Committed as `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]] + + +--- + +## Update (2026-11-11 07:40:01) + +Measured behavior of the Mouse-1 / headroom providers this turn: + +Headroom endpoint http://192.168.20.13:8787 is Anthropic-shaped: +- POST :8787/v1/chat/completions → 502 {"code":"proxy_error"} +- POST :8787/v1/messages → 401 {"type":"error","error":{"type":"authentication_error","message":"invalid x-api-key"}} (Anthropic Messages API — wants an Anthropic key this machine lacks) +- Anthropic upstream (via openai→anthropic translation) → 400 + +Omni router http://192.168.20.13:20129 is OpenAI-shaped: +- /v1/chat/completions → 400 when called with router's own model naming (model name mismatch, not a hard failure) +- A decision call without a key → 401 {"type":"authentication_error","code":"missing_api_key","message":"Send your key as 'Authorization: Bearer [REDACTED_SECRET]'."} + +Mouse-1 cold start (reproduced exactly as prior notes): first attempt 503 {"code":"engine_timeout","message":"The model did not answer in time. After an idle period it takes a few minutes to start; retry after the Retry-After header."} after 30.5s; retry → 200 in 21.7s. bin/triage retries once on 503 and reports it. + +Mouse-1 sampling result is well-formed: next-choice over {merge, person, redo} with confidences, logits, and a mouse block (calibrated:false, p_top, abstain:null, confidence_winning/normalized). Example answer: person (0.98) with reason "a person has to decide or look at it; a machine should not continue". + +Caveat: Mouse-1 cannot act as an agent (no tools, writes nothing to disk on its own) — it works only as a labeller whose answer is commented on the task by bin/triage. + +## Evidence + +- Confidence: 85% +- Reason: Concrete, reproducible API/endpoint behavior and error codes a future agent will hit; useful troubleshooting knowledge. + + +--- + +## Update (2026-11-11 07:40:01) + +## Structural/configuration observations (2026-11-11 07:40:01) + +Two things were built and tested; one of them does not work, and I have the measurements. + +## Headroom: tested, and it cannot sit in front of your agents yet + +I added the provider, called it, and removed it again: + +``` +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 wants an Anthropic key, which this machine does not have. Your `omni` provider speaks the OpenAI API with its own key. So "headroom as an agent" is not a thing — and "headroom in front of an agent" does not work as configured. + +Three real options: + +1. **Give headroom an Anthropic credential** and move an agent to an Anthropic-shaped provider. Then one agent gets compression; per project still impossible, because the provider is chosen by the agent's model. +2. **Reconfigure headroom** to accept the omni router's OpenAI API and key. That is headroom's configuration, not ours. +3. **Do nothing.** The omni router already routes models. Headroom's only addition would be prompt compression for very long jobs, and you have no measurement showing it pays. + +My recommendation is 3 until you have a long job that hurts — the provider entry is removed so no agent can be pointed at a failing endpoint. + +## Mouse-1: built and run + +`bin/triage [--ask next|failure]` asks one four-option question and writes the answer on the task: + +``` +AUD-162 Tree render check — waits on the first + asking Mouse-1: next + answer: person (confidence 0.97, 0.5s, attempt 1) + person 0.98 a person has to decide or look at it; a machine should not continue + environment 0.02 something outside the code is wrong: … + redo 0.00 the work is wrong or incomplete, … + merge 0.00 the work is complete, its checks passed, … + written on the task as a comment +``` + +The cold start reproduced exactly as your notes said: `503` after 30.5 s, then `200` in 21.7 s. The command retries once and prints that it did. Mouse-1 cannot be an agent — it has no tools and writes nothing — but as a labeller it works, and the answer now lives on the task. + +## Machines + +Measured just now: + +| | `.27` sam-4screen-desktop | `.51` sam-thinkpad | +|---|---|---| +| Go | 1.26.2 ✓ | **missing** | +| Nerd Fonts | 98 ✓ | 98 ✓ | +| Pi | 0.82.1 | **0.87.1** | +| TUIOS | 0.12.1 | 0.12.1 | + +`.51` needs `go` in its configuration; `.27` is current. Pi differs between machines (0.87 on `.51`, 0.82 on `.13`/`.27`), which is worth aligning before agents run on `.51`. + +## The cleanup work — options, in the order I would do them + +1. **Old sessions.** `Repair>cleanup` is ready and now confirms before closing. 21 junk sessions remain (`harness-demo-card-*`, `office-test-1*`). I can tick and close them with you watching, or leave you to. +2. **Old harness and old project** (`~/paseo/harness`, `~/paseo/projects/tuios_coding_harness`). Options: leave as read-only reference; tar them into one archive and delete the trees; or delete outright. I would tar first — they are the only record of two earlier attempts. +3. **This build's leftovers**: duplicate shell panes, my test tasks (`AUD-161`, `AUD-162`, `AUD-166`–`171`), the `ocr`/`lazygit` panes I opened. The test tasks are real Paperclip records — I would mark them `cancelled` rather than delete, so the history stays honest. +4. **Documentation with the project-docs skill** — README, Obsidian note, architecture diagram, and a task record. That is a deliberate pass, not a by-product. +5. **Two clean tests**: a brand-new project in a fresh folder (create → task → run → merge), and adopting an existing folder (the harness repo itself). Both are worth a written result. +6. **Handover document** — `docs/HANDOVER.md`: what exists, why each decision was made, what is unproven, and where everything lives. + +Say which of those six you want first, and whether I should close the junk sessions myself. + +## Source paths observed + +- `8787/v1/chat/completions` +- `8787/v1/messages` +- `20129/v1/chat/completions` +- `paseo/projects/tuios_coding_harness` + +## Evidence + +- Confidence: 82% +- Reason: Captured factual repo structure/configuration patterns from rich discovery + +## Related learned memories + +- context: [[packs/paperclip-harness/20-context/omni|Paperclip harness lab: machine fleet, agent provider topology, and lab tooling]] +- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|Mouse-1 provider behavior: Anthropic-shaped key issue, cold-start 503→200, 401 shape]] +- decision: [[packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li|Do not put headroom in front of agents yet; remove the headroom provider entry]] +- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|Built and ran bin/triage (Mouse-1 labeller) and measured headroom provider]] +- session: [[packs/paperclip-harness/80-sessions/paperclip-harness-session-snapshot-provider-feasibility-tria|Paperclip harness session snapshot: provider feasibility + triage tooling]] +- session: [[packs/paperclip-harness/80-sessions/rich-discovery-itself-2026-11-11-07-40-01|Rich discovery: itself 2026-11-11 07:40:01]] diff --git a/.pi/memory-vault/packs/paperclip-harness/80-sessions/paperclip-harness-session-snapshot-provider-feasibility-tria.md b/.pi/memory-vault/packs/paperclip-harness/80-sessions/paperclip-harness-session-snapshot-provider-feasibility-tria.md new file mode 100644 index 0000000..c8e9cb3 --- /dev/null +++ b/.pi/memory-vault/packs/paperclip-harness/80-sessions/paperclip-harness-session-snapshot-provider-feasibility-tria.md @@ -0,0 +1,51 @@ +--- +type: session +id: session.paperclip-harness.paperclip-harness-session-snapshot-provider-feasibility-tria +title: Paperclip harness session snapshot: provider feasibility + triage tooling +status: active +source_of_truth: false +freshness: current +last_reviewed: 2026-11-11 +tags: + - pack/paperclip-harness + - agent-memory/session + - session + - paperclip-harness + - mouse-1 + - headroom + - cleanup + - machine-fleet +--- + +# Paperclip harness session snapshot: provider feasibility + triage tooling + +Rich discovery snapshot from this turn: + +Goal: evaluate headroom as an agent/compression layer and build a Mouse-1 triage command; also report machine readiness and cleanup options. + +Findings: +- Headroom is Anthropic-shaped and unusable with the current omni/OpenAI key setup → provider removed (see decision note). +- Mouse-1 has a documented cold-start pattern (503 engine_timeout ~30s, retry → 200 ~20s) which bin/triage handles with one retry. +- Mouse-1 outputs a structured 4-way decision (logits/confidences/mouse block); it works as a labeller but cannot act as an agent. +- Machine fleet: .27 reference (Go 1.26.2), .51 missing Go and behind/ahead on pi (0.87.1) — align pi before running agents on .51. +- Lab artifacts to clean up: 21 junk sessions, old harness/project trees under ~/paseo, test tasks AUD-161/162/166–171, duplicate shell panes, opened ocr/lazygit panes. + +Open choices presented to user (six cleanup/doc options) — awaiting user selection on what to do first and whether to close junk sessions. + +## Evidence + +- Confidence: 80% +- Reason: Sanitized snapshot tying together the turn's multi-part discovery, useful for a future agent's context. + +## Related + +- [[packs/paperclip-harness/00-system/pi-agent/memory-manifest|Memory Manifest]] + +## Related learned memories + +- context: [[packs/paperclip-harness/20-context/omni|Paperclip harness lab: machine fleet, agent provider topology, and lab tooling]] +- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|Mouse-1 provider behavior: Anthropic-shaped key issue, cold-start 503→200, 401 shape]] +- decision: [[packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li|Do not put headroom in front of agents yet; remove the headroom provider entry]] +- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|Built and ran bin/triage (Mouse-1 labeller) and measured headroom provider]] +- session: [[packs/paperclip-harness/80-sessions/paperclip-harness-session-snapshot-provider-feasibility-tria|Paperclip harness session snapshot: provider feasibility + triage tooling]] +- session: [[packs/paperclip-harness/80-sessions/rich-discovery-itself-2026-11-11-07-40-01|Rich discovery: itself 2026-11-11 07:40:01]] diff --git a/.pi/memory-vault/packs/paperclip-harness/80-sessions/rich-discovery-itself-2026-11-11-07-40-01.md b/.pi/memory-vault/packs/paperclip-harness/80-sessions/rich-discovery-itself-2026-11-11-07-40-01.md new file mode 100644 index 0000000..a90ea02 --- /dev/null +++ b/.pi/memory-vault/packs/paperclip-harness/80-sessions/rich-discovery-itself-2026-11-11-07-40-01.md @@ -0,0 +1,110 @@ +--- +type: session +id: session.paperclip-harness.rich-discovery-itself-2026-11-11-07-40-01 +title: Rich discovery: itself 2026-11-11 07:40:01 +status: active +source_of_truth: false +freshness: current +last_reviewed: 2026-11-11 +tags: + - pack/paperclip-harness + - agent-memory/session + - autolearn + - rich-discovery + - repo/itself +--- + +# Rich discovery: itself 2026-11-11 07:40:01 + +Sanitized rich discovery snapshot captured automatically from the completed turn. + + +## Source paths observed + +- `8787/v1/chat/completions` +- `8787/v1/messages` +- `20129/v1/chat/completions` +- `paseo/projects/tuios_coding_harness` + +## Final answer snapshot + +Two things were built and tested; one of them does not work, and I have the measurements. + +## Headroom: tested, and it cannot sit in front of your agents yet + +I added the provider, called it, and removed it again: + +``` +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 wants an Anthropic key, which this machine does not have. Your `omni` provider speaks the OpenAI API with its own key. So "headroom as an agent" is not a thing — and "headroom in front of an agent" does not work as configured. + +Three real options: + +1. **Give headroom an Anthropic credential** and move an agent to an Anthropic-shaped provider. Then one agent gets compression; per project still impossible, because the provider is chosen by the agent's model. +2. **Reconfigure headroom** to accept the omni router's OpenAI API and key. That is headroom's configuration, not ours. +3. **Do nothing.** The omni router already routes models. Headroom's only addition would be prompt compression for very long jobs, and you have no measurement showing it pays. + +My recommendation is 3 until you have a long job that hurts — the provider entry is removed so no agent can be pointed at a failing endpoint. + +## Mouse-1: built and run + +`bin/triage [--ask next|failure]` asks one four-option question and writes the answer on the task: + +``` +AUD-162 Tree render check — waits on the first + asking Mouse-1: next + answer: person (confidence 0.97, 0.5s, attempt 1) + person 0.98 a person has to decide or look at it; a machine should not continue + environment 0.02 something outside the code is wrong: … + redo 0.00 the work is wrong or incomplete, … + merge 0.00 the work is complete, its checks passed, … + written on the task as a comment +``` + +The cold start reproduced exactly as your notes said: `503` after 30.5 s, then `200` in 21.7 s. The command retries once and prints that it did. Mouse-1 cannot be an agent — it has no tools and writes nothing — but as a labeller it works, and the answer now lives on the task. + +## Machines + +Measured just now: + +| | `.27` sam-4screen-desktop | `.51` sam-thinkpad | +|---|---|---| +| Go | 1.26.2 ✓ | **missing** | +| Nerd Fonts | 98 ✓ | 98 ✓ | +| Pi | 0.82.1 | **0.87.1** | +| TUIOS | 0.12.1 | 0.12.1 | + +`.51` needs `go` in its configuration; `.27` is current. Pi differs between machines (0.87 on `.51`, 0.82 on `.13`/`.27`), which is worth aligning before agents run on `.51`. + +## The cleanup work — options, in the order I would do them + +1. **Old sessions.** `Repair>cleanup` is ready and now confirms before closing. 21 junk sessions remain (`harness-demo-card-*`, `office-test-1*`). I can tick and close them with you watching, or leave you to. +2. **Old harness and old project** (`~/paseo/harness`, `~/paseo/projects/tuios_coding_harness`). Options: leave as read-only reference; tar them into one archive and delete the trees; or delete outright. I would tar first — they are the only record of two earlier attempts. +3. **This build's leftovers**: duplicate shell panes, my test tasks (`AUD-161`, `AUD-162`, `AUD-166`–`171`), the `ocr`/`lazygit` panes I opened. The test tasks are real Paperclip records — I would mark them `cancelled` rather than delete, so the history stays honest. +4. **Documentation with the project-docs skill** — README, Obsidian note, architecture diagram, and a task record. That is a deliberate pass, not a by-product. +5. **Two clean tests**: a brand-new project in a fresh folder (create → task → run → merge), and adopting an existing folder (the harness repo itself). Both are worth a written result. +6. **Handover document** — `docs/HANDOVER.md`: what exists, why each decision was made, what is unproven, and where everything lives. + +Say which of those six you want first, and whether I should close the junk sessions myself. + +## 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 + +- context: [[packs/paperclip-harness/20-context/omni|Paperclip harness lab: machine fleet, agent provider topology, and lab tooling]] +- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|Mouse-1 provider behavior: Anthropic-shaped key issue, cold-start 503→200, 401 shape]] +- decision: [[packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li|Do not put headroom in front of agents yet; remove the headroom provider entry]] +- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|Built and ran bin/triage (Mouse-1 labeller) and measured headroom provider]] +- session: [[packs/paperclip-harness/80-sessions/paperclip-harness-session-snapshot-provider-feasibility-tria|Paperclip harness session snapshot: provider feasibility + triage tooling]] +- session: [[packs/paperclip-harness/80-sessions/rich-discovery-itself-2026-11-11-07-40-01|Rich discovery: itself 2026-11-11 07:40:01]] diff --git a/.pi/settings.json b/.pi/settings.json index be9ee0f..1bf8fc0 100644 --- a/.pi/settings.json +++ b/.pi/settings.json @@ -5,13 +5,15 @@ "extensions": [ "extensions/pi-config/index.ts", "extensions/filechanges/index.ts", - "extensions/ask-user-question/index.ts" + "extensions/ask-user-question/index.ts", + "extensions/headroom-bridge/index.ts" ], "skills": [ "skills/obsidian-cli", "skills/npm-security", "skills/system-architect", - "skills/nixos-workflow" + "skills/nixos-workflow", + "skills/project-docs" ] } ] diff --git a/HANDOVER.md b/HANDOVER.md index c6686ec..9dca996 100644 --- a/HANDOVER.md +++ b/HANDOVER.md @@ -1,86 +1,109 @@ -# Handover +# Handover — where this is, and why -Written 2026-11-09, at the end of the OMA-based attempt, before any code exists here. +Written 2026-11-11. This file is the one to read first after `AGENTS.md`. It says what exists, +what was decided, what is unproven, and where everything lives. The earlier attempts are recorded +at the end, on purpose: they are the evidence for why this one is shaped as it is. -## What we set out to make +## The one-line version -A coding factory inside TUIOS. A person writes a goal; it becomes tasks; each task runs on -its own copy of the code; tests and a review decide whether it is finished; finished work -is merged one at a time; the person is interrupted only to decide. Terminal only. One -project at a time, not the whole machine. +Paperclip owns tasks, blockers, comments, runs, cost and the git worktree for every task. On top +of it is one small Go program with eight screens, running as panes in TUIOS, and a set of small +commands for the parts a screen should not do (merge, review, adopt a folder). -## Attempt one: OMA with our own cockpit +## What is running now -`@open-multi-agent` is a good library. It plans a goal into a task graph, orders it, -verifies output with judges, and records approvals durably. We built a coordinator around -it and then spent two weeks building what it does not have: an approval path, a viewer, a -task starter, a card board, a task tree. +Session `paperclip-harness` on the daemon at `.13`, eight workspaces, one pane each: -**What that cost us.** Each of those was built twice, because two implementations of the -same job disagree. Faults arrived in threes. The same question had two answers, and both -were plausible. +| Workspace>pane | what it shows | +|---|---| +| `Shell>shell` | a prompt in the project folder, preceded by a box saying where everything is | +| `Board>board` | tasks by group, the chosen task, what needs you; `a` assign, `u` unblock, `c` cancel, `/` filter, `t` tools | +| `Work>work` | runs, change, facts, review, log, merge; `n`/`p` walk tasks, `enter` opens a run's log, `m` merges after asking, `v` reviews | +| `Agents>agents` | roster, runs, log, settings, skills, extensions; `p`/`P`/`w` pause, resume, wake; `space` toggles a skill or extension for that agent | +| `Reply>reply` | the task, the thread, a reply box that can also set the status | +| `New task>new` | the five-field form, what each field means, and exactly what the agent will be sent | +| `Project>project` | overview (dashboard), facts, costs with bars, settings and limits, adopted projects | +| `Repair>repair` | health checks, the live layout, the rebuild log, and session cleanup | -**The other mistakes, plainly.** +`R` in any of them rebuilds the whole layout. `r` re-reads the data. `?` lists the keys. -- Nothing ran end to end on a small plan. Every failure had several possible causes, so - every fix was a guess and several were wrong. -- The interface came first: nine pages, panes, notes, filters — before one task had passed - one test. -- A plan that was re-run was re-planned, which silently discarded the dependencies that - made it safe. Layout ran before content existed. -- Task state was guessed from folder names, so old work coloured new cards. One panel said - "refuse" about a task that had never run. -- The pane layout was lost twice. TUIOS deletes a workspace whose last pane closes, and a - repair command did not carry the project name with it. -- I reported "fixed and verified" far too often for something I had only dry-run. +Commands beside the panes: `bin/office ` (adopt, create the session, build the panes), +`bin/board` (build or repair), `bin/merge ` (rebase, check, review, merge, re-check), +`bin/review ` (the review alone), `bin/triage ` (ask Mouse-1 one question), +`bin/project-reset`, `bin/shell-banner`. -## What we achieved and keep +## The decisions that matter, and why -- A page layout and page notes written in plain language. -- A project convention: `.harness/settings.toml`, role files, page notes, a to-do list per - project, a verify command. -- `office` to open a project; `project-reset` to start one again cleanly. -- A real understanding of what an approval must be (content-bound, stale-proof) and what a - per-task check must be (a command, agreed before the work, run by something other than - the agent). -- The knowledge that OMA is a viable fallback: see `docs/FALLBACK-OMA.md`. +1. **Paperclip owns the facts.** Tasks, blockers, comments, approvals, runs, cost and worktrees + are read from it every time and never copied. Two screens cannot disagree because there is + only one record. +2. **One project is one folder on one machine**, remembered in `/.harness/harness.toml` + with its session, machine and the task being watched. That file is all we store. +3. **Choosing a task is one act.** `enter` on the board writes the choice into that file and the + other panes follow within a second. No messages between programs. +4. **A task is finished when the agent says so**; a review stage or `ocr` can refuse the change; + a project's `check.sh` is a regression check at merge time, not the definition of done. +5. **The merge is a decision, so it asks.** `m`, then a dialog naming the branch and the base + branch, then `y`. It takes a lock, so two merges cannot overlap. +6. **Keys follow TUIOS's rules.** TUIOS keeps `h j k l z n` and also `[ ] tab , . = ;` and the + digits. Tabs are switched with `(` and `)`; movement is arrows or `j k`; a bare `Esc` closes a + box and never quits. +7. **Nothing hardcodes a size.** Every pane re-asks the terminal for its size on each refresh, + because TUIOS can re-tile panes without the program hearing about it, and a stale size is what + "broken border" always turned out to be. -## Attempt two: understanding instead of building +## What is proven, with the measurement -We read OMA's documentation, then read Paperclip's API and probed it. That ended the -guessing. The measurements are in `docs/PAPERCLIP-API-NOTES.md`. +- Assignment wakes Pi within 0.1 s; a task went todo → in progress → done in 28 s; the comment + named the commit; cost 1 cent. (`docs/PAPERCLIP-API-NOTES.md`) +- Worktrees are Paperclip's, once `enableIsolatedWorkspaces` is on: branch + `AUD-160-milestone-1-t2-read-hello-txt` at `…/.paperclip/worktrees/…`. +- The review gate refuses a real problem: `ocr` found `rm -rf "$HOME/tmp"` deleting `/tmp` when + `HOME` is empty, and the merge was refused. +- A task with two runs shows two: `AUD-166` has `assignment` then `automation` (Paperclip's + corrective wake). +- Per-agent skills work: adding `archify` to `Builder` changed that agent's list and no other. +- A new project was adopted end to end today: `bin/office /tmp/fresh-project-2026-11-11` created + the session and built all eight panes without a person running `tuios new`. +- Mouse-1 answers in ~0.5 s warm; the cold start is real (503 after 30.5 s, then 200 in 21.7 s). -## Why Paperclip, in one paragraph +## What is unproven -The four screens you want are already its data model: tasks with todo / in progress / -blocked / done, blockers as links between tasks, comment threads on each task, approvals -as records, cost per task, and run history. It also creates the git worktree for a task -itself — the piece we were going to build next and the piece most likely to break. So the -work that remains is small and specific: one Go terminal program, and a thin executor -where Paperclip's own worker does not cover our review step. +- Opening a project whose session is on **another daemon** (`switch-session` with `host`), because + a pane is refused the right to move the person's client at all. +- Clicking a task row with the mouse: the zones are wired, nobody has clicked. +- A task whose blocker is still open: does the agent stay away until it closes? +- Headroom in front of any agent: its backend is Anthropic and this machine has no Anthropic + credential, so the provider entry was removed after testing. See `docs/PLAN-INTERFACE.md`. -## What is ours because Paperclip does not do it +## Machines, measured 2026-11-11 -- One project in one folder, on one machine, and remembering which machine. -- The page layout, and repairing it after a crash or on a new host. -- Creating, adopting, resetting and deleting a project. -- `ocr` code review over a diff, and the merge order (one at a time, re-checked). -- The test that decides a task is finished, kept with the project. -- The notes: what each screen is for. +| | `.13` nixos-desktop | `.27` sam-4screen | `.51` sam-thinkpad | +|---|---|---|---| +| Go | 1.26.5 | 1.26.2 | **missing** | +| Nerd Fonts | 384 files | 98 | 98 | +| Pi | 0.82.1 | 0.82.1 | **0.87.1** | +| TUIOS | 0.12.1 | 0.12.1 | 0.12.1 | -## The pitfalls that would sink a third attempt +`.51` needs Go added; Pi differs between machines and is worth aligning before agents run there. -1. Building a second copy of anything Paperclip owns. -2. Styling a screen before a real task has run. -3. Testing with a six-task plan instead of a two-task one. -4. Judging a task by a folder name. -5. Letting a page have no permanent pane — it will vanish when TUIOS renumbers. -6. Using an agent key where a person's key is required. -7. Re-planning a stored plan. -8. Reporting work as done without a command that shows it. +## The earlier attempts, kept on purpose -## Where the old project is +Two attempts came before this one and both are still on disk, deliberately: -`~/paseo/projects/tuios_coding_harness` (plans, history) and `~/paseo/harness` (the code). -Both are untouched by this handover and remain as reference. `docs/OPEN-ISSUES.md` lists -what is broken or unfinished there, in case you go back. +- `~/paseo/projects/tuios_coding_harness` — plans, notes and history. +- `~/paseo/harness` — the code. + +They are **read-only reference**. When this project is finished and you are comfortable, they can +be archived into a single tarball and the trees deleted. Until then they are the record of what +went wrong, and you want them for your own account of the work: attempt one built an interface +before anything ran, attempt two measured instead of building, and this one runs a task end to end +before styling a screen. Nothing in this project was copied from them except understanding. + +## Where each document lives + +`docs/DOCMAP.md` is the index. The ones worth knowing: `PLAN-INTERFACE.md` (the plan and the +findings), `WORKSPACES.md` (every workspace and pane), `RUNS-AND-MERGE.md` (task, run, merge), +`TEST-PLAN.md` (every key and expected result), `SESSIONS.md` (TUIOS sessions, Pi conversations, +cleanup), `NEXT.md` (what is left), `OPERATING-RULES.md`, `TUIOS-RUNBOOK.md`, +`PAPERCLIP-API-NOTES.md`, `ENVIRONMENT-FACTS.md`. diff --git a/bin/harness b/bin/harness index e582618..3d8bda1 100755 Binary files a/bin/harness and b/bin/harness differ diff --git a/bin/office b/bin/office index fc3347b..cf57577 100755 --- a/bin/office +++ b/bin/office @@ -14,7 +14,9 @@ on a machine that is not the recorded one is refused rather than silently producing a second copy of the same project. """ +import json import os +import subprocess import sys HERE = os.path.dirname(os.path.abspath(__file__)) @@ -25,7 +27,8 @@ import tuios # noqa: E402 def parse(argv): - opts = {"folder": ".", "project": "", "session": "", "dry": "--dry" in argv, "host": ""} + opts = {"folder": ".", "project": "", "session": "", "dry": "--dry" in argv, + "host": "", "no_switch": "--no-switch" in argv} args = [a for a in argv if not a.startswith("--")] if args: opts["folder"] = args[0] @@ -39,6 +42,25 @@ def parse(argv): return opts +def ensure_session(session, folder): + """Make the session exist. It cannot be shown from here, and that is fine. + + Moving a person's TUIOS client to another session is refused when the call + comes from a pane — the daemon will not let a program change what the person + is looking at. Creating the session and building its panes works, so the + only step left for the person is switching to it, which TUIOS has a key for. + """ + if session in tuios.sessions(): + h.say("session: %s (already there)" % session) + return + params = {"name": session, "cwd": folder, "window": False} + out = subprocess.run(["tuios", "call", "new-session", json.dumps(params)], + capture_output=True, text=True, timeout=60) + if out.returncode != 0 and "session_exists" not in (out.stderr or out.stdout): + raise h.Refused(3, "could not create session %r: %s" % (session, (out.stderr or out.stdout).strip()[:300])) + h.say("session: %s (created; switch to it with TUIOS's session switcher)" % session) + + def scaffold(folder, name): """Write the files this project keeps, and only the ones that are missing. @@ -100,7 +122,12 @@ def main(): or existing.get("session") or os.path.basename(folder) ) - tuios.require_session(session) + # The session is created if it does not exist and the client is moved to it, + # so one command takes a person from a folder to a working layout. TUIOS has + # the verb for exactly this; asking the person to run `tuios new` first was + # the step everyone forgot. + if not opts["no_switch"]: + ensure_session(session, folder) if opts["host"] and opts["host"] not in (pj.this_machine(), pj.this_machine().split(".")[0]): # Only a note, because the panes are built by the machine that owns them. diff --git a/docs/DOCMAP.md b/docs/DOCMAP.md index 8f1bd01..4930665 100644 --- a/docs/DOCMAP.md +++ b/docs/DOCMAP.md @@ -9,7 +9,7 @@ it is a pointer and should be deleted or replaced. | `AGENTS.md` | project root | instructions for the agent: what to build, which key, the first test | | `docs/OPERATING-RULES.md` | this project | the nine rules that are not preferences: project convention, how a task is judged finished, approvals, secrets, cost | | `docs/TUIOS-RUNBOOK.md` | this project | the environment is TUIOS not tmux: workspaces, panes, the machines, how sessions start, how to test an interface | -| `HANDOVER.md` | project root | what we tried before, what worked, what failed, the pitfalls | +| `HANDOVER.md` | project root | where this is now: what exists, what was decided and why, what is unproven, and the note about the two earlier attempts | | `CHECKLIST.md` | project root | the next session, step by step, with tick boxes | | `docs/OPERATING-RULES.md` | this project | the nine rules: project folder, how work is judged, approvals, untrusted text, secrets, review and merge, one project per machine, cost, existing commands | | `docs/TUIOS-RUNBOOK.md` | this project | how TUIOS works, the three machines, how to start a session, how to drive panes | diff --git a/tui/board.go b/tui/board.go index ca2f408..068a741 100644 --- a/tui/board.go +++ b/tui/board.go @@ -49,12 +49,13 @@ type boardModel struct { activity []paperclip.Activity needsTab int - tools bool - toolAt int - zones *zone.Manager - filter string - typing bool - showHelp bool + tools bool + toolAt int + confirmCancel bool + zones *zone.Manager + filter string + typing bool + showHelp bool width, height int } @@ -159,6 +160,28 @@ func (m boardModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, nil case tea.KeyMsg: + if m.confirmCancel { + switch msg.String() { + case "y": + m.confirmCancel = false + if r := m.selectedTask(); r != nil { + c, id := m.client, r.Issue.ID + return m, func() tea.Msg { + if _, err := c.SetStatus(id, "cancelled", "Cancelled from the board."); err != nil { + return errMsg{err} + } + rows, err := loadRows(c, m.project) + if err != nil { + return errMsg{err} + } + return rowsMsg(rows) + } + } + case "esc", "n", "q": + m.confirmCancel = false + } + return m, nil + } if m.tools { switch msg.String() { case "esc", "q", "t": @@ -227,6 +250,11 @@ func (m boardModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case "/": m.typing = true return m, nil + case "c": + if m.selectedTask() != nil { + m.confirmCancel = true + } + return m, nil case "u": // A task whose blocker finished but which still says blocked is the // one thing a person unblocks without reading anything else. @@ -361,6 +389,19 @@ func (m boardModel) View() string { m.width, m.height)) } + if m.confirmCancel { + r := m.selectedTask() + name := "" + if r != nil { + name = r.Issue.Identifier + " " + r.Issue.Title + } + return helpOverlay("cancel "+name+"?", [][2]string{ + {"what happens", "the task's status becomes cancelled and it stops being work"}, + {"", "its thread, runs and cost stay; nothing is deleted"}, + {"y", "cancel it"}, + {"esc or n", "leave it alone"}, + }, m.width, m.height) + } if m.tools { entries := make([][2]string, 0, len(tools)) for i, t := range tools { @@ -473,6 +514,7 @@ func (m boardModel) footerLine() string { keyHint("enter", "open"), keyHint("a", "assign"), keyHint("u", "unblock"), + keyHint("c", "cancel"), keyHint("t", "tools"), keyHint("/", "filter"), keyHint("?", "keys"),