Skip to content

fix: converge Homebrew status and privacy feedback - #209

Merged
seonghobae merged 9 commits into
fix/brew-cleanup-nonzero-status-v1from
fix/brew-cleanup-ui-convergence-v1
Aug 24, 2026
Merged

fix: converge Homebrew status and privacy feedback#209
seonghobae merged 9 commits into
fix/brew-cleanup-nonzero-status-v1from
fix/brew-cleanup-ui-convergence-v1

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Purpose

Preserve #189's correct success/failure status semantics while adding bounded privacy-safe planning/execution failure feedback on one dependency-ordered BrewCleanup.svelte owner, without changing Homebrew command, model, human approval, audit, or filesystem authority.

Exact current state

  • Exact stack base: PR fix: distinguish failed Homebrew cleanup status #189 branch fix/brew-cleanup-nonzero-status-v1, unchanged head 19a60a0518668492a9b53e9d92b922f157d7ad12.
  • Exact source head: 3ab6d3793140672c7c90319714eb381757a53f1c.
  • Fresh base-to-head comparison is ahead_by = 2, behind_by = 0, with merge base exactly the stack base.
  • The PR is open, Ready for review, and GitHub reports it mergeable.
  • Current semantic delta is exactly:
    • src/lib/BrewCleanup.svelte;
    • src/lib/brewCleanupErrorPrivacyContract.test.ts.
  • Current-head formal reviews and review threads are empty; no approval is claimed.

Test-first repair

  • RED commit 12e0e04d404843b6a2fe9408f624e27b5255e2db required the component to stop projecting arbitrary caught exception text while preserving the existing judgment/execution authority calls.
  • Narrow implementation 3ab6d3793140672c7c90319714eb381757a53f1c replaces only the two String(e) projections with:
    • planning failure: Homebrew 정리 계획을 만들지 못했습니다.;
    • execution failure: Homebrew 정리를 실행하지 못했습니다..
  • fix: distinguish failed Homebrew cleanup status #189's 실행 성공 / 실행 실패 / 실행되지 않음 status semantics remain intact.
  • Existing role="alert", judgment/execution calls, plan and judgment identifiers, confirmation phrase, rationale, single-use state transitions, stdout/stderr display, audit-result handling, and filesystem authority remain unchanged.

Exact-head validation

On unchanged head 3ab6d3793140672c7c90319714eb381757a53f1c:

  • Test 31664202305 — success, including Rust tests, real process/domain suites, frontend tests, frontend build, and the real CPU LLM-engine build;
  • Release 31664202308 — success for Windows, Ubuntu, and macOS build/package artifact jobs.

The PR targets a feature branch rather than protected main, so default-branch-only organization required workflows and approval rules do not apply to this stack edge. Security Scan and SAST Semgrep did not produce PR runs for this feature-branch target; their absence is not passing evidence. Release publish-release and attest-release were skipped and are not provenance evidence.

Dependency and integration constraints

  • fix: distinguish failed Homebrew cleanup status #189 must remain the exact stack base until this edge is deliberately folded into it or both are reconstructed onto current protected main.
  • Closing the competing main-based privacy-feedback line is only safe after exact semantic convergence proves every valuable unique delta is preserved.
  • Merging this stack edge is not protected-main integration and does not waive repository-wide coverage, security, review, release, or provenance requirements for the eventual main-targeting owner.
  • Repository-wide exact 100% owned-production region/statement-equivalent, branch, function, and line coverage remains materially unsatisfied on canonical owner ci: require exact-head production coverage evidence #156.

Required before any integration

Do not merge to protected main unless the final unchanged exact head satisfies every applicable live required workflow and current finding, every review thread is resolved, a qualifying independent approval covers the last push/current head, fresh protected-main ancestry remains current, repository-wide exact coverage is satisfied without exclusions or threshold weakening, and package/SBOM/provenance evidence is complete. Pending, queued, absent-required, skipped-required, neutral-required, failed, stale, predecessor, synthetic, diagnostic-only, status-only, model-only, rate-limited, no-source scanner, or infrastructure-only evidence is not passing.


Open in Devin Review

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 92ed76d3-1aec-4e41-8474-91f6a0382469

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@seonghobae
seonghobae marked this pull request as ready for review August 15, 2026 08:04

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Rate Limit Exceeded

@seonghobae have exceeded the limit for the number of chat messages per hour. Please wait 19 minutes and 56 seconds before sending another message.

@seonghobae
seonghobae marked this pull request as draft August 15, 2026 12:16

Copy link
Copy Markdown
Contributor Author

Current-head privacy finding on 3ab6d3793140672c7c90319714eb381757a53f1c: src/lib/BrewCleanup.svelte still interpolates execution.record_error directly into the visible audit-record failure alert (...저장하지 못했습니다: {execution.record_error}). That backend field can carry path/implementation detail, so the PR is not yet a complete bounded-feedback convergence. Keep this line Draft. Next source owner should add a realistic RED contract for a path-bearing record_error, replace the projection with a fixed actionable message, then reacquire exact-head checks/review. This invocation is not changing the file because open #211 also targets BrewCleanup.svelte; preserve the single-writer boundary and converge deliberately rather than racing.

@seonghobae
seonghobae marked this pull request as ready for review August 15, 2026 13:20
@opencode-agent

opencode-agent Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

OpenCode Review Overview

  • Head SHA: 3ab6d3793140672c7c90319714eb381757a53f1c
  • Workflow run: 32241837362
  • Workflow attempt: 1
  • Gate result: REQUEST_CHANGES (approval step)

Pull request overview

OpenCode reviewed the current-head bounded evidence and requested changes before merge.

Findings

1. P1 src/lib/brewCleanupErrorPrivacyContract.test.ts:30 - Privacy-contract test does not guard execution.record_error template interpolation

  • Problem: The test's only negative privacy assertion is not.toContain('String(e)'). The template section of BrewCleanup.svelte still interpolates execution.record_error into a visible role=alert element — the same class of privacy leak the PR aims to fix — on a separate rendering path not covered by any test assertion.
  • Root cause: The diff modifies only script-block catch handlers; the template section is unchanged and unchecked. The test structure is sound but incomplete for the full set of user-visible error rendering paths.
  • Fix: (a) Replace execution.record_error interpolation in the template with a static bounded message. (b) Add expect(source).not.toMatch(/{execution.record_error}/) to the existing test case.
  • Regression test: npx vitest run src/lib/brewCleanupErrorPrivacyContract.test.ts
  • Suggested diff: posted in this finding's inline review thread.

Summary

P1 src/lib/brewCleanupErrorPrivacyContract.test.ts:30 — Privacy-contract test gap: the test asserts String(e) absence and static Korean messages but does not check that the template section avoids unsanitized execution.record_error interpolation into a {role="alert"} element. The prior review thread at this exact line (same SHA) is unresolved and independently verified: the PR author's own comment (2026-08-15) confirms the interpolation exists, the diff has no template changes, and sibling component IcloudLocalEviction.svelte:179 shows the identical pattern. Approval sufficiency: BLOCKED by unresolved thread. Verification posture: source-trace only (file reads restricted by directory policy). Linter/static: no active failed checks. TDD/regression: test passes for catch-block paths but misses template path. Coverage: coverage execution evidence shows supported tests passed. Docstring coverage: not applicable (Svelte/TS, no docstring gates). DAG: flowchart above shows base-to-head error rendering flow. PoC/execution: not applicable (static contract test, no runtime PoC needed). DDD/domain: Homebrew cleanup privacy boundary. CDD/context: sibling IcloudLocalEviction shows identical record_error pattern. Similar issues: IcloudLocalEviction.svelte still uses String(e) in catch blocks (out of scope). Claim/concept check: PR title 'converge privacy feedback' overclaims completeness. Standards search: N/A. Compatibility/convention: no breaking changes. Breaking-change/backcompat: none. Implementation completeness: catch-block implementation complete; template path incomplete. Performance: no impact. Developer experience: test file structure is good, needs one more assertion. User experience: unsanitized backend error can leak to user via role=alert. Visual/DOM: non-web desktop UI (Tauri); alert rendering confirmed by role=alert assertion in test. Accessibility/i18n: role=alert present. Supply-chain/license: no dependency changes. Packaging: no manifest changes. Security/privacy: P1 unsanitized backend field in template.

Adversarial validation

{"status":"failed","probes":[{"path":"src/lib/brewCleanupErrorPrivacyContract.test.ts","line":30,"hypothesis":"The test's negative privacy assertions would detect unsanitized execution.record_error interpolation in the BrewCleanup.svelte template","attack_or_counterexample":"The test file's 30 lines contain no assertion referencing record_error, execution.record_error, or template interpolation patterns — only String(e) absence and static string presence checks","evidence":"Trusted source trace at src/lib/brewCleanupErrorPrivacyContract.test.ts:30 — file ends at line 30 with no assertion about execution.record_error; PR author comment (2026-08-15T12:16:31Z) at same SHA confirms the interpolation exists; source-line-sha256=29576b54e255e3c948eea5b5904fa38b81682fdd3cbd9ae841ff0e7bd80d394c","outcome":"confirmed"},{"path":"src/lib/BrewCleanup.svelte","line":76,"hypothesis":"The catch-block fix at line 76 constitutes complete privacy-safe error feedback for all user-visible error rendering paths","attack_or_counterexample":"The diff changes only two catch blocks (lines 29 and 76); the template section with execution.record_error interpolation (confirmed by PR author and sibling IcloudLocalEviction.svelte:179 pattern) is untouched","evidence":"Trusted source trace at src/lib/BrewCleanup.svelte:76 shows the static error message fix; diff stat confirms 32 insertions / 2 deletions with no template changes; source-line-sha256=55c0b9d00542b7a9ee3590d70797c354df90e7c27b9a91d8e9ecadcd644d6cb3","outcome":"confirmed"}],"residual_risk":"The catch-block privacy fix is correct. The remaining gap (unsanitized execution.record_error in the template) is bounded and has an identified fix direction. No other security, correctness, or compatibility regressions detected."}
  • Result: REQUEST_CHANGES

  • Reason: Unresolved prior-review thread at brewCleanupErrorPrivacyContract.test.ts:30 is valid: the privacy-contract test does not guard the execution.record_error template interpolation path, leaving the PR's bounded-feedback convergence claim incomplete for a user-visible alert.

  • Head SHA: 3ab6d3793140672c7c90319714eb381757a53f1c

  • Workflow run: 32241837362

  • Workflow attempt: 1

Changed-File Evidence Map

flowchart LR
  PR["PR changed files"] --> Evidence["OpenCode bounded evidence"]
  Evidence --> S1["Changed file (2 files)"]
  S1 --> I1["repository behavior"]
  I1 --> R1["Review risk: Changed file (2 files)"]
  R1 --> V1["required checks"]
Loading

opencode-agent[bot]

This comment was marked as resolved.

opencode-agent[bot]

This comment was marked as resolved.

@devin-ai-integration devin-ai-integration 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.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 1 additional finding.

Open in Devin Review

@seonghobae

Copy link
Copy Markdown
Contributor Author

@OpenCode review current head aa3039d

@seonghobae
seonghobae dismissed stale reviews from opencode-agent[bot] and opencode-agent[bot] August 20, 2026 16:11

Superseded by current head 2a6ed44. The record-error interpolation findings are addressed, and the current regression additionally rejects raw iCloud eviction catch errors.

@seonghobae
seonghobae force-pushed the fix/brew-cleanup-nonzero-status-v1 branch from 19a60a0 to f748769 Compare August 20, 2026 17:44
@seonghobae
seonghobae force-pushed the fix/brew-cleanup-ui-convergence-v1 branch from 2a6ed44 to 0fc67a4 Compare August 20, 2026 17:44
@seonghobae

Copy link
Copy Markdown
Contributor Author

@OpenCode review current head 0fc67a4

1 similar comment
@seonghobae

Copy link
Copy Markdown
Contributor Author

@OpenCode review current head 0fc67a4

@seonghobae

Copy link
Copy Markdown
Contributor Author

@OpenCode review current head 0fc67a4

@seonghobae

Copy link
Copy Markdown
Contributor Author

@OpenCode review current head 0fc67a4. Re-run exact-head review; predecessor approvals/checks do not transfer.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@OpenCode review current head 0fc67a4. The privacy contract now guards both Brew cleanup error paths and audit-record output; re-evaluate this exact head rather than predecessor 3ab6d37.

@seonghobae

Copy link
Copy Markdown
Contributor Author

Current head 0fc67a4 is clean and exact-head hosted checks are green (Rust/TS/build/security); the prior privacy findings are addressed in both BrewCleanup and IcloudLocalEviction with static audit-record alerts and explicit contract assertions. @OpenCode review current head 0fc67a4 and publish fresh approval only from exact-head evidence.

@seonghobae
seonghobae enabled auto-merge (squash) August 21, 2026 05:01
@seonghobae

Copy link
Copy Markdown
Contributor Author

@OpenCode review current head 0fc67a4. Previous reviews/checks do not transfer; publish exact-head approval only after current evidence.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@OpenCode review current head 0fc67a4. Previous reviews/checks are stale; publish exact-head approval only after current base integration and privacy evidence.

@seonghobae

Copy link
Copy Markdown
Contributor Author

@OpenCode review current head 0fc67a4c0161b9949700f4ce8274f765cfb9918a. Re-evaluate only this exact head; prior privacy findings were addressed and all hosted checks are green. Publish approval only if the current evidence supports it.

@opencode-agent opencode-agent Bot added priority: medium Normal-priority or P2 work status: mergeable GitHub reports a mechanically clean merge state; policy gates may remain type: bug Defect or incorrect behavior labels Aug 22, 2026
@seonghobae

Copy link
Copy Markdown
Contributor Author

@OpenCode review current exact head 0fc67a4c0161b9949700f4ce8274f765cfb9918a. All hosted checks are green and no unresolved threads remain; predecessor reviews are stale/dismissed. Please publish exact-head approval only after evaluating the Homebrew status/privacy convergence change.

…nzero-status-v1' into HEAD

# Conflicts:
#	src/lib/IcloudLocalEviction.svelte
@seonghobae
seonghobae merged commit 2a98451 into fix/brew-cleanup-nonzero-status-v1 Aug 24, 2026
6 of 8 checks passed
@seonghobae
seonghobae deleted the fix/brew-cleanup-ui-convergence-v1 branch August 24, 2026 04:40

@devin-ai-integration devin-ai-integration 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.

Devin Review found 4 new potential issues.

Open in Devin Review

Comment on lines 196 to +197
{:else}
<p class="warning" role="status">현재 축출 불가: {blockerSummary(plan.blockers)}</p>
<p class="warning">현재 축출 불가: {plan.blockers.join(", ")}</p>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 Changes break existing eviction UI contract test

The rewritten status and error text drops blockerSummary, role="status", and several fixed strings (also at IcloudLocalEviction.svelte:38, :50, :86) that the unmodified src/lib/icloudLocalEvictionSafetyUiContract.test.ts still asserts at lines 16-18 and 26-29. Every one of those seven assertions now fails, breaking the test suite.

Prompt for agents
The changes to src/lib/IcloudLocalEviction.svelte contradict the existing, unmodified test src/lib/icloudLocalEvictionSafetyUiContract.test.ts. That test asserts the presence of strings and code that this PR removed or changed: "로컬 최신본·업로드 미확인" and the "로컬 최신본이지만 공급자 업로드가 아직 확인되지 않았습니다..." sentence (from the deleted syncLabel/blockerLabel helpers), the role="status" attribute (removed from the blocker <p> at line 197), the error strings "iCloud 파일 선택을 완료하지 못했습니다. 다시 시도하십시오.", "iCloud 로컬 사본 상태를 확인하지 못했습니다. 다시 시도하십시오.", "iCloud 로컬 사본을 회수하지 못했습니다. 상태를 다시 확인하십시오.", and the presence of function blockerSummary. Reconcile the two: either update icloudLocalEvictionSafetyUiContract.test.ts to match the new privacy-safe UI, or restore the required behavior in the component. The PR description claims IcloudLocalEviction.svelte is out of scope, so confirm whether these component edits were intended at all.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

</div>
{:else}
<p class="warning" role="status">현재 축출 불가: {blockerSummary(plan.blockers)}</p>
<p class="warning">현재 축출 불가: {plan.blockers.join(", ")}</p>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Blocker codes now shown raw to users

The deleted blockerSummary translated internal blocker codes into human-readable, deduplicated guidance. Now plan.blockers.join(", ") surfaces raw codes like icloud-upload-not-confirmed to users, a UX downgrade, though it matches the existing verification_blockers.join at IcloudLocalEviction.svelte:155.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@@ -26,7 +26,7 @@
try {
judgment = await api.judgeBrewCleanup();
} catch (e) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Unused catch binding kept inconsistently in BrewCleanup

In BrewCleanup.svelte and :75 the catch clauses still bind the exception (catch (e)) even though e is no longer referenced, whereas the equivalent edits in src/lib/IcloudLocalEviction.svelte:37,49,85 switched to the optional-catch-binding form (catch {). This is only a style inconsistency (and potentially a lint warning depending on the project's eslint config), not a runtime bug.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

const evictionSource = readSource("src/lib/IcloudLocalEviction.svelte");

expect(source).not.toContain("String(e)");
expect(source).not.toContain("record_error");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: Contract test asserts absence of substrings not just interpolations

The new test at brewCleanupErrorPrivacyContract.test.ts asserts the BrewCleanup source not.toContain("record_error"). This is a broad substring check: the source still contains record_path (BrewCleanup.svelte), which does not match record_error, so the test passes today. However, any future use of a field like record_error_count would fail this test even if privacy-safe. Not a bug, but worth noting the assertion is stricter/looser than an exact interpolation match.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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

Labels

priority: medium Normal-priority or P2 work status: mergeable GitHub reports a mechanically clean merge state; policy gates may remain type: bug Defect or incorrect behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant