Why: a freshly deployed environment boots with an empty settings store,
so the first run dies with "main model unconfigured" and the user has
to open the settings UI before anything works - the opposite of
one-command bring-up.
Evidence: live matrix - full seed (chat+lightweight+tavily) lands in
the settings store (API view shows baseUrl/model with the key masked),
restart without flags does not re-seed and the settings persist,
.svc.env sourcing seeds a fresh environment from the one-time config
file, and a no-flag start stays silent. Also wrapped a /proc read race
in pid_alive that printed tr noise during stop.
Impact: --model-base/--model-key/--model-name, --light-base/-key/
-name, --tavily-keys on start/deploy (idempotent, only provided
fields); SVC_MODEL_*/SVC_LIGHT_*/SVC_TAVILY_KEYS env vars; <repo>/
.svc.env one-time config file (gitignored) makes every future deploy
self-configuring; auth-protected instances fall back to a clear hint.
Refs: feature/svc-auto-seed task card.
Why: the manager only took configuration from SVC_* environment
variables; binding a public interface or pointing at a database meant
exporting vars first, which is awkward for one-off deploys and
invisible in shell history review.
Evidence: live matrix on the worktree - --port (8801), --host 0.0.0.0
(bind verified via ss, health probe auto-maps to 127.0.0.1), --addr
whole-form, CLI-over-env precedence (--port beats SVC_DEV_ADDR),
--mock reaching the server cmdline, --dsn passthrough proven by the
postgres connect attempt in the log, -- passthrough (--artifacts), and
make svc ARGS passthrough. A set -e silent-exit trap in env_config was
caught by the first run and fixed (condition-as-last-statement).
Impact: scripts/svc.sh <env> [action] [--addr|--host|--port|--data|
--dsn|--auth|--mock|--plugins| -- <extra>]; precedence CLI > env vars >
defaults; help rewritten with examples; make svc gains ARGS; logs keeps
the positional line-count form. The real-world port guard held: a dev
instance started from the main checkout was refused with owner info,
untouched.
Refs: feature/svc-cli-args task card.
Why: deploying a new build meant manually finding and killing the old
process, rebuilding and re-launching with the right flags; dev and prod
instances could collide on ports, data dirs or kill each other.
Evidence: live matrix on the worktree - dev deploy (stop -> make build
-> start with health check), redeploy swaps the pid and keeps seeded
data, prod deploys alongside dev on separate port/data with fully
isolated /api/projects, port takeover is refused with the owning
process named while the running env stays up, stop clears pidfile and
frees the port. A pid-capture bug (compound-background subshell wrote
the wrapper pid instead of the server) was caught and fixed during the
first live run.
Impact: scripts/svc.sh <dev|prod> [deploy|stop|start|restart|status|
logs]; runtime/<env>/{data,svc.pid,svc.log,svc.env} isolation; defaults
dev 127.0.0.1:8788 / prod 127.0.0.1:8787 overridable via SVC_* env
vars (incl. SVC_PROD_DSN for the PG tier); make svc ENV=... shortcut;
runtime/ gitignored. Safety: only processes started by the script are
stopped (pidfile + /proc cmdline double check).
Refs: feature/svc-env-script task card.
Why: the hook landed as 100644, so `make setup` chmod left a mode-only diff that makes the main checkout permanently dirty and blocks task.sh close (dirty-tree guard).
Evidence: git status showed " M scripts/hooks/post-merge" with 0 insertions/deletions after make setup; task-finish tail reported the dirty-tree refusal.
Impact: mode 100644 -> 100755 only; no content change.
Refs: task card feature/card-autoclose-r1 (PR #16 follow-up)
Why: 11 merged branches had left their task cards open (bookkeeping debt found on 2026-09-30); closure was manual and never triggered, so card status rotted after each merge.
Evidence: dogfood run of `task.sh close --fold` closed and archived the 11 cards (previous commit); temp-repo matrix 33/33 PASS covering detection, pending-branch idempotence, dirty/no-fold refusals, post-merge auto-close on merge-type pulls, worktree guard, and the full lifecycle (closure PR merge archives cards on main).
Impact: scripts/task.sh (+close, precheck [cards] report, finish-tail trigger), scripts/hooks/post-merge (new), Makefile (+task-close target, setup chmod), AGENTS.md rule; archive fixes correct PR links missed by the first dogfood run; no module or gitlink change.
Refs: task card feature/card-autoclose-r1
Why: Provider repos merged for T1 (core PR#2, agent-command PR#2, frontend
PR#3, ui PR#3, documents PR#9); gitlinks pinned to those mains. The
task-finish guard prevents a repeat of the T0 incident where running
finish from the main checkout deleted it (scripts/task.sh treated $PWD as
the worktree to remove).
Evidence: make test green on the pinned combo — core, backend 13 pkgs,
frontend 9, ui 6, agent-command (vet + tests incl. conformance); make build
produces the binary; combo version string now includes agentcmd SHA.
Impact: combo grows its version traceability; AGENTS.md documents the
worktree-cwd requirement for finish.
Refs: modules/documents docs/records/2026-09-30-t1-core-cards-commands-verification.md
Why: the pin-documents flow exposed guard divergence — precheck counted
submodule drift while task-start checked porcelain only, letting a task
start despite a BUSY verdict; and PR#8 overcorrected by treating
uninitialized (-) submodules as BUSY when they only block builds, not
writes.
Evidence: bash -n clean; precheck on this checkout prints tree line with
drift/uninit split and READY verdict; negative path exercised by the
real divergence that started this task.
Impact: precheck warns on uninitialized, BUSY only on +/U; task-start now
refuses on porcelain dirt and +/U drift, matching precheck.
Refs: PR#8; policy/tool-adaptation-matrix.md A1
Why: precheck missed uninitialized submodules (git submodule status '-'
prefix), and the branch protection configured today plus the second live
probe outcome must be recorded honestly in the matrices.
Evidence: platform negative: direct push to protected main rejected
(pre-receive hook declined, Logging-System probe); second write-guard probe
confirmed session-start config loading (no hook run in the pre-config
session log).
Impact: precheck sub_dirty now counts '-' prefixed entries; A3 registered
enforced at platform layer across 11 repos; zcode matrix pending-live
annotated with the loading-timing proof.
Refs: policy/tool-adaptation-matrix.md; policy/tool-adaptation-zcode.md
Why: zcode lacks a rules feature (AGENTS.md is the resident layer) but
supports PreToolUse hooks that can block Edit/Write before the write lands,
upgrading A1/A3 from commit-time to write-time enforcement; the two block
shapes (integration branch, detached submodule) mirror the real incidents.
Evidence: script-level suite 8/8 (N1-N3 blocks with exit 2 and remediation
hints, P1-P5 allows incl. fail-open degradation paths); config JSON valid;
client-side live-fire interception marked pending-live in the matrix.
Impact: .zcode/config.json enables the hook runner for this workspace;
.zcode/plans/ ignored (client state); no product code change.
Refs: Development-Guidelines 0.1.0-draft.8; policy/tool-adaptation-zcode.md
Why: git unconditionally refuses worktree remove when the tree contains
gitlinks (index-level check; deinit does not bypass it), so the PR#4 fix
path still failed on the second real task.
Evidence: after deinit the worktree was clean and submodule dirs empty, yet
remove refused; rm -rf + worktree prune is the documented workaround and
was proven manually on the empty-list task worktree.
Impact: task-finish now completes the recycle path automatically after its
merge verification; no guard weakened.
Refs: Agent-System-Dev PR#4; policy/tool-adaptation-matrix.md A5
Why: git refuses to remove a worktree with initialized submodules; the first
real dogfood run of task-finish hit this on the empty-list fix task.
Evidence: the fix task's worktree recycled only after manual force-remove;
deinit-then-remove path exercised on the same state afterwards.
Impact: finish deinitializes submodules, removes, prunes, and deletes the
remote branch; unmerged-result guard unchanged.
Refs: .task/fix-empty-list-json.md
Why: agents skipped triggered reading and wrote into shared checkouts holding
other tasks' in-flight changes; the 2026-09-30 empty-list incident session
found 24 overlapping in-flight files only by accident at first write.
Evidence: positive/negative suite in a real scratch repo passed 19/19
(precheck READY/BUSY/SYNC_REQUIRED, start refuse/establish, hook main/badname/
longsubject refusals, sync checkpoint, finish recycle and abandon double-
confirm); the suite caught three real defects (pipefail empty-grep abort,
worktree gitdir COMMIT_EDITMSG resolution, message checks in the wrong hook
phase).
Impact: make setup enables pre-commit/commit-msg hooks; make precheck/task-
start/task-sync/task-finish provide the governed path; no existing workflow
removed. AGENTS.md carries the resident gate rules.
Refs: Development-Guidelines 0.1.0-draft.7; task card .task/delivery-mechanism.md