Skip to content

fix(#111): replace deprecated Homebrew cask postflight stanza - #112

Open
fullsend-ai-coder[bot] wants to merge 11 commits into
mainfrom
agent/111-fix-cask-postflight-steps
Open

fullsend-ai-coder[bot] wants to merge 11 commits into
mainfrom
agent/111-fix-cask-postflight-steps

Conversation

@fullsend-ai-coder

Copy link
Copy Markdown

Summary

  • Replace the deprecated Homebrew postflight cask stanza with the new postflight_steps stanza introduced in Homebrew 7.0.
  • Use GoReleaser's custom_block to emit postflight_steps directly, since native install_steps support is not yet released (planned for GoReleaser v2.19 via feat(cask): add hooks install_steps, deprecate raw Ruby hooks goreleaser/goreleaser#6873).
  • Update the cask test fixture to use the new Homebrew install-steps DSL (on_macos do, run, {{staged_path}}).

Motivation

brew install unbound-force/tap/replicator emits repeated deprecation warnings:

Warning: Calling `postflight` is deprecated! Use `postflight_steps` instead.

The postflight stanza will become an error after 2027-12-11, at which point the cask will fail to install entirely.

Changes

File Change
.goreleaser.yaml Replace hooks.post.install (which emits deprecated postflight) with custom_block containing postflight_steps using Homebrew's declarative DSL
.github/scripts/testdata/replicator-v0.5.0.rb Update fixture: postflight to postflight_steps, if OS.mac? to on_macos do, system_command to run, #{staged_path} to {{staged_path}}

Test plan

  • Cask integrity regression suite passes (patch-homebrew-cask_test.sh)
  • Go test suite passes (go test ./... -count=1 -race)
  • go vet ./... clean
  • go build succeeds
  • Verify next release publishes a cask with postflight_steps (no deprecation warning on brew install)

Closes #111

Post-script verification

  • Branch is not main/master (agent/111-fix-cask-postflight-steps)
  • Secret scan passed (gitleaks — 3e527a578cf3957d9b8f72a3edaed7b773b526bf..HEAD)
  • PR body secret scan passed (gitleaks — no-git)

@fullsend-ai-coder
fullsend-ai-coder Bot requested a review from a team as a code owner September 18, 2026 08:33
@fullsend-ai-coder fullsend-ai-coder Bot added the ready-for-review Triggers review agent dispatch label Sep 18, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:34 AM UTC · Completed 8:50 AM UTC

Commit: b308295 · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $4.19

@fullsend-ai-review fullsend-ai-review Bot added the risk/low PR risk: low label Sep 18, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

Risk Assessment: moderate (2/5)

Details

Re-review: Tier 1 signals unchanged from prior run (FILES 8, LINES 372, PROTECTED_PATH_COUNT 2, bot author); composite (2.0x0.50 + 1.56x0.30 + 1.75x0.20 = 1.82) rounds to 2 -- PROTECTED_PATH_COUNT=2 is the primary elevation factor, offset by bot authorship, zero security sensitivity, no dependency changes, clear issue alignment, and zero churn across all changed files.

Previous run

Risk Assessment: moderate (2/5)

Details

Re-review: Tier 1 signals unchanged from prior run (FILES 8, LINES 377, PROTECTED_PATH_COUNT 2, bot author, no Go source); composite (1.75x0.50 + 1.75x0.30 + 2.0x0.20 = 1.80) rounds to 2 — PROTECTED_PATH_COUNT=2 is the primary elevation factor, offset by bot authorship, zero security sensitivity, no dependency changes, tight issue alignment, and low git churn across all changed files.

Previous run (2)

Risk Assessment: moderate (2/5)

Details

Re-review: Tier 1 signals essentially unchanged from prior run (FILES 7-8, LINES 369-377); composite (2.25x0.50 + 2.0x0.30 + 1.83x0.20 = 2.13) rounds to 2 — PROTECTED_PATH_COUNT and zero Go-test ratio elevate while bot authorship, zero security sensitivity, tight issue alignment, and predominantly low-risk spec documentation keep it at moderate.

Previous run (3)

Risk Assessment: moderate (2/5)

Details

Re-review: Tier 1 signals have shifted from the prior run (FILES_CHANGED now 7 vs 3, LINES_CHANGED now 369 vs 22) because spec artifacts were added to the PR, but the weighted composite (Tier1=2.25x0.50 + Tier2=2.0x0.30 + Tier3=1.5x0.20 = 1.93) still rounds to 2 — the formally elevated PROTECTED_PATH_COUNT and zero test ratio are offset by bot authorship, zero security sensitivity, no CI workflow changes, tight issue alignment, and the fact that the majority of new lines are low-risk spec documentation rather than executable code.

Previous run (4)

Risk Assessment: moderate (2/5)

Details

Re-review: Tier 1 signals are identical to the prior run (PROTECTED_PATH_COUNT=2, TEST_FILE_RATIO=0.00, FILES_CHANGED=3); the independent weighted composite (Tier1=2.0×0.50 + Tier2=2.14×0.30 + Tier3=1.5×0.20 = 1.94) also rounds to 2, confirming the prior score — this is a well-scoped 22-line deprecation fix with formally elevated protected-path and zero-test-ratio signals offset by small blast radius, bot authorship, tight issue alignment, and no unresolved discussions.

Previous run (5)

Risk Assessment: moderate (2/5)

Details

Re-review: Tier 1 signals are identical to the prior run (PROTECTED_PATH_COUNT=2, TEST_FILE_RATIO=0.00, FILES_CHANGED=3); Tier 2 and Tier 3 provide no articulable reason to change the score, so the prior score of 2/moderate is preserved — the weighted composite (Tier1=2.0x0.50 + Tier2=1.71x0.30 + Tier3=1.5x0.20 = 1.813) rounds to 2, confirming a fundamentally low-risk deprecation fix with formally elevated protected-path and zero-test-ratio signals.

Previous run (6)

Risk Assessment: moderate (2/5)

Details

Re-review: Tier 1 signals are identical to the prior run (PROTECTED_PATH_COUNT=2, TEST_FILE_RATIO=0.00, FILES_CHANGED=3); Tier 2 and Tier 3 provide no articulable reason to change the score, so the prior score of 2/moderate is preserved — the weighted composite (Tier1=2.0x0.50 + Tier2=1.71x0.30 + Tier3=1.5x0.20 = 1.813) rounds to 2, confirming a fundamentally low-risk deprecation fix with formally elevated protected-path and zero-test-ratio signals.

Previous run (7)

Risk Assessment: moderate (2/5)

Details

Re-review: protected_path_count rose from 1 to 2 and file count grew from 2 to 3; the weighted composite (Tier1=2.0x0.50 + Tier2=2.3x0.30 + Tier3=1.3x0.20 = 1.95) rounds to 2/moderate, reflecting formally elevated PROTECTED_PATH_COUNT and 0.00 TEST_FILE_RATIO signals despite the fundamentally low-risk deprecation fix.

Previous run (8)

Risk Assessment: low (1/5)

Details

Small, targeted deprecation fix (2 files, 19 lines) replacing a deprecated Homebrew postflight stanza with its successor in goreleaser config and a test fixture; bot author, minimal blast radius, clear linked issue with well-covered acceptance criteria, and no security or CI pipeline concerns beyond the single protected goreleaser path.

@fullsend-ai-review

fullsend-ai-review Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

Review

Findings

Medium

  • [protected-path] .github/scripts/patch-homebrew-cask_test.sh, .github/scripts/testdata/replicator-v0.5.0.rb — Two files under the .github/ protected path are modified. The PR links to issue fix: replace deprecated Homebrew cask postflight stanza #111 and explains the rationale (Homebrew deprecation fix). Human approval is always required for protected-path changes, regardless of context.

Low

  • [naming] .github/scripts/patch-homebrew-cask_test.sh:163 — POSTFLIGHT_LINES holds the numeric count returned by grep -c, not a collection of lines. The _LINES suffix implies a list or multi-line string. A _COUNT suffix (e.g. POSTFLIGHT_COUNT) would better signal that the value is an integer used in arithmetic comparison.
Previous run

Review

Findings

Medium

  • [protected-path] .github/scripts/patch-homebrew-cask_test.sh, .github/scripts/testdata/replicator-v0.5.0.rb — Two files under the .github/ protected path are modified. The PR links to issue fix: replace deprecated Homebrew cask postflight stanza #111 and explains the rationale (Homebrew deprecation fix). Human approval is always required for protected-path changes, regardless of context.

Low

  • [code-organization] .github/scripts/patch-homebrew-cask_test.sh:176 — The rendered-cask section emits its own echo "PASS: Rendered-cask regression ..." before the file's final overall PASS line. Every other test case in the file is silent on success — only fail is called on failure, and the single trailing echo "PASS: Homebrew cask integrity regression suite" serves as the suite-level success indicator. The section-level PASS echo can be removed without changing test semantics.
    Remediation: Remove line 176 (echo "PASS: Rendered-cask regression (postflight_steps DSL validated from .goreleaser.yaml)") so the only PASS signal remains the existing final line, consistent with all other test sections in the file.

  • [dead code / logic clarity] .github/scripts/patch-homebrew-cask_test.sh:141 — The inner else { exit } branch in the awk extraction script is unreachable dead code. The outer if condition guarantees that when the body is entered, either (a) line_indent > key_indent is true (for non-blank lines) or (b) the line is blank. Both cases satisfy the inner if condition, so the inner else branch can never execute. The inner if/else could be replaced with just print.

  • [code-organization] .github/scripts/patch-homebrew-cask_test.sh:57 — The grep -q '#{staged_path}' assertion is technically redundant with the cmp -s fixture comparison above it: if the patched cask is byte-identical to the expected fixture, the grep will always pass. This was deliberately added per the spec's coverage strategy (task 3.2) as a self-documenting canary for the #{staged_path} invariant.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run (2)

Review

Findings

Medium

  • [protected-path] .github/scripts/patch-homebrew-cask_test.sh, .github/scripts/testdata/replicator-v0.5.0.rb — Two files under the .github/ protected path are modified. The PR links to issue fix: replace deprecated Homebrew cask postflight stanza #111 and explains the rationale (Homebrew deprecation fix). Human approval is always required for protected-path changes, regardless of context.

Low

  • [code-organization] .github/scripts/patch-homebrew-cask_test.sh:57 — The grep -q '#{staged_path}' assertion is technically redundant with the cmp -s fixture comparison above it: if the patched cask is byte-identical to the expected fixture, the grep will always pass. This was deliberately added per the spec's coverage strategy (task 3.2) as a self-documenting canary for the #{staged_path} invariant.
Previous run (3)

Review

Findings

Medium

  • [protected-path] .github/scripts/patch-homebrew-cask_test.sh, .github/scripts/testdata/replicator-v0.5.0.rb — Two files under the .github/ protected path are modified. The PR links to issue fix: replace deprecated Homebrew cask postflight stanza #111 and explains the rationale (Homebrew deprecation fix). Human approval is always required for protected-path changes, regardless of context.

  • [missing-changelog-entry] CHANGELOG.md:8 — The ## Unreleased section has no entry for the Homebrew cask postflight migration. This PR eliminates user-visible deprecation warnings on Homebrew 7.0+ and prevents a hard error after 2027-12-11. Per DR-003 [SHOULD], user-visible bug fixes should be recorded in the changelog.
    Remediation: Add a Fixed entry under ## Unreleased describing that the Homebrew cask now uses the postflight_steps DSL, eliminating Homebrew 7.0+ deprecation warnings. Reference issue fix: replace deprecated Homebrew cask postflight stanza #111.

Low

  • [test-integrity] .github/scripts/patch-homebrew-cask_test.sh:158 — The Perl-regex feature detection uses a content-dependent pattern ((?<!_steps)\s+do) that happens to match on_macos do in the current custom_block content. If the custom_block were restructured to remove on_macos do, the grep would exit non-zero and fall to the fallback branch even when grep -P is available. Both branches produce correct results, so this is not a functional bug, but the intent ("detect Perl regex support") is obscured by coupling to content.

Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run (4)

Review

Findings

Medium

  • [protected-path] .github/scripts/patch-homebrew-cask_test.sh, .github/scripts/testdata/replicator-v0.5.0.rb — Two files under the .github/ protected path are modified. The PR links to issue fix: replace deprecated Homebrew cask postflight stanza #111 and explains the rationale (Homebrew deprecation fix). Human approval is always required for protected-path changes, regardless of context.
Previous run (5)

Review

Findings

Medium

  • [protected-path] .github/scripts/patch-homebrew-cask_test.sh, .github/scripts/testdata/replicator-v0.5.0.rb — Two files under the .github/ protected path are modified. The PR links to issue fix: replace deprecated Homebrew cask postflight stanza #111 and explains the rationale (Homebrew deprecation fix). Human approval is always required for protected-path changes, regardless of context.

Low

  • [future-maintenance] .goreleaser.yaml:60 — custom_block bypasses GoReleaser's native DSL validation for cask stanzas. If GoReleaser later introduces a first-class postflight_steps key, the custom_block will need another migration. There is no current GoReleaser release with native postflight_steps support, so this is the correct approach now, but it should be noted as a maintenance touchpoint.
    Remediation: Add a comment above the custom_block stanza (e.g., # custom_block: native postflight_steps not yet supported by GoReleaser DSL; migrate when available).

  • [pattern-inconsistency] .github/scripts/patch-homebrew-cask_test.sh:58 — The fail message cask uses {{staged_path}} instead of Ruby interpolation #{staged_path} presupposes a specific failure cause (Go template substitution) that the grep does not verify. The grep only checks for presence of the correct form #{staged_path}; if absent, the actual cause could be complete removal rather than substitution.
    Remediation: Rephrase to describe absence rather than assuming substitution, e.g.: happy: patched cask is missing Ruby interpolation #{staged_path}.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run (6)

Review

Findings

Medium

  • [protected-path] .github/scripts/patch-homebrew-cask_test.sh, .github/scripts/testdata/replicator-v0.5.0.rb — Two files under the .github/ protected path are modified. The PR links to issue fix: replace deprecated Homebrew cask postflight stanza #111 and explains the rationale (Homebrew deprecation fix). Human approval is always required for protected-path changes, regardless of context.
Previous run (7)

Review

Findings

Medium

  • [protected-path] .github/scripts/patch-homebrew-cask_test.sh, .github/scripts/testdata/replicator-v0.5.0.rb — Two files under the .github/ protected path are modified. The PR links to issue fix: replace deprecated Homebrew cask postflight stanza #111 and explains the rationale (Homebrew deprecation fix). Human approval is always required for protected-path changes, regardless of context.

Low

  • [pattern-inconsistency] .goreleaser.yaml:63 — The run call in the goreleaser custom_block is split across two lines (lines 63–64), while the identical construct in the test fixture .github/scripts/testdata/replicator-v0.5.0.rb (line 35) keeps it on one line. Both Ruby forms are semantically identical, and the test is self-consistent (fixture serves as both input and expected output for the patcher). However, if GoReleaser injects the custom_block verbatim, the generated cask would have the multi-line form, making the fixture not fully representative of actual output.
Previous run (8)

Review

Findings

High

  • [runtime path interpolation] .goreleaser.yaml:64 — The GoReleaser template {{ "{{staged_path}}" }} produces the literal text {{staged_path}} in the generated cask file. However, {{}} is not Ruby string interpolation — Ruby uses #{}. The staged_path method provided by the Homebrew cask DSL will not be invoked, causing xattr to target a nonexistent path (literally {{staged_path}}/replicator), silently failing to remove macOS quarantine. This violates the acceptance criterion "macOS quarantine-removal behavior remains unchanged." The old config used #{staged_path}, which passes through Go template processing unmodified (since # is not a Go template delimiter) and is correctly interpreted as Ruby interpolation.
    Remediation: Replace {{ "{{staged_path}}" }} with #{staged_path} in .goreleaser.yaml. The #{} syntax is not a Go template directive, so it passes through GoReleaser literally and is correctly parsed as Ruby string interpolation. Apply the same fix to the testdata fixture.

  • [runtime path interpolation] .github/scripts/testdata/replicator-v0.5.0.rb:35 — The testdata fixture uses {{staged_path}} on line 35, but the same file uses #{version} on lines 8, 14, and 19 for Ruby string interpolation. This internal inconsistency confirms the syntax error: {{staged_path}} is a literal string in Ruby, not an interpolated reference to the staged_path method. The test passes but validates the wrong output shape.
    Remediation: Change {{staged_path}} to #{staged_path} on line 35 to match the Ruby interpolation syntax used elsewhere in the same file.

Medium

  • [test coverage gap] .github/scripts/patch-homebrew-cask_test.sh — The existing test suite validates SHA patching logic only. It does not verify the semantic correctness of the postflight stanza (syntax, path interpolation, or method names). The {{staged_path}} regression passed the test suite undetected because no test asserts that the generated cask uses valid Ruby interpolation syntax for runtime path references.
    Remediation: Add an assertion that verifies the fixture contains #{staged_path} rather than {{staged_path}}, to prevent interpolation syntax regressions.

  • [protected-path] .github/scripts/testdata/replicator-v0.5.0.rb — This file is under the .github/ protected path. The PR links to issue fix: replace deprecated Homebrew cask postflight stanza #111 and explains the rationale (Homebrew deprecation fix), but human approval is always required for protected-path changes regardless of context.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-coder

fullsend-ai-coder Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Author

🤖 Finished Fix · ✅ Success · Started 8:51 AM UTC · Completed 8:58 AM UTC

Commit: b308295 · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $1.05

fullsend-ai-coder Bot added a commit that referenced this pull request Sep 18, 2026
Replace {{staged_path}} with #{staged_path} in both the GoReleaser
custom_block and the testdata fixture. The {{}} syntax is not Ruby
string interpolation — Ruby uses #{} — so the previous change caused
xattr to target a nonexistent literal path, silently failing to
remove macOS quarantine.

Add a regression assertion to the cask test suite verifying that the
generated cask uses #{staged_path} (Ruby interpolation) rather than
{{staged_path}}.

Addresses #112
@fullsend-ai-coder

Copy link
Copy Markdown
Author

🔧 Fix agent — iteration 1 (bot-triggered)

Fixed Ruby interpolation syntax in both .goreleaser.yaml and testdata fixture: replaced {{staged_path}} with #{staged_path}. The {{}} syntax is not Ruby interpolation and caused xattr to target a literal nonexistent path. Added a regression test assertion to catch this class of error.

Fixed (3):

  1. runtime path interpolation in .goreleaser.yaml (.goreleaser.yaml): Replaced {{ "{{staged_path}}" }} with #{staged_path}. The {{}} syntax is not Ruby string interpolation — Ruby uses #{}. The #{ syntax is not a Go template directive, so GoReleaser passes it through literally into the generated cask file where Ruby correctly interprets it.
  2. runtime path interpolation in testdata fixture (.github/scripts/testdata/replicator-v0.5.0.rb): Changed {{staged_path}} to #{staged_path} on line 35 to match the Ruby interpolation syntax used elsewhere in the same file (e.g., #{version} on lines 8, 14, 19).
  3. test coverage gap for interpolation syntax (.github/scripts/patch-homebrew-cask_test.sh): Added a regression assertion to the happy-path test case that verifies the patched cask contains #{staged_path} (Ruby interpolation), preventing future regressions to {{staged_path}}.

Disagreed (1):

  1. protected-path notice for .github/scripts/testdata/replicator-v0.5.0.rb: This is an informational notice, not an actionable finding. The file is under .github/ (protected path) and requires human approval, which is handled by the post-script. The fix to the file's content is covered by finding 2.

Tests: passed

Decision points
  • Use #{staged_path} instead of attempting a Go template escape sequence (alternatives: Find a different Go template escape for Ruby interpolation, Use #{staged_path} which passes through Go templates unmodified; rationale: The # character is not a Go template delimiter, so #{staged_path} passes through GoReleaser literally and is correctly parsed as Ruby string interpolation in the generated cask file. This matches the original working behavior before the PR.)

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

@fullsend-ai-review

fullsend-ai-review Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:59 AM UTC · Completed 9:15 AM UTC

Commit: b20e48b · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $3.88

@fullsend-ai-review fullsend-ai-review Bot added risk/moderate PR risk: moderate and removed risk/low PR risk: low labels Sep 18, 2026
fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added the requires-manual-review Review requires human judgment label Sep 18, 2026
@em-redhat

Copy link
Copy Markdown
Contributor

/fs-fix the low finding, 1 iteration

@fullsend-ai-coder

fullsend-ai-coder Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Author

🤖 Finished Fix · ✅ Success · Started 10:46 AM UTC · Completed 10:52 AM UTC

Commit: b20e48b · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $0.87

@fullsend-ai-coder

Copy link
Copy Markdown
Author

🔧 Fix agent — iteration 2 (human-triggered)

Fixed pattern inconsistency by combining the split run call in .goreleaser.yaml onto a single line to match the test fixture format

Fixed (1):

  1. pattern-inconsistency: run call split across two lines in .goreleaser.yaml while fixture has it on one line (.goreleaser.yaml): Combined the split run call (lines 63-64) onto a single line to match the test fixture format. Since GoReleaser injects custom_block verbatim, the generated cask now matches the fixture exactly.

Disagreed (1):

  1. protected-path: .github/scripts/patch-homebrew-cask_test.sh and .github/scripts/testdata/replicator-v0.5.0.rb under .github/ protected path: Informational notice requiring human approval, not an actionable code fix. Human approval is handled by the post-script and PR review process.

Tests: passed

Decision points
  • Align goreleaser custom_block with fixture format rather than the reverse (alternatives: Change .goreleaser.yaml to single-line run call, Change fixture to multi-line run call; rationale: The fixture represents the expected generated output. Aligning the goreleaser template to match the fixture ensures the generated cask matches what the test expects, and the fixture is under a protected path.)

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

fullsend-ai-coder Bot added a commit that referenced this pull request Sep 18, 2026
Combine the split `run` call in .goreleaser.yaml onto a single line
to match the test fixture format in testdata/replicator-v0.5.0.rb.
Since GoReleaser injects custom_block verbatim, the generated cask
now matches the fixture exactly.

Addresses #112
@fullsend-ai-review

fullsend-ai-review Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 10:53 AM UTC · Completed 11:07 AM UTC

Commit: fcd92cc · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $3.69

@yvonnedevlinrh yvonnedevlinrh 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.

Requesting changes

CRITICAL: The non-trivial release configuration and test change has no preceding change-specific OpenSpec artifact. This violates the constitution’s Spec-First Development rule; the severity pack classifies constitutional violations as CRITICAL. Add and complete the required OpenSpec artifact with a coverage strategy before implementation.
HIGH: The regression test does not exercise GoReleaser output. .github/scripts/patch-homebrew-cask_test.sh:57-58 checks a hand-maintained fixture, so reverting .goreleaser.yaml:60-65 to legacy hooks.post.install would still pass. Add a deterministic rendered-cask test asserting postflight_steps do is present, postflight do is absent, and #{staged_path} survives rendering. This was suggested in issue #111 but not previously raised inline. Rules: TC-003, TC-006.

yvonnedevlinrh pushed a commit that referenced this pull request Sep 28, 2026
Replace {{staged_path}} with #{staged_path} in both the GoReleaser
custom_block and the testdata fixture. The {{}} syntax is not Ruby
string interpolation — Ruby uses #{} — so the previous change caused
xattr to target a nonexistent literal path, silently failing to
remove macOS quarantine.

Add a regression assertion to the cask test suite verifying that the
generated cask uses #{staged_path} (Ruby interpolation) rather than
{{staged_path}}.

Addresses #112
yvonnedevlinrh pushed a commit that referenced this pull request Sep 28, 2026
Combine the split `run` call in .goreleaser.yaml onto a single line
to match the test fixture format in testdata/replicator-v0.5.0.rb.
Since GoReleaser injects custom_block verbatim, the generated cask
now matches the fixture exactly.

Addresses #112
@yvonnedevlinrh
yvonnedevlinrh force-pushed the agent/111-fix-cask-postflight-steps branch from fcd92cc to 99a2f77 Compare September 28, 2026 16:18
@fullsend-ai-review

fullsend-ai-review Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 4:19 PM UTC · Completed 4:34 PM UTC

Commit: 99a2f77 · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $3.78

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot removed the requires-manual-review Review requires human judgment label Sep 28, 2026
@fullsend-ai-coder

fullsend-ai-coder Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Author

🤖 Finished Fix · ✅ Success · Started 4:35 PM UTC · Completed 4:42 PM UTC

Commit: 99a2f77 · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $1.02

@fullsend-ai-coder

Copy link
Copy Markdown
Author

🔧 Fix agent — iteration 3 (bot-triggered)

Addressed all three review findings: added GoReleaser DSL maintenance comment, rephrased test assertion message to be cause-neutral, and documented that protected-path human approval is a process step not a code fix.

Fixed (2):

  1. Add maintenance comment above custom_block noting GoReleaser DSL limitation (.goreleaser.yaml): Added comment above custom_block stanza documenting that native postflight_steps support is not yet available in GoReleaser DSL, with tracking reference to feat(cask): add hooks install_steps, deprecate raw Ruby hooks goreleaser/goreleaser#6873
  2. Rephrase fail message to describe absence rather than assuming substitution cause (.github/scripts/patch-homebrew-cask_test.sh): Changed fail message from presupposing a specific failure cause (Go template substitution) to describing the actual assertion: missing Ruby interpolation syntax

Disagreed (1):

  1. Protected-path files modified require human approval: The protected-path finding is informational and requires a human process step (approval), not a code change. The .github/ files were intentionally modified as part of the PR's core purpose (fixing Homebrew cask deprecation). Human approval must be obtained through the normal review process.

Tests: passed

Strategy change: Iteration 3 (at escalation threshold): prior iterations fixed actual bugs (template syntax HIGH) and pattern inconsistencies. Remaining findings are LOW-severity cleanup items. Strategy: address all remaining items comprehensively in one pass rather than incremental fixes.

Decision points
  • Protected-path files cannot be un-modified without defeating the PR's purpose (alternatives: Remove .github/ file changes from PR, Keep changes and require human approval; rationale: The .github/ changes are the core deliverable of this PR (fixing Homebrew cask deprecation). Removing them would make the PR pointless. Human approval is the correct resolution path.)

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot removed the requires-manual-review Review requires human judgment label Sep 29, 2026
@fullsend-ai-coder

fullsend-ai-coder Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Author

🤖 Finished Fix · ❌ Failure (running pre-script: exit status 1) · Started 1:01 PM UTC · Completed 1:01 PM UTC

Commit: 24ac360 · View workflow run →

Effort: high

@yvonnedevlinrh

Copy link
Copy Markdown
Contributor

/fs-fix

@fullsend-ai-coder

fullsend-ai-coder Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Author

🤖 Finished Fix · ✅ Success · Started 1:04 PM UTC · Completed 1:11 PM UTC

Commit: 24ac360 · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $1.52

fullsend-ai-coder Bot added a commit that referenced this pull request Sep 29, 2026
Remove unreachable else branch in awk custom_block extractor
(the outer condition guarantees the inner condition is always
true) and remove section-level PASS echo to match the file's
convention of silent-on-success with a single suite-level PASS.

Addresses #112
@fullsend-ai-coder

Copy link
Copy Markdown
Author

🔧 Fix agent — iteration 6 (human-triggered)

Addressed two LOW findings: removed unreachable dead code in awk extractor and removed inconsistent section-level PASS echo. Disagreed on two findings: protected-path is a process step, and the grep assertion is a deliberate spec coverage canary.

Fixed (2):

  1. dead code / logic clarity: unreachable else branch in awk custom_block extractor (.github/scripts/patch-homebrew-cask_test.sh): Simplified the awk block extraction logic by removing the unreachable inner if/else and consolidating to a single condition. The outer condition guaranteed the inner condition was always true, making the else { exit } branch dead code.
  2. code-organization: section-level PASS echo inconsistent with file convention (.github/scripts/patch-homebrew-cask_test.sh): Removed the rendered-cask section PASS echo at line 176. Every other test section in the file is silent on success; only the final suite-level PASS line serves as the success indicator.

Disagreed (2):

  1. protected-path: .github/scripts/ files modified require human approval: The .github/ files are the core deliverable of this PR (fixing Homebrew cask deprecation). Human approval is a process step handled through normal review, not a code change the fix agent can address.
  2. code-organization: grep assertion redundant with fixture comparison: The review itself acknowledges this was deliberately added per the spec's coverage strategy (task 3.2) as a self-documenting canary for the #{staged_path} invariant. Removing it would weaken the coverage strategy.

Tests: passed

Strategy change: Iteration 6 (above escalation threshold): all HIGH/MEDIUM code findings were resolved in iterations 1-5. Only LOW cleanup items remain. Strategy: address both actionable LOW items in a single minimal pass.

Decision points
  • Simplify awk condition vs. only remove inner if/else (alternatives: Remove only the inner if/else, keeping the verbose outer condition, Simplify the outer condition using boolean algebra: (A && !B) || B = A || B; rationale: Applied boolean simplification to produce the clearest, most maintainable code. The simplified form (line_indent > key_indent || blank) directly expresses the extraction rule: continue capturing if the line is indented deeper than the key or is blank.)

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

@fullsend-ai-review

fullsend-ai-review Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 1:13 PM UTC · Completed 1:27 PM UTC

Commit: 1a26588 · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $3.76

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

See the review comment for full details.

fi
else
# Fallback: check that 'postflight do' only appears as 'postflight_steps do'
POSTFLIGHT_LINES=$(echo "$CUSTOM_BLOCK" | grep 'postflight.*do' | grep -cv 'postflight_steps' || true)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[low] naming

POSTFLIGHT_LINES holds the numeric count returned by grep -c, not a collection of lines. The _LINES suffix implies a list or multi-line string. A _COUNT suffix (e.g. POSTFLIGHT_COUNT) would better signal that the value is an integer used in arithmetic comparison.

@fullsend-ai-review fullsend-ai-review Bot added the requires-manual-review Review requires human judgment label Sep 29, 2026
yvonnedevlinrh pushed a commit that referenced this pull request Oct 1, 2026
Replace {{staged_path}} with #{staged_path} in both the GoReleaser
custom_block and the testdata fixture. The {{}} syntax is not Ruby
string interpolation — Ruby uses #{} — so the previous change caused
xattr to target a nonexistent literal path, silently failing to
remove macOS quarantine.

Add a regression assertion to the cask test suite verifying that the
generated cask uses #{staged_path} (Ruby interpolation) rather than
{{staged_path}}.

Addresses #112
yvonnedevlinrh pushed a commit that referenced this pull request Oct 1, 2026
Combine the split `run` call in .goreleaser.yaml onto a single line
to match the test fixture format in testdata/replicator-v0.5.0.rb.
Since GoReleaser injects custom_block verbatim, the generated cask
now matches the fixture exactly.

Addresses #112
yvonnedevlinrh pushed a commit that referenced this pull request Oct 1, 2026
- Add maintenance comment above custom_block in .goreleaser.yaml
  noting that native postflight_steps support is not yet available
  in GoReleaser DSL (tracking goreleaser/goreleaser#6873)
- Rephrase test assertion message in patch-homebrew-cask_test.sh
  to describe absence rather than presupposing substitution cause

Addresses #112
@yvonnedevlinrh
yvonnedevlinrh force-pushed the agent/111-fix-cask-postflight-steps branch from 1a26588 to fe55e3a Compare October 1, 2026 13:57
yvonnedevlinrh pushed a commit that referenced this pull request Oct 1, 2026
…112

Add tactical OpenSpec change (fix-cask-postflight-steps) documenting the
Homebrew postflight migration: proposal, design, tasks, and coverage
strategy. Add a deterministic rendered-cask regression test that extracts
the custom_block from .goreleaser.yaml and verifies postflight_steps is
present, legacy postflight is absent, and #{staged_path} remains valid
Ruby interpolation. The test requires no network access or goreleaser
binary.

Addresses #112
yvonnedevlinrh pushed a commit that referenced this pull request Oct 1, 2026
- Add Fixed entry under ## Unreleased in CHANGELOG.md for the Homebrew
  cask postflight_steps migration (DR-003). References #111.
- Replace content-dependent Perl regex detection with a content-
  independent probe (`echo "probe" | grep -qP 'probe'`) so the
  grep -P availability check does not depend on the custom_block
  content shape.

Addresses #112
yvonnedevlinrh pushed a commit that referenced this pull request Oct 1, 2026
Remove unreachable else branch in awk custom_block extractor
(the outer condition guarantees the inner condition is always
true) and remove section-level PASS echo to match the file's
convention of silent-on-success with a single suite-level PASS.

Addresses #112
Homebrew 7.0 deprecated the `postflight` block in favour of the
declarative `postflight_steps` stanza. GoReleaser's
`hooks.post.install` emits the deprecated form and does not yet
support `postflight_steps` natively (planned for v2.19 via
goreleaser/goreleaser#6873).

Use GoReleaser's `custom_block` to inject the correct
`postflight_steps` stanza directly, replacing `hooks.post.install`.
The new stanza uses Homebrew's install-steps DSL: `on_macos do`
replaces `if OS.mac?`, `run` replaces `system_command`, and
`{{staged_path}}` replaces Ruby interpolation `#{staged_path}`.

Updated the test fixture to match the new stanza syntax. All cask
integrity regression tests pass.

Closes #111
Replace {{staged_path}} with #{staged_path} in both the GoReleaser
custom_block and the testdata fixture. The {{}} syntax is not Ruby
string interpolation — Ruby uses #{} — so the previous change caused
xattr to target a nonexistent literal path, silently failing to
remove macOS quarantine.

Add a regression assertion to the cask test suite verifying that the
generated cask uses #{staged_path} (Ruby interpolation) rather than
{{staged_path}}.

Addresses #112
Combine the split `run` call in .goreleaser.yaml onto a single line
to match the test fixture format in testdata/replicator-v0.5.0.rb.
Since GoReleaser injects custom_block verbatim, the generated cask
now matches the fixture exactly.

Addresses #112
- Add maintenance comment above custom_block in .goreleaser.yaml
  noting that native postflight_steps support is not yet available
  in GoReleaser DSL (tracking goreleaser/goreleaser#6873)
- Rephrase test assertion message in patch-homebrew-cask_test.sh
  to describe absence rather than presupposing substitution cause

Addresses #112
…112

Add tactical OpenSpec change (fix-cask-postflight-steps) documenting the
Homebrew postflight migration: proposal, design, tasks, and coverage
strategy. Add a deterministic rendered-cask regression test that extracts
the custom_block from .goreleaser.yaml and verifies postflight_steps is
present, legacy postflight is absent, and #{staged_path} remains valid
Ruby interpolation. The test requires no network access or goreleaser
binary.

Addresses #112
- Add Fixed entry under ## Unreleased in CHANGELOG.md for the Homebrew
  cask postflight_steps migration (DR-003). References #111.
- Replace content-dependent Perl regex detection with a content-
  independent probe (`echo "probe" | grep -qP 'probe'`) so the
  grep -P availability check does not depend on the custom_block
  content shape.

Addresses #112
Remove unreachable else branch in awk custom_block extractor
(the outer condition guarantees the inner condition is always
true) and remove section-level PASS echo to match the file's
convention of silent-on-success with a single suite-level PASS.

Addresses #112
@yvonnedevlinrh
yvonnedevlinrh force-pushed the agent/111-fix-cask-postflight-steps branch from fe55e3a to d585147 Compare October 2, 2026 10:14
The goreleaser-action with args: --version and install-only: false
extracts the binary to a temp directory that does not persist on
PATH. Subsequent steps fail with 'command not found'.

Switch to install-only: true so the binary remains available for
the snapshot render step. Update the regression assertion and spec
artifacts to match.
Set persist-credentials: false on actions/checkout to prevent
credential leakage through artifacts (artipacked).

Disable Go module caching on actions/setup-go to eliminate the
cache-poisoning vector flagged by zizmor when goreleaser-action
is present in the same job.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-human Agent loop needs human intervention ready-for-review Triggers review agent dispatch requires-manual-review Review requires human judgment risk/moderate PR risk: moderate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: replace deprecated Homebrew cask postflight stanza

3 participants