Why:
svc.sh only knew two hardcoded environments (dev/prod) and always built
the current workspace, so there was no way to deploy a specific Dev- repo
commit or a Releases artifact, and no record of what was actually started.
Evidence:
- scripts/svc.sh commits dev|release lists deployable commits (release
entries annotated with version + devCommit; both mark HEAD and the
environments already running them).
- deploy --from local|dev@<sha>|release@<version|sha> materializes the
chosen source: dev commits build in an isolated worktree
(runtime/.worktrees/<sha>, submodule pins verified to land exactly),
release artifacts are sha256-verified against versions/<v>/manifest.json
(a forged manifest is refused); --pick offers an interactive numbered
choice and --dry-run prints the plan.
- Environment names are generalized (^[a-z][a-z0-9-]{0,15}$, derived port
8800-9099 on collision-free scan); each env is self-contained under
runtime/<env>/{bin,plugins,data} with svc.env (current state) and
history.jsonl (append-only deploy/start/stop events). status scans all
registered envs and history [env] [N] merges the event stream.
- Old artifacts that predate --dsn/--auth have those flags auto-omitted
(probed via serve usage); legacy svc.env files still render in status.
- Verified end to end in the task worktree: stub-binary lifecycle, a real
release@0.1.0 deploy (HTTP 200, source shown in status, commits marked),
failure paths (sha mismatch, immediate exit, non-TTY --pick).
Impact:
scripts/svc.sh users gain multi-version side-by-side environments and
rollback by redeploying an older source; existing dev/prod defaults and
safety constraints (own-pidfile-only stop, port-occupancy check) are
unchanged. Environments deployed by the previous script need one fresh
deploy before start/restart works again. Makefile gains svc-commits and
svc-history targets.
Refs: .task/feature-svc-deploy-source-registry.md(任务卡=PR 描述)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
feature/svc-deploy-source-registry 任务卡
任务主记录:<PR 链接,task-finish 时填写>;状态:进行中;owner:weichen
基线与授权
8c4fd01947scripts/svc.sh与顶层Makefile帮助文案,不动模块 gitlink。目标与非目标
目标(scripts/svc.sh):
(
../Agent-System-Releases,每提交 = 一个发布版本)的提交,并选定提交部署:svc.sh commits [dev|release] [N]:编号列表(短 SHA、日期、主题;release 附版本号与 devCommit;dev 标注 HEAD 与已部署环境)。
svc.sh <env> deploy --from SOURCE:local(默认,保持现行为:构建当前工作区)|dev[<@sha>](隔离 worktree 物化 gitlink → make build → 复制制品)|release[<@version|sha>](取 Releasesbuild/<v>/制品,sha256 对 manifest 校验)。--pick [dev|release]交互式编号选择(仅 TTY);--dry-run只解析打印计划。^[a-z][a-z0-9-]{0,15}$,保留字除外),SVC_<ENV>_ADDR/DATA/DSN/AUTH/MOCK对任意环境生效;自定义环境无显式地址时端口由环境名确定性派生(8800+hash,冲突扫描递增)。启动登记落盘:
runtime/<env>/svc.env(当前态:env/pid/addr/data/bin/source/version/started)runtime/<env>/history.jsonl(追加式:deploy/start/stop 事件,含来源与结果)runtime/<env>/{bin/agent-system,plugins/},跨环境互不串版本。svc.sh status扫描 runtime/* 枚举全部环境(不再硬编码 dev/prod);新子命令
svc.sh history [env] [N]跨环境合并查看。非目标:不改 agent-system serve 的接口与二进制行为;不做容器/多机;不做 git fetch 拉远端新
提交(commits 只列本地已有对象,缺失时提示先 fetch);不改 Releases 仓脚本。
设计要点
端口占用预检、播种逻辑全部保留。
start改用环境目录内二进制;旧环境(无环境产物)首次需重新 deploy(文档注明)。
git worktree add --detach runtime/.worktrees/<sha>+ 递归 submoduleupdate,不触碰主检出工作区(保护他人现场);成功后回收 worktree,失败保留供排障。
scripts/build-release.sh <v>。SVC_RELEASES_DIR>../Agent-System-Releases(相对本仓根)。同步记录
8c4fd019478c4fd01947结果与验证(完成后填写)
scripts/svc.sh重写完成(348 → ~790 行),Makefile 增加 svc-commits/svc-history 目标。commits [dev|release] [N]列举(dev 标注 HEAD/已部署环境;release 附版本与 devCommit);
deploy --from local|dev[@sha]|release[@版本|sha];--pick交互选择;--dry-run打印计划。history.jsonl 事件流;
status扫描发现全部环境;history [env] [N]汇总。bash -n通过;shellcheck 本机未安装(缺项)。-)。stop → history 登记 start/stop ok。
来源 → commits release 标注 [已部署:testrel]。
且 restart 传播 exit 1;--pick 非 TTY 拒绝。
build → 版本串 d26187e+core=b6d428b+backend=9a545b1+frontend=9fc1387+ui=3f692d2(与该
提交组合一致)→ 产物复制 → 启动 HTTP 200 → status 来源 dev@d26187e → 构建 worktree 已回收
(git worktree list 无残留);该提交产物同样不识别 --auth,自动省略逻辑生效。
--port 覆盖生效;make svc-commits/svc-history 可用。
commits 只列本地对象,远端新提交需先 git fetch(设计内);dev@sha 构建需 npm/go 网络。
Why: svc.sh only knew two hardcoded environments (dev/prod) and always built the current workspace, so there was no way to deploy a specific Dev- repo commit or a Releases artifact, and no record of what was actually started. Evidence: - scripts/svc.sh commits dev|release lists deployable commits (release entries annotated with version + devCommit; both mark HEAD and the environments already running them). - deploy --from local|dev@<sha>|release@<version|sha> materializes the chosen source: dev commits build in an isolated worktree (runtime/.worktrees/<sha>, submodule pins verified to land exactly), release artifacts are sha256-verified against versions/<v>/manifest.json (a forged manifest is refused); --pick offers an interactive numbered choice and --dry-run prints the plan. - Environment names are generalized (^[a-z][a-z0-9-]{0,15}$, derived port 8800-9099 on collision-free scan); each env is self-contained under runtime/<env>/{bin,plugins,data} with svc.env (current state) and history.jsonl (append-only deploy/start/stop events). status scans all registered envs and history [env] [N] merges the event stream. - Old artifacts that predate --dsn/--auth have those flags auto-omitted (probed via serve usage); legacy svc.env files still render in status. - Verified end to end in the task worktree: stub-binary lifecycle, a real release@0.1.0 deploy (HTTP 200, source shown in status, commits marked), failure paths (sha mismatch, immediate exit, non-TTY --pick). Impact: scripts/svc.sh users gain multi-version side-by-side environments and rollback by redeploying an older source; existing dev/prod defaults and safety constraints (own-pidfile-only stop, port-occupancy check) are unchanged. Environments deployed by the previous script need one fresh deploy before start/restart works again. Makefile gains svc-commits and svc-history targets. Refs: .task/feature-svc-deploy-source-registry.md(任务卡=PR 描述)