Skip to content

Carry main fixes into redesign (#746) - #669

Merged
thomasluizon merged 3 commits into
redesign/mainfrom
fix/ticket-746-carry-push-transfer
Sep 30, 2026
Merged

thomasluizon merged 3 commits into
redesign/mainfrom
fix/ticket-746-carry-push-transfer

Conversation

@thomasluizon

Copy link
Copy Markdown
Owner

Carry the three requested main commits into redesign/main, in order, with git cherry-pick -x. The API drops the deprecated One Tap route, the reviewer workflow receives main's model configuration, and device push registrations can transfer or be explicitly released with proof of device ownership. The redesign's authorization page, pending-operation previews, revision/refresh flow, and Astra write approval policy remain in place.

Refs thomasluizon/orbit-tickets#746

Carried commits and resolutions

  • e596ee18c1b76562d1fbc5eb66e55e3f9daa3f44 (Delete the deprecated POST /oauth/google route (#957) #664), carried as 59c896df: removed POST /oauth/google, its request/helper and unused dependencies from OAuthController.cs; removed its error code and capability entry; regenerated src/Orbit.Api/openapi.json through the build. The only conflicted path was src/Orbit.Application/Common/ErrorMessages.cs, against the localized error catalog introduced by redesign Redesign the transactional emails, AI push copy and error messages (R20) #532 (23396af4) and extended by prior carries. Kept the complete redesign catalog and its From/FromCounted helpers, deleting only GoogleTokenAudienceMismatch. Removed the matching orphaned entry in ErrorCopy.cs. Updated OAuthLoginPageTests.cs for the controller constructor. In OAuthControllerTests.cs, retained the redesign page assertions and redirect/callback coverage, carried the route-absence assertion, and removed 13 tests plus helpers for the deleted One Tap action. Those tests had already disappeared on main before this pick; retaining them would reference deleted types and dependencies.
  • c95d5488cb2e38ee4fdad7e380146cdc0ca77ffe (chore: run the Pullfrog reviewer on the Codex harness with gpt-6.1-sol #668), carried as f085c8a2: .github/workflows/pullfrog.yml applied unchanged, with no conflicts. The final upstream workflow uses the default opencode harness with openai/gpt-6.1-sol and the anthropic/claude-opus-5-5 fallback.
  • ce78ccb4bf6fbc57f225fe3b94426d5fb354f2fc (Transfer or release a device's push subscription when it changes accounts (#932) #667), carried as c99ea7a7: applied with no conflicts. Carried the subscribe/unsubscribe handlers and validator, push entity guards, repository deletion operation, controller and MCP/chat forwarding, and all upstream tests. Automatic merges retain the redesign's GET /api/notifications/subscriptions and delete_selected notification action alongside the new device-release arguments. The build regenerated OpenAPI after the final pick and produced no additional diff.

No commits were skipped. Each commit retains its source SHA trailer. No migrations or model snapshot changes are needed, and there is no migration ordering question.

External interface evidence

  • The pinned Pullfrog action declares the optional model input and accepts curated slugs or raw model specifiers: action.yml at the pinned release. Confirmed from the actual response to gh api 'repos/pullfrog/pullfrog/contents/action.yml?ref=99c5e781dd54463197d1109998386d37c84f6853', then decoded its base64 content. No action response fields are read by the carried workflow.
  • EF Core 10.0.12's installed Microsoft.EntityFrameworkCore.xml, member EntityFrameworkQueryableExtensions.ExecuteDeleteAsync, confirms immediate deletion without updating tracked entities and a deleted-row count return. PushSubscriptionAccountSwitchTests also execute the real repository over SQLite, including an ownership transfer interleaved between the read and delete.

Test evidence

All final build and test commands completed with exit code 0.

Command Result
env -u LANG dotnet build Orbit.slnx 0 errors
env -u LANG dotnet test 8,308 passed, 0 failed, 0 skipped
env LC_ALL=en_US.UTF-8 dotnet build Orbit.slnx 0 errors
env LC_ALL=en_US.UTF-8 dotnet test 8,308 passed, 0 failed, 0 skipped
From src/Orbit.Api: env -u LANG dotnet ef migrations has-pending-model-changes --project ../Orbit.Infrastructure --startup-project . --no-build No changes since the last migration; exit 0

Focused OAuth check: env -u LANG dotnet test tests/Orbit.Infrastructure.Tests --filter 'FullyQualifiedName~OAuthControllerTests|FullyQualifiedName~OAuthLoginPageTests', 87 passed, exit 0.

node tools/arch-map.mjs completed after route changes. The build's OpenAPI generator ran after both API picks; git diff --exit-code -- src/Orbit.Api/openapi.json is clean. Changed-file dash checks, dash baseline, timeless text against origin/redesign/main, suppression allowlist, and git diff --check passed. Added C# comments are XML documentation.

The intermediate build exposed the orphaned localized error entry and the redesign-only page test's old constructor. Both were adapted within the OAuth carry; the final focused and full runs pass. Upstream push regression tests are carried unchanged. No new regression test was authored here, so a local unchanged/strengthened pre-fix test pair was not run and no such result is claimed.

Assumptions

  • The final "This sync" instruction selects exactly the three specified SHAs; the older carry lists and other main commits are outside this PR.
  • The OAuth removal requires deleting its orphaned localized error entry, updating the redesign-only controller fixture, and removing tests for the deleted action, rather than retaining dead APIs or restoring the One Tap route. These are the only carry adaptations.
  • The final diff of c95d5488 is authoritative despite its earlier commit title mentioning the Codex harness; the carry retains the upstream default opencode harness rather than introducing another workflow change.
  • No empty cherry-picks occurred; all three requested commits were absent and carried.

Manual steps

None. No environment, console, secret, migration, or backfill changes are required by this carry.

thomasluizon and others added 3 commits September 30, 2026 12:43
The MCP authorize page moved to the authorization-code redirect through
/oauth/google/start and /oauth/google/callback, so the One Tap tokeninfo
route kept no caller in either app or in any documented client. It also
created users through a raw repository call instead of an application
command.

Remove the route, its GoogleAuthRequest record, FindOrCreateGoogleUserAsync,
the now orphaned user repository and HTTP client factory dependencies, the
OAuthController.GoogleAuth catalog entry and the GoogleTokenAudienceMismatch
error, and regenerate openapi.json. The route stayed deprecated on main, so
oasdiff reports the removal as api-path-removed-with-deprecation at INFO and
the breaking-change gate passes.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit e596ee1)
#668)

* chore: run the Pullfrog reviewer on the Codex harness with gpt-6.1-sol

The Codex step now sets PULLFROG_AGENT=codex and passes openai/gpt-6.1-sol
as a raw model specifier, because no published Pullfrog alias resolves to it
yet. The Claude fallback moves to claude-opus-5-5.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: keep the Pullfrog reviewer on the opencode harness at the model's default effort

The Codex CLI harness disables multi_agent, which drops the reviewfrog
specialist sub-agent, and a raw model specifier has no effort rung, so the
effort input was never applied. The review step keeps openai/gpt-6.1-sol on
the default opencode harness, where OpenAI's documented default effort is
medium.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit c95d548)
…unts (#932) (#667)

* Transfer a device's push subscription when another account registers it

A device keeps one push endpoint or FCM token across the accounts that
sign in on it. Before, a second account got PUSH_ENDPOINT_OWNED_BY_OTHER_USER,
the client rotated the endpoint, and the first account kept a dead row that
counted toward its five-device cap.

Now the row moves to the registering account when the request proves it
holds the device: a Web Push request must present the stored p256dh key
and auth secret, and an FCM request must present the stored token with
the FCM sentinel. A request without that proof still gets the old error,
so an account cannot take or remove another account's device.

Refs thomasluizon/orbit-tickets#932

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Let the account on a device release its prior account's push row

Unsubscribe only removed a row the caller owned. When a browser or
Android device stayed registered to a previous account and the account
now signed in turned push off, the client dropped the endpoint locally
while the previous account kept listing and counting a dead device.

Unsubscribe now takes the device's p256dh and auth, which both clients
already send, and removes another account's row only when they prove
control of the device, using the same check as the subscribe transfer.
Without that proof the row stays with its owner and the call still
returns success, so it does not reveal who owns an endpoint.

Refs thomasluizon/orbit-tickets#932

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: require explicit cross-account push subscription release

* fix: bind push unsubscribe deletion to the observed owner

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit ce78ccb)

@pullfrog pullfrog 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 new Critical or High issues found.

Reviewed changes across all 26 files and three commits, including the corresponding web and Android consumers on main and redesign/main.

  • OAuth cleanup: Removes the deprecated One Tap endpoint and its orphaned dependencies, error entry, capability reference, and tests while preserving the redirect-based Google flow and redesign authorization page.
  • Reviewer configuration: Carries the explicit primary and fallback model settings into the existing pinned Pullfrog workflow.
  • Push account switching: Transfers existing device registrations with matching credentials, adds opt-in cross-account release, and protects unsubscribe deletion against an intervening ownership transfer. Existing unsubscribe payloads remain accepted.
  • Regression coverage: Covers ownership checks, legacy defaults, validation, REST/MCP/chat forwarding, and SQLite account-switch interleavings. The solution builds with zero errors; all 8,308 unit tests pass.

Pullfrog  | View workflow run | Using openai/gpt-6.1-sol | 𝕏

@thomasluizon
thomasluizon merged commit e0cec58 into redesign/main Sep 30, 2026
22 checks passed
@thomasluizon
thomasluizon deleted the fix/ticket-746-carry-push-transfer branch September 30, 2026 16:09
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.

1 participant