# Evidence Ledger — HUB P0

Status: first source-backed ledger section
Baseline: Compact Canonical Entity Catalog v0.3.1
Date: 2026-06-18
Scope: HUB / Launcher / NDCAuth P0 evidence

Source root:

```text
/Users/dcconstructions/Downloads/mnt/data/nodedc_launcher
```

Restrictions observed:

- Source inspection only.
- No runtime/data/storage/env/secrets/logs/dumps.
- No source code edits.
- No build/test/install/docker/bash execution for the source repos.

## Summary

This pass confirms the core HUB P0 ontology:

- `hub.open_contour` is the product-level open contour.
- `hub.public_pool_context` is the source-backed public pool context.
- `hub.public_pool_client` is a source-backed special `Client` with id `client_public_pool`.
- `hub.open_contour` must not be treated as an ordinary `hub.client_context`.
- `hub.user` is source-backed by `LauncherUser`.
- `hub.public_user` / `hub.client_user` are context classifications of `hub.user`, not separate hard user entities.
- `hub.application_access`, `hub.app_grant`, and `hub.app_exception` are permission/policy concepts.
- `hub.application_card` is UI/presentation over `LauncherServiceView`, not permission authority.
- `ndcauth.identity` and `ndcauth.session` are backed by Auth/OIDC session types; Authentik/OIDC/JWT remain implementation aliases.

## Entity Evidence

| Entity ID | Canonical name | Evidence status | Evidence file:line | Evidence explanation | Notes |
| --- | --- | --- | --- | --- | --- |
| `hub.open_contour` | Hub Open Contour | source-evidenced / owner-confirmed | `src/entities/public-pool/constants.ts:3-5` | Defines `PUBLIC_POOL_CLIENT_ID`, `PUBLIC_POOL_CONTEXT_LABEL = "Открытый контур"`, and `PUBLIC_POOL_CONTEXT_DESCRIPTION = "Public access pool"`. | Product-level canonical open contour. |
| `hub.public_pool_context` | Hub Public Pool Context | source-confirmed | `src/entities/public-pool/constants.ts:3-5` | Public pool constants define the concrete source-backed public context. | Source-backed context alias for open contour. |
| `hub.public_pool_client` | Hub Public Pool Client | source-confirmed special Client | `src/entities/public-pool/constants.ts:7-20` | `PUBLIC_POOL_CLIENT` is typed as `Client`, uses id `client_public_pool`, type `person`, label `Открытый контур`, and note says it is the system contour for public requests, public invites, and self-service users. | This confirms special source-backed Client, not ordinary client context. |
| `hub.client_context` | Hub Client Context | source-confirmed / context-derived | `src/entities/client/types.ts:1-36` | `Client` supports `company` and `person`, status fields, contract/demo fields, contact fields, and TaskManager workspace bindings. | Safer canonical name for closed managed context. |
| `hub.company_contour` | Hub Company Contour | alias / subtype | `src/widgets/admin-overlay/AdminOverlay.tsx:431-443` | Admin UI separates `Открытый контур` from a `Компании` selector backed by `data.clients`. | Product wording/subtype over managed `hub.client_context`. |
| `hub.user` | Hub User / Launcher User | source-confirmed | `src/entities/user/types.ts:10-22` | `LauncherUser` defines the source user entity with `id`, `authentikUserId`, email, name, global status, timestamps. | Core user entity. |
| `hub.public_user` | Hub Public User Classification | source-evidenced / context-derived | `src/widgets/admin-overlay/AdminOverlay.tsx:4760-4799` | `getPlatformUserOrigin` detects a public-pool membership and labels the same user as open-contour/self-service/access-request/invite origin. | Classification of `hub.user`, not hard user class. |
| `hub.client_user` | Hub Client User Classification | source-evidenced / context-derived | `src/widgets/admin-overlay/AdminOverlay.tsx:4801-4809` | If memberships exist outside public handling, UI labels the user as `Компания · ${client.name}` with client legal name. | Classification of `hub.user`, not hard user class. |
| `hub.membership` | Hub Client Membership | source-confirmed | `src/entities/user/types.ts:24-40` | `ClientMembership` links `clientId`, `userId`, role, status, invite/source metadata, and timestamps. | Main user-to-client/context link. |
| `hub.public_membership` | Hub Public Pool Membership | source-confirmed / context-derived | `server/control-plane-store.mjs:3368-3400` | `upsertAccessRequestMembership` defaults `clientId` to `publicPoolClientId`, creates membership with `source: "access_request"` and default disabled status. | Public status comes from membership context. |
| `hub.public_access_request` | Hub Public Access Request | source-evidenced / context-derived | `server/control-plane-store.mjs:713-793` | Public access request creation upserts user, creates disabled public-pool membership, and creates access request with `targetClientId: publicPoolClientId`. | Classification of `hub.access_request`. |
| `hub.client_access_request` | Hub Client Access Request | source-evidenced / context-derived | `server/control-plane-store.mjs:822-890` | Approval resolves target client, activates membership in the selected client, and removes pending public-pool membership when target client is not public pool. | Shows promotion from public request into managed client context. |
| `hub.access_request` | Hub Access Request | source-confirmed | `src/entities/access-request/types.ts:5-22` | `AccessRequest` has email/name/company, status, `targetClientId`, role, approval/review fields. | Base entity for public/client classifications. |
| `hub.invite` | Hub Invite | source-confirmed | `src/entities/invite/types.ts:5-21` | `Invite` has `clientId`, email, role, source, Tasker source refs, token, expiry, status. | Base entity for public/client invite classifications. |
| `hub.group` | Hub Client Group | source-confirmed | `src/entities/user/types.ts:42-50` | `ClientGroup` links group to `clientId` and `memberIds`. | Client-local group. |
| `hub.role` | Hub Role | source-confirmed | `src/entities/user/types.ts:1-6`, `src/entities/user/types.ts:24-25` | Defines global roles and membership roles. | Role vocabulary for HUB. |
| `hub.permission` | Hub Permission | source-confirmed | `src/shared/lib/permissions.ts:3-11`, `src/shared/lib/permissions.ts:21-39` | Defines `LauncherPermissions` and derives permissions from launcher role and membership status. | Permission resolution helper. |
| `hub.application` | Hub Application | source-confirmed | `src/entities/service/types.ts:7-36` | `Service` defines app/service catalog entity with slug/title/URL/status/media/Auth aliases. | Canonical product application/service concept. |
| `hub.application_access` | Hub Application Access | source-confirmed | `src/entities/access/types.ts:28-38` | `EffectiveAccessResult` stores service/user access outcome, visibility, open-enabled, app role, reason, source. | Policy/debug entity for effective app access. |
| `hub.app_grant` | Hub App Access Grant | source-confirmed | `src/entities/access/types.ts:1-14` | `ServiceGrant` targets `client`, `group`, or `user` and grants an app role for a service. | Authority input for app access. |
| `hub.app_exception` | Hub App Access Exception | source-confirmed | `src/entities/access/types.ts:16-26` | `ServiceAccessException` stores user-specific `deny` or `allow` exceptions. | Override layer for app access. |
| `hub.application_card` | Hub Application Card | source-confirmed UI/view only | `src/entities/service/types.ts:45-72`, `src/widgets/service-rail/ServiceRail.tsx:6-52`, `src/widgets/service-stage/ServiceStage.tsx:22-147` | `LauncherServiceView` includes display fields and `effectiveAccess`; `ServiceRail` renders service tiles; `ServiceStage` renders a launch/detail surface using `effectiveAccess`. | Presentation over `hub.application` + access state, not permission authority. |
| `ndcauth.identity` | NDCAuth Identity | source-confirmed with implementation aliases | `src/shared/api/authApi.ts:1-8`, `src/entities/user/types.ts:10-13` | `AuthUser` has `sub`, email/name/groups; `LauncherUser` stores `authentikUserId`. | Authentik/OIDC subject is implementation alias. |
| `ndcauth.session` | NDCAuth Session | source-confirmed | `src/shared/api/authApi.ts:10-23`, `server/dev-server.mjs:270-294` | `AuthSession` represents authenticated/unauthenticated session; `/api/me` returns authenticated runtime session user and groups or login URL. | Session model for launcher runtime. |

## Relation / Flow Evidence

| Relation / guardrail | Evidence status | Evidence file:line | Evidence explanation |
| --- | --- | --- | --- |
| `hub.open_contour` is not ordinary `hub.client_context` | source-evidenced / owner-confirmed | `src/widgets/admin-overlay/AdminOverlay.tsx:411-443` | Admin UI shows a dedicated public-pool context switcher and a separate `Компании` selector. |
| Public pool supports public requests/invites/self-service users | source-confirmed | `src/entities/public-pool/constants.ts:7-20` | The special Client note explicitly says it is the system contour for public requests, public invites, and self-service users. |
| Public access request creates disabled public-pool membership | source-confirmed | `server/control-plane-store.mjs:740-742`, `server/control-plane-store.mjs:3368-3400` | Request creation upserts user and membership; membership helper defaults to `publicPoolClientId` and disabled status. |
| Public request can promote into client/company context | source-confirmed | `server/control-plane-store.mjs:846-865` | Approval creates active membership for target client; if target is not public pool, pending public-pool membership is removed. |
| App access is derived from grants/exceptions, not UI cards | source-confirmed | `src/entities/access/computeEffectiveAccess.ts:31-132` | Effective access checks deny/allow exceptions, user grants, group grants, client grants, then blocks by default. |
| `hub.application_card` is presentation over access state | source-confirmed | `src/entities/service/types.ts:45-72`, `src/widgets/service-stage/ServiceStage.tsx:101-126` | UI view includes `effectiveAccess`; launch button checks `service.effectiveAccess.openEnabled`, but authority is from access computation. |
| NDCAuth uses OIDC/JWT/Auth implementation evidence | source-confirmed | `server/dev-server.mjs:2475-2505`, `server/dev-server.mjs:270-294` | Server verifies JWT/OIDC claims, normalizes `sub/email/groups`, and serves `/api/me`. |

## Guardrails Confirmed

```text
hub.public_pool_client is a source-backed special Client used by hub.public_pool_context.
hub.open_contour must not be treated as an ordinary hub.client_context.
hub.user is the core user entity.
hub.public_user and hub.client_user are context classifications of hub.user.
hub.application_card is UI/presentation only, not permission authority.
hub.application_access / hub.app_grant / hub.app_exception are the app-access policy concepts.
NDCAuth is canonical; Authentik/OIDC/JWT remain implementation aliases.
```

## Open Questions / Follow-up

1. `hub.client_access_request` is source-evidenced by target-client approval flow, but final product wording should decide whether it remains a formal classification or only a relation state of `hub.access_request`.
2. `hub.public_invite` / `hub.client_invite` have base source evidence through `Invite.clientId`; a later HUB P1 pass should harden exact classification rules by public-pool vs client target.
3. Add these rows into the future combined `ontology/EVIDENCE_LEDGER.md` after OPS/ENGINE evidence sections are ready.
