- Go 98.1%
- Shell 1.9%
Three-way merge of agent-foundry b9207e9..5e0c270 with the foundry-upgrade skill. The repository gains the brainstorm, write-plan, diagnose, and forge skills with their Claude links, the change-reviewer and dependency-advisor subagents, the current memory contract and curator adapters, and the source's Claude settings and ignore rules. AGENTS.md takes the source's layout and keeps warden's identity, commands, dependency baseline, and estate-neutral rule. Migrations applied for the old layout: - the memory selection leaves AGENTS.md for each workstation's untracked AGENTS.local.md, and AGENTS.md declares Memory support localrecall; - CLAUDE.md, which only imported AGENTS.md, goes; Claude Code reads AGENTS.md natively; - the Template state field and Template lifecycle section go; - the executed implementation plan leaves docs/superpowers for the local .plans/; - the vendored validator goes, and the Verify command and README stop calling it; the validator runs from the agent-foundry checkout. |
||
|---|---|---|
| .agents/skills | ||
| .claude | ||
| .codex/agents | ||
| cmd | ||
| docs | ||
| internal | ||
| scripts | ||
| .gitignore | ||
| AGENTS.md | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| README.md | ||
warden
Escalation runner for azkaban jails.
warden is a single static-binary Go daemon that lets LocalAGI agents submit bounded jobs which run as non-interactive Claude/Codex sessions inside rootless azkaban jails, and pushes the resulting report back into the agent's conversation. It is the sole policy-enforcement point (budgets, timeouts, queue, audit) between the local model and paid sessions.
Status
Implemented per docs/warden-design.md; the golden contract tests
(tool schemas, job.json, audit lines) and the stub-executor
definition-of-done suite live under internal/. The manual
integration check is documented in docs/manual-integration.md.
Running
warden takes one JSON configuration file and nothing else:
warden -config /path/to/warden.json
warden -version prints the release version and the commit it was
built from, then exits.
The complete field list, with an example, is the "Configuration" section
of docs/warden-design.md. Three fields are worth checking first:
listen—HOST:PORTfor the MCP endpoint, the only listening socket. warden binds it before recovering anything, so a busy or wrong address fails the start instead of spending a session.token_file— the shared MCP bearer token. It must be non-empty and mode 0600; warden refuses to start on a group- or world-accessible token file, and applies the same rule tolocalagi.api_key_file.spool_dir— warden's only persistence, created 0700. It must be an absolute path, as must every other path in the config: warden opens its own files against whatever working directory the service manager gives it, and runs each client launcher from the job directory, so a relative path lands somewhere the config never named.
Service expectations (the unit file belongs to the deployer):
- A simple service with
Restart=on-failure, running as the warden user; rootless podman additionally requires that user to have subuids and lingering enabled. - Leave
KillModeat its default, so stopping the service signals the whole control group. A job still running at that point is recorded asinterruptedat the next start, and any container left behind is removed then via the job'scontainer.cid. - Configuration is read once at startup — there is no reload. Restart the service to apply a change.
Running warden by hand and interrupting it mid-job orphans the jail
session: the executor puts each client launcher in its own process
group, so a terminal's Ctrl-C never reaches it. Prefer the service
manager; after an interrupted hand run, remove any leftover container
with podman rm -f "$(cat <spool_dir>/jobs/<job_id>/container.cid)".
Constraints
- Go standard library plus
github.com/modelcontextprotocol/go-sdk v1.1.0and its pinned dependency set (jsonschema-gois imported directly for the explicit tool schema); any further dependency needs explicit approval. - Estate-neutral: no host names, addresses, or tenant data in code, tests, examples, or docs. Everything deployment-specific comes from the config file.
- Target: static
linux/arm64build (CGO_ENABLED=0); develops and tests on any architecture.
Commands
go mod download # setup
go test ./... # test
go vet ./... && go test ./... && \
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o /dev/null ./cmd/warden # verify
Releasing
A release is a signed tag plus the artifacts scripts/build-release.sh
builds from it, uploaded by hand to the forge release for that tag:
git tag -s v0.1.0 -m "warden v0.1.0" # on a clean, tested main
scripts/build-release.sh v0.1.0 # dist/: binary, SHA256SUMS, SHA256SUMS.sig
git push origin main v0.1.0
The script refuses a dirty tree or a HEAD not tagged with the requested
version, builds the static linux/arm64 binary (Go stamps the tag's
version and the commit into it; warden -version prints both), checks
that embedded build info (target, no CGO, version, clean commit), writes
SHA256SUMS, and signs it with the SSH key named by
git config user.signingkey (--no-sign skips that step). Verify a
download with sha256sum -c SHA256SUMS, then check the signature against
the release's published key:
ssh-keygen -Y verify -f allowed_signers -I <principal> -n file \
-s SHA256SUMS.sig < SHA256SUMS
External contracts
The design pins its external contracts to:
- LocalAGI
v2.8.1—git clone --depth 1 --branch v2.8.1 https://github.com/mudler/LocalAGI - azkaban
e82e4a9—git clone https://git.unitoo.it/claudiomaradonna/azkaban(headless contract:--cidfile, exit-code propagation,--rm --initsignal handling, stderr-only diagnostics)
Before implementing a contract, re-verify it against the pinned source; if the source contradicts the design document, the source wins and the document is amended.
License
MIT — see LICENSE.