Commit Graph
64 Commits
Author SHA1 Message Date
weichen e08ceebb95 Guard start paths with the ss-free port probe too
ci / test-pg (pull_request) Successful in 1m1s
ci / test (pull_request) Successful in 2m34s
Why: check_port_free consulted port_owner (ss -ltnp) only, so the
/dev/tcp fallback added to port_listening never ran on the start path;
CI (no iproute2) still started onto a thief-held port.

Evidence: no-ss simulation refuses a bound port and passes a free one;
full suite 10/10 and make test-governance rerun recorded on the card;
CI on the new head is authoritative.

Impact: scripts/svc.sh check_port_free only.

Refs: .task/feature-svc-autorecover.md
2026-10-11 21:34:12 +00:00
weichen 9b5ecd57a2 Detect listening ports without ss via /dev/tcp fallback
ci / test-pg (pull_request) Successful in 1m0s
ci / test (pull_request) Failing after 1m6s
Why: the CI runner container has no iproute2, so port_listening went
blind: recover started a service onto a thief-held port and the health
probe hit the thief (HTTP 200), reporting a bogus start success.

Evidence: no-ss PATH simulation shows the fallback detects a bound port
and passes free ports; make test-governance rerun recorded on the task
card; CI on the new head is authoritative.

Impact: scripts/svc.sh port_listening only (ss stays primary when
present).

Refs: .task/feature-svc-autorecover.md
2026-10-11 21:12:16 +00:00
weichen 59109e589c Merge authoritative main into the task branch
Why: include the current integration baseline before verification.

Evidence: fetched origin/main=acc8bf124c04b89ed05093467ebce865934bdddc.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-11 20:21:43 +00:00
weichen eda942523c Add svc auto-recovery: autostart desired-state, recover, watchdog
Why: svc services are bare nohup'd processes with persisted registration
but no supervision -- a crash, an OOM kill, or a reboot left them dead
until manual restart (2026-10-11 outage: dev service lost, runtime/ also
wiped by hand, nothing brought services back).

Evidence: tests/test_svc_recover.py 10 cases green (start records
autostart, stop clears it incl. dead-process stop, SIGKILL then recover
revives with persisted exec=, lock-held skips, port-stolen fails with
recover fail event, watchdog unit text via --print); make test-governance
146/146 OK locally; real-machine watchdog install + kill -9 revival to be
recorded on the task card.

Impact: svc.sh gains autostart key in svc.env, `recover [name]
[--quiet]` (postgres-first, per-service .start.lock, recover history
events), `watchdog install|remove|status` (systemd user timer, cron
fallback hint), lifecycle lock across start/stop/restart/deploy/update;
spawned services no longer inherit the lock fd (9>&-), and lock release
no longer clobbers script stderr. Makefile adds svc-recover/svc-watchdog;
docs/svc.md documents semantics and boundaries.

Refs: task card .task/feature-svc-autorecover.md; docs/svc.md 6.5/6.6;
parallel planning card feature/service-restart-recovery-plan (same
problem space, plan-stage).
2026-10-11 20:20:27 +00:00
weichen e67f026827 Build the seeding CLI from the RDM-pinned backend
Why: task-sync advanced the Dev backend gitlink past the RDM pin; a newer-schema user-create CLI migrates the fresh store beyond what the RDM binary (schema ceiling of its pin) can open.

Evidence: reproduce on 20261011-180439 run (v25 store vs v24 binary); rerun green recorded after this change.

Impact: scripts/e2e.sh only; seeding and serving now share one base version.
2026-10-11 18:05:30 +00:00
weichen 46e5e3a477 Build the RDM E2E binary offline from local objects
Why: git submodule clone over the flaky Gitea SSH endpoint hangs the whole run; local archive + pinned-checkout snapshot removes the network dependency and cuts the build stage to seconds.

Evidence: this exact tree ran scripts/e2e.sh to green (4 passed) twice, recorded in the task card.

Impact: scripts/e2e.sh only; behavior unchanged when the network is healthy.
2026-10-11 18:02:53 +00:00
weichen fbd583fc65 Add E2E launcher for U4 audit acceptance and bump frontend pin
Why: U4 acceptance needs a reproducible real-browser run: build the
RDM binary from its origin/main, seed projects/ingest via the command
API, serve with auth on, and drive Playwright against vite preview.

Evidence: scripts/e2e.sh --seed-only smoke (in progress this task);
frontend pin points at the Playwright harness commit.

Impact: dev tooling only (.tmp artifacts ignored; no runtime changes).

Refs: task feature/rdm-e2e-acceptance; frontend feature branch of
the same name.
2026-10-11 17:58:12 +00:00
weichen 4b98e25687 Seed settings with an auto-minted temporary key when auth is on
Why: seed_settings PUTs /api/settings/user without credentials, so under the PG tier's always-on auth the seed always 401s and model config silently never lands (reproduced on the dev instance 2026-10-11; settings had to be written by hand).
Evidence: make test-governance && make test exit=0 (receipt 8ffc3a89); tests/test_svc.py adds three stub-based cases - auth-on seeds with a Bearer header and create/revoke around the PUT, --seed-owner skips account lookup, auth-off stays credential-free; 14/14 svc tests green.
Impact: deployments that pass SVC_MODEL_*/SVC_TAVILY_KEYS now seed reliably regardless of auth mode; a temporary apikey (name=svc-seed) is minted for the first admin (or --seed-owner/SVC_SEED_OWNER) and revoked right after; auth-off path unchanged.
Refs: task card feature-svc-seed-auth.
2026-10-11 14:58:36 +00:00
weichen 6e4ebae2f6 Merge origin/main: supersede the PR #317 minimal fix with the unified resolver
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.
2026-10-11 09:21:27 +00:00
weichen 3b8fef7fad Recover svc.sh database config across restarts and refuse on invalid binding
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.
2026-10-11 09:16:54 +00:00
weichen 7acf3186ca Align the svc.sh startup precheck with the binary auth semantics and keep the reused DSN
Why: G1-7 moved the DSN into AGENT_SYSTEM_DSN, but the precheck only read
the arg string, so a non-loopback restart with auth auto was wrongly
rejected (2026-10-10 dev incident); the reuse path no longer restored the
dbref-bound DSN and would silently fall back to SQLite; and DSN_ENV leaked
across same-process starts (update --all) into other services' env.
Evidence: tests/test_svc_precheck.py 19 cases green (auth matrix vs
config.go AuthEnabled, reuse migration/dbref restore, scope isolation);
full governance suite 123 green; incident-scenario replay allowed + DSN
carried. Recorded via make evidence.
Impact: scripts/svc.sh precheck and reuse-start DSN handling only; no
binary change, no persistence-format change.
Refs: .task/fix-svc-dsn-reuse-dbref.md; config.go AuthEnabled (on || (not
off && DSN non-empty), env DSN counts).
2026-10-11 02:10:21 +00:00
weichen a6d434e432 Pass the PG DSN via environment instead of the command line (G1-7)
ci / test (pull_request) Successful in 2m18s
Why: the plan section 3.4 observed the local dev service carrying the
credential-bearing DSN as a serve --dsn argument, visible to any
process on the host (ps / /proc/<pid>/cmdline) — including scripts
generated by agents. The base config layer already supports
AGENT_SYSTEM_DSN, so the launcher can move the secret out of the
argument vector without touching the binary.

Evidence: bash -n clean; make test-governance 104/104 green; an
end-to-end probe with a stub binary and a legacy exec= carrying
--dsn ...secret... shows the migration stripping the flag
(MIGRATED:yes), the process args free of the secret
(NO-LEAK-IN-CMDLINE), and AGENT_SYSTEM_DSN present in the process
environment (DSN_IN_ENV:yes). New/rebuilt launches never put the DSN
in argv; legacy persisted configs are migrated on first reuse.

Impact: scripts/svc.sh only — rebuild path sets DSN_ENV instead of
--dsn, reuse path strips --dsn from stored exec= once and logs the
migration, launch injects AGENT_SYSTEM_DSN alongside the existing
guard vars. CLI --dsn still wins inside the binary (config
precedence), so manual invocations are unchanged.

Refs: plan G1-7 (line 356) and section 3.4 (2026-10-09 ps
observation); backend config AGENT_SYSTEM_DSN.
2026-10-10 02:39:19 +00:00
weichen 761c2954dc Merge authoritative main into the task branch
Why: include the current integration baseline before verification.

Evidence: fetched origin/main=878e0e7ceba3bb6b78c36c5113eacc846a7f017b.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
2026-10-07 12:35:08 +00:00
weichen 2806371b52 Take the backend intent slow lane and the I2 port pins (I2 WP3)
Why: backend #83 merged the slow-lane wiring (intentsem scorer/
generator, gate SetSemantic/SetGenerator, settings flags default off);
the Dev pins and boundary rules must move with it.
Evidence: backend CI green on 9d29371; check-pins consistent
(agent-intent 343b1e6 across Dev and the backend nested copy);
lint-boundaries registers intentsem as an agent-intent adapter and the
architecture baseline gains backend/app->backend/intentsem.
Impact: product behavior unchanged by default; the two
runtime.intent* flags opt into the slow lane.
Refs: Agent-System-Backend#83, I2 increment 3
2026-10-07 11:34:52 +00:00
weichen 908504e8b5 Connect long-term plans to task completion
Why: preserve project direction across tasks and require grounded next-task recommendations.

Evidence: the generated task-card regression fails before the template update and passes afterward; original SELF receipts are in the task card.

Impact: document the planning entrypoint and extend task records without granting new-task execution rights.

Refs: .task/feature-goal-continuity.md; policy/delivery.md
2026-10-07 06:10:51 +00:00
weichen 14c55def98 Preserve delivery references after task archival
Why: archived task cards change directory and must retain an unambiguous policy reference.

Evidence: review finding 1, focused red-green proof and 104 passing governance tests are preserved in the task card.

Impact: use a repository-root text reference; record the completed review and its resolved finding.

Refs: .task/feature-iterative-delivery.md; .task/reviews/iterative-delivery.json
2026-10-07 03:10:09 +00:00
weichen 1ac79c2a90 Define iterative delivery with explicit stage reviews
Why: make requirements, experiments and implementation revisions reviewable while retaining bounded continuous authorization.

Evidence: task-card SELF receipts include expected red regressions and 104 passing governance checks; full candidate verification follows.

Impact: add project delivery policy and generated task fields; make post-merge reminders read-only.

Refs: .task/feature-iterative-delivery.md; policy/delivery.md
2026-10-07 02:53:20 +00:00
weichen a5f0ca107d Only count remote-unreachable commits as local work in finish guard
ci / test (pull_request) Successful in 2m19s
Why: 本地 main 停在 origin/main 顶端(克隆默认态)在 pin 为 feature 顶端时不在 pin
历史内,--branches 直判仍会误阻(本 worktree 自身收尾实测踩到)。
Evidence: 第五例回归(本地默认分支+克隆 reflog 不阻)全绿;五例套件+全套治理回归
GOVERNANCE-SUITE-OK;worktree 实际 finish 通过即端到端自证。
Impact: local_work_outside 候选提交先过 --not --remotes 过滤(远端可达即已保全);
stash 仍恒算本地独有。
2026-10-05 15:05:54 +00:00
weichen 91d25a3ed1 Fix two finish-guard false positives: IDE locks and remote-only refs
ci / test (pull_request) Successful in 2m21s
Why: 2026-10-05 两次实测踩到——①rglob("*.lock") 把 .git/cursor/ IDE 产物当 Git 锁
(五天陈锁阻断 worktree 回收);②pinned-history 用 --all --reflog 把 refs/remotes
计入,pin 在 feature 顶端的子仓永远无法 finish(被迫删远端引用+清 reflog 损害现场)。
Evidence: FinishGuardFixTests 四例全绿(误报修复+真实锁仍拦+独有提交仍保);
全套治理回归 91 例 OK;make test 全链证据入卡。
Impact: 仅 finish 模式两处判定;IDE 产物与远端引用不再误伤,本地独有工作保全语义不变。
Refs: 本仓 governance 收尾实录(EXT-1 与 governance-reliability 两轮)。
2026-10-05 15:00:20 +00:00
weichen c1fdf0141c Merge current main while preserving governance repairs
Why: main advanced with merged-task-name and legacy evidence guards during this task.

Evidence: SELF 44 lifecycle regressions pass after resolving both hunks; independent review repairs are recorded in the task card.

Impact: retains both task-start protections and the stronger JSON/legacy receipt reader, without rewriting either branch history.

Refs: Dev PR #211 and #212; .task/feature-governance-reliability.md
2026-10-05 13:11:50 +00:00
weichen b84667a697 Close review gaps in cleanup and evidence handling
Why: independent review found shared submodule metadata risk, quoted header leakage, stale JSON receipt blindness and missing abandon coverage.

Evidence: SELF 92 governance regressions pass; the original review receipt and replay output are recorded in the task card.

Impact: preserves external component worktrees, handles both evidence formats and adds targeted failure-path coverage; no product behavior changes.

Refs: .task/feature-governance-reliability.md; .task/reviews/governance-reliability.json
2026-10-05 13:07:10 +00:00
weichen 8af945a1d5 Make development gates preserve work and verifiable evidence
Why: cleanup, component synchronization, receipt recording and credential handling could contradict the documented development boundaries.

Evidence: SELF 75 isolated governance tests and source checks are captured in .task/feature-governance-reliability.md; combination and CI verification follow.

Impact: hardens local task and CI tooling, aligns policy and component documentation, and adds continuous regression tests without changing product behavior.

Refs: .task/feature-governance-reliability.md; policy/governance.md; policy/platform-admission.md
2026-10-05 12:36:02 +00:00
weichen 1e0508e8a7 Skip non-hex cells in the sync evidence scan
Why: 证据命令含 || 时 evidence.sh 把表格单元格里的管道转义为 \|\|,cmd_sync 按裸 |
切行把碎片当 HEAD 传给 git diff,fatal 128 在 set -e 下杀死 sync(本卡功能负例行实测触发,
task-sync 门禁被卡死)。
Evidence: bash -n 通过;含转义管道行的本卡上 bash scripts/task.sh sync 正常完成(WARN 照发、
exit 0);修复后 make test 全链重跑。
Impact: 仅 cmd_sync 证据扫描加十六进制过滤;WARN 语义不变。
Refs: 本卡 12:30-12:32 五次 sync 中毒复现记录。
2026-10-05 12:33:06 +00:00
weichen e58035a8e4 Guard task-start against reusing a merged branch name
Why: 合入后再 task-start 同名分支会从新 main 长出第二段历史并覆盖已合入任务卡
(2026-10-05 EXT-1 复核轮实测,两轮证据差点丢失);原校验只看本地分支能否创建。
Evidence: bash -n 通过;功能负例——start feature/ext-1-inproc-handler 被拒且无
worktree 副作用;make test 全链 exit 0;task-sync 基线 43d33aa。
Impact: 仅 scripts/task.sh cmd_start 增加已合入同名分支检查,其余子命令行为不变。
Refs: EXT-1 任务卡复核轮记录(.task/archive/feature-ext-1-inproc-handler.md)。
2026-10-05 12:30:25 +00:00
weichen 0123cec450 Sharpen the sync evidence warning to non-card changes only
Why: evidence rows are written before their containing card commit, so a naive
HEAD-diff would flag every task's evidence as stale and train people to ignore
the warning.

Evidence: bash -n clean; the live task-sync for this task exercises the new
path (warning fires only when a non-.task diff follows an evidence row's HEAD).

Impact: scripts/task.sh cmd_sync now excludes .task from the staleness diff;
AGENTS.md wording aligned (three-output evidence via make evidence).

Refs: task card evidence table; guidelines verification.md tool-written rule.
2026-10-05 10:51:39 +00:00
weichen efa701279f Fix evidence CMD quoting and record first tool self-tests
Why: the make-variable pass-through re-quoted CMD and broke any command
containing quotes (caught by the redaction self-test before it could run).

Evidence: redaction self-test now records 'token <redacted> hello' with quoting
intact (row sha256 aae6a895); negative 'false' case earlier recorded exit=1
row and propagated rc — both in the task card evidence table.

Impact: CMD now travels via environment (CMD="..." make evidence); SRC/TAIL
stay make variables; usage strings updated in Makefile/AGENTS.md/task.sh
template comment.

Refs: task card evidence table; guidelines draft.10 tool-written-evidence rule.
2026-10-05 10:48:31 +00:00
weichen ba83a17c11 Add evidence gates: facts registry, evidence tooling, and precheck checks
Why: declarations were passing as capability; hand-transcribed outputs flowed
through cards and PR bodies as if they were execution evidence, and stale
external facts (e.g. the dead git-panel host) kept being trusted until burned.

Evidence: guidelines draft.10 (PR Development-Guidelines#4, merged af199ee)
pinned here; policy/facts.md F1-F4 each re-verified on 2026-10-05 before
registration (endpoint version, token HTTP 200 via header only, SSH ls-remote,
dead-host negative probe); scripts syntax-checked (bash -n); tool self-tests
and make test recorded in the task card via the new make evidence.

Impact: new AGENTS.md section (SELF/REPLAY/GATE, tool-written evidence,
replay-on-review, zero-trust facts, honest-empty); make evidence/facts-verify;
precheck gains [hooks]/[facts], task-sync gains stale-evidence-HEAD warning;
task-start cards now embed the evidence table; gitlink advances to draft.10.

Refs: task card .task/feature-evidence-driven-gates.md; guidelines CHANGELOG
0.1.0-draft.10.
2026-10-05 10:47:27 +00:00
weichen 421ee87d04 Normalize the rebuild args comparison to stop spurious drop warnings
Why: adjust_args_for_bin strips the leading space of its return while the
rebuilt args keep it, so every rebuild carrying --dsn/--auth compared
unequal and warned that the legacy binary had the flags dropped even when
nothing was dropped — misleading during incident triage.

Evidence: bash -n clean; against the real dev binary the normalized
comparison reports no drop and the flags survive intact; make test green.

Impact: warning now fires only when flags are actually filtered; no
behavioral change to start/deploy.

Refs: PR #188
2026-10-05 02:23:32 +00:00
weichen 4215107126 Keep the DB binding and fail closed on svc.sh start rebuilds
Why: the 2026-10-05 dev outage — a restart with an explicit --addr rebuilt
the start args, and the rebuild branch dropped the persisted --dsn for the
dev env, so the binary resolved auth=auto to off on 0.0.0.0 and the new
listen guard refused to spawn; record_state then persisted the broken exec=
before the health probe, so bare starts kept failing.

Evidence: bash -n clean; sandbox registry with stub binaries — dbref DSN is
re-derived on rebuild (priority CLI > env > dbref), the pre-flight blocks
non-loopback without auth with actionable remedies, immediate-death starts
leave the previous exec= intact, and DSN masking covers all start-path log
lines; make test green.

Impact: dev/prod agent starts keep their DB binding across explicit-arg
rebuilds; failed starts no longer corrupt the registry; static/pg paths get
the same persist-after-probe ordering (pg already had it); no change to
deploy materialization or the binary guard semantics.

Refs: backend 8eda35f (listen guard), runtime/dev history.jsonl 01:23 fail
2026-10-05 02:16:20 +00:00
weichenandCursor f8e06090e6 Pin the SillyTavern borrow across the linked repositories
Why: The research record, HTML cleaning, listen guard, secret store, and context controls land together, and the parent pointers have to name those commits.
Evidence: Child commits are core bd63223, agent-native 3a110a7, ui d76a8e6, frontend 36b92ed, documents f3f823e, backend 42cca8f. svc.sh forwards the listen switches and info prints them.
Impact: A reverse proxy or a LAN hostname needs allowedHosts or an unauthenticated host check returns 403. Startup moves raw API keys into the secret table after a settings snapshot.
Refs: .task/feature-sillytavern-review.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-04 18:21:17 +00:00
weichen ecfed7be31 Add service config-file switching with schema validation to svc.sh
Why: beyond database binding, services needed a way to switch the JSON config
file they run with and have the new config take effect promptly; hand-editing
exec= risks restarting a service into an invalid config.

Evidence: in the task worktree with a real agent binary -- a config with an
unknown key is rejected by the binary's strict schema check before any state
change; a valid file binds via --config in exec= + conffile= (survives
record_state rewrites), restarts the running service, and the config's dsn
verifiably drives the process (wrong-password variant failed PG auth in the
log; correct variant connected and created 21 tables); editing the file and
re-running 'config <same file>' re-validates and restarts (pid changes);
'--clear' removes both the flag and conffile; db and config coexist in exec=;
view mode shows masked JSON content plus 'config explain' effective values
with masked dsn; list DB column also resolves dsns that live only inside the
config file. Full log in the task card.

Impact: new service-level action 'svc.sh <name> config [file | --clear]
[--no-restart]' for agent services; config-file content snapshots (masked,
--reveal to show) in info; a config-file line in status; conffile persisted
in svc.env. No agent binary changes.

Refs: task card .task/feature-svc-db-bind.md (same doc as PR #182);
docs/svc.md sections 2/4.5/4.6/6/10.1
2026-10-04 13:42:51 +00:00
weichen 843495e0d0 Add per-service database binding and fix single-dash flag detection in svc.sh
Why: info showed services and postgres instances but no service-to-database
correspondence, and switching an agent service to another database required
redeploying with a hand-built DSN. While wiring this up, adjust_args_for_bin
was found matching Go flag help with '--dsn' although Go prints '-dsn', so
deploy-built --dsn/--auth args were silently dropped on current binaries.

Evidence: full E2E in the task worktree with a real agent binary and a real
PostgreSQL 18 instance -- 't-app db bpg' persisted exec=/dbref, auto-restarted
(dbref survives record_state rewrites), and the agent created 21 tables in the
bound database; 'db bpg --db t2' auto-created and switched databases (21
tables in t2); '--clear' returned the service to embedded SQLite; --no-restart
and error paths behave; list gains a DB column, status a database line, info a
reverse bound-services line; legacy deployments without dbref resolve by DSN
host:port; single-dash detection proven with positive and negative cases;
regressions list/db dsn/db ls/info/history/--help pass; make test exit 0.
Full log in the task card.

Impact: new service-level action 'svc.sh <name> db [pg [--db X] | --clear]
[--no-restart]' for agent services (bind/switch/unbind/view), DB column in
list, binding lines in status/info, dbref persisted in svc.env, auto database
creation when the instance runs, and the adjust_args_for_bin fix restoring
deploy --dsn/--auth on current binaries. No agent binary changes.

Refs: task card .task/feature-svc-db-bind.md (same doc as the PR); docs/svc.md
sections 4.5/6.1/6.2/10.1
2026-10-04 13:30:50 +00:00
weichen 106ef07ef0 Add read-only svc.sh info report for services, databases, and config snapshots
Why: svc.sh could show a service table (list), per-instance DB names one at a
time (db ls), and per-service status, but had no single view answering "what
is running, which databases exist, and what is configured" -- the questions
asked when inspecting or handing over a machine.

Evidence: exercised in the task worktree runtime -- empty-state report; fake
agent/static/postgres registrations proving masking (exec DSN password,
password=, SVC_TAVILY_KEYS -> ***, non-secret values verbatim; --reveal shows
plaintext); a real postgres instance (db create r-pg --port 18901, start,
extra orders db, one backup) whose info section lists inner databases with
sizes, pgdata size and backup stats; regressions list/history/--help/help
lifecycle/make svc-info; info stdout carries the full report (stderr 0 bytes)
so it can be redirected as a snapshot. Full log in the task card.

Impact: new read-only `scripts/svc.sh info [name] [--tag T] [--reveal]`
command (also `make svc-info`): service table + running summary, postgres
instances incl. inner databases, per-service svc.env content snapshots plus
global .svc.env / --config / exported SVC_* vars, and recent events. Secrets
are masked by default. No deploy/lifecycle/db-ops behavior changes; `info`
becomes a reserved service name; docs/svc.md gains section 6.2 (former
6.2-6.4 shifted to 6.3-6.5).

Refs: task card .task/feature-svc-info.md (same doc as the PR); docs/svc.md
2026-10-04 12:42:49 +00:00
weichenandCursor 937152a563 Add an architecture edge ratchet and waiting-state tokens
Why: New cross-layer imports and unused exports could land unnoticed, and confirm-waiting reused the success color.
Evidence: bash scripts/lint-boundaries.sh passed, including a probe that a new edge fails. Both design-guard tests passed. Knip counts stay at the baselines.
Impact: make test-boundaries now checks architecture edges. Frontend and ui test targets also run the knip ratchet.
Refs: feature/architecture-baseline
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 16:02:57 +00:00
weichenandCursor 10bff94a6a Pin the D1 heads and cover the adapter modules
Why: Dev has to test the split modules and refuse a core import of a sibling library.
Evidence: bash scripts/lint-boundaries.sh printed boundaries ok. Full make test follows on this pin.
Impact: test-libs runs the intent, native, sqlite, and command modules. The sibling allowlist is empty.
Refs: D1
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 13:47:02 +00:00
weichenandCursor 88d5787f29 Compare pin trees offline and archive finished task cards
ci / test (pull_request) Failing after 1m0s
Why: Merge commits share a tree with the pinned feature commit, the import ratchet downloaded modules during CI, and task sync wrote the checkpoint onto the wrong card.
Evidence: check-pins accepts 6c0f1e8 (same tree as Backend squad 8e987bf) and rejects empty-tree 8db069d; both objects stayed local. An empty GOMODCACHE run of lint-boundaries matches the cached go list, 14 pairs. bash -n scripts/task.sh.
Impact: make pin no longer checks out Backend nested core or agent-command, and a failing pin check does not fail the target. task sync writes the branch card or warns. precheck reports completed-but-unarchived cards and card-close branches older than 24 hours.
Refs: feature/agent-stack-r0-r1
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 10:19:06 +00:00
weichenandCursor 978bf8bdae Check nested library pins and test the three agent libraries
Why: Dev could ship a combination whose nested gitlinks differed from the top-level pins, and make test never ran the three agent libraries.
Evidence: A go.work was measured and not adopted: workspace MVS selected newer golang.org/x crypto, exp, net, term, and text than backend with GOWORK=off. check-pins passes on the new pins and fails when backend's squad pin is 5cbac00.
Impact: make test adds pin checks and GOWORK=off vet/test for intent, native, and squad. make build still compiles inside backend; the pin check requires those gitlinks to match Dev.
Refs: R0
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-03 02:10:00 +00:00
weichenandCursor 09964e522b Pin the extension roadmap and downstream spike
Why: Downstream products need a published extension surface, contract checks, and a sample plugin that does not modify the base.
Evidence: scripts/lint-boundaries.sh printed boundaries ok. examples/downstream-rdm go test passed. Submodule pointers record the core, documents, backend, ui, and frontend commits for this roadmap.
Impact: make test runs the boundary lint first. make plugin-new scaffolds a declaration plugin. Version tags and remote downstream repositories are not created.
Refs: .task/feature-base-extension-roadmap.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-01 10:35:15 +00:00
weichen a42fff69e4 Deploy svc updates from an isolated remote source clone
Why: svc.sh update skipped services with a local@<sha> source whenever the
main checkout was dirty, and bare deploy built the current workspace. The
owner requires updates/deploys to be independent of the working tree
state, defaulting to the latest remote commit built outside the checkout.

Evidence: bash -n passes; commits dev lists from the source clone; bare
deploy --dry-run plans dev@<origin/main>; end-to-end "svc.sh update
svc-selftest" with a dirty tree updated a local@d64742c service to
dev@0be23f9 (built in runtime/.worktrees from
~/.cache/agent-system-svc/src, started healthy), then stopped and purged.
Full make test output recorded on the task card.

Impact: deploy now defaults to dev@<origin/main> resolved in the
script-owned clone (SVC_SRC_DIR, default ~/.cache/agent-system-svc/src);
--from local stays the only workspace-dependent source; update no longer
pulls the main checkout - local@/dev@ services redeploy from remote
latest, ahead/diverged/missing-on-remote still decline to act.
docs/svc.md and in-script help updated to match.

Refs: .task/svc-remote-source.md
2026-09-30 18:39:25 +00:00
weichen aeb9a6a8ea Harden task.sh materialization check and close push retry
Why: two recurring papercuts from 2026-09-30 sessions — (1) task-start treated a zero-exit submodule update as complete, but a worktree could still carry 12 drifted/uninitialized nested submodules that only surfaced at build time; (2) close ran a single git push, so a tunnel hiccup left the card-close branch unpushed and the auto-PR never created (hand-patched twice that day).
Evidence: bash -n clean; smoke start of a throwaway task measured nested drift count explicitly and abandon-path finish recycled worktree and branch cleanly (both PASS); fresh-clone commit identity probe also PASS after setting the global identity outside this repo.
Impact: scripts/task.sh cmd_start (+3-line status check) and cmd_close (one retry on push); no interface change.
Refs: .task/fix-followup-hardening.md
2026-09-30 17:11:40 +00:00
weichen 888aa9471c Retry card-close PR creation instead of failing silently
Why: cmd_close posted the PR with a single curl wrapped in
2>/dev/null || true, so any transient TLS/timeout on the git-home
HTTPS surface left the card-close branch pushed with no PR and no
diagnostics; this hit three times on 2026-09-30 and each needed a
manual API call to recover.

Evidence: bash -n clean; stub-server harness running the block
verbatim (sed-extracted from this file, executed inside the worktree
branch context): ok mode recovers the PR URL on first POST; exists
mode (POST always 500) retries 4x with visible stderr then recovers
the pre-existing open PR via GET ?state=open matching head ref;
fail mode against the retired git-panel host shows four visible
retry notices and falls through to the existing [next] hint.

Impact: scripts/task.sh cmd_close only; precheck/start/sync/finish
untouched; card-close merge authority unchanged (owner merges).
post-merge hook and task-finish auto-close inherit the fix through
the same function.

Refs: task card fix-close-pr-retry
2026-09-30 16:47:53 +00:00
weichen b46d890529 Merge remote-tracking branch 'origin/main' into fix/task-finish-close-followups 2026-09-30 16:01:38 +00:00
weichen c61920a8dc Stop task-finish from uninitializing shared submodule config
Why: cmd_finish ran git submodule deinit --all, but submodule.<name>.url entries live in the shared .git/config — finishing any task silently marked every other checkout and worktree uninitialized (observed twice on 2026-09-30: main checkout uninit=12 after each finish; a parallel session hit it minutes before this fix landed). The deinit serves no purpose: worktree removal with gitlinks is refused regardless, so cleanup already goes through rm -rf + prune. Also aligns AGENTS.md with observed hook behavior (post-merge fires on ff-only pulls too, and its inline close cannot see cards merged remotely until they are pulled), and ignores the ZCode-generated .zcodeignore that tripped the BUSY gate in every session.
Evidence: bash -n clean; abandon-path smoke of the patched script — start + FORCE_ABANDON=1 finish of a throwaway branch left shared submodule url config at 12 entries (pre-fix: 0), main checkout submodule status uninit=0, smoke worktree and branch fully recycled; the smoke close also backfilled a parallel session card left open (gitea-access-facts) via a card-close branch, proving the fallback path.
Impact: scripts/task.sh cmd_finish only (removes one line, updates comment), AGENTS.md card-close paragraph, .gitignore one entry. No product or gitlink change; make test not applicable (repo-level tooling/docs only). web_base default fix intentionally withdrawn from this PR — landed via parallel PR #73.
Refs: .task/fix-task-finish-close-followups.md
2026-09-30 16:00:31 +00:00
weichen 80cddd82d4 Fix stale Gitea host and record access facts in AGENTS.md
Why: the TASK_CARD_WEB_BASE default in scripts/task.sh still pointed at
git-panel.u1680832.nyat.app:30319, which now fails the TLS handshake
(curl exit 35), breaking card-close PR links and API calls; agents also
kept rediscovering hosts and credential locations from scratch each
session.

Evidence: curl https://git-panel...:30319/api/v1/version -> exit 35; curl
https://git-home...:30319/api/v1/version with token from ~/.secrets/gitea
-> {"version":"1.27.3"}; ssh -p 31411 git@git-ssh... -> 'Hi there,
weichen!' with key ~/.ssh/home_gitea (ED25519, fingerprint
SHA256:GYXaOXIMeloQ1fKSfdJ/ndgPQzs/Ix7Hk62ekfkfQ20, key name GMKtec).

Impact: task.sh default web base now resolves to the live host; AGENTS.md
gains a Gitea access-facts section recording hosts plus credential
locations only (no secret values, per baseline hard boundary 2). Follow-up
PRs propagate the same section to the other project repos.

Refs: task card feature-gitea-access-facts
2026-09-30 15:45:22 +00:00
weichen aecaa52e6b Merge remote-tracking branch 'origin/main' into feature/task-start-rootfix 2026-09-30 15:28:27 +00:00
weichen d3893609b7 Fix task worktree path derivation to anchor on the main checkout
Why: cmd_start derived the worktree location from $PWD, so running task.sh start from a repository subdirectory (or inside a task worktree) placed the new worktree at the wrong spot — e.g. scripts-wt-<slug> nested inside the repo.
Evidence: bash -n clean; functional smoke of the patched script from both the main checkout scripts/ subdir and the repo root created ../Agent-System-Dev-wt-<slug> as a sibling of the main checkout (paths asserted; pre-fix subdir run would nest inside the repo); git rev-parse --git-common-dir resolves to the main checkout from both locations (relative ../.git vs absolute).
Impact: scripts/task.sh cmd_start only; from the main checkout root the derived path is identical to before; new worktrees now always land as siblings of the main checkout regardless of invocation directory.
Refs: .task/feature-task-start-rootfix.md
2026-09-30 15:28:14 +00:00
weichen ac8db54ecb Add svc.sh update command: auto-detect repo advances and refresh services
Why:
After the repository moves forward, updating a running service meant
manually figuring out the new commit, rebuilding and redeploying by hand;
the user asked for the tool to detect and update automatically.

Evidence:
- "update [name...] [--check] [--all] [--no-fetch]": fetches origin,
  compares each service's registered source against the latest (Dev repo
  origin/main for local@/dev@ sources, newest Releases version for
  release@), prints a per-service table (current / latest / state), and
  without --check refreshes outdated running services by reusing the full
  deploy pipeline (stop → build/verify → start → health check; persisted
  exec= config and tags survive; update events appended to history).
- local@ services: auto git pull --ff-only origin main + make sync before
  rebuilding, guarded three ways (current branch == main, clean worktree,
  ff-only) — dirty trees or non-main branches are skipped with a warning,
  never touching uncommitted work.
- dev@ sources go straight to the remote main commit via an isolated
  worktree; release@ sources deploy the newest Releases version with
  sha256 verification; postgres and static --dir services are reported as
  not applicable; sources that diverged from or lead the remote are never
  force-updated.
- Verified end to end with five test services: dev@73b2802 → dev@ffda6d3
  (real isolated build, HTTP 200, tag/port preserved, worktree recycled),
  non-main-branch skip, stopped-service warning vs --all, release
  sha256-verified update, --check read-only (svc.env checksums unchanged),
  unregistered name exits 2.
- Fixed en route: a latent bug from the v2 refactor — materialize_dev_commit
  leaked submodule/make stdout into the captured worktree path, breaking
  every real dev@sha deploy since (cp: File name too long); build output
  now goes to stderr. Also fixed an unbound-variable crash in the update
  loop (local statement self-reference under set -u).

Impact:
New read-mostly operational command; no behavior change to existing
commands except dev@sha deploys now actually working end to end.
Makefile gains svc-update; --help and docs/svc.md document the command.

Refs: .task/feature-svc-auto-update.md(任务卡=PR 描述)
2026-09-30 15:22:33 +00:00
weichen 2c7f55bfe8 Document svc.sh comprehensively and layer its help system
Why:
svc.sh grew into a three-kind service manager with database operations,
but its only documentation was a flat --help wall of text; the user asked
for a complete usage document and a better help experience.

Evidence:
- docs/svc.md: 14-section manual (prerequisites, quick start, concepts
  and directory layout, per-command reference for service/global/db
  commands, deploy sources, database operations handbook, configuration
  layering, registry fields and event types, safety boundaries, exit
  codes, troubleshooting table, recipe index) — every claim cross-checked
  against the implementation from the previous two rounds.
- Help layering: no-args and -h print a one-screen overview; --help
  renders the header comment reorganized into 7 labeled sections; the new
  "help [topic]" command deep-dives eight topics (model, deploy,
  lifecycle, db, dbops, config, examples, safety); usage errors now show
  the short overview plus a pointer to --help / help / docs/svc.md.
  All topics verified to render; unknown topic exits 2.
- No runtime behavior changed: end-to-end db lifecycle regression
  (create → start → backup → status → stop → rm --purge) passes after the
  refactor.
- Makefile help and README's documentation section point to docs/svc.md.

Impact:
Documentation-only plus display-layer changes; command semantics,
exit codes and file formats are untouched. Maintenance note: behavior
changes must now update both --help and docs/svc.md.

Refs: .task/feature-svc-docs-help.md(任务卡=PR 描述)
2026-09-30 14:29:39 +00:00
weichen 69871136e5 Add db ops to svc.sh: port change, backup, restore, clone, cross-instance copy
Why:
The service manager could create and run postgres instances but had no
way to retarget a port explicitly, back data up, clone an instance to
another port, or move a database between instances — the user asked for
exactly these operations.

Evidence:
- "set <name> [--port N] [--host H] [--apply] [--tag T...]": explicit
  registration change; running postgres requires --apply (stop → rewrite
  registration → start); port availability checked against both
  registrations and live listeners. Verified: 8890→8895 with data intact
  and DSN updated, old port freed; refusal without --apply.
- "db backup <name> [--db X] [--out F]": pg_dump -Fc into
  runtime/<name>/backups/ (0600) with pg_restore --list self-check;
  "db backups" lists them.
- "db restore <name> --file F [--db X] [--force]": restores into a new db
  or refuses on a non-empty target unless --force (drop with FORCE +
  recreate + restore), reporting table counts afterwards. Verified all
  three paths.
- "db clone <src> <dst> [--port P] [--password PW] [--tag] [--online]":
  default physical clone (brief source stop, cp -a of pgdata minus
  postmaster files, new registration, source restarted on its own port);
  --online copies via dump/restore without stopping the source (verified
  source pid unchanged). Clone lands on the requested or derived port.
- "db copy <src> <dst> [--db X] [--force]": single-database logical move
  between two running instances with the same non-empty-target guard.
  "db ls <name>" lists databases.
- Fixed during verification: clone/copy leaked the CLI --port into the
  source restart path (source briefly came up on the clone's port); the
  address overrides are now cleared inside those commands.

Impact:
All operations stay inside runtime/<name>/, append to history.jsonl, and
reuse the existing safety constraints (own-process stop, port conflicts
reported not seized, secrets in 0600 files). Overwriting a non-empty
database requires an explicit --force everywhere. Makefile help line
mentions the new db subcommands.

Refs: .task/feature-svc-db-ops.md(任务卡=PR 描述)
2026-09-30 14:11:30 +00:00
weichen 60261a835a Generalize svc.sh into a multi-kind service manager with tags and persistence
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 描述)
2026-09-30 13:44:58 +00:00