{"id":49154385,"url":"https://github.com/tesserine/agentd","last_synced_at":"2026-04-22T08:04:08.548Z","repository":{"id":341574140,"uuid":"1170526660","full_name":"tesserine/agentd","owner":"tesserine","description":"Daemon that runs autonomous AI agent sessions in ephemeral Podman containers. The infrastructure layer of the Tesserine ecosystem.","archived":false,"fork":false,"pushed_at":"2026-04-11T15:05:04.000Z","size":266,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-11T16:28:10.327Z","etag":null,"topics":["autonomous-agents","container-runtime","daemon","podman","rust","tesserine"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tesserine.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-02T08:14:38.000Z","updated_at":"2026-04-11T14:48:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tesserine/agentd","commit_stats":null,"previous_names":["pentaxis93/agentd","tesserine/agentd"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/tesserine/agentd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tesserine%2Fagentd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tesserine%2Fagentd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tesserine%2Fagentd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tesserine%2Fagentd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tesserine","download_url":"https://codeload.github.com/tesserine/agentd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tesserine%2Fagentd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32126712,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T07:37:52.372Z","status":"ssl_error","status_checked_at":"2026-04-22T07:37:51.635Z","response_time":58,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["autonomous-agents","container-runtime","daemon","podman","rust","tesserine"],"created_at":"2026-04-22T08:04:07.983Z","updated_at":"2026-04-22T08:04:08.543Z","avatar_url":"https://github.com/tesserine.png","language":"Rust","readme":"# agentd\n\nAutonomous AI agent runtime daemon. agentd runs agent sessions in ephemeral\nPodman containers on infrastructure you control. Each session gets an isolated\nexecution environment — its own identity, credentials, a fresh repository\nclone, and read-only methodology context — supervised from setup through\nteardown. agentd prepares and supervises these environments; model inference and\nMCP transport belong to the agent runtime inside the container.\n\nThe project targets Linux hosts. Non-Linux builds fail intentionally because\nthe runner depends on Linux runtime primitives including rootless Podman,\nsystemd user services, and SELinux-aware filesystem handling.\n\n## Why\n\nRunning autonomous agents requires infrastructure: isolated environments,\ncredential injection, workspace setup, identity management. Operators building\nthis ad-hoc re-solve the same problems for each agent and each deployment.\n\nagentd is the self-hosted runtime layer. The operator declares *what* through\nprofile configuration — which image, which credentials, which methodology.\nagentd owns *how* — container lifecycle, privilege management, resource cleanup.\nThe agent gets an isolated, ephemeral workspace with exactly what it needs and\nnothing more.\n\n## Status\n\nv0.1.0 — early development.\n\nThe session lifecycle works end-to-end: profile configuration, foreground daemon\nstartup, operator-triggered sessions, ephemeral Podman containers, credential\ninjection, execution, and teardown. Startup reconciliation cleans stale\nresources from prior runs. Structured JSON tracing provides operational\nvisibility.\nProfiles may now declare a default repository and an optional cron schedule.\nManual runs still flow through `agentd run`, and scheduled runs dispatch\nthrough the same daemon socket intake without introducing a separate job type.\nProfiles may also declare additional bind mounts for host-managed state such as\nsubscription auth directories. Independently of profile mounts, agentd now\npersists each session's audit record under the rootless default\n`$XDG_STATE_HOME/tesserine/audit/`, falling back to\n`$HOME/.local/state/tesserine/audit/`, with `daemon.audit_root` available as an\nexplicit override for root-owned installs such as `/var/lib/tesserine/audit/`.\n\n## Configuration\n\nA profile is a named environment specification: base image, methodology\ndirectory, optional additional bind mounts, optional default repo, optional\ncron schedule, credentials, and runtime command. Define profiles in a TOML\nconfig file — start from\n[`examples/agentd.toml`](examples/agentd.toml):\n\n```toml\n# Static profile registry for agentd.\n# A profile can carry its own default repo and optional schedule.\n\n#[daemon]\n# Optional explicit host path for persistent audit records. Rootless installs\n# default to $XDG_STATE_HOME/tesserine/audit, falling back to\n# $HOME/.local/state/tesserine/audit when XDG_STATE_HOME is unset.\n# Root-owned system installs should typically point this at\n# /var/lib/tesserine/audit.\n#audit_root = \"/var/lib/tesserine/audit\"\n\n[[profiles]]\n# Stable operator-facing profile name used for lookup and container identity.\nname = \"site-builder\"\n# Prebuilt image containing the agent runtime and runa.\nbase_image = \"ghcr.io/example/site-builder:latest\"\n# Methodology directory to mount read-only into the session environment.\nmethodology_dir = \"../groundwork\"\n# Default repository URL cloned for manual runs when `agentd run` omits a repo,\n# and for every scheduled run of this profile.\nrepo = \"https://github.com/pentaxis93/agentd.git\"\n# Optional five-field cron expression in daemon-local time.\nschedule = \"*/15 * * * *\"\n# Static session command executed from the cloned repository. This profile is\n# tightly bound to one app, so the session repo is the project being built.\ncommand = [\n  \"/bin/sh\",\n  \"-lc\",\n  '''\nruna init --methodology /agentd/methodology/manifest.toml\ncat \u003e .runa/config.toml \u003c\u003c'EOF'\n[agent]\ncommand = [\"site-builder\", \"exec\"]\nEOF\nif [ -n \"${AGENTD_WORK_UNIT:-}\" ]; then\n  exec runa run --work-unit \"${AGENTD_WORK_UNIT}\"\nfi\nexec runa run\n''',\n]\n# Optional environment variable name resolved by the daemon for clone-only\n# repository authentication. This value does not flow into the agent runtime.\nrepo_token_source = \"SITE_BUILDER_REPO_TOKEN\"\n\n#[[profiles.mounts]]\n# Additional host bind mounts are declared explicitly per profile.\n# `source` must be an absolute host path and must already exist.\n# `target` must be an absolute path inside the container and must not\n# duplicate or overlap another mount target in the same profile.\n# `read_only = true` is appropriate for host-managed auth directories.\n#source = \"/home/core/.claude\"\n#target = \"/home/site-builder/.claude\"\n#read_only = true\n\n[[profiles.credentials]]\n# Secret name exposed inside the session environment.\nname = \"GITHUB_TOKEN\"\n# Environment variable name read from the daemon's own process environment.\nsource = \"AGENTD_GITHUB_TOKEN\"\n\n[[profiles]]\n# A home-repo review agent that carries its own review configuration and scans\n# repositories beyond the repo used to launch the session.\nname = \"code-reviewer\"\nbase_image = \"ghcr.io/example/code-reviewer:latest\"\nmethodology_dir = \"../groundwork\"\nrepo = \"https://github.com/pentaxis93/agentd.git\"\ncommand = [\n  \"/bin/sh\",\n  \"-lc\",\n  '''\nruna init --methodology /agentd/methodology/manifest.toml\ncat \u003e .runa/config.toml \u003c\u003c'EOF'\n[agent]\ncommand = [\"code-reviewer\", \"exec\"]\nEOF\nif [ -n \"${AGENTD_WORK_UNIT:-}\" ]; then\n  exec runa run --work-unit \"${AGENTD_WORK_UNIT}\"\nfi\nexec runa run\n''',\n]\nrepo_token_source = \"CODE_REVIEWER_REPO_TOKEN\"\n\n[[profiles.credentials]]\nname = \"GITHUB_TOKEN\"\nsource = \"AGENTD_GITHUB_TOKEN\"\n```\n\nCredential `source` fields name environment variables in the daemon's process\nenvironment — export them before starting the daemon. Additional `mounts`\nentries are bind mounts: `source` must be an absolute existing host path,\n`target` must be an absolute container path, targets must be unique within the\nprofile, and runner-managed targets are reserved: `/agentd/methodology`,\n`/home/{profile}`, `/home/{profile}/.agentd`, and `/home/{profile}/repo` plus\ntheir descendants. Other\ntargets under `/home/{profile}` remain supported, including read-only auth\nmounts such as `/home/site-builder/.claude`. Additional mounts are not\nrelabelled; on SELinux-enabled hosts, operators must ensure each host path\nalready has a container-compatible label. The base image must provide\n`/bin/sh`, `find`, `git`, `useradd`, `gosu`, and whatever binaries the\nconfigured session command uses. When a profile declares `schedule`, it must\nalso declare `repo`. Schedules are evaluated in daemon-local time and missed\nfires are not backfilled after downtime. Persistent audit records default to\n`$XDG_STATE_HOME/tesserine/audit` or `$HOME/.local/state/tesserine/audit`; set\n`daemon.audit_root` to override that for system installations.\n\n## Running a Session\n\nBuild from source with `cargo build --release`. agentd targets Linux and\nrequires rootless Podman for container execution. Operational deployments also\nassume systemd user services and the SELinux considerations described in\n`ARCHITECTURE.md`.\n\nStart the daemon:\n\n```bash\nagentd daemon --config /etc/agentd/agentd.toml\n```\n\n`agentd` with no subcommand is equivalent to `agentd daemon`.\n\nThe daemon runs in the foreground, reconciles stale resources from prior runs,\nand binds a Unix socket for operator control. Default paths:\n`/run/agentd/agentd.sock` and `/run/agentd/agentd.pid`. On SIGINT or SIGTERM,\nthe daemon stops accepting connections and drains in-flight sessions; a second\nsignal exits immediately.\nThe Unix socket protocol is internal to `agentd` in `v0.1.x`: daemon and CLI must be the same build, and operators must restart the daemon after replacing the binary before using `agentd run` again.\n\nTrigger a session through the running daemon:\n\n```bash\nagentd run site-builder --work-unit issue-42\n```\n\n`agentd run` reads the same config file and connects to the socket path defined\nthere. When the profile declares `repo`, the CLI can omit the positional repo\nargument; an explicit repo still overrides the configured default:\n\n```bash\nagentd run site-builder https://github.com/pentaxis93/agentd.git --work-unit issue-42\n```\n\nBoth manual and scheduled dispatches use the same daemon socket intake. Inside\nthe container, the agent sees:\n\n- An unprivileged user with `$HOME` at `/home/site-builder`\n- A fresh clone of the repository at `/home/site-builder/repo`\n- Repo-root `.runa` bridged to persistent audit storage\n- Read-only methodology mount at `/agentd/methodology`\n- Any operator-declared additional bind mounts, read-only or read-write per profile\n- Credentials injected as environment variables\n- `AGENTD_WORK_UNIT` when the invocation includes one\n- The configured session command executing from the repo directory\n\nThe container is force-removed on completion. The session's audit record\npersists on the host under the resolved audit root\n`\u003caudit_root\u003e/\u003cprofile\u003e/\u003csession_id\u003e/`, with runa state in `runa/` and agentd\nmetadata in `agentd/session.json`. If teardown cleanup fails, or if audit\nfinalization attempts closeout and fails, that metadata remains intentionally\nincomplete with no `end_timestamp` or `outcome`. On successful finalization,\nagentd seals persisted runa entries read-only and publishes a read-only\n`session.json` as the final commit point. Ancestor directories remain writable\nso the final same-directory atomic replace can occur. The on-disk metadata does\nnot encode which incomplete path occurred; operators should use\n`runner.lifecycle_failure` plus the surrounding `runner.session_outcome`,\n`runner.session_error`, and `runner.session_teardown` events to disambiguate\ncause.\n\n## Scheduled Runs\n\nProfiles with `schedule` run autonomously while the daemon is up. The scheduler\nevaluates cron expressions in daemon-local time and opens the same Unix-socket\nclient path that `agentd run` uses. Multiple scheduled profiles may overlap,\nand their sessions dispatch independently. Session outcomes do not affect later\nschedule evaluation: the next occurrence runs at its next scheduled time.\n\n## Going Deeper\n\n- **[ARCHITECTURE.md](ARCHITECTURE.md)** — session lifecycle phases, container\n  isolation model, credential flow, and workspace crate boundaries. How the\n  system is built and why.\n- **[AGENTS.md](AGENTS.md)** — development discipline, BDD workflow, commit and\n  branch conventions. Read this before contributing.\n- **[examples/agentd.toml](examples/agentd.toml)** — annotated profile\n  configuration. Starting point for writing your own.\n\n## License\n\n[MIT](LICENSE)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftesserine%2Fagentd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftesserine%2Fagentd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftesserine%2Fagentd/lists"}