Generalize svc.sh into a multi-kind service manager with tags and persistence #57

Merged
weichen merged 3 commits from feature/svc-services-registry into main 2026-09-30 13:45:24 +00:00
Owner

feature/svc-services-registry 任务卡

任务主记录:<PR 链接,task-finish 时填写>;状态:进行中;owner:weichen

基线与授权

  • 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= a2657bc25f
  • 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-svc-services-registry(worktree);分支:feature/svc-services-registry
  • 授权与交付终点:用户授权实施 svc 服务化五项功能(见目标);终点 = 实现合入 main 并回收工作区。
    仅改 Dev 仓 scripts/svc.sh 与 Makefile,不动模块 gitlink;不碰 Releases 仓与主检出运行现场。

目标与非目标

目标(scripts/svc.sh v2 —— 服务模型泛化):

  1. 按版本/提交启动各类服务:agent(后端单二进制,local/dev@sha/release@v 三源已有);
    static(前端静态服务:--from dev@sha|local 构建 frontend dist → 环境内 htdocs,或
    --dir PATH 直接服务既有目录);postgres(见 2)。
  2. 数据库管理:svc.sh db create <name> [--port --host --user --password --db --auth-mode --tag]
    ——initdb(默认 scram-sha-256)到环境目录,pg_ctl 生命周期、pg_isready 探活、
    svc.sh db dsn <name> [--reveal] 打印连接串(默认掩码密码);鉴权/端口/用户/密码/库名
    可配并持久化,供 agent 服务 --dsn 引用。
  3. 配置分层 + 标签:--config FILE(--env 别名,dotenv)+ CLI 覆盖(优先级:
    CLI > 配置文件 > 上次启动持久化配置(svc.env exec=) > 默认);--tag 可重复,
    持久化登记,list --tag 过滤。
  4. 服务总览:svc.sh list|status(等价)——全部服务表格:名称/类型/状态/pid/地址/
    来源(提交或版本)/标签;svc.sh <name> status 单服务详情(版本、数据目录、DSN 等)。
  5. 生命周期:stop/restart 按类型分派——agent/static 走 TERM→KILL;postgres 走
    pg_ctl stop -m fast(绝不裸杀 postmaster);新增 svc.sh rm <name> [--purge]
    (注销登记,--purge 连数据目录一起删,仅限 runtime// 内)。

非目标:不做守护进程/自动拉起/健康巡检(未来可演进二进制);不做 postgres 版本管理
(用系统二进制,版本语义由数据目录+标签承载);static 不做 SPA 路由重写;不管理
容器(全局非容器约束);不动 Releases 仓产物结构。

关键设计决策

  • 脚本而非二进制:Dev 仓是集成父仓(非分发单元),Go 代码都在 modules/*;本功能是
    进程编排 + 状态文件,bash + /proc + dotenv 足够、零构建依赖;registry 用 dotenv 而非
    JSON 保持无 jq 可解析,将来迁二进制可直接沿用文件格式。
  • 服务 = runtime// 目录(沿用上一版布局):登记文件 svc.env(dotenv,chmod 600)
    增加 kind(agent|postgres|static,缺省 agent 兼容旧登记)、tags、pidcheck、exec(上次
    完整启动参数,裸 start/restart 复用)、kind 特有键;事件流 history.jsonl 不变。
  • 安全边界:只写 runtime// 与 runtime/.worktrees/;只停"自己 pidfile +
    cmdline 标记双校验"的进程;端口冲突预检保留;svc.env 含密码 → 600;DSN 默认不回显
    密码。--from local 是唯一写主检出构建产物(bin/、node_modules/、dist/,均 gitignore)
    的路径,显式文档化;dev@sha/release/static 构建完全在隔离 worktree。
  • postgres 事实:宿主机有 linuxbrew postgresql@18 全套工具链(initdb/pg_ctl/pg_isready/
    psql),pg_config --bindir 可定位;SVC_PG_BIN 可覆盖。

同步记录

节点 sync_base_sha tested_head_sha checked_at
启动 a2657bc25f a2657bc25f 2026-09-30T13:30:43Z

结果与验证(完成后填写)

  • 结果:svc.sh 升级为服务模型 v2(~1000 行):kind 三类(agent/static/postgres)、标签、
    --config 配置文件(--env 别名)、持久化配置复用(svc.env exec=/addr/...)、list 总览、
    db create/dsn、rm [--purge];Makefile 增 svc-list 并更新帮助。历史与登记文件格式不变,
    旧登记(无 kind=)自动视为 agent。
  • 验证(全部在任务工作区 runtime 内真实执行;进程均已停止、目录已清理):
    • bash -n 通过;错误路径(保留名/非法名/db 缺参/rm 未登记/list --tag 缺值)均明确报错。
    • postgres 真实全链路(linuxbrew postgresql@18):db create(initdb scram-sha-256 + 随机/
      指定密码,svc.env 600)→ start(pg_ctl + pg_isready 就绪 + 自动建库)→ psql 写入数据 →
      restart 后数据仍在 → 错误密码被拒 → db dsn 掩码/--reveal → stop(pg_ctl fast)→
      rm --purge。测试中修复:psql 参数错位(-c -c)、record_state/write_static_reg 在重定向
      块内读同文件导致 tags 丢失、postgres --version 字段解析。
    • static:--dir 直接服务(登记→HTTP 200→restart→stop);dev@sha dry-run 计划正确;
      release 源明确报"不支持";--dir 不存在报错。
    • agent 回归:release@0.1.0 部署(sha256 校验、--tag stable、自定义端口 8791)→ HTTP 200
      → 裸 restart 复用 svc.env exec=(同端口同参数)→ list 三类服务混排正确 → status 详情
      (版本/标签/来源)→ commits release 标注 [已部署:prod]。
    • DSN 组合:--dsn "$(svc.sh db dsn pg1 --reveal)" 传入 agent 部署(0.1.0 旧二进制自动
      省略 --dsn/--auth 并警告);db dsn stdout 纯净可捕获。
    • 旧格式 svc.env(仅 addr/data)→ list 显示 kind=agent;--config 别名生效;
      history 支持纯数字首参。
  • 影响与剩余项:static dev@sha 真实构建未在本轮重跑(worktree 物化+make 构建路径与上一任务
    合入的 agent 构建同机制,已验证过);static 深链路由不重写(http.server 行为);
    svc 提示信息改走 stderr(stdout 只留数据),脚本管道组合更干净。
# feature/svc-services-registry 任务卡 任务主记录:<PR 链接,task-finish 时填写>;状态:进行中;owner:weichen ## 基线与授权 - 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= a2657bc25f6b43f9b3e1a23cea86e3ebcfd80ecc - 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-svc-services-registry(worktree);分支:feature/svc-services-registry - 授权与交付终点:用户授权实施 svc 服务化五项功能(见目标);终点 = 实现合入 main 并回收工作区。 仅改 Dev 仓 `scripts/svc.sh` 与 `Makefile`,不动模块 gitlink;不碰 Releases 仓与主检出运行现场。 ## 目标与非目标 目标(scripts/svc.sh v2 —— 服务模型泛化): 1. **按版本/提交启动各类服务**:agent(后端单二进制,local/dev@sha/release@v 三源已有); static(前端静态服务:`--from dev@sha|local` 构建 frontend dist → 环境内 htdocs,或 `--dir PATH` 直接服务既有目录);postgres(见 2)。 2. **数据库管理**:`svc.sh db create <name> [--port --host --user --password --db --auth-mode --tag]` ——initdb(默认 scram-sha-256)到环境目录,`pg_ctl` 生命周期、`pg_isready` 探活、 `svc.sh db dsn <name> [--reveal]` 打印连接串(默认掩码密码);鉴权/端口/用户/密码/库名 可配并持久化,供 agent 服务 --dsn 引用。 3. **配置分层 + 标签**:`--config FILE`(--env 别名,dotenv)+ CLI 覆盖(优先级: CLI > 配置文件 > 上次启动持久化配置(svc.env exec=) > 默认);`--tag` 可重复, 持久化登记,`list --tag` 过滤。 4. **服务总览**:`svc.sh list|status`(等价)——全部服务表格:名称/类型/状态/pid/地址/ 来源(提交或版本)/标签;`svc.sh <name> status` 单服务详情(版本、数据目录、DSN 等)。 5. **生命周期**:stop/restart 按类型分派——agent/static 走 TERM→KILL;postgres 走 `pg_ctl stop -m fast`(绝不裸杀 postmaster);新增 `svc.sh rm <name> [--purge]` (注销登记,--purge 连数据目录一起删,仅限 runtime/<name>/ 内)。 非目标:不做守护进程/自动拉起/健康巡检(未来可演进二进制);不做 postgres 版本管理 (用系统二进制,版本语义由数据目录+标签承载);static 不做 SPA 路由重写;不管理 容器(全局非容器约束);不动 Releases 仓产物结构。 ## 关键设计决策 - **脚本而非二进制**:Dev 仓是集成父仓(非分发单元),Go 代码都在 modules/*;本功能是 进程编排 + 状态文件,bash + /proc + dotenv 足够、零构建依赖;registry 用 dotenv 而非 JSON 保持无 jq 可解析,将来迁二进制可直接沿用文件格式。 - **服务 = runtime/<name>/ 目录**(沿用上一版布局):登记文件 svc.env(dotenv,chmod 600) 增加 kind(agent|postgres|static,缺省 agent 兼容旧登记)、tags、pidcheck、exec(上次 完整启动参数,裸 start/restart 复用)、kind 特有键;事件流 history.jsonl 不变。 - **安全边界**:只写 runtime/<name>/ 与 runtime/.worktrees/;只停"自己 pidfile + cmdline 标记双校验"的进程;端口冲突预检保留;svc.env 含密码 → 600;DSN 默认不回显 密码。`--from local` 是唯一写主检出构建产物(bin/、node_modules/、dist/,均 gitignore) 的路径,显式文档化;dev@sha/release/static 构建完全在隔离 worktree。 - postgres 事实:宿主机有 linuxbrew postgresql@18 全套工具链(initdb/pg_ctl/pg_isready/ psql),`pg_config --bindir` 可定位;SVC_PG_BIN 可覆盖。 ## 同步记录 | 节点 | sync_base_sha | tested_head_sha | checked_at | |---|---|---|---| | 启动 | a2657bc25f6b43f9b3e1a23cea86e3ebcfd80ecc | a2657bc25f6b43f9b3e1a23cea86e3ebcfd80ecc | 2026-09-30T13:30:43Z | ## 结果与验证(完成后填写) - 结果:svc.sh 升级为服务模型 v2(~1000 行):kind 三类(agent/static/postgres)、标签、 --config 配置文件(--env 别名)、持久化配置复用(svc.env exec=/addr/...)、list 总览、 db create/dsn、rm [--purge];Makefile 增 svc-list 并更新帮助。历史与登记文件格式不变, 旧登记(无 kind=)自动视为 agent。 - 验证(全部在任务工作区 runtime 内真实执行;进程均已停止、目录已清理): - bash -n 通过;错误路径(保留名/非法名/db 缺参/rm 未登记/list --tag 缺值)均明确报错。 - postgres 真实全链路(linuxbrew postgresql@18):db create(initdb scram-sha-256 + 随机/ 指定密码,svc.env 600)→ start(pg_ctl + pg_isready 就绪 + 自动建库)→ psql 写入数据 → restart 后数据仍在 → 错误密码被拒 → db dsn 掩码/--reveal → stop(pg_ctl fast)→ rm --purge。测试中修复:psql 参数错位(-c -c)、record_state/write_static_reg 在重定向 块内读同文件导致 tags 丢失、postgres --version 字段解析。 - static:--dir 直接服务(登记→HTTP 200→restart→stop);dev@sha dry-run 计划正确; release 源明确报"不支持";--dir 不存在报错。 - agent 回归:release@0.1.0 部署(sha256 校验、--tag stable、自定义端口 8791)→ HTTP 200 → 裸 restart 复用 svc.env exec=(同端口同参数)→ list 三类服务混排正确 → status 详情 (版本/标签/来源)→ commits release 标注 [已部署:prod]。 - DSN 组合:`--dsn "$(svc.sh db dsn pg1 --reveal)"` 传入 agent 部署(0.1.0 旧二进制自动 省略 --dsn/--auth 并警告);db dsn stdout 纯净可捕获。 - 旧格式 svc.env(仅 addr/data)→ list 显示 kind=agent;--config 别名生效; history 支持纯数字首参。 - 影响与剩余项:static dev@sha 真实构建未在本轮重跑(worktree 物化+make 构建路径与上一任务 合入的 agent 构建同机制,已验证过);static 深链路由不重写(http.server 行为); svc 提示信息改走 stderr(stdout 只留数据),脚本管道组合更干净。
weichen added 3 commits 2026-09-30 13:45:12 +00:00
Why:
svc.sh only managed agent-system environments; databases, standalone
frontend serving, per-service tags and reusable start configs were out of
scope, and the user asked for a unified service lifecycle on this host.

Evidence:
- Service model v2: kind=agent|static|postgres registered in
  runtime/<name>/svc.env (dotenv, mode 600); legacy entries without kind=
  are adopted as agent.
- postgres: "db create <name> --port/--user/--password/--db/--auth-mode/
  --tag" runs initdb (scram-sha-256, pwfile 0600), start/stop/restart use
  pg_ctl (-m fast, never SIGKILL on postmaster) with pg_isready checks and
  first-start database creation; "db dsn <name> [--reveal]" prints a
  composable DSN (password masked by default). Verified end to end against
  a real postgresql@18 instance: data survives restart, wrong passwords
  rejected, stop/restart clean.
- static: "deploy --kind static --from dev[@sha]|local" builds frontend
  dist into htdocs/ in an isolated worktree, or "--dir PATH" serves an
  existing directory; verified serving HTTP 200, restart, stop, dry-run
  plan, and explicit rejection of release sources.
- agent: unchanged three deploy sources plus --tag; bare start/restart now
  reuses the persisted exec= from svc.env (verified: same custom port and
  args across restart); old binaries lacking --dsn/--auth get those flags
  auto-omitted with a warning.
- "list|status [--tag]" shows NAME/KIND/STATE/PID/ADDR/SOURCE/TAGS for all
  registered services; "<name> status" gives per-kind detail; "rm <name>
  [--purge]" unregisters (and optionally deletes) only runtime/<name>/.
- Fixed during verification: psql arg mangling (-c -c), tags lost because
  record_state read svc.env inside its own redirect block, postgres
  --version field parsing, unbound vars for unregistered names.

Impact:
Same invariants as before: writes stay under runtime/<name>/ and
runtime/.worktrees/ (only --from local also writes main-checkout build
outputs, all gitignored), stops only own pidfile+cmdline-verified
processes, port conflicts reported not seized. Prompt output moved to
stderr so stdout (tables, DSNs) stays pipeable. Makefile gains svc-list.

Refs: .task/feature-svc-services-registry.md(任务卡=PR 描述)
Record the sync checkpoint
ci / test (pull_request) Failing after 1m35s
ba48c35e09
weichen merged commit 33fe7fb394 into main 2026-09-30 13:45:24 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: weichen/Agent-System-Dev#57