← Design · c134

inventory.md

c134 Phase 0: inventory of both apps

As of: 2026-11-09. Read from the trees, no servers started. Sources: ../app.qpoint.io (last code commit a6fae09, 2026-03-12; later commits are layer bumps), ../qcontrol/crates/qdash/ui on feat/new-pages (app last touched 4af4df15, 2026-10-02), ../qcontrol/crates/qdash/src/web.rs (a7de3f68a, 2026-09-26, 11,680 lines). Rules referenced: the bible ui/docs/data-interface.md (R13, R15, R23, R25, R31) and ui/LAYER-CANDIDATES.md. Reader: Mark; Tyler and Kamal for §6–§9; the c135 executor for §8. Shape of the finding: app.qpoint.io is a frame (sign-in, orgs, members, contexts, settings, install) around traffic pages that are being retired; qdash is pages (44, one data discipline) with no frame at all. The seam is exactly where the plan put it (D1).

1. Side by side

app.qpoint.ioqdash UI
StackNuxt 4 SPA (ssr: false), JavaScript composables, Pinia, @qpoint-io/q-nuxt-layer (latest), Firebase 11, chart.js, d3, headlessuiNuxt 4 SPA, TypeScript everywhere, no Pinia (shell singletons, bible R22), layer pinned by lockfile (0.9.36), vitest on lib/
Routed pages76 (app/pages, excluding components/, dev/, lib/): orgs 28, stacks 10, inventory 9, traffic 7, alerting 6, security 4, sso 4, session 444 (app/pages): inventory 16, organization 6, policies 2, integrations 2, activity 2, 16 single pages; /overview, /reports, /settings, /account are DesignInProgress placeholders
Layoutsdefault (logo + account menu), global (PageMain + section left nav + teleported filter slot), org, session (logo over a white card), devone: app/layouts/default.vue = AppSidebar + BackendBanner + UxStickyBand + GlobalFilterBar + ToastStack
AuthFirebase Auth: email, Google, GitHub, Microsoft popups, SSO by email domain (connectors collection), SAML and OIDC through $api + signInWithCustomToken; auth.global.ts redirects to /sign-in, keeps pre-auth pathnone; web.rs require_local_host refuses non-loopback Hosts; no viewer identity (/account comment: no /api/me)
ScopingURL query orgId / contextId / stackId / endpointId → useContext(); context.global.ts mirrors orgId/contextId into the auth store (localStorage)none; one fleet; filters and ?period= in the URL (useGlobalFilter)
Data accessthree injected clients: $pulse (Pulse /api/v1, bearer from /jwt/tokens, per-org pulseUrl from orgs/{id}/settings/hosting), $api (qpointApiUrl, token from users/{uid}/orgs/{orgId}.apiToken), $warehouse; Firestore live onSnapshot via useList / useEntityone client $qdash (plugins/qdash.ts, relative /api, 8 s timeout, reports to useBackendHealth); Transport = http() or local(key) (composables/api/transport.ts); primitives useList / useResult / useEntity poll at 3 s
Contractnone written; field names live in composables and components28 type files in types/api/ written from web.rs (R13); 46 domain modules; 51 rollup specs in lib/
Timepulse store timeframe (24hrs default) in localStorage; timeFrameToStartthe when: pill: ?period= all / 24h / 7d / 30d, default 7d (filter-keys.ts; 30d at the port, c128)
Honest statesnone (lists default to [], loaded flag only)R31: StateEmpty, SkeletonRows, usePageState, BackendBanner, ToastStack (c108)
Wizardsthe kit in app/components/wizard/ + utils/sequin.js; seven flowsnone; the integration setup modal is a stepper of its own (components/alerts/IntegrationSetupModal.vue)
AlertingPulse-backed rules, events, integrations, scanners (composables/alerting/)"would fire" computed client-side from five feeds (composables/alerts/alerts.ts); routing persisted (/api/channels); delivery projected
Build and serveCloudflare Pages SPA, Firebase project, pulse.qpoint.io, firebase.qpoint.io functionsdist/ committed and embedded in the qdash binary; dev proxies /api to :7878 or QDASH_API_BASE

2. app.qpoint.io mapped

2.1 The frame

  • Sign-in and sign-up (app/pages/sign-in.vue, sign-up.vue, session/components/Oauth.vue): email + password, three OAuth popups, and useSSO(email) which queries connectors by the email's domain and swaps the form for "Sign in with SSO" → /sso/<provider>/sign-in?domain=. /forgot-password is linked but no page exists. On success dataLayer.push (GTM) then the pre-auth path or /.
  • SSO (app/pages/sso/, server/routes/sso/saml/): saml/sign-in asks $api /sso/saml/auth for authUrl and redirects; the IdP posts to the Nitro route assert.ts, which 302s to saml/callback?assertion=; the callback posts /sso/saml/token and signs in with a Firebase custom token. metadata.xml.ts redirects to the API's metadata. OIDC is the same dance with /sso/oidc/auth and /sso/oidc/token (code, state, redirectUri). Per-org settings in orgs/{id}/settings/sso {provider, domain, url, config} (settings/sso.vue, sso/components/provider/OIDC|SAML.vue).
  • After sign-in (app/pages/index.vue): a three-stage wait on Cloud Functions: profile created (users/{uid}), invitations accepted (users/{uid}/invitations), permissions synced (users/{uid}/orgs/{orgId}.roles/.permissions); then /orgs/new or /orgs/overview?orgId=.
  • Org and context (stores/auth.ts, composables/context.js, middleware/context.global.ts): the org is a query param, remembered in localStorage; the Pulse token is re-minted per (org, context) through /jwt/tokens {service, contextId, role}; the org switcher (orgs/components/Selector.vue) and the "View:" context selector (contexts/Selector.vue) sit in the top nav (layouts/components/nav/Top.vue) with PageMessages and the user popover (nav/User.vue: Account, Contact Us, Sign Out).
  • Permissions (composables/user/orgs.js useOrgPermissions): twelve strings read from the user-org doc (traffic.view, security.view, payload.view, log.view, org.config, org.manage, org.team, traffic.manage, security.manage, context.manage, …); roles are chosen as checkboxes on invite (settings/team/manage.vue, save text "Invite").
  • Self-hosting hint already present: orgs/{id}/settings/hosting holds pulseUrl, pulseSecret, warehouseUrl, screenshotUrl (composables/org/settings/hosting.js useSelfHostedSettings); the Pulse plugin points at it when set.

2.2 Data access

StoreCollections and documents (Firestore, composables/firebase/crud.js useList / useEntity)
userusers/{uid} (profile), users/{uid}/orgs/{orgId} (roles, permissions, apiToken, pulseToken, warehouseToken), users/{uid}/invitations, users/{uid}/orgs/{orgId}/contexts, connectors (SSO by domain)
orgorgs/{id} (name, status, ready, relayToken, certificateAuthority, installed…), orgs/{id}/members, orgs/{id}/contexts/{cid}/members, orgs/{id}/settings/{hosting,sso,deploy,proxy,tls,endpoints,jwt,wiretap,stack}, orgs/{id}/deployments/{did}/instances (name, type, token, active), orgs/{id}/tasks (onboarding checklist), orgs/{id}/tags, orgs/{id}/services (adapters Pulse / Qscan / S3 / Warehouse), orgs/{id}/releases, orgs/{id}/stacks/{sid}/… (adapters, rules), wiretap filters
ClientRoutes used ($pulse.fetch → <pulseUrl>/api/v1, composables/pulse/crud.js and metrics.js)
Pulse/alerts (+`/{id}/enable
API/jwt/tokens (POST), `/sso/saml/auth

2.3 Pages by section (nav in pages/<section>/components/Nav.vue)

SectionPagesStanding for the port
Sessionsign-in, sign-up, sign-out, me (profile + delete account), contact, sso ×4frame: moves (re-homed on the new identity)
Orgsindex (create or join), new, configure (deploy preferences), install (qtap wizard), overview (onboarding checklist, four summary tiles, quick actions), settings ×17: Organization, Capabilities, Team, SSO, Views, Config, SSL/TLS, Endpoints, Connect (JWT tokens), qtap Config + Filters, Tokens (deployments), Tags, Services, Releases, Snapshot (generated qpoint.yaml), MCP Clientsframe: moves; the proxy/TLS/qtap-config settings go with the stacks decision
Inventoryvendors, clients, endpoints, api-tokens, geolocation (+ sensitive-data link)replaced by qdash Inventory and Organization
Trafficperformance, availability, bandwidth, connections, HTTP requests (Pulse metrics)dropped (qproxy traffic model)
Securityoverview (vulnerability scanners), data-risk (sensitive data flow)replaced by qdash Findings, Posture, DLP
Alertingevents, rules, integrations ("Webhooks")re-homed (D7) into qdash Alerts + Integrations
Stacksadapters (plugins), config rules, routing, settingsdropped unless qproxy returns (question for Tyler)
dev, libcomponent showcase (/dev/*, /lib/*)design site's job; not ported

2.4 Alerting (composables/alerting/, pages/alerting/components/)

Rules are Pulse entities {name, description, enabled, kind, config, query, checkInterval, reportFrequency} with four kinds and an adapter form each: threshold (metric, operator, threshold, group by), delta (metric, increase/decrease %, group by), discover (new vendor / endpoint / client / PII / token), risk (source and destination define-by, risk labels). Templates or custom (rules/Edit.vue). Integrations are Pulse entities with one UI adapter, Webhook (method, URL, token); rules link integrations through /alerts/{id}/integrations. Events (events.js) join /events/alerts with the rules and draw lines per alert. Scanners (scanner.js) are the vulnerability side. qdash's counterpart: lib/catalogs/connectors.ts + lib/integration-setup.ts recipes (Slack, PagerDuty, email digest, webhook previews), /api/channels routing, /api/integrations config, no engine and no sender.

2.5 Wizards

The kit (app/components/wizard/: Steps, EduHarness, PingListener, ToggleHarness, FinalStep; utils/sequin.js) was replicated by c125 into design app/components/replicas/wizard/ (plus the mask-image radar) and demoed at /pages/phase4/wizard-kit; it is still not in the layer. Flows: Install Qtap (orgs/components/install/qtap/: Name → Choose your Environment → Installation with Docker / Kubernetes / Linux instructions → wait for first traffic (deployment.active) → Installation Successful; mounted by orgs/install.vue on the default deployment's token), Install Qscan (Environment → Install, Docker / Kubernetes), Deploy Qproxy and Connect an app (dev mocks only: dev/components/mock/wizards/), the onboarding checklist (orgs/{id}/tasks: QtapDeploy, QscanDeploy, S3Configure; onboarding/Checklist.vue), preferences (Capabilities, Hosting), create a View (Name → Filter → Members), the security activate wizards (data types, stacks, persistence; scanner categories), MCP configure (Claude / Codex / Other instructions).

3. qdash UI mapped

3.1 Shell

app/layouts/default.vue: AppSidebar (three sections MONITOR / GOVERN + SECURE / ADMIN, disclosures per c109, footer with Working and Experimental toggles and the theme toggle), BackendBanner (unreachable → one banner; 2+ missed polls → "last updated" tag), UxStickyBand with the title pinned beside the filter (c104/c106), GlobalFilterBar (the one layer Filter; keys from composables/shell/filter-keys.ts FILTER_KEYS: team, provider, user, host, agent, posture, kind, source, status, flagged, attention, server, model, workspace, adapter; the permanent when: pill), ToastStack. / is the index of micros (pages/index.vue, c109); middleware/team-routes.global.ts redirects moved routes (lib/moved-routes.ts). Shell composables auto-import; domain and primitives import explicitly (bible §14).

3.2 Pages → composables → routes

Page(s)Domain moduleRoutes
/ indexfleet/indexSummarythe listings' own feeds
/inventory/harnesses (+detail), /inventory/agents/detailinventory/harnesses, inventory/agents/api/harnesses, /api/agent
/inventory/providers (+detail, accounts/detail)inventory/providers, inventory/accounts/api/providers, /api/accounts
/inventory/models, mcp-servers, skills, tools, workspaces (+details)inventory/*/api/models, /api/mcp-servers, /api/skills, /api/tools, /api/workspaces; details add inventory/surface → /api/surface
/organization/users, teams (+details)team/people (seven feeds), team/teams, fleet/costs/api/sessions, /api/teams (GET/POST), /api/costs, …
/organization/endpoints (+detail)team/endpoints/api/endpoints (?host= detail mode)
/activity (+detail)team/sessions/api/sessions (?run= detail)
/livelive/* (8 modules)/api/events/stream (SSE), /api/agent/focus, /api/agent/reveal
/findingssecurity/findings/api/security, /api/finding-state, /api/finding-decision
/policies (+detail)security/controls, compliance/policies/api/controls, /api/control-vocab, /api/control-test, /api/egress-decisions; staged localBlob('qdash.policies.v1')
/compliance, /frameworkcompliance/frameworksstaged localBlob('qdash.compliance.frameworks'); findings all-time
/posturefleet/posture/api/agents?period=all, /api/installations, /api/trends, /api/security
/costfleet/costs/api/costs (+ models, providers, accounts, workspaces, sessions for Cost Center, c105)
/dlp, /identity, /performance, /campaignssecurity/dlp, fleet/identity, fleet/performance, security/campaigns/api/dlp, /api/inventory, /api/performance, /api/campaigns (GET/POST/DELETE)
/alertsalerts/alerts (+channels)/api/security?period=all, /api/egress, /api/campaigns, /api/stats, /api/channels, /api/controls
/integrations (+[id])alerts/integrations/api/integrations (GET/POST/DELETE)
/overview, /reports, /settings, /account—placeholders (DesignInProgress)

Routes no UI module reads: /api/activity, /api/attestations. /api/security-packet is read by the Policies evidence packet.

3.3 Served, derived, staged (R23)

  • Served: everything in §3.2's routes column, typed in types/api/*.ts with the handler's field names.
  • Derived: lib/*-rollups.ts and *-bands.ts (pure, specced): posture, findings (group, SLA, status), people, endpoints, harnesses, costs, team cost trend, alerts, compliance, index micros, surface, and the live view's virtual rows.
  • Staged state (R25, local() / localBlob): framework activation and control toggles (compliance/frameworks.ts), policy enablement, exceptions, lists, detectors, thresholds (compliance/policies.ts). Each names the contract that retires it: GET /api/frameworks (+/frameworks/<slug>), GET /api/policies.
  • Staged values (R24, lib/projected/*.ts, 66 ledger entries): alerts 19 (delivery, connector registry, secrets at rest, default routing, source heuristic), compliance 30 (catalogs, requirements, level counts, detector hits, quota thresholds, exception fixtures, framework links), fleet 7 (guardrail rule, enforcement, factor points, credential risk, label join), inventory 6 (tool success, provider labels, workspace git), people 4 (seats, team assignment), security 10 (SLA rubric, event log, operator assignee, expiry in note, DLP labels), session 4 (summary, provider of session). Every entry's contract field is a backend ask; §6 consolidates them.

4. The qdash backend: 38 /api/* routes (web.rs lines 59–132)

RouteServesWindowWrites
events/streamSSE live tail of hub events, no replay or cursor; 503 on static servelive—
agent/focus, agent/revealfocus a harness window / reveal a file on this host (macOS bundles)—POST (host-local action)
statsfleet headline numbers, world seam, coverage {injection_failures, adapter_errors, uninspectable_conns}cost and tokens 24h fixed—
inventoryper-run identity and credential rows (Identity page)?period=—
agents, agent(harness × user × host) identities; detail by id?period= listing; detail all-time—
costsspend and tokens by model / harness / user / team / provider + daily series; rows keyed by label?period=, ?team=—
performanceLLM latency per harness, twelve slowestnone—
egressdestination hosts with TLS and allow-list standingnone—
activityevent-family composition and per-second timelines (unused by the UI)none—
trends90-day daily posture, spend, egress, findings, coveragefixed 90 UTC days—
teamsemail → team map (qdash-side; "an IdP/SCIM sync replaces the source later")—POST upsert
dlpsensitive file movement, secrets and PII by category?period=, ?team=, ?q=; volume unwindowed—
securityfindings (control × scope) with workflow row; sla_due served, never written?period=, ?team=—
security-packetevidence packet JSONcurrent state—
finding-state, finding-decisionone UPSERTed workflow row per finding key; apply a decision—POST
controls, control-vocab, control-testcontrol catalog (cond, sev, act, enf, packs), vocabulary, dry-run—POST upsert, DELETE archive, POST test
egress-decisionsoperator decisions per (host × scope × agent)—POST upsert
installationsat-rest scan snapshot, instrumented, fp_confirmednone (inventory)—
endpointsdeveloper machines and what runs on them; ?host= detail?period= activity; installs at rest—
surfacewhat an actor touches, one axis per list?<scope>=&period=—
models, mcp-servers, workspaces, tools, sessions, harnesses, providers, accounts, skillsthe inventory categories, list by default, detail by the category's identity param?period= (24h / 7d / 30d, else all; cut back from fleet_anchor, not the wall clock)—
attestationsevidenced out-of-band clauses (unused by the UI)—POST upsert
channelsseverity → connector routing register—POST upsert
integrationsconnector config, stored verbatim including secrets—POST upsert, DELETE
campaignscampaigns with live progress; wall-clock windows—POST create, DELETE

SQLite behind every route (db.rs); period_span (web.rs:2334) accepts only 24h / 7d / 30d; no from / to; no auth; no org column.

5. What moves, what is replaced, what is dropped

  • Moves (frame, re-homed on the new identity and API): sign-in / sign-up / sign-out / profile, SSO (SAML routes kept, OIDC added, D2), orgs and members with roles and permissions, invitations, the org switcher and user popover, settings (Organization, Team, SSO, Capabilities, Tokens / deployments with the first-ping wait, Snapshot), the onboarding checklist, the wizard kit and the Install flow (Choose environment → instructions → wait for the first ping → done), the Pulse plugin's one-client pattern (already the bible's R14), useList / useEntity's protocol (already the primitives').
  • Moves (pages, as they are): all 40 qdash pages with data, their shell, filter, when: pill, honest states, types/api, rollups and specs. Transport swap only (R2).
  • Replaced: app.qpoint.io Inventory → qdash Inventory + Organization; Security overview and data-risk → Findings, Posture, DLP; app.qpoint.io alerting rules, events and webhooks → qdash Alerts + Integrations fed by a real engine (D7: the rule kinds threshold / delta / discover / risk and the webhook adapter are the spec of that engine); Firestore live subscriptions → polling (or an API stream) per R1; Cloud Functions (profile, invitations, permissions) → the Go app; contexts ("Views") → the global filter unless Tyler keeps member-scoped views.
  • Dropped: Traffic (performance, availability, bandwidth, connections, requests), Stacks (adapters, rules, routing), the $warehouse client, GTM and Sentry wiring as built, the /dev and /lib showcases, agent/focus and agent/reveal on the plane (they belong to the native app, c131 / c137), DesignInProgress placeholders, the demo=true query flow (c113's worlds replace it, D5).

6. The API gap list

What the qdash pages (and the frame) need that the 38 routes do not serve. Sources: types/api/* headers, lib/projected/*.ts contract fields, page comments, c128 data-inventory.md, c105, c131, c136, c137.

#GapNeeded byRecorded at
1from / to on every windowed list and rollup (period_span takes three presets)the when: pill's range picker, every reportc128 data-inventory.md gap 1; CYCLE.md:32
2One window on every route: stats (24h fixed), trends (90d), performance, egress, activity, installations, and the pages that fetch all-time (posture, compliance, alerts, identity, integrations, detail pages)window consistency; reports vs pagesc128 gap 5; lib/projected/compliance.ts unwindowed; alerts.ts severityCountsAllTime
3History beyond 90 days (/api/trends)quarterly and SOC 2 reportsc128 gap 2
4Daily snapshot store: inventory counts, coverage, versions as of date Xreports "as of"; evolution viewsc128 gap 3; c128 plan Phase 6
5Viewer identity GET /api/me (name, email, roles) and the authenticated operator on writes/account; finding-decision assigneepages/account.vue; projected/security.ts operatorAssignee
6Sessions: local accounts, OIDC, SAML, sign-out, password reset, invitation acceptancesign-in frameapp.qpoint.io /jwt/tokens, /sso/*, connectors; /forgot-password has no page
7Orgs, members, roles and permissions, invitations (twelve permission strings today)org frame, nav gatingcomposables/user/orgs.js, org/members.js, user/invitations.js
8Contexts / views (member-scoped filter presets) or an explicit decision to drop themorg frameapp.qpoint.io orgs/{id}/contexts, Pulse /contexts
9Settings: GET/POST /api/settings (org name, SSO config, hosting, deploy preferences, tags)/settingspages/settings.vue comment; app.qpoint.io settings/*
10Endpoint connect: base URL + standardised credential exchange, enrolment, heartbeatthe native app's Connect; Install wizard's first pingc131 plan D13; c134 D8; app.qpoint.io deployments.token/.active
11Mechanic-access grants as plane objects (time-boxed, categorised)c136c136 plan D1; c134 D8
12Operator inbox and send (messages as a resource)c137c137 plan D1; c134 D8
13GET /api/frameworks (+/frameworks/<slug> requirements → control ids, activation state)/compliance, /frameworkcompliance/frameworks.ts (R25); projected/compliance.ts gap 7
14GET /api/policies (enabled, config, exceptions, lists, detectors, thresholds)/policiescompliance/policies.ts (R25, backlog B3)
15Seat prices per provider plan; seats on /api/accountsCost Center, Usersc105 plan.md:55; projected/people.ts gap 10
16Identity roster (SSO / SCIM / HRIS) replacing the qdash-side /api/teams mapUsers, Teams, findings by teamweb.rs teams_list comment; projected/people.ts teamAssignment
17An alert engine: rules on a schedule, an events history, delivery, enable / disable/alerts, /integrationsprojected/alerts.ts delivery, connectorCatalog; app.qpoint.io Pulse /alerts, /events/alerts
18Connector registry with status, last_delivery_at, last_error; a redacting read path and secret store for /api/integrations/integrationsprojected/alerts.ts secretsAtRest; types/api/integration.ts (audit C)
19Server-side default routing on /api/channels/alertsprojected/alerts.ts defaultRoute
20entity_id on /api/costs rows and /api/performance rowsdrill-downstypes/api/cost.ts, performance.ts; projected/fleet.ts labelJoin
21Labels: provider label on /api/models, vendor label and os on /api/agent, category labels on /api/dlpModel, Harness install, DLPprojected/inventory.ts, security.ts (audit B)
22git {remote, host, branch} on /api/workspacesWorkspacestypes/api/workspace.ts; projected/inventory.ts (gap 9)
23Findings workflow: sla_due written, a finding_events log, expires_at, host on the rowFindingstypes/api/finding.ts; projected/security.ts (gap 6)
24Skill invocation as a session event; judged tool invocations (success rate); session summary; provider on session rowsSkills, Tools, Activityweb.rs skills comment; projected/inventory.ts toolSuccess; session.ts
25credential_risk on /api/inventory; posture factors on /api/agents; per-level counts for policy levelsIdentity, Posture, Policiesprojected/fleet.ts, compliance.ts levelCounts
26Live stream with a cursor or replay, from the plane's store; hub {connected, subscribers} on /api/stats/livetypes/api/live.ts; projected/alerts.ts liveInbound
27Sensor (qcontrol / native app) version, heartbeat and health per endpoint; show Stats.coverageEndpoints, reports, the self-hosted health pagec128 gap 4; data-inventory.md:95,103
28Deployment denominator (identity or MDM roster)coverage %c128 data-inventory.md (sensor-coverage-gap)
29Org scoping on every call and every row (even at one org per install, D3)SaaS laterc134 plan R1, D3
30Install status: first run, first admin, databases reachable, version, last update checkthe install wizard; the health pagec134 plan deliverable 5, patterns

Thirty gaps; the window (1–4) and identity (5–9) groups block the most pages.

7. Backend asks, consolidated

AskWhere it is already recordedStatus
from / to on every page; one window everywherec128 CYCLE.md:32, data-inventory.md gaps 1 and 5, plan.md:187; c134 plan "What exists"handed to Tyler 2026-11-03
History beyond 90 days; snapshotsc128 gaps 2–3; plan.md Phase 6handed to Tyler
Sensor version, heartbeat, healthc128 gap 4; data-inventory.md:95,103handed to Tyler
Seat prices (served, customer-entered)c105 plan.md:55 ("goes on the backend-asks list"); projected/people.ts gap 10open; c105 parked
Frameworks and policies served (R25 swaps)compliance/frameworks.ts, policies.ts; projected/compliance.ts gap 7; bible backlog B3open since c99
Every contract in lib/projected/*.ts (66 entries)the ledger itself (grep contract app/lib/projected)open since c99 audits A–C
/api/me, /api/settingspages/account.vue, pages/settings.vueplaceholders since c103
Connect credential, grants, messagesc131 D13, c136 D1, c137 D1; c134 D8ruled 2026-11-09, unspecified
IdP / SCIM identity sourceweb.rs teams_list doc commentnoted in code only
Alert engine and senderprojected/alerts.ts; app.qpoint.io composables/alerting/ as the specD7

8. For c135: what the web app needs that the layer (0.9.37) does not have

Start from ui/LAYER-CANDIDATES.md (17 staged components in ui/app/components/lib/: ProjectedBadge, ProjMark, ProjectedRing, SimulatedBadge, Panel, StatTile, Spark, MetricCell, BarList, AttentionStrip / Message / List / Reasons, JsonTree, AlertHandlers, SkeletonRows, StateEmpty; the composable useVirtualRows; and the state port for DataTable, UxTableList, BarList, DataMachine) plus the Opus track's 59 fixes (git show archive/qdash-opus-5.5:crates/qdash/apps/claude-code-opus-5.5/LAYER-CANDIDATES.md). Add, from app.qpoint.io's frame (all app-local there, none in q-nuxt-layer/components/):

NeedPrior artLayer today
Session card layout (logo over a white card)layouts/session.vuenone (layout/Grid only)
OAuth / SSO button with provider markcomponents/ux/OauthBtn.vuenone; UxButton has no provider variant
Sign-in / sign-up form with the SSO switchpages/sign-in.vue + useSSOUxInput, UxButton, form/* exist; the composition does not
Org switcherpages/orgs/components/Selector.vue (headlessui Listbox)UxSelect, UxPopover; no switcher
View / context selector (if views survive)orgs/components/contexts/Selector.vuenone
User menu popover (avatar → Account, Sign out)layouts/components/nav/User.vue, page/AccountMenu.vueUxAvatar, UxPopover; no menu
Invite member form with a role pickersettings/team/manage.vue, team/NewMember.vueUxCheckbox, form/SaveBar; no role picker
SSO provider form (OIDC / SAML)settings/sso.vue, sso/components/provider/*none
Secret / certificate box (copy, view, edit)ux/CertBox.vue, ux/CopyBox.vueUxCopyBtn, UxCode; no boxed secret
Wizard kit: Steps, EduHarness, PingListener (+radar), ToggleHarness, FinalStep, Sequincomponents/wizard/; design app/components/replicas/wizard/ (c125)prose/Step is a doc step, not a wizard
Onboarding checklist (task master + summary)components/task/Master.vue, Summary.vuenone
Toast stack + backend banner (R31 shell parts)qdash components/shell/ToastStack.vue, BackendBanner.vuenone
Date-range picker for the when: pill (from / to)c128 (ruled: the pill's panel)Filter has presets only
Export helper (CSV / JSON, print styles)qdash lib/download.ts; c128none
Code block with title, height and copy (the Snapshot page)ux/CodeHighlighter.vueUxCodeBlock: verify parity
Flash / incoming-deploy message strippage/Messages.vue, stores/flash.tsnone

Not needed if D1 holds: app.qpoint.io's PageMain / TopNav / teleported filter slot (qdash's shell is the frame's body), ux/Teleport, the traffic cells (HttpStatus, RequestMethod, table-list/td/*).

9. Open questions for Tyler and Kamal

  1. Is Pulse's source readable by design? Which of its patterns survive: the server-side filter grammar, /contexts (member-scoped views), the alert rule kinds?
  2. Identity: OIDC plus local accounts for self-hosted, SAML kept (D2). Who issues the session, and is it a cookie or a bearer the UI holds? Where do invitations live?
  3. Tenancy: one org per install (D3). Does the schema carry org_id on every row from day one so SaaS multi-org is a flag, not a migration?
  4. The window: from / to on every list and rollup, with period kept as presets; cut back from the wall clock or from the data's anchor (the baked worlds depend on the anchor)?
  5. Alerting (D7): does the Go app run the rule engine and the senders, with app.qpoint.io's four rule kinds and webhook adapter as the first spec, or is alerting a later phase?
  6. The live tail: a stream from the Go app over ClickHouse with a cursor, or polling only at first?
  7. Endpoint connect (c131 D13): credential format, enrolment, heartbeat cadence; does the heartbeat carry sensor version and health (gap 27)?
  8. Contract generation: TypeScript (and Rust for the native app) from the Go handlers or a shared schema, per c131 R3?
  9. demo.qpoint.io: do c113's baked worlds survive the new routes (they are keyed by URL), or is the demo re-baked against the new API?
  10. Host-local actions (agent/focus, agent/reveal): confirm they leave the plane for the native app.
  11. The qproxy settings (proxy, TLS, stacks, qtap filters): dropped, or does qproxy return under the plane?

Qpoint Brand Style Guide