Skip to content

fix: herdr target source, changelog-owner check; test: clean-room tolerant reader; chore: dependabot labels - #532

Merged
cameronsjo merged 9 commits into
mainfrom
claude/cadence-open-issues-9z9lqo
Sep 26, 2026
Merged

cameronsjo merged 9 commits into
mainfrom
claude/cadence-open-issues-9z9lqo

Conversation

@cameronsjo

@cameronsjo cameronsjo commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Summary

Tests

  • TestChangelogOwnershipGuardIgnoresMainsOwnReleaseEdit: a release on main under a GitHub-style merge commit passes with both base SHAs.
  • New TestChangelogOwnershipGuardCatchesAnEditBehindAMergeFromMain is the negative control: a PR that edits CHANGELOG.md and then merges main in is rejected on both the CI path and the fallback path. It fails against the previous three-dot script. Test helpers now set HEAD_SHA explicitly, so a developer's shell can't change which path runs.
  • The existing TestChangelogOwnershipGuard cases still pass, including the invalid-base, hand-edit and Release Please ones.
  • TestRecipeAfkBadTargetNamesItsSource, TestResolveRecipeHerdrTarget, and TestPrepareLocal_RefusesCleanRoomFromRecordStrictDecoderRejects, which I mutation-checked.
  • gofmt, go vet ./..., go test ./... and golangci-lint v2.13.1 (0 issues) all pass.
  • The cadence code-reviewer and security-reviewer both returned CLEAN on the earlier head. Their two changelog-check findings are fixed in 8cd4cba.

Release notes

None.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Wfuj7jLb8eNvEHdxurJgt9

Summary by CodeRabbit

  • Bug Fixes
    • Local preparation now blocks workspaces recorded outside the temporary directory, including records created by newer versions.
    • Changelog ownership checks correctly account for release edits on the main branch and changes made in pull requests that merge from it.
  • Developer Experience
    • Errors for invalid recipe targets now identify whether the value came from a command-line option or an environment variable.
    • Changelog validation reports an error when its base commit cannot be found.

activate() switched menuMode on the raw list index. With a filter
applied, "1" or enter on the only visible row ran whatever sat first in
the unfiltered menu (Pick). It now switches on SelectedItem(), the same
filter-aware pattern hubMode and leavesMode use since #490.

Closes #496

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

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Essentials

Run ID: 71876c44-609f-402e-9d03-b0d5d26256ac

📥 Commits

Reviewing files that changed from the base of the PR and between fa73978 and cfc6b45.

📒 Files selected for processing (8)
  • .github/workflows/ci.yml
  • changelog_ownership_test.go
  • internal/cli/recipe.go
  • internal/cli/recipe_test.go
  • internal/pr/local.go
  • internal/pr/local_test.go
  • internal/pr/repair.go
  • scripts/check-changelog-owner.sh

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour. Your free on-demand review promotion remains active until October 9, 2026 at 6:00 PM UTC.


📝 Walkthrough

Walkthrough

The pull request updates filtered TUI menu activation, recipe target-source reporting, breadcrumb workspace checks, and changelog ownership comparisons. Tests cover the menu selection, target resolution, workspace refusal, and changelog comparison changes.

Changes

TUI menu activation

Layer / File(s) Summary
Selected-item dispatch and regression test
internal/tui/tui.go, internal/tui/tui_test.go
menuMode dispatches using the selected menuItem label. A regression test verifies that pressing 1 or Enter opens Cheatsheet when filtering leaves it as the only visible row.

Recipe target source reporting

Layer / File(s) Summary
Target resolution and error reporting
internal/cli/recipe.go, internal/cli/recipe_test.go
Target resolution returns the source of the selected value. Target-validation errors identify --target or the environment variable that supplied the value. Tests cover source selection, fallback order, and an invalid environment target that runs no commands.

Breadcrumb workspace guard

Layer / File(s) Summary
Tolerant workspace lookup and regression test
internal/pr/local.go, internal/pr/repair.go, internal/pr/local_test.go
Comments explain why the workspace lookup avoids strict breadcrumb decoding. A test confirms that PrepareLocal refuses a workspace recorded in a newer-version breadcrumb, even when the strict decoder rejects the record.

Changelog ownership guard

Layer / File(s) Summary
PR-head comparison and merge regression test
.github/workflows/ci.yml, scripts/check-changelog-owner.sh, changelog_ownership_test.go
CI passes the PR head SHA to the ownership check. The script compares the base with the selected PR head using a three-dot diff. A regression test covers merge history with a later main release edit.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Low

Merge Risk: ⚪ Minimal · up to cfc6b

The supplied evidence identifies no issue that needs resolution before merge.

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR contains changes unrelated to #496 and #464. The changelog ownership workflow and script changes, their tests, and the breadcrumb handling changes in internal/pr/local.go, `internal/pr/local_… Remove the changelog ownership and breadcrumb changes from this PR, or move them to separate pull requests. Keep only changes that implement #496, #464, and their supporting tests.
Docstring Coverage ⚠️ Warning Docstring coverage is 53.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 15 functions across 9 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ⚠️ Warning The title names several real changes, including the Herdr target source and changelog-owner check. However, it omits the primary filtered-menu fix, includes an unsubstantiated Dependabot-label change,… Rewrite the title to focus on the primary changes, for example: "fix(tui, recipe): honor filtered menu rows and identify invalid Herdr target sources"
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR meets the coding requirements for #496 and #464. In internal/tui/tui.go, menuMode now dispatches from the filter-aware selected menuItem label. The TUI regression test covers number-key a…
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Full details: Out of Scope Changes check

Explanation

The PR contains changes unrelated to #496 and #464. The changelog ownership workflow and script changes, their tests, and the breadcrumb handling changes in internal/pr/local.go, internal/pr/local_test.go, and internal/pr/repair.go do not implement filtered TUI activation or herdr target validation and source reporting.

Full details: Docstring Coverage

Explanation

Docstring coverage is 53.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 15 functions across 9 files. (1 skipped: 1 unsupported.)

Full details: Title check

Explanation

The title names several real changes, including the Herdr target source and changelog-owner check. However, it omits the primary filtered-menu fix, includes an unsubstantiated Dependabot-label change, and is too long for a concise summary.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

A rabbit taps the filtered row,
And watches Cheatsheet open below.
A target source is named with care,
While newer breadcrumbs guard the lair.
The changelog checks the PR’s own track,
Then bounds along the garden path.

Comment @coderabbitai help to get the list of available commands.

The #475 allowlist rejects a malformed target, but the error named only
the value. A bad HERDR_PANE_ID left the operator no path back to the
variable. resolveRecipeHerdrTarget now returns where the target came
from (--target, HERDR_PANE_ID, HERDR_ACTIVE_PANE_ID) and the error names it.

Closes #464

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wfuj7jLb8eNvEHdxurJgt9
@cameronsjo cameronsjo changed the title fix(tui): tmux menu acts on the selected row, not its filtered position fix(tui, recipe): filtered menu acts on the shown row; bad herdr target names its source Sep 25, 2026
The check diffed BASE_SHA against the PR merge commit, which also holds
every main commit since the branch point, so a release cut landing on
main failed every open PR. It now diffs BASE_SHA...<PR head>, taking the
head from HEAD_SHA or the merge commit's second parent.

Closes #458

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

recordedWorkspaceFor reads breadcrumbs without the strict decoder, so a
newer forgectl's record still refuses its clean room. Nothing tested
that: routing the reader through decodeBreadcrumbRecord allowed the
path with the suite green. The new test seeds a record the strict
decoder rejects, outside $TMPDIR, and goes red under that mutation.
Both tolerant readers now point at each other.

Closes #504

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wfuj7jLb8eNvEHdxurJgt9
@cameronsjo cameronsjo changed the title fix(tui, recipe): filtered menu acts on the shown row; bad herdr target names its source fix: filtered tmux menu, herdr target source, changelog-owner race; test: clean-room tolerant reader Sep 25, 2026
Dependabot's default dependencies and github_actions labels are folded
into kind:chore by the estate label rollout, so every Dependabot PR
recreated them. The updates entry now sets kind:chore directly.

refs cameronsjo/cadence-ecosystem#553

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wfuj7jLb8eNvEHdxurJgt9
The new-findings lint gate flagged the fixture's 0o755 workspace and the
os.ReadFile of the breadcrumb it just wrote. Use 0o750 and note why the
read is safe.

refs #504

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

Copy link
Copy Markdown
Owner Author

This PR now conflicts with main. #531 merged first, and both PRs change the filtered tmux menu in internal/tui/tui.go, so merge main in and keep one version of that fix.

One follow-up from #531: the secret masking in internal/exec/mask.go merged without a dedicated security review. It is worth an Opus-level review pass before the next release.

# Conflicts:
#	internal/tui/tui.go
#	internal/tui/tui_test.go
…hangelog check

Review follow-up on #458. The three-dot diff trusted a merge base: a
criss-cross history could pick one that hid a CHANGELOG edit, and with
HEAD_SHA unset the HEAD^2 guess named main, not the PR, so an edit
behind a merge-from-main passed. The check now diffs HEAD^1..HEAD only
when HEAD is GitHub's merge commit whose second parent is HEAD_SHA, and
otherwise falls back to BASE_SHA..HEAD, which can over-block but never
passes a PR's own edit. A non-commit base still fails closed. Tests pin
HEAD_SHA explicitly and add the merge-from-main negative control.

refs #458

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wfuj7jLb8eNvEHdxurJgt9
@cameronsjo cameronsjo changed the title fix: filtered tmux menu, herdr target source, changelog-owner race; test: clean-room tolerant reader fix: herdr target source, changelog-owner check; test: clean-room tolerant reader; chore: dependabot labels Sep 26, 2026

Copy link
Copy Markdown
Owner Author

build-test red on 8cd4cba in code this PR doesn't touch. internal/sops's TestIntegration_RoundTripAndDiffShape reported 2 lines changed, want 3 … [llm_key_hermes mac]. The same test passed on main at 6c82c8c and on this PR's previous head 6eb39a1.

Cause: sops writes lastmodified with one-second resolution. If sopsFixture encrypts the file and SetValue edits it within the same second, lastmodified doesn't change, so only the value and mac differ. The test hard-codes 3 changed lines, so it fails whenever both steps land in the same second. That depends on runner speed, not on this PR.

Proposed patch (not applied here, to keep the PR on its issues): assert which lines changed rather than how many.

// internal/sops/driver_test.go, replacing the `changed != 3` check
changed := changedKeys(beforeLines, afterLines)
must := map[string]bool{"llm_key_hermes": true, "mac": true}
may := map[string]bool{"lastmodified": true} // second resolution: unchanged when both steps share a second
for _, k := range changed {
	if !must[k] && !may[k] {
		t.Errorf("unexpected changed line %q: %v", k, changed)
	}
	delete(must, k)
}
for k := range must {
	t.Errorf("expected %q to change: %v", k, changed)
}

I'm re-running the failed job once. No fix for this exists on main yet.


Generated by Claude Code

sops stores lastmodified at one-second resolution, so when the fixture's
encryption and SetValue land in the same second only the value and mac
change. The test counted a fixed 3 changed lines and failed on fast
runners. It now requires the value and mac lines to change, allows
lastmodified, and rejects any other changed line.

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

Copy link
Copy Markdown
Owner Author

Update: the re-run was refused (403 Resource not accessible by integration), so I applied the patch above instead. The commit is on this branch: the diff-shape test now requires the value and mac lines to change, allows lastmodified, and rejects any other changed line. It compiles, and go vet and golangci-lint are clean. The sops integration leg only runs in CI, where the sops binary is available.


Generated by Claude Code

@cameronsjo
cameronsjo merged commit b32c062 into main Sep 26, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants