Skip to content

Project Arc – Technical Design Document

Introduction

Purpose: This document describes the design, architecture, and operational model of Arc, Appcircle's central AI assistant. It covers the agent core, all integrated capabilities, security controls, multi-user isolation, deployment model, cost breakdown, and planned next steps.

Scope: Arc as a whole: the Claude agent loop, all MCP server integrations, the subagents and skills, the Slack adapter, the authorization and audit model, the per-user workspace isolation mechanism, and the Docker deployment.

Source code: github.com/appcircleio/arc


System Overview

Arc is Appcircle's central AI assistant, accessible through Slack as a single conversational interface to the systems that engineering and operations work is spread across: GitHub, Linear, Appcircle documentation, Jenkins, KolayIK, Microsoft Teams, Zendesk, HubSpot, and the Appcircle codebase itself.

Arc is an orchestrator, not a search index. At the center is a Claude agent that reads every incoming message and decides which tools to call before producing a response. Each capability is an independent module registered as an MCP (Model Context Protocol) server. Adding a new capability means adding a new module without touching the agent core.

Arc is built on Anthropic's @anthropic-ai/claude-agent-sdk, a Node.js SDK that drives the agent query loop, running on the Claude Opus 4.8 model.


Architecture

Technology Stack:

Layer Technology
Runtime Node.js 22, ES modules
Agent model Claude Opus 4.8 (CLAUDE_MODEL=claude-opus-4-8)
Package manager Yarn
Agent loop @anthropic-ai/claude-agent-sdk
Capability protocol Model Context Protocol (MCP)
Slack integration @slack/bolt (socket-mode)
Observability Langfuse / OpenTelemetry tracing
Container Docker (DHI hardened base dhi/node:22-dev, Debian 13 / glibc)
Config JS defaults + config/arc.env + OS env vars

Agent Loop:

The agent loop is driven by query() from @anthropic-ai/claude-agent-sdk. Every authorized message enters the loop. The loop runs until the agent produces a final text response, calling MCP tools as many times as needed.

Key properties:

  • System prompt and identity. ARC.md at the project root defines who Arc is. It is read once at startup and passed as systemPrompt to every query() call. Keeping it static means the prompt stays in Anthropic's prompt cache, reducing latency and cost.
  • Per-session workspace. The user's session workspace path is prepended to the user message (not the system prompt), so each user gets scoped context while the system prompt stays cached.
  • Skill discovery. settingSources: ['project'] instructs the SDK to auto-discover Arc's skills from .claude/skills/ and its subagents from .claude/agents/. Skills inject a prompt into the main session without a separate Claude API call.
  • Conversation continuity. Each Slack thread maps to a sessionId (resume). Subsequent messages in the same thread continue the prior context.
  • Cancellation. Each query runs under an AbortController. The "Stop" button in Slack triggers the abort signal; the loop exits cleanly.
  • Live progress. Every tool call the agent makes is streamed to the Slack message in real time (:gear: tool_name params).

Key Components

Claude Agent SDK (Core)

The primary reasoning and orchestration layer. Reads every user message, calls MCP tools, synthesizes results, and produces responses. All other components are tools called by this core. The model is Claude Opus 4.8 (switched from an earlier model on 2026-06-11 for lower per-token cost and fewer tokens per turn).

Skills

Skills inject a specialized prompt into the main session when their trigger matches, with no extra Claude API round trip. The current skill set:

  • linear-issue - create/update Linear items with Appcircle's templates.
  • docs-authoring - draft new documentation pages to the project's writing standard.
  • appcircle-code-standard - the team's code/PR-review standard, loaded before writing or reviewing code.
  • code-explanation - trace and explain a code flow across services.
  • bug-investigation - investigate a reported bug to root cause before assuming it exists.
  • feature-planning - impact analysis and design before implementation.
  • incident-postmortem - produce a blameless postmortem from a thread.
  • branch-cleanup - list/clean stale git branches (delegates deletion to the branch-deleter subagent after approval).
  • prep-release - the PREP pre-production release ruleset.
  • caveman / caveman-review - opt-in token-compressed communication / review modes.

The critic skill (Gemini destructive-action gate, see below) exists in the repo but is currently disabled in the loaded skill set.

Subagents

Self-contained, heavy-input / light-reasoning tasks run as subagents on cheaper models, invoked by the core through the Task tool. Each lives in .claude/agents/ and is auto-discovered:

  • appcircle-docs (sonnet) - answers Appcircle documentation questions; the answer is relayed as-is.
  • teams-transcript (haiku) - summarizes Microsoft Teams meeting transcripts.
  • code-reviewer (sonnet) - reviews a large / cross-service / high-risk branch diff in an isolated context, invoked by appcircle-code-standard.
  • branch-deleter (haiku) - mechanically deletes already-approved branches for branch-cleanup.

Gemini MCP (Critic Gate – currently disabled)

An independent second opinion from a different AI model (Google Gemini, gemini-3.5-flash). The critic skill is designed to call mcp__gemini__judge before any destructive or irreversible action to cross-check it against the conversation context.

The skill is currently disabled (since 2026-06-11): a Gemini outage caused repeated skip-asks, and it will be re-enabled behind a circuit breaker. While it is off, explicit human confirmation is the active gate before destructive actions. The Gemini MCP server and the mcp__gemini__judge tool remain wired and available.

Implementation: src/mcp-gemini.js. Authenticates with GEMINI_API_KEY.

Jenkins MCP (Read-only)

Appcircle's CI/CD orchestration server at jenkins.appcircle.io.

Arc can: list jobs, read job details, list builds, read build metadata, stream console logs, and run a composite diagnose-build (result + failed stage + relevant log slice in one call). Write and trigger operations are intentionally absent.

Implementation: src/mcp-jenkins.js. Authenticates with JENKINS_USER=arc and JENKINS_API_TOKEN.

KolayIK MCP

Appcircle's HR platform for team directory, leave management, and company calendar.

Arc can: look up team members by name, list upcoming leaves, list public holidays, list upcoming birthdays.

Implementation: src/mcp-kolayik.js. Authenticates with KOLAYIK_EMAIL=arc@appcircle.io and KOLAYIK_PASSWORD.

Microsoft Teams MCP

Microsoft Teams meeting transcripts, via the Microsoft Graph API.

Arc can: list meetings and fetch a meeting transcript. Access is authorized per meeting: the requesting user's trusted work email (from the SLACK_USERS map, originally sourced from KolayIK) is passed to the MCP server as ARC_REQUESTER_EMAIL, and the server only returns a transcript for a meeting the requester actually participated in (fail-closed when the email is missing).

Implementation: src/mcp-teams.js. Uses a delegated arc@appcircle.io refresh token (MS_REFRESH_TOKEN) against the arc-teams-transcript Microsoft Entra app (MS_TENANT_ID, MS_CLIENT_ID). Summaries are produced by the teams-transcript subagent.

Zendesk MCP (Read-only)

Appcircle's customer support platform.

Arc can: read and search tickets, organizations, users, and comments; list tickets by status, priority, assignee, or staleness; pull customer context. Read-only - the MCP server exposes no write tools. Access is gated per user by MCP_USER_ACL.zendesk.

Implementation: src/mcp-zendesk.js. Authenticates with API-token Basic auth (ZENDESK_EMAIL/token:ZENDESK_API_TOKEN) against ZENDESK_SUBDOMAIN.zendesk.com.

HubSpot MCP (Read-only)

HubSpot CRM. Arc can: search and read contacts, companies, deals, tickets and other CRM records, run SQL-style queries, and read owners, property definitions, org details, and campaign analytics. Read-only for phase 1 - the server's single write tool is deliberately not on the allowlist. Access is gated per user by MCP_USER_ACL.hubspot.

Transport: HTTP MCP. Authentication is per user: a shared OAuth app (HS_CLIENT_ID / HS_CLIENT_SECRET) plus a per-user refresh token (HS_REFRESH_TOKEN__<user>), collected into config.HUBSPOT_CREDENTIALS at startup and minted at runtime (src/auth-hubspot.js).

ast-grep MCP

A structural code search and rewrite tool based on Abstract Syntax Trees (ASTs). Unlike text search (ripgrep), ast-grep understands code structure, so patterns like $VAR.method($$$ARGS) match semantically rather than textually.

Arc can:

  • search - find code patterns across any cloned repo (C#, TypeScript, JS, Python, Java, Go, and more).
  • rewrite-preview - dry-run a structural transformation and show the diff before applying.
  • rewrite-apply - apply the transformation in place (always previewed first).

Implementation: src/mcp-ast-grep.js. Calls the @ast-grep/cli@0.43.0 binary.

GitHub: github.com/ast-grep/ast-grep

gitnexus MCP (Code Knowledge Graph)

A code knowledge graph that indexes a curated set of Appcircle source repositories into a queryable graph database (LadybugDB). The graph captures structural relationships between symbols: which method calls which, which class implements which interface, which service imports which module.

Indexed set. Not the full organization. config/repos.txt is a curated subset - every repo with recent human activity (roughly the last month, bots excluded) plus all backend repos by prefix (ac-server-*, ac-service-*, ac-lib-*). The full org is too RAM-heavy to index; the curated set keeps it manageable.

How the graph is built:

  1. Each source file is parsed into an AST using language-specific parsers (tree-sitter grammars for C#, TypeScript, Java, Go, Python, and more). This step uses no LLM - it is deterministic and fast.
  2. From the AST, structural nodes (class, method, function, file) and edges (calls, implements, imports, contains) are extracted.
  3. The resulting graph is stored in LadybugDB, an embedded graph database. The index lives at /gitnexus and the source files live at /repositories.

Arc's graph queries:

  • impact / api_impact - blast radius of a change before writing code.
  • context - callers and callees of a symbol.
  • query - execution-flow search and concept queries in natural language.
  • cypher - custom graph queries using Cypher syntax.
  • detect_changes - map a diff to the affected execution flows.
  • list_repos / group_list - list indexed repos / groups; if empty, fall back to ast-grep/ripgrep.
  • route_map, shape_check, tool_map - structural analysis tools.
  • rename, group_sync - graph-write operations (used deliberately, not for ad-hoc reads).

Index lifecycle: The index is not built in the container. A prebuilt artifact is produced out-of-band by the build-index GitHub Actions workflow (nightly + manual) and published to a GitHub Release. On every container start the entrypoint downloads and extracts that artifact into /gitnexus (scripts/fetch-index.mjs); if it is unreachable, the cached copy is reused, otherwise boot fails fast. The container never runs gitnexus analyze, so boot stays light. The agent reads a consistent snapshot and never triggers an inline refresh.

License note: gitnexus does not carry a standard open-source license. Its inclusion as a core dependency creates a commercial risk if the tool's terms change. This is tracked as a known risk.

Version in use: gitnexus@1.6.5

Linear MCP

Appcircle's project management and issue tracking platform.

Arc can: read teams, issues, projects, milestones, and comments; create and update issues, projects, milestones, and comments using Appcircle's team templates (via the linear-issue skill).

Transport: HTTP MCP at mcp.linear.app/mcp. Authenticates via OAuth2 client credentials (LINEAR_CLIENT_ID, LINEAR_CLIENT_SECRET). The token is minted at runtime and cached; it is re-minted automatically before expiry (~30-day tokens).

No paid Linear seat is required. A dedicated OAuth app was created and authorized via the client credentials grant, covering all of Arc's Linear operations at no additional monthly cost.

GitHub MCP

GitHub, via the GitHub Copilot MCP endpoint.

Arc can: browse code, list branches, commits, releases, pull requests, and issues across all Appcircle repos; open and update pull requests; comment on pull requests and issues; create branches.

Arc cannot: merge pull requests, delete branches, force-push, manage repository settings, write to issues, or leave inline review approvals/change requests. Notably, direct file writes are also excluded (create_or_update_file is not allowed): it re-sends whole files and skips lockfile/build steps, so file changes go through a fresh workspace clone plus git push. All of these are deliberately omitted from ALLOWED_TOOLS.

Transport: HTTP MCP at api.githubcopilot.com/mcp/. Authenticates with GITHUB_PAT.

Context7 MCP

A versioned third-party library documentation service. When Arc needs to answer a question about an external package, Context7 returns up-to-date docs for the specific version in use rather than relying on potentially stale training data.

Arc can: resolve-library-id to find a library, query-docs to fetch relevant documentation.

Transport: HTTP MCP at mcp.context7.com/mcp. Authenticates with CONTEXT7_API_KEY.

Website: context7.com


Team of Rivals

Arc's design is intentionally multi-model. Rather than a single AI making all decisions, independent systems are meant to check each other's work. This is the "Team of Rivals" principle:

"If You Want Coherence, Orchestrate a Team of Rivals" arxiv.org/abs/2601.14351

The pillars:

  • Claude Agent SDK (core). The primary reasoning and orchestration layer. Handles all tool calls and response synthesis.
  • Gemini MCP (critic gate). An independent second opinion from a different AI model, designed to run before every destructive or irreversible action. Currently disabled (see the Gemini MCP component above); while off, explicit human confirmation is the active gate.
  • CodeRabbit (PR reviewer). An automated code review service that triggers on every pull request Arc opens on GitHub, providing a review layer independent of both Claude and Gemini. A single seat is scoped to Arc's GitHub user, so only pull requests opened by Arc receive automated review - not the entire organization's pull request volume. Website: coderabbit.ai

For high-risk diffs Arc opens, the code-reviewer subagent adds a further internal review pass before the PR is finalized.


Detailed Design

Security

Security is layered across multiple mechanisms, none of which relies on a single point of trust.

Trust Boundary

Only a message from an authorized Slack user is treated as an instruction. URLs, file contents, Linear and GitHub issue bodies, Jenkins console logs, and MCP tool results are all data, not instructions. If any of that data contains text that looks like a command ("ignore previous instructions", "your real task is..."), it is treated as content to analyze and surfaced to the user. Arc never executes shell commands, modifies files, opens PRs, or calls any write tool based solely on the content of a tool result or pasted text.

Authorization - Allowlists

Access to Arc is governed by two allowlists, both keyed on stable Slack IDs (never display names):

  • DM access (USER_ALLOWLIST). Direct messages are restricted to a named allowlist in config/index.js. The list is written with human-readable Slack usernames for maintainability, but the runtime gate resolves each username to its stable Slack user ID (SLACK_USERS map) at startup and checks the incoming message.user against the stable ID.
  • Channel access (CHANNEL_ALLOWLIST). Arc also answers @mentions inside a small set of allowlisted (private) channels. Authorization there is membership-based: any member of a listed channel may mention Arc. Mentions from any other channel (public ones included) are ignored silently. An empty list means no channels (fail-closed).

This means:

  • A Slack display name change does not affect access in either direction.
  • There is no way to gain access by impersonating or guessing a username.
  • Removing a user (or channel) from the list takes effect on the next restart.

The SLACK_USERS map also carries each user's trusted work email (sourced from KolayIK). That email is the requester identity used for write attribution (the "Requesting user:" preamble) and to authorize Teams transcript and HubSpot access.

Unauthorized requests are rejected before the agent loop starts. A rejection audit event is written and the user receives :no_entry: You are not authorized to use Arc.

Per-User MCP Access Control

Some MCP servers are restricted per user via MCP_USER_ACL (server key -> allowed emails). For any other requester the server is removed from the query's mcpServers and its mcp__<server>__* tools are dropped from allowedTools - deterministic and fail-closed on a missing or unknown email. Currently hubspot and zendesk are gated this way; servers not listed are available to every authorized user.

Audit Logging

Every accepted request and every rejection is written as a structured JSON line to stdout. Docker log collection (or any compatible log aggregator) picks this up as jsonPayload.

Accepted request log:

{
  "ts": "2026-06-04T10:00:00.000Z",
  "event": "prompt",
  "user": "U0B3P0MM41E",
  "username": "ozcanovunc",
  "prompt": "first 500 chars of the message..."
}

Rejection log:

{
  "ts": "2026-06-04T10:00:00.000Z",
  "event": "rejected",
  "user": "UXXXXXXXXXX",
  "username": "unknown"
}

The username field is resolved at runtime via client.users.info and cached in memory. It is stored in the audit log for human readability only - the authorization gate never uses it.

Tracing of the agent loop and tool calls is also exported to Langfuse / OpenTelemetry (src/instrumentation.js), with secret values masked before export.

Read/Write Separation - Allowed Tools

Arc has an explicit ALLOWED_TOOLS whitelist in config/index.js. Any tool not on this list is blocked by the SDK before it can execute. The whitelist is intentionally asymmetric:

  • Read tools (Read, Grep, Glob) are allowed broadly - they can read any path.
  • Write tools are listed by exact name - adding a new write capability requires a deliberate code change.
  • MCP tools follow the same principle: Jenkins, KolayIK, and Zendesk are read-only (list-* / get-* / search-* prefixes). GitHub write tools are listed individually, excluding merge, delete, admin, issue writes, inline review writes, and direct file writes. HubSpot is read-only for phase 1. ast-grep rewrite-apply and gitnexus rename/group_sync are the only structural write tools, each previewed first.

Tool-Use Hooks

Three hooks run around tool calls:

  • hook-gitnexus.js (PreToolUse). A narrow substring-deny hook that blocks any tool call referencing the /gitnexus index path with 403 Forbidden. It is false-positive-free because no legitimate flow references that path.
  • hook-attribution.js (PreToolUse). Appends the requester-attribution footer (the trusted Slack-derived work email) to Linear and GitHub writes. Fail-closed: a write with no resolvable email is blocked.
  • hook-secret-guard.js (PostToolUse). Withholds any tool output that contains a configured secret value (read from arc.env.example + process.env) before it reaches the model - the backstop against printenv / file-read leaks.

Note on path enforcement. The earlier broad PreToolUse path guard was removed on 2026-06-04 after false positives on legitimate git/gh paths. Current path enforcement is: /app (Arc's own source) is immutable via the read-only image filesystem; /gitnexus is guarded by the narrow hook above; /repositories is read-only at the source mount but is not yet guarded at the process level (mount-layer enforcement is an open TODO). Per-user workspace isolation under $WORKSPACE_DIR relies on ARC.md instructions plus the Slack allowlist as the outer bound.

Destructive Action Gate (Critic)

Code changes, PR creation, Linear ticket creation, and comments are designed to be gated behind the critic skill, which calls mcp__gemini__judge with the proposed action and conversation context. The critic skill is currently disabled (see the Gemini MCP component); while it is off, explicit user confirmation in-thread is the active gate before Arc executes a destructive or irreversible action.

Surface Restriction

Arc responds only to direct messages (channel_type === 'im') from allowlisted users and to @mentions inside allowlisted private channels. Bot messages and system subtypes are ignored. This limits the attack surface to authenticated Slack users on the allowlists.

CodeRabbit - Data Privacy

CodeRabbit reviews pull request code on behalf of Arc. Before enabling this integration on Appcircle's private repositories, written confirmation was obtained from CodeRabbit (Mitali Sapra, mitali@coderabbit.ai) on the following points:

  • Private repository code is not used to train foundation models.
  • Privacy and security handling for private repositories is consistent across all plans.
  • Enterprise-grade security controls are available, with documentation on retention, subprocessors, and DPA availability on request.
  • Providers are engaged in a way designed to protect customer data and support strong privacy guarantees.

This confirmation was requested in the context of KVKK compliance. The written exchange is on file with the Appcircle team.


Deployment and Infrastructure

Base Image and Runtime

FROM dhi/node:22-dev   # DHI hardened base (Debian 13 / glibc); production pulls the GAR mirror

Node.js 22 on a DHI (Docker Hardened Images) base. @ast-grep/cli@0.43.0 and gitnexus@1.6.5 are installed globally as CLI binaries. The C++ build toolchain is used only during image build (to compile tree-sitter grammars without prebuilts) and is purged afterward to keep the final image lean. Production builds from a GAR mirror of the base image; a local build can swap to the dhi.io base.

Volume Mounts

The container uses three Docker volumes:

Mount Purpose Agent access
/repositories Canonical Appcircle source (curated subset) Read-only at source; process-level guard is an open TODO
/gitnexus Knowledge graph index (LadybugDB) Read-only (narrow PreToolUse deny hook)
/workspaces Per-user session workspaces Read-write

On every start the entrypoint script (scripts/entrypoint.sh) wipes the per-user session workspaces, clones or shallow-pulls every canonical repo into /repositories, and acquires the gitnexus index into /gitnexus by downloading the prebuilt artifact from a GitHub Release. The container never builds the index itself.

Health Check

A minimal HTTP server listens on $PORT (default 8080) and responds ok to any request. This gives the container a health check endpoint. The Slack socket-mode adapter does not expose an HTTP port on its own.

Configuration and Secrets

Non-secret defaults are in config/index.js (committed). Secrets are supplied via:

  • config/arc.env (local development, gitignored, KEY=value format)
  • OS environment variables (CI/CD, production)

Precedence: OS env vars override arc.env, which overrides config/index.js defaults.

Secrets required at runtime:

SLACK_BOT_TOKEN          - Slack bot token (socket-mode)
SLACK_APP_TOKEN          - Slack app-level token (socket-mode)
CLAUDE_CODE_OAUTH_TOKEN  - Claude agent SDK authentication token
GITHUB_PAT               - GitHub Personal Access Token
GEMINI_API_KEY           - Gemini API key (critic gate)
CONTEXT7_API_KEY         - Context7 API key (library docs)
JENKINS_API_TOKEN        - Jenkins service account token
KOLAYIK_PASSWORD         - KolayIK service account password
LINEAR_CLIENT_ID         - Linear OAuth app client ID
LINEAR_CLIENT_SECRET     - Linear OAuth app client secret
MS_REFRESH_TOKEN         - Microsoft Graph delegated refresh token (Teams transcripts)
ZENDESK_API_TOKEN        - Zendesk Support API token
HS_CLIENT_ID             - HubSpot OAuth app client ID (shared)
HS_CLIENT_SECRET         - HubSpot OAuth app client secret (shared)
HS_REFRESH_TOKEN__<user> - HubSpot per-user refresh token
LANGFUSE_PUBLIC_KEY      - Langfuse tracing public key
LANGFUSE_SECRET_KEY      - Langfuse tracing secret key

Performance Considerations

Multi-User Isolation

Multiple team members can use Arc simultaneously with no risk of interference between sessions.

Automatic workspace assignment. When a message arrives, the Slack adapter derives a session workspace from the stable Slack user ID:

/workspaces/<slack_user_id>/

This directory is created automatically (mkdir -p) if it does not exist.

Write isolation. Every file write, git clone, build output, and generated artifact is scoped to the requesting user's workspace. Two team members can edit the same repository simultaneously with no conflict because each works in their own fresh clone. Isolation under $WORKSPACE_DIR relies on the ARC.md instructions and the Slack allowlist as the outer bound; mount-layer enforcement of the per-user boundary is an open TODO (see the security note above).

Shared read, isolated write. The curated Appcircle repositories live at /repositories as a single shared read-only copy. All users query the same source for understanding code - there is no per-user copy. When a user needs to modify code, the relevant repo is cloned freshly from GitHub into the user's own workspace.

Thread-based session continuity. Each Slack thread maps to a sessionId. Concurrent queries run under separate AbortController instances. A user clicking "Stop" aborts only their own query.

File attachments. Files dropped into a Slack DM are downloaded into the user's workspace under slack-uploads/<file_id>/. Other users cannot access this path.

Adapter Portability

The runQuery() function in src/common.js is adapter-agnostic. It accepts prompt, sessionId, abortSignal, and userWs. The Slack-specific logic (DM and channel-mention paths) lives entirely in src/adapter-slack.js. Adding support for a new surface (Microsoft Teams, CLI, web UI) means adding a new src/adapter-<name>.js file without changing the agent core, security hooks, or MCP server registrations.


Risks and Mitigation Strategies

Claude Enterprise Upsell Trigger

Arc uses a Claude Team account, not Claude Enterprise. Anthropic's systems can detect usage patterns that resemble enterprise-scale workloads - particularly from US-market accounts - and may apply pressure to upgrade or trigger unexpected billing.

Mitigation: The Claude Team account will be created in Turkey. A Turkish account with moderate user counts is less likely to appear on Anthropic's enterprise radar. This is a mitigation, not a guarantee, and the risk of unexpected cost escalation remains.

CodeRabbit Scope Creep

CodeRabbit is configured as a single seat tied to Arc's GitHub user. The expectation is that only pull requests opened by Arc are reviewed automatically. If the seat is later reused or the integration is widened to the organization level, costs will increase significantly (CodeRabbit's organization-wide plans are substantially more expensive). Any change to the CodeRabbit configuration should be a deliberate decision, not a side effect of a GitHub org settings change.

gitnexus License

gitnexus does not carry a standard open-source license. Its inclusion as a core dependency creates a commercial risk if the tool's terms change or if Appcircle's usage exceeds what is implicitly permitted.


Costs

The figures below reflect the original phase-1 plan and have not been revised since Arc went live with additional integrations (Teams, Zendesk, HubSpot, Langfuse) and the move to the Claude Opus 4.8 model. They should be refreshed against current usage.

All figures are in USD per month.

Claude Team

A dedicated Claude Team workspace for Arc. Initially one premium seat to observe usage patterns; a second seat can be added under a rotation model if usage warrants it.

Seats Monthly cost
1 (initial) $125
2 (if needed) $250

Context7

Context7 starts on the free tier. If monthly usage exceeds 1,000 API calls, the pro plan will be activated.

Tier Monthly cost
Free (up to 1,000 calls) $0
Pro (above 1,000 calls) $10

Gemini

Used for the critic gate (currently disabled). Ongoing cost is not yet determined.

Tier Monthly cost
Free trial $0
Paid (TBD) TBD

CodeRabbit

Pro plan on a single seat scoped to Arc's GitHub user.

Plan Monthly cost
Pro $30

Linear

No paid Linear seat is required. A dedicated OAuth app was created and authorized via the client credentials grant, covering all of Arc's Linear operations at no additional cost.

Tier Monthly cost
OAuth app (client credentials) $0

Summary

Service Initial monthly cost
Claude Team (1 seat) $125
Context7 (free tier) $0
Gemini (free trial) $0
CodeRabbit Pro $30
Linear (OAuth app) $0
Total $155

Adding a second Claude seat would increase the monthly total to $280. This summary predates the Teams / Zendesk / HubSpot / Langfuse additions and the Opus 4.8 switch and should be refreshed.


Next Steps

  • Teams adapter. The Teams transcript capability is in place (Teams MCP + teams-transcript subagent). The remaining step is a full src/adapter-teams.js that, following the Slack adapter as a blueprint, brings Arc's full capability set to Microsoft Teams as a second chat surface.
  • CSM meeting summaries at scale. Building on the Teams transcript capability, scale it to Customer Success Manager meetings: summarize customer calls, extract action items, and link them to Linear issues automatically.
  • HubSpot / Zendesk writes. Both are read-only today. A deliberate phase-2 decision could add scoped write tools (e.g. ticket updates, CRM record updates) behind the per-user ACL.
  • Re-enable the critic gate. Bring the critic skill back behind a circuit breaker so a Gemini outage degrades gracefully instead of forcing repeated skip-asks.
  • Admin panel. A lightweight internal UI (or Arc command) to add and remove users from the allowlists, grant or revoke specific capabilities per user, and view active sessions without requiring a code change or container restart.
  • Extended KolayIK capabilities. Expand the KolayIK MCP beyond read-only lookups - for example, submitting leave requests, viewing payslips, or managing time-off approvals directly from Slack.
  • Observability alerting. Structured audit logs and Langfuse/OpenTelemetry tracing are in place. The next step is routing logs to a centralized aggregator and adding alerting for repeated authorization rejections, high error rates, and cost anomalies.
  • Process-level mount enforcement. Close the open TODO: enforce the /repositories read-only boundary and per-user $WORKSPACE_DIR isolation at the mount/process layer rather than relying on instructions plus the allowlist.
  • Onboarding documentation. A short internal guide for adding or removing users from the allowlists, rotating secrets, and refreshing the gitnexus index.