
# 工作原理

## 主机

```text
people ─┐
        ├─► your TLS proxy or tunnel ─► Acahti control plane ─► Runner
agents ─┘
```

| 主机 | 运行内容 |
|---|---|
| 控制面 | 网关镜像 `ghcr.io/acahti-ai/acahti`、Forgejo、Woodpecker server 和 PostgreSQL，以 Docker Compose 运行在 `~/acahti` 下。这里不运行流水线 |
| 执行节点 | 一个执行作业的 Woodpecker agent。并行度取决于主机的 CPU 和内存 |

## 网关

Go 网关是唯一对外公开的应用。网页端、MCP 和 REST API 都调用同一个内部目录，因此所有入口看到的数据和权限都一致。

| 路径 | 客户端 | 后端 |
|---|---|---|
| `/ui/*` | 浏览器中的用户 | 目录 |
| `/mcp` | IDE Agent | 目录 |
| `/acahti/v1` | CLI、脚本 | 目录 |
| `/<org>/<repo>.git` | Git | 以已认证用户身份代理到 Forgejo |
| `/api/packages/*` | npm、pip、uv | 以已认证用户身份代理到 Forgejo |
| `/hooks/*` | Forgejo、Woodpecker | 索引更新和实时事件 |

列表、「看板」和导航读取网关自己在 PostgreSQL 中的索引。Forgejo webhook 保持仓库数据最新；网关轮询 Woodpecker 的队列，并每分钟对账一次流水线历史。文件内容、diff 和运行中步骤的日志实时从内核读取；失败步骤的日志保存在索引中。

## 流水线

推送或 PR 会触发 Woodpecker。作业启动前，网关会展开它的 YAML：官方 pipe 变成 `acahti-pipe` 调用，具名密钥变成环境变量，每个步骤都会拿到本次运行的 Acahti 身份（`ACAHTI_USER`、`ACAHTI_TOKEN`、`ACAHTI_ROOT_URL`、`ACAHTI_ORG`）：即头提交作者的账号，找不到时退回到启动这次运行的账号。网关每隔几秒轮询一次 Woodpecker 的队列，每分钟把其历史对账进索引，`checks_wait`、Inbox 和「看板」都从索引读取。参见[流水线](/docs/pipelines/)。

## 数据

所有状态都以 bind mount 的形式存放在 `ACAHTI_DATA` 下。一旦有了数据，绝不要运行 `docker compose down -v`。

| 目录 | 内容 |
|---|---|
| `postgres/` | Forgejo、Woodpecker 和网关的数据库 |
| `forgejo/` | Git 仓库和 Forgejo 状态 |
| `woodpecker/` | Woodpecker server 状态 |
| `gateway/` | 邀请、密码、OAuth 客户端和刷新令牌、个人访问令牌、Argos 运行文件 |

每次升级前都要备份 PostgreSQL 和 `ACAHTI_DATA`。

## 独立插件

Phaevo 是一个单独维护的 GitHub 服务。插件的签名描述文件可以提供一个带自有图标的页头标签、侧栏、页面和 MCP 操作。内核负责验证来源、解析实时身份，并控制访问授权和安装状态。工单、待办、文档、Chat 和 Argos 内置于网关，无需安装插件。

每个插件都支持同样的安装、升级、启用、停用和卸载操作。部署和数据迁移由插件源码仓库的发布流水线负责；卸载会保留应用数据。用户只能看到当前权限允许的页面和操作。

Agent 通过 `whoami.plugins` 发现自己可访问的插件安装。源码仓库和文档链接在安装元数据中。
