Skip to content

Decisions and unresolved policy ​

Recorded 2026-09-12. Confirmed means supported by landed code or the dated owner record. Selected architecture is this planning session's contract; it is not new product authorization.

Confirmed decisions ​

IDDecisionEvidence
C-01CPM consumes campaign budget; RPM creates gross creator earnings. Keep exact versioned decimal rates and prospective history.Backend rate policy, merged #70, rate domain/history and migration.
C-02Highest numeric RPM wins across all applicable sources; overlapping campaign groups are allowed. Current individual override is per submission.Owner decisions, #61 and rates/history.ts. Older payout precedence/one-group proposals are superseded.
C-03Tracking is independent of moderation and anchored to submission creation; expiry/terminal campaign state still applies.#24, merged #71; lifecycle predicates and reconciliation. #46/#42 wording is stale.
C-04Sponsor link/report is implemented MVP scope, including grant-selected creator gross payout rankings. Keep token scope, redaction, revocation and expiry.#67, backend #74, frontend #28/#30; current report docs. Aggregate-only prose in older cross-repo docs is not the current implementation contract.
C-05Canonical AuditEvent is the only audit store. Foundation is available; feature producer/history completion remains #68.#30/#69; schema and audit docs.
C-06RBAC building blocks landed; most business mappings are pending. Analytics preserves existing protection and delegates mappings to #75/#77 owners.#73; RBAC docs, actionPolicy.ts.
C-07Confirmed post-payment corrections become attributable recovery due; seven-day finality remains tentative.#55/#58 and dated owner clarification. No confirmed collection/offset policy inferred.
C-08Canonical docs stay in the main workspace, without a new docs repository. Preserve unrelated worktree changes.This session's user instructions and Git inspection.

Selected architecture ​

IDDecision and reasonImplementation owner
A-01Shared pure projection contracts plus domain-owned readers; no analytics-owned earning/funding/payout ledger. This avoids competing accounting and allows isolated fixture work now.A01/A03; upstream #31/#37/#53/#54/#59
A-02Exact decimal-string amounts; separate gross/net, pending/held/available/reserved/paid, receipts/commitments/spend. No hidden arithmetic aliases.Financial contract
A-03UTC half-open windows, recorded baselines, signed observation deltas, explicit cohort/time basis/coverage. No inferred daily traffic.A02 and upstream #37
A-04Group cohort measures use membership at fact time. Reconcile de-duplicated union, not the sum of overlapping groups. Keep rate attribution distinct.A09; D-04 only if additive reporting is requested
A-05Preserve recorded legacy amounts in a labelled compatibility adapter with incomplete attribution. Never infer campaign allocation from current rates, names, or proportional views.A03/A05/A10; migration gate M-02
A-06Additive v2 reads, backend before each frontend slice; unavailable stays unavailable. Public campaign endpoints get no new private liability/detail fields.A02–A16
A-07Seventeen narrow analytics PRs, existing prerequisite issues owned separately. One smart schema/financial integrator; cheaper agents implement bounded wiring only after contracts freeze.Execution plan
A-08Existing direct canonical submission-status events may supply a known lower-bound review view only. Validate the exact event contract, keep history partial, and map mixed legacy actor IDs to unknown instead of calling them webUserId; #41/#42/#68 still own reliable production and identity.A07 merged #80
A-09#37's next producer contract is additive MetricObservation: stable unique ScrapeJob source ID; immutable campaign/submission/webUser/platform attribution; required raw views plus nullable raw engagement metrics; source observedAt plus recordedAt; global deterministic sequence; source_observed_at/raw-platform provenance; correction disposition derived against the prior applied raw view in recorded order; restrictive observation FKs block hard deletes. Dual-write normalized raw observations and legacy budget-clamped ViewSnapshot in one reconciliation transaction. Bridge-backed initial submissions write a normalized observation in their creation transaction; legacy/direct initial paths remain partial.#37 prerequisite; A02 reader
A-10Roll out the observation table first, then the dual writer. Old workers/apps remain compatible; old versions write only legacy, new versions dual-write when a durable source exists. Rollback reverts readers/writer flag/application while retaining additive facts; never drop facts. No legacy ViewSnapshot backfill and no fabricated scraped_at.#37/#36 rollout; verification plan
A-11Dependency sequencing split A02 across physical PRs: pure projection #79, #37 producer prerequisite #82, normalized reader #83 stacked on #82, then protected route wiring. The 17 IDs remain acceptance/workstream boundaries rather than an inaccurate physical PR count. Normalized and legacy rows stay separate because dual-written ViewSnapshot rows have no provable source key.A02; execution plan
A-12Protected A02 routes require explicit from, to, and canonical asOf; date-only boundaries normalize in UTC and a date-only to advances to the next midnight. Expose only all_submissions and the explicitly present-current current_accepted cohort until #41/#42 readers land. Creator scope comes only from authenticated identity; staff platform/campaign scope keeps the current ANALYTICS action and a precise future RBAC marker.A02 protected API
A-13#41/#42 reuse canonical AuditEvent/targets with a versioned required transaction writer and stable command identity; no second moderation-event store or speculative index. Existing v1 rows remain partial/unattributed. New staff commands use canonical WebUser.id, expected source status, required denial reason, and one transaction for status, current budget side effects, notification, and event. Tracking remains creation-based. Payout/system writers migrate through bounded follow-ups.#41/#42 prerequisite; A02/A07
A-14Historical status is resolved per submission from committed events ordered by (occurredAt, recordedAt, eventId). The first pre-observation event establishes the baseline; no prior event is unknown. A malformed event, campaign-conflicting event, or discontinuity makes the affected submission unknown. Historical mode never queries or falls back to the current-accepted cohort.A02 PR #96 (d113a4e), stacked on A07 #95
A-15A14 keeps committed-event summaries separate from the current review queue. It uses UTC exclusive-to/campaign/status filters, aggregate/day buckets, lazy submission history, stable asOf pagination, explicit partial/unavailable/unknown actor labels, full moderation reasons, and invalidates analytics after successful moderation. Reviewer filtering and permission mapping remain absent until the backend/RBAC contracts provide them; no current-status inference is allowed.Frontend PR #33 (97f7662), feature/review-analytics-ui → dev; backend #95 (4a08fe3) stacked on #93

Current prerequisite wave record ​

The review-transition rollout is frontend-first: frontend #31 and backend #86/#87 are landed. Backend #88/#89/#90 merged only into stale feature/review-transition-command and are absent from dev; corrected dev-targeted #91/#92/#93 remain open. A07 protected API #95 is stacked on #93, and A02 historical status #96 is stacked on #95. Known #42 producer coverage and disposable database evidence remain incomplete. No active Discord review writer exists because the dashboard owns that path.

The mixed-version rollout order is frontend #31 before backend #87. A rollback retains v2 facts and reverts reader/writer behavior; it does not delete committed audit events. No migration or backfill is scheduled for #86/#87.

Merge-topology correction (2026-09-12): backend dev is d937bfe with #86/#87 landed, and frontend dev is e4b5f5c with #31 landed. Dev-targeted carry-forwards #91 (eaee854 scraper), #92 (9f38877 payout), and #93 (151a80f history) remain OPEN and are not on dev. A07 protected review analytics is in #95 (4a08fe3), stacked on #93; it uses bounded canonical event reads, v1/v2 normalization, partial diagnostics, aggregate-before-pagination and recordedAt ordering, excludes malformed conflicting campaign attribution, and makes no platform filter/current inference/schema/migration change. A02 historical status is active on feature/performance-historical-status, stacked on #95, with frozen cohort scope. Six review suites plus build/diff checks pass, but #41/#42 remain incomplete, #68 remains a normalized accountability blocker, and disposable PostgreSQL transition/history-ordering evidence remains blocked because no loopback _test database is available.

PR #96 (d113a4e) records the A02 historical-status implementation on feature/performance-historical-status, stacked on #95. It validates the per-submission baseline/unknown rules, treats malformed/campaign-conflicting/discontinuous histories as unknown for the affected submission, and removes the current-accepted query from historical mode. Eleven analytics/routes suites, creator-route checks, build and diff check pass. No migration or RBAC map changed. Keep #41/#42 and #91/#92/#93/#95/#96 open; #68 and the missing loopback _test evidence remain blockers.

Frontend A14 is PR #33 (97f7662), open, clean and mergeable on feature/review-analytics-ui, targeting frontend dev, with backend dependencies #95/#93. The UI implementation is review-ready but does not complete A14: focused analytics/command tests, changed lint, TypeScript, production build and diff checks passed; DB/manual/browser evidence remains outstanding. Backend #41/#42/#51/#52/#63/#68 were revalidated OPEN and unassigned on 2026-09-12. Keep #33, #95 and #96 open; no issue is complete from this evidence.

Open decisions / evidence required ​

No product decision blocks the current pure slices. Do not ask the owner to re-approve established scope. Gate only the dependent implementation or rollout.

IDMissing decision or evidenceWho resolves / whenSafe planning behavior
D-01Finality duration, anchor, and any campaign-end ingestion grace. Seven days is tentative; current tracking drops results once ineligible.Owner with #55/#35/#53 owners before finality/cutoff implementation ships.Represent explicit policy IDs/effective times; test parameterized boundaries. Do not start a seven-day countdown from a guessed date.
D-02Creator fee/withholding, threshold/scheduling, affiliate inclusion, and tax policy for Whop credit. Existing legacy 7% fee and referral sweep are behavior, not confirmed new-rail policy.Finance/product and payout owner #56–#59 before dispatch or promises of net eligibility.Separate gross, deductions, net, content/referral classes; no tax/legal ruling in analytics. Older payout options are proposals, not votes.
D-03Economic attribution for growth spanning approval/rate/cap/group changes; initial below-minimum views, regressions, late/out-of-order observations, and freeze/cutoff corrections.Smart #37/#53/#54/#42 owners; seek owner only for unresolved economics before writer rollout.Analytics consumes explicit funded view intervals and adjustment facts; no interpolation or current-state replay. This is an upstream posting decision, not permission to choose rates in a query.
D-04Only if requested: should group tiles be additive allocations instead of overlapping cohorts? Which allocation policy then applies?Product owner before an additive variant; not a blocker to the documented cohort/union view.Show cohort scope and union reconciliation; preserve tied rate sources and ungrouped facts.
D-05Can every legacy financial row be authoritatively mapped, and what launch treatment applies to unallocated/open legacy payments? Older payout docs assume disposable development-only data without current proof.Finance/data owner + #53/#59 migration owners before backfill/cutover.Preserve existing records; prove mappings read-only; return incomplete coverage. No clean-slate deletion or invented opening balance.
D-06Verified provider capability, sandbox identity, transfer semantics and reconciliation evidence for the actual Whop account.Payout owner; Phase 0 register remains an unverified external gate.Analytics tests provider-result fixtures without network movement. Recheck current official provider docs at implementation; old API pins/scopes are not approved here.
D-07Exact business capability attachment and existing owner-guard defect.Separate RBAC owners #75/#77 and frontend #29; before new enforcement/production access rollout.Retain present guards and named TODOs. No speculative Whop proxy permission, alternate ACL, or central mapping edits.
D-08Deployed schema version, historical data quality, worker supervision/leases, and environment performance.Relevant dependency owner / release validator.Code-ready never means production-verified; use explicit disposable DB for mutations/tests. No production database was inspected in this session.

Rejected approaches ​

  • Rebuild rates, sponsor link infrastructure, or RBAC foundation because an old parent issue calls them missing.
  • Treat a summarized GitHub count or issue checklist as proof of hierarchy or code completion.
  • Patch a supposed duplicate addition without changing financial authority; current stats.ts already adds once.
  • Recompute past earnings from current rates/caps; infer missing observations on upload dates; clamp financial disagreement to zero.
  • Use paidViewsTotal or approval as transfer success; retry ambiguous transfers as new operations; multiply campaign totals by joins to attempts/holds/groups.
  • Deduct RPM and paid amounts again from CPM-consumed funding, or equate gross sponsor payouts to creator net credits.
  • Use AuditEvent as a general financial ledger or create another audit store for analytics.
  • Retrofit funding/payout/fraud/RBAC implementations into the analytics PRs, or ship a single large PR.
  • Assume legacy data can be deleted because a September 1 proposal described it as development-only.

Evidence corrections to older documents/issues ​

Native #63 is three issues/two leaves; dependencies are deeper sibling trees, not hidden native children. #29 additionally body-links #68 without a native sub-issue edge. #63/#51 and the sibling handoff's duplicate-addition claim is not reproduced in current code; inspected history also shows a single addition, so no fix commit is invented. Rates are immutable but their consumers still revalue totals. Shares are retained after sponsor reports, so #37's discarded-shares claim is stale. Scraper YouTube support landed. Canonical root docs still describe an admin-only creator dashboard, two repositories/no durable queue, and legacy audit stores; current code differs. Current frontend has Node API tests despite older “no test runner” shorthand. Detailed proof and remaining mismatches are in evidence and system map.