Skip to content

feat: server-authoritative commerce presentation and moderation (w4b) - #5321

Merged
iscekic merged 31 commits into
mainfrom
audit-w4b-commerce-moderation-5698
Aug 18, 2026
Merged

feat: server-authoritative commerce presentation and moderation (w4b)#5321
iscekic merged 31 commits into
mainfrom
audit-w4b-commerce-moderation-5698

Conversation

@iscekic

@iscekic iscekic commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Summary

The app now decides which purchase UI each platform may show, and the server is the source of truth for that decision.

  • Android users see a truthful "Kilo Pass is not available as an in-app purchase on Android" state, or "This Kilo Pass is managed on the web" with a Manage action, instead of a hidden or broken card.
  • iOS users who already own a pass on another account see a clear "belongs to another Kilo account" message.
  • You can report an AI response and get a receipt, without the response text being sent back.
  • You can report, mute, or block people in PR discussion, and hidden authors disappear from the discussion list.
  • Posting a PR comment or review now requires accepting the current Terms and confirming you are 13 or older.

Purchase presentation and mutations are server-authoritative, keyed by platform, storefront, product, and program. Moderation is a new router backed by four new tables.

Commerce — server-authoritative purchase presentation

A new shared helper resolves which purchase UI a platform, storefront, and product may show, and the web router exposes it plus a preflight check and a hardened completion mutation. The single allowed native-IAP combination is iOS + App Store + Kilo Pass; everything else is unavailable or web-managed, and the checkout path now refuses mobile platforms.

Files
  • packages/app-shared/src/commerce/purchase-presentation.ts — new pure helper: resolvePurchasePresentation, mapKiloPassStatusToClass, isNativeIapMutationAllowed, and the exact copy constants.
  • packages/app-shared/src/commerce/index.ts — new barrel export.
  • apps/web/src/lib/kilo-pass/purchase-presentation.ts — new wrapper: buildPurchasePresentation and getPurchasePresentationForUser derive statusClass and the absolute webUrl.
  • apps/web/src/routers/kilo-pass-router.ts — adds getPurchasePresentation and preflightPurchase; reworks completeAppStorePurchase to take platform/storefront/product and reject non-native_iap with FORBIDDEN commerce_not_available; createCheckoutSession rejects ios/android; mapAppStoreCompletionError maps CONFLICT to a "still being processed" message.
  • packages/app-shared/package.json — registers the ./commerce and ./moderation export paths.

Commerce — store completion on the operation ledger

App Store purchase completion now runs through the shared operation ledger, so a retried completion replays its settled result instead of re-executing, and a permanent provider/user mismatch settles failed and is never retried. A purchase_settled terminal event is emitted from the settle path.

Files
  • apps/web/src/lib/kilo-pass/store-subscription-completion.ts — admits a purchase/complete_store_purchase row, replays settled rows, settles failed on mismatch, and emits purchase_settled.
  • apps/web/src/lib/kilo-pass/apple-store-notifications.ts — marks a notification event processed (never retried) when completion settles a permanent mismatch.
  • packages/db/src/operation-ledger.ts — adds purchase to OPERATION_DOMAINS.
  • packages/app-shared/src/analytics/event-map.ts — adds PURCHASE_SETTLED_EVENT with a strict schema.

Commerce — mobile Kilo Pass IAP

The Kilo Pass screen now gates on the server presentation, and a single IAP owner is mounted only when the presentation is native_iap on iOS, so Android never initializes StoreKit. The profile card derives its state from the same presentation.

Files
  • apps/mobile/src/components/kilo-pass/kilo-pass-native-iap-owner.tsx — new single useIAP call site owning purchase, restore, and recovery; exposes useKiloPassNativeIap.
  • apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.ts — purchase/restore/recovery actions, deduped toasts, inline-error ownership, and the completeAppStorePurchase call.
  • apps/mobile/src/components/kilo-pass/kilo-pass-subscription-screen.tsx — gates on getPurchasePresentation; runs preflightPurchase before purchase.
  • apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.tsx — derives the profile card from the presentation and subscription state.
  • apps/mobile/src/lib/kilo-pass/subscription-card-state.ts — card content and ownership-preflight derivation from presentation and status class.
  • apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-products.ts — fetches App Store SKUs with a bounded connection timeout.
  • apps/mobile/src/components/kilo-pass/kilo-pass-ios-manage.ts — new lazy expo-iap management entry point (open App Store management, dev refund).
  • apps/mobile/src/components/kilo-pass/restore-purchases-button.tsx — reads from the IAP owner context.
  • apps/mobile/src/app/(app)/_layout.tsx — removes the app-wide StoreKiloPassPurchaseProvider.
  • apps/mobile/src/components/profile-screen.tsx — removes the standalone restore button.

Moderation — router and tables

A new moderation router exposes report, appeal, block, mute, hidden-user, and Terms procedures, backed by four new tables. Report context is minimized by construction so a message or comment body can never be persisted.

Files
  • apps/web/src/routers/moderation-router.ts — new router: reportContent, reportUser, getReportReceipt, appealReport, blockUser/unblockUser, muteUser/unmuteUser, listHiddenUsers, getTermsStatus, acceptTerms; report context is .strict() with only platform/storefront.
  • packages/app-shared/src/moderation/types.ts — new shared constants: surfaces, reasons, CURRENT_UGC_TERMS_VERSION, UGC_AGE_POSTURE.
  • packages/app-shared/src/moderation/index.ts — new barrel export.
  • packages/db/src/schema.ts — adds content_moderation_reports, user_moderation_blocks, user_moderation_mutes, user_terms_acceptances.
  • packages/db/src/migrations/0219_supreme_firelord.sql — the generated migration for those four tables.
  • apps/web/src/routers/root-router.ts and packages/trpc/src/mobile.ts — register moderation.
  • apps/web/src/lib/user/index.tssoftDeleteUser deletes the four moderation tables.

Moderation — UGC Terms gate

The three comment-creating PR mutations require an accepted current Terms record before any ledger row is created, throwing PRECONDITION_FAILED terms_required when absent.

Files
  • apps/web/src/routers/github-pr-review-router.ts — adds assertTermsAccepted before createReviewComment, replyToComment, and submitReview.

Moderation — mobile UI

The mobile app adds the Report AI response control, the PR-discussion overflow menu (report content, report user, mute, block), hidden-author filtering, and the Terms gate across the reply and composer surfaces.

Files
  • apps/mobile/src/components/agents/report-ai-response.ts — new pure helper building the minimized report input and the retryable/terminal error toast.
  • apps/mobile/src/components/agents/message-details-sheet.tsx — adds the "Report AI response" control.
  • apps/mobile/src/components/pr-review/discussion/comment-row.tsx — adds the overflow menu with report/mute/block, gating self-target.
  • apps/mobile/src/components/pr-review/discussion/pr-review-discussion-list.tsx — filters hidden authors and passes the viewer login.
  • apps/mobile/src/components/pr-review/discussion/discussion-thread.tsx — passes viewerLogin through.
  • apps/mobile/src/components/pr-review/discussion/reply-input.tsx — adds the Terms gate before replying.
  • apps/mobile/src/components/pr-review/composer-inline-error.tsx — new inline-error component and hook with the Terms gate.
  • apps/mobile/src/components/pr-review/pr-review-comment-composer.tsx and pr-review-submit.tsx — surface the Terms gate and inline error states.
  • apps/mobile/src/components/pr-review/review-event-chips.tsx — new review-event radio chips extracted for the submit sheet.
  • apps/mobile/src/lib/pr-review/classify-pr-review-query-state.ts — adds the terms-required mutation classification.
  • apps/mobile/src/lib/trpc-error.ts — new shared readTrpcErrorField and isTerminalTrpcCode helpers.

Dev seed

A new dev seed creates a Stripe test-mode Kilo Pass subscription for the Android web-management E2E scenario.

Files
  • dev/seed/app/kilo-pass-stripe.ts — new idempotent seed creating a web-managed (Stripe) Kilo Pass subscription for a given email.

Tests: 22 test files added or updated across mobile, web, and app-shared, covering the presentation matrix, ledger admit/replay, the moderation router, the Terms gate, and the mobile purchase-screen states. Generated: 2 files updated (0219_snapshot.json, _journal.json).


Verification

  • bot-e2e scenarios S1–S9 (run by the orchestrator)

Visual Changes

Kilo Pass purchase screen (iOS)

s1-tiles.png

Android storefront cards

Unavailable:

s2s3-00-01-45.png

Web-management:

s4-card.png

Report AI response

Retryable toast:

s5-retryable-toast.png

Submitted with receipt:

s6-submitted-receipt.png

PR discussion report / mute / block

Report receipt:

s8-1-receipt-toast.png

Muted author:

s8-2-muted-bob.png

Blocked author:

s8-4-blocked-carol.png

UGC Terms gate

Cancel:

s9-1-gate-cancel.png

Accept:

s9-2-gate-accept.png

Reviewer Notes

  • The three reader notes above are the what, why, and how of the change.
  • Human steps: none required before or after merge.

iscekic added 18 commits August 17, 2026 23:58
Add pure purchase presentation/status helpers and moderation type constants shared by web and mobile. Wire ./commerce and ./moderation package exports.
…ight

Add getPurchasePresentation and preflightPurchase procedures that decide purchase UI by platform, storefront, product, and program. Enforce native-IAP authz on completeAppStorePurchase and reject mobile platforms on createCheckoutSession. Update callers and add universal-link null-path tests.
…stants

Add preflight tests for ended-sub allow and live Play reject. Move Kilo Pass copy strings into app-shared so web and mobile share one source.
Wrap completeStoreKiloPassPurchase in admit/settle with domain purchase, intent complete_store_purchase, and reconcile-first taxonomy. Settle failed on provider/user mismatch, mark reconcile-pending otherwise. Emit purchase_settled outbox event.
Map roast configs to balanced guidance at prompt time. Offer only strict, balanced, and lenient in the mobile and web pickers. Keep roast in Zod and templates for old saved configs.
Add an idempotent app:kilo-pass-stripe seed that creates a user with a real Stripe test subscription for Android web-management E2E.
…owner

Gate the Kilo Pass screen on getPurchasePresentation and mount one native IAP owner only for iOS native_iap. Drive the Android card from presentation kind. Key the product cache by account and clear it on authEpoch.
Add tests for the Apple notification mismatch catch (processed_at + processed true) and the duplicate_settled failed-row replay that throws the stored domain error.
Throw on missing price id or non-test secret before any destructive cleanup. Persist the created subscription id idempotently so the Stripe webhook write does not collide.
…s gate

Add content_moderation_reports, user_moderation_blocks/ mutes, and user_terms_acceptances tables with a moderation router. Gate PR UGC writes on the current Terms version. Extend softDeleteUser.
Seed a current-version Terms acceptance for UGC mutation tests and add a test proving a missing acceptance throws PRECONDITION_FAILED terms_required with no ledger row.
Add a Report AI response action on assistant messages that submits a moderation report with surface ai_output and no body, with submitted/retryable/terminal outcomes.
Add report-content, report-user, mute, and block to the comment overflow. Filter hidden users. Gate reply, comment, and submit on the current Terms version with a 13+ sheet.
Show a Retry action that resubmits the minimized payload on retryable failures and no Retry on terminal failures, with tests for both.
Show a retryable message and Retry CTA on Accept Terms and report/mute/block failures, a terminal message on outdated Terms, and add four-state tests.
Catch a transient preflight rejection and show a retryable message with a
Try again CTA. Show a non-retryable state and disable the purchase tiles
when preflight returns allowed: false. Add screen coverage for happy,
retryable, non-retryable, and empty states.
@iscekic
iscekic requested a review from pandemicsyn August 18, 2026 03:19
@iscekic iscekic self-assigned this Aug 18, 2026
@iscekic
iscekic requested a review from jeanduplessis August 18, 2026 03:19

@kilo-code-bot kilo-code-bot Bot 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.

Inline code review findings

Comment thread apps/web/src/routers/moderation-router.ts
Comment thread apps/web/src/routers/moderation-router.ts Outdated
Comment thread apps/web/src/routers/github-pr-review-router.ts Outdated
Comment thread apps/web/src/lib/kilo-pass/store-subscription-completion.ts Outdated
Comment thread apps/web/src/lib/kilo-pass/store-subscription-completion.ts
Comment thread apps/mobile/src/components/kilo-pass/kilo-pass-subscription-screen.tsx Outdated
Comment thread apps/mobile/src/components/pr-review/composer-inline-error.tsx Outdated
Comment thread apps/mobile/src/lib/pr-review/classify-pr-review-query-state.ts Outdated
Comment thread dev/seed/app/kilo-pass-stripe.ts Outdated
@kilo-code-bot

kilo-code-bot Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Incremental review of e1ace2096 (restore roast as a public review style, plus the main merge): roast is offered again in the web/mobile pickers, prompt generation uses review_style directly, and the merge only renumbered this PR's moderation migration to 0219 without changing its DDL. No new issues in the changed code.

Files Reviewed (10 files)
  • packages/app-shared/src/code-review/enums.ts
  • apps/mobile/src/lib/code-reviewer-config.ts
  • apps/mobile/src/app/(app)/(tabs)/(3_profile)/code-reviewer/[scope]/[platform]/(edit)/style.tsx
  • apps/web/src/components/code-reviews/ReviewConfigForm.tsx
  • apps/web/src/lib/code-reviews/prompts/generate-prompt.ts (+ test)
  • apps/web/src/lib/user/index.ts (+ test; merge-only invite-outbox cleanup from main)
  • packages/db/src/migrations/0219_supreme_firelord.sql
  • packages/db/src/migrations/meta/_journal.json
  • apps/mobile/src/components/pr-review/pr-review-connect-gate.tsx (+ test; merge-only)
  • packages/db/src/schema.ts (merge-only main tables; moderation tables unchanged)
Previous Review Summaries (3 snapshots, latest commit 26fd417)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 26fd417)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Incremental review of 26fd41780 (honest Terms-gate failure + cross-account purchase block): getTermsStatus failures now return unknown instead of accepted, reactive terms_required paths keep a retryable error, and pre-flight writes still proceed so the server remains the enforcer; Kilo Pass tiles are disabled when the IAP owner reports ownedByAnotherAccount. No new issues in the changed code.

Files Reviewed (9 files)
  • apps/mobile/src/components/kilo-pass/kilo-pass-native-iap-owner.tsx
  • apps/mobile/src/components/kilo-pass/kilo-pass-subscription-screen.tsx (+ test)
  • apps/mobile/src/components/pr-review/composer-inline-error.tsx (+ test)
  • apps/mobile/src/components/pr-review/discussion/reply-input.tsx (+ test)
  • apps/mobile/src/components/pr-review/pr-review-comment-composer.tsx
  • apps/mobile/src/components/pr-review/pr-review-submit.tsx

Previous review (commit 9da7842)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Incremental review of the 5 fix commits since the previous review (4af76fc9da7842): all 13 previously reported findings are resolved — the Terms-gate Alerts are now non-cancelable with an outdated outcome surfaced distinctly, purchase recovery has a server-backed SKU fallback and invalidates getPurchasePresentation, the preflight→purchase path has a mounted guard and disables tiles while pending, the post-commit settle is guarded with Sentry capture, CONFLICT markers map to friendly copy, moderation logins are normalized to lowercase with case-insensitive self-target checks, the unused appeal reason field is dropped, and the Stripe seed uses delete-then-insert over both unique keys (safe: all FK references to kilo_pass_subscriptions are cascade/set-null). No new issues found in the changed code; memory-leak focus areas (Alert promise lifecycle, async continuations after unmount) verified clean.

Files Reviewed (23 files)
  • apps/mobile/src/components/agents/report-ai-response.ts
  • apps/mobile/src/components/kilo-pass/kilo-pass-native-iap-owner.tsx
  • apps/mobile/src/components/kilo-pass/kilo-pass-subscription-screen.tsx (+ test)
  • apps/mobile/src/components/pr-review/composer-inline-error.tsx (+ new test)
  • apps/mobile/src/components/pr-review/discussion/comment-row.tsx (+ test)
  • apps/mobile/src/components/pr-review/discussion/pr-review-discussion-list.tsx
  • apps/mobile/src/components/pr-review/discussion/reply-input.tsx
  • apps/mobile/src/lib/code-reviewer-config.ts
  • apps/mobile/src/lib/kilo-pass/subscription-card-state.ts
  • apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.test.tsx
  • apps/mobile/src/lib/pr-review/classify-pr-review-query-state.ts
  • apps/mobile/src/lib/trpc-error.ts (new)
  • apps/web/src/lib/kilo-pass/store-subscription-completion.ts (+ test)
  • apps/web/src/routers/github-pr-review-router.ts
  • apps/web/src/routers/kilo-pass-router.ts (+ test)
  • apps/web/src/routers/moderation-router.ts (+ test)
  • dev/seed/app/kilo-pass-stripe.ts

Review notes: verified no remaining callers of the removed ensureTermsAccepted boolean export or the removed REVIEW_STYLES mobile re-export; no client depends on the raw operation_in_progress message on the Kilo Pass completion path; the kilocode-landing content SEO rules don't apply (no landing/markdown pages changed); no .md files changed, so the markdown-image rule is not triggered.

Previous review (commit 4af76fc)

Status: 13 Issues Found | Recommendation: Address before merge

Executive Summary

The highest-risk issues cluster in the new server-authoritative purchase flow: the mobile IAP owner's recovery SKUs now depend on the StoreKit product fetch (charged-but-uncompleted transactions may never be recovered when that fetch fails), the post-purchase invalidation misses getPurchasePresentation (stale "Subscribe" card against an active subscription), and the web completion path reports failure to the client after the purchase transaction has already committed if the success settle throws; additionally the Terms-gate Alerts can leave a promise suspended forever on Android.

Overview

Severity Count
CRITICAL 0
WARNING 8
SUGGESTION 5
Issue Details (click to expand)

WARNING

File Line Issue
apps/web/src/routers/moderation-router.ts 155 Appeal reason is validated but never persisted
apps/web/src/routers/moderation-router.ts 74 Case-sensitive GitHub login comparison allows self-block bypass and duplicate block/mute rows
apps/web/src/lib/kilo-pass/store-subscription-completion.ts 827 Unguarded success settle after commit surfaces a completed purchase as failure
apps/mobile/src/components/kilo-pass/kilo-pass-native-iap-owner.tsx 178 Recovery SKUs derived from StoreKit fetch; auto-recovery/purchase completion silently skipped when it fails
apps/mobile/src/components/kilo-pass/kilo-pass-native-iap-owner.tsx 184 Post-purchase invalidation misses getPurchasePresentation (stale profile card)
apps/mobile/src/components/pr-review/discussion/reply-input.tsx 89 Terms-gate Alerts cancelable on Android; gate promise can never settle (leak + swallowed action)
apps/mobile/src/components/kilo-pass/kilo-pass-subscription-screen.tsx 214 No mounted guard between preflight await and purchase start; modal dismissal mid-preflight still initiates IAP
dev/seed/app/kilo-pass-stripe.ts 235 Seed upsert conflict target omits the partial provider-subscription unique index; guarded race can still raise unique_violation

SUGGESTION

File Line Issue
apps/web/src/routers/github-pr-review-router.ts 920 Terms-gate docstring claims "any PR write" but only 3 of 11 write mutations are gated
apps/web/src/lib/kilo-pass/store-subscription-completion.ts 546 Internal identifiers operation_in_progress / operation_key_reuse_mismatch surface raw to clients
apps/mobile/src/components/kilo-pass/kilo-pass-subscription-screen.tsx 304 Product tiles not disabled while preflight is in flight (double-tap race)
apps/mobile/src/components/pr-review/composer-inline-error.tsx 71 Boolean gate collapses terminal outdated outcome into dismiss copy
apps/mobile/src/lib/pr-review/classify-pr-review-query-state.ts 107 Dead branch reading shape.data.message (message lives at shape.message)
Files Reviewed (65 files)
  • apps/mobile/src/components/kilo-pass/kilo-pass-native-iap-owner.tsx - 2 issues
  • apps/mobile/src/components/kilo-pass/kilo-pass-subscription-screen.tsx (+ test) - 2 issues
  • apps/mobile/src/components/pr-review/discussion/reply-input.tsx (+ test) - 1 issue
  • apps/mobile/src/components/pr-review/composer-inline-error.tsx - 1 issue
  • apps/mobile/src/lib/pr-review/classify-pr-review-query-state.ts (+ test) - 1 issue
  • apps/web/src/routers/moderation-router.ts (+ test) - 2 issues
  • apps/web/src/routers/github-pr-review-router.ts (+ test) - 1 issue
  • apps/web/src/lib/kilo-pass/store-subscription-completion.ts (+ test) - 2 issues
  • dev/seed/app/kilo-pass-stripe.ts - 1 issue
  • Reviewed with no findings: apps/mobile/src/components/kilo-pass/kilo-pass-ios-manage.ts, kilo-pass-subscription-card.tsx, restore-purchases-button.tsx, apps/mobile/src/lib/kilo-pass/subscription-card-state.ts (+ tests), use-store-kilo-pass-products.ts, use-store-kilo-pass-purchase.ts (+ test), apps/mobile/src/app/(app)/_layout.tsx, apps/mobile/src/components/profile-screen.tsx, apps/mobile/src/components/agents/message-details-sheet.tsx, report-ai-response.ts (+ test), all remaining pr-review components, apps/web/src/lib/kilo-pass/purchase-presentation.ts (+ test), apple-store-notifications.ts (+ test), apps/web/src/lib/user/index.ts (+ test), apps/web/src/lib/code-reviews/prompts/generate-prompt.ts (+ test), apps/web/src/lib/analytics-outbox/operation-ledger.integration.test.ts, apps/web/src/components/code-reviews/ReviewConfigForm.tsx, apps/web/src/routers/kilo-pass-router.ts (+ test), root-router.ts, packages/db (migration 0217 + schema + operation-ledger), packages/app-shared (commerce, moderation, analytics, code-review enums, universal-links tests), packages/trpc/src/mobile.ts, and all changed test files.

Review notes: the DB migration (0217) is additive on new tables with correct index coverage; the kilocode-landing content SEO rules don't apply (no landing/markdown pages changed); no .md files changed, so the markdown-image rule is not triggered. Memory-leak focus areas were the Terms-gate Alert lifecycle and the IAP owner/preflight async continuations.

Fix these issues in Kilo Cloud


Reviewed by grok-4.6 · Input: 73.9K · Output: 15.6K · Cached: 621.2K

Review guidance: REVIEW.md from base branch main

Extract readTrpcErrorField and isTerminalTrpcCode into one shared
module, drop the unreachable status-class branches, and remove the
single-caller ensureTermsAccepted wrapper.
…reason

Compare and store block/mute logins lowercase so case variants cannot
bypass the self-check or create duplicate rows. Drop the appeal reason
from the input contract since it was never persisted. Narrow the Terms
gate comment to the comment-creating mutations.
Catch a settle failure after the purchase commits so it never reports a
false negative, and stop leaking operation_in_progress machine text to
the mobile client.
Fall back to the server product list when the StoreKit fetch is empty so
recovery still runs, invalidate getPurchasePresentation after completion,
and stop the purchase after an unmounted modal or a double preflight.
Make the Terms alerts non-cancelable so the gate promise always settles,
handle the outdated outcome in the composer, and match the server's
lowercase login normalization in self-disable and hidden-user filtering.
Delete any row matching either unique key before a plain insert so the
Stripe webhook race cannot raise unique_violation, and remove the unused
REVIEW_STYLES re-export that failed check-unused.
jest.fn in @jest/globals 30 takes a FunctionLike, not a return type; cast
the requireActual spreads to object and type the mock as a function.
@iscekic iscekic added the human-ready The PR is ready for human review. label Aug 18, 2026
@iscekic iscekic changed the title feat: server-authoritative commerce presentation and moderation feat: server-authoritative commerce presentation and moderation (w4b) Aug 18, 2026
Comment thread apps/web/src/lib/kilo-pass/store-subscription-completion.ts
Comment thread apps/mobile/src/components/pr-review/discussion/reply-input.tsx Outdated
Report an unread Terms status as `unknown` instead of `accepted`. The
reactive `terms_required` path now keeps a retryable error, so a failed
lookup no longer clears a rejected reply, comment, or review. A write is
still attempted on `unknown`; the server enforces the Terms.

Block the Kilo Pass tiles when the App Store account already owns a pass
on another Kilo account. The native IAP owner computes the ownership
preflight, so the route keeps one `useIAP` call site.
@iscekic
iscekic requested a review from pandemicsyn August 18, 2026 15:35
…deration-5698

# Conflicts:
#	packages/db/src/migrations/meta/0217_snapshot.json
#	packages/db/src/migrations/meta/_journal.json
Offer roast again in the web and mobile pickers. Generate roast
guidance, comment format, and summary format for roast configs.
@iscekic
iscekic merged commit df6de56 into main Aug 18, 2026
50 checks passed
@iscekic
iscekic deleted the audit-w4b-commerce-moderation-5698 branch August 18, 2026 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

human-ready The PR is ready for human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants