Appearance
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
| ID | Decision | Evidence |
|---|---|---|
| C-01 | CPM 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-02 | Highest 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-03 | Tracking 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-04 | Sponsor 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-05 | Canonical AuditEvent is the only audit store. Foundation is available; feature producer/history completion remains #68. | #30/#69; schema and audit docs. |
| C-06 | RBAC 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-07 | Confirmed 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-08 | Canonical 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
| ID | Decision and reason | Implementation owner |
|---|---|---|
| A-01 | Shared 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-02 | Exact decimal-string amounts; separate gross/net, pending/held/available/reserved/paid, receipts/commitments/spend. No hidden arithmetic aliases. | Financial contract |
| A-03 | UTC half-open windows, recorded baselines, signed observation deltas, explicit cohort/time basis/coverage. No inferred daily traffic. | A02 and upstream #37 |
| A-04 | Group 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-05 | Preserve 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-06 | Additive v2 reads, backend before each frontend slice; unavailable stays unavailable. Public campaign endpoints get no new private liability/detail fields. | A02–A16 |
| A-07 | Seventeen 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-08 | Existing 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-10 | Roll 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-11 | Dependency 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-12 | Protected 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-14 | Historical 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-15 | A14 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.
| ID | Missing decision or evidence | Who resolves / when | Safe planning behavior |
|---|---|---|---|
| D-01 | Finality 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-02 | Creator 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-03 | Economic 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-04 | Only 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-05 | Can 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-06 | Verified 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-07 | Exact 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-08 | Deployed 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.tsalready adds once. - Recompute past earnings from current rates/caps; infer missing observations on upload dates; clamp financial disagreement to zero.
- Use
paidViewsTotalor 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
AuditEventas 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.