Files
claude-projects/claude-config/config/prompts/agent-sudo-secrets-proxy/AS3_image_build_and_runbook.md
T
2026-10-02 00:19:54 -05:00

6.4 KiB
Raw Blame History

AS3 — agent-sudo image build + AS3 runbook (spawned 2026-10-01, main session 771b2744)

You are a bounded background agent for agent-sudo (personal_projects #176). Budget: --max-turns 40. If you issue the same tool call twice with identical arguments, STOP and emit the wrap-up with status=partially_succeeded.

HARD RULES

  • NO sudo, ever. If a step truly needs root, end your run with a final message headed exactly ⏸ OWNER-COMMAND-REQUEST containing host:, command:, why:, paste_back:, resume_at: — then stop.
  • NEVER restart/stop/recreate any container or systemd unit on either host (that is the owner's step, written into your runbook). docker build, docker tag, docker push, docker run --rm of the NEW image for a smoke test (no ports published, no bind mounts of the live bridge dir) are allowed on primary.
  • NO git add/commit/push. NO Postgres writes. Never print secret values (mask anything from .env files; do not cat .env files at all).
  • Do not make design decisions beyond the ones below; if reality contradicts them, STOP and report.

FACTS (verified by the main session 2026-10-01 17:10)

  • ASH hardening is LIVE on both hosts since 17:01 (primary) / 17:06 (server-01): root-owned daemon code at /usr/local/lib/agent-sudo/, signed SUDO.md copy at /etc/agent-sudo/SUDO.md (digest eba7b9c00856..), unit is a regular file with EnvironmentFile=/etc/agent-sudo/daemon.env. Daemon = AS1/AS2/ASH code.
  • Both containers still run the OLD image gitea.local/backtalk6858/agent-sudo:latest (b227d3cdfa9d, ~2 months old, pre-AS1 protocol). primary :8084 /health ok; server-01 bound 192.168.1.90:8082. A new container against the new daemon is required for tier 1–3 (old image speaks the pre-AS1 protocol).
  • Repo: /opt/appdata/docker/docker-compose/agent-sudo (uncommitted AS1/AS2/ASH changes; tests 185 pass). server-01's repo copy is OLDER (28+ commits behind) — do not touch it; the runbook syncs what the container needs.
  • server-01 Timeshift: /etc/timeshift/ has only default.json + restore-hooks.d (unconfigured). Target disk for rsync snapshots: /dev/sda4, ext4, UUID 6c2dbfca-8133-4e54-a510-8ffc19290f1c, mounted /data (931 G, 3 % used). SMART has never been read (needs root).
  • Signed SUDO.md (main-session grep 17:12): tier-1 ACTIVE rules are systemctl/cp/install rows only (e.g. systemctl daemon-reload, systemctl enable --now control-plane-up.timer, resolver timer rows); the mkdir -p /opt/appdata/* t1 row is NOT active. EVERY tier-3 row is proposed (none active). So §5 needs a SUDO.md change: in the runbook, write the exact proposed row to activate for the tier-3 test (narrowest possible, e.g. an exact systemctl start as3-dry.service row, tier 3, host_override primary=4) as a SUDO.md.as3-proposed file next to SUDO.md + the re-sign + install.sh + restart steps (mirror deploy/hardening/HARDENING_RUNBOOK.md §1–§3). Pick the §4 tier-1 test from the ACTIVE rows only.
  • Owner decision (09-30): build the AS3 image directly on primary, NOT via Jenkins (JH-3 not built yet).

TASKS

  1. Run the full test suite (python3 -m pytest -q -p no:cacheprovider in the repo). Must be 185 passed; else STOP.
  2. Read Dockerfile + app.py + docker-compose.yml. Confirm the image needs nothing that only the daemon has now (AS1 moved undo/snapshot/sandbox into the daemon). List what the image copies; do NOT edit the Dockerfile unless the build fails — if it fails, STOP and report the error.
  3. Build on primary: tag gitea.local/backtalk6858/agent-sudo:as3-<short git sha of HEAD>-<yyyymmdd> AND :latest. Smoke test: docker run --rm --entrypoint python3 <new tag> -c "import app" (or the equivalent import check for the real entrypoint) — no network, no mounts. Push both tags to Gitea (docker login is already configured for gitea.local; if push is refused for auth, STOP and report — do not handle creds). Record the image ID and the pushed digest.
  4. WRITE /opt/appdata/docker/docker-compose/agent-sudo/deploy/AS3_RUNBOOK.md — owner-facing, one command per block, each with Why/Expect, FULL commands (never abbreviate), in this order: §0 SMART read on server-01 (smartctl -a /dev/sda and the NVMe) — pass/fail criteria stated (reallocated/pending sectors, CRC errors); STOP the runbook if it fails. §1 Configure Timeshift on server-01 for RSYNC mode to the sda4 UUID above, minimal schedule off (snapshots on demand only), exclude /data itself and /var/lib/docker; one manual test snapshot + timeshift --list; how to delete that test snapshot. §2 primary: pull + recreate the agent-sudo container with the new tag (the compose is plain docker compose with an --env-file; find the exact env-file path and the exact command the July deploy used from DEPLOY_RUNBOOK.md; do NOT read .env contents). Then health check + one tier-0 /exec test through the container (a SUDO.md t0 command, e.g. systemctl status docker), with the exact curl incl. how the caller key is supplied WITHOUT echoing it (read -rs). §3 server-01: what the container needs from the repo (bridge/SUDO.md copy for the container — note the daemon validates against /etc/agent-sudo/SUDO.md), pull + recreate with SNAPSHOT_ENABLED=true, health, tier-0 test. §4 tier-1 test on server-01 (an active t1 rule from the signed SUDO.md — pick one that is harmless, e.g. mkdir -p /opt/appdata/<throwaway>), confirm undo captured, run the undo, confirm reverted. §5 tier-3 test on server-01 on a THROWAWAY unit: write a tiny as3-dry.service (oneshot, ExecStart=/bin/true) — installing it needs root, so it's an owner block — then a t3 systemctl start as3-dry.service through agent-sudo; confirm Timeshift snapshot created + undo recorded; then cleanup (remove unit, delete snapshot). §6 rollback per host (previous image b227d3cdfa9d re-tag + recreate). Every tier test must be checked against the signed SUDO.md for the rule it relies on — quote the row. If a needed t1/t3 rule is not ACTIVE in the signed SUDO.md, say so in the runbook and in your output (do NOT edit SUDO.md — that needs a re-sign).
  5. Verify your own artifacts exist (ls + grep the runbook sections).

Wrap-up: FINAL message = JSON only: status, project "agent-sudo", actions_taken[], actions_failed[], files_touched[], image_tags[], image_id, pushed_digest, tests_passed, runbook_path, rules_relied_on[] (pattern, tier, state), missing_rules[], unverified_claims[], next_step, notes.