35 added, 0 removed. Audit A to A.
# 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 问题、明显更低成本的方案或不可接受的风险时,应直接用中文指出并给出替代方案。
- 直接回答用户当前问题,同时补充确实影响决策的风险或替代方案;不要为了固定格式制造重复内容。