← Back to index | ← 12 Security

What's not done, what's intentionally postponed, what the future-work backlog looks like. Updated 2026-05-19.


Track tail items (small, additive)

C4 — Regression tests for Game/Deal/Realm calibration

The TS-side calibration is tested in scoring-calibration.test.ts. The Python implementations (agent + gateway) have NO unit tests yet. Cross-language equivalence is verified manually today.

Effort: ~2 hours. Add tests/test_scoring_calibration.py in agent + gateway with the same fixture set as the TS tests.

C6 — End-to-end per-format calibration smoke

A scripted full-completion of each format against a known-good Tier-2 fixture, verifying the resulting top-3 archetypes match the expected calibrated outcome.

Today: only Mirror has been manually validated against the n=26 dataset. Game/Deal/Realm should be smoked once with the same input shape.

Effort: ~3 hours. Add to Personas/_tier2_eval.py + run on every agent image build.

D3 — Propagate mq_variant to GA4 events from all formats

Today only the WP Likert page fires mq_variant_exposure + quiz_completed GA4 events with the A/B variant. The Mirror/Game/Deal/Realm flows don't carry this label, so the A/B Tests tab can't show cross-format conversion.

Solution: pass mq_variant cookie (set by mmc-mq-ab-variant.php) through the iframe via URL parameter; fire GA4 from moneyquiz-app on completion.

Effort: ~3 hours.


Larger deferred initiatives

Phase 4 — Likert WP → Postgres migration

Today MMC's Money Quiz (Likert) lives entirely in WP mq_* tables. To bring it on par with the other formats (where session data is in assess_sessions), we'd:

  1. ETL mq_* rows into assess_sessions (read-only mirror initially).
  2. Wire the WP receiver to write to BOTH for 7 days.
  3. Cut reads to Postgres.
  4. Decommission WP-side writes.

Why deferred: it's a big migration with risk of dropping Ilana's customer data. Needs explicit go-ahead + a tested rollback path. C5 calibration bridge (2026-05-19) gets us calibration parity without the migration.

Effort: ~1 week.

Per-tenant Sessions drilldown in CoachPilot dashboard

A new route /[locale]/coach/quiz-sessions/?tenant=<id> mirroring MMC's Quiz Leads UX:

  • Paginated list of sessions
  • Filters by date, format, email, archetype combo
  • Slide-out per-prospect detail
  • Hot/Warm/Cool/Cold likelihood scoring
  • Notes + campaigns + tracking

Today: only /admin/analytics exists (aggregate, not per-tenant; not per-prospect).

Effort: ~2 days. UI work primarily — data is already in assess_sessions.

Federation: unified Ilana view (CoachPilot + MMC)

Once Phase 4 migration completes, build a unified per-coach view that combines:

  • New-format sessions (in assess_sessions)
  • Legacy MMC Money Quiz history (in mq_* via bridge OR after ETL)
  • Booking + campaign data
  • AI cost per coach

Effort: ~3 days after Phase 4.

MMC theme traditional-quiz-engine.jsmoney-quiz-engine.js

C9 phase deferred this. Touches live WP theme + 10+ refs in PHP/JS. Low priority (cosmetic), high risk (live SEO-loaded paths).

Do this at the next planned MMC theme deploy with proper SEO validation + 301 redirect plan.

SG-drop auto-remedy CronJob (Lesson #42)

Today: SG drop after nodepool resize is a manual recovery (repair_worker_sgs.py). A CronJob that periodically verifies worker SGs and re-attaches if missing would make this self-healing.

Effort: ~1 day. Wrap the existing script in a k8s CronJob.


Architecture-level deferrals

tenant_brand snapshot system

framework_configs has snapshots + restore. tenant_brand does NOT. To roll back a brand change today, you have to manually re-enter previous values.

Solution: extend the snapshot table to support target_kind = 'tenant_brand' rows, or add a parallel tenant_brand_snapshots table.

Effort: ~half a day.

Live preview / sandbox publishing

Phase 7 of the original plan. Admin previews a config change in a sandboxed Next.js render before publishing to the public quiz.

Approach: POST /api/v1/assess/framework/{id}/preview returns a draft_id; public quiz URL quiz.thesynergygroup.ch/?config=draft:<id>&tenant=<t> renders against the draft state.

Today: the dashboard live preview (B8, brand only) is a static mockup. Full sandbox preview is harder because it spans every consumer.

Effort: ~2 days.

Per-tenant CSP frame-ancestors generation

Today CSP frame-ancestors is hardcoded in middleware.ts. When a new white-label tenant onboards, we edit middleware + deploy. Could be dynamic: read from tenant_brand.website_url server-side and emit a per-tenant CSP.

Effort: ~half a day. Caveat: need to handle attacker-controlled website_url carefully — only allow https://, validate against a regex.

MFA + IP allowlist on PATCH endpoints

Today: Clerk session OR static bearer is sufficient. No MFA enforced, no IP gating.

Future state: require MFA for admin role; optional IP allowlist per-tenant for service tokens.

Effort: ~1 day for MFA enforcement; ~half a day for IP allowlist (Cloudflare or nginx Ingress).

WAF in front of the gateway

Today: no WAF. Reliance on FastAPI validation + parameterised SQL + Clerk auth.

Future state: Cloudflare or AWS WAF rules for SQL injection / XSS / known attacker IPs.

Effort: ~1 day setup; ongoing tuning.


Removed / dropped scope

Items that were in earlier plans but explicitly removed:

  • Standalone assess.thesynergygroup.ch admin — collapsed into app.coachpilot.ch/portal/tenant/brand.
  • Re-architecting commerce beyond what licensing touches — out of scope; commerce remains in CoachPilot's existing /admin/products/.
  • Building Ikigai/Wheel-of-Life deep editors — Phase 1 added the index page listing them; their existing JSONs continue to serve them. Equivalent deep editors can ship later by reusing the same tab pattern.
  • HSP as a 4th MVP tenant — schema-compatible, but no production rollout planned yet.

Living TODO list

To keep this section actionable, every deferred item should have:

  • A short name
  • A one-sentence problem statement
  • An effort estimate
  • A trigger condition ("when X is true, this becomes urgent")

When picking up a deferred item, first verify the problem statement still applies — the system may have evolved.

When completing a deferred item, move its description out of this file and into the appropriate section (e.g. Phase-4 migration history goes into 04 Config schema §Migrations once it ships).


Open questions for the next planning cycle

  1. Tenant naming consistency: Should we standardise tenant slugs (e.g. always <org> not <product>)? Today: mmc, tsg, coachpilot. Adding hsp later is fine; but if we sign up a customer whose org name conflicts, we'll need a rename plan.

  2. MMC bridge longevity: How long do we keep MMC's WordPress as the canonical analytics surface? If we build the per-tenant Sessions drilldown (above), do we then retire the WP Quiz Leads? Customer adoption + dependency.

  3. Multi-framework future: Today every editor and consumer assumes money_archetypes. Adding Wheel of Life or Ikigai as deeply-configurable frameworks would require revisiting the dashboard's /[locale]/assessments/[framework]/... routing pattern and per-framework defaults.

  4. Cross-tenant collaboration: Could a coach in MMC share an assessment template with a coach in another tenant? Today: no path. Would need a "template" object distinct from framework_configs.

  5. Premium card-game expansion (Deal): the current Deal engine has a premium tier with chat + image generation + couples mode. Documentation of that flow lives elsewhere and isn't yet pulled into this architecture doc. Decide whether to absorb it here or keep it as a separate deal-premium/ doc.


Back to index