openalice-clonelab-dashboard
Architecture rating
0 circular deps and 0 dead imports is clean, but 7 god modules, 5 duplicate signatures, 40 format issues, and missing manifest (30/100) show inconsistent module decomposition and no enforced style gate
Max cyclomatic complexity 47 (fragile hot path); 20 bare/broad excepts swallow errors instead of surfacing them; no health endpoint (Atlas confirms up:false); no evidence of request timeouts, retry logic, or graceful shutdown handling
5 undeclared env vars inc. NEXT_PUBLIC_CLONELAB_API/VAULT_API leaking to client bundle; 20 bare/broad excepts can swallow auth failures silently; no evidence of CSP headers, rate-limiting, or CSRF protection; no health endpoint to verify TLS termination
Pure frontend dashboard — no migrations, no owned tables, no schema; no evidence of input sanitization, form validation, or safe data-fetching patterns despite consuming CLONELAB_API and VAULT_API
Atlas health probe fails ('no https endpoint in manifest exposes'); no manifest, no structured logging evidence, no metrics export, no tracing headers; dashboard is effectively invisible to monitoring stack
Empty README excerpt, no manifest present, 212 missing docstrings, roadmap score 30/100; 12 features exist per Atlas but no in-code @feature annotations or architecture notes
No test directory, no test files found anywhere in repo structure; zero test coverage for a 12-feature dashboard with complexity-47 modules
source · auto-grader-2026-06-17
Code composition
tokei · loc- TSX58.9%
- CSS23.4%
- TypeScript15.6%
- JSON2.1%
- TSX58.9%
- CSS23.4%
- TypeScript15.6%
- JSON2.1%
- TSX58.9%· 1,747
- CSS23.4%· 695
- TypeScript15.6%· 462
- JSON2.1%· 62
| Language | % code | code | comments | blanks | files |
|---|---|---|---|---|---|
| TSX | 58.9% | 1,747 | 137 | 145 | 13 |
| CSS | 23.4% | 695 | 108 | 79 | 3 |
| TypeScript | 15.6% | 462 | 78 | 76 | 7 |
| JSON | 2.1% | 62 | 0 | 0 | 2 |
Telemetry ribbon · last 90 days
2 eventsclonelab-dashboard/components
2 features- clonelab-dashboard.components.app-shellsrc/components/AppShell.tsx:2Left-rail + topbar shell for authenticated pages. Uses the same .oa-rail / .oa-topbar / .oa-canvas token classes from globals.css. No Tailwind — pure CSS custom properties from the design system.
- clonelab-dashboard.components.brand-marksrc/components/BrandMark.tsx:2Two-circle Mandelbrot mark — the OpenAlice logomark. Mirrors embed-app BrandMark exactly (same SVG, same class).
clonelab-dashboard/create-self
1 feature- clonelab-dashboard.create-self.flowsrc/app/create/self/SelfCloneFlow.tsx:2Multi-step self-clone creation flow: 1. Liveness capture (STUB — placeholder token, honest disclosure) 2. Name + vault draft (POST /v1/identities with subject_kind: self) 3. Media upload (photos / voice / text — sent to POST .../ingest) 4. Pipeline progress poll (GET /v1/ingest/{job}) — 7 stages 5. Sealed soul result The liveness step is honest: the UI captures a placeholder token and CLEARLY tells the user that real biometric verification is not yet wired (backend stub). The marker value "liveness-stub-v0" is sent so the backend pipeline receives it and can run its own stub logic. onMouseEnter/onMouseLeave are style helpers on interactive articles — safe for client components but not idiomatic for server components.
clonelab-dashboard/create-synthetic
1 feature- clonelab-dashboard.create-synthetic.flowsrc/app/create/synthetic/SyntheticFlow.tsx:2Synthetic NPC generator: 1. Create vault draft (subject_kind: random) 2. POST /v1/synthetic with seed + identity_id 3. Show generated NPC + poll job → sealed soul result (same 7 stages) No liveness check — synthetic souls have no real person behind them. The seed makes the NPC reproducible; leaving it blank lets the backend pick a random one (which is then shown so the user can reproduce it).
clonelab-dashboard/lib
5 features- clonelab-dashboard.lib.auth-clientsrc/lib/authClient.ts:2Server-side proxy to openalice-tenants auth surface. Mirrors embed-app/src/lib/authClient.ts — same API contract, same error types. Runs server-side only; plaintext password never touches the browser.
- clonelab-dashboard.lib.clonelab-apisrc/lib/clonelab-api.ts:2Server-side typed client for openalice-clone-lab HTTP API. Routes consumed: POST /v1/identities/{id}/ingest — enqueue an ingest job (JWT-gated) GET /v1/ingest/{job} — poll job status + per-stage progress POST /v1/synthetic — seed → synthetic NPC ingest + seal Base URL: CLONELAB_API env var (default http://localhost:3994). Auth: JWT Bearer from the session cookie. The 7 pipeline stages (in order): intake → visual → voice → style → knowledge → consent → seal Each stage may be: pending | running | done | skipped | failed
- clonelab-dashboard.lib.clonelab-clientsrc/lib/clonelab-client.tsx:2Client-side shared helpers for the creation flows (self + synthetic). This is the browser-side counterpart to the `server-only` clonelab-api.ts: the creation flows are `"use client"` components that call vault + clone-lab DIRECTLY from the browser using the JWT handed down as a prop, so they cannot import the `server-only` module. This module consolidates the helpers that were previously duplicated verbatim across SelfCloneFlow.tsx and SyntheticFlow.tsx: - apiPost / apiGet — typed fetch wrappers ({ ok, data } | { ok, message }) - IngestStage / JobStatus — the shared status shapes the poll loop fills - STAGE_LABELS / StageIcon / StageRow — the 7-stage pipeline UI The 7 pipeline stages (in order): intake → visual → voice → style → knowledge → consent → seal Each stage may be: pending | running | done | skipped | failed No `server-only` import here — this code runs in the browser. The JWT it carries is the same one already in the authenticated session cookie; the pages pass it to the client components intentionally (same origin, behind auth) so the browser can talk to the backend directly.
- clonelab-dashboard.lib.sessionsrc/lib/session.ts:2Session management — HttpOnly cookie carrying the tenant JWT. Mirrors embed-app/src/lib/session.ts exactly (same cookie name, same security posture). The login server action writes the cookie; every server-side data-fetch reads it.
- clonelab-dashboard.lib.vault-apisrc/lib/vault-api.ts:2Server-side typed client for openalice-vault HTTP API. Routes consumed: POST /v1/identities — create a draft soul (self | random) GET /v1/identities — list owner's souls (newest first) Base URL: VAULT_API env var (default http://localhost:3992). Auth: JWT Bearer from the session cookie — passed in as a parameter so this module is a pure HTTP wrapper without cookie access.
clonelab-dashboard/login
1 feature- clonelab-dashboard.login.actionssrc/app/login/actions.ts:4Server actions for login + signup. Mirrors embed-app/login/actions.ts exactly — same error-collapsing policy (no field-level leaks), same HttpOnly cookie write via setSessionCookie.
clonelab-dashboard/page
3 features- clonelab-dashboard.page.createsrc/app/create/page.tsx:2Class chooser — pick Self, Synthetic, or see the "other-clone" blocked notice. Honest copy per §3 of the product design doc: - Self: liveness required (stub in M1, honest disclosure) - Synthetic: free, no real person - Other-clone: default-deny, not available
- clonelab-dashboard.page.loginsrc/app/login/page.tsx:2Split-screen auth: brand panel (dark-sakura, left) + auth card (cream, right). Mirrors embed-app login/page.tsx structure + visual language exactly. Tabs: Sign in | Create account. No SSO tab (Cloning Lab is direct-auth only).
- clonelab-dashboard.page.soulssrc/app/souls/page.tsx:2Souls list — GET /v1/identities from the vault API. Shows all souls the authenticated owner has created. Redirects to /login if no session exists.