baa-conductor

git clone 

baa-conductor / bugs / archive
codex@macbookpro  ·  2026-03-30

BUG-026-artifact-repo-root-fallback-broken.md

  1# BUG-026: `/artifact/repo/:repo_name` 根路径不会落到默认 `log.html`
  2
  3> 提交者:代码核对 + 公网实测
  4> 日期:2026-03-29
  5
  6## 现象
  7
  8当前 stagit 仓库静态页的显式文件路径可正常访问,但 repo 根路径不会按设计落到默认 `log.html`  9
 10- `GET /artifact/repo/baa-conductor/log.html` 返回 `200 text/html`
 11- `GET /artifact/repo/baa-conductor` 返回 `404 application/json`
 12
 13这意味着用户或 AI 只拿到 repo 根 URL 时,不能直接进入仓库首页,必须显式补上 `/log.html` 14
 15## 触发路径
 16
 17```text
 18GET /artifact/repo/:repo_name
 19-> route matcher 先命中 /artifact/:artifact_scope/:artifact_file
 20-> 走通用 artifact read
 21-> 读取 artifacts/repo/:repo_name 普通文件
 22-> 文件不存在
 23-> 404
 24```
 25
 26而不是:
 27
 28```text
 29GET /artifact/repo/:repo_name
 30-> 命中 /artifact/repo/:repo_name/*
 31-> repo handler 把空 wildcard fallback 为 log.html
 32-> 返回 stagit 首页
 33```
 34
 35## 根因
 36
 37根因已经明确:
 38
 39- `LOCAL_API_ROUTES` 里通用路由 `/artifact/:artifact_scope/:artifact_file` 定义在 repo 专用路由 `/artifact/repo/:repo_name/*` 之前
 40- `matchRoute()` 按声明顺序返回第一个匹配项
 41- 对三段路径 `/artifact/repo/<repo>` 来说,前者已经完全匹配,后者根本没有机会执行
 42- 因此 repo handler 中的默认值 `context.params["*"] || "log.html"` 只对 `/artifact/repo/<repo>/...` 生效,对根路径不生效
 43
 44这不是 stagit 生成问题,也不是公网部署问题,而是本地 API 路由分派顺序问题。
 45
 46## 复现步骤
 47
 48公网最小复现:
 49
 50```bash
 51curl -sS -o /dev/null -w '%{http_code} %{content_type}\n' \
 52  https://conductor.makefile.so/artifact/repo/baa-conductor/log.html
 53
 54curl -sS -o /dev/null -w '%{http_code} %{content_type}\n' \
 55  https://conductor.makefile.so/artifact/repo/baa-conductor
 56```
 57
 582026-03-29 实测结果:
 59
 60- 第一条返回:`200 text/html; charset=utf-8`
 61- 第二条返回:`404 application/json; charset=utf-8`
 62
 63本地代码最小核对点:
 64
 65- `apps/conductor-daemon/src/local-api.ts`
 66- 通用 artifact 路由先于 repo 路由定义
 67- `matchRoute()` 采用 first-match 行为
 68- `handleArtifactRepoRead()` 里虽然实现了 `log.html` fallback,但根路径走不到这里
 69
 70## 当前影响
 71
 72- repo 静态页不是完全不可用,因为显式 `/log.html` 可正常访问
 73- 但“repo 根路径可作为稳定入口”这个语义当前不成立
 74- 任何只拼出 `/artifact/repo/<repo>` 的调用方都会得到 404
 75- 会影响 AI/脚本/人工直接把 repo 根 URL 当作首页入口的体验和可发现性
 76
 77## 修复建议
 78
 79### 方案 A(推荐)
 80
 81调整路由优先级,让 `/artifact/repo/:repo_name/*` 在通用 artifact 路由之前匹配。
 82
 83这样最直接,也与现有 fallback 设计一致。
 84
 85### 方案 B
 86
 87保留当前顺序,但让 `matchRoute()` 对“更具体的静态段更多”的路由优先。
 88
 89这更通用,但复杂度高于当前问题本身。
 90
 91### 方案 C
 92
 93单独增加一个显式根路径路由 `/artifact/repo/:repo_name`,直接映射到 `log.html` 94
 95可以修问题,但会让 repo 路由定义分裂成两条。
 96
 97## 严重程度
 98
 99**Medium**
100
101repo 静态浏览功能本身可通过显式 `/log.html` 使用,不是全量不可用;但默认首页入口失效,且与当前代码中的 fallback 意图不一致。
102
103## 发现时间
104
105`2026-03-29 by Codex`
106
107## 备注
108
109- 同一时间点公网已确认 `https://conductor.makefile.so/artifact/repo/baa-conductor/log.html` 正常
110- 本 bug 只指向 repo 根路径 fallback 失效,不指向 stagit 内容生成失败