# Evidence Hardening Plan v0.3.1

Status: draft plan
Baseline: Compact Canonical Entity Catalog v0.3.1
Scope: documentation / ontology evidence only

## 1. Цель

Evidence hardening нужен, чтобы текущий canonical catalog v0.3.1 перестал быть только продуктовой договорённостью и получил проверяемую source-backed основу.

Для каждой ключевой сущности каталога нужно собрать прямое evidence:

```text
file path + line/section + короткое объяснение, почему этот фрагмент подтверждает entity или relation
```

Прямое evidence не обязано доказывать всю будущую продуктовую семантику. Оно должно честно фиксировать один из статусов:

- `source-confirmed` — сущность прямо представлена в source;
- `source-evidenced/context-derived` — сущность выводится из source-backed context/flow;
- `product-required` — сущность нужна продуктово, но source пока неполный;
- `future concept` — концепт оставлен на будущее;
- `tech debt / non-canonical` — существующий source есть, но он не является canonical truth.

## 2. Scope

### HUB

Readonly source:

```text
data/nodedc_launcher
```

Цель: укрепить evidence для `hub.open_contour`, `hub.public_pool_context`, `hub.public_pool_client`, `hub.user`, `hub.membership`, `hub.application`, `hub.application_access`, invite/access-request flows и NDCAuth aliases.

### OPS

Readonly source:

```text
data/dc_taskmanager/NODEDC_TASKMANAGER
```

Цель: укрепить evidence для `ops.card`, card submodel, workspace/project/member/status/assignment/labels/comments/files/activity/external refs.

### OPS Gateway

Readonly source:

```text
data/NODEDC_TASKMANAGER_CODEXAPI
```

Цель: укрепить evidence для `agent.identity`, grants, scopes, tokens, MCP tools, idempotency, audit, Tasker adapter, AI Workspace entitlement.

### ENGINE

Readonly source:

```text
NODEDC/NODEDC_ENGINE_INFRA
```

Цель: укрепить evidence для `engine.application_boundary`, Engine L1/L2 workflow entities, ACL/share, L2 runtime core/IDs/events/source stamps, Assistant/Provider/Executor split, and tech-debt boundary.

### Запреты

Не читать и не использовать как evidence:

```text
runtime/data/storage/env/secrets/logs/dumps/node_modules/build outputs
.env / .env.*
credentials / keys / pem / ssh
DB dumps / archives / backup contents
postgres/Engine L2 runtime data
```

Не менять:

```text
source code
БД
миграции
docker files
package files
runtime config
```

Не запускать:

```text
bash
build
test
install
docker
migrations
servers
```

## 3. Entity groups needing direct evidence

### 3.1. HUB P0 — two-contour model

Entity ids:

```text
hub.open_contour
hub.public_pool_context
hub.public_pool_client
hub.client_context
hub.company_contour
```

Expected source files / search targets:

```text
data/nodedc_launcher/src/entities/public-pool/constants.ts
search: PUBLIC_POOL_CLIENT_ID
search: PUBLIC_POOL_CONTEXT_LABEL
search: PUBLIC_POOL_CONTEXT_DESCRIPTION
search: client_public_pool

data/nodedc_launcher/src/entities/client/types.ts
search: ClientType
search: ClientStatus
search: ClientTaskManagerWorkspaceBinding

data/nodedc_launcher/doc/base/nodedc_launcher_tz_frontend_mvp.md
search: Открытый контур
search: Клиент
search: Компания
```

Current confidence:

```text
source-evidenced/context-derived, owner-accepted baseline
```

Что надо проверить:

- что `client_public_pool` действительно source-backed special Client;
- что open contour не моделируется как ordinary `hub.client_context`;
- что closed managed context подтверждается через `Client`, memberships, groups, grants and TaskManager links.

Риск смешения терминов:

```text
Нельзя писать “hub.client inside hub.public_pool_context” как будто open contour является обычным managed client context.
Правильно: hub.public_pool_client is a source-backed special Client used by hub.public_pool_context.
```

### 3.2. HUB P0 — user, membership, access, application access

Entity ids:

```text
hub.user
hub.public_user
hub.client_user
hub.membership
hub.public_membership
hub.group
hub.role
hub.permission
hub.application
hub.application_access
hub.app_grant
hub.app_exception
hub.application_card
```

Expected source files / search targets:

```text
data/nodedc_launcher/src/entities/user/types.ts
search: LauncherUser
search: ClientMembership
search: ClientGroup
search: LauncherGlobalRole
search: ClientMembershipRole

data/nodedc_launcher/src/entities/access/types.ts
search: ServiceGrant
search: ServiceAccessException
search: EffectiveAccessResult
search: ServiceModuleEntitlement

data/nodedc_launcher/src/entities/access/computeEffectiveAccess.ts
search: computeEffectiveAccess
search: deny
search: allow

data/nodedc_launcher/src/entities/service/types.ts
search: Service
search: LauncherServiceView

data/nodedc_launcher/src/shared/lib/permissions.ts
search: resolvePermissions
search: LauncherPermissions

data/nodedc_launcher/src/widgets/service-rail/ServiceRail.tsx
search: ServiceRail

data/nodedc_launcher/src/widgets/service-stage/ServiceStage.tsx
search: ServiceStage
```

Current confidence:

```text
source-confirmed for base user/membership/group/application/access;
context-derived for public/client user classifications;
UI-confirmed for hub.application_card.
```

Что надо проверить:

- `hub.user` is source-backed by `LauncherUser`;
- `hub.public_user` and `hub.client_user` are classifications of `hub.user`, not hard entities;
- access authority belongs to `hub.application_access`, `hub.app_grant`, `hub.app_exception`;
- `hub.application_card` is presentation/UI only.

Риск смешения терминов:

```text
hub.application_card не является permission authority.
HUB app access не равен Engine workflow ACL.
```

### 3.3. HUB P1 — invite, access request, sync, NDCAuth aliases

Entity ids:

```text
hub.invite
hub.public_invite
hub.client_invite
hub.access_request
hub.public_access_request
hub.client_access_request
hub.sync_status
ndcauth.identity
ndcauth.session
```

Expected source files / search targets:

```text
data/nodedc_launcher/src/entities/invite/types.ts
search: InviteStatus
search: source
search: sourceTaskerInviteRequestId

data/nodedc_launcher/src/entities/access-request/types.ts
search: AccessRequest
search: targetClientId
search: approvedInviteId

data/nodedc_launcher/src/entities/sync/types.ts
search: SyncStatus
search: SyncTarget

data/nodedc_launcher/src/shared/api/authApi.ts
search: AuthUser
search: AuthSession
search: groups
search: /api/me

data/nodedc_launcher/server/dev-server.mjs
search: /api/access-requests
search: /api/invites
search: /api/internal/handoff/consume
search: /api/internal/access/check
```

Current confidence:

```text
source-confirmed for generic invite/access_request/sync/auth;
context-derived for public/client classifications.
```

Что надо проверить:

- access request can be classified by contour/context and target client;
- invite can be classified by contour/context and source/target;
- Authentik/OIDC/JWT names remain NDCAuth implementation aliases.

Риск смешения терминов:

```text
NDCAuth product names must not be replaced by Authentik/OIDC/JWT implementation aliases.
```

### 3.4. OPS P0 — card core

Entity ids:

```text
ops.workspace
ops.project
ops.card
ops.card_status
ops.card_priority
ops.card_assignment
ops.assignee
ops.responsible
ops.card_type
ops.card_relation
```

Expected source files / search targets:

```text
data/dc_taskmanager/NODEDC_TASKMANAGER/plane-src/apps/api/plane/db/models/workspace.py
search: class Workspace
search: class WorkspaceMember

data/dc_taskmanager/NODEDC_TASKMANAGER/plane-src/apps/api/plane/db/models/project.py
search: class Project
search: class ProjectMember
search: project_lead
search: default_assignee

data/dc_taskmanager/NODEDC_TASKMANAGER/plane-src/apps/api/plane/db/models/issue.py
search: class Issue
search: PRIORITY_CHOICES
search: state = models.ForeignKey
search: assignees = models.ManyToManyField
search: IssueAssignee
search: parent
search: type = models.ForeignKey

data/dc_taskmanager/NODEDC_TASKMANAGER/plane-src/apps/api/plane/db/models/state.py
search: class State
search: StateGroup
```

Current confidence:

```text
source-confirmed for workspace/project/card/status/priority/assignment/assignee;
product-required for responsible;
inferred/product-defined for card_type and card_relation until direct evidence is attached.
```

Что надо проверить:

- `Plane Issue` is source alias for canonical `ops.card`;
- `ops.card_priority` is card attribute, not global root;
- `ops.responsible` remains separate from `ops.assignee` and may be product-required;
- `IssueType` must not be overclaimed as source-confirmed unless direct evidence is strong.

Риск смешения терминов:

```text
task / issue / work item are aliases or card types, not canonical root.
Canonical root remains ops.card.
```

### 3.5. OPS P1 — card artifacts, activity, external refs

Entity ids:

```text
ops.card_label
ops.card_comment
ops.card_artifact_link
ops.file_asset
ops.stored_blob
ops.card_activity
ops.external_ref
```

Expected source files / search targets:

```text
data/dc_taskmanager/NODEDC_TASKMANAGER/plane-src/apps/api/plane/db/models/label.py
search: class Label

data/dc_taskmanager/NODEDC_TASKMANAGER/plane-src/apps/api/plane/db/models/issue.py
search: IssueLabel
search: IssueComment
search: IssueAttachment
search: IssueActivity
search: external_source
search: external_id

data/dc_taskmanager/NODEDC_TASKMANAGER/plane-src/apps/api/plane/db/models/asset.py
search: class FileAsset
search: class StoredBlob
search: sha256
search: canonical_object_key
search: storage_metadata
```

Current confidence:

```text
source-confirmed for labels/comments/attachments/file assets/stored blobs;
activity source-evidenced but exact event taxonomy needs hardening.
```

Что надо проверить:

- `ops.card_artifact_link` is relation/link, not global artifact root;
- `ops.file_asset` is OPS-local Plane `FileAsset`;
- `ops.stored_blob` is OPS-local `StoredBlob`;
- `ops.artifact` must not become a competing global artifact root.

Риск смешения терминов:

```text
Do not collide OPS-local file evidence with future global artifact layer.
```

### 3.6. OPS Gateway P1 — agent, grants, idempotency, audit

Entity ids:

```text
agent.identity
agent.token
agent.grant
agent.scope
agent.mcp_tool
agent.idempotency_key
agent.audit_event
agent.ai_workspace_entitlement
agent.tasker_adapter
```

Expected source files / search targets:

```text
data/NODEDC_TASKMANAGER_CODEXAPI/docs/ARCHITECTURE.md
search: Agent Gateway owns
search: agent
search: agent_token
search: agent_grant
search: pairing_code
search: agent_audit_event
search: idempotency_key

data/NODEDC_TASKMANAGER_CODEXAPI/docs/MCP_TOOLS_CONTRACT.md
search: tasker_
search: idempotency_key
search: denied tools

data/NODEDC_TASKMANAGER_CODEXAPI/src/repositories/agents.ts
search: agent_tokens
search: token_hash
search: agent_grants
search: idempotency_keys

data/NODEDC_TASKMANAGER_CODEXAPI/src/domain/scopes.ts
search: workspace:read
search: issue:create

data/NODEDC_TASKMANAGER_CODEXAPI/src/mcp/tool-runtime.ts
search: tasker_
search: claimIdempotencyKey

data/NODEDC_TASKMANAGER_CODEXAPI/src/routes/agents.ts
search: ai-workspace/entitlements
search: preflight

data/NODEDC_TASKMANAGER_CODEXAPI/src/tasker/client.ts
search: internal/nodedc/agent
```

Current confidence:

```text
source-confirmed for agent identity/tokens/grants/scopes/MCP/idempotency;
audit source-evidenced by docs and code search;
Tasker adapter source-confirmed by docs/API contract, exact code links pending.
```

Что надо проверить:

- Agent Identity is technical identity with owner, grants, scopes, tokens;
- Assistant/Agent split remains intact;
- MCP tools can request/perform scoped operations, not freely mutate OPS cards;
- writes require grants/scopes/idempotency/audit.

Риск смешения терминов:

```text
Codex is Assistant Provider, not Agent superclass.
Agent Identity is not Hub User.
```

### 3.7. ENGINE P0 — application boundary and tech debt boundary

Entity ids:

```text
engine.application_boundary
engine.tech_debt.ops_adapter
```

Expected source files / search targets:

```text
NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/server/index.js
search: /auth/nodedc/handoff
search: NODEDC_LAUNCHER
search: /api/internal/access/check

NODEDC/NODEDC_ENGINE_INFRA/.ai-bridge/core-ontology-owner-decisions.md
search: engine.application_boundary
search: Engine-side OPS
search: Agent Monitor
search: tender-agent

NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/server/routes/ops.js
search only, do not treat as canonical OPS:
search: opsAgentInstanceId
search: tender
search: activeTemplateId

NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/src/driveinspector/nodes/AgentMonitor.definition.ts
search: AgentMonitor
```

Current confidence:

```text
owner-confirmed for application boundary;
tech debt / non-canonical for Engine-side OPS / Agent Monitor / tender config.
```

Что надо проверить:

- HUB to ENGINE goes through `engine.application_boundary`;
- no direct HUB relation to workflow internals;
- Engine-side OPS remains tech debt and non-canonical.

Риск смешения терминов:

```text
Do not use ENGINE server/routes/ops.js as OPS product truth.
```

### 3.8. ENGINE P1 — L1/L2 workflow/runtime IDs

Entity ids:

```text
engine.workflow_l1
engine.node_l1
engine.edge_l1
engine.node_type_l1
engine.workflow_acl
engine.workflow_owner
engine.workflow_share
engine.workflow_access_request
engine.workflow_l2
engine.node_l2
engine.l2_runtime_core
engine.workflow_l2_runtime_id
engine.l2_execution
engine.l2_run
engine.l2_session
engine.l2_runtime_event
engine.source_stamp
```

Expected source files / search targets:

```text
NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/src/store.ts
search: nodes
search: edges
search: updateNodeData
search: sourceHandle
search: targetHandle

NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/src/nodes/autoRegistry.ts
search: nodeTypes
search: meta.type
search: TYPE_LABEL

NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/server/workflows/acl.js
search: ROLE_RANK
search: owner
search: users
search: groups
search: invites
search: canRead
search: canWrite

NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/server/index.js
search: /api/workflows
search: /api/workflows/:id/share
search: workflow-access-requests
search: engine-role-access-requests

Engine execution deployment route
search: runtimeWorkflowId
search: resolveNodeDcByRuntimeWorkflowId
search: resolveWorkflowIdByNodeDcBindingRest
search: executionId

NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/server/ops/runtimeTap.js
search: runtimeWorkflowId
search: runtime core id
search: executionId
search: runId
search: sessionId

Engine execution runtime hooks
search: workflow:start
search: workflow:finish
search: node:start
search: node:success
search: node:error

NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/server/routes/ndcAgentMcp.js
search: editedBy
search: editedAt
search: editIntent
```

Current confidence:

```text
source-evidenced by previous ENGINE pass; direct links pending.
```

Что надо проверить:

- L1 and L2 remain separate concrete workflow types;
- L2 runtime ID is not same as product workflow identity;
- runtime core/id/event concepts have direct source anchors.

Риск смешения терминов:

```text
The Engine L2 runtime is the only canonical product term in ontology and documentation.
```

### 3.9. ENGINE / Assistant P1 — Assistant, Provider, Executor, Bridge

Entity ids:

```text
assistant.assistant
assistant.provider
assistant.executor
assistant.thread
assistant.message
assistant.bridge
```

Expected source files / search targets:

```text
NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/server/routes/aiWorkspace.js
search: EXECUTOR_TYPES
search: normalizeExecutor
search: thread
search: message
search: bridge
search: requestBridge

NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/server/aiWorkspace/assistantRegistryClient.js
search: provider
search: executor
search: owner

NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/src/components/ai/AIWorkspaceConsole.tsx
search: executor
search: thread
search: Ops workspace
search: Ops project

NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/workers/ai-workspace-bridge/worker.mjs
search: workspaces
search: bridge
search: events
```

Current confidence:

```text
source-confirmed by previous ENGINE/AI Workspace pass; direct links should be hardened.
```

Что надо проверить:

- Assistant is product-facing interactive layer;
- Codex is Assistant Provider;
- Executor/Bridge are runtime/connection concepts;
- Agent Identity belongs to OPS Gateway and is not the Assistant superclass.

Риск смешения терминов:

```text
Do not model Codex as Agent superclass.
Do not collapse Assistant and Agent Identity.
```

## 4. Priority order

### P0

```text
HUB two-contour model
hub.user / membership / access / application access
ops.card core
ENGINE application boundary
Engine-side OPS tech debt boundary
```

### P1

```text
OPS artifacts / activity / external refs
OPS Gateway agent / grants / idempotency / audit
ENGINE L1/L2 workflow / runtime IDs
ENGINE Assistant / Provider / Executor split
```

### P2

```text
future concepts / product-required terms:
ops.responsible
ops.card_type taxonomy
ops.card_relation taxonomy
artifact.version / 3D model versioning
final global artifact/event layer
Agent Monitor future product role
```

## 5. Output artifacts

Следующие документы нужно создать после hardening passes:

```text
ontology/EVIDENCE_LEDGER.md
ontology/CANONICAL_ENTITY_CATALOG.md
ontology/RELATION_CATALOG.md
ontology/GUARDRAILS.md
ontology/OPEN_QUESTIONS.md
```

### ontology/EVIDENCE_LEDGER.md

Назначение: file+line ledger для каждой entity/relation.

Минимальная строка:

```text
Entity ID | Canonical name | Source root | Evidence file | Evidence line/section | Evidence status | Explanation | Notes
```

### ontology/CANONICAL_ENTITY_CATALOG.md

Назначение: frozen catalog после evidence hardening.

### ontology/RELATION_CATALOG.md

Назначение: canonical relations and boundaries.

### ontology/GUARDRAILS.md

Назначение: settled terminology and forbidden conflations.

### ontology/OPEN_QUESTIONS.md

Назначение: owner/product decisions not yet closed.

## 6. Next safe task

Следующая маленькая безопасная задача:

```text
Сделать HUB P0 evidence ledger section.
```

Scope следующей задачи:

```text
Только NodeDC HUB Readonly.
Только source/docs files, без runtime/data/storage/env/secrets/logs/dumps.
Собрать file+line evidence для:
- hub.open_contour
- hub.public_pool_context
- hub.public_pool_client
- hub.user
- hub.public_membership
- hub.membership
- hub.application
- hub.application_access
- hub.app_grant
- hub.app_exception
- hub.application_card
- ndcauth.identity
- ndcauth.session
```
