baa-conductor

git clone 

commit
cf510d3
parent
4aea341
author
codex@macbookpro
date
2026-04-01 20:05:10 +0800 CST
feat: remove stagit repo route
8 files changed,  +219, -143
M PROGRESS/2026-03-29-current-code-progress.md
+4, -5
 1@@ -52,7 +52,7 @@
 2 - `/artifact/` 静态文件服务
 3 - `/v1/messages`、`/v1/executions`、`/v1/sessions`、`/v1/sessions/latest`
 4 - `/describe` 返回 `recent_sessions_url`
 5-- stagit 仓库静态页面
 6+- repo 静态页浏览能力后来已迁到 `baa-pgit`,当前 `conductor` 不再提供 `/artifact/repo/*`
 7 
 8 因此,`ARTIFACT_STATIC_SERVICE.md` 现在更适合作为已完成主线的实现参考,而不是当前活跃任务入口。
 9 
10@@ -80,11 +80,10 @@
11 
12 ## 当前 open bug / 风险
13 
14-### BUG-026
15+### BUG-026(历史背景)
16 
17-- `/artifact/repo/:repo_name` 根路径不会落到默认 `log.html`
18-- 显式 `/artifact/repo/<repo>/log.html` 可用
19-- 影响 repo 首页入口和 URL 语义一致性
20+- 该问题对应的 repo 静态页路由已在后续任务中整体删除
21+- `/artifact/repo/*` 不再是当前仓库能力;相关描述只保留为历史排障背景
22 
23 ### BUG-027
24 
M apps/conductor-daemon/src/index.test.js
+6, -12
 1@@ -7846,10 +7846,6 @@ test("handleConductorHttpRequest serves artifact files and robots.txt", async ()
 2   const { repository, snapshot } = await createLocalApiFixture();
 3 
 4   await withArtifactStoreFixture(async ({ artifactStore }) => {
 5-    const repoDir = join(artifactStore.getArtifactsDir(), "repo", "demo-repo");
 6-    mkdirSync(repoDir, { recursive: true });
 7-    writeFileSync(join(repoDir, "log.html"), "<html><body>demo repo home</body></html>\n");
 8-
 9     await artifactStore.insertMessage({
10       conversationId: "conv_artifact",
11       id: "msg_artifact",
12@@ -7935,27 +7931,25 @@ test("handleConductorHttpRequest serves artifact files and robots.txt", async ()
13     assert.equal(sessionLatestResponse.status, 200);
14     assert.match(Buffer.from(sessionLatestResponse.body).toString("utf8"), /session_artifact/u);
15 
16-    const repoIndexResponse = await handleConductorHttpRequest(
17+    const removedRepoRootResponse = await handleConductorHttpRequest(
18       {
19         method: "GET",
20         path: "/artifact/repo/demo-repo"
21       },
22       context
23     );
24-    assert.equal(repoIndexResponse.status, 200);
25-    assert.match(repoIndexResponse.headers["content-type"], /^text\/html\b/u);
26-    assert.match(Buffer.from(repoIndexResponse.body).toString("utf8"), /demo repo home/u);
27+    assert.equal(removedRepoRootResponse.status, 404);
28+    assert.equal(parseJsonBody(removedRepoRootResponse).error, "not_found");
29 
30-    const repoLogResponse = await handleConductorHttpRequest(
31+    const removedRepoFileResponse = await handleConductorHttpRequest(
32       {
33         method: "GET",
34         path: "/artifact/repo/demo-repo/log.html"
35       },
36       context
37     );
38-    assert.equal(repoLogResponse.status, 200);
39-    assert.match(repoLogResponse.headers["content-type"], /^text\/html\b/u);
40-    assert.match(Buffer.from(repoLogResponse.body).toString("utf8"), /demo repo home/u);
41+    assert.equal(removedRepoFileResponse.status, 404);
42+    assert.equal(parseJsonBody(removedRepoFileResponse).error, "not_found");
43 
44     const missingResponse = await handleConductorHttpRequest(
45       {
M apps/conductor-daemon/src/local-api.ts
+0, -73
 1@@ -437,16 +437,6 @@ const LOCAL_API_ROUTES: LocalApiRouteDefinition[] = [
 2     pathPattern: "/robots.txt",
 3     summary: "返回允许 AI 访问 /artifact/ 的 robots.txt"
 4   },
 5-  // Keep the repo route ahead of the generic artifact route so repo root URLs
 6-  // can fall back to log.html instead of being claimed by the generic matcher.
 7-  {
 8-    id: "service.artifact.repo",
 9-    exposeInDescribe: false,
10-    kind: "read",
11-    method: "GET",
12-    pathPattern: "/artifact/repo/:repo_name/*",
13-    summary: "读取 stagit 生成的 git 仓库静态页面"
14-  },
15   {
16     id: "service.artifact.read",
17     exposeInDescribe: false,
18@@ -6576,67 +6566,6 @@ async function handleArtifactRead(context: LocalApiRequestContext): Promise<Cond
19   }
20 }
21 
22-const REPO_STATIC_CONTENT_TYPES: Record<string, string> = {
23-  ".html": "text/html; charset=utf-8",
24-  ".css":  "text/css; charset=utf-8",
25-  ".xml":  "application/xml",
26-  ".atom": "application/atom+xml",
27-  ".json": "application/json",
28-  ".txt":  "text/plain; charset=utf-8",
29-  ".png":  "image/png",
30-  ".ico":  "image/x-icon",
31-  ".svg":  "image/svg+xml"
32-};
33-
34-function getRepoStaticContentType(filePath: string): string {
35-  const dot = filePath.lastIndexOf(".");
36-
37-  if (dot !== -1) {
38-    const ext = filePath.slice(dot).toLowerCase();
39-    const ct = REPO_STATIC_CONTENT_TYPES[ext];
40-
41-    if (ct) {
42-      return ct;
43-    }
44-  }
45-
46-  return "text/plain; charset=utf-8";
47-}
48-
49-const REPO_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/u;
50-
51-async function handleArtifactRepoRead(context: LocalApiRequestContext): Promise<ConductorHttpResponse> {
52-  const artifactStore = requireArtifactStore(context.artifactStore);
53-  const repoName = context.params.repo_name;
54-  const wildcard = context.params["*"] || "log.html";
55-
56-  if (!repoName || !REPO_NAME_PATTERN.test(repoName) || wildcard.includes("..")) {
57-    throw new LocalApiHttpError(
58-      404,
59-      "not_found",
60-      `No conductor route matches "${normalizePathname(context.url.pathname)}".`
61-    );
62-  }
63-
64-  const filePath = join(artifactStore.getArtifactsDir(), "repo", repoName, wildcard);
65-
66-  try {
67-    return binaryResponse(200, readFileSync(filePath), {
68-      "content-type": getRepoStaticContentType(wildcard)
69-    });
70-  } catch (error) {
71-    if (isMissingFileError(error)) {
72-      throw new LocalApiHttpError(
73-        404,
74-        "not_found",
75-        `Artifact "${normalizePathname(context.url.pathname)}" was not found.`
76-      );
77-    }
78-
79-    throw error;
80-  }
81-}
82-
83 function buildPlainTextBinaryResponse(status: number, body: string): ConductorHttpResponse {
84   return binaryResponse(status, Buffer.from(body, "utf8"), {
85     "content-type": CODE_ROUTE_CONTENT_TYPE
86@@ -7754,8 +7683,6 @@ async function dispatchBusinessRoute(
87       return handleRobotsRead();
88     case "service.artifact.read":
89       return handleArtifactRead(context);
90-    case "service.artifact.repo":
91-      return handleArtifactRepoRead(context);
92     case "service.code.read":
93       return handleCodeRead(context);
94     case "service.health":
M plans/ARTIFACT_STATIC_SERVICE.md
+1, -1
1@@ -379,7 +379,7 @@ D1 同步细节:
2 7. **D1 异步适配器**(TypeScript async 重写)
3 8. **D1 同步队列**(后台推送 + 重试)
4 9. **会话索引自动更新**(事件触发)
5-10. **stagit 集成**(后续)
6+10. **repo 静态页浏览能力迁出**(当前仓库不做)
7 
8 ## 11. 不做的事
9 
M plans/STATUS_SUMMARY.md
+2, -1
 1@@ -17,7 +17,7 @@
 2   - 本地 SQLite + D1 异步同步
 3   - `/artifact/` HTTP serve
 4   - recent sessions 入口
 5-  - stagit 仓库浏览
 6+  - repo 静态页浏览能力已迁到 `baa-pgit`;当前 `conductor` 不再提供 `/artifact/repo/*`
 7 - 插件诊断日志链路已经完成:
 8   - 插件 → WS → conductor → `logs/baa-plugin/YYYY-MM-DD.jsonl`
 9   - `browser.final_message` ingest → `logs/baa-ingest/YYYY-MM-DD.jsonl`
10@@ -72,6 +72,7 @@
11 - `OPT-002`、`OPT-007` 已分别随 `889f746`、`b8d69c8` 合入 `main`,旧汇总中的 open 状态已改正
12 - `T-BUG-029` / `T-BUG-031` 的任务卡已完成,但旧汇总文档仍把它们写成 pending manual verification;现统一改为“建议补做浏览器复核”
13 - Artifact 静态服务已经完成,不再把它写成“下一阶段主线”
14+- `T-S050` 曾引入 stagit repo 静态页,但该能力已随 `T-S070` 迁出到 `baa-pgit`;旧汇总里“当前主线仍提供 /artifact/repo/*”的口径已清理
15 
16 ## 当前最高优先级
17 
D scripts/git-snapshot.sh
+0, -49
 1@@ -1,49 +0,0 @@
 2-#!/usr/bin/env bash
 3-# git-snapshot.sh — generate static HTML for a git repo using stagit.
 4-# Usage: git-snapshot.sh <repo_path> <output_dir>
 5-#
 6-# Supports incremental generation via stagit -c (cachefile).
 7-
 8-set -euo pipefail
 9-
10-REPO_PATH="${1:?Usage: git-snapshot.sh <repo_path> <output_dir>}"
11-OUTPUT_DIR="${2:?Usage: git-snapshot.sh <repo_path> <output_dir>}"
12-
13-# Resolve to absolute paths.
14-REPO_PATH="$(cd "$REPO_PATH" && pwd)"
15-
16-# Ensure output directory exists.
17-mkdir -p "$OUTPUT_DIR"
18-OUTPUT_DIR="$(cd "$OUTPUT_DIR" && pwd)"
19-
20-CACHEFILE="$OUTPUT_DIR/.stagit-cache"
21-
22-# stagit must be run from the output directory.
23-cd "$OUTPUT_DIR"
24-
25-# Generate static HTML (with incremental cache).
26-stagit -c "$CACHEFILE" "$REPO_PATH"
27-
28-# Provide a minimal style.css if one doesn't exist yet.
29-if [ ! -f "$OUTPUT_DIR/style.css" ]; then
30-  cat > "$OUTPUT_DIR/style.css" <<'CSSEOF'
31-body { font-family: monospace; margin: 1em; background: #fff; color: #222; }
32-table { border-collapse: collapse; }
33-td, th { padding: 2px 6px; }
34-a { color: #005f87; }
35-pre { overflow-x: auto; }
36-hr { border: 0; border-top: 1px solid #ccc; }
37-#content { overflow-x: auto; }
38-.num { text-align: right; }
39-CSSEOF
40-fi
41-
42-# Create a 1x1 transparent PNG for logo/favicon if missing.
43-if [ ! -f "$OUTPUT_DIR/logo.png" ]; then
44-  printf '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\nIDATx\x9cc\x00\x01\x00\x00\x05\x00\x01\r\n\xb4\x00\x00\x00\x00IEND\xaeB`\x82' > "$OUTPUT_DIR/logo.png"
45-fi
46-if [ ! -f "$OUTPUT_DIR/favicon.png" ]; then
47-  cp "$OUTPUT_DIR/logo.png" "$OUTPUT_DIR/favicon.png"
48-fi
49-
50-echo "stagit: generated static HTML in $OUTPUT_DIR"
A tasks/T-S070.md
+199, -0
  1@@ -0,0 +1,199 @@
  2+# Task T-S070:移除 conductor 内的 stagit 仓库静态页能力
  3+
  4+## 状态
  5+
  6+- 当前状态:`已完成`
  7+- 规模预估:`M`
  8+- 依赖任务:无
  9+- 建议执行者:`Codex`
 10+
 11+## 直接给对话的提示词
 12+
 13+读 `/Users/george/code/baa-conductor/tasks/T-S070.md` 任务文档,完成开发任务。
 14+
 15+如需补背景,再读:
 16+
 17+- `/Users/george/code/baa-conductor/tasks/TASK_OVERVIEW.md`
 18+- `/Users/george/code/baa-conductor/plans/STATUS_SUMMARY.md`
 19+- `/Users/george/code/baa-conductor/tasks/T-S050.md`
 20+
 21+## 当前基线
 22+
 23+- 仓库:`/Users/george/code/baa-conductor`
 24+- 分支基线:`main`
 25+- 提交:`4aea341`
 26+
 27+## 分支与 worktree(强制)
 28+
 29+- 分支名:`feat/remove-stagit-repo-route`
 30+- worktree 路径:`/Users/george/code/baa-conductor-remove-stagit-repo-route`
 31+
 32+开工步骤:
 33+
 34+1. `cd /Users/george/code/baa-conductor`
 35+2. `git worktree add ../baa-conductor-remove-stagit-repo-route -b feat/remove-stagit-repo-route main`
 36+3. `cd ../baa-conductor-remove-stagit-repo-route`
 37+4. 在这个 worktree 目录里开发,不要回到主仓库目录
 38+
 39+完成后提交与推送:
 40+
 41+1. 在 worktree 里提交所有变更(包括更新后的任务文档)
 42+2. `git push -u origin feat/remove-stagit-repo-route`
 43+
 44+合并步骤(由合并者执行):
 45+
 46+1. `cd /Users/george/code/baa-conductor`
 47+2. `git fetch origin`
 48+3. `git merge origin/feat/remove-stagit-repo-route`
 49+4. `git push`
 50+5. `git worktree remove ../baa-conductor-remove-stagit-repo-route`
 51+
 52+合并冲突处理:
 53+
 54+1. 如果 `git merge` 报冲突,先 `git diff` 查看冲突文件
 55+2. 手动解决冲突后 `git add` 冲突文件
 56+3. `git merge --continue` 完成合并
 57+4. 不要用 `git merge --abort` 然后 force 覆盖
 58+
 59+## 目标
 60+
 61+删除 `conductor` 仓库内的 stagit 生成与 `/artifact/repo/*` 静态服务能力,不做兼容跳转。
 62+
 63+## 背景
 64+
 65+静态 repo 页面功能已经移到 `baa-pgit` 仓库,这个仓库内保留的 stagit 路由、脚本和测试已经不再属于当前主线。继续保留只会让 `conductor` 同时承担两套 repo 浏览方案,增加维护成本和文档歧义。
 66+
 67+当前实现边界很清楚:
 68+
 69+- `apps/conductor-daemon/src/local-api.ts` 内有 `/artifact/repo/:repo_name/*` 路由与 handler
 70+- `scripts/git-snapshot.sh` 负责调用 stagit 生成静态页
 71+- `apps/conductor-daemon/src/index.test.js` 有对应 repo 路由测试
 72+- 多份文档仍把 stagit 仓库浏览写成当前能力
 73+
 74+本任务要求直接删除,不保留兼容跳转。
 75+
 76+## 涉及仓库
 77+
 78+- `/Users/george/code/baa-conductor`
 79+
 80+## 范围
 81+
 82+- 删除 conductor 内的 stagit repo 静态页路由与读取逻辑
 83+- 删除 stagit 生成脚本和对应测试
 84+- 更新总览、状态、实现说明文档,移除“当前主线仍提供 /artifact/repo/*”的口径
 85+
 86+## 路径约束
 87+
 88+- 不在本任务里接入 `baa-pgit` 跳转或新域名代理
 89+- 不改动普通 `/artifact/:artifact_scope/:artifact_file` 读路径
 90+- 不改动 `artifact-db`、D1 同步、recent sessions 或其他 artifact 主链
 91+- 历史任务卡和 archive 文档可以保留历史描述,不要求批量清洗
 92+
 93+## 推荐实现边界
 94+
 95+建议删除或收缩:
 96+
 97+- `service.artifact.repo` 路由与 `handleArtifactRepoRead`
 98+- `scripts/git-snapshot.sh`
 99+- repo 静态页测试
100+
101+建议更新:
102+
103+- `/Users/george/code/baa-conductor/tasks/TASK_OVERVIEW.md`
104+- `/Users/george/code/baa-conductor/plans/STATUS_SUMMARY.md`
105+- 如有必要,更新主 README 或相关 API/plan 文档
106+
107+## 允许修改的目录
108+
109+- `/Users/george/code/baa-conductor/apps/conductor-daemon/src/`
110+- `/Users/george/code/baa-conductor/scripts/`
111+- `/Users/george/code/baa-conductor/tasks/`
112+- `/Users/george/code/baa-conductor/plans/`
113+- `/Users/george/code/baa-conductor/docs/`
114+
115+## 尽量不要修改
116+
117+- `/Users/george/code/baa-conductor/packages/`
118+- `/Users/george/code/baa-conductor/plugins/`
119+- `/Users/george/code/baa-conductor/ops/sql/`
120+
121+## 必须完成
122+
123+### 1. 删除 repo 静态页路由
124+
125+- 删除 `/artifact/repo/:repo_name/*` 路由注册
126+- 删除对应 handler、content-type 辅助逻辑和只为 repo 静态页服务的辅助代码
127+- 确保普通 `/artifact/` 路由不受影响
128+
129+### 2. 删除 stagit 生成脚本与测试
130+
131+- 删除 `scripts/git-snapshot.sh`
132+- 删除或改写只覆盖 repo 静态页的测试
133+- 确保删除后测试套仍通过
134+
135+### 3. 更新文档口径
136+
137+- 从总览和状态文档中移除“stagit 仓库浏览是当前能力”的描述
138+- 明确说明 repo 静态页能力已迁出当前仓库
139+- 更新任务文档状态与执行记录
140+
141+## 需要特别注意
142+
143+- 本任务是功能删除,不是兼容迁移;不要额外加入跳转逻辑
144+- 不要误删普通 artifact 静态读接口
145+- 不要顺手改动 `baa-pgit` 或其他仓库
146+- 所有开发必须在 worktree 中进行,不要在主仓库目录修改代码
147+
148+## 验收标准
149+
150+- `conductor` 代码中不再保留 `/artifact/repo/:repo_name/*` 路由
151+- 仓库内不再保留 `scripts/git-snapshot.sh`
152+- 文档不再把 stagit 仓库浏览写成当前主线能力
153+- 相关测试通过,且普通 artifact 路由不回退
154+
155+## 推荐验证命令
156+
157+- `pnpm -C /Users/george/code/baa-conductor/apps/conductor-daemon test`
158+- `pnpm -C /Users/george/code/baa-conductor/apps/conductor-daemon build`
159+- `rg -n "artifact/repo|stagit|git-snapshot\\.sh" /Users/george/code/baa-conductor`
160+
161+## 执行记录
162+
163+> 以下内容由执行任务的 AI 填写,创建任务时留空。
164+
165+### 开始执行
166+
167+- 执行者:`Codex`
168+- 开始时间:`2026-04-01 19:57:00 CST`
169+- 状态变更:`待开始` -> `进行中`
170+
171+### 完成摘要
172+
173+- 完成时间:`2026-04-01 20:04:52 CST`
174+- 状态变更:`进行中` -> `已完成`
175+- 修改了哪些文件:
176+  - `apps/conductor-daemon/src/local-api.ts`
177+  - `apps/conductor-daemon/src/index.test.js`
178+  - `scripts/git-snapshot.sh`
179+  - `tasks/TASK_OVERVIEW.md`
180+  - `plans/STATUS_SUMMARY.md`
181+  - `plans/ARTIFACT_STATIC_SERVICE.md`
182+  - `PROGRESS/2026-03-29-current-code-progress.md`
183+  - `tasks/T-S070.md`
184+- 核心实现思路:
185+  - 直接删除 `service.artifact.repo` 路由、`handleArtifactRepoRead` 和 repo 静态页专用 content-type/路径校验逻辑,不保留跳转或兼容层
186+  - 把 repo 静态页测试改成负向断言,确认 `/artifact/repo/*` 现在返回 `404`,同时保留普通 artifact 路径回归覆盖
187+  - 删除 `scripts/git-snapshot.sh`,并把当前文档口径统一改成“repo 静态页能力已迁到 `baa-pgit`”
188+- 跑了哪些测试:
189+  - `pnpm -C /Users/george/code/baa-conductor-remove-stagit-repo-route/apps/conductor-daemon test`
190+  - `pnpm -C /Users/george/code/baa-conductor-remove-stagit-repo-route/apps/conductor-daemon build`
191+  - `rg -n --glob '!tasks/archive/**' --glob '!plans/archive/**' --glob '!bugs/archive/**' --glob '!node_modules/**' "artifact/repo|stagit|git-snapshot\\.sh" /Users/george/code/baa-conductor-remove-stagit-repo-route`
192+
193+### 执行过程中遇到的问题
194+
195+- 主仓库 worktree 里已有未提交的文档改动,因此先确认 `main` 与 `origin/main` 一致,再从 `main` 新建独立 worktree,避免污染主仓库工作区
196+- 新建 worktree 默认没有 `node_modules`,首次执行 `pnpm test` 时 `pnpm exec tsc` 缺失;在 worktree 根目录执行一次 `pnpm install` 后恢复正常
197+
198+### 剩余风险
199+
200+- 历史任务卡、archive 文档和历史需求文档仍保留 stagit 描述;这是按任务约束刻意保留的历史记录,不代表当前主线能力
M tasks/TASK_OVERVIEW.md
+7, -2
 1@@ -16,7 +16,7 @@
 2   - `artifact-db` 持久化 messages / executions / sessions
 3   - `conductor` HTTP serve `/artifact/`
 4   - D1 异步同步队列
 5-  - stagit 仓库浏览:`/artifact/repo/baa-conductor/log.html`
 6+  - repo 静态页浏览能力已迁到 `baa-pgit`;当前 `conductor` 不再提供 `/artifact/repo/*`
 7 - Firefox 插件诊断日志链路已落地:
 8   - `page-interceptor -> content-script -> controller -> WS -> conductor`
 9   - conductor 写 `logs/baa-plugin/YYYY-MM-DD.jsonl`
10@@ -72,6 +72,7 @@
11 - `OPT-002`、`OPT-007` 已分别随 `889f746`、`b8d69c8` 合入 `main`,旧总览中的 open 状态已改正
12 - `T-BUG-029`、`T-BUG-031` 的任务卡已是 `已完成`,但旧文档仍把它们写成 pending manual verification;现统一改为“建议补做浏览器复核”
13 - Artifact 静态服务已经完成,不再把 `T-S039`~`T-S045` 写成“当前活跃主线”
14+- `T-S050` 曾引入 stagit repo 静态页,但该能力已随 `T-S070` 迁出到 `baa-pgit`;旧文档里“当前主线仍提供 /artifact/repo/*”的口径已清理
15 
16 ## 当前活跃任务与优先级
17 
18@@ -94,6 +95,7 @@
19 | [`T-S068`](./T-S068.md) | ChatGPT proxy send 冷启动降级保护 | S | 无 | Codex | 已完成 |
20 | [`T-S069`](./T-S069.md) | proxy_delivery 成功语义增强 | L | T-S060 | Codex | 已完成 |
21 | [`T-S065`](./T-S065.md) | policy 配置化 | M | 无 | Codex | 已完成 |
22+| [`T-S070`](./T-S070.md) | 移除 conductor 内的 stagit 仓库静态页能力 | M | 无 | Codex | 已完成 |
23 
24 ### 当前下一波任务
25 
26@@ -123,6 +125,7 @@
27 | T-S048 | Gemini 投递适配器 | ✅ |
28 | T-S049 | 开放 chatgpt/gemini target | ✅ |
29 | T-S050 | stagit git 静态页面 | ✅ |
30+| T-S070 | 移除 conductor 内的 stagit 仓库静态页能力 | ✅ |
31 | T-S052 | D1 数据库初始化 | ✅ |
32 | T-S053 | 插件诊断日志 | ✅ |
33 | T-S054 | 插件日志 WS 转发 | ✅ |
34@@ -181,7 +184,9 @@
35 
36 ## 当前主线判断
37 
38-Phase 1(浏览器主链)、Artifact 静态服务,以及 timed-jobs + 续命主线都已完成收口。`T-S060`、`T-S061`、`T-S062`、`T-S063`、`T-S064`、`T-S065`、`T-S066`、`T-S067`、`T-S068`、`T-S069` 已全部落地,当前主线已经没有 open bug blocker,也没有 open opt。
39+Phase 1(浏览器主链)、Artifact 静态服务,以及 timed-jobs + 续命主线都已完成收口。`T-S060`、`T-S061`、`T-S062`、`T-S063`、`T-S064`、`T-S065`、`T-S066`、`T-S067`、`T-S068`、`T-S069`、`T-S070` 已全部落地,当前主线已经没有 open bug blocker,也没有 open opt。
40+
41+repo 静态页浏览能力已随 `T-S070` 迁出到 `baa-pgit`;当前仓库只保留普通 artifact 静态读面,不再提供 `/artifact/repo/*`。
42 
43 如果继续推进,建议:
44