Why: establish the authorized task workspace and its initial baseline.
Evidence: preserved precheck receipt in .task/feature-svc-db-config-recover.md; R0=80a518628c526fd6ddece4abeb707ab4bb0b5618.
Impact: task metadata only; the feature workspace starts at 80a518628c.
Refs: .task/feature-svc-db-config-recover.md
Why: the exec= reuse path stripped --dsn into the process environment (G1-7)
and record_state then persisted a DSN-less exec=, while the dbref fallback only
existed in the explicit-rebuild branch - the second bare restart after a
rebind silently dropped the database (SQLite fallback on loopback). Auth
preflight also matched --dsn on the command line only, so env-delivered DSN
with auth=auto was misjudged as unauthenticated.
Evidence: bash -n OK; make test-governance 115 tests OK (new tests/test_svc.py
11 cases; 10/11 fail against the pre-fix script); make test green; make build
OK; isolated real PostgreSQL 18.6 + real binary validation 27/27 (consecutive
restarts/deploy keep binding, psql-verified database identity, DB-down restart
fails without SQLite fallback or config loss, no credential leakage) - all
recorded via make evidence in the task card.
Impact: svc.env gains db=/dbref=/dsn= recovery keys (atomic 0600 writes);
start/restart/deploy/update/db share one resolver; invalid bindings, config
conflicts, mock coexistence and env-DSN-incapable binaries now refuse to
start instead of silently downgrading; legacy exec= DSN migrates idempotently;
docs/svc.md and script help updated.
Refs: task card .task/feature-svc-db-config-recover.md; user-approved plan
(2026-10-11 session message); AGENTS.md evidence gates.
Why: main landed fix-svc-dsn-reuse-dbref (reuse-path dbref restore, env-DSN
aware precheck, DSN_ENV scoping) for the same restart-DSN incident; the
approved recovery plan is its superset and replaces those mechanisms with
resolve_db_config + recoverable svc.env keys + refuse-on-invalid semantics.
Evidence: tests/test_svc_precheck.py ported to the new units (18 cases green,
same scenario matrix; broken-dbref expectation updated to refusal per the
approved plan); tests/test_svc.py 11 cases green; bash -n OK.
Impact: conflict hunks resolved toward the unified resolver; main's source
guard at the script tail restored; agent_listen_rejected kept as a pure
predicate (used by the start precheck and the governance tests).
Refs: main 7acf318 (PR #317); task card .task/feature-svc-db-config-recover.md.
Why: include the current integration baseline before verification.
Evidence: fetched origin/main=36897a1009eb8d3ec63fac8974446bbd4c59bbc0.
Impact: integrate upstream changes without rewriting task history.
Refs: task-sync
Why: include the current integration baseline before verification.
Evidence: fetched origin/main=b1caa7cae13d35ec6e62c883d1f379aee35e35ef.
Impact: integrate upstream changes without rewriting task history.
Refs: task-sync
Why: include the current integration baseline before verification.
Evidence: fetched origin/main=2229d718c7b25941cba1c2464ddd62f9d7466bec.
Impact: integrate upstream changes without rewriting task history.
Refs: task-sync
Why: include the current integration baseline before verification.
Evidence: fetched origin/main=56152323f6179d8f99cfb2b4808573f1d95a63a2.
Impact: integrate upstream changes without rewriting task history.
Refs: task-sync
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.
任务卡:.task/feature-svc-db-config-recover.md(本 PR 描述与任务卡为同一份记录;证据表见卡内)。
Why: 复用 exec= 分支的 G1-7 迁移把 --dsn 剥入进程环境后 record_state 写回不含 DSN 的 exec=,而 dbref 兜底只在重建分支——重新绑定后的第二次裸 restart 丢库(回环下静默回退 SQLite)。认证预检只看命令行 --dsn,env DSN + auth=auto 被误判为未开认证。
改动:svc.env 新增 db=/dbref=/dsn= 可恢复专键(0600 临时文件原子写入);start/restart/deploy/update/db 共用 resolve_db_config 统一解析(改端口/地址/版本不改变数据库选择,重建保留 conffile);绑定失效/直接 DSN 与 dbref 不同库/conffile 不一致/mock 共存/产物不消费 AGENT_SYSTEM_DSN 一律拒绝启动(移除"无法重建 DSN 按无绑定启动"降级);restart/deploy 在停止旧进程前完成静态预检;认证判定对齐后端 AuthEnabled;存量 exec= DSN 幂等迁移(命中实例升级托管绑定)。合并取舍:main 的 PR #317 最小修复被本方案取代,其 18 用例移植到新单元。
Evidence(SELF,CI 于 PR HEAD 复跑 make test+make build 为 GATE):bash -n;make test-governance 133 用例(test_svc.py 11 + 移植 test_svc_precheck.py 18;对修复前脚本 10/11 失败复现);make test 全绿;make build;隔离环境真实 PostgreSQL 18.6 + 真实产物 27/27(连续重启/部署保绑定、psql 直查库身份、库不可用拒启且配置可恢复、无凭据泄露)。详见任务卡证据表(HEAD=ea74479)。
Impact: scripts/svc.sh、tests/test_svc.py、tests/test_svc_precheck.py、docs/svc.md。行为变化:旧产物/mock 与绑定共存从静默降级改为拒绝;坏绑定从"无绑定启动"改为拒绝。dev 运行环境部署验收不在本 PR(另行授权)。
Refs: 用户 2026-10-11 方案消息;main 7acf318(PR #317,被取代);AGENTS.md 证据门禁。