# Architecture: NODE.DC Tasker Codex API

Last updated: 2026-07-18.

## Goal

Give selected NODE.DC users a controlled way to connect their local Codex or another AI coding agent to Tasker so the agent can maintain project work items according to NODE.DC task-card rules.

The agent can create projects inside an explicitly granted workspace, create and
update cards, move them through states, write structured task documentation,
update checkers, add comments and bounded file attachments, assign existing
workspace users to project cards when permitted, and apply labels. It cannot
delete cards or projects, manage workspace settings, bypass workspace/project
grants, or call arbitrary Tasker endpoints.

## Product boundary

This module is a standalone service:

```text
Launcher / Hub
  owns platform entitlement: can this user/client use Codex agents?

Tasker / Operational Core
  owns workspaces, projects, issues, labels, states, members, comments

Agent Gateway
  owns agents, tokens, scopes, grants, MCP tools, audit, rate limits
```

The service is deployed as its own Docker container and has its own repository and database. It may call Launcher and Tasker through internal APIs, but it does not read or write either database directly.

## Runtime shape

```text
Local Codex
  -> independent Ops and read-only Ontology MCP servers over HTTPS
  -> Agent Gateway public endpoints (/mcp and /ontology-mcp)
  -> scope and grant checks
  -> Tasker internal adapter
  -> Tasker domain models
```

```text
User UI
  -> Launcher entitlement
  -> Tasker workspace feature settings
  -> Agent Gateway agent/token management
```

## Components

### Launcher integration

Launcher decides whether a user can use the module at all.

Required Launcher concepts:

- service: `operational-core`
- module entitlement: `codex_agents`
- scope owner: client/user/access matrix
- open contour support
- enterprise contour support

Launcher should not create low-level Tasker cards or tokens. It only projects entitlement and global lifecycle state.

### Tasker integration

Tasker shows the feature in `Workspace settings -> Features` only when:

- the current user has Tasker access;
- Launcher access check says the user has `codex_agents`;
- the workspace policy allows this workspace to host agents.

Tasker remains the owner of issues, states, labels, project members, comments, and structured blocks.

### Agent Gateway

Agent Gateway owns:

- agent profiles;
- pairing codes;
- opaque access tokens;
- token hashes;
- grants;
- scopes;
- audit events;
- idempotency keys;
- rate limits;
- MCP tools exposed to local Codex.

It should not execute user code and should not run Codex itself.

Agent lifecycle management is not public. Tasker/Launcher-facing management calls use `NODEDC_AGENT_GATEWAY_INTERNAL_TOKEN`, while external Codex calls use only the opaque agent token issued for one agent. The owner-scoped internal routes verify that the requested agent belongs to the requested `owner_user_id`.

### Tasker internal adapter

The adapter is a narrow Tasker API layer for Agent Gateway. It exists because the current Plane REST API is broad and includes operations the agent must not receive directly.

The adapter should expose intent-level operations:

- list allowed workspaces/projects;
- read project states, labels, members;
- create a project within a granted workspace after Tasker admin revalidation;
- search/list issues;
- read one issue with full comments and attachment metadata;
- create issue;
- patch allowed issue fields;
- append comment;
- attach a bounded base64 file through Tasker-owned object storage;
- update NODE.DC structured blocks;
- add existing workspace member to project when explicitly allowed;
- publish audit/realtime events.

It must reject delete, archive, workspace settings, project deletion, invite
creation, arbitrary path/URL attachments, and arbitrary path proxying.

## Data model

Initial Agent Gateway entities:

```text
agent
  id
  owner_user_id
  owner_email
  display_name
  avatar_url
  status: active | disabled | revoked
  created_at
  updated_at

agent_token
  id
  agent_id
  token_hash
  name
  purpose: ops | ontology
  status: active | revoked | expired
  expires_at
  last_used_at
  created_at

agent_grant
  id
  agent_id
  workspace_slug
  project_id (empty string internally means workspace-level grant)
  scopes[]
  mode: voluntary | reporting
  created_by_user_id
  created_at
  updated_at

pairing_code
  id
  agent_id
  code_hash
  status: active | used | expired | revoked
  expires_at
  created_at
  used_at

agent_audit_event
  id
  agent_id
  event_type
  actor_user_id
  metadata
  created_at

idempotency_key
  key
  agent_id
  request_hash
  response_body
  created_at
  expires_at
```

## Actor model

Writes should be visible as agent actions, not anonymous platform automation.

Recommended Tasker-side identity:

```text
display_name: Codex Agent: <name>
email: agent+<agent_id>@agents.nodedc.local
is_bot: true
owner_user_id: <human user id>
```

For audit and UI, every write must preserve both:

- `agent_id`;
- `owner_user_id`.

If Tasker cannot yet represent owned bot users cleanly, the adapter can initially use a system actor and store the agent metadata in audit payloads, but this should be treated as a migration step, not the final model.

## Capability model

Allowed initial scopes:

```text
workspace:read
project:read
project:create
project:member:add_existing
issue:read
issue:create
issue:update
issue:move
issue:comment
issue:label
issue:assign
issue:structured_blocks:write
issue:attachment:write
```

Explicitly denied for MVP:

```text
issue:delete
issue:archive
comment:delete
label:delete
state:create
state:delete
project:delete
workspace:settings
workspace:member:invite
workspace:member:remove
raw_tasker_api
```

Deleting or archiving a card remains a human-only operation.

## Two operating modes

### Voluntary mode

The user creates an agent and gives its token to their local Codex. Codex updates Tasker when the user asks it to.

This mode is user-owned and best for personal development workflow.

### Reporting mode

The enterprise/project admin requires agent reporting for a project. The developer still runs local Codex, but the expected workflow is:

- start work session;
- update active issue/checker;
- append implementation notes;
- finish work session.

This mode is policy-visible but cannot be fully enforced if Codex runs entirely on the developer machine outside a managed wrapper. The system can enforce token scope and show stale/missing reports, but it cannot force an arbitrary local agent to report unless the organization distributes a managed Codex config or wrapper.

## Deployment

Initial local target:

```text
ops-agents.local.nodedc -> Agent Gateway
```

Production-like domains should follow platform conventions:

```text
ops-agents.nodedc.ru or ops-agents.<deployment-domain>
```

The service should support:

- local `.env`;
- staging `.env.staging`;
- production secret store;
- Docker image build;
- container startup migrations;
- health endpoint;
- preflight script validating URLs/secrets.
