# NODE.DC Ontology Core

Docs-first ontology service/module for NODE.DC.

Current status: `v0.4-pre` implementation slice.

The read-only dynamic MCP integration for AI Workspace is documented in
[`../../docs/AI_WORKSPACE_ONTOLOGY_MCP.md`](../../docs/AI_WORKSPACE_ONTOLOGY_MCP.md).

This module owns:

- canonical entity catalog;
- relation catalog;
- alias registry;
- guardrails;
- evidence index;
- first context resolver rules for OPS -> ENGINE and ENGINE -> OPS.
- assistant access policy for NDC Core Assistant permissions.
- assistant action registry and risk policy for safe assistant-mediated operations.

It does not own:

- HUB users/clients/app access source data;
- OPS cards/projects source data;
- ENGINE workflows/runtime source data;
- OPS Gateway grants/tokens/scopes enforcement;
- runtime data, logs, dumps, storage, env, or secrets.

## Layout

```text
catalog/entities.json
catalog/relations.json
catalog/aliases.json
catalog/guardrails.json
catalog/evidence.json
catalog/resolver-rules.json
catalog/context-bindings.json
catalog/assistant-access-policy.json
catalog/assistant-actions.json
catalog/assistant-risk-policy.json
catalog/domain-packages/*/*.json
examples/*.json
docs/baseline/*.md
docs/CONTEXT_BINDINGS.md
docs/ASSISTANT_ACCESS_POLICY.md
docs/ASSISTANT_ACTION_REGISTRY.md
docs/ASSISTANT_CALLER_CONTRACT.md
docs/ASSISTANT_EXECUTION_GATEWAY.md
docs/SEO_DOMAIN_ONTOLOGY.md
docs/PROJECT_ONTOLOGY_INSTANCE_SCHEMA.md
src/catalog.mjs
src/registry.mjs
src/validate.mjs
src/resolver.mjs
src/assistant-policy.mjs
src/assistant-action-resolver.mjs
src/assistant-action-plan.mjs
src/assistant-action-caller.mjs
src/assistant-action-executor.mjs
src/adapters/hub-launcher-admin.mjs
```

## Validate

```text
npm run validate
npm run smoke:mcp
```

## Resolver Smoke

```text
npm run smoke:resolver
```

## Assistant Policy Smoke

```text
npm run smoke:assistant-policy
```

Resolve one assistant access input:

```text
npm run assistant:policy -- --input-json examples/assistant-access-admin-client.example.json
```

## Assistant Action Smoke

```text
npm run smoke:assistant-actions
npm run smoke:assistant-action-plan
npm run smoke:assistant-caller
npm run smoke:assistant-executor
```

Resolve one assistant action request:

```text
npm run assistant:action -- --input-json examples/assistant-action-block-user.example.json
npm run assistant:plan -- --input-json examples/assistant-action-block-user.example.json
npm run assistant:caller -- --input-json examples/assistant-caller-preview-block-user.example.json
npm run assistant:execute -- --input-json examples/assistant-action-block-user.example.json
```

The action resolver returns a policy decision such as `forbidden`, `denied`, `needs_confirmation`, `future_adapter`, or `allowed`.
The action planner returns a dry-run app-owned adapter request plan. It does not execute mutations.
The caller contract returns compact UI previews and confirmation tokens for write actions.
The executor validates the plan and defaults to `dry_run`; live write execution requires a matching confirmation token, internal gateway auth, and an implemented adapter.

## Resolve One Request

```text
npm run resolve -- --input-json examples/ops-card-to-engine-request.json
```

## Registry CLI

List known contexts:

```text
npm run registry -- list-contexts
```

Dry-run adding an Engine context:

```text
npm run registry -- add-context --input-json examples/engine-context.example.json --dry-run
```

After a real Engine `workflow_id` / `node_id` is known, create a real context JSON and run the same command without `--dry-run`.

Dry-run adding an OPS <-> ENGINE binding:

```text
npm run registry -- add-binding --input-json examples/ops-engine-binding.example.json --dry-run
```

Dry-run importing an Engine workflow manifest and optional OPS binding:

```text
npm run registry -- import-engine-context --input-json examples/engine-workflow-manifest.example.json --dry-run
```

The resolver returns:

- canonical input entity;
- matched source-system contexts;
- selected resolver rule;
- existing context bindings;
- missing binding types required for the selected route.

## Domain Packages

Ontology Core can load domain packages from:

```text
catalog/domain-packages/*
```

Each package may contribute entities, relations, aliases, guardrails, evidence, resolver rules, context binding types, assistant access policy entries, assistant actions, and risk policy entries.

Current package:

- `integration` - provider-neutral external provider connection, capability, collection, read-model and red command-domain ontology used by all adapter services.
- `seo` - NDC SEO mod domain ontology for site scans, project ontology instances, scope contracts, semantic analysis, market evidence, optimization planning, validation, changesets, and future app-owned SEO assistant actions.
- `map` - provider-neutral NDC Module Studio map ontology for spatial subjects, layers, routes, zones, shared labels, visibility rules, selection, and replaceable renderer adapters.
- `gelios` - provider-neutral Gelios fleet and telemetry ontology, bound to map.moving_object, map.zone and map.place_target without exposing provider credentials or renderer objects.

The package loader merges domain packages into the base catalog before validation. Domain packages extend core meanings; they do not own app data or execute mutations.

## First Implementation Target

The first useful resolver flows are:

- OPS -> ENGINE: resolve an OPS project/card request into Engine workflow/L1/L2 context.
- ENGINE -> OPS: resolve an Engine workflow/node request into target OPS project/card context.

Ontology Core advises context. OPS Gateway remains the permission/enforcement layer.

## Context Bindings

`catalog/context-bindings.json` is the bridge from stable ontology IDs to real source-system identifiers.

Current active seed contexts:

- OPS project `NDC PLATFORM`
- OPS card `Антология / Ontology Core`

Cross-surface bindings are intentionally empty until a real OPS card/project is linked to a real ENGINE workflow/node. The resolver already reports which binding type is missing, instead of pretending the link exists.
