Skip to content

feat(adf-setup): root-privileged worktree sweep for systemd ExecStartPre (Layer 3) Refs #1571 (Gitea)#873

Merged
AlexMikhalev merged 1 commit into
mainfrom
task/1571-adf-cleanup-sh
May 17, 2026
Merged

feat(adf-setup): root-privileged worktree sweep for systemd ExecStartPre (Layer 3) Refs #1571 (Gitea)#873
AlexMikhalev merged 1 commit into
mainfrom
task/1571-adf-cleanup-sh

Conversation

@AlexMikhalev
Copy link
Copy Markdown
Contributor

Summary

Layer 3 of the ADF worktree-lifecycle hardening epic (Gitea #1567). Defence in depth: a POSIX sh script run as root via systemd ExecStartPre= so worktree residue owned by root-elevated agents (sccache, container builds) gets reaped at the next service restart even if Layers 1 (RAII guard) and 2 (orchestrator-side sweep) miss it.

Three new files:

  • scripts/adf-setup/adf-cleanup.sh -- the sweep script.
  • scripts/adf-setup/tests/test_adf_cleanup.sh -- shell test driver (creates a real git repo in a TempDir, seeds review-/keep-me, asserts review- removed and keep-me preserved, idempotency on second run).
  • docs/operations/adf-orchestrator-systemd.md -- operator install/rollback runbook.

No Rust changes. Hot-shippable: install via sudo install -m 750 -o root -g root scripts/adf-setup/adf-cleanup.sh /opt/ai-dark-factory/bin/adf-cleanup.sh plus the systemd drop-in snippet in the ops doc.

Test plan

  • ./scripts/adf-setup/tests/test_adf_cleanup.sh -- PASS: test_adf_cleanup (first run sweeps 3 worktrees, second run is no-op).
  • dash -n POSIX syntax check -- clean.
  • Phase 4 verification on bigbox per design §8.4 after merge.

Refs terraphim/terraphim-ai#1571 (Gitea)
Refs terraphim/terraphim-ai#1567 (Gitea epic)

…tartPre

Layer 3 of the four-layer ADF worktree lifecycle plan (epic #1567).
This commit introduces the hot-shippable defence: a POSIX `sh` script
that systemd invokes as root via `ExecStartPre=` before the
orchestrator starts. Layers 1 and 2 prevent new residue from
accumulating but cannot reclaim root-owned trees written by
container-build agents; Layer 3 is the only layer that can.

Files:

* `scripts/adf-setup/adf-cleanup.sh` -- POSIX `sh` (verified with
  `dash -n`), `set -eu`. Sweeps `${ADF_WORKTREE_ROOT}/review-*` and
  `${ADF_AGENT_TMP_ROOT}/*` via `git worktree remove --force` with a
  `/bin/rm -rf` fallback, finishes with `git worktree prune
  --verbose` and a single summary line `adf-cleanup: swept=N
  failed=M repo=PATH`. Three environment variables overridable.
* `scripts/adf-setup/tests/test_adf_cleanup.sh` -- POSIX shell test
  driver. Seeds a real git repo under `mktemp -d`, creates three
  `review-test-*` worktrees plus a `keep-me/` directory, asserts the
  review entries are removed and `keep-me/` is preserved, and a
  second run is a no-op. Exits 0 on PASS, 1 on FAIL.
* `docs/operations/adf-orchestrator-systemd.md` -- operator-facing
  doc with the systemd drop-in, the `install` commands (mode 0750,
  owner root:root), verification recipe (cross-referencing §8.4 of
  the design), and rollback steps.

Deviations from the design verbatim (small portability hardenings):

* Test driver passes `-c init.defaultBranch=main` to `git init` to
  silence the default-branch hint, and `-c user.email/-c user.name`
  to `git commit --allow-empty` so the test survives on hosts
  without a global git identity.

Verification:

* `./scripts/adf-setup/tests/test_adf_cleanup.sh` -- PASS.
  Output: `adf-cleanup: swept=3 failed=0 ...` then
  `adf-cleanup: swept=0 failed=0 ...` then `PASS: test_adf_cleanup`.
* `dash -n` on both scripts -- POSIX syntax clean.
* `shellcheck` not installed locally; skipped.
* `git diff --check` -- clean.

No Rust files touched; `cargo fmt --check` does not fire.

Refs #1571 (Gitea)
@AlexMikhalev AlexMikhalev merged commit 3b5566d into main May 17, 2026
3 checks passed
@AlexMikhalev AlexMikhalev deleted the task/1571-adf-cleanup-sh branch May 17, 2026 13:55
@github-actions
Copy link
Copy Markdown
Contributor

Documentation Preview

Your documentation changes have been deployed to:
https://07745d15.terraphim-docs.pages.dev

This preview will be available until the PR is closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant