# 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.
