No description
  • Python 97.1%
  • Shell 1.8%
  • Dockerfile 1.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Nimby 7a5fe53e5b
All checks were successful
Build and Push / test (push) Successful in 24s
Build and Push / build-and-push (push) Successful in 1m6s
Merge pull request 'Publish multi-arch homelab-fabric container image' (#1) from container-image into main
2026-10-09 17:42:32 -04:00
.forgejo/workflows Publish multi-arch container image to the Forgejo registry 2026-10-08 12:01:28 -04:00
docs Clarify Fabric worker labels 2026-08-05 00:38:34 -04:00
fabric Publish multi-arch container image to the Forgejo registry 2026-10-08 12:01:28 -04:00
tests Publish multi-arch container image to the Forgejo registry 2026-10-08 12:01:28 -04:00
.dockerignore Publish multi-arch container image to the Forgejo registry 2026-10-08 12:01:28 -04:00
.gitignore Restructure as standalone HomelabFabric repo 2026-10-08 11:31:04 -04:00
Dockerfile Publish multi-arch container image to the Forgejo registry 2026-10-08 12:01:28 -04:00
README.md Publish multi-arch container image to the Forgejo registry 2026-10-08 12:01:28 -04:00

HomelabFabric

The AI Operations Fabric: a small, dependency-light toolkit for sending bounded, reviewable jobs to local worker hosts and tracking their results.

  • fabric/agent_runner.py: validates job specs against a worker host catalog and runs them through a shell or ssh backend, writing a run directory (job.json, status.json, notes.md, logs, declared outputs).
  • fabric/ai_fabric.py: dashboard and API server. Indexes run artifacts into SQLite, tracks the worker registry, and serves the web UI.
  • fabric/ai_fabric_dispatch.py: dashboard-triggered dispatch with worker-pool selection and per-group job authorization.
  • fabric/ai_fabric_mcp.py: MCP server that lets coding agents list, validate, run and publish jobs.
  • fabric/draft_job_spec.py: drafts new job specs with a local Ollama model.

Design notes live in docs/ai-ops-fabric.md and docs/local-agent-runner-design.md.

Consumer contract

Fabric is generic. The jobs it runs and the hosts it runs them on belong to the consuming repository, which is expected to provide:

  • scripts/agents/agent_runner.py: the dispatcher, MCP server and job specs invoke the runner at this path inside the consumer's checkout.
  • examples/agent-jobs/*.json: job specs.
  • examples/agent-hosts/<name>.json: the worker host catalog.

The homelab repository is the primary consumer. It vendors a tagged release of fabric/*.py into scripts/agents/ with scripts/sync_fabric.sh, and its Ansible roles deploy from that pinned copy.

Container image

The dashboard (ai_fabric.py serve) ships as a multi-arch (linux/amd64, linux/arm64) image built by .forgejo/workflows/build.yml:

git.scruffydude.net/scruffydude/homelab-fabric
Tag Pushed on
:<short-sha> every build
:latest pushes to main
:vX.Y.Z pushing a v* tag

Pull requests run the tests only; images are built after the tests pass on a push or manual workflow_dispatch. The workflow needs a REGISTRY_TOKEN repo Actions secret (a scruffydude access token with write:package) and a runner job image that has the docker buildx plugin.

Mounts

Path Mode Contents
/data rw fabric.sqlite3, agent-runs/, and worker-registry.json. Seed the registry from the consumer's examples/agent-hosts/<name>.json before first start; the server exits if it is missing.
/repo ro Consumer checkout: scripts/agents/agent_runner.py, examples/agent-jobs/, examples/agent-hosts/. Dispatch runs /repo/scripts/agents/agent_runner.py with /repo as its working directory.
/root/.ssh ro Dispatch key (id_ed25519) and known_hosts for SSH workers.

Environment

serve reads its defaults from these variables; explicit flags passed after serve override them. The image sets them to the values below, so it runs with no extra configuration given the mounts above. Outside the image the defaults are the ones in ai_fabric.py serve --help.

Variable Flag Image default
AI_FABRIC_HOST --host 0.0.0.0
AI_FABRIC_PORT --port 8765
AI_FABRIC_DB --db /data/fabric.sqlite3
AI_FABRIC_ARTIFACT_ROOT --artifact-root /data/agent-runs
AI_FABRIC_HOST_CONFIG --host-config /data/worker-registry.json
AI_FABRIC_JOB_DIR --job-dir /repo/examples/agent-jobs
AI_FABRIC_REPO_ROOT --repo-root /repo
AI_FABRIC_IMPORT_BEFORE_SERVE --[no-]import-before-serve true
AI_FABRIC_IMPORT_INTERVAL --import-interval 15
AI_FABRIC_COST_PER_MILLION_TOKENS --cost-per-million-tokens 10

The entrypoint is python3 /app/ai_fabric.py and the default command is serve, so other subcommands work too, e.g. docker run --rm -v ...:/data homelab-fabric summary.

The image exposes port 8765 and has a HEALTHCHECK that requests /api/summary with Remote-Groups: admins. That endpoint is admin-only and Authelia normally supplies the header.

docker run -d --init -p 8765:8765 \
  -v /srv/ai-fabric/data:/data \
  -v /srv/ai-fabric/workspace:/repo:ro \
  -v /srv/ai-fabric/ssh:/root/.ssh:ro \
  git.scruffydude.net/scruffydude/homelab-fabric:latest

tests/smoke_image.sh IMAGE starts an image against tests/fixtures and checks that it reports healthy and serves /api/summary and /api/jobs.

Development

Python 3.10+ standard library only (tests use pytest).

pytest tests/ -v

Releasing

Releases are cut by pushing a v* tag: git tag -a vX.Y.Z, then git push origin vX.Y.Z. The build workflow publishes homelab-fabric:vX.Y.Z for that commit. Then in homelab run scripts/sync_fabric.sh vX.Y.Z to update the vendored copy, point the deployment at the new image tag, commit, and deploy.