diff --git a/.pi/memory-vault/packs/paperclip-harness/20-context/paperclip-harness.md b/.pi/memory-vault/packs/paperclip-harness/20-context/paperclip-harness.md index 590486b..3abbd7b 100644 --- a/.pi/memory-vault/packs/paperclip-harness/20-context/paperclip-harness.md +++ b/.pi/memory-vault/packs/paperclip-harness/20-context/paperclip-harness.md @@ -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 ` 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 ` and `bin/review `. + +## 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 + +- 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]] diff --git a/.pi/memory-vault/packs/paperclip-harness/20-context/tmp.md b/.pi/memory-vault/packs/paperclip-harness/20-context/tmp.md index 64e78cc..04b0194 100644 --- a/.pi/memory-vault/packs/paperclip-harness/20-context/tmp.md +++ b/.pi/memory-vault/packs/paperclip-harness/20-context/tmp.md @@ -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 + +- 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]] 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 d46fb42..c9295b1 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 @@ -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 + +- 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]] 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 8368b07..08dcc44 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 @@ -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 ` is the gate. Caveat: `bin/review ` runs the review alone. + +## Evidence + +- Confidence: 90% +- Reason: Architectural/convention decision with context, rationale, and consequences. + +## Related learned memories + +- 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]] 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 c892753..fa1693a 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 @@ -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 + +- 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]] diff --git a/.pi/memory-vault/packs/paperclip-harness/80-sessions/rich-discovery-tmp-2026-11-11-01-58-59.md b/.pi/memory-vault/packs/paperclip-harness/80-sessions/rich-discovery-tmp-2026-11-11-01-58-59.md new file mode 100644 index 0000000..0241939 --- /dev/null +++ b/.pi/memory-vault/packs/paperclip-harness/80-sessions/rich-discovery-tmp-2026-11-11-01-58-59.md @@ -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 + +- 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]] diff --git a/README.md b/README.md index 3223d8e..ae8027f 100644 --- a/README.md +++ b/README.md @@ -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 | diff --git a/bin/harness b/bin/harness index 2190ab0..713e617 100755 Binary files a/bin/harness and b/bin/harness differ diff --git a/docs/DOCMAP.md b/docs/DOCMAP.md index 2e64710..65ef02b 100644 --- a/docs/DOCMAP.md +++ b/docs/DOCMAP.md @@ -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 diff --git a/docs/RUNS-AND-MERGE.md b/docs/RUNS-AND-MERGE.md new file mode 100644 index 0000000..0d7282e --- /dev/null +++ b/docs/RUNS-AND-MERGE.md @@ -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. diff --git a/tui/work.go b/tui/work.go index 00e4d36..c3d2d9b 100644 --- a/tui/work.go +++ b/tui/work.go @@ -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" +}