RFC Review: Centralized Web Session — CRM Frontend Integration of @mekari/sdk Session
Executive Summary
- Overall Score:
6.5/10 - Rating:
Needs Work - RFC Type:
frontend - Sub-Type:
enhancement - Assessment Confidence:
High - Applied Caps/Gates:
CNT = 5.5 (below 7.0 → no soft cap triggered; CNT < 5.0 cap NOT applied). No hard cap fired; overall held to 6.5 by judgment — 4 critical blockers prevent end-to-end agentic build. - Implementation Readiness Verdict:
HOLD — resolve Q1–Q4 (critical) before full agent execution; chunks 2, 3, 6 are independently executable now - Report Path:
/Users/mekari/Documents/crm/rfc-review-report.md - RFC Author:
Qontak CRM Frontend| Reviewed:2026-06-28
This RFC is among the most disciplined integration specs reviewable: it carries a full Repo Reading Guide (§2.0), a Source Verification table that distinguishes verified anchors from UNVERIFIED unknowns, seven ADR blocks, a per-story change map, and a numbered rollback recipe. An AI agent could execute chunks 2, 3, and 6 (msli helper, plugin scaffold + toggle gate, observability) today without asking a question. It cannot complete the integration's core purpose — constructing new Session({ current_user: user_sso_id }) — because the source of user_sso_id in CRM's /users/me response is explicitly UNVERIFIED (§2.0 Source Verification, Q2). The biggest strength is anti-hallucination honesty: every unknown is flagged rather than invented. The biggest gap is that three of the seven decisions (D5 switch_user, D7 current_company, plus the D1 dependency availability) terminate in critical open questions, so the RFC author correctly self-marks "Ready for agent execution: no" (§7). The one thing that must change before agentic execution: confirm user_sso_id's field path in /users/me (Q2) — without it the SDK input is a guess and every event handler compares against an unknown.
Quick Verdict
Why this RFC can be implemented agentically:
- Scope, file list, plugin registration point (
nuxt.config.js:58), and reuse targets (store/user.js:userLogout) are pinned to verified line numbers. - Failure paths (server_down fallback, fail-closed toggle read, switch_user interim) are drawn as sequence + state diagrams with explicit branches.
- Each execution chunk (§4.C) has an assertable acceptance criterion tied to a real
package.jsonscript.
Why this RFC will cause agent guessing or rework:
- The SDK constructor input
user_sso_idhas no verified source — agent would guess a field on$auth.user(CNT, Q2). switch_userresolves only to an "interim sign-out" because the real SSO-autologin contract is unknown for CRM's token model (TDC, Q1).- Exact
centralized_sessioncode string and@mekari/sdkregistry path are placeholders (DEP, Q3/Q6).
PRD → RFC Traceability Matrix
PRD exists (Confluence driver RFC, linked §1.5). Standard format applies.
| PRD Element | RFC Section | Coverage |
|---|---|---|
| Overview / known stale-session issues | §1.1 | Full — CRM-relevant cases mapped (logout, switch account) |
| Success Criteria | §1.2 | Partial — FE-slice subset; SDK/Redis criteria correctly excluded as A&L-owned |
| Out of Scope | §1.3 | Full — inherited + CRM additions |
| Dependencies (SDK, SM, Redis) | §2.0 / §5 | Partial — SDK consumed; SM+Redis flagged as A&L deps (Q6 registry open) |
| How to use the SDK | §2.4 / §2.2 | Full — mapped to plugin + session.on() |
Local Storage (msli) | §2.2 / §2.3 | Full — new helper, 2h window |
Cookies (_mekari_account) | §2.0 / §2.3 | Full — read-only contract documented |
| SDK event contract (4 events) | §2.4 Inbound | Full — all four handled with payload + CRM action |
| FE Web Session Flow | §2.5 / §5 Q1 | Missing — CRM is token-based, mapping unresolved (Q1 critical) |
| OAuth2 Authz-Code Flow | §5 Q1 | Missing — CRM does not use authz-code; explicitly unresolved |
| User Switch Account | §2.6 / §5 Q1 | Partial — interim sign-out only; seamless switch deferred (ADR-5) |
| current_company sync | §2 ADR-7 / §5 Q4 | Missing — deferred, no CRM endpoint exists (Q4 critical) |
| Database Model (no changes) | §2.3 | Full — confirmed no DDL |
| HA & Security | §3 | Partial — FE CSP/origin; backend p95/RPS A&L-owned |
| Rollout Plan | §4 | Full — CRM = step 5 post-Launchpad |
Summary: ~11 of 17 mapped PRD elements fully covered, 3 partial, 3 missing (all 3 missing are the critical-tagged token-model/switch/current_company items). No RFC decision lacks PRD justification — no scope creep detected.
Scorecard
Frontend Scorecard (11 categories)
| Category | Score | Evidence-Based Rationale |
|---|---|---|
| PRT — PRD Traceability | 7.5 | Detail 1.A gives a full bidirectional PRD-section coverage matrix; reverse mapping clean (no unjustified additions). Docked for 3 missing mappings (Web Session Flow, OAuth2 flow, current_company) that are the integration's hard parts. |
| TDC — Technical Decisions | 6.0 | 7 ADRs with options + rationale + reversibility (strong). But D5 (switch_user) is "interim" pending Q1, D7 (current_company) deferred pending Q4 — two decisions resolved only as "defer/interim," not closed. Agent cannot build the seamless paths. |
| CNT — Contract Specificity | 5.5 | SDK event payloads tabulated (§2.4 Inbound); msli/cookie artifacts shaped (§2.3); data-fetching/refresh strategy stated (throttled session.refresh() + router afterEach, ADR-3). But the constructor input user_sso_id source is UNVERIFIED (§2.0, Q2) — the single most important contract is a hole. |
| SCB — Scope Boundaries | 8.5 | Repo Map (§2.0) names every file with create/modify/read tags; non-goals explicit (§1.3); "CRM frontend repository only" scope guard at top; per-story change map (Detail 1.C) lists exact paths. Agent can produce file-by-file plan. |
| DEP — Dependencies | 6.5 | A&L deps (SM, Redis, Kong) named and bounded; reused CRM endpoints verified with line numbers. Docked: @mekari/sdk registry availability unconfirmed (Q6) blocks chunk 1; verified absent from current package.json. |
| FMC — Failure Mode Coverage | 7.0 | server_down fallback fully drawn (§2.5 failure seq + §2.6 state machine); fail-closed toggle-read (§2.7); cross-origin logout path diagrammed. Docked: no error-message catalog/i18n keys; only one toast string in prose; toast component API unconfirmed (Q5). |
| NFS — Non-Functional Specificity | 6.5 | postMessage origin validation mandated (§3.1); SDK init explicitly non-blocking (§3.3); security threat (iframe/CSP) modeled. Docked: CSP delivery mechanism unconfirmed (Q8); no quantified perf budget (acceptable for an integration enhancement). |
| TPS — Test Plan Specificity | 7.5 | Per-chunk assertable criteria (§4.C); per-event test list (§2.4 → chunk 4); named spec files (tests/plugins/mekari-session.spec.js). Failure paths in scope. Docked: no explicit a11y/keyboard test for the toast surface. |
| ROL — Rollout & Rollback | 8.0 | 4 staged rollout with go/no-go evidence (§4.A); numbered agent-executable rollback (§4.D) with toggle-off as instant primary lever; pre-merge command list verified against package.json (§4.B). Config contract = the toggle. |
| OBS — Observability | 7.5 | Named RUM action mekari_session.event + error on server_down and origin-mismatch (§3.2); reuses plugins/datadog-rum.js convention; post-deploy signals enumerated (§4.D). |
| CPA — Pattern Alignment | 8.5 | "Patterns to Follow" table (§2.0) maps every concern to a reference file; reuses userLogout, datadog-rum init, custom_features read, window.location.href redirect convention. Explicitly avoids new patterns. Strong for an enhancement. |
Decision Closure Assessment
Decision Index
| # | Decision | Status | Critical Gaps |
|---|---|---|---|
| D1 | SDK delivery (npm @mekari/sdk + Nuxt plugin) | Partial | Registry availability unconfirmed (Q6) |
| D2 | Feature gating via custom_features code centralized_session | Partial | Exact code string unverified (Q3) |
| D3 | SDK mount point + event wiring (plugin after auth) | Resolved | SPA route-change refresh hook noted but not fully specified |
| D4 | logged_out/server_down → reuse userLogout + SSO redirect | Resolved | Impact on other userLogout callers open (Q7, important) |
| D5 | switch_user → interim sign-out + toast | Dangling | Real seamless flow unresolved (Q1 critical); SSO-autologin contract unknown |
| D6 | msli localStorage fallback helper | Resolved | None — fully specified |
| D7 | current_company sync | Dangling | Deferred; no CRM endpoint/field exists (Q4 critical) |
Aggregate: 3 of 7 Resolved (D3, D4, D6), 2 Partial (D1, D2), 2 Dangling (D5, D7).
Decision: D5 — switch_user action under CRM's token model
Status: Dangling
What was decided
Interim: treat switch_user as full sign-out + "user has changed" toast + re-login; seamless SSO-autologin path deferred (ADR-5, §2.4).
Alternatives considered
(a) Full SSO-autologin round-trip — rejected: needs SSO callback route + token re-issue CRM lacks. (b) Interim sign-out — chosen. (c) Silent token swap — rejected: no mechanism, security risk. Genuine evaluation, tied to codebase reality (crm-user redirects to crmV1Host/login).
Grounding in existing code
Grounded: schemes/crmAuthScheme.js (token model), middleware/crm-user.js (redirect target), store/user.js:userLogout. Strong.
Interface specification
Interim path fully specified (reuse userLogout + toast + redirect). Seamless path UNSPECIFIED — the SSO-autologin contract for token products does not exist in-repo.
Failure handling
Interim path degrades cleanly (user re-logs in). No silent failure.
Challenge results
- Scale: Holds — per-user event, no shared-resource contention.
- Reversibility: High — upgradeable to seamless when contract defined.
- Consistency: Consistent with D4 (both end at
account.mekari.com/sign_out). - Agent implementability: Agent CAN build the interim path. Agent CANNOT build the seamless path — would hallucinate the SSO callback.
Gaps and suggestions
Missing: SSO-autologin contract for CRM's token model; whether interim UX is product-accepted. Suggested resolution: Ship interim behind toggle; open a follow-up ticket against A&L for the token-product autologin contract; get product sign-off on the re-login UX before GA. Open questions for the author: Q1 — which PRD flow applies to a token-based product, and what is the autologin callback contract?
Decision: D7 — current_company sync
Status: Dangling
What was decided
Defer — out of FE-deliverable scope; CRM uses teams, no current_company endpoint found (ADR-7, §5 Q4).
Alternatives considered
(a) Implement once BE exposes endpoint; (b) map to CRM team context; (c) defer — chosen. Evaluated against verified absence of any current_company field (only /users/crm_teams, /crm/teams found, store/user.js:244,261,274).
Grounding in existing code
Grounded in the absence — Source Verification marks it UNVERIFIED/absent. Correct anti-hallucination posture.
Interface specification
N/A — deferred; no interface invented.
Failure handling
After interim sign-out + re-login, company context resolves via CRM normal login — acceptable interim behavior.
Challenge results
- Reversibility: N/A (deferred).
- Consistency: Consistent — relies on D5 interim re-login.
- Agent implementability: Agent correctly does nothing here; building it would require inventing a contract.
Gaps and suggestions
Missing: Whether CRM even has a per-company switch equivalent; need for a BE RFC.
Suggested resolution: Confirm with CRM BE whether current_company maps to a team-context switch; if a real need exists, raise a separate BE RFC and link it in S4.
Open questions for the author: Q4 — is a BE RFC required, and what is CRM's company-context equivalent?
Decision: D1 — SDK delivery into CRM
Status: Partial
What was decided
npm @mekari/sdk imported in new plugins/mekari-session.js (ADR-1), over a <script src> runtime tag.
Alternatives considered
(a) npm + plugin — chosen (matches PRD import form, plugin pattern, testability). (b) script tag — rejected. Reasoned.
Grounding in existing code
Grounded in plugins/datadog-rum.js pattern + nuxt.config.js:58 registration.
Interface specification
Plugin shape specified. Constructor input incomplete — depends on Q2 (user_sso_id).
Failure handling
Toggle off / read error → fail-closed (SDK not loaded), no regression. Good.
Challenge results
- Reversibility: High — remove plugin + dep, toggle off.
- Agent implementability: Cannot run
yarn add @mekari/sdkuntil registry confirmed (Q6).
Gaps and suggestions
Missing: Confirmed registry availability + pinned version. Suggested resolution: Verify package in Mekari private npm registry; pin version in chunk 1 before any other chunk. Open questions for the author: Q6.
Decision: D2 — Feature gating
Status: Partial
What was decided
Reuse custom_features from /users/me/feature_enabled, check code centralized_session (ADR-2).
Alternatives considered
(a) reuse custom_features — chosen; (b) env flag; (c) packageFeatures entry — both rejected with server-rollout rationale.
Grounding in existing code
Grounded: store/user.js:67 getCustomFeature, middleware/redirect-to-v3.js:49 read pattern. Strong.
Interface specification
Read mechanism specified. Exact code string unverified (Q3) — format ambiguity between CP-QONTAKCRM-YYYY-NNNN and plain string codes (e.g. use_central_contact_data).
Failure handling
Fail-closed on read error — SDK not loaded. Good.
Challenge results
- Reversibility: High — server toggle.
- Agent implementability: Agent would guess the code string; left as placeholder (correct, but blocks the gate test).
Gaps and suggestions
Missing: Exact centralized_session code value.
Suggested resolution: Confirm with backend toggle owner; until then, parameterize the code as a constant in assets/variables/ so the guess is single-sourced.
Open questions for the author: Q3.
UI State Audit
One user-visible surface (toast). Other "states" are session behaviors, not data-driven components.
| Component | Loading | Empty | Error | Partial | Success | Assessment |
|---|---|---|---|---|---|---|
switch_user toast | n/a | n/a | missing | n/a | defined ("user has changed") | 1/2 applicable — toast failure-to-render path not addressed; exact copy/i18n key + component API unconfirmed (Q5) |
Summary: The RFC is behavior-centric (events → store/nav), not screen-centric, so the 5-state model maps weakly. The single rendered surface lacks an i18n key and a confirmed component contract.
Performance Budget Check
| Metric | Target | Current Baseline | Source | Assessment |
|---|---|---|---|---|
| LCP / INP / CLS | not stated | not stated | — | Not specified — acceptable: §3.3 commits to non-blocking async SDK init, no render-path change |
| Bundle size delta | not stated | — | — | Missing — adding @mekari/sdk introduces a dep with unquantified size; add a budget note in chunk 1 |
Assessment: NO QUANTIFIED PERFORMANCE BUDGET — low impact for this sub-type since SDK init is async/non-blocking, but the bundle delta of @mekari/sdk should be measured at chunk 1.
Accessibility Review
| Aspect | Specified? | Details | Assessment |
|---|---|---|---|
| Keyboard navigation | no | — | N/A — no new interactive surface beyond toast |
| Focus management | no | — | Missing — switch_user toast appears before forced sign-out; focus/announce behavior undefined |
| ARIA / screen reader | no | toast not specified | Missing — confirm toast uses an aria-live region (defer to user-notifications skill, Q5) |
| Color contrast / motion | no | reuses existing notification | Assumed inherited from design system |
Assessment: Minimal a11y surface, but the switch_user toast must announce via aria-live since it precedes an involuntary sign-out — note this in chunk 4.
Pattern Alignment Check
| Pattern | RFC Approach | Assessment |
|---|---|---|
| Third-party SDK init | follows (plugins/datadog-rum.js) | Strong — conditional gate, default-export init fn |
| Feature-flag read | follows (middleware/redirect-to-v3.js:49) | Strong — same custom_features.find shape |
| Sign-out orchestration | extends (store/user.js:userLogout) | Good — adds SSO redirect to existing path; verify other callers (Q7) |
| External redirect | follows (window.location.href) | Strong — matches version-switcher convention |
| Observability | follows (@datadog/browser-rum) | Strong — reuses service convention |
msli storage | creates (new helper) | Justified — new artifact, isolated + unit-testable |
Assessment: Excellent pattern adherence; only one new pattern (msli helper), and it's justified and isolated. No parallel-system risk.
Cross-Layer Note (frontend RFC — out of scope by design)
The SSO/Session Manager/Redis/Kong-MAG layers are A&L-owned and READ-ONLY here (scope guard). Two cross-layer dependencies leak into FE readiness and are correctly flagged: the account.mekari.com CSP frame-ancestors whitelist must include CRM's domain before stage-1 pilot (§4.A), and the SSO-autologin contract (Q1) and current_company endpoint (Q4) are BE/SSO prerequisites for the deferred paths.
Agentic Readiness Deep-Dive
Vague Word Audit
| # | Word/Phrase | Location | Impact | Concrete Replacement |
|---|---|---|---|---|
| 1 | "throttled" session.refresh() | §2.2, ADR-3, Q9 | Agent guesses interval | Define: time-based (e.g. ≤1/min) vs per-navigation; Q9 acknowledges this |
| 2 | "[REQUIRED field — §5 Q2]" user_sso_id | §2.2 | Agent cannot fill SDK input | Pin exact $auth.user.<field> path |
| 3 | "[REQUIRED: confirm component]" toast | §2.0 Patterns | Agent invents toast API | Name the components/_general/ notification component + i18n key |
Total vague words in spec sections: 3 (each already cross-linked to an open question — good hygiene).
Dangling Alternatives
| # | Alternatives | Location | Impact |
|---|---|---|---|
| 1 | switch_user: full autologin vs interim sign-out | ADR-5 / Q1 | Agent builds interim only; seamless path absent |
| 2 | current_company: implement vs map-to-team vs defer | ADR-7 / Q4 | Agent does nothing (correct) |
Total dangling alternatives: 2 (both critical-tagged and consciously deferred, not accidentally left open).
Task Decomposition Assessment
| Chunk | Acceptance Criteria | Assessment |
|---|---|---|
| 2 msli helper | msli<2h+cookie→logged_in; >2h/no cookie→logged_out; missing→server_down | verifiable |
| 3 plugin + gate | toggle off→no Session; on→Session w/ user_sso_id; origin validated | verifiable (but blocked on Q2 for the user_sso_id assertion) |
| 4 event handlers | per-event tests; msli cleared on logout | verifiable |
| 5 logout→SSO redirect | after sign_out resolves, window.location.href set | verifiable |
| 6 observability | RUM action emitted (mock datadogRum) | verifiable |
| 1 add dep | dep present, frozen-lockfile passes | blocked on Q6 |
Assessment: Strong decomposition with dependency ordering stated (§4.C). Chunks 2, 3 (scaffold), 6 executable now; 1, 4, 5 gated on critical answers.
Strengths
- Source Verification table (§2.0) separates verified anchors (with file:line) from UNVERIFIED unknowns — the single best agentic-readiness feature in this RFC; it converts unknowns into explicit blockers instead of silent guesses.
- Reuse-first pattern alignment (§2.0 Patterns, ADR-4) — every concern maps to an existing file (
userLogout, datadog-rum, custom_features), so generated code will look native to the codebase. - Numbered, toggle-first rollback recipe (§4.D) with server-side toggle-off as the instant primary lever and PR revert as secondary — executable without the author.
Biggest Gaps
user_sso_idsource UNVERIFIED (§2.0, §2.2, Q2) — the SDK constructor input has no confirmed field on/users/me; only company-levelexternal_company_idis verified. Without it the entire integration object is a guess. Blocks chunks 1, 3, 4.switch_userreal flow unresolved (ADR-5, Q1) — CRM is token-based with no SSO-autologin callback; only an interim sign-out is buildable. The PRD's headline "seamless switch" behavior cannot be implemented from this RFC.centralized_sessionexact code +@mekari/sdkregistry (Q3, Q6) — the feature-gate string is a placeholder and the npm package is unconfirmed in the registry, so chunk 1 (yarn add) and the gate test cannot be authored deterministically.
Priority Actions
- Q2 / §2.0 Source Verification — Confirm the exact field exposing the user's SSO id in the
/users/me(crmAuthScheme.fetchUser) response and pin it in §2.2. Unblocks SDK construction and every event comparison; without it chunks 3 and 4 are guesses. - Q1 / ADR-5 — Get product sign-off on the interim sign-out UX and open a follow-up against A&L for the token-product SSO-autologin contract. Lets chunk 4's
switch_userhandler ship without inventing a callback. - Q3 / ADR-2 — Confirm the literal
centralized_sessionfeature code with the toggle owner; store it as a single constant. Unblocks the gate test in chunk 3. - Q6 / chunk 1 + Q5 / §2.0 — Verify
@mekari/sdkregistry availability + pin version, and confirm thecomponents/_general/toast component API + i18n key for "user has changed." Unblocks chunk 1 and the chunk-4 toast.
Implementation Readiness Checklist
Unblocked (agent can proceed)
- PRD → RFC traceability matrix present (Detail 1.A)
- Scope boundaries / file list pinned (§2.0 Repo Map, Detail 1.C)
- Pattern alignment verified (§2.0 Patterns)
- Rollout plan + rollback mechanism (§4.A, §4.D)
- Observability metrics named (§3.2)
- Task decomposition with per-chunk acceptance criteria (§4.C)
-
mslifallback + server_down failure path specified (ADR-6, §2.5) - Config contract:
centralized_sessiontoggle, fail-closed default
Blocked (must fix first)
-
user_sso_idsource unverified — SDK constructor input cannot be filled (Q2, critical) -
switch_userseamless flow unresolved for token model (Q1, critical) -
current_companysync deferred with no contract (Q4, critical) -
centralized_sessionexact code unverified (Q3, critical) -
@mekari/sdkregistry availability + toast component API unconfirmed (Q6, Q5)
Verdict: Fix 4 critical blockers (Q1–Q4) first — chunks 2, 3 (scaffold), 6 may proceed in parallel.
Task Manifest
RFC specifies decomposition in §4.C; verified and reproduced with readiness tags.
| Order | Chunk | Files to Create/Modify | Acceptance Criteria | Dependencies |
|---|---|---|---|---|
| 1 | Add dependency | package.json, yarn.lock | @mekari/sdk pinned; yarn install --frozen-lockfile passes | Blocked on Q6 |
| 2 | msli fallback helper | utils/helpers/mekari-session.js, tests/utils/helpers/mekari-session.spec.js | msli<2h+cookie→logged_in; >2h/no cookie→logged_out; missing→server_down | None — executable now |
| 3 | SDK plugin + toggle gate | plugins/mekari-session.js, nuxt.config.js, tests/plugins/mekari-session.spec.js | toggle off→no Session; on→Session built; event.origin validated | Chunk 2; user_sso_id assertion blocked on Q2 |
| 4 | Event handlers | plugins/mekari-session.js, store/user.js (clear msli in deleteUserLocalData) | per-event tests pass per §2.4 | Chunk 3; switch_user blocked on Q1; toast on Q5 |
| 5 | Logout → SSO redirect | store/user.js:userLogout | after sign_out resolves, window.location.href = account.mekari.com/sign_out | Verify other callers (Q7) |
| 6 | Observability | plugins/mekari-session.js | RUM mekari_session.event emitted (mock datadogRum) | Chunk 3 |
RFC SPECIFIES decomposition — verified against package.json scripts; no invention needed.
Dangling Decisions Log
| # | Decision | Location | Owner | Deadline |
|---|---|---|---|---|
| 1 | switch_user seamless flow (token model) | ADR-5 / Q1 | A&L (SSO) + CRM FE | before GA |
| 2 | current_company sync | ADR-7 / Q4 | CRM BE + A&L | before GA (or confirm not needed) |
| 3 | centralized_session exact code | ADR-2 / Q3 | Toggle owner | before chunk 3 test |
| 4 | @mekari/sdk registry availability | ADR-1 / Q6 | A&L (SDK) | before chunk 1 |
Open Questions
| # | Question | Category | Severity |
|---|---|---|---|
| 1 | Which PRD flow applies to CRM's token model; SSO-autologin contract? | TDC | Blocking |
| 2 | Source of user_sso_id in /users/me? | CNT | Blocking |
| 3 | Exact centralized_session feature code string? | DEP / CNT | Blocking |
| 4 | current_company CRM equivalent; BE RFC needed? | TDC | Blocking |
| 5 | Exact toast component API + i18n key? | FMC / a11y | Important |
| 6 | @mekari/sdk published to private registry? | DEP | Important |
| 7 | Do existing userLogout callers break with SSO redirect? | FMC / CPA | Important |
| 8 | CSP delivery mechanism (edge vs meta)? | NFS | Important |
| 9 | session.refresh() throttle interval? | NFS | Nice-to-have |
Evidence Notes
- §2.0 Source Verification — strongest evidence; verified anchors carry file:line, and three rows are explicitly UNVERIFIED (user_sso_id, current_company, feature code). Drove the CNT (5.5) and TDC (6.0) scores and the HOLD verdict.
- §4.C Agent Execution Plan + §4.B commands — assertable acceptance criteria tied to real
package.jsonscripts lifted TPS (7.5) and ROL (8.0). - §5 Open Questions — four
[critical]items map cleanly to the §7 failing gates; their presence is why this scores Needs Work rather than Insufficient — the gaps are identified, not hidden. - §1.4 / §2.0 toast component — absence of a confirmed notification component API and i18n key held FMC at 7.0 and surfaced the a11y
aria-livegap.