# VEGA Agent 协作规范

本文件适用于 `adp/vega/` 子系统。开始工作前必须先读取仓库根目录的 `AGENTS.md`、相关 `rules/`，以及目标目录下更具体的 `AGENTS.md` 或 `CLAUDE.md`。规则冲突时，以更具体目录的规则为准。

## 强制语言规范

- 与用户的沟通、计划、进度、分析、结论和交付说明必须使用中文。
- 日志文本遵循目标模块既有风格，同一调用链内不得混用语言；除非兼容性或既有约定要求，不得仅为翻译日志制造无关 diff。
- 用户明确要求其他语言，或外部制品规范强制使用其他语言时，可以例外，并在交付说明中注明原因。

## 工作方式

1. 编写代码前，先用中文说明实现方法；需要实质性判断或范围选择时，等待用户批准。
2. Plan 模式默认给出验收清单和失败条件。
3. 需求中的歧义会实质影响范围、行为或风险时，先提出澄清问题；其余情况说明合理假设后继续。
4. Bug 修复应先增加或更新能够复现问题的回归测试，再完成修复直至测试通过；确实无法先写测试时必须说明原因。
5. 修改完成后，列出相关边界场景、已覆盖测试和仍存在的测试缺口。
6. 预计修改超过 3 个文件时，先说明拆分方案和文件范围，避免把无关重构混入同一变更。
7. 用户纠正工作方式后，应反思原因并把可长期复用的约束更新到相应 `AGENTS.md`，但仍须先提供 diff 供 review。
8. 回答历史工作或决策问题前，必须先查阅仓库记录、Issue、PR 或可用的记忆文件，不得仅凭印象回答。
9. 完成修改和验证后先向用户提供 diff；未经明确批准，不得 commit、push、创建或更新 PR，也不得写回 Issue/PR。

## 工程原则

- 优先解决根因，避免叠加临时补丁。
- 遵循 VEGA 既有六边形架构：`interfaces` → `logics` → `driveradapters` / `drivenadapters`。
- 保持 diff 聚焦，不做与任务无关的格式化、重命名、文件移动或依赖升级。
- 新模式必须说明必要性；能复用既有实现、测试 helper 和错误处理模式时优先复用。
- Go 代码必须通过 `gofmt`；新增日志、错误处理和 tracing 行为应与所在包保持一致。
- 不得修改、覆盖或提交工作区中属于用户的无关改动。

## 列表接口的权限过滤

挂在目录下的列表（构建任务、探查任务、语义理解任务，以及此后新增的同类接口）**一律按这一套写**，这是统一设计，不要另起炉灶。

### 规则

**可见的目录集在 service 层解析出来，下推进查询；不要对取回的页做过滤。**

```go
visible, unrestricted, excluded, err := cs.AuthorizedCatalogsForTasks(ctx, interfaces.OPERATION_TYPE_TASK_MANAGE)
if !unrestricted && len(visible) == 0 {
    return empty, 0, nil            // 一个目录都看不见,不必查库
}
params.CatalogIDs = visible         // 通配放行时为空
params.ExcludeCatalogIDs = excluded // 通配放行够不到的内部目录
tasks, total, err := xxa.List(ctx, params)
```

判定落在**目录**上：数据表的管理权已经收敛到它所在的目录（#801），任务是目录下的产物。任务行上本来就带 `f_catalog_id`，不需要回查资源表。

动词**一律是 `task_manage`**，读和写都一样，包括列表过滤与按 id 读详情。任务属于管理面，看得到一张表不等于该看到它的构建历史——只持目录 `view_detail` 的只读用户看不到任何任务，这是预期。用两个动词还会重新制造「列表判 A、详情判 B」那类不一致。

### 为什么下推，而不是过滤取回的页

页内过滤会让分页失去意义：`total` 计入调用方看不到的行，而且会出现**中间空页、后面仍有可见行**。调用方按空页停就漏数据，按 `total` 翻又会请求大量全被滤掉的页。两种用法都错，且不报错。

下推在这里可负担，恰恰因为判的是**目录**而不是表——线上实测单账号最多被授权 12 个目录（全库 15 个），而按表算是 731 个。目录是数据源连接，几十个量级，不随建表增长。**如果以后有列表要按表的 id 过滤，这个结论不成立，要重新算。**

### 两条例外

- **调用方显式传了 `catalog_id`**：在查库**之前**用 `CheckTaskPermission` 单独判这一个 id，不再解析整个可见集。
- **判权返回错误**：只有 **403** 算「拒绝」（返回空列表），其余一律上抛。把鉴权服务不可达或数据库失败报成 200 空页，会让界面显示「这里没有数据」而监控看到一次成功请求。用 `interfaces.IsPermissionRefusal(err)` 区分。

同一条原则也适用于**读目录本身**：`CheckTaskPermission` 只在目录确实**查不到**（404）时才退到类型级授权兜底，读取失败要原样上抛。把库故障当成「目录被删了」，等于用一次不可用换一个权限决定。

## 测试要求

VEGA Backend 的标准入口是 `adp/vega/vega-backend/Makefile`。

### 测试分层

- 单元测试：不得依赖外部数据库、网络或已部署服务，使用 mock 或 sqlmock 隔离依赖。
- 集成测试：涉及真实中间件时必须与单元测试隔离，并使用专用 target 或 build tag。
- 验收测试：依赖运行中的服务和测试配置，只能通过 `test-at*` target 执行，不得混入 `make test`。
- 测试文件使用同包 `*_test.go`，优先沿用目标包现有断言、fixture 和 mock 风格。
- Bug 回归测试必须验证失败语义，而不只是覆盖代码路径；例如同时验证 error、返回值和副作用。

### 必跑命令

在 `adp/vega/vega-backend/` 下执行：

```bash
# 格式与静态检查
make lint

# 无外部依赖的全部单元测试
make test

# 单元测试与覆盖率产物
make test-cover

# 提交前完整本地 CI：lint + test-cover
make ci

# 涉及并发行为时追加
make test-race
```

开发过程中可在 `server/` 下运行目标包测试，但交付 review 前至少必须执行 `make lint` 和 `make test`。准备提交或更新 PR 前必须执行 `make ci`。

验收测试仅在服务及依赖已就绪时运行：

```bash
make test-at-setup
make test-at
```

不得为了通过检查而跳过、禁用或弱化既有测试和 linter。若检查因与本次变更无关的既有问题失败，应记录命令、失败位置和影响，不得擅自扩大修复范围。

### 单元测试编写规范

- 测试验证业务行为、边界和失败语义，不以覆盖率为唯一目标；缺陷修复应优先补充回归测试。
- 测试文件与生产文件一一对应：`foo.go` 对应 `foo_test.go`。一个非构造生产函数原则上对应一个顶层测试，成功、边界和失败场景用 `t.Run` 组织；不新增仅验证构造函数、getter/setter 或零值的测试。
- Go 命名使用 `Test<Type><Method>`（方法）或 `Test<Function>`（包级函数）。触达旧测试时，应合并同一生产函数被拆散的顶层测试，除非合并会明显降低可读性。
- `require` 用于前置条件和无法继续的错误；`assert` 用于返回值、状态、持久化内容及多个独立结果。不得只断言“无错误”。
- 覆盖正常路径、非法/边界输入、下游错误、权限或状态转换，以及关键副作用或“不应发生的副作用”；错误断言优先检查错误类型、错误码或稳定语义，避免依赖完整易变文案。
- 优先复用目标包已有的 mock、fixture 与 helper 风格。新增 helper 应具体命名并放在最贴近的业务测试文件中；不要引入隐藏业务语义的泛化 helper。
- Service 层 mock 下游 Access/Connector/Manager；数据访问层使用 sqlmock 验证查询条件、写入字段、级联与错误传播。不得依赖真实数据库、网络、文件系统、时钟或已部署服务。
- 不依赖真实 `sleep`、随机数或偶然调度顺序；固定或恢复时间、随机源、环境变量与全局状态。并发测试必须有超时，并验证取消和资源释放。
- 不得通过 skip、弱化断言、扩大超时或吞掉错误让测试通过；测试中不得出现敏感配置、密码、令牌或真实服务地址。

## CI 要求

- 修改 `adp/vega/**` 时必须确保 `.github/workflows/ci-adp-vega.yml` 对应的 build 和 lint 门禁可通过。
- 本地执行结果不能替代 GitHub CI；CI 未完成或失败时，不得宣称变更已全部验证通过。
- 新增可静态检测的缺陷修复时，应优先将对应 analyzer 接入 lint/CI，防止回归。
- 修改 CI workflow 时必须同时核对触发路径、工作目录、Go 版本来源和本地命令的一致性。
- Agent 不得跳过 CI、批准或合并 PR；CI 失败必须先定位原因，再决定修复或交还人工处理。

## 文档与配置

- API 变更必须同步更新仓库约定位置的 OpenAPI YAML，并运行相应文档 lint。
- README 的中英文版本必须保持结构和语义同步。
- 示例不得包含个人绝对路径、真实密钥、令牌或生产配置。
- 配置变更必须说明默认值、兼容性和影响范围；生产配置、权限、密钥或数据迁移仍受根目录确认门禁约束。

## Review 交付清单

- [ ] diff 仅包含当前目标相关内容，未带入用户的无关改动。
- [ ] 新增或修改的注释符合规范，命名和架构与现有代码一致。
- [ ] Bug 有聚焦的回归测试，正常路径和错误路径均得到验证。
- [ ] 已执行 `make lint`、`make test`；提交前已执行 `make ci`。
- [ ] 已说明执行命令、结果、边界场景和测试缺口。
- [ ] 尚未获得用户批准时，没有 commit、push 或更新外部协作状态。

## 思考与输出

- 运用第一性原理审视目标和路径；发现 XY 问题、明显更低成本的方案或不可接受的风险时，应直接用中文指出并给出替代方案。
- 直接回答用户当前问题，同时补充确实影响决策的风险或替代方案；不要为了固定格式制造重复内容。
