Task and run navigation inside Work>work; explain what a run and a merge are

This commit is contained in:
Sam
2026-11-11 13:17:22 +11:00
parent 049e25af70
commit 6aef6ce249
11 changed files with 566 additions and 6 deletions

View File

@@ -297,3 +297,86 @@ Committed as `7198c34`; the eight workspaces are rebuilt and running.
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-bin-2026-11-11-01-02-31|Rich discovery: bin 2026-11-11 01:02:31]]
- context: [[packs/paperclip-harness/20-context/tmp|bin]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|bin repository structure and configuration patterns]]
---
## Update (2026-11-11 01:58:59)
The paperclip-harness TUI is a Go program in `paperclip-harness/tui` (main logic in `work.go`). It wraps work on Paperclip tasks/issues: pane `Work>work` shows a tab bar `runs · change · facts · review · log · merge` with `runs` as the default tab, listing every run of the chosen task with a cursor. Pressing Enter on a run opens the `log` tab showing what Pi actually did (wake payload, reasoning, tool calls). Merge is gated: pressing `m` opens a confirmation dialog describing exactly what will happen (rebase onto base branch, optional verify command, `ocr` review with critical findings refusing merge, merge, then re-run checks on base branch); nothing merges until `y`. `t` opens lazygit for manual git inspection; that is not the merge gate — `bin/merge <TASK>` is. The Shell pane (`Shell>shell`) opens with a 'where things are' box listing project folder, task worktrees (`.paperclip/worktrees`), project file (`.harness/harness.toml`), harness commands (repo `bin`), pi conversations (`~/.pi/paperclips`), pi skills (`~/.agents/skills`), paperclip data (`~/.paperclip/instances/default`), session name, and watched task. Harness commands include wrapped panes plus unwrapped shell commands `bin/merge <TASK>` and `bin/review <TASK>`.
## Detailed context from completed turn
You caught three real problems. All three were mine, and all three are fixed.
## "You are auto merging" — that was the `m` key, and it was wrong
`m` used to merge immediately. Now it asks, and tells you exactly what it will do:
```
╭─ merge AUD-171? ─────────────────────────────────────·focus· ╮
│ what happens rebase onto the base branch │
│ no verify command: the review decides │
│ ocr reviews the change; a critical finding refuses the merge
│ merge, then re-run the checks on the base branch
│ y do it │
│ esc or n do nothing │
```
Nothing merges until you press `y`. That is the approve step. The workflow is now: read the verdict in **review**, then `m` → read what will happen → `y`.
The two merges you saw (`AUD-168`, `AUD-171`) were me pressing `m` while testing, not an agent and not the interface deciding on its own.
## "Work>work does not have a list of runs"
It had one, but the pane was left sitting on the **merge** tab from my test, so you never saw it. Two changes:
- **runs is the default tab** when the pane opens, and it lists every run of the chosen task with a cursor;
- pressing **`Enter` on a run opens a new `log` tab** with what Pi actually did — the wake payload, its reasoning, its tool calls.
The tab bar is now `runs · change · facts · review · log · merge`.
## Lazygit, and where it fits
Lazygit is not the merge gate. It is still one keystroke away (`t` → lazygit) for looking at branches, staging or history by hand. The gate is `bin/merge`: rebase, verify if the task has a command, `ocr` review, merge, re-check. Two different jobs — one is for you to poke at git, the other is the decision to put work on the main line.
## Shell now says where everything is
`Shell>shell` opens with a box, so you never have to remember a path:
```
┌─ where things are ───────────────────────────────────────────────────┐
│ project folder /tmp/pc-sandbox-2026-11-10 │
│ task worktrees /tmp/pc-sandbox-2026-11-10/.paperclip/worktrees │
│ this project's file /tmp/pc-sandbox-2026-11-10/.harness/harness.to… │
│ harness commands /home/sam/paseo/projects/paperclip-harness/bin │
│ pi conversations /home/sam/.pi/paperclips │
│ pi skills you own /home/sam/.agents/skills │
│ paperclip data /home/sam/.paperclip/instances/default │
│ session paperclip-harness │
│ watching AUD-171 │
└──────────────────────────────────────────────────────────────────────┘
```
Below it, four commands with one line each, for the things we deliberately do not wrap.
## Documentation updated
- `docs/TEST-PLAN.md` — step 4 now includes the confirmation, and a new step 4b covers picking a run and reading its log. Still no terminal commands anywhere.
- `README.md` and `docs/WORKSPACES.md` — the new tabs, the `m` confirmation, the shell box.
Committed as `049e25a`. The eight workspaces are rebuilt; `Work>work` will open on runs with `AUD-171` chosen.
## Evidence
- Confidence: 90%
- Reason: Durable architecture/component overview discovered in the turn.; enriched with final-answer detail because persistence should be reusable
## Related learned memories <!-- same-turn-2026-11-11 01:58:59 -->
- context: [[packs/paperclip-harness/20-context/paperclip-harness|paperclip-harness TUI]]
- decision: [[packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li|Merge key requires explicit confirmation; lazygit is not the merge gate]]
- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|Fixed TUI merge confirmation, Work>work runs/log tabs, and shell path box; committed 049e25a]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-tmp-2026-11-11-01-58-59|Rich discovery: tmp 2026-11-11 01:58:59]]
- context: [[packs/paperclip-harness/20-context/tmp|tmp]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|tmp repository structure and configuration patterns]]

View File

@@ -839,3 +839,94 @@ Committed as `7198c34`; the eight workspaces are rebuilt and running.
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-bin-2026-11-11-01-02-31|Rich discovery: bin 2026-11-11 01:02:31]]
- context: [[packs/paperclip-harness/20-context/tmp|bin]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|bin repository structure and configuration patterns]]
---
## Update (2026-11-11 01:58:59)
## Rich discovery update (2026-11-11 01:58:59)
You caught three real problems. All three were mine, and all three are fixed.
## "You are auto merging" — that was the `m` key, and it was wrong
`m` used to merge immediately. Now it asks, and tells you exactly what it will do:
```
╭─ merge AUD-171? ─────────────────────────────────────·focus· ╮
│ what happens rebase onto the base branch │
│ no verify command: the review decides │
│ ocr reviews the change; a critical finding refuses the merge
│ merge, then re-run the checks on the base branch
│ y do it │
│ esc or n do nothing │
```
Nothing merges until you press `y`. That is the approve step. The workflow is now: read the verdict in **review**, then `m` → read what will happen → `y`.
The two merges you saw (`AUD-168`, `AUD-171`) were me pressing `m` while testing, not an agent and not the interface deciding on its own.
## "Work>work does not have a list of runs"
It had one, but the pane was left sitting on the **merge** tab from my test, so you never saw it. Two changes:
- **runs is the default tab** when the pane opens, and it lists every run of the chosen task with a cursor;
- pressing **`Enter` on a run opens a new `log` tab** with what Pi actually did — the wake payload, its reasoning, its tool calls.
The tab bar is now `runs · change · facts · review · log · merge`.
## Lazygit, and where it fits
Lazygit is not the merge gate. It is still one keystroke away (`t` → lazygit) for looking at branches, staging or history by hand. The gate is `bin/merge`: rebase, verify if the task has a command, `ocr` review, merge, re-check. Two different jobs — one is for you to poke at git, the other is the decision to put work on the main line.
## Shell now says where everything is
`Shell>shell` opens with a box, so you never have to remember a path:
```
┌─ where things are ───────────────────────────────────────────────────┐
│ project folder /tmp/pc-sandbox-2026-11-10 │
│ task worktrees /tmp/pc-sandbox-2026-11-10/.paperclip/worktrees │
│ this project's file /tmp/pc-sandbox-2026-11-10/.harness/harness.to… │
│ harness commands /home/sam/paseo/projects/paperclip-harness/bin │
│ pi conversations /home/sam/.pi/paperclips │
│ pi skills you own /home/sam/.agents/skills │
│ paperclip data /home/sam/.paperclip/instances/default │
│ session paperclip-harness │
│ watching AUD-171 │
└──────────────────────────────────────────────────────────────────────┘
```
Below it, four commands with one line each, for the things we deliberately do not wrap.
## Documentation updated
- `docs/TEST-PLAN.md` — step 4 now includes the confirmation, and a new step 4b covers picking a run and reading its log. Still no terminal commands anywhere.
- `README.md` and `docs/WORKSPACES.md` — the new tabs, the `m` confirmation, the shell box.
Committed as `049e25a`. The eight workspaces are rebuilt; `Work>work` will open on runs with `AUD-171` chosen.
## Source paths observed
- `tmp/pc-sandbox-2026-11-10/.paperclip/worktrees`
- `tmp/pc-sandbox-2026-11-10/.harness/harness.toml`
- `home/sam/paseo/projects/paperclip-harness/bin`
- `home/sam/.pi/paperclips`
- `home/sam/.agents/skills`
- `home/sam/.paperclip/instances/default`
- `tmp/pc-sandbox-2026-11-10/.harness/harness.to`
## Evidence
- Confidence: 84%
- Reason: Update component/repository context with detailed discovered structure and configuration
## Related learned memories <!-- same-turn-2026-11-11 01:58:59 -->
- context: [[packs/paperclip-harness/20-context/paperclip-harness|paperclip-harness TUI]]
- decision: [[packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li|Merge key requires explicit confirmation; lazygit is not the merge gate]]
- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|Fixed TUI merge confirmation, Work>work runs/log tabs, and shell path box; committed 049e25a]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-tmp-2026-11-11-01-58-59|Rich discovery: tmp 2026-11-11 01:58:59]]
- context: [[packs/paperclip-harness/20-context/tmp|tmp]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|tmp repository structure and configuration patterns]]

View File

@@ -586,3 +586,24 @@ Follow-ups proposed (in order): user runs nine-step keys-only plan and reports d
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-bin-2026-11-11-01-02-31|Rich discovery: bin 2026-11-11 01:02:31]]
- context: [[packs/paperclip-harness/20-context/tmp|bin]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|bin repository structure and configuration patterns]]
---
## Update (2026-11-11 01:58:59)
Completed work (commit `049e25a`, message: 'Merge asks first; Work>work lists runs with a log tab; Shell says where everything is'): (1) `work.go` in `paperclip-harness/tui` now guards merge behind a confirmation dialog (y/n); (2) `Work>work` defaults to the `runs` tab, lists runs with a cursor, and Enter on a run opens a new `log` tab showing the run's wake payload, reasoning, and tool calls; tab bar is now `runs · change · facts · review · log · merge`; (3) `Shell>shell` prints a 'where things are' box of key paths plus one-line hints for unwrapped commands `bin/merge` and `bin/review`. Docs updated: `docs/TEST-PLAN.md` step 4 includes the confirmation and new step 4b covers picking a run and reading its log (still no terminal commands in the test plan); `README.md` and `docs/WORKSPACES.md` cover the new tabs, the `m` confirmation, and the shell box. Validation: builds clean (`go build` of tui), syntax checks ok, the eight workspaces were rebuilt, and `Work>work` opens on runs with AUD-171 chosen.
## Evidence
- Confidence: 90%
- Reason: Concrete completed deliverable with artifacts and validation.
## Related learned memories <!-- same-turn-2026-11-11 01:58:59 -->
- context: [[packs/paperclip-harness/20-context/paperclip-harness|paperclip-harness TUI]]
- decision: [[packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li|Merge key requires explicit confirmation; lazygit is not the merge gate]]
- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|Fixed TUI merge confirmation, Work>work runs/log tabs, and shell path box; committed 049e25a]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-tmp-2026-11-11-01-58-59|Rich discovery: tmp 2026-11-11 01:58:59]]
- context: [[packs/paperclip-harness/20-context/tmp|tmp]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|tmp repository structure and configuration patterns]]

View File

@@ -192,3 +192,24 @@ Committed as `7198c34`; the eight workspaces are rebuilt and running.
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-bin-2026-11-11-01-02-31|Rich discovery: bin 2026-11-11 01:02:31]]
- context: [[packs/paperclip-harness/20-context/tmp|bin]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|bin repository structure and configuration patterns]]
---
## Update (2026-11-11 01:58:59)
Decision: In the paperclip-harness TUI, pressing `m` on a task no longer merges immediately. It opens a confirmation dialog that explains the merge steps (rebase onto base branch, run the task's verify command if one exists else the review decides, `ocr` review that refuses on critical findings, merge, then re-run checks on the base branch), and the merge only proceeds on `y` (esc/n cancels). Context: earlier `m` merged instantly, which was interpreted as auto-merging and was undesirable; two unintended test merges (AUD-168, AUD-171) happened this way. Rationale: make approval explicit and make consequences visible before an irreversible action. Consequences: intended workflow is read the verdict in `review`, press `m`, read what will happen, press `y`. Lazygit (`t`) remains available for manual branch/stage/history work but is explicitly NOT the merge gate; `bin/merge <TASK>` is the gate. Caveat: `bin/review <TASK>` runs the review alone.
## Evidence
- Confidence: 90%
- Reason: Architectural/convention decision with context, rationale, and consequences.
## Related learned memories <!-- same-turn-2026-11-11 01:58:59 -->
- context: [[packs/paperclip-harness/20-context/paperclip-harness|paperclip-harness TUI]]
- decision: [[packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li|Merge key requires explicit confirmation; lazygit is not the merge gate]]
- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|Fixed TUI merge confirmation, Work>work runs/log tabs, and shell path box; committed 049e25a]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-tmp-2026-11-11-01-58-59|Rich discovery: tmp 2026-11-11 01:58:59]]
- context: [[packs/paperclip-harness/20-context/tmp|tmp]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|tmp repository structure and configuration patterns]]

View File

@@ -2294,3 +2294,94 @@ Committed as `7198c34`; the eight workspaces are rebuilt and running.
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-bin-2026-11-11-01-02-31|Rich discovery: bin 2026-11-11 01:02:31]]
- context: [[packs/paperclip-harness/20-context/tmp|bin]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|bin repository structure and configuration patterns]]
---
## Update (2026-11-11 01:58:59)
## Structural/configuration observations (2026-11-11 01:58:59)
You caught three real problems. All three were mine, and all three are fixed.
## "You are auto merging" — that was the `m` key, and it was wrong
`m` used to merge immediately. Now it asks, and tells you exactly what it will do:
```
╭─ merge AUD-171? ─────────────────────────────────────·focus· ╮
│ what happens rebase onto the base branch │
│ no verify command: the review decides │
│ ocr reviews the change; a critical finding refuses the merge
│ merge, then re-run the checks on the base branch
│ y do it │
│ esc or n do nothing │
```
Nothing merges until you press `y`. That is the approve step. The workflow is now: read the verdict in **review**, then `m` → read what will happen → `y`.
The two merges you saw (`AUD-168`, `AUD-171`) were me pressing `m` while testing, not an agent and not the interface deciding on its own.
## "Work>work does not have a list of runs"
It had one, but the pane was left sitting on the **merge** tab from my test, so you never saw it. Two changes:
- **runs is the default tab** when the pane opens, and it lists every run of the chosen task with a cursor;
- pressing **`Enter` on a run opens a new `log` tab** with what Pi actually did — the wake payload, its reasoning, its tool calls.
The tab bar is now `runs · change · facts · review · log · merge`.
## Lazygit, and where it fits
Lazygit is not the merge gate. It is still one keystroke away (`t` → lazygit) for looking at branches, staging or history by hand. The gate is `bin/merge`: rebase, verify if the task has a command, `ocr` review, merge, re-check. Two different jobs — one is for you to poke at git, the other is the decision to put work on the main line.
## Shell now says where everything is
`Shell>shell` opens with a box, so you never have to remember a path:
```
┌─ where things are ───────────────────────────────────────────────────┐
│ project folder /tmp/pc-sandbox-2026-11-10 │
│ task worktrees /tmp/pc-sandbox-2026-11-10/.paperclip/worktrees │
│ this project's file /tmp/pc-sandbox-2026-11-10/.harness/harness.to… │
│ harness commands /home/sam/paseo/projects/paperclip-harness/bin │
│ pi conversations /home/sam/.pi/paperclips │
│ pi skills you own /home/sam/.agents/skills │
│ paperclip data /home/sam/.paperclip/instances/default │
│ session paperclip-harness │
│ watching AUD-171 │
└──────────────────────────────────────────────────────────────────────┘
```
Below it, four commands with one line each, for the things we deliberately do not wrap.
## Documentation updated
- `docs/TEST-PLAN.md` — step 4 now includes the confirmation, and a new step 4b covers picking a run and reading its log. Still no terminal commands anywhere.
- `README.md` and `docs/WORKSPACES.md` — the new tabs, the `m` confirmation, the shell box.
Committed as `049e25a`. The eight workspaces are rebuilt; `Work>work` will open on runs with `AUD-171` chosen.
## Source paths observed
- `tmp/pc-sandbox-2026-11-10/.paperclip/worktrees`
- `tmp/pc-sandbox-2026-11-10/.harness/harness.toml`
- `home/sam/paseo/projects/paperclip-harness/bin`
- `home/sam/.pi/paperclips`
- `home/sam/.agents/skills`
- `home/sam/.paperclip/instances/default`
- `tmp/pc-sandbox-2026-11-10/.harness/harness.to`
## Evidence
- Confidence: 82%
- Reason: Captured factual repo structure/configuration patterns from rich discovery
## Related learned memories <!-- same-turn-2026-11-11 01:58:59 -->
- context: [[packs/paperclip-harness/20-context/paperclip-harness|paperclip-harness TUI]]
- decision: [[packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li|Merge key requires explicit confirmation; lazygit is not the merge gate]]
- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|Fixed TUI merge confirmation, Work>work runs/log tabs, and shell path box; committed 049e25a]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-tmp-2026-11-11-01-58-59|Rich discovery: tmp 2026-11-11 01:58:59]]
- context: [[packs/paperclip-harness/20-context/tmp|tmp]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|tmp repository structure and configuration patterns]]

View File

@@ -0,0 +1,110 @@
---
type: session
id: session.paperclip-harness.rich-discovery-tmp-2026-11-11-01-58-59
title: Rich discovery: tmp 2026-11-11 01:58:59
status: active
source_of_truth: false
freshness: current
last_reviewed: 2026-11-11
tags:
- pack/paperclip-harness
- agent-memory/session
- autolearn
- rich-discovery
- repo/tmp
---
# Rich discovery: tmp 2026-11-11 01:58:59
Sanitized rich discovery snapshot captured automatically from the completed turn.
## Source paths observed
- `tmp/pc-sandbox-2026-11-10/.paperclip/worktrees`
- `tmp/pc-sandbox-2026-11-10/.harness/harness.toml`
- `home/sam/paseo/projects/paperclip-harness/bin`
- `home/sam/.pi/paperclips`
- `home/sam/.agents/skills`
- `home/sam/.paperclip/instances/default`
- `tmp/pc-sandbox-2026-11-10/.harness/harness.to`
## Final answer snapshot
You caught three real problems. All three were mine, and all three are fixed.
## "You are auto merging" — that was the `m` key, and it was wrong
`m` used to merge immediately. Now it asks, and tells you exactly what it will do:
```
╭─ merge AUD-171? ─────────────────────────────────────·focus· ╮
│ what happens rebase onto the base branch │
│ no verify command: the review decides │
│ ocr reviews the change; a critical finding refuses the merge
│ merge, then re-run the checks on the base branch
│ y do it │
│ esc or n do nothing │
```
Nothing merges until you press `y`. That is the approve step. The workflow is now: read the verdict in **review**, then `m` → read what will happen → `y`.
The two merges you saw (`AUD-168`, `AUD-171`) were me pressing `m` while testing, not an agent and not the interface deciding on its own.
## "Work>work does not have a list of runs"
It had one, but the pane was left sitting on the **merge** tab from my test, so you never saw it. Two changes:
- **runs is the default tab** when the pane opens, and it lists every run of the chosen task with a cursor;
- pressing **`Enter` on a run opens a new `log` tab** with what Pi actually did — the wake payload, its reasoning, its tool calls.
The tab bar is now `runs · change · facts · review · log · merge`.
## Lazygit, and where it fits
Lazygit is not the merge gate. It is still one keystroke away (`t` → lazygit) for looking at branches, staging or history by hand. The gate is `bin/merge`: rebase, verify if the task has a command, `ocr` review, merge, re-check. Two different jobs — one is for you to poke at git, the other is the decision to put work on the main line.
## Shell now says where everything is
`Shell>shell` opens with a box, so you never have to remember a path:
```
┌─ where things are ───────────────────────────────────────────────────┐
│ project folder /tmp/pc-sandbox-2026-11-10 │
│ task worktrees /tmp/pc-sandbox-2026-11-10/.paperclip/worktrees │
│ this project's file /tmp/pc-sandbox-2026-11-10/.harness/harness.to… │
│ harness commands /home/sam/paseo/projects/paperclip-harness/bin │
│ pi conversations /home/sam/.pi/paperclips │
│ pi skills you own /home/sam/.agents/skills │
│ paperclip data /home/sam/.paperclip/instances/default │
│ session paperclip-harness │
│ watching AUD-171 │
└──────────────────────────────────────────────────────────────────────┘
```
Below it, four commands with one line each, for the things we deliberately do not wrap.
## Documentation updated
- `docs/TEST-PLAN.md` — step 4 now includes the confirmation, and a new step 4b covers picking a run and reading its log. Still no terminal commands anywhere.
- `README.md` and `docs/WORKSPACES.md` — the new tabs, the `m` confirmation, the shell box.
Committed as `049e25a`. The eight workspaces are rebuilt; `Work>work` will open on runs with `AUD-171` chosen.
## 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 01:58:59 -->
- context: [[packs/paperclip-harness/20-context/paperclip-harness|paperclip-harness TUI]]
- decision: [[packs/paperclip-harness/50-decisions/paperclip-harness-ui-six-workspaces-spec-first-four-panel-li|Merge key requires explicit confirmation; lazygit is not the merge gate]]
- action: [[packs/paperclip-harness/40-actions/2026-11-10-wrote-docs-ui-layout-md-and-three-live-layout-mockups|Fixed TUI merge confirmation, Work>work runs/log tabs, and shell path box; committed 049e25a]]
- session: [[packs/paperclip-harness/80-sessions/rich-discovery-tmp-2026-11-11-01-58-59|Rich discovery: tmp 2026-11-11 01:58:59]]
- context: [[packs/paperclip-harness/20-context/tmp|tmp]]
- observation: [[packs/paperclip-harness/60-observations/tmp-repository-structure-and-configuration-patterns|tmp repository structure and configuration patterns]]

View File

@@ -60,7 +60,7 @@ program running in the Board workspace.
|---|---|---|
| Shell>shell | a prompt in the project folder, with a box saying where the project's files, worktrees and Pi sessions are | — |
| Board>board | tasks by group · the chosen task · needs you | ↑↓ j k · enter · a · u · / · t (tools) · tab |
| Work>work | runs · change · facts · review · log · merge | [ ] tab · ↑↓ j k · enter (open a run) · o (choose task) · m (merge, asks first) · t (tools) |
| Work>work | runs · change · facts · review · log · merge | [ ] tab · n p (task) · o (pick task) · ↑↓ j k · enter (open a run) · m (merge, asks first) · t (tools) |
| Reply>reply | the task · the thread · the reply box | enter · s · esc |
| New task>new | the form · what a task needs · what will be sent | tab · enter · ctrl+n |
| Project>project | overview · facts · costs · settings | [ ] tab · ↑↓ j k |

Binary file not shown.

View File

@@ -23,6 +23,7 @@ it is a pointer and should be deleted or replaced.
| `docs/PLAN-INTERFACE.md` | this project | the plan: Paperclip object → screen, what exists, what is missing, and in what order |
| `docs/SESSIONS.md` | this project | the two kinds of session, where Pi's conversations are, and the plan for the junk TUIOS sessions |
| `docs/TEST-PLAN.md` | this project | the test plan: every step, every key, every expected result |
| `docs/RUNS-AND-MERGE.md` | this project | what a task, a run and a merge are, with the measured run counts |
## What is not a document of this project

76
docs/RUNS-AND-MERGE.md Normal file
View File

@@ -0,0 +1,76 @@
# A task, a run, and a merge — what each one is
Three different things, and the interface uses all three words.
## A task
One unit of work in Paperclip: a title, a description, an assignee, a status, a thread, a cost,
and its own copy of the code (a **worktree**) so two tasks cannot overwrite each other.
## A run
**One execution of one agent.** A task can have several. Paperclip records why each one
started — its *wake reason* — and they are different events:
| what woke it | when it happens |
|---|---|
| `assignment` | the task was given to an agent, or a person pressed assign |
| comment | somebody replied on the task |
| `automation` | Paperclip started a corrective run, for example because the previous run ended without setting a status |
| blockers resolved | the task was waiting on another task, and that task finished |
Measured in this sandbox:
```
AUD-167 1 run [assignment]
AUD-164 2 runs [automation, assignment]
AUD-166 2 runs [automation, assignment]
```
So when the runs tab shows one run, that is not the screen hiding anything: the agent finished
the task in a single run. `AUD-169`, `AUD-168`, `AUD-171` all did exactly that.
Each run has its own log — what the agent was told, what it thought, which tools it called. In
`Work>work`, pick a run on the **runs** tab and press `Enter`; the **log** tab opens.
## A merge
Merging is about **code**, not about the review.
An agent works in the task's own worktree on its own branch. When the task is done, that branch
holds commits that are *not* on the project's main line. A merge is the step that puts them
there:
```
AUD-171-another-status-file-status-2 ──merge──▶ main
```
`ocr` is not the merge. `ocr` is the reviewer that reads the change first. The order `bin/merge`
follows is:
1. **rebase** the task's branch onto the base branch, so the checks run on what would land;
2. **verify** — the task's own command, if it has one;
3. **review** — `ocr` reads the diff; a critical finding refuses the merge;
4. **merge** the branch into the base branch;
5. **re-verify** on the base branch, and roll back if it fails.
Merging does not happen on its own. `m` in `Work>work` asks first and shows the branch and the
base branch before anything runs.
## Working without the Board
`Work>work` is self-contained now:
| key | does |
|---|---|
| `n` / `p` | next / previous task in the project — the header shows `task 3 of 13` |
| `o` | pick a task from a list |
| `↑` / `↓` | choose a run in the runs tab |
| `Enter` | open that run's log |
| `[` / `]` | switch tabs: runs, change, facts, review, log, merge |
| `m` | merge this task — asks first |
| `t` | open a tool pane (Lazygit, Hunk, Yazi, Neovim, fzf, shell, ocr) |
Choosing a task here also writes the choice to the project's file, so `Reply>reply` and the rest
follow. `Board>board` is still the best place to see everything at once; it is no longer the
only way to move.

View File

@@ -32,6 +32,7 @@ type pickTasksMsg struct {
type workMsg struct {
task paperclip.Issue
tasks []paperclip.Issue
runs []paperclip.Run
activity []paperclip.Activity
cost paperclip.Cost
@@ -63,6 +64,7 @@ type workModel struct {
toolAt int
// choosing a task here, so the screen does not depend on the Board
taskList []paperclip.Issue
picking bool
pickList []paperclip.Issue
pickNames map[string]string
@@ -111,9 +113,18 @@ func (m workModel) load() tea.Cmd {
return errMsg{err}
}
runs, _ := c.Runs(id)
var list []paperclip.Issue
if all, err := c.Issues(); err == nil {
cfg, _ := readHarnessFile(folder)
for _, i := range all {
if i.ProjectID == cfg["paperclip.project"] {
list = append(list, i)
}
}
}
act, _ := c.Activity(id)
cost, _ := c.CostSummary(id)
msg := workMsg{task: task, runs: runs, activity: act, cost: cost}
msg := workMsg{task: task, runs: runs, activity: act, cost: cost, tasks: list}
if ws := task.Workspace; ws != nil && ws.CWD != "" {
msg.diff, msg.diffErr = worktreeDiff(ws.CWD, ws.BaseRef)
} else {
@@ -234,6 +245,35 @@ func (m workModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case "t":
m.tools = true
return m, nil
case "n", "p":
if len(m.taskList) == 0 {
return m, nil
}
at := -1
for i, t := range m.taskList {
if t.ID == m.task.ID {
at = i
}
}
if at < 0 {
at = 0
}
if msg.String() == "n" {
at = (at + 1) % len(m.taskList)
} else {
at = (at + len(m.taskList) - 1) % len(m.taskList)
}
chosen := m.taskList[at]
if err := rememberTask(m.folder, chosen.Identifier); err != nil {
m.err = err
return m, nil
}
m.explicit = true
m.issue = chosen.ID
m.task = chosen
m.tab = 0
m.runAt = 0
return m, m.load()
case "o":
c := m.client
folder := m.folder
@@ -334,6 +374,9 @@ func (m workModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case workMsg:
m.task = msg.task
if msg.tasks != nil {
m.taskList = msg.tasks
}
m.runs = msg.runs
m.activity = msg.activity
m.cost = msg.cost
@@ -374,7 +417,13 @@ func (m workModel) View() string {
head := titleStyle.Render("Work") + mutedStyle2().Render(" · ")
if m.task.Identifier != "" {
head += lipgloss.NewStyle().Foreground(lipgloss.Color(active.Text)).Render(m.task.Identifier)
head += mutedStyle2().Render(" " + truncateVisible(m.task.Title, max(10, m.width-50)))
head += mutedStyle2().Render(" " + truncateVisible(m.task.Title, max(10, m.width-60)))
for i, t := range m.taskList {
if t.ID == m.task.ID {
head += mutedStyle2().Render(fmt.Sprintf(" task %d of %d", i+1, len(m.taskList)))
break
}
}
}
state := "read " + m.readAt.Format("15:04:05")
if m.readAt.IsZero() {
@@ -403,8 +452,13 @@ func (m workModel) View() string {
if cmd := verifyFromDescription(m.task.Description); cmd != "" {
verify = "verify command: " + cmd
}
return helpOverlay("merge "+m.task.Identifier+"?", [][2]string{
{"what happens", "rebase onto the base branch"},
branch := "(no branch yet)"
if m.task.Workspace != nil && m.task.Workspace.Branch != "" {
branch = m.task.Workspace.Branch
}
return helpOverlay("merge "+m.task.Identifier+" into main?", [][2]string{
{"what is merged", branch + " → " + baseRefOf(m.task)},
{"what happens", "rebase the branch onto the base, then merge it"},
{"", verify},
{"", "ocr reviews the change; a critical finding refuses the merge"},
{"", "merge, then re-run the checks on the base branch"},
@@ -435,8 +489,12 @@ func (m workModel) View() string {
return helpOverlay("open a tool pane here", entries, m.width, m.height)
}
title := "the work"
if m.tab == 0 {
title = fmt.Sprintf("the work · %s", fmtCount(len(m.runs), "run", "runs"))
}
p := panel{
title: "the work", width: m.width, height: m.height - 2,
title: title, width: m.width, height: m.height - 2,
tabs: workTabs, active: m.tab, focused: true,
}
@@ -674,3 +732,11 @@ func (m workModel) factsLines(width int) []string {
row("cost", fmt.Sprintf("%d cent(s), %d run(s), %d tokens out", m.cost.CostCents, m.cost.RunCount, m.cost.OutputTokens))
return out
}
// baseRefOf is the branch a task's work will be merged into.
func baseRefOf(t paperclip.Issue) string {
if t.Workspace != nil && t.Workspace.BaseRef != "" {
return t.Workspace.BaseRef
}
return "main"
}