{"id":48866806,"url":"https://github.com/zeroqn/agentbox","last_synced_at":"2026-06-01T16:00:47.511Z","repository":{"id":351559261,"uuid":"1211501728","full_name":"zeroqn/agentbox","owner":"zeroqn","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-28T04:37:42.000Z","size":837,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-28T06:31:26.556Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zeroqn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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-04-15T13:06:20.000Z","updated_at":"2026-05-28T04:35:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"e2212741-3bdc-4c5d-a9bc-bd0b5c0f64d8","html_url":"https://github.com/zeroqn/agentbox","commit_stats":null,"previous_names":["zeroqn/agentbox"],"tags_count":99,"template":false,"template_full_name":null,"purl":"pkg:github/zeroqn/agentbox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeroqn%2Fagentbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeroqn%2Fagentbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeroqn%2Fagentbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeroqn%2Fagentbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zeroqn","download_url":"https://codeload.github.com/zeroqn/agentbox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeroqn%2Fagentbox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33782317,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2026-04-15T19:02:35.276Z","updated_at":"2026-06-01T16:00:47.503Z","avatar_url":"https://github.com/zeroqn.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# agentbox\n\n`agentbox` is a small Rust CLI that starts an interactive Podman container shell\nfor your current project.\n\nIt mounts the current directory at `/workspace`, persists Codex/Cargo state on\nthe host, and runs Nix inside the default libkrun guest runtime.\n\n\u003e **Runtime notice:** default libkrun mode is not a stock Podman runtime. It is\n\u003e intended to run with this flake's custom `crun`/Podman build and the pinned\n\u003e `libkrunfw` firmware package, which provide the `krun` handler, raw data disk\n\u003e annotations, and nested-KVM firmware support used by agentbox.\n\nCurrent runtime split:\n\n- **Libkrun mode (default):** Podman + crun/libkrun VM mode with two sparse\n  raw btrfs data images attached through `krun.disk.*` annotations. The guest\n  uses disk 0 for a persistent kernel overlay at `/nix` and disk 1 for\n  rootless Podman storage as `dev` with the `btrfs` storage driver. The image\n  also provides `docker` and `docker-compose` compatibility commands backed by\n  Podman rather than a Docker daemon. Libkrun shell entry starts rootless\n  Podman preparation in the background; direct `podman` waits only for that\n  prep to finish, while `docker` and `docker-compose` additionally start or\n  repair the Podman API socket on first use.\n  The `/workspace` bind mount uses `--userns=keep-id` so ownership matches the\n  host user after the guest drops privileges.\n- **Container mode (`agentbox container`):** native Podman task container plus\n  host `fuse-overlayfs` and a reusable `nix-daemon` sidecar.\n  `agentbox container sidecar` starts or reuses only the sidecar stack for\n  debugging.\n- **Microvm mode (`agentbox microvm`, experimental):** task-based direct-libkrun\n  runtime branch for one-shot microVM runs from an OCI image cache. It prepares\n  a clean per-task rootfs, attaches per-workspace sparse btrfs disks for `/nix`\n  and rootless container storage, supervises a same-binary helper that calls\n  libkrun directly, runs `agentbox-guest-init microvm enter`, and mounts the\n  current workspace at `/workspace` through virtiofs.\n\nSeeded `/nix` copy fallback has been removed. Container mode always uses the\nmanaged sidecar.\n\n---\n\n## Prerequisites\n\n- Linux\n- `podman`\n- `nix` (for building via flake)\n- `fuse-overlayfs` (required for `agentbox container` sidecar mode and for\n  `agentbox microvm --storage fuse-overlay`; included by the\n  `.#agentbox-prebuilt` package runtime environment)\n- `buildah` for experimental `agentbox microvm` cache misses, for `agentbox\n  microvm --storage btrfs-snapshot` task-rootfs snapshot/delete operations, and\n  for loftd's default `btrfs-snapshot` Buildah image-source transaction;\n  included by the Nix `.#agentbox` and `.#agentbox-prebuilt` package runtime\n  environments. Agentbox cache-miss ingestion is\n  rootless and runs as one `buildah unshare` transaction so Buildah storage,\n  mount, copy, and cleanup share the same user namespace; the Rust ingestion\n  child creates a btrfs subvolume cache rootfs when supported, then copies with\n  `cp -a --reflink=auto` so CoW filesystems can avoid full data copies while\n  non-reflink filesystems keep the portable fallback. Existing digest-keyed\n  microvm cache hits do not require Buildah unless the selected storage backend\n  is `btrfs-snapshot`.\n- `libkrun.so` at runtime for experimental `agentbox microvm` and `loftd`\n  direct boot. The normal host binaries do not link to libkrun at build time;\n  the Nix `.#agentbox` package wraps the binary with this repo's\n  libkrun/libkrunfw library path, and source/debug builds can set\n  `AGENTBOX_LIBKRUN_LIBRARY=/path/to/libkrun.so.1` for agentbox microvm or\n  `LOFTD_LIBKRUN_LIBRARY=/path/to/libkrun.so.1` for loftd.\n- `btrfs`, `mkfs.btrfs`, and `blkid` on the host for microvm btrfs-snapshot\n  storage, first-time libkrun/microvm raw-image creation, and reuse validation\n  (`btrfs-progs` + `util-linux`; included in `nix develop`, and `btrfs` is\n  included in the Nix `.#agentbox` and `.#agentbox-prebuilt` runtime wrappers).\n  Task-rootfs btrfs snapshot and delete commands run through `buildah unshare`.\n  Rootless btrfs-snapshot cleanup also requires the backing btrfs mount to allow\n  user-owned subvolume removal; add `user_subvol_rm_allowed` to that mount's\n  options when using this fast path.\n- `/dev/net/tun` on the host for libkrun mode, passed through to the guest so\n  nested rootless Podman can set up TUN-backed networking.\n- default libkrun mode requires Podman using the custom crun/libkrun stack that\n  supports `krun_add_disk` annotations plus guest kernel overlay and btrfs\n  support.\n\n---\n\n## Development\n\n```bash\nnix develop\ncargo build\ncargo test\n```\n\n`nix develop` opens `fish` + `starship` by default. Keep your current shell:\n\n```bash\nAGENTBOX_DISABLE_AUTO_FISH=1 nix develop\n```\n\nInside the agentbox container, `nix` is invoked through a small compatibility\nwrapper that clears the entrypoint's NSS wrapper preload before running the real\nNix binary. This prevents nested dev shells from mixing the container NSS preload\nwith a different glibc from the shell's realized dependencies. If you are using\nan older image without that wrapper, use this temporary workaround:\n\n```bash\nenv -u LD_PRELOAD -u NSS_WRAPPER_PASSWD -u NSS_WRAPPER_GROUP nix develop\n```\n\nThe container also enables GrapheneOS `hardened_malloc` for Nix-linked dynamic\nbinaries through `/etc/ld-nix.so.preload`, matching NixOS' allocator preload\nmechanism rather than setting a global allocator `LD_PRELOAD`. `rustc` and\n`rust-analyzer` are started through wrappers that mask `/etc/ld-nix.so.preload`\nfor those processes so they keep the default allocator. Foreign/FHS glibc\nbinaries usually read `/etc/ld.so.preload` instead of `/etc/ld-nix.so.preload`,\nwhile static or musl binaries generally ignore both files. For a specific\nforeign/FHS command, opt in with:\n\n```bash\nhardening-run some-foreign-binary --flag\n```\n\n`hardening-run` sets `LD_PRELOAD` only for the wrapped command, so the usual\nopt-out remains:\n\n```bash\nenv -u LD_PRELOAD some-foreign-binary --flag\n```\n\n---\n\n## Build\n\n```bash\nnix build .#loftd\nnix build .#agentbox-prebuilt\nnix build .#loftd-prebuilt\nnix build .#agentbox-musl\nnix build .#rtk-prebuilt\nnix build .#reasonix\nnix build .#libkrunfw\nnix build .#libkrun\nnix build .#crun\nnix build .#podman\nnix build .#container-lib-policy-seccomp-json\nnix build .#container\n```\n\n### Build outputs\n\n- `.#agentbox`: compile from source.\n- `.#loftd`: compile from source as the dynamic host `loftd` package. It uses\n  the same Rust package output as `.#agentbox`, which wraps both host binaries\n  with this flake's runtime library path. The stable raw release payload is\n  also available at `libexec/loftd`; `bin/loftd` remains the wrapped CLI for\n  normal use.\n- `.#agentbox-prebuilt`: install pinned published binary (currently pinned for\n  `x86_64-linux`; use `.#agentbox` elsewhere). This package brings\n  `fuse-overlayfs` and `buildah` into the runtime environment for\n  `agentbox container` sidecar mode and experimental `agentbox microvm`\n  cache misses.\n- `.#loftd-prebuilt`: install a pinned published raw-ELF `loftd` asset and\n  wrap it with this flake's runtime tools and `libkrun`/`libkrunfw` library\n  path. If a system lacks a pinned raw-ELF asset, it fails with a clear\n  not-pinned message until a matching raw-ELF `sha-*` release is published and\n  pinned.\n- `.#agentbox-musl`: static/musl `agentbox`, `agentbox-guest-init`, and\n  `loftd-guest-init` binaries for image/guest use. It intentionally does not\n  build or expose `bin/loftd`; the host `loftd` binary is always dynamically\n  linked so it can load `libkrun.so`/`libkrunfw.so` from the package or dev\n  shell runtime library path.\n- `.#reasonix`: build the pinned DeepSeek-Reasonix CLI from the release source rev.\n- `.#rtk-prebuilt`: install the pinned published RTK release asset (currently\n  pinned for `x86_64-linux`).\n- `.#libkrunfw`: install the pinned `zeroqn/libkrunfw` release asset for the\n  current system.\n- `.#libkrun`: build libkrun 1.18.0 from source (overrides nixpkgs 1.17.4)\n  with net, sound, GPU, block, and input support enabled.\n- `.#crun`: build `zeroqn/crun` branch `agentbox` with this repo's libkrun\n  override, krun handler support, raw data disk annotation support,\n  `krun.nested_virt` support, and `pkgs.passt` on crun's runtime `PATH`.\n- `.#podman`: build Podman against the custom crun for libkrun/raw-image\n  development.\n- `.#container-lib-policy-seccomp-json`: install the pinned\n  `containers/container-libs` `common/pkg/seccomp/seccomp.json` policy at\n  `share/containers/seccomp.json` for downstream flakes or image reuse.\n- `.#container`: loftd-compatible Podman image archive named\n  `localhost/loftd:latest`. This is the only container image build target; it\n  packages both `loftd-guest-init` and `agentbox-guest-init`, so agentbox also\n  uses it by default.\n\n### Nix store / DB diagnostics\n\n`nix build .#container` depends on a static image metadata linter before\nrunning the layered image build command. To run only that linter:\n\n```bash\nnix build .#checks.$(nix eval --raw --impure --expr builtins.currentSystem).container-nix-db-metadata\n```\n\nThe check compares store paths referenced by the image Docker config/env against\nthe `pkgs.closureInfo { rootPaths = layers.imageContents; }` store-path list.\nThat is the same closure Docker Tools loads into the image Nix DB when\n`includeNixDB = true`. It fails fast when image metadata can pull a store path\ninto `/nix/store` without that path being covered by generated image Nix DB\nmetadata. This check does not inspect or mutate the host Nix DB.\n\nInside an agentbox container, run the packaged live DB scanner manually:\n\n```bash\nagentbox-nix-store-db-check\n```\n\nThe runtime checker compares present `/nix/store/\u003chash\u003e-name` entries with\n`nix path-info --all`, ignores the internal `/nix/store/.links` link farm and\ntransient `*.lock` files, and prints `nix-store --verify-path` evidence for\npresent-but-invalid paths. When the libkrun Nix disk upperdir is visible at\n`/run/agentbox/nix-disk/upper`, failures also compare each invalid store object\nwith `/run/agentbox/nix-disk/upper/store/\u003cname\u003e` and report whether that\nstore-layer object is present in the upperdir or not found there. This is\nstore-layer evidence only, not root-cause proof: absence from the upperdir is\nnot proof that lower image metadata is correct or that the lower image is at\nfault. If `upper/var/nix` or `upper/var/nix/db` exists, the checker reports it\nonly as metadata-shadow context. It is diagnostic only and never repairs or\nmutates the Nix DB.\n\n---\n\n## Quick start\n\nShow CLI help:\n\n```bash\nnix develop --command cargo run -p agentbox-host -- --help\n```\n\nBuild image + loftd binary, then show the loftd CLI:\n\n```bash\nnix build .#container\npodman load \u003c result\nnix build .#loftd\n./result/bin/loftd --help\n```\n\nImage selection behavior:\n\n- default: `localhost/loftd:latest`\n- fallback: `ghcr.io/zeroqn/loftd:latest`\n\n### Packaged seccomp policy\n\nThe image includes the pinned `containers/container-libs` seccomp policy package\nand writes global `/etc/containers/containers.conf` with:\n\n```toml\n[containers]\nseccomp_profile = \"/nix/store/...-container-lib-policy-seccomp-json-.../share/containers/seccomp.json\"\n```\n\nThis makes inner Podman use the packaged policy by default while still allowing\nper-user containers config to override it. To refresh the policy, update the\n`containerLibPolicySeccompJson` revision/hash in `nix/pins.nix`, then rebuild\n`.#container-lib-policy-seccomp-json` and `.#container`.\n\nForce GHCR latest:\n\n```bash\n./result/bin/agentbox --pull-latest\n```\n\nOverride image explicitly:\n\n```bash\nAGENTBOX_IMAGE=\u003cimage-ref\u003e ./result/bin/agentbox\n# or\n./result/bin/agentbox --image \u003cimage-ref\u003e\n```\n\nEnable debug logging for troubleshooting agentbox-managed Podman commands:\n\n```bash\n./result/bin/agentbox --debug\n./result/bin/agentbox container sidecar --debug\n```\n\n`--debug` passes `--log-level=debug` to Podman commands that agentbox runs,\nincluding task launch, sidecar setup, image inspection/mounting, health probes,\nand cleanup paths. It also allows guest-side diagnostic reports to use stderr.\n\nCollect agentbox component timings:\n\n```bash\n./result/bin/agentbox --profile --debug\n./result/bin/agentbox container --profile --debug\n./result/bin/agentbox microvm --profile --debug\n```\n\n`--profile` enables timing collection. Timings are printed only when `--debug`\nis also set, and reports are written to stderr so stdout remains reserved for\ncommand output. `--profile` without `--debug` enables measurement but suppresses\nreports; `--debug` without `--profile` does not print timing reports. Container\nand libkrun task runs emit `agentbox-guest-init` timings. Microvm runs also emit\na host-side `agentbox microvm host profile` report for completed profiled host\nphases such as image reference resolution, image cache lookup/ingestion, task\nrootfs materialization, guest-init lookup, persistent disk preparation, launch\nconfig build, helper session, task rootfs unmount, and task state cleanup.\nLibkrun background Podman prep/wait workers and sidecar debug runs do not emit\nguest-init profile reports.\nWhen libkrun `/nix` overlay bootstrap runs, nested\n`bootstrap-nix:*` rows break down disk discovery, mount/preseed work, daemon\nstartup, and the `bootstrap-nix:wait-socket` polling loop.\n\nEnter the final task shell as root when root-only operations are needed:\n\n```bash\n./result/bin/agentbox --root\n./result/bin/agentbox --root libkrun\n./result/bin/agentbox --root container\n```\n\nBy default, agentbox drops the interactive shell to the host/dev identity.\n`--root` is an explicit opt-in that keeps only the final task shell/command as\nroot inside the guest/container; it does not install or require `sudo`.\nBecause `--root` is global, `agentbox --root container sidecar` parses, but\nsidecar-only mode starts no final task shell so the flag is a harmless no-op\nthere.\n\nTask containers, including libkrun-backed tasks, are named with the current\nrepo/workspace slug followed by a unique suffix. For example, a checkout named\n`my-repo` appears in `podman ps` as `my-repo-\u003csuffix\u003e`, making active tasks easy\nto map back to their repo.\n\n---\n\n## Runtime modes\n\n### 1) Libkrun mode (default)\n\nRun:\n\n```bash\n./result/bin/agentbox\n./result/bin/agentbox libkrun\n./result/bin/agentbox libkrun --mem 8\n./result/bin/agentbox libkrun --tsi\n./result/bin/agentbox libkrun --publish 127.0.0.1:8080:8080\n```\n\n`agentbox` with no subcommand defaults to libkrun. Runtime-specific libkrun\noptions are accepted under the `libkrun` subcommand.\n\nInside the shared loftd image, the configured image entrypoint is\n`loftd-guest-init enter --`. Agentbox does not depend on that image\nentrypoint: it explicitly starts `/bin/agentbox-guest-init default enter --`\nfrom the same image. That default agentbox guest entrypoint selects the\nexplicit `libkrun` guest runtime when agentbox passes `AGENTBOX_LIBKRUN_*`\nenvironment flags; otherwise it falls back to the explicit `container` guest\nruntime. The explicit `agentbox-guest-init container enter` path does not\nswitch to libkrun.\n\nOn first run, agentbox creates two sparse btrfs raw images:\n\n```text\n\u003cstate-root\u003e/libkrun-nix.raw\n\u003cstate-root\u003e/libkrun-containers.raw\n```\n\nEach default apparent size is `64 GiB`. Because the files are sparse, host disk\nusage grows as blocks are written, but guest-visible capacity is still each raw\nfile's apparent size at VM start.\n\nThe raw images are attached with crun annotations:\n\n```text\nrun.oci.handler=krun\nkrun.ram_mib=\u003cmemory MiB\u003e\nkrun.cpus=\u003ccpu count\u003e\nkrun.nested_virt=1\nkrun.disk.0.path=\u003cstate-root\u003e/libkrun-nix.raw\nkrun.disk.0.id=agentbox-nix\nkrun.disk.0.readonly=false\nkrun.disk.1.path=\u003cstate-root\u003e/libkrun-containers.raw\nkrun.disk.1.id=agentbox-containers\nkrun.disk.1.readonly=false\nkrun.use_passt=1\n--device /dev/net/tun:/dev/net/tun\n--publish \u003cpublish-spec\u003e\n```\n\nBy default, agentbox sizes libkrun memory to 80% of host memory, rounded down to\nwhole GiB, and emits that value with `krun.ram_mib=\u003cMiB\u003e`. Pass\n`agentbox libkrun --mem \u003cGiB\u003e` to override it. On Linux, agentbox also emits\n`krun.cpus=\u003cn\u003e`: hosts with up to 6 CPUs pass all available CPUs through;\nlarger hosts reserve 2 CPUs for the host.\n\nAgentbox also emits `krun.nested_virt=1` so crun/libkrun expose VMX/SVM to the\nlibkrun guest when the host or outer VM already supports nested KVM. This does\nnot bind-mount host `/dev/kvm` into the guest and cannot enable nested KVM if\nthe host kernel or outer hypervisor has disabled it. During guest root prep,\n`agentbox-guest-init` makes an exposed guest `/dev/kvm` world-accessible so the\ndefault non-root `dev` task shell can use nested KVM.\n\nBy default, libkrun mode uses passt networking through `krun.use_passt=1`. Pass\n`agentbox libkrun --tsi` to switch to the older TSI/proxy environment path.\nPublish inbound ports with repeatable `agentbox libkrun --publish \u003cSPEC\u003e` or\n`agentbox libkrun -p \u003cSPEC\u003e`. `\u003cSPEC\u003e` is passed through to Podman using\nPodman's publish syntax, for example `8080:80`, `127.0.0.1:8080:80`,\n`127.0.0.1::80`, `8080:80/udp`, or `8000-8010:80-90`. Agentbox does not\nrewrite the host bind address; include `127.0.0.1:` when the published port\nshould be loopback-only. Port publishing requires default passt networking and\nis rejected with `--tsi`. It applies only to interactive libkrun tasks, not\n`resize` or `reset-nix` maintenance runs.\n\nDuring libkrun guest bootstrap, `agentbox-guest-init` sets\n`kernel.dmesg_restrict=1` so kernel logs are root-only inside the guest; the\ndefault `dev` shell cannot read `dmesg`.\n\nFor guest-side debugging, test a modified `agentbox-guest-init` without\nrebuilding the container image by building only the static guest-init binary and\nbind-mounting it over the in-image guest-init path:\n\n```bash\nnix build .#agentbox-musl -o result-musl\n./result/bin/agentbox libkrun --guest-init ./result-musl/bin/agentbox-guest-init\n```\n\nThis keeps the normal image entrypoint and shell arguments intact, but the\nentrypoint executes the host-provided `agentbox-guest-init` binary. `agentbox`\nderives the in-image mount target from the selected image's first entrypoint\nelement with `podman image inspect`, so this works with the default image,\n`--image`, and `AGENTBOX_IMAGE` without a separate target-path environment\nvariable. The selected image must already be local and inspectable unless you\nused an existing path such as `--pull-latest` that pulls it before inspection.\n\nExisting raw images are reused only if `blkid` reports btrfs. Agentbox refuses\nto overwrite invalid existing images.\n\nRestart-time btrfs auto-grow is not performed. To grow an existing\nagentbox-managed libkrun raw image, use the explicit resize command:\n\n```bash\n./result/bin/agentbox libkrun resize --target nix --size 128G\n./result/bin/agentbox libkrun resize --target containers --size 128G\n```\n\nTargets are limited to the current workspace's managed raw images:\n\n- `nix`: `\u003cstate-root\u003e/libkrun-nix.raw`\n- `containers`: `\u003cstate-root\u003e/libkrun-containers.raw`\n\nBare integer sizes are interpreted as GiB. Supported binary suffixes include\n`G`, `GiB`, `T`, and `TiB`. Resize is grow-only: shrinking and equal-size no-op\nrequests are rejected. The command validates that the selected managed image\nexists, is a regular file, and is btrfs before it extends the sparse raw file.\nIt then starts a one-shot libkrun guest-init maintenance task to mount the\nselected btrfs disk privately under `/run/agentbox/resize-*` and run\n`btrfs filesystem resize max`.\n\nResize launches a direct one-shot `agentbox-guest-init` entrypoint, so the\nselected image must be local and inspectable before host-side growth occurs. Use\n`--pull-latest` or pre-load/build the image if needed.\n\nThe resize command refuses to run if Podman reports a running container with a\nmatching `krun.disk.*.path` annotation, and it fails closed if that live-state\nprobe cannot complete. It does not live-resize active disks, does not auto-grow\nduring normal `agentbox libkrun` startup, does not accept arbitrary image paths,\nand does not reset or migrate state. Avoid starting a libkrun task concurrently\nwith resize; the live-state check cannot eliminate every race between the probe\nand the one-shot maintenance task.\n\nIf the host raw file is enlarged but the one-shot guest filesystem resize fails,\nagentbox reports the failure as retryable. Fix the reported guest issue and\nrerun the same resize command; agentbox will not shrink, roll back, or reset the\nraw image automatically. Full end-to-end verification requires a real libkrun\nguest with the raw disk mounted, so this path should be manually smoke-tested in\naddition to the host and guest unit tests.\n\nTo discard the current workspace's managed libkrun `/nix` disk and recreate it\nat the default size, use the explicit reset command:\n\n```bash\n./result/bin/agentbox libkrun reset-nix --force\n```\n\n`reset-nix` only targets `\u003cstate-root\u003e/libkrun-nix.raw`; it does not reset the\ncontainers raw image, run any guest VM maintenance step, migrate state, create a\nbackup, or prompt interactively. `--force` is required: without it the command\nfails before probing Podman or touching the filesystem. With `--force`, agentbox\nfirst refuses to proceed if Podman reports any running container with a matching\n`krun.disk.*.path` annotation, then deletes the existing managed `/nix` raw file\nif present and creates a fresh default btrfs image. Non-file paths at the managed\nimage location are refused instead of removed.\n\nNo live auto-resize, state migration, snapshot/rollback UX, direct microvm\nhost-port helper UX, rootful nested Podman workflow, or container-mode\nnested-Podman support is implemented.\n\nManual host smoke checklist for the nested rootless Podman runtime:\n\n1. Build and load `.#container`, then start default libkrun mode on the host.\n2. Inside the guest, confirm the shell is `dev` and run `podman info`; the\n   `podman` compatibility command waits for rootless Podman prep to finish,\n   then execs real Podman. Verify rootless mode and storage driver `btrfs`.\n3. Confirm the Docker-compatible API endpoint is exported:\n\n   ```bash\n   echo \"$DOCKER_HOST\"\n   ```\n\n   `DOCKER_HOST` should be `unix:///run/user/\u003cuid\u003e/podman/podman.sock`. The\n   socket is created lazily by Docker-compatible commands rather than by guest\n   shell entry or direct `podman`.\n4. Run `docker info`; it should use the Docker compatibility wrapper, wait for\n   Podman prep if needed, start or repair the rootless Podman API socket, and\n   report the same rootless Podman storage instead of starting `dockerd`.\n   After this, the socket should exist and accept remote Podman requests:\n\n   ```bash\n   test -S \"$XDG_RUNTIME_DIR/podman/podman.sock\"\n   podman --remote --url \"$DOCKER_HOST\" info\n   ```\n\n   The socket is a rootless Podman API endpoint for the `dev` user. It is less\n   privileged than a rootful Docker daemon socket, but still grants API-level\n   control over that user's containers and images, so treat it as a trusted\n   in-guest development interface.\n5. Confirm `/dev/net/tun` exists inside the guest, then run both:\n\n   ```bash\n   podman run --rm docker.io/library/alpine:latest echo hello\n   docker run --rm docker.io/library/alpine:latest echo hello\n   docker-compose version\n   ```\n\n6. Exit and restart agentbox; verify pulled Podman image/storage persists via\n   `\u003cstate-root\u003e/libkrun-containers.raw`. Runtime state should live under\n   `/home/dev/.local/share/containers/storage`; `/var/lib/docker`,\n   `/var/lib/containerd`, and `/home/dev/.local/share/docker` should be absent.\n7. For Podman troubleshooting, inspect `/run/agentbox/podman-prep.status`,\n   `/run/agentbox/podman-prep.log`, and\n   `$XDG_RUNTIME_DIR/podman/podman.sock`. Use\n   `agentbox-guest-init libkrun podman wait` to wait only for prep readiness,\n   or `agentbox-guest-init libkrun podman service-wait` to also start/repair\n   the Docker-compatible Podman API socket.\n8. Confirm no fuse-overlayfs path/config/binary is required by rootless Podman\n   setup.\n\nLibkrun mode intentionally does **not** use the container sidecar/overlay bridge,\ndoes **not** set `AGENTBOX_NIX_PROXY_HOST`, does **not** fall back to seeded Nix\nstate, and does **not** use fuse-overlayfs for nested rootless Podman storage.\n\n---\n\n### 2) Container mode\n\nRun:\n\n```bash\n./result/bin/agentbox container\n```\n\nWhat container mode does (high level):\n\n1. Resolves the selected image and mounts its filesystem.\n2. Uses image `/nix` as `lowerdir` for host `fuse-overlayfs`.\n3. Builds an external merged Nix tree under project state.\n4. Starts/reuses a deterministic native Podman `nix-daemon` sidecar daemon.\n5. Preserves that sidecar while matching task containers are still running.\n6. Starts the interactive container with read-only `/nix` + daemon socket.\n7. When the last matching task container exits, removes the idle sidecar and\n   unmounts the `nix-merged` FUSE overlay in the matching Podman mount\n   namespace so `fuse-overlayfs` does not linger.\n\nOverlay writes live in `\u003cstate-root\u003e/nix-upper`; `nix-merged` is only the\nmounted merged view and may be unmounted/recreated between runs.\n\nSidecar metadata is saved at:\n\n```text\n\u003cstate-root\u003e/nix-sidecar.state\n```\n\nNew sidecar metadata is container-only. Legacy metadata from older libkrun/TSI\nsidecar experiments is tolerated for safe cleanup/recreate decisions, but it is\nnot reused as the current native sidecar configuration while matching legacy task\ncontainers are still active.\n\nContainer mode always requires the managed sidecar. No direct/no-sidecar\ncontainer mode is currently implemented.\n\n#### Sidecar debugging\n\nStart or reuse just the container nix-daemon sidecar stack, print the sidecar\nname and host proxy port, and exit without launching the interactive task\ncontainer:\n\n```bash\n./result/bin/agentbox container sidecar\n```\n\n`agentbox container sidecar` intentionally leaves the sidecar container and\nmerged nix overlay running after exit so they can be inspected. It skips the\nnix-daemon socket health probe so a broken daemon can still be debugged after\ncontainer startup.\n\nUse the printed sidecar name for inspection and cleanup, for example:\n\n```bash\npodman logs \u003csidecar-name\u003e\npodman port \u003csidecar-name\u003e 19876\npodman rm -f \u003csidecar-name\u003e\n```\n\n---\n\n### 3) Microvm mode (experimental)\n\nRun/help:\n\n```bash\n./result/bin/agentbox microvm --help\n./result/bin/agentbox microvm --storage auto\n./result/bin/agentbox microvm --storage btrfs-snapshot\n./result/bin/agentbox microvm --storage fuse-overlay\n./result/bin/agentbox microvm --storage reflink\n```\n\n`agentbox microvm` is an explicit experimental task-based direct-libkrun runtime.\nIt is intentionally separate from the current Podman-backed `libkrun` mode. The\nmicrovm path does not call the Podman-backed image resolver, `podman run`,\n`crun`, or `runc`; cache misses require the microvm-owned Buildah ingestion\npath, and `agentbox --pull-latest microvm` currently fails clearly instead of\nreusing Podman semantics.\n\nCurrent implemented milestone:\n\n- image references are resolved against a global per-user immutable cache under\n  the agentbox state root;\n- digest-pinned references hit by digest;\n- mutable tags may hit only through local ref-to-digest metadata, which is a\n  cache hint rather than an authoritative freshness check;\n- cache misses are ingested through the microvm-owned rootless Buildah path:\n  one `buildah unshare` transaction runs the hidden Rust ingestion child, which\n  performs `buildah from`, `buildah inspect --format '{{.FromImageDigest}}'`,\n  `buildah mount`, opportunistically creates a btrfs subvolume cache rootfs,\n  copies into the digest-keyed cache with `cp -a --reflink=auto`, validates\n  exact-one executable `agentbox-guest-init`, atomically finalizes the\n  compatibility marker, then performs explicit mount/container/staging cleanup;\n- per-task writable rootfs directories are materialized from compatible cached\n  roots through explicit copy-on-write storage methods. `btrfs-snapshot` uses a\n  writable btrfs subvolume snapshot and deletes it through `buildah unshare`;\n  rootless deletion requires the backing btrfs mount option\n  `user_subvol_rm_allowed`. `fuse-overlay` mounts a real `fuse-overlayfs`\n  merged root from cached lower plus per-task upper/work dirs, and explicit\n  `reflink` requires `cp -a --reflink=always`. Plain recursive task-rootfs\n  copies are not used. Normal cleanup deletes task subvolumes, unmounts any task\n  overlay, and removes the task state dir; `--preserve-debug` intentionally\n  preserves the task rootfs for inspection;\n- the parent process prepares two per-workspace sparse btrfs raw disks:\n\n  ```text\n  \u003cstate-root\u003e/microvm-nix.raw\n  \u003cstate-root\u003e/microvm-containers.raw\n  ```\n\n  Each disk has a default apparent size of `64 GiB` and is reused only when the\n  existing file validates as btrfs. Invalid existing files are refused rather\n  than reformatted automatically;\n- the parent process writes a std-only `KEY=hex-encoded-value` launch config,\n  starts a hidden same-binary helper, waits for the helper status, maps that\n  status back to the `agentbox microvm` exit code, and still cleans the task\n  rootfs after helper failure;\n- the helper dynamically loads `libkrun.so` using `AGENTBOX_LIBKRUN_LIBRARY`\n  when set, otherwise by normal soname lookup. The Nix package supplies the\n  libkrun/libkrunfw library path for the normal packaged path. After loading, it\n  creates a context, sets CPU/memory, sets the task rootfs, attaches `/nix` and\n  container-store disks through `krun_add_disk`, disables libkrun's implicit\n  console, wires stdio through `krun_add_virtio_console_default(0, 1, 2)`, adds\n  the workspace virtiofs device, sets workdir/exec and env through\n  `krun_set_exec`, then calls `krun_start_enter()`;\n- inside the guest, `agentbox-guest-init microvm enter` mounts the workspace\n  virtiofs tag at `/workspace`, starts reusable Nix and rootless container-store\n  preparation against the attached disks, then drops to the host/dev identity and\n  execs the default `fish -l` shell.\n\nCurrent limitations: networking relies on libkrun's no-passt/TSI default path, direct\nmicrovm inbound port publishing is intentionally unavailable, terminal resize has only the\nnarrow default virtio-console hook wired so far, and real VM smoke validation is\nstill pending. See `docs/microvm-smoke.md` for the manual smoke checklist and\ncurrent not-tested items.\n\nThe storage policy values are:\n\n- `auto`: try `btrfs-snapshot` first, then clean partial output and try the\n  `fuse-overlayfs` fallback. `auto` does not select `reflink`.\n- `btrfs-snapshot`: require `buildah unshare btrfs subvolume snapshot` for\n  task-rootfs materialization and `buildah unshare btrfs subvolume delete` for\n  cleanup; fail instead of falling back to another backend. Rootless cleanup\n  requires the backing btrfs mount to include `user_subvol_rm_allowed`; if\n  cleanup reports `Operation not permitted`, inspect the mount with\n  `findmnt -T '\u003ctask-rootfs\u003e' -o TARGET,SOURCE,FSTYPE,OPTIONS`, add\n  `user_subvol_rm_allowed` to the matching `/etc/fstab` btrfs entry, remount\n  with `sudo mount -o remount,user_subvol_rm_allowed \u003cmountpoint\u003e`, and retry\n  `buildah unshare btrfs subvolume delete '\u003ctask-rootfs\u003e'`. Existing\n  non-subvolume cache entries may need refresh before this explicit mode works.\n- `fuse-overlay`: require the portable `fuse-overlayfs` image-rootfs path with\n  cached image rootfs as lowerdir and per-task upper/work/merged dirs.\n- `reflink`: explicit opt-in only; require `cp -a --reflink=always` for\n  task-rootfs materialization and fail instead of falling back to byte-for-byte\n  file copies.\n\nThe shorthand `btrfs` storage policy remains intentionally rejected; use the\nprecise `btrfs-snapshot` policy for snapshot-backed task roots.\n\nImage selection remains global through `--image` or `AGENTBOX_IMAGE`; microvm\ndoes not add a runtime-local image flag.\n\nFailure diagnostics are phase-classified around cache ingestion, storage backend\nselection, task rootfs materialization, guest-init resolution, persistent disk\npreparation, launch config construction, helper/libkrun launch, task rootfs\nunmount, and task state cleanup. If `--preserve-debug` is set and a failure\nhappens after task rootfs materialization, the error reports the preserved task\nrootfs, task state directory, expected `launch.conf` path, and for fuse-overlay\ntasks an explicit unmount hint for later cleanup. Preserved btrfs-snapshot\ntasks report the matching `buildah unshare btrfs subvolume delete` cleanup\ncommand and point permission-denied cleanup failures at the btrfs\n`user_subvol_rm_allowed` mount option.\n\n---\n\n### 4) Loftd extraction (Phase 4 complete)\n\n`loftd` is the extracted direct-libkrun microvm runtime owner. Phase 4 is\ncomplete: the implementation builds a typed launch plan, uses Buildah as the\ndurable OCI image source for the default btrfs path, materializes a per-task\nbtrfs snapshot rootfs, prepares loftd-owned persistent raw btrfs disks for\n`/nix` and rootless container storage, starts a same-binary\n`loftd internal libkrun-enter` helper to call libkrun, and enters the guest\nthrough `loftd-guest-init enter`. The parent process owns task-rootfs cleanup,\nwith best-effort cleanup on unwind and `--preserve-debug` for manual inspection.\nThe explicit `fuse-overlay` backend is still a future slice.\n\nRun/help:\n\n```bash\n./result/bin/loftd --help\n./result/bin/loftd --rootfs-backend btrfs-snapshot\n./result/bin/loftd --rootfs-backend fuse-overlay\n./result/bin/loftd --pull-latest\n./result/bin/loftd --image ghcr.io/example/loftd:dev\n./result/bin/loftd -- bash -lc 'echo ok'\n```\n\nImage selection is materialized through Buildah for the btrfs-snapshot path: with no\nimage option, loftd first inspects `localhost/loftd:latest` and uses it with\n`--pull=never` when present, otherwise loftd uses `ghcr.io/zeroqn/loftd:latest`\nwith `--pull=missing`. The flake's canonical `.#container` output builds that\nlocal `localhost/loftd:latest` image with `loftd-guest-init enter` as its guest\ncontract. `--pull-latest` uses the canonical image with `--pull=always`, and\n`--image` uses exactly the supplied image reference with `--pull=missing`.\n`--image` and `--pull-latest` are mutually exclusive.\n\nLoftd uses **task rootfs backend** terminology for the host-side mechanism that\nmaterializes the clean task root filesystem. The default backend is\n`btrfs-snapshot`: one `buildah unshare` transaction creates a temporary Buildah\nworking container, mounts the selected image rootfs, validates exactly one\nexecutable `loftd-guest-init`, snapshots the mounted rootfs into loftd task\nstate, and removes the Buildah working container. There is no `auto` backend,\nno initial loftd `reflink` backend, and no copy/reflink fallback for the default\nbtrfs path; choose `fuse-overlay` explicitly when the future portable overlay\npath is wanted.\n\nOn a successful btrfs-snapshot run, loftd then resolves the image's executable\n`loftd-guest-init`, writes a private hex-encoded `launch.conf` under the task\nstate directory, and supervises `loftd internal libkrun-enter \u003claunch.conf\u003e`.\nThe helper dynamically loads `libkrun.so.1` or `libkrun.so` (or\n`LOFTD_LIBKRUN_LIBRARY` when set), attaches the task rootfs, the `/workspace`\nvirtiofs mount, and two writable persistent disks:\n\n- `loftd-nix.raw` exposed to the guest as `LOFTD_NIX` / `loftd-nix` for `/nix`;\n- `loftd-containers.raw` exposed as `LOFTD_CONTAINERS` / `loftd-containers` for\n  rootless container storage.\n\n`loftd-guest-init enter` reads only `LOFTD_*` guest contract variables, mounts\nthe workspace before identity drop, prepares the persistent cache disks, exports\nthe shell environment, and runs `fish -l` by default. For deterministic smoke\ntests, `loftd -- \u003ccommand\u003e` preserves the same guest bootstrap path but replaces\nthe final guest command with the explicit argv after `--`.\n\nPhase 4 completion was validated with targeted `loftd` and `loftd-guest-init`\nunit tests plus a focused local-image libkrun smoke test. The smoke used a local\n`localhost/loftd:latest` image and verified Buildah-backed btrfs rootfs\nmaterialization, persistent disk preparation, launch-config handoff, and a\nsuccessful libkrun guest-init entry. Full public-image publication and broader\nguest-bootstrap hardening are follow-on work.\n\nLoftd config lives at:\n\n```text\n$XDG_CONFIG_HOME/loftd/loftd.toml\n```\n\nor, when `XDG_CONFIG_HOME` is unset:\n\n```text\n$HOME/.config/loftd/loftd.toml\n```\n\nSupported launch-planning keys are:\n\n```toml\n[state]\nlocation = \"/home/dev/loftd-state\"\n\n[task-rootfs]\nbackend = \"btrfs-snapshot\" # or \"fuse-overlay\"\n```\n\n`[state].location` changes the base loftd state location; loftd appends\n`/loftd/\u003cworkspace-slug\u003e`. `--rootfs-backend` overrides\n`[task-rootfs].backend` for a single run.\n\n---\n\n## Persistent host mounts\n\nEach run ensures and mounts:\n\n- `~/.codex` -\u003e `/home/dev/.codex`\n- `~/.pi` -\u003e `/home/dev/.pi`\n- `\u003cstate-root\u003e/cargo` -\u003e `/home/dev/.cargo`\n\nThis keeps Codex, Pi, and Cargo state outside the repo.\n\n---\n\n## State root and config\n\nDefault state root:\n\n```text\n$XDG_STATE_HOME/agentbox/\u003crepo-slug\u003e\n```\n\nFallback when `XDG_STATE_HOME` is unset:\n\n```text\n$HOME/.local/state/agentbox/\u003crepo-slug\u003e\n```\n\nOverride base location in:\n\n```text\n$XDG_CONFIG_HOME/agentbox/agentbox.toml\n```\n\nor:\n\n```text\n$HOME/.config/agentbox/agentbox.toml\n```\n\nExample:\n\n```toml\n[state]\nlocation = \"/home/dev/xxx/\"\n```\n\nThis makes the base `/home/dev/xxx/agentbox`.\n\nAgentbox also keeps a shared sccache at:\n\n```text\n\u003cstate.location\u003e/agentbox/sccache\n```\n\nThat directory is bind-mounted into each task container at\n`/home/dev/.cache/sccache`, so compiler cache entries are reused across\nagentbox repos and containers.\n\n---\n\n## Container environment summary\n\nThe container provides:\n\n- interactive `fish` + `starship`\n- Codex CLI, bubblewrap (`bwrap`), Pi (`pi`), Reasonix (`reasonix`/`dsnix`), and `oh-my-codex` (`omx`)\n- cargo-deny and Symposium (`cargo-agents`, invoked as `cargo agents`)\n- prebuilt OMX native helpers (`omx-api`, `omx-runtime`, `omx-sparkshell`, and `omx-explore-harness`) with matching `OMX_*` binary override environment variables preset\n- Python 3 (`PyYAML`, Tree-sitter, Tree-sitter Rust parser), Node.js\n- Rust toolchain (`cargo`, `rustc`, `clippy`, `rustfmt`, `rust-analyzer`, `sccache`, `mold`)\n- `gcc`, `musl`, `clang`\n- GrapheneOS `hardened_malloc` enabled for Nix-linked dynamic binaries through `/etc/ld-nix.so.preload`, plus `hardening-run` for per-command foreign/FHS `LD_PRELOAD` opt-in\n- RTK (`rtk`)\n- libkrun 1.18.0 (`libkrun.so`) plus pinned `libkrunfw.so` for nested KVM support inside the container\n- `nix` wrapper that clears the container NSS wrapper preload before invoking\n  the real Nix binary, avoiding glibc-version mismatches in nested dev shells\n- `agentbox-nix-store-db-check` for non-mutating live `/nix/store` vs Nix DB\n  validity diagnostics, including cautious libkrun upperdir store-layer\n  evidence when `/run/agentbox/nix-disk/upper` is visible\n- `rustc` and `rust-analyzer` wrappers that mask `/etc/ld-nix.so.preload` so\n  both tools keep the default allocator\n- `CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER` preset to the bundled\n  `clang_mold_wrapper` helper for the `x86_64-unknown-linux-gnu` target\n- `LIBCLANG_PATH` preset to the bundled Nix `libclang` library directory\n- `RUSTC_WRAPPER`, `CMAKE_C_COMPILER_LAUNCHER`, and `CMAKE_CXX_COMPILER_LAUNCHER` preset to the bundled `sccache`\n- `SCCACHE_DIR=/home/dev/.cache/sccache`, backed by the shared host cache under the agentbox state root\n- `/usr/bin/env` compatibility for common env-based shebangs such as\n  `#!/usr/bin/env bash`\n- narrow hardcoded-interpreter compatibility for `/bin/sh`, `/bin/bash`,\n  `/bin/python`, and `/bin/python3`; `/bin/python` resolves to Python 3\n  (not broad FHS compatibility)\n- common tools (`curl`, `jq`, `tmux`, etc.); tmux disables mouse support and\n  includes system-wide pane split bindings for `Ctrl-b |` and `Ctrl-b -` plus\n  Vim-style pane focus movement on `Ctrl-b h/j/k/l`\n\n`clang_mold_wrapper` keeps the default linker policy in the image and avoids\nsetting `RUSTFLAGS`, so existing Cargo config can still layer on top normally.\nIf `clang -fuse-ld=mold` ever stops resolving correctly in-image, the fallback\nis to pin `mold` explicitly inside the wrapper and update this document to\nmatch.\n\nBoth container and libkrun task containers run with `--userns=keep-id` so\n`/workspace` ownership matches host mapping. The `--root` flag keeps the final\nshell as root, but does not otherwise change the persistent host mount layout.\n\n---\n\n## Publishing\n\n### Container image (GitHub Actions)\n\nOn push to `main`, push to `dev`, and tag pushes, CI publishes to:\n\n- `ghcr.io/\u003crepo-owner\u003e/loftd:latest` (main only)\n- `ghcr.io/\u003crepo-owner\u003e/loftd:dev` (dev only)\n- `ghcr.io/\u003crepo-owner\u003e/loftd:\u003cgit-tag\u003e` (tag only)\n- `ghcr.io/\u003crepo-owner\u003e/loftd:sha-\u003c12-char-commit\u003e`\n- `ghcr.io/\u003crepo-owner\u003e/agentbox:*` with the same tags as a compatibility\n  alias for existing agentbox users.\n\nBoth image names point at the same shared loftd-compatible image built from\n`.#container`; CI does not build a separate agentbox image. The shared image\ncontains both `loftd-guest-init` and `agentbox-guest-init`, so loftd uses the\ncanonical image entrypoint while agentbox explicitly enters through its\ncompatibility guest init path.\n\n### Prebuilt binaries (GitHub Releases)\n\nMain-branch CI also publishes prerelease binary assets:\n\n- rolling `alpha`\n- commit-specific `sha-\u003c12-char-commit\u003e`\n\nOlder `sha-*` prereleases are pruned (retains newest 20).\n\nThe `agentbox-\u003carch\u003e-unknown-linux-musl` asset is the portable static/musl\nagentbox CLI. The `loftd-\u003carch\u003e-linux-flake-locked` asset is a raw dynamically\nlinked ELF and intentionally non-standalone: it can rely on the exact Nix store\nclosure from this flake lock. For ordinary loftd usage, prefer\n`nix build .#loftd`, `nix build .#loftd-prebuilt` for pinned systems, or the\npublished `ghcr.io/\u003crepo-owner\u003e/loftd` image.\n\n---\n\n## Maintenance helpers\n\nRefresh pinned prebuilt release in `nix/pins.nix`:\n\n```bash\nnix develop --command ./scripts/update-agentbox-prebuilt.sh\n```\n\nRefresh pinned loftd prebuilt release metadata in `nix/pins.nix` from a\nraw-ELF `sha-*` release. The updater rejects wrapper-script assets:\n\n```bash\nnix develop --command ./scripts/update-loftd-prebuilt.sh\n```\n\nRefresh pinned RTK prebuilt release metadata in `nix/pins.nix`:\n\n```bash\nnix develop --command ./scripts/update-rtk-prebuilt.sh\n```\n\nRefresh pinned `zeroqn/libkrunfw` release metadata in `nix/pins.nix`:\n\n```bash\nnix develop --command ./scripts/update-libkrunfw.sh\n```\n\nRefresh pinned OpenCode release metadata in `nix/pins.nix` from `anomalyco/opencode`:\n\n```bash\nnix develop --command ./scripts/update-opencode.sh\n```\n\nRefresh pinned Pi coding agent source/npm metadata in `nix/pins.nix` from `earendil-works/pi`:\n\n```bash\nnix develop --command ./scripts/update-pi-coding-agent.sh\n```\n\nRefresh pinned Reasonix source/npm metadata in `nix/pins.nix` from the latest `esengine/DeepSeek-Reasonix` release target rev:\n\n```bash\nnix develop --command ./scripts/update-reasonix.sh\n```\n\nRefresh pinned `oh-my-codex` version/hashes in `nix/pins.nix` (including bundled Linux-musl native helper asset hashes):\n\n```bash\nnix develop --command ./scripts/update-oh-my-codex.sh\n```\n\n---\n\n## Use from another flake (prebuilt binary)\n\n```nix\n{\n  inputs.agentbox.url = \"github:zeroqn/agentbox\";\n\n  outputs = { self, nixpkgs, agentbox, ... }: {\n    nixosConfigurations.my-host = nixpkgs.lib.nixosSystem {\n      system = \"x86_64-linux\";\n      modules = [\n        ({ pkgs, ... }: {\n          environment.systemPackages = [\n            agentbox.packages.${pkgs.system}.agentbox-prebuilt\n          ];\n        })\n      ];\n    };\n  };\n}\n```\n\nFor a source-build fallback, use:\n\n```nix\nagentbox.packages.${pkgs.system}.agentbox\n```\n\nDownstream flakes can also depend on the packaged seccomp policy via:\n\n```nix\nagentbox.packages.${pkgs.system}.container-lib-policy-seccomp-json\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzeroqn%2Fagentbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzeroqn%2Fagentbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzeroqn%2Fagentbox/lists"}