Skip to content

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

Merged
thomasluizon merged 23 commits into
redesign/mainfrom
thomasluizon/ticket-746-carry-1018
Oct 18, 2026
Merged

thomasluizon merged 23 commits into
redesign/mainfrom
thomasluizon/ticket-746-carry-1018

Conversation

@thomasluizon

@thomasluizon thomasluizon commented Oct 18, 2026 •

Copy link
Copy Markdown
Owner

Carry the 21 requested main commits after 8356d4de onto redesign/main at 5d9ff03e, in order with git cherry-pick -x. Preserve the newer Notion, proactive, ordered-response, and ask-block work. The follow-up commit applies the carried API version declarations to the two newer controllers and regenerates the v2 document.

Refs thomasluizon/orbit-tickets#746. This remains the standing sync ticket.

Carried commits

Source Carry Resolution
61b0090bf (#728) 52af0caf Patched analyzer test dependency; clean.
bcfd81eaf (#729) 7b60cc84 Added PR domain shards and concurrency; retained the actual PR base for fetch and since.
5526c9bc6 (#723) 71e975f2 Imported compatibility, preview binding, skip fixes, release validation, and proofs; retained the later redesign tree.
1b886bdfe (#724) 4cfe1ca4 Added account flag targeting and administration; retained Notion forced refresh and chat-only tools.
ac8b34a20 (#733) 7cebaf24 Header versioning; clean pick. Follow-up 5d22617a versions the newer Notion and proactive controllers.
a9d8dd595 (#734) 1e432b5c Typed config OpenAPI response; clean.
9c6477087 (#735) 0992cb33 Cloudflare production redesign routing; clean.
7472203c7 (#736) 20384f74 Habit edit gates, end dates, and reminders; clean.
b802f9e4d (#737) c481e0e8 Mutation and guard job reductions; clean.
0e3262836 (#739) ad60dc7e Habit and goal ownership coverage; clean.
da2f53a54 (#740) fffcd22d Checkout user metadata coverage; clean.
114960615 (#741) 4e32a4ce OAuth Turnstile protection; clean.
98faf4e62 (#743) 5f6fa7d8 Chat scope guard before context; retained block-answer parsing and statuses. Regenerated documents.
a9e5fb9d7 (#745) 7ec37462 Accountability deletion and reset; retained the combined migration guard.
0e63842e5 (#747) 7229647a Goal dates and reminder counts; clean.
abdd738e2 (#742) 2e5439b1 Staging landing Terraform settings; clean.
d9f847a81 (#751) d7edd2c7 Web Push endpoint restrictions; clean.
fa33a94a2 (#750) cf8489db Upload erasure and owner checks; retained the proactive engine scheduler in its fixture.
de0f42fe6 (#749) cd6931a0 Email and source IP limits, including BFF forwarding; retained block-answer-only limiting.
ade7016c3 (#738) a1207aa0 Fifteen-minute access tokens; clean.
1bd0d2650 (#744) e2dd228b Equalized provisioning and durable signup work; combined SQLite encryption and concurrency support, migration assertions, and the newer rate-limit fixture dependency.

Every source SHA has its own original-source trailer. The two older commits checked below already exist by content.

Already present by content

  • b8abb7628 (test: make achievement count fixture independent of the clock #695): tests/Orbit.Application.Tests/Gamification/AchievementProgressServiceTests.cs:118-119 sets the old log's creation timestamp to its logged date at noon, exactly as the source change does.
  • 41d806406 (fix: send the staging pinger with manual redirects #678): infra/workers/staging-pinger.mjs:29 uses manual redirects; infra/staging-pinger.test.mjs:106 checks rejection of a 301; infra/README.md:69 documents the behavior.
  • Both complete patches passed git show --format= <source> | git apply --reverse --check, exit 0. Neither needed a cherry-pick.

Promotion conflicts by redesign commit

Comparing 0a32fab3 with 5526c9bc6 isolates the promotion's additions from its copy of the older redesign tree. Each group below names the latest redesign commit touching its conflicted paths. Later redesign behavior and tests remain; the compatibility additions are applied on top.

a2f5469 Clean timeless text on redesign branch for #715 (#577)

Path Resolution
src/Orbit.Api/Middleware/LocalizedErrorResultFilter.cs Added the English calendar-connection compatibility exception to the current filter.
tests/Orbit.Infrastructure.Tests/Extensions/McpConfirmationGateTests.cs Added the pending-operation-store constructor argument to the current fixture.
tests/Orbit.Infrastructure.Tests/Middleware/LocalizedErrorResultFilterTests.cs Added all four shipped-client calendar language compatibility cases.

5d9ff03 feat: connect Notion tasks to Astra (#732)

Path Resolution
src/Orbit.Api/openapi.json Retained the current document while resolving; regenerated both documents from the combined source.
src/Orbit.Application/Chat/ChatToolGroups.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Application/Common/FeatureFlagKeys.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Application/Profile/Models/UserDataExport.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Application/Profile/Queries/ExportUserDataQuery.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Domain/Models/AgentContracts.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Infrastructure/Migrations/OrbitDbContextModelSnapshot.cs Retained proactive, block, and Notion models and seeds; combined the later main migration additions.
tests/Orbit.Application.Tests/Queries/Profile/ExportUserDataQueryHandlerTests.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.

c8877ee feat: return ordered Astra response parts (#727)

Path Resolution
src/Orbit.Application/Chat/AccountRowsCard.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Application/Chat/FollowUpDirective.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Application/Chat/PeriodInsightCard.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Application/Chat/RecordListCard.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Application/Chat/StatusCards.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
tests/Orbit.Application.Tests/Chat/FollowUpDirectiveTests.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.

d80442d feat: add Astra choice and pick list ask blocks (#731)

Path Resolution
src/Orbit.Application/Chat/Commands/ProcessUserChatCommand.Accumulator.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Application/Chat/Commands/ProcessUserChatCommand.Ai.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Application/Chat/Commands/ProcessUserChatCommand.Tools.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Application/Chat/Commands/ProcessUserChatCommand.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Application/Chat/Validators/ProcessUserChatCommandValidator.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Application/Common/ErrorCopy.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Infrastructure/Services/AgentOperationExecutor.cs Added persistence of the initial preview fingerprint; retained PreviewOnly policy and execution guards.
tests/Orbit.Application.Tests/Commands/Chat/ChatWriteHoldHandlerTests.cs Retained current chat setup and added the pending-operation-store dependency.
tests/Orbit.Application.Tests/Commands/Chat/ProcessUserChatCommandHandlerTests.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
tests/Orbit.Infrastructure.Tests/Services/AgentChatWriteHoldTests.cs Added the initial preview binding cases and store dependency; retained chat-only tool filtering.

a644692 Add record list pages and complete Astra card data for #706 (#571)

Path Resolution
src/Orbit.Application/Chat/Queries/GetRecordListPageQuery.cs Applied the source formatting only; retained all record-page behavior.

c10a291 feat: add proactive Astra item engine (#725)

Path Resolution
src/Orbit.Application/Common/ErrorMessages.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Infrastructure/Services/AiProactiveCheckinMessageService.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
src/Orbit.Infrastructure/Services/ProactiveCheckinSchedulerService.cs Kept the deletion; the proactive engine scheduler remains the implementation.
tests/Orbit.Infrastructure.Tests/Services/AiProactiveCheckinMessageServiceGenerationTests.cs Kept the deletion and the replacement proactive engine coverage.
tests/Orbit.Infrastructure.Tests/Services/AiProactiveCheckinMessageServiceTests.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.
tests/Orbit.Infrastructure.Tests/Services/NotificationVoiceTests.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.

52c8db9 Add guarded undo for single habit skips (#681)

Path Resolution
src/Orbit.Application/Habits/Commands/BulkSkipHabitsCommand.cs Carried the transaction return value for refresh success and concurrent-update conflict handling.
src/Orbit.Application/Habits/Commands/UndoSkipHabitCommand.cs Carried AsSplitQuery for the existing tags and goals read.

97c39fb feat(chat): enrich day and calendar cards for in-place actions (#726)

Path Resolution
tests/Orbit.Application.Tests/Chat/StatusCardBuilderTests.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.

40efecf Add optional imported events to calendar API (#659)

Path Resolution
tests/Orbit.Application.Tests/Queries/Calendar/CalendarEventItemSerializationTests.cs Applied source formatting while retaining calendar fields and values.

36fff55 Add proactive item lifecycle status read (#730)

Path Resolution
tests/Orbit.Infrastructure.Tests/Services/AgentCatalogServiceTests.cs Retained the current redesign behavior and tests; the promotion repeats the earlier tree here.

3f82b8d Fix confirmed bulk habit creation and preserve approval on failure (#702) (#704)

Path Resolution
tests/Orbit.Infrastructure.Tests/Services/AgentExecutionAndSanitizerTests.cs Added the pending-operation-store constructor argument; retained all current tests.
tests/Orbit.Infrastructure.Tests/Services/BulkCreateAgentOperationTests.cs Added the pending-operation-store constructor argument; retained confirmed bulk-creation coverage.

Other conflict resolutions

Redesign behavior or integration Carried source Path and resolution
Earlier branch sync (c3c7a92f, #556) #729 .github/workflows/mutation.yml: kept github.base_ref for fetch and since; added shard arguments and concurrency. The later #737 matrix change preserves this.
Ask blocks (d80442d3, #731) #724 src/Orbit.Api/Extensions/ResultActionResultExtensions.cs: combined all Astra and feature-flag status mappings. src/Orbit.Application/Chat/Tools/IAiTool.cs: kept IChatOnlyAiTool and added IMcpOnlyAiTool.
Notion (5d9ff03e, #732) #724 src/Orbit.Infrastructure/Services/FeatureFlagService.cs: account targeting uses the new shared snapshot; forceRefresh still bypasses its cache for the Notion access gate.
Ask blocks (d80442d3, #731) #743 src/Orbit.Api/Controllers/ChatController.cs: combined block parsing and 404/409/410 responses with 403 and the early scope guard. Generated OpenAPI replaces the conflicting document.
Combined migration proof introduced by #724 #745, #744 tests/Orbit.Infrastructure.Tests/Persistence/FeatureFlagAccountsMigrationTests.cs: retained historical flag/signup model proofs, exact accountability FK assertions, all eight migration IDs in order, and the current snapshot guard. The historical-to-current FK comparison selects FK operations because the newer redesign also adds tables and seeds.
Proactive engine (c10a291e, #725) #750 tests/Orbit.Infrastructure.Tests/BackgroundJobs/ScheduledJobRegistryTests.cs: retained ProactiveEngineSchedulerService and added the erasure-capable AccountDeletionScopeFactory.
Ask blocks (d80442d3, #731) #749 src/Orbit.Api/RateLimiting/DistributedRateLimitAttribute.cs: retained the optional block-answer gate and added BFF settings plus both anonymous partitions. Updated the corresponding existing block-answer fixture for its added dependency.
Notion encryption (5d9ff03e, #732) #744 tests/Orbit.Infrastructure.Tests/Persistence/SqliteOrbitDbContextFactory.cs: retained encryption-aware model caching and the proactive partial index; added file-backed connections, disabled pooling, and file cleanup for auth concurrency tests.

The newer AstraPickListPreviewTests fixture also receives the carried executor store and real account flag resolver dependencies. The versioning suite identified the two newer controllers requiring the carried v1/v2 declarations; the final follow-up applies those declarations and generated output together.

Migrations and contract

The combined snapshot retains all redesign models and adds AddFeatureFlagAccounts, CascadeAccountabilityPairsOnUserDeletion, and AddDurableSignupWork. The source migration and Designer files remain byte-for-byte copies of main. Existing redesign migrations are unchanged.

Order: AddHabitSkipUndo, AddFeatureFlagAccounts, ReplaceProactiveCheckinsWithItems, AddIssuedAstraBlocks, AddNotionConnection, TrackNotionOAuthStateConsumption, CascadeAccountabilityPairsOnUserDeletion, AddDurableSignupWork. The flag migration sorts before the newer redesign migrations and depends only on existing Users and AppFeatureFlags. EF applies missing migration IDs; use the normal full migration sequence, including on a database that already applied later redesign IDs. No unresolved ordering question remains.

The carried historical schema proof stays pinned to AddHabitSkipUndo.TargetModel. The current snapshot is checked separately against the full combined model. dotnet ef migrations has-pending-model-changes --project . --startup-project ../Orbit.Api --no-build, run in src/Orbit.Infrastructure with unused design-time connection strings, exits 0 and reports no model changes. No database connection or new migration was required.

Both OpenAPI documents are generator output. Existing DTO fields and the minimum supported client version remain intact. The two newer controllers expose the same behavior under omitted/v1/v2 headers.

Test evidence

Both locale modes passed: env -u LANG and LC_ALL=en_US.UTF-8. Each build and test command was judged by its process exit code. Broad verification finished in 76.22 seconds, within the 25-minute budget.

Check LANG unset LC_ALL=en_US.UTF-8
dotnet build Orbit.slnx Exit 0, zero errors Exit 0, zero errors
dotnet test tests/Orbit.Domain.Tests --no-build --no-restore Exit 0, 737 passed Exit 0, 737 passed
dotnet test tests/Orbit.Application.Tests --no-build --no-restore Exit 0, 5,692 passed Exit 0, 5,692 passed
dotnet test tests/Orbit.Infrastructure.Tests --no-build --no-restore Exit 0, 3,668 passed Exit 0, 3,668 passed
dotnet test tests/Orbit.Analyzers.Tests --no-build --no-restore Exit 0, 32 passed Exit 0, 32 passed
git diff --exit-code -- src/Orbit.Api/openapi.json src/Orbit.Api/openapi_v2.json after build Exit 0 Exit 0

Total: 10,129 tests per locale, no failures or skips. Build warnings remain for existing package-version constraints, deprecated Firebase/subscription members, and an existing captured parameter.

node --test .github/scripts/mutation-matrix.test.mjs tests/Orbit.Infrastructure.Tests/Controllers/OAuthPageScriptTests.mjs infra/check-web-plan.test.mjs infra/staging-pinger.test.mjs infra/google-play-isolation.test.mjs infra/ses-isolation.test.mjs infra/bff-forwarding.test.mjs: exit 0, 69 passed. terraform fmt -check infra, timeless text, dash baseline, root allowlist, and suppression allowlist checks all exit 0. Added bare C# line comments were inspected; the one carried line links its evidence. All commit hooks passed.

The unmodified carried ApiVersioningTests suite initially exited 1 with 11 passes and two failures: EveryControllerRoute_AcceptsV2AndRejectsUnsupportedVersion rejected the newer Notion route under v2, and the v2 document comparison lacked the newer controller schemas. After adding the same carried version declarations to ConnectionsController and ProactiveAstraController and regenerating, the unchanged suite passed all 13 cases, exit 0. No strengthened test was needed because the existing test already caught this integration defect.

Exact before/after command: env -u LANG dotnet test tests/Orbit.Infrastructure.Tests --no-build --no-restore --filter 'FullyQualifiedName~ApiVersioningTests'.

The promotion's unchanged historical schema test initially failed against the newer live model, with 18 other focused cases passing. The next requested source commit (#724) already pins that proof to the promotion snapshot; it is carried as written. Final focused combined runs passed 55 Domain, 87 Application, and 178 Infrastructure cases, each exit 0. Those Infrastructure cases cover the complete combined snapshot, the historical schema proof, Notion refresh, pick-list preview, scope checks, anonymous rate limiting, scheduler wiring, deletion, and auth provisioning races.

No new regression tests were authored in this carry. Source tickets own their original failing-before evidence. No app server, browser, live database, infrastructure apply, or mutation run was started. Miniflare runtime routing checks were not run under the work order's server restriction; the 69 Node unit cases run here exclude that file. CI owns mutation testing and infrastructure rollout verification.

External interface evidence

  • Production health was read with curl --fail --silent --show-error https://api.useorbit.org/health. Complete response: {"status":"Healthy","commit":"7472203c7450bdd914c68282fefa905d9b432653","checks":[{"name":"background-services","status":"Healthy","description":"All background services running"},{"name":"database","status":"Healthy","description":"Database reachable"}]}. This proves the carried release check's status and commit fields. Their in-repository producer is WriteHealthCheckResponseAsync.
  • Source PR #733 records installed Asp.Versioning, ASP.NET OpenAPI and Scalar source evidence, including real routing error code, title, status, supported-version headers, document grouping and generated filenames. The carried routing suite invokes that actual middleware and passes here.
  • Source PR #735 records the actual pinned Terraform provider schema for Render service id, url, and image attributes, plus installed Miniflare request and binding contracts. Source PR #742 records the installed Render env_vars schema and complete redacted environment response.
  • Source PR #741 records the inspected Cloudflare loader hash, render/reset exports, widget ID, option and callback names. Its Node tests run the real page script and pass here.
  • Source PR #750 records decompilation of installed AWSSDK.S3 4.0.104.3 request marshallers, response unmarshallers and response handler: ListObjectsV2 S3Objects/Key, null empty listings, deletion XML, DeleteErrors, and DeleteObjectsException on partial failure. It includes exact ilspycmd reproduction commands.
  • Source PR #744 records real EF command interception and Hangfire job-expression evidence. The SQL row-count return is ignored; insert ownership comes from the candidate identity. No new Google or Supabase response field is read. Source PR #749 records the actual trusted-hop middleware results; those tests pass here.

Review round 1

Commit b34d0100 answers the Pullfrog finding on 5d22617a (the per-account proactive kill switch was ignored). This is a redesign-only integration: the proactive engine exists only on redesign/main, so the fix lives in this carry and nothing changes on main.

  • ProactiveEngineService.LoadAsync resolves each loaded user's enabled flags through IFeatureFlagService.GetEnabledKeysForUsersAsync (one batch read), drops users whose effective flags include astra_proactive_engine_disabled, and CalendarAllowed reads the same per-user flags instead of the raw global rows.
  • Red first: the strengthened tests failed on 5d22617a (4 failed, 2 passed, exit 1: targeted delivery, active status despite the switch, ignored calendar targeting).
  • Green after: 89 focused tests (ProactiveEngineServiceTests, ProactiveAstraControllerTests, FeatureFlagAndAgentSupportTests, FeatureFlagAccountsMigrationTests) pass, including query-count invariance at 10 and 1,000 eligible accounts. dotnet build Orbit.slnx 0 errors; all test projects pass with LANG unset and LC_ALL=en_US.UTF-8 (Domain 737, Application 5,692, Infrastructure 3,674, Analyzers 32: 10,135). OpenAPI generation unchanged.
  • Mutation (domain-habit-freeze) was cancelled at its 45-minute limit on 5d22617a (414 mutants). No carried Domain test explains it: the slowest changed case is PushSubscriptionTests.Create_Valid_Success at 0.0145 s.

Assumptions

  • Treat the promotion's 0a32fab3 tree as its imported redesign baseline and carry its unique additions onto the current branch; rejected restoring that older tree over later Astra work.
  • Preserve source historical migration metadata and compare historical compatibility separately from the full current snapshot; rejected rewriting applied migration/Designer files to resemble the combined branch.
  • Apply the carried v1/v2 declarations to both newer controllers because the unchanged source route guard requires every controller route to support both versions; rejected leaving those routes v1-only.

Manual steps

These are inherited release prerequisites from the carried source PRs; this carry does not perform them.

  1. Before staging release, review/apply aws_iam_user_policy.uploads["staging"]. In AWS IAM > Users > orbit-api-uploads-staging > Permissions > uploads-object-access, verify s3:ListBucket on arn:aws:s3:::orbit-uploads-staging-713285551626 and s3:DeleteObject on its objects. Erasure must empty the user's prefix, remove the database row, and return 404 for the stable link. Production's equivalent policy for orbit-api-uploads-production and orbit-uploads-production-713285551626 requires the owner's authorization before production release.
  2. In the Terraform execution environment's ignored infra/local.tfvars, remove production_storage_provider and staging_storage_provider. In Render > Environment Groups > orbit-staging-api / orbit-production-api, retain the Storage__S3__Bucket, Storage__S3__Region, Storage__S3__PublicBaseUrl, Storage__S3__AccessKeyId, Storage__S3__SecretAccessKey, Supabase__Url, and Supabase__AnonKey keys. Retire Storage__Provider, Supabase__SecretKey, and Supabase__Bucket from storage configuration. Startup and erasure verify the result.
  3. Apply the Terraform JWT settings to staging and verify effective Jwt__ExpiryMinutes=15 and Jwt__ExpiryHours=0 in Render > orbit-api-staging > Environment, including linked orbit-staging-api and service overrides. Production's equivalent in Render > orbit-api > Environment requires the owner's authorization. Before releasing this shorter token lifetime, verify the Android build carrying thomasluizon/orbit-tickets#1525 (orbit-ui-mobile#1843) is live on the open track, as required by source PR Limit access tokens to fifteen minutes #738.
  4. For BFF IP forwarding, apply the Terraform-managed SecureString parameters /orbit/staging/api/Auth__BffForwardingSecret and /orbit/production/api/Auth__BffForwardingSecret through the existing infrastructure process. In AWS Systems Manager > Parameter Store and Render > corresponding API/web environment groups, verify the API's Auth__BffForwardingSecret and web's BFF_FORWARDING_SECRET share their environment's value without printing it. Distinct verified client addresses must consume distinct IP buckets; mismatched headers must retain the direct connection partition.
  5. To enable OAuth bot protection, Cloudflare > Turnstile > selected widget > Hostname management must allow the serving API host. In Render > the corresponding API service > Environment, set BotProtection__SiteKey and its paired BotProtection__SecretKey; activate with BotProtection__Enabled=true. Verify the OAuth widget and valid-token send, and verify missing-token rejection without an email job. The carried checked-in setting remains disabled.
  6. For production redesign routing, Cloudflare > My Profile > API Tokens must provide Workers Scripts Write, Workers Routes Write and DNS Write plus their required read permissions. In ignored infra/local.tfvars, supply approved production_redesign_web_digest, retain dns_app_target=orbit-web-3qmv.onrender.com and web_custom_domains=["app.useorbit.org"], then review the saved Terraform plan and web plan guard before applying through the existing process. In Render > orbit-web-redesign > Environment/Settings, verify orbit-production-web, NEXT_PUBLIC_SITE_URL=https://app.useorbit.org, digest, and health. Pass production_redesign_web_service_id and production_redesign_web_host outputs to the separate #1499 release work. After its UI release and cookie change, compare app health commits with and without orbit_design=redesign, verify callbacks/session renewal/Server Actions, record routed latency, and verify route-removal rollback as detailed in infra/README.md.
  7. Normal API release applies the included migration IDs through the existing migration process. Verify the released health commit and __EFMigrationsHistory, including all missing redesign IDs and the three carried migrations. This PR does not deploy, merge, or close the standing sync ticket.

thomasluizon and others added 22 commits October 18, 2026 16:46
* Bring the API redesign tree onto main for #1413

* Preserve calendar connection detection for shipped clients

* Prove API and migrated schema compatibility with shipped clients

* Trim whitespace in the archived main schema proof

* Require the production health response to report the released commit

* Bind initial approval previews to stored pending operations

* fix: return the bulk skip refresh outcome and split the undo skip query

SonarCloud failed the quality gate on two reliability findings in code this pull request brings to main:
the bulk skip conflict check read a flag only a lambda wrote (S2583), and the undo skip check loaded
Tags and Goals in one query (S8733). The transaction now returns whether every habit refreshed, and the
undo skip check splits its query. A new case covers the concurrent change conflict; it failed with the
refresh outcome forced to true and passes with the fix.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 5526c9b)
* feat: resolve feature flags per account

* feat: administer account feature flags through MCP and REST

* test: exclude feature flag targets from rate limit fixture

* fix: reconcile account flag tests and migration metadata with redesign

(cherry picked from commit 1b886bd)
* Add header API versioning with v1 compatibility

* Verify versioned OpenAPI and browser header compatibility

* Preserve skip undo path contract with optional version header

(cherry picked from commit ac8b34a)
* Add cookie-based routing for the production redesign web service

* Document web routing rollout, permissions, and rollback checks

* Fix web routing coverage and disable infra install scripts

* chore: regenerate the v2 OpenAPI document on main

orbit-api#733 added openapi_v2.json and orbit-api#734 typed the /api/config
response in parallel, so main carries a v2 document without the typed config
schema and the Build check's stale-document step fails on every merge with
main. dotnet build src/Orbit.Api regenerates it; openapi.json is unchanged.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 9c64770)
* fix: validate habit updates with the resulting time range

* fix: preserve end dates when creating root habits

* fix: gate slip alert activation and preserve unchanged reminders

* fix: compare effective reminder rules across stored formats

(cherry picked from commit 7472203)
* Select mutation shards from changed projects

* Consolidate guards and filter artifact generation

* Skip project documentation in mutation selection

* Validate mutation base refs and restrict Git PATH

* Read mutation shard changes from standard input

(cherry picked from commit b802f9e)
* fix: erase accountability pairs during account deletion and reset

* test: preserve migration compatibility checks after accountability cleanup

(cherry picked from commit a9e5fb9)
* fix: compare streak sync dates in the user timezone

* fix: show actual days remaining in goal deadline reminders

* test: configure timezone for streak scheduler fixtures

(cherry picked from commit 0e63842)
Web Push subscriptions accept only HTTPS endpoints on the FCM, Mozilla, Apple and WNS push hosts, and the push HTTP client follows no redirects. Replaces orbit-api#748 as one commit so no commit carries the high-entropy sample fixture.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit d9f847a)
* fix: erase uploaded objects before completing account deletion

* fix: refuse upload reads after permanent account deletion

* fix: grant uploads bucket deletion permissions and verify provider wiring

* test: align storage startup checks with erasure requirements

* fix: retire deleted Supabase upload storage

* test: configure upload erasure providers in deletion fixtures

Share the existing object-store fake across account deletion and scheduler fixtures after merging main. Preserve accountability assertions and production provider requirements for thomasluizon/orbit-tickets#1507.

(cherry picked from commit fa33a94)
…8) (#749)

* fix: enforce source IP ceilings alongside anonymous email limits

* test: cover both rate limit dimensions before bot verification

* fix: isolate BFF email rate limits by verified client IP

* fix: generate and persist BFF forwarding secrets

(cherry picked from commit de0f42f)
* fix(auth): limit access tokens to fifteen minutes

* fix(auth): align managed JWT lifetime and prove logout rejection

(cherry picked from commit ade7016)
* test(auth): expose registration dependent sign-in work

* fix(auth): perform uniform registration work before sign-in responses

* test(auth): cover expired codes and tracked upsert conflicts

* fix(auth): isolate signup retries and restore provisioning guards

* fix(auth): recover signup work after dispatch failures

* fix(auth): roll back failed signup referrals before retry

(cherry picked from commit 1bd0d26)
Apply the carried version declarations to the Notion and proactive controllers and regenerate the v2 contract. Refs thomasluizon/orbit-tickets#746.

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

Important

The carried account-targeting model leaves the newer proactive engine outside effective flag enforcement. A targeted proactive kill switch still permits item generation and notifications.

Reviewed changes Reviewed the complete carry from main onto redesign/main, including the conflict resolutions and final controller-versioning follow-up.

  • API compatibility: Adds header-selected v1/v2, preserves omitted-header v1 behavior, types the config response, and regenerates both OpenAPI documents.
  • Account feature flags: Adds targeting persistence, shared account/plan resolution, admin REST/MCP controls, and resolver integration into config, agent policy and streak-freeze eligibility.
  • Astra safeguards: Persists initial preview fingerprints and enforces chat API-key scope before context dispatch while retaining the newer ask-block, ordered-response and Notion behavior.
  • Habit and goal fixes: Corrects edit gates, end dates, reminder invalidation, bulk-skip refresh outcomes, localized streak-sync dates and deadline reminder counts.
  • Authentication: Carries OAuth Turnstile protection, composite email/IP rate limits, authenticated BFF forwarding support, shorter access tokens and checkpointed signup jobs.
  • Erasure and delivery: Adds S3 upload erasure and owner checks, accountability cleanup, and provider-restricted Web Push delivery.
  • Infrastructure and CI: Carries Cloudflare redesign routing, Render/SSM/IAM configuration, staging landing settings, mutation shards, consolidated guards and compatibility coverage.

Verification: the build passed with zero errors; all 10,129 unit tests and 69 Node tests passed. The targeted-flag defect below was reproduced separately using the existing SQLite proactive harness. Sibling client changes and the paired BFF PR were inspected; no live deployment or Play-track verification was performed. The optional cross-model check was unavailable because codex was not installed.

⚠️ Per-account proactive kill switch is ignored

High: Enabling astra_proactive_engine_disabled for an individual account does not stop its proactive engine, even though the new resolver reports the switch as enabled for that account. The preserved ProactiveEngineService.LoadAsync still reads only globally enabled rows, so targeted accounts continue receiving generated items and notifications.

Technical details
# Integrate account targeting into the preserved proactive engine

## Affected sites
- `src/Orbit.Infrastructure/Services/FeatureFlagService.cs:41-46,78-82`: the new shared resolver supports batch account eligibility and global-or-account targeting.
- `src/Orbit.Infrastructure/Services/ProactiveEngineService.cs:52-54`: `Where(f => f.Enabled)` excludes account-only assignments before checking `AstraProactiveEngineDisabled`.
- `src/Orbit.Infrastructure/Services/ProactiveEngineService.cs:253-255`: `CalendarAllowed` consumes the same global-only list, also ignoring account-targeted calendar enablement.
- `src/Orbit.Infrastructure/Services/ProactiveEngineService.cs:31-39,320-350`: scheduled evaluation, current-item retrieval and actionability checks share this loader.

## Reproduction
Using the existing `ProactiveEngineServiceTests.Harness` at the evening-checkin window with a paid account and a due habit:
1. Add `AppFeatureFlag.Create(FeatureFlagKeys.AstraProactiveEngineDisabled, false)` and an `AppFeatureFlagAccount` assignment for that account.
2. Run the real engine and query the real `FeatureFlagService`.
3. Compare with a globally enabled kill switch.

Actual output:
```text
global=False; effectiveDisabled=True; items=1; notifications=1
global=True; effectiveDisabled=True; items=0; notifications=0
```

## Required outcome
- Proactive delivery and current/status reads honor each account's effective kill-switch state.
- Calendar eligibility uses the same effective account flags rather than raw global rows.
- Preserve the existing volume-invariant batch-read behavior.
- Add unit coverage with targeted and untargeted eligible accounts, including suppression of generated items and notifications for the targeted account.

## Suggested approach
Use the existing batch resolver to resolve enabled keys for loaded users, then apply those keys to proactive eligibility and calendar checks. This missing consumer integration is specific to combining account targeting with the newer redesign engine; no change to the resolver's global-or-account semantics is needed.

Pullfrog  | Fix it ➔ | View workflow run | Using gpt-6.1-sol | 𝕏

@sonarqubecloud

Copy link
Copy Markdown

@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. The proactive account-targeting concern from the prior review is addressed.

Reviewed changes Reviewed b34d0100 against the previously reviewed 5d22617a, using the prior complete carry review as the baseline for unchanged code rather than repeating it.

  • Integrated effective account flags into the proactive engine's batch loader, suppressing generation, notifications, current items and active-status reads for targeted-disabled accounts.
  • Aligned calendar eligibility with the same per-user resolved flags instead of globally enabled rows.
  • Expanded regression coverage for global and account targeting, existing-item visibility/status, calendar fetch suppression and invariant query counts at 10 and 1,000 accounts.

Verification: solution build passed with zero errors; all 10,135 unit tests passed with no failures or skips. The focused proactive/resolver/migration suite also passed all 89 tests, and the worktree remained clean. No live deployment was exercised.

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

@thomasluizon
thomasluizon merged commit 7d85e55 into redesign/main Oct 18, 2026
24 of 25 checks passed
@thomasluizon
thomasluizon deleted the thomasluizon/ticket-746-carry-1018 branch October 18, 2026 21:47
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