feat(ontology): add core service catalog

This commit is contained in:
Codex
2026-06-20 12:54:03 +03:00
parent 83cca4224b
commit 2d5fef3948
59 changed files with 7878 additions and 0 deletions
@@ -0,0 +1,164 @@
# Canonical Entity Catalog v0.4-pre
Status: pre-release implementation baseline
Date: 2026-06-18
Scope: NodeDC core ontology for HUB, OPS, OPS Gateway, ENGINE, Assistant routing, and future interface layer.
This catalog is the current canonical naming baseline. It is intentionally compact:
implementation can start from it, while open items stay marked instead of being hidden.
## Evidence Status
- `source-confirmed`: direct code/schema evidence exists.
- `source-evidenced`: source supports the concept, but naming or boundary is partly product-level.
- `owner-confirmed`: confirmed by product/architecture discussion.
- `product-required`: needed for target platform behavior, not fully implemented yet.
- `future-concept`: planned service/domain concept, not a current source truth.
- `tech-debt-noncanonical`: current working code that must not define the canonical model.
- `pending`: keep as candidate until a deeper source pass confirms it.
## HUB / Launcher
| Entity ID | Canonical name | Status | Authority | Notes |
| --- | --- | --- | --- | --- |
| `hub.open_contour` | HUB Open Contour | source-evidenced / owner-confirmed | HUB | Public/open branch for simple users. Must be separate from company/client contour. |
| `hub.public_pool_context` | HUB Public Pool Context | source-confirmed | HUB | Source-backed public context. |
| `hub.public_pool_client` | HUB Public Pool Client | source-confirmed | HUB | Special source-backed `Client`, not an ordinary company/client. |
| `hub.client_context` | HUB Client Context | source-confirmed | HUB | Managed closed contour for companies/clients. |
| `hub.company_contour` | HUB Company Contour | source-evidenced alias/subtype | HUB | Product wording over managed `hub.client_context`. |
| `hub.user` | HUB User | source-confirmed | HUB / NDCAuth bridge | Canonical user in launcher domain. |
| `hub.public_user` | HUB Public User Classification | source-evidenced | HUB | Classification of `hub.user` by public-pool membership/origin. |
| `hub.client_user` | HUB Client User Classification | source-evidenced | HUB | Classification of `hub.user` by client/company membership. |
| `hub.membership` | HUB Membership | source-confirmed | HUB | User-to-client/context relation. |
| `hub.public_membership` | HUB Public Membership | source-confirmed | HUB | Membership in public pool context. |
| `hub.access_request` | HUB Access Request | source-confirmed | HUB | Base access request entity. |
| `hub.public_access_request` | HUB Public Access Request | source-evidenced | HUB | Public/open-contour access request subtype. |
| `hub.client_access_request` | HUB Client Access Request | source-evidenced | HUB | Company/client-context access request subtype. |
| `hub.invite` | HUB Invite | source-confirmed | HUB | Invitation into a context. |
| `hub.group` | HUB Group | source-confirmed | HUB | Client-local group. |
| `hub.role` | HUB Role | source-confirmed | HUB | Role vocabulary for user/membership decisions. |
| `hub.permission` | HUB Permission | source-confirmed | HUB | Derived permission capability. |
| `hub.application` | HUB Application | source-confirmed | HUB | Product application/service registered in launcher. |
| `hub.application_access` | HUB Application Access | source-confirmed | HUB | Effective app access result. |
| `hub.app_grant` | HUB App Grant | source-confirmed | HUB | Access authority input. |
| `hub.app_exception` | HUB App Exception | source-confirmed | HUB | User-specific allow/deny override. |
| `hub.application_card` | HUB Application Card | source-confirmed UI/view | HUB UI | Presentation over application/access state; not access authority. |
## NDCAuth
| Entity ID | Canonical name | Status | Authority | Notes |
| --- | --- | --- | --- | --- |
| `ndcauth.identity` | NDCAuth Identity | source-confirmed | NDCAuth / HUB | Canonical auth identity. Authentik/OIDC/JWT are implementation aliases. |
| `ndcauth.session` | NDCAuth Session | source-confirmed | NDCAuth / HUB | Runtime authenticated/unauthenticated session. |
## OPS Product
OPS Product is the operational project/work layer. It is not ENGINE-side OpsLayer, Agent Monitor, tender-agent config, or OPS Gateway.
| Entity ID | Canonical name | Status | Authority | Notes |
| --- | --- | --- | --- | --- |
| `ops.workspace` | OPS Workspace | source-confirmed | OPS Product | Workspace/root collaboration context. |
| `ops.workspace_member` | OPS Workspace Member | source-confirmed | OPS Product | User membership in workspace. |
| `ops.project` | OPS Project | source-confirmed | OPS Product | Project inside workspace. |
| `ops.project_member` | OPS Project Member | source-confirmed | OPS Product | User membership in project. |
| `ops.card` | OPS Card | source-confirmed / owner-confirmed | OPS Product | Canonical work object. Plane `Issue`, task, work item are aliases/types. |
| `ops.card_status` | OPS Card Status | source-confirmed | OPS Product | State/status of a card. |
| `ops.card_priority` | OPS Card Priority | source-confirmed | OPS Product | Attribute of `ops.card`, not a root domain object. |
| `ops.card_assignment` | OPS Card Assignment | source-confirmed | OPS Product | Relation between card and assignee. |
| `ops.assignee` | OPS Assignee | source-confirmed | OPS Product | Assigned user/member. |
| `ops.responsible` | OPS Responsible | product-required / source-adjacent | OPS Product | Product-needed accountability role; not identical to assignee until source semantics are hardened. |
| `ops.card_type` | OPS Card Type | source-evidenced / pending taxonomy | OPS Product | Type/subtype of card: task, report, milestone, mailstone, architecture block, etc. |
| `ops.card_relation` | OPS Card Relation | source-confirmed | OPS Product | Dependency/link between cards. |
| `ops.external_ref` | OPS External Reference | source-confirmed | OPS Product | Link to external/source object. |
| `ops.card_label` | OPS Card Label | source-confirmed | OPS Product | Label/tag classification. |
| `ops.card_comment` | OPS Card Comment | source-confirmed | OPS Product | Discussion/comment on a card. |
| `ops.card_activity` | OPS Card Activity | source-evidenced | OPS Product | Change/activity history. |
| `ops.card_artifact_link` | OPS Card Artifact Link | source-evidenced | OPS Product | Relation/link to output artifact; not a global artifact root. |
| `ops.file_asset` | OPS File Asset | source-evidenced | OPS Product | File attached/linked through OPS. |
| `ops.stored_blob` | OPS Stored Blob | source-evidenced | OPS Product | Storage-level blob behind file assets. |
## OPS Gateway / MCP Agent Access
OPS Gateway is the scoped MCP/API access layer for agents. It does not own OPS product truth.
| Entity ID | Canonical name | Status | Authority | Notes |
| --- | --- | --- | --- | --- |
| `agent.identity` | Agent Identity | source-confirmed | OPS Gateway | Execution identity for an agent/client in Gateway, not a universal assistant persona. |
| `agent.token` | Agent Token | source-confirmed | OPS Gateway | Opaque credential; not user identity. |
| `agent.session` | Agent Session | source-confirmed | OPS Gateway | Runtime/session envelope for agent operations. |
| `agent.grant` | Agent Grant | source-confirmed | OPS Gateway | Permission grant for agent identity/session. |
| `agent.token_grant` | Token Grant | source-confirmed | OPS Gateway | Token-to-grant binding. |
| `agent.scope` | Agent Scope | source-confirmed | OPS Gateway | Tool/capability permission, not OPS role. |
| `agent.denied_capability` | Denied Capability | source-confirmed | OPS Gateway | Explicitly unavailable operation. |
| `agent.mcp_tool` | MCP Tool | source-confirmed | OPS Gateway | Exposed callable tool surface. |
| `agent.idempotency_key` | Idempotency Key | source-confirmed | OPS Gateway | Required write-safety key. |
| `agent.audit_event` | Agent Audit Event | source-confirmed | OPS Gateway | Audit trail for agent actions. |
| `agent.tasker_adapter` | Tasker Adapter | source-confirmed | OPS Gateway | Adapter to Tasker/OPS product API. |
| `agent.setup_packet` | Agent Setup Packet | source-evidenced | OPS Gateway | Setup payload for creating client app/tool access. |
| `agent.ai_workspace_entitlement` | AI Workspace Entitlement | source-evidenced / pending boundary | HUB + OPS Gateway | Entitlement/access context for AI workspace; exact entity vs policy boundary needs hardening. |
| `agent.pairing_code` | Pairing Code | source-evidenced / pending route hardening | OPS Gateway | Pairing/setup flow candidate. |
## ENGINE / Workflow System
ENGINE remains workflow/dev environment. It may reference OPS and assistants, but it is not the place for heavy product UI.
| Entity ID | Canonical name | Status | Authority | Notes |
| --- | --- | --- | --- | --- |
| `engine.workflow_l1` | ENGINE L1 Workflow | source-confirmed | ENGINE | NodeDC canvas/workflow stored as workflow metadata and graph. |
| `engine.node_l1` | ENGINE L1 Node | source-confirmed | ENGINE | React Flow node in L1 graph. |
| `engine.edge_l1` | ENGINE L1 Edge | source-confirmed | ENGINE | React Flow edge in L1 graph. |
| `engine.node_type_l1` | ENGINE L1 Node Type | source-confirmed | ENGINE | Auto-registered node type/module. |
| `engine.workflow_acl` | ENGINE Workflow ACL | source-confirmed | ENGINE | Workflow-level ACL with viewer/editor/owner/admin roles. |
| `engine.workflow_owner` | ENGINE Workflow Owner | source-confirmed | ENGINE | Owner field in ACL. |
| `engine.workflow_share` | ENGINE Workflow Share | source-confirmed | ENGINE | Share/invite/user access routes. |
| `engine.workflow_access_request` | ENGINE Workflow Access Request | source-confirmed | ENGINE | Access request route/model for workflow access. |
| `engine.workflow_l2` | ENGINE L2 Workflow | source-evidenced | ENGINE / n8n bridge | n8n subworkflow attached to L1 node by `workflowId` + `nodeId`. |
| `engine.node_l2` | ENGINE L2 Node | source-evidenced | ENGINE / n8n bridge | Node inside compiled/deployed n8n workflow. |
| `engine.l2_runtime_core` | ENGINE L2 Runtime Core | source-evidenced | ENGINE / n8n bridge | Target n8n runtime/core instance. |
| `engine.workflow_l2_runtime_id` | ENGINE L2 Runtime Workflow ID | source-confirmed | ENGINE / n8n bridge | n8n runtime workflow id, separate from NodeDC workflow id. |
| `engine.l2_execution` | ENGINE L2 Execution | source-confirmed | ENGINE / n8n bridge | n8n execution id mapped to run/execution records. |
| `engine.l2_run` | ENGINE L2 Run | source-confirmed | ENGINE-side OpsLayer | Runtime run id used to bind execution/session. Current implementation is tech-debt-adjacent. |
| `engine.l2_session` | ENGINE L2 Session | source-confirmed | ENGINE-side OpsLayer | Runtime session anchor, often derived from run id if upstream omits session id. |
| `engine.l2_runtime_event` | ENGINE L2 Runtime Event | source-confirmed | ENGINE / n8n bridge | `workflow:start`, `workflow:finish`, `node:start`, `node:success`, `node:error`. |
| `engine.source_stamp` | ENGINE Source Stamp | pending | ENGINE | Candidate for future source/version traceability. |
## Assistant / AI Workspace
These entities are required by near-term routing, but need a dedicated AI Workspace evidence pass before they become fully source-confirmed.
| Entity ID | Canonical name | Status | Authority | Notes |
| --- | --- | --- | --- | --- |
| `assistant.assistant` | Assistant | product-required / pending source pass | AI Workspace | User-facing assistant capability/persona. |
| `assistant.provider` | Assistant Provider | product-required / pending source pass | AI Workspace | Model/provider integration boundary. |
| `assistant.executor` | Assistant Executor | product-required / pending source pass | AI Workspace / Codex / MCP | Execution adapter: Codex, MCP tools, local agent, browser app. |
| `assistant.thread` | Assistant Thread | product-required / pending source pass | AI Workspace | Conversation context. |
| `assistant.message` | Assistant Message | product-required / pending source pass | AI Workspace | Message unit in thread. |
| `assistant.bridge` | Assistant Bridge | product-required / pending source pass | AI Workspace / OPS Gateway | Bridge between assistant, ontology, OPS Gateway, Codex, and Engine. |
## Future Interface Layer
The future interface layer owns automation work views and UI compositions. It is motivated by the current ENGINE-side tender/Agent Monitor tech debt.
| Entity ID | Canonical name | Status | Authority | Notes |
| --- | --- | --- | --- | --- |
| `future.interface_layer` | Future Interface Layer | owner-confirmed future-concept | Platform | Dedicated layer for user-facing automation UIs, dashboards, maps, forms, and control panels. |
| `future.interface_view` | Interface View | future-concept | Interface Layer | A generated/configured view over ontology-backed domain data. |
| `future.interface_widget` | Interface Widget | future-concept | Interface Layer | Map, table, analytics block, form, graph, control, etc. |
| `future.interface_binding` | Interface Binding | future-concept | Interface Layer + ENGINE | Binding from workflow/node output to interface data/control layer. |
| `future.domain_package` | Domain Ontology Package | future-concept | Ontology Core | Procurement/tenders, ecology, transport analytics, robotics/Helius, ERP/business process, client-specific domains. |
## ENGINE Tech Debt / Non-Canonical Boundary
These names identify current working areas that must not leak into canonical core ontology.
| Entity ID | Canonical name | Status | Authority | Notes |
| --- | --- | --- | --- | --- |
| `engine.tech_debt.ops_layer` | ENGINE OpsLayer Tech Debt | tech-debt-noncanonical | ENGINE | Current ENGINE-side operational/runtime layer; do not confuse with OPS Product. |
| `engine.tech_debt.ops_agent_instance` | ENGINE Ops Agent Instance | tech-debt-noncanonical | ENGINE | Local runtime agent instance; not OPS Gateway `agent.identity`. |
| `engine.tech_debt.agent_monitor_node` | Agent Monitor Node | tech-debt-noncanonical | ENGINE | Current monitor/control UI experiment. |
| `engine.tech_debt.monitor_profile` | Monitor Profile | tech-debt-noncanonical | ENGINE | Current profile/config around Agent Monitor. |
| `engine.tech_debt.tender_domain_ui` | Tender Domain UI | tech-debt-noncanonical | ENGINE | Hardcoded tender/procurement UI in ENGINE. |
| `engine.tech_debt.tender_storage` | Tender Storage | tech-debt-noncanonical | ENGINE | Current domain storage in ENGINE-side implementation. |
| `engine.tech_debt.tender_ai_review` | Tender AI Review | tech-debt-noncanonical | ENGINE | Current AI review implementation for tender domain. |
| `engine.tech_debt.ops_tabs_control` | ENGINE OPS Tabs Control | tech-debt-noncanonical | ENGINE | UI/control surface tied to current OpsLayer experiment. |
@@ -0,0 +1,806 @@
# 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/n8n 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
NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/server/routes/n8n.js
search: runtimeWorkflowId
search: resolveNodeDcByRuntimeWorkflowId
search: resolveWorkflowIdByNodeDcBindingRest
search: executionId
NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/server/ops/runtimeTap.js
search: runtimeWorkflowId
search: n8nCoreId
search: executionId
search: runId
search: sessionId
NODEDC/NODEDC_ENGINE_INFRA/nodedc-source/services/n8n/runtime-plugin/hooks.js
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
n8n names are implementation aliases for Engine L2 runtime, not canonical product names.
```
### 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
```
@@ -0,0 +1,49 @@
# Evidence Ledger Index v0.4-pre
Status: consolidated index
Date: 2026-06-18
This file indexes the source-backed evidence ledgers. It is not a replacement for the detailed ledger files.
## Ledger Files
| Ledger | Scope | Status | Main result |
| --- | --- | --- | --- |
| `EVIDENCE_LEDGER_HUB_P0.md` | HUB / Launcher / NDCAuth | source-backed P0 | Confirms open contour vs client/company contour, public pool client/context, user classifications, app access/card split. |
| `EVIDENCE_LEDGER_OPS_P0.md` | OPS Product | source-backed P0 | Confirms workspace/project/card model and `ops.card` as canonical work object. |
| `EVIDENCE_LEDGER_OPS_GATEWAY_P1.md` | OPS Gateway / MCP access | source-backed P1 | Confirms scoped agent identity/token/grant/scope/tool/idempotency/audit boundary. |
| `EVIDENCE_LEDGER_ENGINE_DIRTY_BOUNDARY_P1.md` | ENGINE-side OpsLayer / Agent Monitor / tender tech debt | source-backed P1 | Confirms this is non-canonical tech debt and must not define OPS Product. |
| `EVIDENCE_LEDGER_ENGINE_WORKFLOW_P1.md` | ENGINE L1/L2 workflow and runtime evidence | source-backed P1 | Confirms L1 graph, workflow ACL/share, L2 n8n runtime ids/events/run/session bridge. |
## Source Roots Used
| Surface | Source root | Notes |
| --- | --- | --- |
| HUB | `/Users/dcconstructions/Downloads/mnt/data/nodedc_launcher` | Read-only source inspection. |
| OPS Product | `/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER` | Read-only source inspection. |
| OPS Gateway | `/Users/dcconstructions/Downloads/mnt/data/NODEDC_TASKMANAGER_CODEXAPI` | Read-only source inspection. |
| ENGINE | `/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_ENGINE_INFRA/nodedc-source` | Read-only source inspection; runtime/data/storage excluded. |
| Ontology workspace | `/Users/dcconstructions/Downloads/mnt/NODEDC_ONTOLOGY` | Documentation-only write workspace. |
## Accepted Evidence-Based Decisions
- HUB has two operational contours:
- open/public contour for simple users;
- managed closed company/client contour.
- `hub.public_pool_client` is a source-backed special Client, but it must not be modeled as ordinary company context.
- OPS Product canonical work object is `ops.card`.
- OPS Product, OPS Gateway, and ENGINE-side OpsLayer are three different things.
- ENGINE-side Agent Monitor/tender UI is working tech debt, not target architecture.
- ENGINE L1/L2 split is real enough for first ontology implementation:
- L1 = NodeDC canvas/workflow graph;
- L2 = n8n/subworkflow runtime attached to L1 node.
- Future interface layer is a planned platform service/layer, motivated by current ENGINE-side custom UI debt.
## Evidence Gaps That Remain Non-Blocking
- Assistant / AI Workspace needs a dedicated source pass before its entities become source-confirmed.
- `ops.responsible` needs exact source/product semantics.
- `ops.card_type` needs taxonomy.
- Gateway pairing/entitlement flow needs route-level hardening.
- Domain ontology packages need separate passes; core must not absorb domain-specific tender/ecology/transport concepts.
@@ -0,0 +1,136 @@
# Evidence Ledger — ENGINE Dirty Boundary P1
Status: source-backed tech-debt boundary note
Baseline: Compact Canonical Entity Catalog v0.3.1
Date: 2026-06-18
Scope: ENGINE-side OpsLayer / tender-agent / Agent Monitor boundary
Source root:
```text
/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_ENGINE_INFRA/nodedc-source
```
Restrictions observed:
- Source inspection only.
- No runtime/data/storage/env/secrets/logs/dumps.
- No source code edits.
- No build/test/install/docker execution.
## Summary
This pass confirms an important ontology boundary:
```text
OPS product
!= OPS Gateway
!= ENGINE-side OpsLayer / tender-agent / Agent Monitor
```
The ENGINE repository contains a substantial embedded `OpsLayer` around n8n workflows, tender search/review, monitor profiles, agent runs, trace events, and Agent Monitor UI nodes.
This code is working product/legacy infrastructure, but it must be treated as:
```text
tech debt / non-canonical
```
It should not be promoted into canonical OPS product truth and should not define the final automation UI architecture.
## Boundary Evidence
| Boundary ID | Canonical treatment | Evidence status | Evidence file:line | Evidence explanation | Notes |
| --- | --- | --- | --- | --- | --- |
| `engine.tech_debt.ops_layer` | Engine-side legacy OpsLayer | source-confirmed tech debt | `server/index.js:25`, `server/index.js:333`, `server/routes/ops.js:1-34`, `server/routes/ops.js:6412-11855` | ENGINE imports `opsRouter` and mounts it at `/api/ops`; `routes/ops.js` implements a large set of run/result/tender/AI review/monitor endpoints. | This is not the separate OPS product / Tasker model. |
| `engine.tech_debt.ops_agent_instance` | Legacy Engine agent instance | source-confirmed tech debt | `server/ops/migrations/0001_init_opslayer.sql:89-137`, `src/store.ts:444-480`, `src/utils/opsApi.ts:759-855` | OpsLayer has `agents`, `agent_instances`, `agent_runs`; frontend prevents copied n8n nodes from inheriting `opsAgentInstanceId`; API can start/stop agent instances and record runs. | Do not merge with OPS Gateway `agent.identity`. |
| `engine.tech_debt.agent_monitor_node` | Agent Monitor canvas node | source-confirmed tech debt | `src/nodes/AgentMonitorNode.tsx:10-14`, `src/nodes/AgentMonitorNode.tsx:21-38`, `src/driveinspector/nodes/AgentMonitor.definition.ts:1-13` | ENGINE has a visible `agentMonitor` React Flow node and inspector definition that binds monitor profiles/agents through `opsApi`. | This is current UI embedding, not final interface layer. |
| `engine.tech_debt.monitor_profile` | Engine-side monitor profile | source-confirmed tech debt | `server/ops/migrations/0001_init_opslayer.sql:240-299`, `src/utils/opsApi.ts:260-360`, `src/utils/opsApi.ts:460-520` | OpsLayer stores monitor profiles, profile assignments, bound agent instances, n8n cores, and monitor nodes; frontend can list/create/update/bind profiles and save monitor layouts. | Useful evidence for future work-view requirements. |
| `engine.tech_debt.tender_domain_ui` | Tender-specific embedded UI/domain slice | source-confirmed tech debt | `server/routes/ops.js:45-63`, `server/routes/ops.js:75-145`, `src/n8n/N8nAgentMonitorPanel.tsx:1-44`, `src/n8n/N8nAgentMonitorPanel.tsx:1160-1245`, `src/n8n/tenderElectronicPlaceCountries.ts:1-12` | ENGINE includes Kontur tender URLs, tender categories/electronic places, tender search settings, and a large Agent Monitor panel. | Treat as procurement/tender domain evidence, not core ontology. |
| `engine.tech_debt.tender_storage` | Tender storage inside Engine OpsLayer | source-confirmed tech debt | `server/ops/migrations/0001_init_opslayer.sql:210-239`, `server/ops/migrations/0006_tender_dedup_registry.sql:1-17`, `server/ops/migrations/0007_tender_details.sql:1-24`, `server/ops/migrations/0008_tender_documents.sql:1-37` | OpsLayer stores tender results, dedup registry, details, and downloaded documents. | Do not confuse with future domain ontology persistence. |
| `engine.tech_debt.tender_ai_review` | Tender AI review workflow state | source-confirmed tech debt | `server/ops/migrations/0009_tender_ai_review.sql:1-90`, `src/n8n/N8nAgentMonitorPanel.tsx:1214-1238`, `src/utils/opsApi.ts:577-688` | OpsLayer stores AI review tasks/latest state; UI has default manual AI criteria/response format; API enqueues/retries review tasks. | Useful sample for domain-specific assistant review flows. |
| `engine.tech_debt.ops_tabs_control` | Engine inspector ops control | source-confirmed tech debt | `src/driveinspector/ControlRegistry.tsx:27-50` | Drive inspector registers `opsTabs` control. | Another marker that Ops UI is embedded in ENGINE editor controls. |
| `future.interface_layer` | Future platform UI/work-view layer | product-required / source-informed | `src/n8n/N8nAgentMonitorPanel.tsx:46-120`, `src/utils/opsApi.ts:460-520`, `server/ops/migrations/0001_init_opslayer.sql:240-299` | Current monitor panel/layout/profile code shows the kind of configurable work views the future interface layer must support. | Future home should be separate platform service/app, not Engine core. |
## Route / Surface Evidence
| Surface | Evidence status | Evidence file:line | Evidence explanation |
| --- | --- | --- | --- |
| `/api/ops` is mounted inside ENGINE server | source-confirmed | `server/index.js:25`, `server/index.js:333` | ENGINE server imports and mounts `opsRouter`. |
| Ops router owns runs/results/tender/AI review/monitor APIs | source-confirmed | `server/routes/ops.js:6412-11855` | Router exposes health, runs, tender results/details/docs, AI review, trace, monitor profiles/layout/admin, agent instance start/stop, actions, contour limits/search. |
| Agent Monitor is an ENGINE canvas node | source-confirmed | `src/nodes/AgentMonitorNode.tsx:10-14`, `src/nodes/AgentMonitorNode.tsx:73-170` | Node type is `agentMonitor`; UI opens monitor through n8n subworkflow event. |
| Agent Monitor panel directly consumes Ops APIs | source-confirmed | `src/n8n/N8nAgentMonitorPanel.tsx:5-31` | Panel imports many Ops API functions for tender details, AI review, layout, runs, trace, start/stop, take-in-work. |
| Engine graph copy logic special-cases Ops bindings | source-confirmed | `src/store.ts:444-480` | Copied n8n nodes clear `opsAgentInstanceId`; copied `agentMonitor` nodes clear monitor profile/binding fields. |
## Guardrails Confirmed
```text
Do not use ENGINE server/routes/ops.js as OPS product truth.
Do not use ENGINE OpsLayer agent_instances as OPS Gateway agent.identity.
Do not use Agent Monitor as the final automation UI model.
Do not put future custom product UI directly into ENGINE core.
Do not collapse tender/procurement domain concepts into core ontology roots.
```
Canonical separation:
```text
ops.*
= product OPS / Tasker / operational work system
agent.*
= OPS Gateway execution identity, token, grant, scope, tool boundary
engine.tech_debt.*
= current ENGINE-embedded OpsLayer / tender-agent / Agent Monitor legacy slice
future.interface_layer.*
= future platform UI/work-view/configurator surface, still not implemented
```
## Product / Architecture Notes
### Why this matters
The current Engine-side tender/Agent Monitor implementation proves the need for an ontology-backed interface layer:
- users need domain-specific work views;
- workflows need to emit structured data into user-facing controls;
- assistants will likely compose or modify these views;
- tender/procurement is only the first domain slice;
- future slices may include ecology, transport, robotics/Helius, ERP/business processes, and client-specific domains.
But the current implementation should remain a learning sample and migration source, not the target architecture.
### Future target
Recommended direction:
```text
ENGINE
owns workflow/node execution and development environment
future interface layer
owns configurable work views, dashboards, maps, analytics, forms, and domain UI composition
Ontology Core
resolves meanings, relations, aliases, domain schemas, and routing context
```
### Migration posture
Do not migrate or refactor this now.
Near-term treatment:
- document the boundary;
- avoid using these entities as canonical roots;
- use them as source-backed evidence for future interface/work-view requirements;
- preserve current working behavior until a real interface layer exists.
## Open Questions / Follow-up
1. Later ENGINE pass should separately document canonical workflow L1/L2 entities without mixing in OpsLayer.
2. Future interface-layer RFC should decide whether views/widgets/surfaces are core ontology entities or platform-service entities with ontology references.
3. Tender/procurement should become a domain ontology package, not a core ontology root.
4. Decide whether Engine-side OpsLayer data gets migrated, archived, or only bridged when the future interface layer exists.
@@ -0,0 +1,67 @@
# Evidence Ledger — ENGINE Workflow P1
Status: source-backed ledger section
Baseline: Canonical Entity Catalog v0.4-pre
Date: 2026-06-18
Scope: ENGINE L1/L2 workflow, ACL/share, n8n runtime bridge, runtime event tracking
Source root:
```text
/Users/dcconstructions/Downloads/mnt/NODEDC/NODEDC_ENGINE_INFRA/nodedc-source
```
Restrictions observed:
- Source inspection only.
- No runtime/data/storage/env/secrets/logs/dumps.
- No source code edits.
- No build/test/install/docker execution.
## Summary
This pass confirms the minimum ENGINE ontology needed for the first implementation:
- `engine.workflow_l1`, `engine.node_l1`, and `engine.edge_l1` exist as NodeDC/React Flow graph concepts.
- `engine.node_type_l1` is sourced from the auto node registry.
- Workflow ACL/share/access-request concepts are implemented in source.
- `engine.workflow_l2` is source-evidenced as an n8n subworkflow attached to an L1 workflow/node pair.
- Runtime events carry `workflowId`, `nodeId`, `runtimeWorkflowId`, `executionId`, `runId`, and `sessionId`.
- Current runtime run/session tracking is tied to ENGINE-side OpsLayer tables and should remain tech-debt-adjacent.
## Entity Evidence
| Entity ID | Evidence status | Evidence file:line | Evidence explanation |
| --- | --- | --- | --- |
| `engine.workflow_l1` | source-confirmed | `src/store.ts:603-680`, `server/index.js:768-840`, `server/index.js:2716-3045` | Client state stores graph `nodes`/`edges`; server stores workflow metadata/graph and exposes workflow list/read/create/update routes. |
| `engine.node_l1` | source-confirmed | `src/store.ts:603-680`, `src/store.ts:1510-1585`, `src/store.ts:1770-1845` | Store manages React Flow nodes, creates nodes from templates/types, and updates node data. |
| `engine.edge_l1` | source-confirmed | `src/store.ts:764-780`, `src/store.ts:1510-1549` | Edges have source/target handles and are normalized in store. |
| `engine.node_type_l1` | source-confirmed | `src/nodes/autoRegistry.ts:4-56` | Node modules expose `meta`, `runtime`, `ports`, `monitor`, and derive type/label from module metadata. |
| `engine.workflow_acl` | source-confirmed | `server/workflows/acl.js:5-13`, `server/workflows/acl.js:109-165`, `server/workflows/acl.js:259-303` | ACL stores owner/users/groups/invites and supports viewer/editor/owner/admin checks. |
| `engine.workflow_owner` | source-confirmed | `server/workflows/acl.js:109-165` | ACL owner field is normalized and role checked. |
| `engine.workflow_share` | source-confirmed | `server/index.js:3185-3245`, `server/index.js:3250-3312`, `server/index.js:3371-3635` | Workflow share routes expose owner/users/groups/invites and email/internal invite operations. |
| `engine.workflow_access_request` | source-confirmed | `server/index.js:2792`, `server/index.js:2860`, `server/index.js:2916`, `server/index.js:3314` | Workflow access request, approve, reject, and request routes are present. |
| `engine.workflow_l2` | source-evidenced | `server/routes/n8n.js:11661-11737` | `/api/n8n/subworkflow/deploy` loads subworkflow graph for `workflowId` + `nodeId`, compiles it, injects runtime events, and writes compiled n8n workflow. |
| `engine.node_l2` | source-evidenced | `server/routes/n8n.js:2288-2365`, `services/n8n/runtime-plugin/hooks.js:132-145` | Runtime event node and hooks capture n8n node name/id. |
| `engine.l2_runtime_core` | source-evidenced | `server/routes/n8n.js:11685-11696`, `server/routes/n8n.js:11739-11748` | Deploy resolves n8n target/base URL/instance and docker compose service/container. |
| `engine.workflow_l2_runtime_id` | source-confirmed | `services/n8n/runtime-plugin/hooks.js:52-61`, `server/routes/n8n.js:2323-2324`, `server/routes/n8n.js:12041-12055` | Runtime plugin extracts n8n workflow id; injected event uses `$workflow.id`; deploy sync stores resolved workflow id. |
| `engine.l2_execution` | source-confirmed | `services/n8n/runtime-plugin/hooks.js:77-86`, `server/routes/n8n.js:2323-2325`, `server/ops/runtimeTap.js:773-818`, `server/ops/runtimeTap.js:820-855` | Runtime events carry execution id; runtime tap writes trace event and run execution binding. |
| `engine.l2_run` | source-confirmed / tech-debt-adjacent | `services/n8n/runtime-plugin/hooks.js:88-106`, `server/ops/runtimeTap.js:247-270`, `server/ops/runtimeTap.js:467-542` | Hooks extract run id; runtime tap resolves/canonicalizes run id through ENGINE-side OpsLayer tables. |
| `engine.l2_session` | source-confirmed / tech-debt-adjacent | `services/n8n/runtime-plugin/hooks.js:108-130`, `server/ops/runtimeTap.js:272-289`, `server/ops/runtimeTap.js:354-430` | Hooks extract session id or fall back to run id; runtime tap resolves session anchors and can create session-workflow split runs. |
| `engine.l2_runtime_event` | source-confirmed | `services/n8n/runtime-plugin/hooks.js:220-231`, `services/n8n/runtime-plugin/hooks.js:233-279`, `services/n8n/runtime-plugin/hooks.js:285-387`, `server/routes/n8n.js:2298-2332`, `services/n8n/runtime-plugin/runtime-bridge.js:200-223` | Runtime events are emitted/enqueued for workflow/node start/finish/success/error and sent to NodeDC runtime endpoint with retry/failure handling. |
## Guardrails Confirmed
```text
engine.workflow_l1 id != engine.workflow_l2_runtime_id.
engine.workflow_l2 is attached through NodeDC workflowId + nodeId.
engine.l2_run and engine.l2_session are useful routing evidence but currently live in ENGINE-side OpsLayer tech debt.
Engine-side OpsLayer runtime tables do not define OPS Product ontology.
```
## Non-Blocking Follow-Up
- Harden `engine.source_stamp` after implementation needs are clearer.
- Separate stable L2 domain concepts from current n8n-specific deployment helpers.
- Decide whether runtime run/session belongs in future Ontology Core, Interface Layer, OPS Gateway, or a dedicated runtime observability package.
@@ -0,0 +1,92 @@
# 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.
@@ -0,0 +1,138 @@
# Evidence Ledger — OPS Gateway P1
Status: first source-backed gateway ledger section
Baseline: Compact Canonical Entity Catalog v0.3.1
Date: 2026-06-18
Scope: OPS Gateway / Codex API / MCP agent boundary
Source root:
```text
/Users/dcconstructions/Downloads/mnt/data/NODEDC_TASKMANAGER_CODEXAPI
```
Restrictions observed:
- Source inspection only.
- No runtime/data/storage/env/secrets/logs/dumps.
- No source code edits.
- No build/test/install/docker execution.
## Summary
This pass confirms that OPS Gateway is not just a loose Codex config helper.
It is a separate boundary service that owns:
- agent identity;
- opaque agent tokens;
- project/workspace grants;
- tool scopes;
- MCP tool exposure;
- idempotency for write tools;
- audit events;
- a narrow Tasker adapter;
- AI Workspace entitlement projection into token-scoped MCP grants.
Ontology implication:
```text
agent.* entities belong to OPS Gateway.
They are not the same thing as Assistant, Codex, ChatGPT, or a human user.
```
## Entity Evidence
| Entity ID | Canonical name | Evidence status | Evidence file:line | Evidence explanation | Notes |
| --- | --- | --- | --- | --- | --- |
| `agent.identity` | OPS Gateway Agent | source-confirmed | `docs/ARCHITECTURE.md:72-89`, `migrations/001_initial.sql:8-17`, `src/repositories/agents.ts:15-24` | Agent Gateway owns agent profiles; `agents` table stores owner identity, display name, avatar, status, timestamps; `AgentRecord` mirrors those fields. | This is a gateway execution identity, not the assistant superclass. |
| `agent.token` | OPS Gateway Agent Token | source-confirmed | `docs/MCP_TOOLS_CONTRACT.md:19-50`, `migrations/001_initial.sql:38-47`, `src/repositories/agents.ts:488-545`, `src/security/tokens.ts:1-10` | Tokens are opaque bearer credentials; storage uses token hash/suffix/status/expiry; `createToken` stores hash and token grant scope; token strings use `ndcag_` prefix. | Token is not a user password and not a durable ontology identity. |
| `agent.session` | OPS Gateway Agent Session | source-confirmed | `src/repositories/agents.ts:50-55`, `src/repositories/agents.ts:579-630`, `src/routes/agents.ts:161-177` | Session joins active agent, active token, effective grants, and grant source; agent-session routes expose current session and setup packet. | Runtime auth context for MCP/tool calls. |
| `agent.grant` | OPS Gateway Grant | source-confirmed | `docs/ARCHITECTURE.md:134-143`, `migrations/001_initial.sql:22-33`, `src/repositories/agents.ts:26-36` | Grants bind an agent to workspace/project with scopes and mode. | Workspace-level grant is represented with empty/null project internally. |
| `agent.token_grant` | Token-scoped Run Grant | source-confirmed | `migrations/004_run_grants.sql:1-21`, `src/repositories/agents.ts:488-545`, `src/repositories/agents.ts:633-663`, `src/routes/agents.ts:964-972` | Tokens can have their own grant scope; token grants can reference source agent grants and intersect effective scopes. | Important for AI Workspace run-scoped access. |
| `agent.scope` | Agent Tool Scope | source-confirmed | `src/domain/scopes.ts:1-13`, `src/security/authorization.ts:11-39`, `src/mcp/tool-runtime.ts:540-557` | Allowed scopes list workspace/project/card operations; runtime checks both global scope and project grant scope before writes/reads. | Scopes are tool permissions, not product roles. |
| `agent.denied_capability` | Denied Gateway Capability | source-confirmed | `src/domain/scopes.ts:17-30`, `docs/ARCHITECTURE.md:91-107`, `docs/MCP_TOOLS_CONTRACT.md:321-333` | Delete/archive/settings/invite/raw Tasker API capabilities are explicitly denied. | Guardrail entity or policy list, not user-facing capability. |
| `agent.mcp_tool` | OPS MCP Tool | source-confirmed | `docs/MCP_TOOLS_CONTRACT.md:11-17`, `src/mcp/tool-runtime.ts:118-215`, `src/routes/mcp.ts:56-127` | Gateway exposes `/mcp`; supported methods include initialize/ping/tools/list/tools/call; runtime defines Tasker tools and required scopes. | Tools are filtered by effective session scopes. |
| `agent.idempotency_key` | Gateway Idempotency Key | source-confirmed | `docs/MCP_TOOLS_CONTRACT.md:303-319`, `migrations/001_initial.sql:77-86`, `src/repositories/agents.ts:676-765`, `src/mcp/tool-runtime.ts:390-448` | Write tools require idempotency key; Gateway stores processing/completed state, detects replay/conflict/in-progress, completes or releases keys. | Key is agent-scoped and protects Tasker writes from duplicate execution. |
| `agent.audit_event` | Gateway Audit Event | source-confirmed | `migrations/001_initial.sql:65-75`, `src/repositories/agents.ts:666-674`, `src/mcp/tool-runtime.ts:427-445`, `src/repositories/agents.ts:536-542` | Audit table stores event type/actor/metadata; tool executed/replayed/failed and token created events are recorded. | Required for trustworthy assistant/tool writes. |
| `agent.tasker_adapter` | Tasker Internal Adapter | source-confirmed | `docs/ARCHITECTURE.md:91-107`, `src/tasker/client.ts:104-203`, `src/tasker/client.ts:228-267` | Adapter exposes narrow intent-level Tasker operations and sends agent metadata/headers to Tasker internal endpoints. | Gateway must not call broad/raw Tasker APIs. |
| `agent.setup_packet` | Agent Setup Packet | source-confirmed | `docs/MCP_TOOLS_CONTRACT.md:335-350`, `src/routes/agents.ts:170-177`, `src/routes/agents.ts:1090-1128`, `src/routes/agents.ts:1153-1203` | Authenticated setup endpoint returns MCP server config template, available tools, and generated AGENTS.md rules. | Current Codex config workflow lives here; raw token is represented as placeholder in setup template. |
| `agent.ai_workspace_entitlement` | AI Workspace Entitlement Grant | source-confirmed | `src/routes/agents.ts:132-147`, `src/routes/agents.ts:179-249`, `src/routes/agents.ts:834-895`, `src/routes/agents.ts:942-972` | Internal AI Workspace route validates app/context/owner, selects matching grants, creates short-lived run token, records audit, and returns MCP server grant config. | This is the main future hook for ontology-assisted routing. |
| `agent.pairing_code` | Agent Pairing Code | storage-confirmed / route pending | `docs/ARCHITECTURE.md:74-83`, `docs/ARCHITECTURE.md:145-152`, `migrations/001_initial.sql:52-63` | Pairing codes are part of documented Gateway ownership and have storage table/status/expiry fields. | This pass did not confirm active route behavior; keep P2 pending. |
## Tool / Flow Evidence
| Flow / relation | Evidence status | Evidence file:line | Evidence explanation |
| --- | --- | --- | --- |
| `agent.session` exposes only scoped tools | source-confirmed | `src/mcp/tool-runtime.ts:373-375`, `src/routes/mcp.ts:92-106` | `getToolsForSession` filters tools by required scopes before `/mcp tools/list` returns them. |
| `agent.mcp_tool` executes through grants and scopes | source-confirmed | `src/mcp/tool-runtime.ts:450-557`, `src/security/authorization.ts:11-39` | Each tool validates args, scope, and project grant before calling Tasker adapter. |
| Write tools require idempotency | source-confirmed | `src/mcp/tool-runtime.ts:390-448`, `docs/MCP_TOOLS_CONTRACT.md:303-319` | Non-read tools fail without idempotency key and use claim/replay/conflict/in-progress behavior. |
| Gateway records write audit | source-confirmed | `src/mcp/tool-runtime.ts:427-445`, `src/repositories/agents.ts:666-674` | Successful, replayed, and failed tool attempts produce audit events. |
| Gateway calls Tasker through internal adapter | source-confirmed | `src/tasker/client.ts:104-203`, `src/tasker/client.ts:228-267` | Client calls internal Tasker endpoints and forwards agent id, owner user id, token id, and display metadata. |
| AI Workspace can receive token-scoped MCP grant | source-confirmed | `src/routes/agents.ts:179-249`, `src/routes/agents.ts:858-895` | Internal entitlement route returns an app grant with MCP server URL and bearer token for matching workspace/project grants. |
## Guardrails Confirmed
```text
agent.identity is an OPS Gateway execution identity, not a universal Assistant identity.
agent.token is an opaque credential and must not become a canonical user identity.
agent.scope is a tool permission model, not an OPS role model.
agent.grant binds agent/tool access to OPS workspace/project context.
agent.mcp_tool can request/perform scoped operations, not freely mutate OPS data.
All write tools require grants, scopes, idempotency, and audit.
Gateway should not expose raw Tasker API, delete/archive, workspace settings, invites, or arbitrary attachments.
Tasker remains source of truth for OPS cards/projects/states/labels/members/comments.
Launcher/HUB remains source of entitlement truth.
```
## Product / Architecture Notes
### Current MCP / Codex config path
The current path is workable but rough:
```text
AI Workspace or user setup
-> Agent Gateway setup packet / entitlement grant
-> MCP server config with bearer token
-> Codex or other MCP client
-> scoped Tasker tools
```
This should not be treated as final UX, but it is already a clean enough safety boundary:
- token is opaque and revocable;
- tools are scope-filtered;
- writes are idempotent;
- tool attempts are audited;
- Tasker calls go through a narrow adapter.
### Ontology hook for later
Ontology can improve the setup/routing layer without replacing Gateway:
```text
User asks from OPS / HUB / ENGINE / AI Workspace context
-> ontology resolves target workspace/project/card/workflow/application
-> Gateway issues or selects the correct token-scoped grant
-> Assistant receives only the tools/context it needs
```
Do not immediately rewrite the current Codex config flow. The future improvement is better context resolution and safer grant selection, not removing Gateway.
### Relation to future interface layer
The same pattern will matter for the future automation UI/interface layer:
- interface builder needs ontology-backed meanings;
- assistant may assemble views/widgets from domain entities;
- Gateway-style grants can bound which cards/projects/workflows/views can be mutated;
- Engine should emit structured automation data, not own every custom UI directly.
## Open Questions / Follow-up
1. Confirm active pairing-code route behavior or mark pairing as storage-only legacy/planned.
2. Decide whether `agent.ai_workspace_entitlement` should become a first-class ontology entity or remain a flow/policy object.
3. Map Gateway scopes to canonical OPS operations after the final OPS relation catalog exists.
4. Later, connect ontology resolver to AI Workspace entitlement context selection.
5. Keep `Assistant`, `Agent`, `MCP Client`, `Tool`, and `Gateway Token` as separate concepts.
@@ -0,0 +1,146 @@
# Evidence Ledger — OPS P0
Status: first source-backed ledger section
Baseline: Compact Canonical Entity Catalog v0.3.1
Date: 2026-06-18
Scope: OPS / TaskManager / Plane P0 evidence
Source root:
```text
/Users/dcconstructions/Downloads/mnt/data/dc_taskmanager/NODEDC_TASKMANAGER
```
Restrictions observed:
- Source inspection only.
- No runtime/data/storage/env/secrets/logs/dumps.
- No source code edits.
- No build/test/install/docker execution.
## Summary
This pass confirms the OPS P0 model:
- `ops.workspace` is source-backed by Plane `Workspace`.
- `ops.project` is source-backed by Plane `Project`.
- `ops.card` is the canonical NodeDC term for the Plane `Issue` work object.
- `ops.card_status` is backed by Plane `State` / `StateGroup`.
- `ops.card_priority` is a card attribute backed by `Issue.priority`.
- `ops.card_assignment` / `ops.assignee` are backed by `Issue.assignees` and `IssueAssignee`.
- `ops.card_relation` is backed by `IssueRelation` and relation choices.
- `ops.card_type` is source-backed by `IssueType`, but product taxonomy can grow beyond Plane's current naming.
- `ops.responsible` remains product-required/source-adjacent, not fully source-confirmed as a separate canonical entity.
## Entity Evidence
| Entity ID | Canonical name | Evidence status | Evidence file:line | Evidence explanation | Notes |
| --- | --- | --- | --- | --- | --- |
| `ops.workspace` | Ops Workspace | source-confirmed | `plane-src/apps/api/plane/db/models/workspace.py:119-183` | `Workspace` defines workspace name, owner, slug, timezone/storage fields and maps to `workspaces` table. | Plane source alias: `Workspace`. |
| `ops.workspace_member` | Ops Workspace Member | source-confirmed | `plane-src/apps/api/plane/db/models/workspace.py:200-233` | `WorkspaceMember` links workspace to member, role, active/banned state, and per-member props. | Membership context for workspace-level OPS access. |
| `ops.project` | Ops Project | source-confirmed | `plane-src/apps/api/plane/db/models/project.py:68-167` | `Project` links to workspace and defines name, identifier, project settings, default state, external refs. | Plane source alias: `Project`. |
| `ops.project_member` | Ops Project Member | source-confirmed | `plane-src/apps/api/plane/db/models/project.py:212-227` | `ProjectMember` links project/member with role, preferences, sort order, and active state. | Project-level OPS membership. |
| `ops.card` | Ops Card | source-confirmed canonical NodeDC term | `plane-src/apps/api/plane/db/models/issue.py:104-177` | Plane `Issue` defines the core work object with parent, state, name, description, priority, assignees, labels, dates, external refs, and type. | `Issue`, `task`, `work item` are aliases/types; canonical NodeDC term is `ops.card`. |
| `ops.card_status` | Ops Card Status | source-confirmed | `plane-src/apps/api/plane/db/models/state.py:14-20`, `plane-src/apps/api/plane/db/models/state.py:79-115`, `plane-src/apps/api/plane/db/models/issue.py:119-125` | `StateGroup` defines backlog/unstarted/started/completed/cancelled/triage; `State` is project-scoped; `Issue.state` links card to state. | Plane source aliases: `State`, `StateGroup`. |
| `ops.card_priority` | Ops Card Priority | source-confirmed card attribute | `plane-src/apps/api/plane/db/models/issue.py:105-111`, `plane-src/apps/api/plane/db/models/issue.py:140-145` | `Issue.PRIORITY_CHOICES` and `Issue.priority` define urgent/high/medium/low/none priority. | Rename from broad `ops.priority`; this is card-scoped. |
| `ops.card_assignment` | Ops Card Assignment | source-confirmed | `plane-src/apps/api/plane/db/models/issue.py:148-154`, `plane-src/apps/api/plane/db/models/issue.py:337-357` | `Issue.assignees` is a ManyToMany through `IssueAssignee`; `IssueAssignee` links issue to assignee. | Assignment relation/entity for card. |
| `ops.assignee` | Ops Assignee | source-confirmed | `plane-src/apps/api/plane/db/models/issue.py:337-360` | `IssueAssignee` links card to user and enforces uniqueness for non-deleted assignment. | Confirmed source term. |
| `ops.responsible` | Ops Responsible | product-required / source-adjacent | `plane-src/apps/api/plane/db/models/project.py:77-90` | `Project` has `default_assignee` and `project_lead`, which are adjacent to responsibility semantics but not the full product concept. | Keep separate from `ops.assignee`; do not mark fully source-confirmed yet. |
| `ops.card_type` | Ops Card Type | source-confirmed source anchor + product-defined taxonomy | `plane-src/apps/api/plane/db/models/issue.py:163-169`, `plane-src/apps/api/plane/db/models/issue_type.py:14-29`, `plane-src/apps/api/plane/db/models/issue_type.py:35-52` | `Issue.type` links to `IssueType`; `IssueType` has workspace-level name/description/default/active fields; `ProjectIssueType` maps types into projects. | Source-backed by Plane `IssueType`; NodeDC taxonomy can still include task/report/milestone/note/request as product-defined types. |
| `ops.card_relation` | Ops Card Relation | source-confirmed | `plane-src/apps/api/plane/db/models/issue.py:112-118`, `plane-src/apps/api/plane/db/models/issue.py:264-309` | `Issue.parent` supports hierarchy; `IssueRelationChoices` and `IssueRelation` model duplicate/relates_to/blocked_by/start_before/finish_before/implemented_by relations. | Relation taxonomy exists; product meaning may need curation. |
| `ops.external_ref` | Ops External Ref | source-confirmed cross-cutting field | `plane-src/apps/api/plane/db/models/issue.py:161-162`, `plane-src/apps/api/plane/db/models/project.py:120-122`, `plane-src/apps/api/plane/db/models/state.py:92-93`, `plane-src/apps/api/plane/db/models/issue_type.py:23-24` | Issue, Project, State, and IssueType all carry `external_source` / `external_id` fields. | Useful for future cross-app ontology links. |
## Supporting P1 Evidence Found During P0
| Entity ID | Canonical name | Evidence status | Evidence file:line | Evidence explanation | Notes |
| --- | --- | --- | --- | --- | --- |
| `ops.card_label` | Ops Card Label / Marker | source-confirmed | `plane-src/apps/api/plane/db/models/label.py:11-44`, `plane-src/apps/api/plane/db/models/issue.py:156`, `plane-src/apps/api/plane/db/models/issue.py:534-542` | `Label` is workspace/project-scoped; `Issue.labels` uses `IssueLabel`. | P1 but confirmed while reading card model. |
| `ops.card_comment` | Ops Card Comment | source-confirmed | `plane-src/apps/api/plane/db/models/issue.py:442-469` | `IssueComment` links to issue, actor, access, attachments, external refs, parent comment. | P1. |
| `ops.card_activity` | Ops Card Activity | source-confirmed | `plane-src/apps/api/plane/db/models/issue.py:406-435` | `IssueActivity` stores issue, verb, changed field, old/new values, comment/attachments, actor. | P1 event/activity evidence. |
| `ops.card_artifact_link` | Ops Card Artifact Link | source-confirmed | `plane-src/apps/api/plane/db/models/issue.py:389-399`, `plane-src/apps/api/plane/db/models/asset.py:28-75` | `IssueAttachment` links issue to file asset; `FileAsset` can link to issue and stores file metadata. | Relation/link, not global artifact root. |
| `ops.file_asset` | Ops File Asset | source-confirmed | `plane-src/apps/api/plane/db/models/asset.py:28-75` | `FileAsset` stores asset file, workspace/project/issue/comment links, entity type, external refs, metadata, blob ref. | OPS-local source entity. |
| `ops.stored_blob` | Ops Stored Blob | source-confirmed | `plane-src/apps/api/plane/db/models/asset.py:110-147` | `StoredBlob` is canonical stored object with workspace, sha256, size, mime type, canonical object key, status, ref count, metadata. | OPS-local stored binary/blob source entity. |
## Relation / Flow Evidence
| Relation / guardrail | Evidence status | Evidence file:line | Evidence explanation |
| --- | --- | --- | --- |
| `ops.workspace` contains `ops.project` | source-confirmed | `plane-src/apps/api/plane/db/models/project.py:68-76` | `Project.workspace` is a foreign key to workspace. |
| `ops.project` contains `ops.card` | source-confirmed | `plane-src/apps/api/plane/db/models/issue.py:104-177`, `plane-src/apps/api/plane/db/models/project.py:182-191` | `Issue` inherits `ProjectBaseModel`, which stores project and workspace; save copies workspace from project. |
| `ops.card` has status | source-confirmed | `plane-src/apps/api/plane/db/models/issue.py:119-125` | `Issue.state` links to `State`. |
| `ops.card` has priority | source-confirmed | `plane-src/apps/api/plane/db/models/issue.py:140-145` | `Issue.priority` is selected from `PRIORITY_CHOICES`. |
| `ops.card` has assignees | source-confirmed | `plane-src/apps/api/plane/db/models/issue.py:148-154`, `plane-src/apps/api/plane/db/models/issue.py:337-357` | `Issue.assignees` uses the `IssueAssignee` through model. |
| `ops.card` can have type | source-confirmed | `plane-src/apps/api/plane/db/models/issue.py:163-169`, `plane-src/apps/api/plane/db/models/issue_type.py:14-29` | `Issue.type` links to `IssueType`. |
| `ops.card` can relate to other cards | source-confirmed | `plane-src/apps/api/plane/db/models/issue.py:112-118`, `plane-src/apps/api/plane/db/models/issue.py:264-309` | `Issue.parent` and `IssueRelation` support hierarchical and typed cross-card relations. |
| `ops.card` can link to external systems | source-confirmed | `plane-src/apps/api/plane/db/models/issue.py:161-162` | `external_source` / `external_id` on Issue give source-backed external refs. |
## Guardrails Confirmed
```text
ops.card is the canonical NodeDC work object.
Plane Issue is a source alias for ops.card.
task / issue / work item are aliases or card types, not canonical roots.
ops.card_priority is a card attribute, not an OPS-wide root entity.
ops.card_type is source-backed by IssueType, but final NodeDC card type taxonomy is product-defined.
ops.responsible is not the same as ops.assignee.
ops.responsible remains product-required/source-adjacent until product semantics are defined.
ops.card_artifact_link is a relation/link, not a global artifact root.
ops.file_asset and ops.stored_blob are OPS-local source entities.
```
## Product / Architecture Notes
### OPS as assistant surface
OPS is likely the first high-value surface for ontology-backed assistant routing.
Near-term expected use:
```text
User is in OPS card/project context.
Assistant resolves workspace/project/card and can route requests to Engine or Gateway tools.
```
This requires:
- stable `ops.workspace` / `ops.project` / `ops.card` identifiers;
- aliases and external refs;
- clear relation from OPS card/project to Engine application/workflow context;
- scoped tool operations through OPS Gateway, not direct DB mutation.
### Responsible vs assignee
Current source confirms assignees strongly.
Source-adjacent evidence for broader responsibility exists at project level:
- `Project.default_assignee`
- `Project.project_lead`
But these do not fully define the product term `ops.responsible`.
Recommendation:
```text
Keep ops.responsible as product-required.
Define later whether it means owner, accountable person, reviewer, project lead, default assignee, or card-level responsibility role.
```
### Card type taxonomy
`IssueType` is source-confirmed, but NodeDC should not collapse product card semantics into raw Plane naming.
Recommendation:
```text
Use ops.card_type as canonical.
Map Plane IssueType into ops.card_type.
Allow future product taxonomy: task, report, milestone, note, request, automation output, etc.
```
## Open Questions / Follow-up
1. Define `ops.responsible` product semantics before implementing assistant routing around responsibility.
2. Decide canonical `ops.card_type` taxonomy and how it maps to Plane `IssueType`.
3. Later P1 pass should harden card artifacts/activity/external refs in a dedicated file.
4. OPS Gateway pass must confirm that assistant/tool writes happen through scoped operations, grants, idempotency, and audit.
@@ -0,0 +1,77 @@
# Ontology Guardrails v0.4-pre
Status: pre-release implementation baseline
Date: 2026-06-18
These rules exist to stop future agents and developers from merging similar-looking but different NodeDC concepts.
## Core Naming Rules
1. Use canonical IDs from `CANONICAL_ENTITY_CATALOG.md`.
2. Treat aliases as aliases, not new roots.
3. If source evidence is missing, mark the entity as `pending`; do not invent implementation facts.
4. Keep `source-confirmed`, `owner-confirmed`, `product-required`, and `future-concept` separate.
5. Use `ops.card` as the canonical work object. `Issue`, `task`, `work item`, and `ticket` are aliases or subtypes.
## HUB Guardrails
- `hub.open_contour` is not an ordinary `hub.client_context`.
- `hub.public_pool_client` is a special source-backed Client used by public pool context.
- `hub.public_user` and `hub.client_user` are classifications of `hub.user`, not separate hard user tables/classes unless future source proves otherwise.
- `hub.application_card` is presentation only. Access authority belongs to `hub.application_access`, `hub.app_grant`, and `hub.app_exception`.
- Authentik, OIDC, JWT, and provider-specific auth names are implementation aliases under `ndcauth.identity` / `ndcauth.session`.
## OPS Product Guardrails
- OPS Product is the operational work/project/card layer.
- OPS Product must not be derived from ENGINE-side `server/routes/ops.js` or Agent Monitor experiments.
- Plane `Issue` maps to canonical `ops.card`.
- `ops.card_priority` is a card attribute, not a global root entity.
- `ops.responsible` is not automatically equal to `ops.assignee`; keep the distinction until source/product semantics are finalized.
- `ops.card_artifact_link` is a relation/link to outputs, not a global artifact root.
## OPS Gateway Guardrails
- OPS Gateway is the scoped MCP/API access layer for agents.
- `agent.identity` is a Gateway execution identity, not a human user and not a universal assistant persona.
- `agent.token` is an opaque credential. Do not treat it as user identity.
- `agent.scope` is a tool/capability permission. Do not confuse it with HUB/OPS roles.
- Gateway writes must remain scoped, audited, and idempotent.
- Gateway does not own raw OPS product truth. Tasker/OPS remains source of truth for projects/cards.
- HUB remains source of truth for platform user/client/application entitlement.
## ENGINE Guardrails
- ENGINE is workflow/dev environment, not the final home for heavy product UIs.
- `engine.workflow_l1` is the NodeDC canvas/workflow graph.
- `engine.workflow_l2` is a runtime/subworkflow layer, currently n8n-backed.
- `engine.workflow_l2_runtime_id` is not the same as NodeDC `engine.workflow_l1` id.
- `engine.l2_run`, `engine.l2_session`, and current trace tables are useful evidence but are tech-debt-adjacent because they live in ENGINE-side OpsLayer.
- Do not turn ENGINE-side Agent Monitor/tender UI into core ontology roots.
- Procurement/tender concepts should later become a domain ontology package, not a core root.
## Future Interface Layer Guardrails
- Do not add new heavy custom product UI directly into ENGINE core.
- Future automation UI should live in a dedicated interface layer/service.
- ENGINE nodes may emit data/control bindings for that layer, but the layer owns views, widgets, dashboards, maps, forms, and control panels.
- Assistant-built interfaces must use ontology-backed meanings, not hardcoded one-off field guesses.
- Current tender/Agent Monitor UI is evidence of need and tech debt, not the target architecture.
## Assistant / MCP Routing Guardrails
- Assistant is not the same as Gateway identity.
- Codex, browser ChatGPT, MCP tool, local executor, and OPS Gateway are different execution surfaces.
- Ontology Core should help resolve target context before selecting grant/tool/workflow, especially for:
- OPS user asks to inspect or switch an Engine workflow.
- Engine user asks to create/update OPS cards.
- Assistant needs to choose project/workflow/card context by human-readable name.
- Browser ChatGPT can propose RFCs, but source evidence and accepted docs remain on disk.
## Data Safety Guardrails
- Do not read or copy env files, secrets, database dumps, storage, runtime buffers, logs, caches, build outputs, `node_modules`, or archives into ontology docs.
- Do not delete files unless explicitly asked by the user.
- Do not edit application source code from the ontology workspace.
- Do not run Docker/build/install/test for docs-only ontology work.
@@ -0,0 +1,94 @@
# Implementation Readiness v0.4-pre
Status: ready to start first implementation phase
Date: 2026-06-18
This is the stop point for the current ontology design pass. The next phase is implementation planning/code, not more broad ontology discussion.
## Ready Baseline
The following documents form the implementation baseline:
- `CANONICAL_ENTITY_CATALOG.md`
- `RELATION_CATALOG.md`
- `GUARDRAILS.md`
- `TERMS_GLOSSARY.md`
- `EVIDENCE_LEDGER.md`
- `EVIDENCE_LEDGER_HUB_P0.md`
- `EVIDENCE_LEDGER_OPS_P0.md`
- `EVIDENCE_LEDGER_OPS_GATEWAY_P1.md`
- `EVIDENCE_LEDGER_ENGINE_DIRTY_BOUNDARY_P1.md`
- `EVIDENCE_LEDGER_ENGINE_WORKFLOW_P1.md`
- `ONTOLOGY_SERVICE_PLACEMENT_AND_USE_CASES.md`
- `OPEN_QUESTIONS.md`
## Target Home
Final platform home:
```text
/Users/dcconstructions/Downloads/mnt/NODEDC/platform/services/ontology-core
```
Current working home:
```text
/Users/dcconstructions/Downloads/mnt/NODEDC_ONTOLOGY
```
Do not move source repositories during this phase. The next implementation step can create a clean service skeleton under `platform/services/ontology-core` and copy accepted docs there.
## First Implementation Slice
1. Create `platform/services/ontology-core` as docs-first platform service/module.
2. Add machine-readable catalog files:
- `catalog/entities.json`
- `catalog/relations.json`
- `catalog/aliases.json`
- `catalog/guardrails.json`
- `catalog/evidence.json`
3. Add schema validation for entity/relation IDs and evidence statuses.
4. Add resolver MVP for two high-value flows:
- OPS -> ENGINE: resolve project/card/user request into Engine workflow/L1/L2 context.
- ENGINE -> OPS: resolve workflow/node/domain context into target OPS project/card path.
5. Add read-only lookup API or CLI only after schema and resolver rules are stable.
6. Wire OPS Gateway grant/tool preflight later; ontology advises context, Gateway enforces permission.
## Non-Goals For First Slice
- No database migration yet unless schema pressure requires it.
- No runtime refactor.
- No Engine-side OpsLayer cleanup.
- No tender/Agent Monitor rewrite.
- No full UI constructor yet.
- No broad domain ontology buildout.
- No secret/env/runtime/data/storage ingestion.
## First Useful Product Outcomes
- User in OPS can ask assistant to inspect, switch, or reason about an Engine workflow by human-readable project/workflow/card context.
- User in Engine can ask assistant to create/update the right OPS cards without manually switching OPS project context.
- Agents stop confusing:
- OPS Product;
- OPS Gateway;
- ENGINE-side OpsLayer.
- Future interface layer has a stable conceptual runway and does not repeat the current ENGINE hardcoded UI pattern.
## Handoff Prompt For Implementation
```text
Implement Ontology Core first slice as docs-first platform service at
/Users/dcconstructions/Downloads/mnt/NODEDC/platform/services/ontology-core.
Use /Users/dcconstructions/Downloads/mnt/NODEDC_ONTOLOGY/ontology as accepted baseline.
Do not edit HUB/OPS/Gateway/ENGINE source code in this task.
Create catalog JSON files and validation around canonical entity/relation/alias/guardrail data.
Focus first resolver MVP on OPS -> ENGINE and ENGINE -> OPS context routing.
Keep Gateway permissions as enforcement authority; ontology only resolves/advises context.
Do not read env/secrets/runtime/data/storage/logs/dumps.
```
## Stop Point
The ontology design pass should pause here. Additional browser ChatGPT creativity is useful only as RFC review against these files, not as a replacement for the accepted baseline.
@@ -0,0 +1,340 @@
# Ontology Service Placement and Near-Term Use Cases
Status: planning note
Date: 2026-06-18
Scope: architecture direction for NodeDC ontology work
## Current State
Current research workspace:
```text
/Users/dcconstructions/Downloads/mnt/NODEDC_ONTOLOGY
```
This workspace is a temporary documentation/write area for ontology design, evidence ledgers, guardrails, and open questions.
It should not be treated as the final production home.
Do not move it while the active ChatGPT `NodeDC Ontology Write` app points at this path. Moving it now would break the connector.
## Target Home
The ontology belongs in the platform layer, not as a random folder in `mnt`.
Recommended future home:
```text
/Users/dcconstructions/Downloads/mnt/NODEDC/platform/services/ontology-core
```
Alternative names:
```text
platform/services/ontology-registry
platform/services/context-registry
```
Recommended name for now:
```text
ontology-core
```
Reason:
- It is a platform service, not a feature of only HUB, OPS, or ENGINE.
- It should live near:
- `services/notification-core`
- `services/ai-workspace-assistant`
- `services/ai-workspace-hub`
- It should not own HUB/OPS/ENGINE domain data directly.
- It should own canonical cross-app meaning, aliases, relations, routing context, and guardrails.
## What Ontology Core Should Own
Ontology Core should own:
- canonical entity catalog;
- relation catalog;
- alias registry;
- evidence ledger;
- guardrails / forbidden conflations;
- cross-surface context mapping;
- future API for entity/relation resolution;
- future API for assistant/tool routing context.
Ontology Core should not own:
- Launcher users/clients/groups/access data;
- Plane/OPS cards/projects/workspaces/comments;
- Engine workflows/nodes/runtime events;
- Authentik identity/session data;
- Notification deliveries/read-state;
- actual source-code edits.
Domain data stays with the owning service. Ontology Core describes and connects meaning across services.
## Near-Term Product Use Case
The first practical value is cross-application assistant routing.
### OPS to ENGINE
Example:
```text
User is in OPS and asks Assistant:
"Replace the workflow for this project/card with another Engine workflow and then continue coding."
```
Expected future behavior:
1. Assistant knows current OPS surface context:
- workspace;
- project;
- card;
- selected assistant/project context.
2. Ontology resolves that OPS context to relevant Engine application boundary / workflow context.
3. Assistant can ask the correct Engine-side tool/action to inspect or switch workflow.
4. Engine remains owner of workflow internals.
5. OPS remains owner of card/project/task context.
6. The action is auditable and bounded by user permissions.
Ontology requirement:
```text
ops.card / ops.project / ops.workspace
can relate to
engine.application_boundary / engine.workflow_l1 / engine.workflow_l2
through explicit relation and permission context,
not by hardcoded UI assumptions.
```
### ENGINE to OPS
Example:
```text
User is in ENGINE and asks Assistant:
"Create OPS tasks for this workflow issue / describe next implementation steps in the right project."
```
Expected future behavior:
1. Assistant knows current Engine surface context:
- workflow;
- node;
- application boundary;
- selected assistant/project context.
2. Ontology resolves the target OPS workspace/project/card destination.
3. Assistant can create or update OPS cards through scoped OPS Gateway operations.
4. User should not have to manually switch assistant project if target can be resolved by name/context.
Ontology requirement:
```text
engine.workflow_l1 / engine.node_l1 / engine.application_boundary
can relate to
ops.workspace / ops.project / ops.card
through explicit routing relations and aliases.
```
## Why This Matters
Without ontology:
- Assistant context is surface-local.
- OPS assistant may not know the correct Engine workflow target.
- Engine assistant may not know the correct OPS project/card destination.
- Users must manually switch projects/surfaces.
- Workflows become hardcoded by UI glue and fragile assumptions.
With ontology:
- Assistant can resolve user intent across HUB, OPS, ENGINE, and platform services.
- Names, aliases, and relations can be normalized.
- Cross-app actions can be permissioned, audited, and routed.
- Future automation can target stable meanings instead of brittle file/UI paths.
## Design Guardrails
Ontology must stay flexible:
- Core ontology should stay small and stable.
- Task-specific entities can be added later per domain.
- Do not force every future use case into the first core catalog.
- Use statuses:
- `source-confirmed`
- `source-evidenced/context-derived`
- `product-required`
- `future concept`
- `tech debt / non-canonical`
- Dirty but working implementations should be marked as tech debt, not silently promoted into canonical product truth.
## Known Dirty Areas To Track
### Engine-side OPS / tender-agent / Agent Monitor
Status:
```text
tech debt / non-canonical
```
Do not use it as OPS product truth.
Future direction:
```text
automation control surface / UI constructor / automation work views
```
Automation nodes should emit structured data into a separate work/control layer rather than keeping heavy custom OPS-like UI inside ENGINE.
Clarification:
- `OPS product` means the separate operational system / Tasker surface with workspaces, projects, cards, statuses, labels, comments, and assignment.
- `Engine-side OPS / tender-agent / Agent Monitor` means the old custom workflow/UI implementation inside ENGINE. It is a working prototype/legacy slice, not the canonical OPS product model.
- Do not let the ontology merge these two meanings under one root.
- Treat the Engine-side tender UI as evidence for future interface needs, not as the final architecture.
### Future Interface / Automation UI Layer
Status:
```text
future concept / product-required soon
```
Strategic direction:
- ENGINE should remain a workflow/development environment.
- New heavy custom product interfaces should not be hardcoded inside ENGINE.
- Automation/workflow nodes should be able to emit structured data for a separate interface/control layer.
- A future platform service or app should own user-facing automation work views, dashboards, cards, maps, analytics panels, and other generated/custom UI surfaces.
- Assistants are expected to help assemble these interfaces from ontology-backed domain meanings and UI rules.
Possible future names:
```text
platform/services/interface-core
platform/services/automation-ui
platform/services/workview-core
platform/services/ui-workbench
```
No final name is selected yet.
The ontology must be ready to describe:
- domain entities and their aliases;
- workflow node outputs;
- UI view definitions;
- widget/control types;
- dashboard/work-view composition;
- source application and permission context;
- relation from OPS card/project or ENGINE workflow/node to the generated UI surface.
Near-term implication:
```text
Do not canonize the current tender-agent / Agent Monitor UI embedded in ENGINE.
Use it as a learning sample for what the future interface layer must support.
```
### Domain Ontology Expansion
Core ontology should stay compact, but it must leave a clean path for domain ontologies.
Expected domain families already visible from product direction:
- tenders / procurement;
- ecology;
- transport analytics;
- robotics / Helius-style analysis;
- business processes;
- ERP-like operational domains;
- future client-specific domains.
These domains should extend the core catalog rather than polluting the core roots.
Recommended shape:
```text
core ontology
-> platform/service/application/surface/user/card/workflow basics
domain ontology
-> domain-specific entities, fields, relations, UI views, and automation outputs
```
### Assistant Project / Surface Selection
Current concern:
```text
Assistant can be attached to one project/context at a time, forcing manual switching.
```
Ontology should support later resolution by:
- entity name;
- aliases;
- current surface;
- user permissions;
- project/workflow/card relation;
- explicit target override from the user.
This is a core near-term reason for building the ontology.
### MCP / Codex Config Routing
Current OPS Gateway already has a rough setup/config route:
```text
AI Workspace / Codex config
-> token-scoped MCP grant
-> OPS Gateway
-> Tasker internal adapter
```
Do not refactor this immediately.
Ontology can later improve this by resolving the correct target context before issuing or selecting grants:
- owner/user identity;
- active surface;
- OPS workspace/project/card;
- ENGINE application/workflow/node;
- explicit user target;
- aliases and product names;
- permitted tool/action set.
This keeps the current working MCP path while creating a path toward less manual config and safer assistant routing.
## Migration Plan
Short term:
1. Keep writing research docs in `NODEDC_ONTOLOGY`.
2. Finish evidence ledgers for HUB / OPS / OPS Gateway / ENGINE.
3. Create consolidated:
- `CANONICAL_ENTITY_CATALOG.md`
- `RELATION_CATALOG.md`
- `EVIDENCE_LEDGER.md`
- `GUARDRAILS.md`
- `OPEN_QUESTIONS.md`
Medium term:
1. Create `platform/services/ontology-core`.
2. Move accepted docs from `NODEDC_ONTOLOGY/ontology` into the service docs.
3. Reconnect ChatGPT write app to the final path.
4. Decide whether the service starts as docs-only, JSON registry, or API + DB.
Long term:
1. Add machine-readable catalog format.
2. Add resolver APIs for Assistant / OPS Gateway / Engine tools.
3. Add relation/evidence versioning.
4. Add permissions-aware context resolution.
@@ -0,0 +1,63 @@
# Open Questions v0.4-pre
Status: pre-release open question register
Date: 2026-06-18
No question below blocks the first Ontology Core implementation. These are the items to resolve during implementation or the next evidence pass.
## P0 Before First Code Merge
| ID | Question | Current stance |
| --- | --- | --- |
| `OQ-001` | What exact package/service shape starts `platform/services/ontology-core`? | Start docs-first + machine-readable catalog schema; add API/db only after resolver MVP needs it. |
| `OQ-002` | What is the first resolver use case? | OPS -> ENGINE workflow context and ENGINE -> OPS project/card context. |
| `OQ-003` | What is accepted source of truth for current docs? | `NODEDC_ONTOLOGY/ontology/*` until moved/copied into target platform service. |
## OPS Product Questions
| ID | Question | Current stance |
| --- | --- | --- |
| `OQ-101` | Exact `ops.responsible` semantics? | Keep distinct from `ops.assignee`; define during OPS card workflow hardening. |
| `OQ-102` | `ops.card_type` taxonomy? | Need explicit list: architecture block, task, report, milestone/mailstone, incident, decision, research, etc. |
| `OQ-103` | How should artifacts/files attach to cards? | Keep as `ops.card_artifact_link` until storage/file authority is clear. |
## OPS Gateway Questions
| ID | Question | Current stance |
| --- | --- | --- |
| `OQ-201` | Is `agent.ai_workspace_entitlement` a durable entity or a policy/flow? | Keep as source-evidenced pending boundary. |
| `OQ-202` | Pairing/setup flow exact route model? | Keep `agent.pairing_code` pending route hardening. |
| `OQ-203` | How should ontology select Gateway grants? | First version can be advisory/preflight; Gateway remains enforcement authority. |
## ENGINE Questions
| ID | Question | Current stance |
| --- | --- | --- |
| `OQ-301` | Should `engine.l2_run` and `engine.l2_session` be canonical long term? | They are source-confirmed but tech-debt-adjacent; keep but do not overbuild around current tables. |
| `OQ-302` | Where should future runtime observability live? | Candidate: dedicated runtime/observability package, not OPS Product and not final Interface Layer. |
| `OQ-303` | What is `engine.source_stamp` exactly? | Pending. Use only when implementation needs stable version/source traceability. |
| `OQ-304` | How to retire ENGINE-side tender/Agent Monitor UI? | Defer until Interface Layer MVP exists; mark as tech debt now. |
## Assistant / AI Workspace Questions
| ID | Question | Current stance |
| --- | --- | --- |
| `OQ-401` | Exact source entities for assistant/thread/message/provider/executor? | Dedicated AI Workspace source pass needed. |
| `OQ-402` | How much browser ChatGPT/codex bridge state becomes product state? | Treat current bridge as workflow/process, not product data model, until source exists. |
| `OQ-403` | Can ontology reduce MCP config/token routing pain? | Yes as resolver/preflight later; do not rewrite config flow in this phase. |
## Future Interface Layer Questions
| ID | Question | Current stance |
| --- | --- | --- |
| `OQ-501` | Final service name? | Candidate names: `interface-core`, `automation-ui`, `workview-core`, `ui-workbench`, `notg-controller-layer`. |
| `OQ-502` | First MVP view type? | Likely table/report/control panel over an Engine workflow output, not the full UI constructor. |
| `OQ-503` | How are view bindings emitted from Engine? | Future custom nodes should emit ontology-backed data/control bindings into a separate interface data layer. |
## Domain Ontology Questions
| ID | Question | Current stance |
| --- | --- | --- |
| `OQ-601` | Which domain package goes first? | Candidate: procurement/tenders because existing dirty implementation exposes many lessons. |
| `OQ-602` | How to handle ecology/transport/robotics/ERP domains? | Add as packages after core resolver and entity/relation schema stabilize. |
@@ -0,0 +1,33 @@
# Ontology Documents
Primary documents:
- `CANONICAL_ENTITY_CATALOG.md`
- `RELATION_CATALOG.md`
- `EVIDENCE_LEDGER.md`
- `GUARDRAILS.md`
- `TERMS_GLOSSARY.md`
- `OPEN_QUESTIONS.md`
- `IMPLEMENTATION_READINESS.md`
Current accepted baseline:
- Canonical Entity Catalog v0.4-pre is the active pre-release baseline.
- HUB has an open contour and a managed client/company context.
- `hub.public_pool_client` is a source-backed special Client used by the public pool context.
- `hub.open_contour` must not be treated as an ordinary `hub.client_context`.
- `ops.card` is the canonical OPS work object.
- OPS Product, OPS Gateway, and ENGINE-side OpsLayer are different entities.
- ENGINE L1/L2 workflow split is source-evidenced enough for first resolver implementation.
- Engine-side OPS / Agent Monitor / tender-agent config is non-canonical tech debt.
- Future Interface Layer is a planned separate layer/service, not more custom UI inside ENGINE core.
Current working evidence artifacts:
- `EVIDENCE_HARDENING_PLAN_V0_3_1.md`
- `EVIDENCE_LEDGER_HUB_P0.md`
- `EVIDENCE_LEDGER_OPS_P0.md`
- `EVIDENCE_LEDGER_OPS_GATEWAY_P1.md`
- `EVIDENCE_LEDGER_ENGINE_DIRTY_BOUNDARY_P1.md`
- `EVIDENCE_LEDGER_ENGINE_WORKFLOW_P1.md`
- `ONTOLOGY_SERVICE_PLACEMENT_AND_USE_CASES.md`
@@ -0,0 +1,90 @@
# Relation Catalog v0.4-pre
Status: pre-release implementation baseline
Date: 2026-06-18
Relations are written as product-level semantics, not database foreign keys. Implementation can later map them to tables, APIs, MCP tools, or resolver rules.
## HUB Relations
| Relation ID | From | To | Meaning | Status |
| --- | --- | --- | --- | --- |
| `hub.open_contour.uses_public_pool` | `hub.open_contour` | `hub.public_pool_context` | Open contour is implemented through public pool context. | source-evidenced |
| `hub.public_pool_context.backed_by_client` | `hub.public_pool_context` | `hub.public_pool_client` | Public pool context uses a special source-backed Client. | source-confirmed |
| `hub.user.has_membership` | `hub.user` | `hub.membership` | User belongs to a context through membership. | source-confirmed |
| `hub.membership.in_context` | `hub.membership` | `hub.client_context` / `hub.public_pool_context` | Membership points to closed client context or public pool. | source-confirmed |
| `hub.access_request.targets_context` | `hub.access_request` | `hub.client_context` / `hub.public_pool_context` | Request targets a context. | source-confirmed |
| `hub.public_access_request.promotes_to_client_context` | `hub.public_access_request` | `hub.client_context` | Public request can become client membership after approval. | source-confirmed |
| `hub.invite.targets_context` | `hub.invite` | `hub.client_context` / `hub.public_pool_context` | Invite targets a context. | source-confirmed |
| `hub.application.has_access_result` | `hub.application` | `hub.application_access` | Application exposes effective access state. | source-confirmed |
| `hub.app_grant.grants_access_to` | `hub.app_grant` | `hub.application` | Grant contributes to effective access. | source-confirmed |
| `hub.app_exception.overrides_access_to` | `hub.app_exception` | `hub.application` | User-specific allow/deny exception. | source-confirmed |
| `hub.application_card.presents` | `hub.application_card` | `hub.application` | UI card presents app plus access state. | source-confirmed |
| `ndcauth.identity.maps_to_hub_user` | `ndcauth.identity` | `hub.user` | Auth subject resolves to launcher user. | source-confirmed |
## OPS Product Relations
| Relation ID | From | To | Meaning | Status |
| --- | --- | --- | --- | --- |
| `ops.workspace.contains_project` | `ops.workspace` | `ops.project` | Project belongs to workspace. | source-confirmed |
| `ops.workspace.has_member` | `ops.workspace` | `ops.workspace_member` | Workspace membership. | source-confirmed |
| `ops.project.has_member` | `ops.project` | `ops.project_member` | Project membership. | source-confirmed |
| `ops.project.contains_card` | `ops.project` | `ops.card` | Card belongs to project. | source-confirmed |
| `ops.card.has_status` | `ops.card` | `ops.card_status` | Card state. | source-confirmed |
| `ops.card.has_priority` | `ops.card` | `ops.card_priority` | Card priority attribute. | source-confirmed |
| `ops.card.assigned_to` | `ops.card` | `ops.assignee` | Card assignment. | source-confirmed |
| `ops.card.accountable_to` | `ops.card` | `ops.responsible` | Product-level responsibility relation. | product-required |
| `ops.card.typed_as` | `ops.card` | `ops.card_type` | Card subtype/purpose. | source-evidenced |
| `ops.card.related_to` | `ops.card` | `ops.card_relation` | Relation/dependency between cards. | source-confirmed |
| `ops.card.has_label` | `ops.card` | `ops.card_label` | Label/tag classification. | source-confirmed |
| `ops.card.has_comment` | `ops.card` | `ops.card_comment` | Discussion/comment relation. | source-confirmed |
| `ops.card.has_activity` | `ops.card` | `ops.card_activity` | Timeline/change relation. | source-evidenced |
| `ops.card.links_artifact` | `ops.card` | `ops.card_artifact_link` | Links output artifacts or docs. | source-evidenced |
| `ops.card.has_external_ref` | `ops.card` | `ops.external_ref` | Links external/source object. | source-confirmed |
## OPS Gateway Relations
| Relation ID | From | To | Meaning | Status |
| --- | --- | --- | --- | --- |
| `agent.token.represents_identity` | `agent.token` | `agent.identity` | Token authenticates agent identity, not user identity. | source-confirmed |
| `agent.identity.has_grant` | `agent.identity` | `agent.grant` | Identity receives grants. | source-confirmed |
| `agent.token.has_token_grant` | `agent.token` | `agent.token_grant` | Token-level grant binding. | source-confirmed |
| `agent.grant.allows_scope` | `agent.grant` | `agent.scope` | Grant enables tool/capability scope. | source-confirmed |
| `agent.scope.exposes_tool` | `agent.scope` | `agent.mcp_tool` | Scope controls MCP tool exposure. | source-confirmed |
| `agent.mcp_tool.writes_via_adapter` | `agent.mcp_tool` | `agent.tasker_adapter` | Gateway writes to OPS through adapter. | source-confirmed |
| `agent.mcp_tool.requires_idempotency` | `agent.mcp_tool` | `agent.idempotency_key` | Write operations require idempotency. | source-confirmed |
| `agent.mcp_tool.emits_audit` | `agent.mcp_tool` | `agent.audit_event` | Operations produce audit records. | source-confirmed |
| `agent.setup_packet.provisions_token` | `agent.setup_packet` | `agent.token` | Setup flow produces token/connect config. | source-evidenced |
## ENGINE Relations
| Relation ID | From | To | Meaning | Status |
| --- | --- | --- | --- | --- |
| `engine.workflow_l1.contains_node` | `engine.workflow_l1` | `engine.node_l1` | L1 workflow graph contains nodes. | source-confirmed |
| `engine.workflow_l1.contains_edge` | `engine.workflow_l1` | `engine.edge_l1` | L1 workflow graph contains edges. | source-confirmed |
| `engine.edge_l1.connects_nodes` | `engine.edge_l1` | `engine.node_l1` | Edge connects source/target node handles. | source-confirmed |
| `engine.node_l1.has_type` | `engine.node_l1` | `engine.node_type_l1` | Node type comes from registry/module. | source-confirmed |
| `engine.workflow_l1.has_acl` | `engine.workflow_l1` | `engine.workflow_acl` | Workflow uses access control. | source-confirmed |
| `engine.workflow_acl.has_owner` | `engine.workflow_acl` | `engine.workflow_owner` | ACL owns owner field. | source-confirmed |
| `engine.workflow_l1.has_share` | `engine.workflow_l1` | `engine.workflow_share` | Workflow can be shared/invited. | source-confirmed |
| `engine.workflow_l1.has_access_request` | `engine.workflow_l1` | `engine.workflow_access_request` | Access requests target workflow. | source-confirmed |
| `engine.node_l1.embeds_l2_workflow` | `engine.node_l1` | `engine.workflow_l2` | n8n subworkflow is attached to L1 node. | source-evidenced |
| `engine.workflow_l2.deployed_as_runtime_workflow` | `engine.workflow_l2` | `engine.workflow_l2_runtime_id` | Compiled n8n workflow deploy returns runtime workflow id. | source-confirmed |
| `engine.workflow_l2.runs_on_runtime_core` | `engine.workflow_l2` | `engine.l2_runtime_core` | L2 workflow targets n8n instance/core. | source-evidenced |
| `engine.l2_execution.belongs_to_runtime_workflow` | `engine.l2_execution` | `engine.workflow_l2_runtime_id` | Execution is emitted for n8n workflow id. | source-confirmed |
| `engine.l2_runtime_event.describes_execution` | `engine.l2_runtime_event` | `engine.l2_execution` | Runtime events carry execution id. | source-confirmed |
| `engine.l2_runtime_event.binds_run` | `engine.l2_runtime_event` | `engine.l2_run` | Event binds to run id. Current storage is ENGINE-side OpsLayer. | source-confirmed / tech-debt-adjacent |
| `engine.l2_run.has_session` | `engine.l2_run` | `engine.l2_session` | Session anchors related runtime events/runs. | source-confirmed / tech-debt-adjacent |
## Cross-Surface Relations Needed First
These are the first useful implementation targets for Ontology Core.
| Relation ID | From | To | Meaning | Status |
| --- | --- | --- | --- | --- |
| `ontology.resolves_ops_card_to_engine_context` | `ops.card` | `engine.workflow_l1` / `engine.workflow_l2` | Assistant in OPS can route a request to the correct Engine workflow context. | product-required |
| `ontology.resolves_engine_context_to_ops_project` | `engine.workflow_l1` / `engine.workflow_l2` | `ops.project` | Assistant in Engine can create/update cards in the correct OPS project. | product-required |
| `ontology.resolves_hub_app_to_project_context` | `hub.application` | `ops.project` / `engine.workflow_l1` | Application selection can suggest project/workflow context. | product-required |
| `ontology.selects_gateway_grant_context` | `assistant.bridge` | `agent.grant` | Ontology can help choose proper MCP/Gateway grant before tool calls. | product-required |
| `ontology.routes_interface_view_to_domain_package` | `future.interface_view` | `future.domain_package` | Future UI layer renders domain-specific views from ontology-backed data. | future-concept |
@@ -0,0 +1,49 @@
# Terms Glossary v0.4-pre
Status: pre-release glossary
Date: 2026-06-18
## Canonical Terms
| Term | Meaning |
| --- | --- |
| HUB | Launcher/application access layer with open and company/client contours. |
| Open contour | Public/open HUB branch for simple users and public pool access. |
| Client/company contour | Managed closed HUB context for companies/clients. |
| OPS Product | Operational work/project/card layer. |
| OPS Card | Canonical work object in OPS; Plane Issue/task/work item are aliases or subtypes. |
| OPS Gateway | Scoped MCP/API access layer for agents working with OPS. |
| Agent identity | Gateway execution identity, not a human user and not assistant persona. |
| Agent token | Opaque credential used by Gateway; not user identity. |
| ENGINE | Workflow/dev environment. |
| L1 workflow | NodeDC/React Flow canvas workflow. |
| L2 workflow | Runtime/subworkflow layer, currently n8n-backed. |
| Runtime workflow id | n8n runtime workflow id, separate from NodeDC L1 workflow id. |
| Runtime event | Event emitted by L2 runtime: workflow/node start/finish/success/error. |
| Assistant | Product assistant capability; exact source model pending AI Workspace pass. |
| Ontology Core | Future platform service/module for canonical entities, relations, aliases, evidence, and resolver rules. |
| Interface Layer | Future UI/workview layer for automation dashboards, maps, forms, and controls. |
| Domain package | Domain-specific ontology extension, e.g. tenders, ecology, transport, robotics, ERP. |
## Alias Rules
| Alias | Canonical term |
| --- | --- |
| Plane Issue | `ops.card` |
| task / ticket / work item | `ops.card` or `ops.card_type`, depending on context |
| Authentik user / OIDC subject / JWT subject | `ndcauth.identity` |
| Launcher service / app | `hub.application` |
| Application tile / app card | `hub.application_card` |
| n8n workflow id | `engine.workflow_l2_runtime_id` |
| n8n execution | `engine.l2_execution` |
| Engine-side OPS / Agent Monitor OPS | `engine.tech_debt.ops_layer`, not OPS Product |
| Tender Agent Monitor UI | `engine.tech_debt.tender_domain_ui`, not future Interface Layer |
## Forbidden Shortcuts
- Do not say "OPS" without specifying OPS Product, OPS Gateway, or ENGINE-side OpsLayer.
- Do not say "workflow" without specifying L1 workflow, L2 workflow, or runtime workflow id when ambiguity matters.
- Do not say "user" when the context needs HUB user, NDCAuth identity, OPS member, or Gateway agent identity.
- Do not say "task" as the root concept when the object is an OPS card.
- Do not treat current tender/Agent Monitor implementation as target architecture.