No description
  • Rust 97.8%
  • Nix 2.1%
  • Shell 0.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
JMARyA 6a98822bdb
Some checks are pending
moira/threads moira/threads — definitions compiled
moira/flake/checks.moira-clippy@x86_64-linux checks.moira-clippy — queued
moira/flake/checks.moira-fmt@x86_64-linux checks.moira-fmt — queued
moira/flake/checks.moira-gate-approval@x86_64-linux checks.moira-gate-approval — queued
moira/flake/checks.moira-gate-approval-container@x86_64-linux checks.moira-gate-approval-container — queued
moira/flake/checks.moira-git-integration@x86_64-linux checks.moira-git-integration — queued
moira/flake/checks.moira-smoke-container@x86_64-linux checks.moira-smoke-container — queued
moira/flake/checks.moira-test@x86_64-linux checks.moira-test — queued
moira/flake/env.flake.eeb9c92140c77a3b@x86_64-linux env.flake.eeb9c92140c77a3b — queued
moira/flake/env.path.cd14140fcc94447c@x86_64-linux env.path.cd14140fcc94447c — built
moira/flake/packages.default@x86_64-linux packages.default — queued
moira/flake/packages.moira@x86_64-linux packages.moira — queued
moira/flake/packages.moira-agent@x86_64-linux packages.moira-agent — queued
moira/flake/packages.moira-agent-image@x86_64-linux packages.moira-agent-image — queued
moira/flake/packages.moira-cache@x86_64-linux packages.moira-cache — queued
moira/flake/packages.moira-cache-image@x86_64-linux packages.moira-cache-image — queued
moira/flake/packages.moira-server@x86_64-linux packages.moira-server — queued
moira/flake/packages.moira-server-image@x86_64-linux packages.moira-server-image — queued
moira/flake/checks.moira-agent@x86_64-linux checks.moira-agent — queued
moira/flake/checks.moira-agent-labels@x86_64-linux checks.moira-agent-labels — queued
moira/flake/checks.moira-agent-labels-container@x86_64-linux checks.moira-agent-labels-container — queued
moira/flake/checks.moira-binary-cache@x86_64-linux checks.moira-binary-cache — queued
moira/flake/checks.moira-cache@x86_64-linux checks.moira-cache — queued
moira/flake/checks.moira-cancellation@x86_64-linux checks.moira-cancellation — queued
moira/flake/checks.moira-cancellation-container@x86_64-linux checks.moira-cancellation-container — queued
moira/flake/checks.moira-cli@x86_64-linux checks.moira-cli — queued
moira/flake/checks.moira-git-integration-container@x86_64-linux checks.moira-git-integration-container — queued
moira/flake/checks.moira-server@x86_64-linux checks.moira-server — queued
moira/flake/checks.moira-smoke@x86_64-linux checks.moira-smoke — queued
moira/publish moira/publish — succeeded
moira/ci moira/ci — succeeded
fix(forge): register webhooks as the repo admin, and say when one is missing
Forgejo mounts every /repos/{o}/{r}/hooks route behind reqAdmin(), the
listing included. The bot is a `write` collaborator, so the background setup
that runs after `repo add` / `repo connect` was refused on every repo: the
collaborator got added, no webhook was ever registered, and the only trace
was a warning in the server log. The docs claimed webhooks were under write.

- ensure_repo_setup takes the requesting person's forge identity and
  converges the webhook as them first, then as the bot, strictly in sequence
  so two passes cannot each create a hook.
- `repo connect` (already an admin check) runs setup inline and reports it;
  `repo add`, `repo sync` and `forge attach` pass the caller's forge sign-in
  when they have one. `repo sync` is the repair command.
- RepoSetup carries the webhook's reason instead of a bare bool; a 403 names
  the fix. The CLI prints registered / NOT registered with that reason.
- The connect-repo test forge now refuses hooks to non-admins, as Forgejo
  does; the old stub answered anyone, which is how this went unnoticed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 17:27:01 +02:00
.moira/envs test: server test fixture with a self-starting Postgres (T.1) 2026-07-30 16:23:30 +02:00
crates fix(forge): register webhooks as the repo admin, and say when one is missing 2026-09-27 17:27:01 +02:00
docs fix(forge): register webhooks as the repo admin, and say when one is missing 2026-09-27 17:27:01 +02:00
grafana feat(cache): serve /cache/* and artifacts from their own data plane 2026-09-13 17:47:49 +02:00
k8s feat(cache): serve /cache/* and artifacts from their own data plane 2026-09-13 17:47:49 +02:00
nix fix(tests): the disk floor makes every VM test wait forever 2026-09-14 01:12:16 +02:00
openspec docs(openspec): bound work that never finishes 2026-09-14 01:12:16 +02:00
scripts refactor(security): a moira instance is a single trust domain 2026-09-02 19:33:14 +02:00
.gitignore feat(web): show what went into a run and what came out 2026-08-30 15:51:57 +02:00
AGENTS.md fix(forge): register webhooks as the repo admin, and say when one is missing 2026-09-27 17:27:01 +02:00
Cargo.lock feat(web): commits and artifacts are pages 2026-09-24 20:27:40 +02:00
Cargo.toml chore(deps): facet moves with vox, or not at all 2026-09-14 21:50:00 +02:00
CLAUDE.md docs: add AGENTS.md with full model/architecture reference, symlink CLAUDE.md 2026-05-31 06:01:00 +02:00
devenv.lock update devenv lock 2026-04-19 14:12:08 +02:00
devenv.nix add devenv postgres 2026-04-19 13:14:08 +02:00
flake.lock feat: add nix-darwin agent module 2026-08-27 02:15:35 +02:00
flake.nix fix(publish): push the cache image, not only build it 2026-09-13 18:30:35 +02:00
README.md docs(readme): bring the standard library section up to date 2026-09-03 01:18:11 +02:00
renovate.json chore(deps): facet moves with vox, or not at all 2026-09-14 21:50:00 +02:00
zensical.toml feat(cache): serve /cache/* and artifacts from their own data plane 2026-09-13 17:47:49 +02:00

Moira

Alpha software. Moira is under active development — interfaces, config schemas, and APIs may change without notice between commits. Run it, break it, report what you find, but don't depend on stability yet.

moira is a unified automation fabric for infrastructure engineers who believe the git repository is the only legitimate source of truth. It merges the concerns of CI pipelines, scheduled automation, workflow orchestration, and IaC execution into a single declarative system — hermetically sealed by Nix, driven by Rust, and accountable to nothing but your repo.


The mythology

Hydra builds moira.

In Hesiod's Theogony, the three Moirai — the Fates — are daughters of Nyx, the primordial goddess of night. They weave the thread of every mortal life: Clotho spins it into being, Lachesis measures its length, Atropos cuts it with inexorable finality.

Your infrastructure has the same shape. Intent is declared. Work is measured and scheduled. Execution is final, hermetic, irreversible. And it all runs on Nix — named, knowingly or not, for the same primordial darkness the Fates were born from.

Hydra — the many-headed — spawns Moira. Moira, daughters of Nyx, runs on Nix.

The lore wrote itself.

Internal architecture: the three sisters

The moira runtime is divided internally along the mythological grain:

Sister Role
Clotho (CLI) Git watcher and intent compiler — she reads your declared threads and spins them into executable task graphs
Lachesis (Server) Scheduler and reconciler — she measures, allots work to agents, manages approval gate state, and ensures reality converges to declaration
Atropos (Agent) Step executor — she cannot be turned aside; hermetic, deterministic, she runs the step and cuts the thread when done

These are internal names. Users interact only with moira.

Documentation

Full docs live in docs/. To serve locally:

zensical serve

Standard library

moira-modules — curated environments, typed modules, and thread constructors. Import as a flake input and use directly in your pipelines.

Modules — HTTP, git, SSH, S3, container push, compression, crypto, JWT, TOTP, ntfy, SMTP, OpenTofu/Terraform, Vikunja, CalDAV, Home Assistant. Each declares typed inputs and outputs; credentials are secret-typed and injected at runtime.

Thread constructors — rustCi, nodeCi, goCi, pythonCi, container, containerManifest, s3Site, notify. Applied to an options attrset, with withDefaults for per-site values.

Derived threads — fromProject { src = self; } reads a repo's own manifests at eval time and returns one thread per project it finds, so a monorepo gets per-project path filters without hand-written config.