Skip to content

test(desktop): isolate the Suggested tasks feedback owner authority - #12650

Merged
kodjima33 merged 2 commits into
BasedHardware:mainfrom
aryanorastar:fix/12039-suggested-tasks-owner-isolation
Sep 3, 2026
Merged

test(desktop): isolate the Suggested tasks feedback owner authority#12650
kodjima33 merged 2 commits into
BasedHardware:mainfrom
aryanorastar:fix/12039-suggested-tasks-owner-isolation

Conversation

@aryanorastar

@aryanorastar aryanorastar commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

What

SuggestedTasksStoreTests is one of the flaky suites tracked in #12039. This isolates its feedback owner authority, which is what made it order-dependent.

The defect

SuggestedTasksStore resolves two owner authorities. The tests injected one and left the other global:

let store = SuggestedTasksStore(client: api, suppressionStore: MemorySuppressionStore())
//                                            ^ injected      ^ feedbackOutboxStore defaults to
//                                                              SuggestedFeedbackOutboxDefaults

SuggestedFeedbackOutboxDefaults.currentOwnerID() is process-global:

fixedOwnerID ?? defaults.string(forKey: .authUserId) ?? "signed-out"

dismiss re-checks owner currency after awaiting the backend reject:

_ = try await client.rejectCanonicalCandidate(...)      // suspension point
...
guard ownersAreCurrent(suppressionOwnerID:feedbackOwnerID:) else {
  refreshOwnerScopedState()
  return                                                // feedback never recorded
}

Any other suite in the binary that writes auth_userId while that await is suspended flips the feedback owner, dismiss returns early, and api.feedback stays empty — which is exactly the CI failure on an unrelated backend PR:

("nil") is not equal to ("Optional(…TaskIntelligenceFeedbackReason.not_mine)")

34 other test files touch auth_userId, so the failure tracks suite order rather than anything in this suite.

The fix

27 of the 37 store constructions in this file were half-isolated. The other 10 already injected a MemoryFeedbackOutboxStore, because they assert on outbox contents — so the seam existed and was simply not used consistently. All 37 now pin both owners to the suite.

This is the same repair #12192 and #12259 made for the Rewind and FloatingBar owner authorities.

Guard

testDismissSurvivesAGlobalAuthOwnerFlipAtTheAwaitedRejectPoint pins the contract. It drives the owner flip through the existing onReject hook — the precise suspension point — so the hazard is reproduced deterministically instead of by suite order.

Verification

  • 40/40 in this suite.
  • 99/99 running it alongside the owner and auth suites that write auth_userId in one process (AuthRefreshResilienceTests, RuntimeOwnerIdentityTests, AuthSessionAttemptFenceTests, EffectiveOwnerDatabaseBoundaryTests, TasksStoreOwnerBoundaryTests, FloatingOwnerProjectionTests, RewindStorageTestIsolation).
  • Mutation-checked, not assumed. Removing the feedbackOutboxStore injection from the new test reproduces CI's failure byte for byte:
XCTAssertEqual failed: ("nil") is not equal to
("Optional(Omi_Computer.OmiAPI.TaskIntelligenceFeedbackReason.not_mine)")

Restoring the injection returns green.

Scope

One leg of #12039. KernelTurnRecordedProjectionTests remains open. The chat-gesture, Rewind-owner and FloatingBar-owner legs landed in #12406, #12192 and #12259.

Tests only — no production code changes.

Failure-Class: none

Review in cubic

`SuggestedTasksStoreTests.testNotMineAndAlreadyHandledPersistReasonAndResolveCandidate`
is one of the flakes tracked in BasedHardware#12039. It failed in CI on an unrelated backend PR with:

    ("nil") is not equal to ("Optional(…TaskIntelligenceFeedbackReason.not_mine)")

The store resolves two owner authorities. `suppressionStore` was injected, but
`feedbackOutboxStore` was left on the default `SuggestedFeedbackOutboxDefaults`, whose
owner is process-global:

    fixedOwnerID ?? defaults.string(forKey: .authUserId) ?? "signed-out"

`dismiss` re-checks owner currency *after* awaiting the backend reject. Any other suite
in the same binary that writes `auth_userId` while that await is suspended flips the
owner, so `dismiss` returns early without recording feedback — the assertion above sees
an empty `api.feedback`. 34 other test files touch that key, which is why the failure
tracks suite order rather than anything in this suite.

27 of the 37 store constructions in this file were half-isolated this way; the other 10
already injected a `MemoryFeedbackOutboxStore` because they assert on outbox contents.
All 37 now pin both owners to the suite, which is the same repair BasedHardware#12192 and BasedHardware#12259 made
for the Rewind and FloatingBar owner authorities.

`testDismissSurvivesAGlobalAuthOwnerFlipAtTheAwaitedRejectPoint` pins the contract. It
drives the flip through the existing `onReject` hook — the exact suspension point — so
the hazard is deterministic rather than order-dependent.

Verification: 40/40 in this suite; 99/99 with the owner and auth suites that write
`auth_userId` in one process. Mutation-checked: dropping the `feedbackOutboxStore`
injection from the new test reproduces CI's failure byte for byte,
`("nil") is not equal to ("Optional(Omi_Computer.OmiAPI.TaskIntelligenceFeedbackReason.not_mine)")`,
and restoring it returns green.

This is one leg of BasedHardware#12039. `KernelTurnRecordedProjectionTests` remains open; the chat
gesture, Rewind owner, and FloatingBar owner legs landed in BasedHardware#12406, BasedHardware#12192 and BasedHardware#12259.

Failure-Class: none
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@cubic-dev-ai cubic-dev-ai 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.

No issues found across 1 file

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

@Git-on-my-level

Copy link
Copy Markdown
Collaborator

Thanks @aryanorastar — verified end to end; this is a clean piece of test-infrastructure repair.

Production seam (verified in SuggestedTasksStore.swift): SuggestedFeedbackOutboxDefaults.currentOwnerID() resolves fixedOwnerID ?? defaults.string(forKey: .authUserId) ?? "signed-out" from process-global UserDefaults.standard, and dismiss(...) awaits client.rejectCanonicalCandidate(...) before the ownersAreCurrent(suppressionOwnerID:feedbackOwnerID:) re-check — so a global auth_userId write landing at that suspension point makes the store early-return and the feedback never lands. The mechanism in the PR description matches the code exactly.

The change (SuggestedTasksStoreTests.swift): all 37 SuggestedTasksStore(...) constructions now inject feedbackOutboxStore: MemoryFeedbackOutboxStore() (previously only the outbox-asserting tests did), pinning the feedback owner to the suite instead of the global key — mechanical, consistent, no production behavior touched. testDismissSurvivesAGlobalAuthOwnerFlipAtTheAwaitedRejectPoint turns the suite-order hazard into a deterministic in-test reproduction: api.onReject flips .authUserId at exactly the awaited moment, and the defer restores the prior value. Good guard. This mirrors the Rewind/FloatingBar owner-authority isolations from #12192 and #12259.

On the red required checks: they are not from this change. The only failing suite out of 749 was HubEscalationTests.testPublicWebPromptIsSpeakableAndExcludesPrivateToolContext (HubEscalationTests.swift:87); that test file and the prompt builders it exercises are identical between main and this PR's base and are untouched here. The same lane failed on an unrelated branch this morning with a different suite (ProactiveListenEventTests) — the #12039 flake family. SuggestedTasksStoreTests itself passed in this run. A re-run should clear it.

Leaving for human maintainer review only for the merge call: someone needs to sign off on merging while a required check is red from an unrelated flake.


by AI on behalf of David — if you need David’s attention urgently, please @Git-on-my-level and escalate with need human response.

@kodjima33 kodjima33 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Desktop bug-fix fast lane (3/5): test-only change isolates the SuggestedTasksStore feedback-owner authority, fixing order-dependent flakiness in the #12039 flaky-suite family (mirrors the #12192/#12259 repair pattern). Root cause reproduced/mutation-checked in PR body. CI green, no abuse signals.

@kodjima33
kodjima33 merged commit 797be9c into BasedHardware:main Sep 3, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macOS positive-signal Good PR — positive signal, not a formal approval

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants