No description
This repository has been archived on 2026-10-07. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
  • Go 98.1%
  • Shell 1.9%
Find a file
Motoko Kusanagi d30e2d6f4b
chore(agents): upgrade agent-foundry to 5e0c270
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.
2026-10-06 21:32:21 +02:00
.agents/skills chore(agents): upgrade agent-foundry to 5e0c270 2026-10-06 21:32:21 +02:00
.claude chore(agents): upgrade agent-foundry to 5e0c270 2026-10-06 21:32:21 +02:00
.codex/agents chore(agents): upgrade agent-foundry to 5e0c270 2026-10-06 21:32:21 +02:00
cmd build(release): add -version, the release script, and a Releasing section 2026-09-04 12:33:04 +02:00
docs chore(agents): upgrade agent-foundry to 5e0c270 2026-10-06 21:32:21 +02:00
internal fix(runner): keep LocalAGI waits off the dispatch and recovery paths 2026-09-03 22:15:12 +02:00
scripts chore(agents): upgrade agent-foundry to 5e0c270 2026-10-06 21:32:21 +02:00
.gitignore chore(agents): upgrade agent-foundry to 5e0c270 2026-10-06 21:32:21 +02:00
AGENTS.md chore(agents): upgrade agent-foundry to 5e0c270 2026-10-06 21:32:21 +02:00
go.mod chore(deps): tidy go.mod after adding the MCP SDK 2026-09-03 18:50:21 +02:00
go.sum chore(deps): tidy go.mod after adding the MCP SDK 2026-09-03 18:50:21 +02:00
LICENSE chore: initialize from agent-foundry template 2026-09-03 11:30:11 +02:00
README.md chore(agents): upgrade agent-foundry to 5e0c270 2026-10-06 21:32:21 +02:00

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:PORT for 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 to localagi.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 KillMode at its default, so stopping the service signals the whole control group. A job still running at that point is recorded as interrupted at the next start, and any container left behind is removed then via the job's container.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.0 and its pinned dependency set (jsonschema-go is 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/arm64 build (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 --init signal 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.