docs: insights-driven guardrails — SSH pre-flight, bash safety, infra approval, dispatch pre-flight, session end, ask-minimax fallback
This commit is contained in:
32
claude/agent-dispatch-preflight.md
Normal file
32
claude/agent-dispatch-preflight.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Agent Dispatch Pre-flight
|
||||
|
||||
## When this applies
|
||||
|
||||
Before starting `/loop ... /orchestrate`, `/dispatch`, or any unattended or overnight agent batch. Run this checklist once, before the loop starts — not mid-run.
|
||||
|
||||
## Checklist — all must pass before the loop starts
|
||||
|
||||
1. **CP reachable.** `curl -fsS "$CP_URL/health"` returns 200. `CP_URL` is defined in `claude/agent-runtimes-cp.md` — read that file for the correct value and any auth headers required.
|
||||
|
||||
2. **A dispatcher is polling.** Check the CP dispatchers endpoint (see `agent-runtimes-cp.md`). A queued task with no live dispatcher sits forever — confirm at least one dispatcher is active before queuing work.
|
||||
|
||||
3. **Scaffolding present.**
|
||||
- `.agent-tasks.json` exists and passes `jq empty .agent-tasks.json` (valid JSON).
|
||||
- All templates, repos, and input files referenced by tasks are resolvable from this host.
|
||||
- Agent push keys are loaded (`ssh-add -l`) — container agents push branches back; a missing key silently fails the push.
|
||||
|
||||
4. **Auth done this session.** `CLAUDE_CODE_OAUTH_TOKEN` is set in the environment or readable from `~/dev/claude/secrets/claude/long_lived_oauth_token`. Confirm before launching containers.
|
||||
|
||||
Do not start the loop until all four pass. Surface any failure to the user and wait for remediation.
|
||||
|
||||
## Circuit-breaker
|
||||
|
||||
Track task-state changes across invocations. After **5 consecutive invocations with no state change** (no task moved from pending→running, running→completed/failed, etc.): stop dispatching, print a stuck-queue report listing each task and its current status, and wait for the user. Never run an unattended loop without this guard.
|
||||
|
||||
## Recovery
|
||||
|
||||
If a dispatch batch needs to be aborted mid-run:
|
||||
|
||||
- Drain queued tasks: set pending tasks to `cancelled` in `.agent-tasks.json` before the next invocation so the orchestrator does not launch them.
|
||||
- Let running containers finish or `docker stop` them explicitly.
|
||||
- Re-dispatch from a clean state once the root cause is resolved.
|
||||
@@ -21,3 +21,7 @@
|
||||
## How to delegate
|
||||
|
||||
Pass file *paths*, not file *contents*. If you read the input files yourself before invoking, you have already paid the token cost the skill exists to avoid.
|
||||
|
||||
## Failure handling
|
||||
|
||||
MiniMax intermittently returns `invalid system role` and other transient errors. Retry once. If it fails again, fall back to a Claude subagent with the same brief — Sonnet for file-heavy grunt work, Opus for reasoning-grade consults. Never silently drop the task. Log new error shapes to the project's `memory/gotchas-*.md`.
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# Scripting Conventions
|
||||
|
||||
## Bash safety
|
||||
|
||||
- Open every script with `set -euo pipefail` — fail fast on errors, unset vars, and pipeline failures.
|
||||
- `grep` exits 1 on no match — under `set -e` use `grep ... || true`; under `pipefail`, beware `grep ... | head` triggering SIGPIPE (use `|| true` on the grep side).
|
||||
- One stdin per process — never pipe into a command that also reads a heredoc; pick one input source.
|
||||
- Validate JSON before consuming: `jq empty <file>` or `python3 -m json.tool <file>`. Especially before dispatch loops that iterate over JSON state.
|
||||
- Quote all expansions: `"$var"`, `"${array[@]}"`. Bare expansions split on whitespace.
|
||||
- Edit-tool `replace_all` is a substring match — a short `old_string` like `2` will corrupt `24` → `244`. Make `old_string` unique (add surrounding context) or use individual targeted edits.
|
||||
|
||||
## Conventions
|
||||
|
||||
- All scripts live in `scripts/` and run from the repository root
|
||||
- Scripts should be idempotent and safe to re-run
|
||||
- Use colour output for pass/fail indicators in verification scripts
|
||||
|
||||
@@ -15,10 +15,33 @@ Pattern: `gitea.oreillyit.nz-<username>`.
|
||||
|
||||
- `gitea.oreillyit.nz-homelab` → authenticates as `cluster-administrator` (key: `~/.ssh/gitea-cluster-admin`)
|
||||
- `gitea.oreillyit.nz-ai-enablement` → authenticates as `ai_enablement` (key: `~/.ssh/gitea.ai-enablement`)
|
||||
- `gitea.oreillyit.nz-accelerators` → (key: `~/.ssh/gitea.accelerators.2026`)
|
||||
|
||||
Git remote URL format: `git@gitea.oreillyit.nz-<user>:<org>/<repo>.git`
|
||||
- Example: `git@gitea.oreillyit.nz-ai-enablement:skynet/custom-claude-skills.git`
|
||||
|
||||
## SSH agent pre-flight
|
||||
|
||||
Before the first push of a session:
|
||||
|
||||
1. Derive the alias: `git remote get-url origin` — the host segment is the SSH alias.
|
||||
2. Confirm the key is loaded: `ssh-add -l` — the relevant key must appear.
|
||||
3. Confirm auth: `ssh -T git@<alias>` — expect a Gitea welcome message.
|
||||
|
||||
Claude cannot answer a passphrase prompt. If the key isn't loaded, ask the user to `ssh-add ~/.ssh/<keyfile>` before proceeding.
|
||||
|
||||
In non-interactive contexts (CI, container agents, unattended loops), use `GIT_SSH_COMMAND='ssh -o BatchMode=yes' git push` so a missing credential fails fast instead of hanging on a passphrase prompt.
|
||||
|
||||
## Push failure recovery
|
||||
|
||||
| Symptom | Likely cause |
|
||||
|---|---|
|
||||
| `Permission denied (publickey)` | Key not loaded, or wrong alias in remote URL |
|
||||
| Push hangs silently | Passphrase prompt in non-interactive context — use `BatchMode=yes` |
|
||||
| 403 after API-created repo | SSH user not added as collaborator — add via Gitea UI or API |
|
||||
|
||||
Commit locally first, surface the failure explicitly, and never end a session with finished work unpushed and unmentioned. Record the recovery step in CONTEXT.md.
|
||||
|
||||
## Working rules
|
||||
|
||||
- **Always pull before planning work** — run `git pull --ff-only` when entering a project. Work may have been pushed from another machine or by container agents. If the pull fails (diverged history, uncommitted changes), warn the user before proceeding.
|
||||
|
||||
Reference in New Issue
Block a user