veritas-kanban/AGENTS.md

17 KiB

AGENTS.md — Canonical Agent Instructions for Veritas Kanban

Canonical source. All coding harnesses — Codex, OpenClaw, Hermes, Claude, and others — read this file first. Harness-specific supplements (e.g. CLAUDE.md) extend, never duplicate or contradict, these rules.

Version: 5.2.5 Freshness policy: update within two working days of any toolchain or architecture change. Stale fields (package manager, Node version, provider list, test commands) are caught by pnpm check:pnpm-settings and the smoke-test CI job.


Runtime requirements

Tool Required version How to verify
Node.js ≥ 22.22.1 node --version
pnpm ≥ 11.0.0 pnpm --version
Git ≥ 2.38 git --version

The packageManager field in package.json is pinned to pnpm@11.1.1. Do not install with npm or yarn. Do not up-rev the pin without updating this file.


Repository layout

veritas-kanban/
├── server/          Express + TypeScript API, agent orchestration, storage
├── web/             React + Vite SPA
├── cli/             Commander.js CLI (mirrors API endpoints)
├── shared/          Shared TypeScript types and utilities
├── mcp/             MCP server
├── desktop/         Electron desktop wrapper
├── docs/            Operator and developer documentation
├── prompt-registry/ Prompt templates and cross-model review SOPs
└── .veritas-kanban/ Runtime data: agent-registry, logs, telemetry

Workspaces are declared in pnpm-workspace.yaml.


Essential commands

# Install
pnpm install

# Build (all workspaces in dependency order)
pnpm build

# Dev server (server + web, hot-reload)
pnpm dev

# Tests
pnpm test                       # Vitest across server, web, mcp, cli
pnpm test:unit                  # Per-workspace tests sequentially
pnpm test:e2e                   # Playwright end-to-end

# Type check (builds shared first)
pnpm typecheck

# Lint / fix
pnpm lint
pnpm lint:fix

# Smoke checks
pnpm check:pnpm-settings        # Validates package manager fields match this file
pnpm smoke:cli-mcp              # CLI ↔ MCP compatibility smoke test

Do not run npm install, yarn, or bun install. If lockfile conflicts arise, resolve with pnpm install and commit the updated pnpm-lock.yaml without reformatting it.


Architecture rules

Server (Express + TypeScript)

  • All routes go through centralized middleware in server/src/middleware/.
  • Auth: JWT + API keys. Dev bypass: VERITAS_AUTH_LOCALHOST_BYPASS=true.
  • Storage: always go through storage/interfaces.ts. Never import fs directly in service files.
  • Error classes: UnauthorizedError, ForbiddenError, BadRequestError, InternalError.
  • Pagination: sendPaginated(res, items, { page, limit, total }).
  • Path traversal: always call validatePathSegment() on any user-supplied path component, then ensureWithinBase(base, resolved) before file I/O.
  • SQLite journal conversion runs from the bootstrap before server.ts imports routes. Normal startup eagerly creates many independent SQLite handles, so a live API handler cannot prove exclusive database ownership.
  • Governed SQLite DELETE or expert-override mode requires the signed external policy and the reference-counted process/host ownership lock. Do not reuse the short-lived generic FileLock for authoritative database ownership.

Web (React + Vite)

  • State: Zustand stores. No prop drilling past 2 levels.
  • Realtime: useRealtimeUpdates WebSocket hooks. Do not add polling when a hook exists.
  • Styling: Tailwind CSS with component-scoped overrides.
  • Frontend interfaces must exactly match server response shapes. Server is the source of truth.

CLI (Commander.js)

  • Every command mirrors an API endpoint.
  • --json flag for machine-readable output.
  • Colored output via chalk.

Shared types

  • All cross-package types live in shared/src/types/.
  • AgentProvider union is the single definition consumed by both server and web. Currently supported providers: openclaw | codex-cli | codex-sdk | codex-app-server | codex-cloud | claude-code | acp-stdio | hermes-cli | ollama-local | ollama-cloud | lm-studio-local | custom
  • Executable task adapters are currently openclaw, codex-cli, codex-sdk, codex-app-server, claude-code, acp-stdio, and hermes-cli. Explicitly configured providers outside that set must fail closed; never route them through an implicit OpenClaw fallback.
  • Probe and persist provider-runtime-manifest/v1 before mutating attempt state. New runtime controls must use the persisted evidence instead of provider-name checks, and provider version/build changes must invalidate cached conformance. Increment PROVIDER_RUNTIME_PROBE_REVISION whenever probe semantics or the built-in adapter capability evidence changes.
  • Normalize every configured harness through harness-support-profile/v1. Settings, API diagnostics, vk doctor, dispatch, and telemetry must use the same support tier and redacted readiness evidence. Only known legacy records whose built-in type and command both identify codex or hermes may infer a provider during migration; provider-less or profile/adapter-mismatched records fail closed before an attempt is created.
  • Credential-bound tool servers persist only exact definition/scope digests and safe target names in run-tool-catalog/v1. Discovery strips their source environment/header values, native provider injection omits them, and mediated invocation issues exact-action leases using the server-owned launch manifest digest. Credential-bound sessions are one-shot and raw values may exist only inside the controlled downstream dispatch callback.
  • Providers access credential-bound tools only through the system-owned veritas-run MCP bridge and an opaque in-memory run handle. Codex CLI/SDK, Codex app-server, Claude Code, and ACP stdio inject this shared contract; Hermes and OpenClaw fail closed until their certified transports can enforce it.
  • Classify launch credentials through run-launch-credential-plan/v1. Provider boot authentication, task integration definition IDs, and explicit high-risk environment passthrough are separate classes. Task integration credentials fail closed until an accepted tool or egress boundary proves brokered, non-bypassable delivery.
  • Persist run-supervisor/v1 before provider dispatch. Restart recovery must validate the exact runtime, task-envelope, launch-manifest, worktree, host, lease, and process/session identity; replay only after the durable event cursor; and record a typed recovery action instead of starting duplicate work or signaling an unverified process.
  • Resolve selected MCP servers through tool-server-definition/v1 and persist an immutable run-tool-catalog/v1 before provider dispatch. Required discovery failures block launch; optional failures remain visible and audited.
  • Native provider configuration may expose only tools with an allow decision. Approval-required tools must use the Veritas-mediated call_run_tool path so the exact action hash is approved before dispatch.
  • Tool-server environment values and credential values are never persisted. Credential-bound tool definitions remain fail-closed until the provider launch credential broker is active.

Agent provider notes

OpenClaw (v2026.6.11)

  • Task dispatch uses the gateway /tools/invoke endpoint with sessions_spawn.
  • Required gateway policy: sessions_spawn and sessions_send must be explicitly allowed on the operator-level gateway; they are blocked by default on fresh OpenClaw installs.
  • Set OPENCLAW_GATEWAY_URL (default http://127.0.0.1:18789) and optionally OPENCLAW_GATEWAY_TOKEN.
  • A pre-flight check is run before a task is marked active; policy denial returns an actionable configuration error.
  • See docs/AGENT-PROVIDERS.md § OpenClaw for full setup instructions.

Hermes Agent (v2026.7.7.2)

  • Dispatch uses the one-shot scripted interface: hermes -z <prompt>.
  • Hermes is spawned in the task worktree without a shell; stdout captures the final response, stderr captures diagnostics.
  • Project instructions are loaded automatically from AGENTS.md in the worktree root.
  • Session resume is not yet implemented; --resume/--continue are reserved for a future provider iteration.
  • Provider ID: hermes-cli. Auth probe: hermes --version.
  • Set HERMES_API_KEY or the appropriate model-provider key in the operator environment.
  • See docs/AGENT-PROVIDERS.md § Hermes for full setup instructions.

Codex (OpenAI)

  • codex-cli: codex exec --sandbox workspace-write --json
  • codex-sdk: programmatic SDK, requires @openai/codex-sdk
  • codex-app-server: pinned to codex-cli 0.145.0; supervised JSON-RPC v2 over strict stdio for one task-bound thread and turn.
  • App-server launch arguments are system-owned. Inherited MCP servers, hooks, plugins, apps, browser/computer tools, and remote control remain disabled. Selected run-scoped MCP servers are injected only through the immutable catalog's thread configuration.
  • App-server consumes only the checked-in v0.145.0 schemas and exposes initialize, thread start/resume/fork/compact/archive, and turn start/steer/interrupt. thread/shellCommand is never reachable.
  • conversation-lifecycle/v1 persists opaque thread, turn, item, parent, and fork identities. Resume and fork validate the source launch manifest, provider/model/policy, base revision, and worktree compatibility before a new attempt is created.
  • App-server command, file, permission, tool-question, and elicitation requests use run-approval/v1. Decisions must preserve the persisted revision and exact action hash; interruption and cancellation invalidate pending requests.
  • Auth: codex login status / OPENAI_API_KEY

Claude Code (v2.1.218)

  • Provider ID: claude-code. Default command: claude.
  • Veritas launches claude --bare --print --output-format stream-json with static sandbox-derived permissions and no shell.
  • Bare mode requires explicit environment authentication. OAuth/keychain state reported by claude auth status does not prove bare-mode readiness.
  • The terminal result record is authoritative. Veritas drains stdout after process close, persists session_id, and maps partial, hook, tool, subagent, usage, cost, and result records into run-event/v1.
  • Resume uses the exact persisted session through system-owned --resume. Native history fork adds --fork-session; caller-supplied lifecycle flags remain prohibited. Run-scoped MCP uses a system-owned strict config and exposes only catalog tools with an allow decision.
  • The shared approval broker is available, but Claude stays on static dontAsk permissions until its adapter exposes a pinned interactive request/response contract.

Agent Client Protocol (ACP v1)

  • Provider ID: acp-stdio. Configure the exact ACP agent command and arguments.
  • Veritas launches the agent without a shell in the task worktree and negotiates stable ACP protocol version 1 before attempt mutation.
  • Capability evidence comes from initialize; resume/load, fork, and close fail closed when the runtime does not advertise them.
  • session/update records enter the causal run journal. session/request_permission uses the durable approval broker.
  • Only immutable all-allow MCP server catalogs can be passed natively because ACP v1 has no per-tool allowlist. Partial catalogs fail closed.
  • The built-in buzz-agent profile remains provider acp-stdio, pins Buzz v0.4.24 at commit 710ed9fff57878a1d69f809b80a6ee0416c53fc4, and rejects buzz-acp, version drift, session loading, and network MCP claims.
  • The built-in copilot profile remains provider acp-stdio, pins Copilot CLI v1.0.74, owns the stdio safety argv, rejects broad allow/remote/TCP/config injection, and records public-preview plus incomplete-source limitations.
  • The built-in grok-build profile remains provider acp-stdio, pins Grok Build v0.2.111 build 94172f2aa4e5, launches grok agent --no-leader stdio, and rejects approval bypass, reauthentication, leader, plugin, endpoint, prompt, and resume argument injection.
  • vk acp serve --stdio exposes one Veritas-managed task as an ACP v1 server view for editors and other ACP clients. Bind with --task or require _meta["veritas/taskId"] on session/new; client-owned MCP catalogs fail closed.
  • ACP client disconnect never stops the durable Veritas run. Reconnect with session/load and _meta["veritas/afterSequence"]; cancellation uses the conversation interrupt path, not task termination.
  • See docs/AGENT-PROVIDERS.md § ACP stdio agent provider.

Security boundaries

  • No secrets in code. Use environment variables or brokered credentials.
  • Input validation. All user input is validated with Zod schemas before processing.
  • Path traversal. validatePathSegment() + ensureWithinBase() on every user-supplied path.
  • Env passthrough. Agents receive only the keys in the configured safe allowlist; see server/src/utils/codex-env.ts, server/src/utils/hermes-env.ts, and server/src/services/claude-code-adapter.ts plus server/src/services/acp-stdio-adapter.ts.
  • Launch arguments. Never put credential values in provider commands or arguments; use an allowlisted environment key or run-scoped brokered credential reference.
  • Log redaction. Trace logs and telemetry run through TRACE_SECRET_PATTERNS before storage.
  • No credentials in PR descriptions, test fixtures, or log snippets.

Testing expectations

  • Framework: Vitest (server, cli, mcp), React Testing Library (web).
  • Test files: *.test.ts co-located in src/__tests__/ or alongside source.
  • Aim for >80% coverage on critical paths (agent dispatch, auth, storage adapters).
  • Use vi.mock()/vi.fn() to isolate external processes and HTTP calls; no live credentials in unit tests.
  • Credential-gated smoke tests document the tested provider version in a @smoke describe block.
  • Match actual runtime schema in test fixtures — wrong field names (status: "success" vs success: true) are a common source of false-passing tests.

Multi-agent runtime

  • Agent registry: .veritas-kanban/agent-registry.json (file-based).
  • Agent names: use ALL CAPS for acronyms (VERITAS, TARS, CASE, K-2SO, R2-D2, MAX).
  • Heartbeat timeout: 5 min (configurable). Stale-check interval: 1 min.
  • Activity data source of truth: status-history files, not activity.json.
  • Dashboard optimistic updates: use onMutate in Zustand mutations.

Conventions

Artifact Style
TS files kebab-case.ts
Components PascalCase.tsx
Variables camelCase
Constants UPPER_SNAKE_CASE
Git commits Conventional Commits (feat:, fix:, docs:, chore:)
Branches feat/description-issue-number / fix/description-issue-number

Code quality gates

  1. Cross-model review required for non-trivial code changes. If Claude writes it, GPT reviews; if GPT writes it, Claude reviews. See prompt-registry/cross-model-review.md.
  2. No direct fs imports in service files — use the storage abstraction layer.
  3. All provider schemas validated — do not guess flag names; verify against versioned docs or provider --help output.
  4. pnpm-lock.yaml is generated by pnpm; do not reformat or hand-edit it.

File locations quick-reference

What Where
API routes server/src/routes/
Services server/src/services/
Zod schemas server/src/schemas/
Storage server/src/storage/
Server utilities server/src/utils/
React components web/src/components/
Zustand stores web/src/stores/
CLI commands cli/src/commands/
Shared types shared/src/
MCP server mcp/src/
Prompt registry prompt-registry/
SOPs docs/SOP-*.md
Agent registry .veritas-kanban/agent-registry.json
Agent run logs .veritas-kanban/logs/
Telemetry events .veritas-kanban/telemetry/

Harness-specific supplements

Harness File Purpose
Claude CLAUDE.md Claude-specific lessons, cross-model review notes
Codex / GPT AGENTS.md This file (canonical)
Hermes AGENTS.md This file (Hermes reads AGENTS.md first)
OpenClaw AGENTS.md This file