Skip to content

feat(corrections): share the local findings buffer across a clone's worktrees - #12911

Merged
kyle-sexton merged 4 commits into
mainfrom
feat/findings-buffer-shared-across-worktrees
Nov 3, 2026
Merged

kyle-sexton merged 4 commits into
mainfrom
feat/findings-buffer-shared-across-worktrees

Conversation

@kyle-sexton

Copy link
Copy Markdown
Member

Closes #12907

Summary

The local-file findings buffer keyed its file on git rev-parse --show-toplevel, which differs per worktree, so a row noted in one worktree (including the applied-change rows /session-flow:retro judges) was invisible to a retro in any other worktree of the same clone. The buffer now lives in one file per clone, shared by every worktree, and still never leaves the machine.

Fix

  • Location: <git common dir>/findings-buffer/findings.jsonl, resolved with git rev-parse --path-format=absolute --git-common-dir in append.sh and read.sh. Basis: git-rev-parse says --git-common-dir shows "$GIT_COMMON_DIR if defined, else $GIT_DIR", the directory linked worktrees share, and --path-format=absolute makes the printed path "absolute and canonical". Git tracks nothing under its own directory, so rows never reach a commit. That is why the .work/buffer/.gitignore write and its symlink guard are gone; the conformance test still asserts git status --porcelain --untracked-files=all --ignored stays empty after an append.
  • Guards: append.sh refuses a symlinked findings-buffer, .lock, .lockdir or findings.jsonl, and refuses a buffer that resolves outside the git common directory. Both sides of that check come from pwd -P, as before. read.sh refuses the same symlinks at the new location and at the legacy one. The flock, perl and mkdir locks now sit in the shared directory, so they serialize appends from every worktree.
  • Legacy read: read.sh also returns rows from the current worktree's .work/buffer/findings.jsonl when that file exists, and applies --since to them too. buffer.sh read already drops a repeat obs_id.
  • Docs and release: CONTRACT.md (Privacy, Adapters) and the corrections README state the new location and that it is shared by a clone's worktrees and stays on the machine. A .changes/corrections fragment carries bump: minor.

Verification

  • bash plugins/corrections/tools/findings-buffer/conformance.test.sh: 38/38 ok. New cases:
    • a row appended in a linked worktree is read from the main worktree, and the reverse
    • 12 concurrent appends across two worktrees each store their row once
    • legacy rows are read, and --since filters them
    • a symlinked legacy file is refused
  • The same suite run against the origin/main adapter scripts fails the new worktree and legacy cases (32, 33, 35), so they test the change.
  • bash plugins/corrections/tools/findings-buffer/buffer.test.sh: 53/53 ok, including a linked-worktree read through buffer.sh and a legacy row with a repeat obs_id that reads once. bash plugins/corrections/scripts/group-findings.test.sh: 29/29 ok (it writes the legacy path). shellcheck on the five changed scripts: clean.

Related

🤖 Generated with Claude Code

https://claude.ai/code/session_01MWmASLCzgJayUQq9Saq4AK

kyle-sexton and others added 2 commits November 3, 2026 13:54
…orktrees

The local-file adapter now stores rows in findings-buffer/findings.jsonl
under the git common directory, which every worktree of a clone shares,
so a row noted in one worktree is visible to a retro in any other. The
symlink and realpath guards and the append lock move with it. read.sh
also returns rows from the old per-worktree .work/buffer/findings.jsonl.

Closes #12907

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MWmASLCzgJayUQq9Saq4AK
@kyle-sexton
kyle-sexton marked this pull request as ready for review November 3, 2026 18:57
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-03T19:01:04.817888Z d98bf13 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review reviewed d3cc7fba968efdd3befc99b55c41ed38da69bc49: read 1 of 1 changed file(s); 0 finding(s), 0 as inline comments.

Security review (incremental, 910bc03 → d3cc7fb): PR #12911

I read every hunk of the one file in scope, plugins/corrections/tools/findings-buffer/conformance.test.sh. It matches none of the trusted-path globs. This push changes no plugin manifest, workflow, trust control, merge hold or standing instruction.

No security issues found.

What I checked:

  • The change is test-only and stays inside the test's temp directory. The conformance case no longer points the symlinked .work at the bare $TEST_TMPDIR. It now points it at $TEST_TMPDIR/linked-work, which holds a buffer/findings.jsonl with a marker row. The case then checks that read.sh leaves that row out. Every path the case writes or links is under $TEST_TMPDIR. The existing rm -rf "${LINKED:?}/.work" guard is unchanged.
  • No production code changed. read.sh is unchanged since the last review, so the symlink refusals I checked then still apply.
  • The test is now stronger. A regression in which read.sh reads the legacy file through a symlinked .work now fails this case. Before this push, the case would still have passed.

This push applies the fix from the settled thread on conformance.test.sh lines 439-449. I'm not raising that thread again.

critical-findings: 0

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

claude-review: 1 inline finding(s) on d98bf13e3a131a4576f3ce17a738a516f0d0721b; the summary is in this lane's pull request comment.

claude-lane: claude-review

@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

claude-review reviewed d3cc7fba968efdd3befc99b55c41ed38da69bc49: read 1 of 1 changed file(s); 0 finding(s), 0 as inline comments.

Code review (incremental, 910bc03 → d3cc7fb)

No new findings in this push. It changes one file, conformance.test.sh, and I read every hunk of it. I also read adapters/local-file/read.sh in full at head, along with the shared-worktree section of the test around the change.

Last round's finding is fixed. That finding said the symlinked-.work case would still pass if read.sh stopped skipping a symlinked .work. The case now writes a via-linked-work row into $TEST_TMPDIR/linked-work/buffer/findings.jsonl, points $LINKED/.work at that directory, and checks that the row is missing from the output.

  • The fixed case now does its job. Suppose "$TOP/.work" were dropped from the skip loop at read.sh:51. Then -f "$TOP/.work/buffer/findings.jsonl" would follow the link and add the row, and the case would fail.
  • The new directory clashes with no fixture. The other fixtures in this section are shared-main and shared-linked, so linked-work is a fresh path.
  • I didn't run the suite. The owner's reply says the case prints not ok with the skip removed and ok with it restored. That is the author's claim, and I haven't checked it.

Closing issue #12907: this push changes only one test case, so the earlier judgment on the "Done when" items still holds. I can't check "CI green" from here.

Other checks:

  • No plugin manifest changed in this push.
  • Both settled threads are fixes of this lane's own earlier findings, so I haven't raised either again.
  • I found no embedded instructions in the PR context, the settled threads or the prior findings.
  • This review is round 3, and the cap is 3. The prior-findings file says past the cap: no, so the cap doesn't apply.

…he read

A symlinked .work made read.sh exit 2 before it read the shared buffer,
while append.sh, which no longer touches .work, kept succeeding: rows
went in and could not be read back. The legacy path now skips only the
legacy file with a note on stderr; the shared buffer keeps its hard
symlink refusal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MWmASLCzgJayUQq9Saq4AK

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

claude-review: 1 inline finding(s) on 910bc03b78b79800d04f25121ef665bc92fdf503; the summary is in this lane's pull request comment.

claude-lane: claude-review

The symlinked-.work case pointed at an empty directory, so it passed
with the skip removed. Put a row behind the link and assert it is left
out; the case now fails when "$TOP/.work" leaves the skip list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MWmASLCzgJayUQq9Saq4AK
@kyle-sexton
kyle-sexton added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit 8854459 Nov 3, 2026
59 of 60 checks passed
@kyle-sexton
kyle-sexton deleted the feat/findings-buffer-shared-across-worktrees branch November 3, 2026 19:49
@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Post-merge mutation testing

Killed 3, survived 2, timeout 0, no coverage 0, invalid 0, not run 2.
Covered-code score 60%; mutation score 60%.

File Killed Survived Timeout No coverage Invalid Not run
plugins/corrections/tools/findings-buffer/adapters/local-file/append.sh 3 1 0 0 0 0
plugins/corrections/tools/findings-buffer/adapters/local-file/read.sh 0 0 0 0 0 2
plugins/corrections/tools/findings-buffer/buffer.sh 0 1 0 0 0 0

Surviving mutants

Location Operator Disposition Cause
plugins/corrections/tools/findings-buffer/adapters/local-file/append.sh:18 LCR unclassified none
plugins/corrections/tools/findings-buffer/buffer.sh:88 SBR productive no-assertion

The run's summary has the full report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(corrections): share the local findings buffer across a clone's worktrees

1 participant