RFC Review: Centralized Web Session — Launchpad SDK Integration
Re-rate addendum (2026-07-02, latest review). This review originally scored the RFC's SDK contract (
current_user,switch_user,session.refresh(),(data, error)callback, CDN/sm/sdk.js,_mekari_accountreadability) as "specified" and several related decisions (ADR-2, ADR-4, ADR-6) as "Resolved" or "Partial-pending-external-dependency" — but the SDK source (mekari-account-web-sdkv0.3.0) was never consulted, and the contract it validated was fabricated: the real constructor option iscurrentUser(camelCase), the only statuses arelogged_in/logged_out/server_down(noswitch_user), there is norefresh()API, the callback is single-arg, the package is a bundled git dependency with no CDN, and the SDK does not validateevent.origin. A wrong SDK contract is a correctness blocker, not a pending external dependency — the scores and verdicts below have been re-rated accordingly (R13). Verified, repo-grounded anchors (useAuthCookies.ts,authStore.ts,authenticated.global.ts,ssoCallback.ts,nuxt.config.ts) were correct then and remain correct — they are preserved as-is.
Executive Summary
- Overall Score:
6.0/10(re-rated from 7.5/10 — see addendum) - Rating:
Moderate(re-rated fromStrong) - RFC Type:
frontend - Sub-Type:
new-feature - Assessment Confidence:
Medium(re-rated fromHigh— the SDK source was never consulted, so the original review's confidence in the SDK contract was unfounded) - Applied Caps/Gates:
CNT and DEP downgraded on re-rate (see Scorecard); no hard cap triggered post-correction - Implementation Readiness Verdict:
PARTIAL GO (re-rated) — after the latest review correction, OQ-1 (SDK package) and OQ-3 (canonical iframe path) are RESOLVED: mekari-account-web-sdk v0.3.0 is a real, installable git dependency and the canonical host is sm.mekari.com/current. Chunks 1–5 can now be implemented for real against the corrected contract. The one remaining hard blocker is OQ-2 (a live/staging Session Manager) for true end-to-end verification (chunk 6). - Report Path:
/Users/mekari/Documents/qontak-launchpad-fe/rfc-review-report.md - RFC Author:
Syafrizal Muhammad| Reviewed:2026-06-28| Re-rated:2026-07-02
This RFC remains strong on grounding + scope discipline for everything that
touches the existing Launchpad codebase: every anchor independently
verified against the repo (useAuthCookies.ts:5-7,30, authStore.ts:30,139,142,
authenticated.global.ts:80,109, ssoCallback.ts:6, nuxt.config.ts:89-95,131-149
— all still accurate), scope is file-precise, the execution plan is ordered
with per-chunk acceptance criteria, and patterns are mirrored to real files.
The gap the original review missed: it treated the SDK's own contract
(constructor shape, event names, callback signature, distribution mechanism,
origin-validation behavior) as a settled or merely-pending-external fact,
when in reality it was never checked against the SDK source and several
specifics were wrong. Post-correction (latest review), the real remaining work
is smaller and different than this review originally characterized:
SB-1 (SDK distribution) and the iframe-path ambiguity are resolved; the sole
hard blocker is a live Session Manager to integration-test against (OQ-2),
plus the pre-existing, SDK-independent current_company dependency (OQ-4).
Quick Verdict
Why this RFC can be implemented agentically:
- File-by-file scope, verified anchors, and an ordered chunk plan with acceptance criteria (§2.0, §4.C) — an agent can start chunk 1 with zero clarification.
- Pattern alignment is explicit and honest (§2.0 "Patterns to Follow"; flags that no in-repo iframe/
postMessagepattern exists rather than fabricating one). - Failure branches enumerated (
logged_in/logged_out/server_down+ fail-open, §2.4/§2.9) with a state machine (§2.8). (Re-rated: the original 3-branch reality is simpler than the 4-branch — includingswitch_user— version this review first assessed; see addendum.)
Why this RFC will cause agent guessing or rework (re-rated):
- The original SDK contract (
current_user,switch_user,refresh(), CDN) was fabricated and has since been corrected in the RFC (latest review) — an agent implementing against the pre-correction draft would have built the wrong constructor call, subscribed to non-existent per-status events (silent no-op), and called a method that does not exist. - One cross-SDK dependency remains genuinely open: company-sync endpoint (OQ-4). It is independent of the SDK and was correctly identified as open in the original review.
- The
event.originquestion (OQ-5) is not an open question to "confirm" — it is a resolved-negative finding (the SDK does not validate origin) that must be escalated to the SDK owners as an infosec item, not tracked as a pending decision.
PRD → RFC Traceability Matrix
Standard format (PRD exists — Confluence PT/48962437340, not fetchable at review time; assessed via §1.4 self-declared coverage)
| PRD Element | RFC Section | Coverage |
|---|---|---|
| Overview / issue (stale session, no SSO-logout observation) | §1.1 | Full |
| SC1 — SDK reports status across products | §1.2, §2.4 | Full (FE reacts to the 3 real SDK statuses — re-rated from "4 events", see addendum) |
| SC2 — 2h idle expiry → logout | §1.2, §2.4 logged_out | Full |
| SC3 — periodic session re-validation | §1.2, §4.C ch.5 | Full — achieved via the constructor's interval option; the original "activity refreshes session / session.refresh()" framing did not match the real SDK and has been corrected (OQ-6 moot) |
| SC4 — 1 account → multiple sessions | §1.2, §1.6 | Full (correctly scoped n/a — BE-owned) |
| Out of scope | §1.3 | Full |
| Dependencies (SDK, Session Manager, Redis) | §2.2, §5 OQ-2/OQ-4 | Partial — SDK distribution and iframe path now resolved; Session Manager staging + company-sync endpoint remain genuinely open |
| How to use SDK / events | §2.4 | Full (corrected contract) |
Local storage msli / _mekari_account | §2.6 | Full — corrected to reflect the SDK owns msli internally; Launchpad has no consumer-side fallback logic to build |
| FE Web Session Flow | §1.4 | Mapped n/a — Launchpad is OAuth2 (ADR-3) |
| OAuth2 code flow | §2.7 | Full |
| User logout / switch account | §2.7, §2.9 | Full — an SSO account switch is delivered as logged_out (no distinct switch_user status exists) |
current_company endpoint | ADR-5 / OQ-4 | Partial — reuse vs PRD endpoint unresolved (genuinely open, independent of the SDK) |
| Database model (no change) | §2.3 | Full |
| HA & Security | §3 | Full (FE-side); the event.origin item is now recorded as a resolved-negative security finding, not an open question |
| Rollout plan | §4 | Full (step 4; step 5 deferred) |
Summary: ~14 of 16 PRD elements fully covered, 2 partial (dependency
confirmation, current_company), 0 silently missing. No RFC decision lacks a
PRD driver (no scope creep). PRD body not independently fetched → PRT scored
on the RFC's self-declared §1.4 matrix, which is structurally complete;
confidence on forward-coverage accuracy is medium for that reason and
because the SDK-contract-specific claims were not independently verified
against SDK source in the original pass.
Scorecard
Frontend Scorecard (11 categories)
| Category | Score | Evidence-Based Rationale |
|---|---|---|
| PRT — PRD Traceability | 7.5 | §1.4 maps every PRD section bidirectionally; 2 partials remain (dependency confirmation, current-company). PRD body not fetchable → forward-coverage taken on trust. Unchanged from original — this dimension was not affected by the SDK-contract error. |
| TDC — Technical Decisions | 6.5 (re-rated from 7.5) | 6 ADRs in §1.5 each name a chosen option grounded in real files, but ADR-2, ADR-4, and ADR-6 as originally reviewed encoded a fabricated SDK constructor/event contract and were rated "Resolved"/"Partial" as if only availability were pending — the shape of the decision was itself wrong. Now corrected in the RFC; the review's original pass should have caught this by reading the SDK source. |
| CNT — Contract Specificity | 4.5 (re-rated from 7.0) | SDK event table (§2.4), state surface (§2.5), storage keys (§2.6) were specified in detail — but every field was wrong (current_user vs currentUser, 4 events vs 3, (data, error) vs (data), consumer-owned msli vs SDK-owned). A contract this specific but this wrong is worse for an agent than an honestly-vague one, because it reads as authoritative. This is the primary re-rate driver (R13). |
| SCB — Scope Boundaries | 9.0 | Repo map + named new/modified files (§2.0), explicit non-goals (§1.3), deferred cross-repo work tagged (§1.6). Agent can produce file-by-file plan directly. Unaffected by the SDK-contract error. |
| DEP — Dependencies | 5.0 (re-rated from 6.0) | All deps named with status, but the review characterized @mekari/sdk as merely "absent, needs to be published" (a status/availability problem) when the real issue was a fabricated package name and contract — the actual package (mekari-account-web-sdk, git dependency, no CDN) was never checked. Post-correction, DEP is lighter than originally scoped (no CDN/publish step needed at all) but the review's own diligence gap here is scored down. |
| FMC — Failure Mode Coverage | 6.5 (re-rated from 7.0) | server_down fail-open (§2.7, §2.9) and logged_out paths now correctly reflect a 3-state SDK (no switch_user); race condition originally flagged at OQ-7 is now understood to be moot (the SDK never exposes a comparison user id, so there is no race to detect). Error-message catalog still only partial — 2 toast strings, no full SDK-error→copy/i18n map. |
| NFS — Non-Functional Specificity | 6.5 | CSP/frame-ancestors/token/OWASP table (§3), now naming the correct host (sm.mekari.com) and control type (frame-src, not script-src). Perf budget correctly BE-owned. a11y of toasts unaddressed; hardcoded copy not i18n keys. Unaffected in kind by the SDK-contract error, only in host/mechanism detail (corrected). |
| TPS — Test Plan Specificity | 7.5 (re-rated from 8.0) | Per-chunk acceptance, TDD red-first, named branch assertions (§4.C ch.3 now asserts 3 real SDK statuses; ch.4 asserts cookie clear only — msli clearing removed from Launchpad's responsibility; ch.5 asserts interval-driven re-check, not a throttled refresh()). Score trimmed slightly because the original acceptance criteria (switch_user branch, refresh-throttle fake-timer test) tested behavior that does not exist in the real SDK. |
| ROL — Rollout & Rollback | 8.5 | Flag contract default-off (§4.A, verified surface nuxt.config.ts:148), ordered rollback recipe (§4.D), stages + go/no-go (§4.E), config contract present (corrected to the real two-file configs/{development,production}.json set — see Decision 1). |
| OBS — Observability | 7.0 | mixpanel event counts + server_down rate alert (§3). Exact event names/properties not enumerated. Unaffected by the SDK-contract error. |
| CPA — Pattern Alignment | 9.0 | Mirrors real patterns: Pinia setup-store (authStore.ts:30), plugin init (pixel.ts), logout redirect (authenticated.global.ts:109). Honestly flags no in-repo iframe pattern. Unaffected by the SDK-contract error. |
Re-rate note: the three dimensions most directly touching the fabricated SDK contract (CNT, DEP, TDC) moved down; SCB, CPA, OBS, PRT — which assess the RFC's use of the real, existing Launchpad codebase rather than the SDK itself — are unchanged, because those anchors were genuinely verified and remain correct. No hard score cap is triggered post-correction; the verdict is a readiness/confidence adjustment, not a rejection.
Decision Closure Assessment
Decision Index
| # | Decision | Status | Critical Gaps |
|---|---|---|---|
| 1 | Feature-flag mechanism (ADR-1) | Resolved | Corrected: configs/{development,production}.json — this repo has no configs/local.json (see Decision 1 below) |
| 2 | Where SDK loads (ADR-2) | Resolved (re-rated from Partial) | SDK distribution (OQ-1) and constructor shape are now resolved — mekari-account-web-sdk v0.3.0, currentUser option |
| 3 | Which PRD flow applies (ADR-3) | Resolved | none — OAuth2 code flow verified ssoCallback.ts:6 |
| 4 | currentUser source (ADR-4) | Resolved (re-rated from Partial) | OQ-7 (stale-token pre-detection of a switch_user event) is moot — no such event exists to pre-detect |
| 5 | Current-company sync (ADR-5) | Dangling | endpoint choice unresolved (OQ-4) — genuinely open, independent of the SDK |
| 6 | Event→action routing (ADR-6) | Resolved (callback signature corrected) | Single session.on("event", (data) => ...) subscription switching on data.status; per-status subscriptions and the 2-arg (data, error) callback were wrong and are corrected |
| 7 | Periodic re-validation mechanism | Resolved (re-rated from Dangling "refresh throttle window") | No refresh() API exists; achieved via constructor interval (recommended 5*60*1000ms). OQ-6 moot. |
| 8 | Iframe canonical path | Resolved (re-rated from Dangling) | sm.mekari.com/current confirmed from SDK source (session.ts default sessionUrl). OQ-3 resolved. |
Aggregate (re-rated): 6 Resolved, 1 Dangling (current-company, OQ-4), 1 Resolved-with-correction (feature flag file list). Previously: 3 Resolved, 2 Partial, 3 Dangling — the swing is almost entirely the SDK-contract correction, not new external information becoming available independently.
Decision: 1 — Feature-flag mechanism (ADR-1)
Status: Resolved (corrected)
- What was decided: New
centralized_sessionkey inconfigs/{development,production}.json→runtimeConfig.public, defaultfalse. - Correction: The original review endorsed
configs/{local,development,production}.json. This repo has noconfigs/local.json— onlydevelopment.jsonandproduction.jsonexist. The original review's grounding table cited "local.json" without independently confirming the file exists; it does not. Corrected here and in the RFC. - Alternatives considered: Env-var-only / remote config rejected — "no env-var-only or remote-config system exists" (§4.A). Grounded.
- Grounding:
nuxt.config.ts:148env spread (verified —...CONFIGENVIRONMENT.env);configs/{development,production}.json. - Interface:
runtimeConfig.public.centralized_session: boolean = false. Fully specified. - Failure handling: Flag off → SDK not constructed, zero behavior change (chunk 1 acceptance).
- Challenge: Scale n/a; reversibility trivial (flip + redeploy); no conflicts; agent-implementable now.
Decision: 2 — Where SDK loads (ADR-2)
Status: Resolved (re-rated from Partial)
- What was decided: New
~/plugins/centralized-session.tsregistered afterauth.ts(verified ordernuxt.config.ts:89-95). - Alternatives: Init in middleware vs plugin — plugin chosen per
pixel.ts/mixpanel.tsprecedent. Grounded. - Grounding: Strong; mirrors
plugins/pixel.ts. - Interface:
new Session({ currentUser, interval })— the real SDK module (mekari-account-web-sdkv0.3.0) is a git dependency and its constructor/return type are now known and typeable. - Failure handling: Flag-gated; the SDK is bundled (no
<script>load-failure mode to handle — that concern does not exist for a git dependency).server_downremains the only degraded-mode event path. - Singleton note (R11):
Sessionis a singleton — a 2ndnew Session()call returns the 1st instance and ignores new options. Teardown must callsession.destroy()(which resets the singleton);off()alone leaves the iframe and window listener attached. This is a one-line implementation note, not an elaborate idempotency-guard design — the original review did not need (and does not need) a bespoke double-init guard analysis for this. - Challenge: None remaining beyond standard PR review; no longer blocked.
Decision: 5 — Current-company sync (ADR-5)
Status: Dangling
- What was decided: Reuse
/users/me(authStore.fetchAuthLaunchpad) — verified atauthStore.ts:80-88— unless OQ-4 forces PRD's/v1.1/users/me/current_company. - Alternatives: PRD endpoint named but not chosen.
- Interface: If reuse, fully specified; if new endpoint, request/response unspecified.
- Gaps: Branch unresolved → agent cannot know which call to wire for the
logged_incompany-resync step. This is a genuine BE/SSO dependency — the SDK exposes no company data at all, so it is correctly decoupled from the SDK contract (R10) and was not affected by the re-rate. - Suggested resolution: Default to
/users/mereuse (already returnscompany_id,authStore.ts:88); only adoptcurrent_companyif SSO requires a fresh server-side switch confirmation. Confirm with SSO BE. - Open question: OQ-4.
Decision: 7 — Periodic re-validation mechanism
Status: Resolved (re-rated from Dangling "refresh throttle window")
- What was decided (corrected): There is no
session.refresh()API in the real SDK. Periodic re-validation is achieved by passinginterval(ms, ≥1000; recommended5*60*1000per PRD constraint 6.9) to theSessionconstructor — the SDK reloads its hidden iframe on that fixed timer. - Gaps: None remaining — chunk 5 acceptance ("
Sessionconstructed once withintervalset; fake timers assert periodic iframe reload") is deterministic without inventing a throttle value. - Open question: OQ-6 — moot.
Decision: 8 — Iframe canonical path
Status: Resolved (re-rated from Dangling)
- What was decided (corrected):
sm.mekari.com/current— the SDK's defaultsessionUrl(session.ts). Notaccount.mekari.com/sm/current, not/sessionmanager/current. - Gaps: None remaining for the path itself. CSP
frame-src/child-srcandserver_down/checkTimeouttiming can now be wired deterministically against this host. - Open question: OQ-3 — resolved.
(ADR-3 assessed Resolved as indexed, unaffected by the re-rate; all grounded in verified anchors.)
UI State Audit
This RFC adds session-lifecycle logic, not data-driven view components. UI surface = redirects + one toast pattern (re-rated: the original "user has changed"
switch_usertoast surface has been removed — see Pattern Alignment / Data Flow below; no dedicated account-switch UI exists because the SDK cannot distinguish a switch from a logout).
| Component/Surface | Loading | Empty | Error | Partial | Success | Assessment |
|---|---|---|---|---|---|---|
Session-expired toast/redirect (logged_out/server_down) | n/a | n/a | defined (sign-out on logged_out; fail-open, no redirect, on server_down) | n/a | defined | 2/2 applicable — simplified from the original 3/3 count, which double-counted a switch_user surface that does not exist in the real SDK |
Summary: No multi-state data components introduced. Session surfaces have
their applicable states defined. Gap: exact toast copy is hardcoded, not
i18n — see Accessibility/NFS. Re-rate: the original "'User has changed'
notice" row is removed — it modeled a switch_user event/toast that the real
SDK does not emit.
Performance Budget Check
| Metric | Target | Baseline | Source | Assessment |
|---|---|---|---|---|
sm.mekari.com/current p95 | <100ms | — | PRD §3 | BE-owned — correctly out of FE scope (§3) |
| SDK script weight | not stated | — | — | Re-rated: the SDK is a bundled git dependency, not an external <script> — there is no separate network-load-strategy (async/defer) concern to pin. The only budget item is the bundle-size delta of mekari-account-web-sdk inside the Launchpad build, which remains unestimated (minor gap). |
No FE Core Web Vitals budget — acceptable for a session-logic feature.
Accessibility Review
| Aspect | Specified? | Details | Assessment |
|---|---|---|---|
| Toast announcement (aria-live) | no | reuses @mekari/pixel3 toast.notify | rely on Pixel3 defaults — acceptable, unverified |
| Focus after redirect | no | full-page redirect on logout (incl. account switch) | acceptable (browser nav resets focus) |
| i18n of copy | n/a (re-rated) | the original "user has changed" hardcoded copy was tied to the now-removed switch_user surface; no equivalent copy remains to i18n-key | gap closed by removal, not by fixing i18n — flag if a future logout-specific message is added |
| Motion/contrast | n/a | no new visual surfaces | n/a |
Pattern Alignment Check
| Pattern | RFC Approach | Assessment |
|---|---|---|
| State management (Pinia setup store) | follows authStore.ts:30 | Aligned |
| 3rd-party SDK init | follows plugins/pixel.ts/mixpanel.ts, now against the real mekari-account-web-sdk git dependency | Aligned |
| Logout redirect | reuses authenticated.global.ts:109 (verified) | Aligned |
| Cookie access | reuses useAuthCookies.ts:9-30 (verified); no new _mekari_account read helper needed (that cookie remains cross-domain-unreadable and SDK-internal) | Aligned |
iframe/postMessage | none in repo — explicitly flagged, SDK-encapsulated (the SDK owns its own window message listener; Launchpad never installs one) | Honest; no parallel system introduced |
| Analytics | extends mixpanel.ts event counts | Preserved/extended |
Data Flow Trace
Flow: SSO logout detected on Launchpad
SDK emits event {status:'logged_out'}
→ plugins/centralized-session.ts → useCentralizedSession handler
→ reuse authenticated.global.ts:109 redirect → window.location.replace(CHATPANEL_URL/logout)
→ (no /users/me call; terminal redirect)
Gap: none — terminal path is grounded. Re-rated: this same flow now
also covers an SSO account switch, since the SDK reports both as
logged_out and never exposes the incoming user's ssoId.
Flow: SSO account switch (re-rated — no longer a distinct switch_user flow)
SDK emits event {status:'logged_out'} (the SDK cannot distinguish a switch from a plain logout)
→ same handler as plain logout above → sign-out flow
→ any post-re-login company re-sync happens naturally via the normal
OAuth2 re-auth + /users/me resync (authStore.ts:80), NOT as an
SDK-driven "switch_user" branch
Original gaps now moot: the original review's "order of resetAuth vs
cookie clear vs msli removal" and "stale current_user may not yield
switch_user" (OQ-7) concerns no longer apply — there is no switch_user
branch to order or race-check. msli clearing is also removed from
Launchpad's responsibility entirely (R7) — it is SDK-internal.
Agentic Readiness Deep-Dive
Vague Word / Deferred-Value Audit
| # | Word/Phrase | Location | Impact | Concrete Replacement |
|---|---|---|---|---|
| 1 | §1.2 SC3, §4.C ch.5 | Resolved — replaced with the constructor's interval option, recommended 5*60*1000ms | n/a | |
| 2 | "reuse /users/me unless OQ-4 forces new endpoint" | ADR-5 | agent guesses which call | decide endpoint pre-chunk-3 — still open, genuine BE dependency |
| 3 | "cache max 5s" (iframe render) | §2.7 | BE-owned; FE retry timing depends on the (now-resolved) checkTimeout/interval values | resolved — canonical host + timing constants now known from SDK source |
Total deferred-value blockers in spec sections: 1 (down from 3 — two were artifacts of the fabricated SDK contract, not real ambiguity).
Dangling Alternatives
| # | Alternatives | Location | Impact |
|---|---|---|---|
| 1 | /sm/current vs /sessionmanager/current | §2.7 / OQ-3 | Resolved — sm.mekari.com/current per SDK source |
| 2 | /users/me vs /v1.1/users/me/current_company | ADR-5 / OQ-4 | wrong endpoint wired — still open |
Total dangling alternatives: 1 (down from 2).
Task Decomposition Assessment
| Chunk | Acceptance Criteria | Assessment |
|---|---|---|
| 1 Feature flag | runtimeConfig.public.centralized_session===false; flag-off renders unchanged | verifiable — executable now |
| 2 SDK loader | Real mekari-account-web-sdk Session instantiated once when flag on, with currentUser + interval | verifiable and now executable for real (re-rated — was "blocked OQ-1") |
| 3 Event router | spec asserts all 3 real statuses (logged_in/logged_out/server_down) | verifiable — executable now |
| 4 Sign-out cleanup wiring | cookies cleared before redirect; no msli touch | verifiable |
| 5 Periodic re-validation + fail-open | interval-driven iframe reload asserted via fake timers; server_down → no destructive action | verifiable — re-rated: the original "refresh() ≤1/window" acceptance criterion tested an API that does not exist and has been replaced |
| 6 pilot enable | metrics emit; server_down < threshold | verifiable post-deploy; still gated on OQ-2 (live Session Manager) for a true end-to-end signal |
Strengths
- Verified grounding (§2.0 + Source Verification table): every cited repo anchor checked accurate against the codebase (
authStore.ts:139,142,authenticated.global.ts:80,109,useAuthCookies.ts:5-7,30,nuxt.config.ts:89-95,148). An agent can trust the map. This strength stands unchanged post-correction. - Scope discipline (§1.3, §1.6, §2.0 repo map): in/out scope file-precise; cross-repo (CRM/Hub/HubChat) explicitly deferred — no surprise blast radius.
- Rollout/rollback (§4.A–§4.E): default-off flag, ordered rollback recipe, FE-only safety (no DB coupling), pre-merge command gates from real
package.json. - Post-correction, the RFC is easier to execute than originally assessed: no CDN/publish step, no throttle value to invent, no
switch_userrace to reason about — the SDK's real API surface is smaller than what was originally reviewed.
Biggest Gaps (re-rated)
- The original review's own methodology gap: it scored a fabricated SDK contract (
current_user,switch_user,refresh(), CDN, 2-arg callback) as specified/pending-dependency rather than flagging that the SDK source had not been consulted at all. This is now corrected in the RFC and reflected in the Scorecard re-rate (CNT/DEP/TDC). - OQ-2 (§5): no Session Manager in any FE repo → chunk 6 (and any true end-to-end assertion) cannot run or integration-test yet. This is now the sole hard execution blocker.
- OQ-4 (ADR-5): company-sync endpoint choice remains genuinely unresolved and is independent of the SDK — unaffected by this re-rate.
Priority Actions (re-rated)
- OQ-2 — Stand up a staging
sm.mekari.com/currentfor integration testing. This is now the single upstream blocker; everything else (chunks 1–5) can be built and unit-tested against the real, corrected SDK contract today. - OQ-4 / ADR-5 — Decide
/users/mereuse vscurrent_company; default to reuse (authStore.ts:88already returnscompany_id) unless SSO mandates otherwise. - OQ-5 (security finding) — Escalate to the SDK owners (Account & Launchpad) and infosec that the SDK does not validate
event.origin; this cannot be fixed from the Launchpad side and should not be tracked as a "confirm" question. - Add an i18n key for any future logout-specific copy (the original "user has changed" string was tied to the now-removed
switch_usersurface).
Implementation Readiness Checklist
Unblocked (agent can proceed)
- PRD → RFC traceability matrix (§1.4)
- Pattern alignment verified (§2.0)
- Rollout plan with flag + rollback (§4)
- Task decomposition with per-chunk acceptance (§4.C)
- Chunks 1–5 fully specified against the corrected, real SDK contract (re-rated — previously only chunk 1 + mocked chunk 3)
- All UI/redirect failure surfaces defined (§2.4/§2.9)
- OQ-1 — SDK package availability — RESOLVED
- OQ-3 — canonical iframe path — RESOLVED
- OQ-6 — refresh/periodic-revalidation mechanism — MOOT/RESOLVED
- OQ-7 — stale-token switch_user race — MOOT
Blocked (must fix first)
- OQ-2 — live/staging Session Manager
sm.mekari.com/currentfor integration test (sole remaining hard blocker) - OQ-4 — company-sync endpoint choice (blocks chunk 3/4 resync only, not coding)
Verdict: 1 hard blocker remains (OQ-2); OQ-4 blocks a single assertion, not the chunk plan. — FE specification is strong and, post-correction, its dependency surface is materially smaller than the original review assessed.
Task Manifest
| Order | Chunk | Files to Create/Modify | Acceptance Criteria | Dependencies |
|---|---|---|---|---|
| 1 | Feature flag | configs/{development,production}.json, nuxt.config.ts | runtimeConfig.public.centralized_session===false; flag-off path unchanged (spec) | None |
| 2 | Event router | app/common/composables/useCentralizedSession.ts + .spec.ts | spec asserts all 3 real SDK statuses route correctly against a mocked Session interface | Chunk 1 |
| 3 | SDK loader plugin | package.json (add mekari-account-web-sdk git dependency), app/plugins/centralized-session.ts, nuxt.config.ts:89-95 | Session instantiated once with currentUser + interval when flag on; not instantiated when off | Chunk 1 |
| 4 | Sign-out cleanup wiring | useCentralizedSession.ts, reuse authStore.resetAuth (authStore.ts:142), authenticated.global.ts:109 | spec: token cookies cleared before the sign-out redirect (no msli touch — SDK-owned) | Chunk 2 |
| 5 | Periodic re-validation + fail-open | app/plugins/centralized-session.ts, useCentralizedSession.ts | interval-driven re-check asserted via fake timers; server_down → no destructive action | Chunk 2 |
| 6 | Pilot enable | configs/production.json | post-deploy SDK metrics emit; server_down < threshold | Chunks 2–5; OQ-2 |
Re-rate note: the original manifest's Chunk 4 was titled "switch_user /
logout wiring" and asserted a switch_user handler + toast. That chunk is
struck — there is no switch_user event to wire — and its logout-only
portion is preserved as the current Chunk 4. RFC specifies this decomposition
(§4.C) — manifest verified against it; anchors confirmed real.
Dangling Decisions Log
| # | Decision | Location | Owner | Deadline |
|---|---|---|---|---|
| 1 | §2.7 / OQ-3 | — | Resolved — sm.mekari.com/current | |
| 2 | Company-sync endpoint (/users/me vs current_company) | ADR-5 / OQ-4 | AL + SSO BE | pre-chunk-3 |
| 3 | session.refresh() throttle window | §1.6 / OQ-6 | — | Moot — no refresh() API; use constructor interval |
| 4 | SDK event.origin enforcement guarantee | §3 / OQ-5 | SSO BE / infosec | Resolved-negative — SDK does not validate origin; escalate as a security finding, not a pending decision |
Open Questions
| # | Question | Category | Severity |
|---|---|---|---|
| 1 | @mekari/sdk package name/version + CDN URL availability? | DEP | Resolved — mekari-account-web-sdk v0.3.0, git dependency, no CDN |
| 2 | Staging sm.mekari.com/current endpoint to integration-test the postMessage contract? | DEP | Blocking |
| 3 | CNT | Resolved — sm.mekari.com/current | |
| 4 | Reuse /users/me or adopt /v1.1/users/me/current_company? | TDC | Important |
| 5 | event.origin? | SAS/NFS | Resolved = NO — recorded as an open infosec finding (not a pending confirm) |
| 6 | session.refresh() throttle interval? | CNT | Moot — no refresh() API |
| 7 | current_user still yields switch_user? | FMC | Moot — no switch_user status exists |
Evidence Notes
app/common/composables/useAuthCookies.ts:5-7,30— confirmed token keys +launchpad.sso_id; validates ADR-4currentUsersource. Lifted CNT/SCB. (anchor unaffected by re-rate — kept as-is)app/middleware/authenticated.global.ts:80,109— confirmed OAuth2 redirect shape + logout redirect target; validates ADR-3 and thelogged_outreuse path. Lifted TDC/FMC. (kept as-is)app/common/store/authStore.ts:30,88,139,142— confirmed Pinia setup store,/users/mecompany source,resetAuth; validates ADR-5/ADR-6 + CPA. (kept as-is)package.json:63-77— confirmedmekari-account-web-sdk(previously mis-cited as@mekari/sdk) is not yet added as a dependency; re-rated: the original review treated this as "the central DEP blocker" requiring an external publish. It is in fact a resolvable, install-now git dependency — the review's characterization of it as an unpublished/CDN-pending package was the fabricated part, not the "absent from package.json" observation (which was itself correct).nuxt.config.ts:89-95,148— confirmed plugin order +runtimeConfigenv spread; validates ADR-1/ADR-2. Lifted ROL. (kept as-is, except theconfigs/local.jsonreference removed — that file does not exist in this repo)- PRD (Confluence PT/48962437340) — not fetchable at review; PRT scored on §1.4 self-declared matrix → confidence on forward coverage is medium, overall confidence Medium (re-rated down from High) given the SDK-contract diligence gap.