Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18ffce5d29 |
+1
-1
@@ -90,7 +90,7 @@ G0–G4 批次已完成全量迁移(14 规则、17 技能整目录、\_shared
|
||||
- **HARD**(全 core 生效,含 adapters):实例主机名、内网 IP 段、实例
|
||||
配置路径——实例机密与实例专有地址任何 core 文件不得出现。
|
||||
- **SOFT**(`core/adapters/**` 豁免):`.octopus/`、`packages/octopus`、
|
||||
MCP 工具名、工作树路径等实例绑定内容——adapter 目录是 Gitea 参考
|
||||
后端绑定内容(REST 端点、工作树路径等)——adapter 目录是 Gitea 参考
|
||||
实现,允许承载;其余 core 文件不得出现。
|
||||
|
||||
G0 三份规则是从实例规则**逐字复制**的,规则正文里出现实例路径字样属
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
| --- | --- |
|
||||
| 工单后端(ticket backend) | Gitea |
|
||||
| Tier-2 工件库 | Gitea wiki |
|
||||
| 工单评论 API(ticket backend 评论接口) | `gitea_issue_comment__*` |
|
||||
| wiki 读写 API(Tier-2 工件库读写接口) | `gitea_wiki__*` |
|
||||
| 看板移动 API(工单看板列迁移接口) | `gitea_column__move_issue` |
|
||||
| 项目看板 API(工单面板管理接口) | `gitea_project__*` |
|
||||
| 工单评论 API(ticket backend 评论接口) | Gitea REST 评论端点族:`GET/POST /repos/{owner}/{repo}/issues/{index}/comments`、`PATCH /repos/{owner}/{repo}/issues/comments/{id}` |
|
||||
| wiki 读写 API(Tier-2 工件库读写接口) | Gitea REST wiki 端点族:`wiki/pages` GET、`wiki/page/{pageName}` GET/PATCH、`wiki/new` POST(路径前缀 `/api/v1/repos/{owner}/{repo}/`) |
|
||||
| 看板移动 API(工单看板列迁移接口) | Gitea REST projects 相关端点(经 `swagger.v1.json` 查询后调用,勿臆造路径) |
|
||||
| 项目看板 API(工单面板管理接口) | Gitea REST projects/columns 端点族:`GET /repos/{owner}/{repo}/projects`、`GET /repos/{owner}/{repo}/projects/{project_id}/columns` |
|
||||
| 路由解析工具(Step 0 路由门依赖) | `route_resolver` |
|
||||
| 会话工作树路径(并发分支工作区根) | `<worktrees-root>` |
|
||||
| 测试命令·变更集(本地前置检查) | `bun run test:changed` |
|
||||
|
||||
+101
-65
@@ -2,34 +2,37 @@
|
||||
|
||||
> Gitea adapter 参考实现(Increment 3,自 dogfood 源
|
||||
> `_shared/gitea-write-patterns.md` 拆分上提)。本目录承载后端绑定的
|
||||
> API 形态(MCP 工具名、REST 端点、curl 形态);页名规范与寻址语义
|
||||
> API 形态(REST 端点 + swagger 契约,curl 形态);页名规范与寻址语义
|
||||
> 是后端中立契约,见 `core/rules/artifact-addressing.md`(本文不重复)。
|
||||
> 实例基址由实例配置提供(下文 `<gitea-base-url>`),见
|
||||
> `core/adapters/TERMINOLOGY.md`。
|
||||
> `core/adapters/TERMINOLOGY.md`。认证一律 `-H "Authorization: token <token>"`;
|
||||
> 端点契约以 `<gitea-base-url>/swagger.v1.json` 为唯一正典(按需 jq 提取,
|
||||
> 见 `core/skills/gitea-rest/`)。
|
||||
|
||||
Owner/repo 固定为 `Octopus/octopus`。所有 wiki 页名遵循 Core 契约
|
||||
`{slug}/{type}-{seq:02d}-{title}`(例外页全枚举见 artifact-addressing.md)。
|
||||
|
||||
## Wiki URL 构造 — html_url 规则
|
||||
|
||||
**黄金规则:绝不手工拼接 wiki URL。** `gitea_wiki__create_page` /
|
||||
`gitea_wiki__get_page` / `gitea_wiki__list_pages` 响应中的 `html_url`
|
||||
字段是唯一权威链接,发布时捕获并原样复用。`page_name` → `html_url`
|
||||
的变换不可推导(`/`→`%2F`、含斜杠页名带 `.-` 尾缀、CJK 百分号编码),
|
||||
必须读 API。
|
||||
**黄金规则:绝不手工拼接 wiki URL。** `POST .../wiki/new`、
|
||||
`GET .../wiki/page/{mangled-name}`、`GET .../wiki/pages` 响应中的
|
||||
`html_url` 字段是唯一权威链接,发布时捕获并原样复用。页名 →
|
||||
`html_url` 的变换不可推导(`/`→`%2F`、含斜杠页名带 `.-` 尾缀、CJK
|
||||
百分号编码),必须读 API。
|
||||
|
||||
**两种标识符勿混淆**:
|
||||
|
||||
| 标识符 | 是什么 | 用途 |
|
||||
| ----------- | ------------------------------------ | ---------------------------------------- |
|
||||
| `page_name` | 原始页标识;字面 `/`、无主机、无编码 | wiki MCP 工具的 `page_name`/`title` 参数 |
|
||||
| `html_url` | 后端生成的完整可点击 URL | markdown 链接、`target_url`、PR 正文 |
|
||||
| 标识符 | 是什么 | 用途 |
|
||||
| ------ | ------ | ---- |
|
||||
| 逻辑页名(`title`) | 原始页标识;字面 `/`、无主机、无编码 | 写侧:`POST .../wiki/new` 的 `title`;`PATCH` 省略 `title` 保名 |
|
||||
| mangled `pageName`(`sub_url`) | 后端改写的存储名(含 `%2F` 编码与 `.-` 尾缀) | 读侧/改侧路径参数:先 `GET .../wiki/pages` 拿 `sub_url`,**原样**用于 `wiki/page/{pageName}`,绝不手工拼 |
|
||||
| `html_url` | 后端生成的完整可点击 URL | markdown 链接、`target_url`、PR 正文 |
|
||||
|
||||
**去向**:
|
||||
|
||||
- **工件索引位置列** — 一个单元格同时存两者:
|
||||
``[`{page_name}`]({html_url})``。链接文本供读侧调
|
||||
`gitea_wiki__get_page`,href 供人点击(见 Pattern 10)。
|
||||
``[`{page_name}`]({html_url})``。链接文本供读侧回读该页,href 供人
|
||||
点击(见 Pattern 10)。
|
||||
- **commit-status `target_url`** — 终报页的 `html_url`(见 Pattern 8)。
|
||||
- **页内交叉链接** — 用 `html_url`。
|
||||
|
||||
@@ -37,38 +40,56 @@ Owner/repo 固定为 `Octopus/octopus`。所有 wiki 页名遵循 Core 契约
|
||||
|
||||
## Pattern 1: create-wiki-page
|
||||
|
||||
```bash
|
||||
curl -fsS -X POST "<gitea-base-url>/api/v1/repos/Octopus/octopus/wiki/new" \
|
||||
-H "Authorization: token <token>" -H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"title": "{slug}/{type}-{seq:02d}-{title}",
|
||||
"content_base64": "<base64(内容)>",
|
||||
"message": "{可选 commit message}"
|
||||
}'
|
||||
```
|
||||
gitea_wiki__create_page(owner="Octopus", repo="octopus",
|
||||
title="{slug}/{type}-{seq:02d}-{title}",
|
||||
content="{内容}",
|
||||
message="{可选 commit message}")
|
||||
```
|
||||
|
||||
**base64 陷阱(强制注明)**:wiki 写接口只认 `content_base64`;传
|
||||
`content` 会被静默忽略(无报错、返回 2xx,页面存成 0 字节)。正文必须
|
||||
先 base64 编码,且发布后回读确认非空。
|
||||
|
||||
**发布→验证(强制)**:发布后立刻回读确认存在且内容一致:
|
||||
|
||||
```
|
||||
gitea_wiki__get_page(owner="Octopus", repo="octopus", page_name="{同 title}")
|
||||
```bash
|
||||
# 1. 列页拿 mangled sub_url(绝不手工拼 mangled name)
|
||||
curl -fsS -H "Authorization: token <token>" \
|
||||
"<gitea-base-url>/api/v1/repos/Octopus/octopus/wiki/pages"
|
||||
# 2. 用返回的 sub_url 原样读页
|
||||
curl -fsS -H "Authorization: token <token>" \
|
||||
"<gitea-base-url>/api/v1/repos/Octopus/octopus/wiki/page/{sub_url}"
|
||||
```
|
||||
|
||||
404 / 内容不一致 → 修复后重发。页名冲突(409)→ 该页已存在,改用
|
||||
Pattern 2 update,绝不另发新页。响应的 `html_url` 立即捕获复用。
|
||||
404 / 内容为空或不一致 → 修复后重发。页名冲突(409)→ 该页已存在,
|
||||
改用 Pattern 2 update,绝不另发新页。响应的 `html_url` 立即捕获复用。
|
||||
|
||||
## Pattern 2: update-wiki-page
|
||||
|
||||
```
|
||||
gitea_wiki__update_page(owner="Octopus", repo="octopus",
|
||||
page_name="{页名}",
|
||||
content="{新内容}",
|
||||
message="{commit message}")
|
||||
```bash
|
||||
curl -fsS -X PATCH "<gitea-base-url>/api/v1/repos/Octopus/octopus/wiki/page/{sub_url}" \
|
||||
-H "Authorization: token <token>" -H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"content_base64": "<base64(新内容)>",
|
||||
"message": "{commit message}"
|
||||
}'
|
||||
```
|
||||
|
||||
更新后再回读验证;409 冲突 → 拉最新内容手工合并后重试。
|
||||
路径参数用 mangled `sub_url`(先 `GET .../wiki/pages` 获取,原样使用)。
|
||||
**省略 `title` 保持页名不变**——只发 `content_base64`+`message`。
|
||||
同样只认 `content_base64`(`content` 会静默存 0 字节页)。更新后再回读
|
||||
验证;409 冲突 → 拉最新内容手工合并后重试。
|
||||
|
||||
## Pattern 3: create-issue
|
||||
|
||||
```
|
||||
gitea_issue__create(owner="Octopus", repo="octopus",
|
||||
title="{标题}", body="{正文}", labels=["{label}"])
|
||||
```bash
|
||||
curl -fsS -X POST "<gitea-base-url>/api/v1/repos/Octopus/octopus/issues" \
|
||||
-H "Authorization: token <token>" -H "Content-Type: application/json" \
|
||||
-d '{"title":"{标题}","body":"{正文}","labels":[{label_id}]}'
|
||||
```
|
||||
|
||||
### 工单交叉链接(强制)
|
||||
@@ -86,9 +107,10 @@ gitea_issue__create(owner="Octopus", repo="octopus",
|
||||
|
||||
## Pattern 4: update-issue
|
||||
|
||||
```
|
||||
gitea_issue__update(owner="Octopus", repo="octopus",
|
||||
index={issue_number}, body="{正文}", state="{open|closed}", ...)
|
||||
```bash
|
||||
curl -fsS -X PATCH "<gitea-base-url>/api/v1/repos/Octopus/octopus/issues/{index}" \
|
||||
-H "Authorization: token <token>" -H "Content-Type: application/json" \
|
||||
-d '{"body":"{正文}","state":"{open|closed}"}'
|
||||
```
|
||||
|
||||
原位更新正文(checklist 勾选、live 状态表维护);关闭工单即触发
|
||||
@@ -96,9 +118,10 @@ gitea_issue__update(owner="Octopus", repo="octopus",
|
||||
|
||||
## Pattern 5: add-issue-comment
|
||||
|
||||
```
|
||||
gitea_issue_comment__create(owner="Octopus", repo="octopus",
|
||||
index={issue_number}, body="{评论正文}")
|
||||
```bash
|
||||
curl -fsS -X POST "<gitea-base-url>/api/v1/repos/Octopus/octopus/issues/{index}/comments" \
|
||||
-H "Authorization: token <token>" -H "Content-Type: application/json" \
|
||||
-d '{"body":"{评论正文}"}'
|
||||
```
|
||||
|
||||
首次评论后捕获返回的 `comment_id`——后续对同一逻辑评论的更新必须走
|
||||
@@ -107,33 +130,42 @@ Pattern 6 原位 edit,绝不再 create。用于:评审综合(Synthesis)
|
||||
|
||||
## Pattern 6: edit-issue-comment
|
||||
|
||||
```
|
||||
gitea_issue_comment__edit(owner="Octopus", repo="octopus",
|
||||
comment_id={comment_id}, body="{新正文}")
|
||||
```bash
|
||||
curl -fsS -X PATCH "<gitea-base-url>/api/v1/repos/Octopus/octopus/issues/comments/{comment_id}" \
|
||||
-H "Authorization: token <token>" -H "Content-Type: application/json" \
|
||||
-d '{"body":"{新正文}"}'
|
||||
```
|
||||
|
||||
单评论聚合不变量(工件索引、当前状态表等)的执行手段。
|
||||
|
||||
## Pattern 7: move-issue-to-column
|
||||
|
||||
```
|
||||
gitea_column__move_issue(owner="Octopus", repo="octopus",
|
||||
project_id={project_id}, column_id={column_id}, index={issue_number})
|
||||
```
|
||||
看板列迁移(Todo → In Progress → Review → Done)。projects/columns
|
||||
发现用 REST;「把工单移到列」的操作端点语义复杂,经 swagger 查询后
|
||||
调用,不臆造路径:
|
||||
|
||||
看板列迁移(Todo → In Progress → Review → Done)。
|
||||
```bash
|
||||
# 列出 repo 级 projects(projects 仅 repo 级,无 org/user 级端点)
|
||||
curl -fsS -H "Authorization: token <token>" \
|
||||
"<gitea-base-url>/api/v1/repos/Octopus/octopus/projects"
|
||||
# 列某 project 的 columns
|
||||
curl -fsS -H "Authorization: token <token>" \
|
||||
"<gitea-base-url>/api/v1/repos/Octopus/octopus/projects/{project_id}/columns"
|
||||
# 移动工单到列:先经 swagger.v1.json 查询 projects 相关端点后调用
|
||||
curl -s <gitea-base-url>/swagger.v1.json -o /tmp/gitea-sw.json
|
||||
jq -r '.paths | keys[]' /tmp/gitea-sw.json | grep projects
|
||||
```
|
||||
|
||||
## Pattern 7.5: move-issue-to-pipeline-stage
|
||||
|
||||
管线阶段板列(Pipeline Stages board column)承载阶段迁移——阶段转移
|
||||
落到板列,**不落** `## 当前状态` 行(该表只承载 PR / 评审 / CI 行与
|
||||
非阶段阻塞项)。列序列按管线阶段定义;移动用 Pattern 7 同款
|
||||
`gitea_column__move_issue`,column 由 `gitea_project__list` /
|
||||
`gitea_column__list` 发现。
|
||||
非阶段阻塞项)。列序列按管线阶段定义;移动与 Pattern 7 同款
|
||||
(projects/columns 经 REST + swagger 发现,同上)。
|
||||
|
||||
## Pattern 8: post-commit-status(REST 回退)
|
||||
## Pattern 8: post-commit-status
|
||||
|
||||
MCP 工具缺席时用 REST 直发 commit status(评审综合的 Tier-2 落点):
|
||||
commit status 直发 REST(评审综合的 Tier-2 落点):
|
||||
|
||||
```bash
|
||||
curl -X POST "<gitea-base-url>/api/v1/repos/Octopus/octopus/statuses/{sha}" \
|
||||
@@ -153,16 +185,19 @@ merge 前读回验证:`GET /commits/{PR_SHA}/status`。
|
||||
|
||||
## Pattern 9: create-iteration-board
|
||||
|
||||
```
|
||||
gitea_project__create(owner="Octopus", repo="octopus",
|
||||
title="{slug} — Iteration {N}", description="…")
|
||||
gitea_column__create(owner="Octopus", repo="octopus",
|
||||
project_id={project_id}, title="Todo")
|
||||
# … In Progress / Review / Done 同款
|
||||
```bash
|
||||
# 建 project(board):先经 swagger 查询 create 端点契约
|
||||
curl -s <gitea-base-url>/swagger.v1.json -o /tmp/gitea-sw.json
|
||||
jq '.paths["/repos/{owner}/{repo}/projects"].post' /tmp/gitea-sw.json
|
||||
# 随后 POST 建板(title="{slug} — Iteration {N}", description="…")
|
||||
# 再对每列(Todo / In Progress / Review / Done):
|
||||
jq '.paths["/repos/{owner}/{repo}/projects/{project_id}/columns"].post' /tmp/gitea-sw.json
|
||||
# 随后 POST 建列
|
||||
```
|
||||
|
||||
DAG 聚合 agent 在单门 PASS 后建板;工单正文模板带 `## Node Reference`
|
||||
(指向 `{epic-slug}/dag`)、`## Acceptance Criteria`、`## Parent`。
|
||||
projects 仅 repo 级。DAG 聚合 agent 在单门 PASS 后建板;工单正文模板带
|
||||
`## Node Reference`(指向 `{epic-slug}/dag`)、`## Acceptance Criteria`、
|
||||
`## Parent`。
|
||||
|
||||
## Pattern 10: artifact-index(工单 ↔ 工件索引)
|
||||
|
||||
@@ -170,14 +205,15 @@ DAG 聚合 agent 在单门 PASS 后建板;工单正文模板带 `## Node Refer
|
||||
索引(反向链接 + compaction 恢复主路径;语义不变量见
|
||||
`core/rules/artifact-addressing.md` §4):
|
||||
|
||||
```
|
||||
```bash
|
||||
# 1. 找源工单(PR body / commit 的 Closes #N,或 DAG 父映射);无则跳过
|
||||
# 2. 评论已存在?
|
||||
gitea_issue_comment__list(owner="Octopus", repo="octopus", index={issue_number})
|
||||
curl -fsS -H "Authorization: token <token>" \
|
||||
"<gitea-base-url>/api/v1/repos/Octopus/octopus/issues/{index}/comments"
|
||||
# → 扫 body 以 "## 工件索引" 开头的评论(遗留前缀 "## Pipeline 工件追踪表"
|
||||
# 原位升级,不重复发)
|
||||
# 3a. 不存在 → gitea_issue_comment__create 初始化
|
||||
# 3b. 存在 → gitea_issue_comment__edit 原位编辑(复用 comment_id)
|
||||
# 3a. 不存在 → POST .../issues/{index}/comments 初始化
|
||||
# 3b. 存在 → PATCH .../issues/comments/{comment_id} 原位编辑(复用 comment_id)
|
||||
```
|
||||
|
||||
**索引表模板**(每工件一行;技能只增改自己的行,绝不删他技的行):
|
||||
@@ -191,11 +227,11 @@ gitea_issue_comment__list(owner="Octopus", repo="octopus", index={issue_number})
|
||||
| DAG | 任务图 | v1 (frozen) | [`{epic-slug}/dag`]({html_url}) | CORE |
|
||||
|
||||
**位置列填充规则**:单元格 = markdown 链接 ``[`{page_name}`]({html_url})``;
|
||||
链接文本(page_name,字面 `/`)供读侧 `gitea_wiki__get_page`;href
|
||||
(html_url)供人点击,必须取自 API 响应,严禁拼接。
|
||||
链接文本(逻辑页名,字面 `/`)供读侧先 `GET .../wiki/pages` 拿 `sub_url`
|
||||
后回读该页;href(html_url)供人点击,必须取自 API 响应,严禁拼接。
|
||||
|
||||
**重读优先级**:`CORE` = compaction 后必读(重读集 = 全部 CORE 行);
|
||||
`ON-Demand` → `ON-DEMAND` = 按需;`ARCHIVE` = 已归档不读。
|
||||
`ON-DEMAND` = 按需;`ARCHIVE` = 已归档不读。
|
||||
|
||||
**归档动作(archive-at-close)**:工单关闭时由关闭方 agent 原位 edit
|
||||
本评论——表格上方加归档横幅(`> **状态**: ✅ 已归档 — issue #{N} 关闭于
|
||||
|
||||
@@ -12,7 +12,12 @@ Owner/repo 固定 `Octopus/octopus`。compaction 恢复从 Pattern 6
|
||||
## Pattern 1: read-wiki-page
|
||||
|
||||
```
|
||||
gitea_wiki__get_page(owner="Octopus", repo="octopus", page_name="{slug}/{page_title}")
|
||||
# 1. 列 wiki 页拿 mangled sub_url(绝不手工拼 mangled name)
|
||||
curl -fsS -H "Authorization: token <token>" \
|
||||
"<gitea-base-url>/api/v1/repos/Octopus/octopus/wiki/pages"
|
||||
# 2. 用返回的 sub_url 原样读页(含 %2F 编码与 .- 尾缀)
|
||||
curl -fsS -H "Authorization: token <token>" \
|
||||
"<gitea-base-url>/api/v1/repos/Octopus/octopus/wiki/page/{mangled-name}"
|
||||
```
|
||||
|
||||
常用页名(全量文法 + 例外枚举见 `core/rules/artifact-addressing.md` §2):
|
||||
@@ -45,7 +50,7 @@ gitea_wiki__get_page(owner="Octopus", repo="octopus", page_name="{slug}/{page_ti
|
||||
`{slug}/roadmap/{page}`、`{slug}/shared/{file}`、
|
||||
`{slug}/reviews/{roadmap|design-space|plan}/final/report`。
|
||||
|
||||
**本地回退(wiki MCP 工具不可用)**:读本地 wiki 克隆(实例路径见
|
||||
**本地回退(REST 不可达时)**:读本地 wiki 克隆(实例路径见
|
||||
TERMINOLOGY.md)。wiki 文件名 URL 编码(`/`→`%2F`,`.md` 前可能带
|
||||
`.-`),用 glob 而非固定路径解析:
|
||||
|
||||
@@ -56,7 +61,8 @@ glob(pattern="*{slug}*{page-title}*.md", path="<local-wiki-clone>/{repo}-wiki/")
|
||||
## Pattern 2: read-issue
|
||||
|
||||
```
|
||||
gitea_issue__get(owner="Octopus", repo="octopus", index={issue_number})
|
||||
curl -fsS -H "Authorization: token <token>" \
|
||||
"<gitea-base-url>/api/v1/repos/Octopus/octopus/issues/{issue_number}"
|
||||
```
|
||||
|
||||
读工单详情、正文、元数据(label、assignee、milestone、state)。
|
||||
@@ -64,20 +70,28 @@ gitea_issue__get(owner="Octopus", repo="octopus", index={issue_number})
|
||||
## Pattern 3: read-issue-comments
|
||||
|
||||
```
|
||||
gitea_issue_comment__list(owner="Octopus", repo="octopus", index={issue_number})
|
||||
curl -fsS -H "Authorization: token <token>" \
|
||||
"<gitea-base-url>/api/v1/repos/Octopus/octopus/issues/{issue_number}/comments?page=N&limit=50"
|
||||
```
|
||||
|
||||
分页用 `page`/`limit`(上限 50),响应头 `x-total-count` 给总数。
|
||||
|
||||
读工单全部评论(评审结果、状态备注、讨论线程)。
|
||||
|
||||
## Pattern 4: read-project-column-issues
|
||||
|
||||
看板列工单队列。project/column 发现:
|
||||
|
||||
```
|
||||
gitea_column__list_issues(owner="Octopus", repo="octopus",
|
||||
project_id={project_id}, column_id={column_id})
|
||||
curl -fsS -H "Authorization: token <token>" \
|
||||
"<gitea-base-url>/api/v1/repos/Octopus/octopus/projects"
|
||||
curl -fsS -H "Authorization: token <token>" \
|
||||
"<gitea-base-url>/api/v1/repos/Octopus/octopus/projects/{project_id}/columns"
|
||||
```
|
||||
|
||||
看板列工单队列。project/column 发现:`gitea_project__list` +
|
||||
`gitea_column__list`。
|
||||
「把工单移到列」等复杂操作:经 `swagger.v1.json`
|
||||
(`jq '.paths | keys[]' | grep projects`)查询 projects 相关端点后调用,
|
||||
不要臆造具体端点路径。projects 仅 repo 级(无 org/user 级端点)。
|
||||
|
||||
## Pattern 5: read-review-status(CLI)
|
||||
|
||||
@@ -103,17 +117,24 @@ success,1 = 有 failure/error。
|
||||
而非猜测页名路径:
|
||||
|
||||
```
|
||||
gitea_issue__get(owner="Octopus", repo="octopus", index={issue_number})
|
||||
gitea_issue_comment__list(owner="Octopus", repo="octopus", index={issue_number})
|
||||
# 找 body 以 "## 工件索引"(遗留 "## Pipeline 工件追踪表")开头的评论
|
||||
gitea_wiki__get_page(owner="Octopus", repo="octopus", page_name=page_name)
|
||||
# 1. 读源工单
|
||||
curl -fsS -H "Authorization: token <token>" \
|
||||
"<gitea-base-url>/api/v1/repos/Octopus/octopus/issues/{issue_number}"
|
||||
# 2. 拉评论列表,找 body 以 "## 工件索引"(遗留 "## Pipeline 工件追踪表")开头的评论
|
||||
curl -fsS -H "Authorization: token <token>" \
|
||||
"<gitea-base-url>/api/v1/repos/Octopus/octopus/issues/{issue_number}/comments?page=N&limit=50"
|
||||
# 3. 按 CORE 行位置列逐个读工件页:先 GET .../wiki/pages 拿 sub_url(mangled
|
||||
# name),再原样请求
|
||||
curl -fsS -H "Authorization: token <token>" \
|
||||
"<gitea-base-url>/api/v1/repos/Octopus/octopus/wiki/page/{mangled-name}"
|
||||
```
|
||||
|
||||
**位置列提取规则**:单元格形如 ``[`{page_name}`]({html_url})`` ——
|
||||
取**链接文本**(首个 `[` 与 `]` 之间、剥反引号)作为 page_name,不是
|
||||
href(含 `%2F`/`.-`,API 不认)。裸 page_name 单元格(无链接包裹)也
|
||||
接受:整格即 page_name。形如 `#comment-{id}` 的值改用
|
||||
`gitea_issue_comment__list` 读,不得喂给 `gitea_wiki__get_page`。
|
||||
`GET .../issues/{index}/comments` 拉工单评论列表后按 id 取,不得当作
|
||||
wiki 页名去读 wiki 端点。
|
||||
|
||||
**重读规则**:重读集 = 全部 `CORE` 行;`ON-DEMAND` 行仅当前任务需要
|
||||
时读;绝不读 `ARCHIVE` 行。索引缺失(历史工单)→ 回退 issue body +
|
||||
|
||||
@@ -40,7 +40,8 @@ error, returns empty, or you cannot otherwise access a required resource, you
|
||||
MUST report the failure honestly. NEVER fabricate, invent, or hallucinate a
|
||||
plausible-looking result to fill the gap.
|
||||
|
||||
- An honest "I could not call `gitea_wiki__get_page`, so I cannot review
|
||||
- An honest "I could not reach the wiki read API (`GET
|
||||
<gitea-base-url>/api/v1/repos/{owner}/{repo}/wiki/pages`), so I cannot review
|
||||
dimension Y" is always correct. An honest failure beats a confident fiction.
|
||||
- Producing a complete, specific-looking structured result — review JSON with
|
||||
findings, severity levels, and file references, all invented — without a
|
||||
@@ -52,5 +53,6 @@ plausible-looking result to fill the gap.
|
||||
it, you do not know it — say so.
|
||||
|
||||
Origin: [org-internal #2115] root cause 5 / [org-internal #2118] — deepseek-v4-flash reviewers fabricated
|
||||
full review JSON when the `gitea_wiki__*` tools were unavailable to subagents.
|
||||
full review JSON when the wiki tool surface (MCP tooling at the time, now
|
||||
retired) was unavailable to subagents.
|
||||
|
||||
|
||||
@@ -68,12 +68,13 @@ in `_shared/gitea-write-patterns.md`.
|
||||
in the Orchestrator instead of letting {DIMENSION_COUNT} parallel subagents
|
||||
each rediscover the gap:
|
||||
|
||||
- **Primary path**: confirm `gitea_wiki__*` tools are registered (the
|
||||
Orchestrator checks its own tool catalog; these tools are forwarded to
|
||||
reviewer subagents when registered — [org-internal #2116] raised the tool cap 50→100 so
|
||||
they are present in normal runs). If available → continue to step 2.
|
||||
- **Fallback path** (when `gitea_wiki__*` is NOT registered, e.g. a
|
||||
cross-repo scenario [org-internal #2115]): verify the **local wiki clone** at
|
||||
- **Primary path**: confirm the Gitea REST API is reachable — probe
|
||||
`GET <gitea-base-url>/api/v1/repos/{owner}/{repo}/wiki/pages` with
|
||||
`-H "Authorization: token <token>"` (a 200 or 403 response means
|
||||
reachable; anything else — timeout, connection refused, 5xx — is
|
||||
unreachable). If reachable → continue to step 2.
|
||||
- **Fallback path** (when REST is unreachable, e.g. a
|
||||
cross-repo scenario [org-internal #2115]): verify the **local wiki clone** at
|
||||
`<wiki-clone-root>/{repo}-wiki/` is readable —
|
||||
`glob(pattern="*.md", path="<wiki-clone-root>/{repo}-wiki/")`. If the clone
|
||||
is readable → continue to step 2; reviewers use the local clone (see
|
||||
@@ -82,13 +83,14 @@ in `_shared/gitea-write-patterns.md`.
|
||||
- **Both unavailable → FAIL FAST**: post a `failure` commit status (state
|
||||
`"failure"`, context `pipeline/{REVIEW_TYPE}`, description naming the
|
||||
missing capability) and abort — do NOT enter parallel dispatch. Report the
|
||||
gap so the environment can be fixed (register the wiki MCP server, or
|
||||
populate `<wiki-clone-root>/{repo}-wiki/`).
|
||||
gap so the environment can be fixed (restore Gitea REST reachability —
|
||||
token validity, network route — or
|
||||
populate `<wiki-clone-root>/{repo}-wiki/`).
|
||||
|
||||
This probe is belt-and-suspenders: RC1 (tool cap, [org-internal #2116]) already fixed the
|
||||
primary cause of missing `gitea_wiki__*` in subagents. It exists so a future
|
||||
environment regression fails gracefully with one clear message instead of N
|
||||
silent subagent aborts.
|
||||
This probe is belt-and-suspenders: it exists so a future
|
||||
environment regression (REST unreachable, stale token) fails gracefully
|
||||
with one clear message instead of N
|
||||
silent subagent aborts.
|
||||
|
||||
2. Post an initial pending commit status via REST:
|
||||
|
||||
@@ -471,8 +473,10 @@ not the round-1 full set.
|
||||
|
||||
3.5. **Gitea approval timing (mandatory when the PR needs a human approval
|
||||
gate)**: if the flow requests approval from a human reviewer on Gitea,
|
||||
register the reviewer FIRST via `gitea_pull__add_reviewer`, wait for the
|
||||
`REQUEST_REVIEW` registration to be recorded, and only THEN ask the human
|
||||
register the reviewer FIRST via
|
||||
`POST <gitea-base-url>/api/v1/repos/{owner}/{repo}/pulls/{index}/requested_reviewers`,
|
||||
wait for the
|
||||
`REQUEST_REVIEW` registration to be recorded, and only THEN ask the human
|
||||
to approve. Approving before the reviewer is registered produces
|
||||
`official: false` on the approval — the gate treats the PR as unapproved
|
||||
and the approval must be re-done. ([org-internal #1931]: audit R2→R3 re-loop + re-approve,
|
||||
|
||||
@@ -65,7 +65,8 @@ Label: {DIMENSION_NAME}
|
||||
|
||||
## What You Must NOT Do
|
||||
|
||||
- Do NOT fabricate results. If a tool you need (e.g. `gitea_wiki__get_page`,
|
||||
- Do NOT fabricate results. If a tool you need (e.g. the Gitea REST call
|
||||
`GET <gitea-base-url>/api/v1/repos/{owner}/{repo}/wiki/pages`,
|
||||
`read`, `codegraph_*`) is unavailable, errors, or returns empty, report the
|
||||
failure honestly — emit a finding stating the dimension could not be
|
||||
reviewed due to the missing tool. NEVER invent findings, severities, or
|
||||
|
||||
@@ -65,8 +65,8 @@ model**.
|
||||
and coordinate on the issue before proceeding.
|
||||
|
||||
**c. Open-PR check.** List open PRs referencing `#N` —
|
||||
`工单 API(见 TERMINOLOGY)search(q: "#N", type: "pulls", state: "open")` (API source)
|
||||
or `gitea_pull__list` — and **ABORT** if an open PR already covers the ticket.
|
||||
`GET <gitea-base-url>/api/v1/repos/issues/search?q="#N"&type=pulls&state=open`
|
||||
(API source) — and **ABORT** if an open PR already covers the ticket.
|
||||
|
||||
**d. Remote branch check ([org-internal #2297]).** A local branch is invisible to other
|
||||
sessions — check the remote too:
|
||||
|
||||
@@ -104,15 +104,15 @@ Phase 2 and Phase 4, not after the fix:
|
||||
[Worker: developer] Phase 1 reproduce + Phase 2 root cause
|
||||
→ write repro-notes (reproduction steps, root cause, bug path,
|
||||
expected behavior)
|
||||
↓ persist: wiki page `{slug}/repro-notes` (gitea_wiki__create_page)
|
||||
↓ persist: wiki page `{slug}/repro-notes` (`POST .../wiki/new`, body `content_base64`)
|
||||
[Worker: tester] read repro-notes → Phase 3 write failing regression test
|
||||
(confirms FAIL before fix)
|
||||
↓ persist: wiki page `{slug}/test-report` (gitea_wiki__create_page, failing test confirmed)
|
||||
↓ persist: wiki page `{slug}/test-report` (`POST .../wiki/new`, body `content_base64`, failing test confirmed)
|
||||
[Worker: developer] Phase 4 fix → run test:changed to green
|
||||
→ write impl-notes (post-fix behavior contract)
|
||||
↓ persist: wiki page `{slug}/impl-notes` (gitea_wiki__create_page, post-fix behavior contract)
|
||||
↓ persist: wiki page `{slug}/impl-notes` (`POST .../wiki/new`, body `content_base64`, post-fix behavior contract)
|
||||
[Worker: tester] supplement boundary regression tests → run test:changed
|
||||
↓ persist: update wiki page `{slug}/test-report` (gitea_wiki__update_page, final)
|
||||
↓ persist: update wiki page `{slug}/test-report` (`PATCH .../wiki/page/{mangled-name}`, omit `title`, body `content_base64` — final)
|
||||
— consumed by the human stakeholder / next iteration planning for DoD regression-test evidence
|
||||
```
|
||||
|
||||
|
||||
@@ -499,8 +499,8 @@ issue exists.
|
||||
retired — each one re-triggered the full CI surface for near-zero re-tested
|
||||
risk.
|
||||
|
||||
> **Kanban column lifecycle**: automated (`工单 API(见 TERMINOLOGY)create` → Backlog,
|
||||
> `gitea_pull__create` → Review; no manual moves). Single shared reference:
|
||||
> **Kanban column lifecycle**: automated (`POST <gitea-base-url>/api/v1/repos/{owner}/{repo}/issues` → Backlog,
|
||||
> `POST .../pulls` → Review; no manual moves). Single shared reference:
|
||||
> `_shared/gitea-write-patterns.md` Pattern 7.5; column semantics: wiki
|
||||
> `kanban-lifecycle`.
|
||||
|
||||
|
||||
@@ -234,7 +234,7 @@ After all steps are complete:
|
||||
{If the refactoring changes the internal architecture in a way that merits an
|
||||
ADR, reference the ADR. **Deprecated:** `.artifacts/{slug}/design/adr/{NNNN}-*.md`
|
||||
→ ADRs now live on the Gitea wiki at page `{slug}/03-adr-{NNNN}-{title}`,
|
||||
readable via `gitea_wiki__get_page`. Or "None".}
|
||||
readable via `GET <gitea-base-url>/api/v1/repos/{owner}/{repo}/wiki/page/{mangled-name}`. Or "None".}
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -25,19 +25,22 @@ role: Reviewer
|
||||
## Tool Availability & Path Resolution
|
||||
|
||||
This skill's reviewers (parallel Explorer subagents) read two kinds of files.
|
||||
Some runs lack the `gitea_wiki__*` MCP tools (cross-repo scenario, [org-internal #2115]); the
|
||||
fallbacks below keep reviews working without them.
|
||||
Some runs cannot reach the Gitea REST API (cross-repo scenario, [org-internal #2115]); the
|
||||
fallbacks below keep reviews working without it.
|
||||
|
||||
The Orchestrator probes availability **before dispatching reviewers** (Phase A
|
||||
The Orchestrator probes REST reachability **before dispatching reviewers** (Phase A
|
||||
step 1, `_shared/review-pipeline-phases.md`) and fails fast if neither path is
|
||||
usable, so every reviewer has a working read path by the time it runs.
|
||||
|
||||
### Wiki artifacts (DAG artifact / review reports)
|
||||
|
||||
- **Primary**: `wiki 读写 API(见 TERMINOLOGY)(owner, repo, page_name)` — use when the
|
||||
tool is available. `page_name` construction is in
|
||||
- **Primary**: `GET <gitea-base-url>/api/v1/repos/{owner}/{repo}/wiki/page/{mangled-name}`
|
||||
— use when REST is reachable. Resolve `{mangled-name}` from
|
||||
`GET .../wiki/pages` (`sub_url` — mangled name with `%2F` encoding and
|
||||
possible `.-` suffix); never construct it by hand. Page-name resolution
|
||||
context is in
|
||||
`_shared/gitea-read-patterns.md` Pattern 1.
|
||||
- **Fallback** (when `gitea_wiki__*` is unavailable): read the **local wiki
|
||||
- **Fallback** (when REST is unreachable): read the **local wiki
|
||||
clone** at `<wiki-clone-root>/{repo}-wiki/` — a git checkout of the wiki repo,
|
||||
kept current. Wiki filenames are URL-encoded (`/` → `%2F`, with a possible
|
||||
`.-` before `.md`), so resolve the file with `glob` rather than constructing
|
||||
@@ -393,7 +396,7 @@ file (concurrent write race):
|
||||
- `{BASELINE_SECTION}`:
|
||||
```
|
||||
## Baseline
|
||||
The artifact under review is the DAG at wiki page `{epic-slug}/dag` (read via `gitea_wiki__get_page`). Read it first for orientation. Its `dag_metrics.review_depth` (D1–D4) sets this review's depth and round cap.
|
||||
The artifact under review is the DAG at wiki page `{epic-slug}/dag` (read via `GET <gitea-base-url>/api/v1/repos/{owner}/{repo}/wiki/page/{mangled-name}`, `sub_url` resolved from `GET .../wiki/pages` first). Read it first for orientation. Its `dag_metrics.review_depth` (D1–D4) sets this review's depth and round cap.
|
||||
```
|
||||
- `{READ_FIRST_STEPS}`:
|
||||
1. Read the DAG artifact at `{epic-slug}/dag` first for orientation.
|
||||
|
||||
@@ -974,7 +974,8 @@ After the Developer completes revision:
|
||||
`question` tool, passing `stage: "review-code"`:
|
||||
|
||||
> **Gitea approval timing (mandatory when the PR needs a human approval
|
||||
> gate)**: register the reviewer FIRST via `gitea_pull__add_reviewer`,
|
||||
> gate)**: register the reviewer FIRST via
|
||||
> `POST <gitea-base-url>/api/v1/repos/{owner}/{repo}/pulls/{index}/requested_reviewers`,
|
||||
> wait for the `REQUEST_REVIEW` registration to be recorded, and only
|
||||
> THEN ask the human to approve. Approving before the reviewer is
|
||||
> registered produces `official: false` on the approval — the gate
|
||||
@@ -987,7 +988,7 @@ After the Developer completes revision:
|
||||
Final verdict: {PASS | WARN | FAIL}
|
||||
Converged: {true | false}
|
||||
|
||||
See full report: wiki page `{slug}/reviews/code/final/report` (DAG task mode: `{epic-slug}/reviews/code/final/report-task-{node-id}`)(via `gitea_wiki__get_page`,`_shared/gitea-read-patterns.md` Pattern 1)
|
||||
See full report: wiki page `{slug}/reviews/code/final/report` (DAG task mode: `{epic-slug}/reviews/code/final/report-task-{node-id}`)(via `GET <gitea-base-url>/api/v1/repos/{owner}/{repo}/wiki/page/{mangled-name}` — `sub_url` resolved from `GET .../wiki/pages` first, `_shared/gitea-read-patterns.md` Pattern 1)
|
||||
All review artifacts: ticket #{issue_number} comments + wiki pages under `{slug}/reviews/code/`(DAG task mode: under `{epic-slug}/reviews/code/`, Tier 1 round artifacts under `<runs-root>/{epic-slug}-task-{node-id}/reviews/code/`)
|
||||
Inline comments(only when step 2.56 ran;omit for no-PR flows): `inline: X posted / Y file-level / Z fallback / W failed`
|
||||
|
||||
|
||||
+14
-16
@@ -732,10 +732,10 @@ originating slug in each row so the trail survives.
|
||||
independent ticket THEN, carrying the reserved `TD-NNN`:
|
||||
|
||||
```
|
||||
gitea_issue__create(owner="Octopus", repo="octopus",
|
||||
title="[{origin}] Tech debt: {short description} (TD-{NNN})",
|
||||
body=<promotion template below>,
|
||||
labels=[tech_debt_label_id, severity_label_id])
|
||||
POST <gitea-base-url>/api/v1/repos/Octopus/octopus/issues
|
||||
body: {"title":"[{origin}] Tech debt: {short description} (TD-{NNN})",
|
||||
"body":<promotion template below>,
|
||||
"labels":[tech_debt_label_id, severity_label_id]}
|
||||
```
|
||||
|
||||
- **Severity → label** (reuse the existing exclusive Priority set):
|
||||
@@ -820,8 +820,7 @@ AND closed), per `core/rules/testing.md`** (de-duplicate BEFORE filing,
|
||||
retro [org-internal #2696]). Query `baseline-failure` issues in ALL states:
|
||||
|
||||
```
|
||||
gitea_issue__list(owner="Octopus", repo="octopus",
|
||||
labels="baseline-failure", state="all")
|
||||
GET <gitea-base-url>/api/v1/repos/Octopus/octopus/issues?labels=baseline-failure&state=all&page=N&limit=50
|
||||
```
|
||||
|
||||
Match each candidate by **failure signature** — the error/assertion signature
|
||||
@@ -848,10 +847,10 @@ number `#NNNN` is the tracker handle.
|
||||
no existing family matches the signature:
|
||||
|
||||
```
|
||||
gitea_issue__create(owner="Octopus", repo="octopus",
|
||||
title="[{origin}] Baseline failure: {test identifier} (BF-{NNN})",
|
||||
body=<issue body template below>,
|
||||
labels=[baseline_failure_label_id, severity_label_id, kind_bug_label_id])
|
||||
POST <gitea-base-url>/api/v1/repos/Octopus/octopus/issues
|
||||
body: {"title":"[{origin}] Baseline failure: {test identifier} (BF-{NNN})",
|
||||
"body":<issue body template below>,
|
||||
"labels":[baseline_failure_label_id, severity_label_id, kind_bug_label_id]}
|
||||
```
|
||||
|
||||
- **Title**: `[{origin}] Baseline failure: {signature summary} (BF-{NNN})`
|
||||
@@ -965,8 +964,7 @@ AND closed), per `core/rules/testing.md`** (de-duplicate BEFORE filing,
|
||||
retro [org-internal #2696]). Query `flaky-test` issues in ALL states:
|
||||
|
||||
```
|
||||
gitea_issue__list(owner="Octopus", repo="octopus",
|
||||
labels="flaky-test", state="all")
|
||||
GET <gitea-base-url>/api/v1/repos/Octopus/octopus/issues?labels=flaky-test&state=all&page=N&limit=50
|
||||
```
|
||||
|
||||
Match each candidate by **failure signature** — the flakiness mode (timeout /
|
||||
@@ -991,10 +989,10 @@ incl. closed tickets). `FT-NNN` names the FAMILY.
|
||||
no existing family matches the signature:
|
||||
|
||||
```
|
||||
gitea_issue__create(owner="Octopus", repo="octopus",
|
||||
title="[{origin}] Flaky test: {test identifier} (FT-{NNN})",
|
||||
body=<issue body template below>,
|
||||
labels=[flaky_test_label_id, severity_label_id, kind_testing_label_id])
|
||||
POST <gitea-base-url>/api/v1/repos/Octopus/octopus/issues
|
||||
body: {"title":"[{origin}] Flaky test: {test identifier} (FT-{NNN})",
|
||||
"body":<issue body template below>,
|
||||
"labels":[flaky_test_label_id, severity_label_id, kind_testing_label_id]}
|
||||
```
|
||||
|
||||
- **Title**: `[{origin}] Flaky test: {signature summary} (FT-{NNN})` — the
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
{
|
||||
"name": "octopus-workflow",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"description": "Standalone workflow core: provider-neutral agent workflow corpus (skills / rules / checklists / templates / schemas) with drift guards, extracted from the octopus agent platform.",
|
||||
"license": "MIT",
|
||||
"private": false,
|
||||
|
||||
Reference in New Issue
Block a user