Mifa
Mifa is Astra's package manager, Cargo-shaped, agent-friendly, and built around one non-negotiable: the same inputs must always produce the same build.
From zero to running project
Five commands take an empty folder to a running native program.
$ mkdir myapp && cd myapp
$ mifa init myapp # scaffold astra.toml + src/main.astra here
$ mifa verify # validate astra.toml and the src/ layout
$ mifa lock # write astra.lock (sha256-stable)
$ mifa run # compile + execute natively
$ mifa verify --json # same result as a machine-readable envelope
$ mifa login <token> # store a registry token (~/.mifa/credentials.toml)
$ mifa publish --dry-run # validate + archive + checksum, no upload
$ mifa clean --cache # drop target/ and ~/.mifa/cache
The manifest is Cargo-style TOML. This is exactly what
mifa init writes; only name and
version are required:
[package]
name = "myapp"
version = "0.1.0"
description = "A new Astra package"
[dependencies]
lib = { path = "../lib" } # a local dependency (mifa add lib --path ../lib)
Manifests in Mifa's older flat form still load.
Dependencies you can import
A local package is a real dependency. mifa build compiles
src/main.astra to target/<name> and
searches each path dependency's src/ folder for modules;
mifa run passes arguments through and exits with your
program's exit code.
$ mifa init app # creates app/
$ mifa init textutil
$ cd app
$ mifa add textutil --path ../textutil # checks ../textutil/astra.toml
$ mifa run
HI!
pub fn shout(s: str) -> str:
return s.to_upper() + "!"
import textutil
fn main() -> int:
print(textutil::shout("hi"))
return 0
mifa add needs --path, --git
or a package in the registry; anything else is
an error instead of recording a package nothing can fetch. This flow is covered
by an end-to-end test that drives the real mifa binary.
Version requirements v0.13.1
A requirement means what it means in Cargo, and the newest matching version wins.
| Written | Means |
|---|---|
"1.2" or "^1.2" | compatible: 1.2.0 up to, not including, 2.0.0 (^0.3 stops before 0.4.0) |
"~1.2.3" | 1.2.3 up to, not including, 1.3.0 |
"=1.2.3" | exactly 1.2.3 |
">=1.0, <3.0" | a range |
"*" | any version |
Versions are ordered by semver, so 10.0.0 is newer than
9.0.0 (before v0.13.1 they were compared as text). A
requirement Mifa cannot read is named in the error
(invalid version requirement 'banana'), and one nothing
satisfies lists the versions that exist.
Behaviour change in v0.13.1: a bare
"1.2.3" used to mean exactly 1.2.3 and now means
^1.2.3; write "=1.2.3" to pin.
Git dependencies and workspaces v0.13.2
Dependencies from git, the whole graph resolved, and several packages in one tree.
# astra.toml
[dependencies]
textutil = { git = "https://github.com/acme/textutil.git", tag = "v1.2.0" }
helper = { git = "https://github.com/acme/helper.git", version = "^1.2" }
util = { version = "0.3", path = "../libs/util" }
- Git dependencies by
tag,branchorrev, or aversionchosen among the repository's version tags.mifa add textutil --git <url> --tag v1.2.0checks the repository before writing the manifest; repositories are cached and each commit is checked out once. - Version solving across the whole graph. Your dependencies' dependencies are resolved too. Mifa picks one version of each package that satisfies every requirement, backs off to an older version when the newest makes another requirement impossible, and names each requirement and who made it when nothing works. Cycles are refused.
- Pinned and reproducible.
astra.lockrecords each package's version, source and git commit; a branch stays on its pinned commit untilmifa update.--lockedfails instead of changing the lockfile and--offlinebuilds from the cache, for CI.mifa treeshows the graph. - Workspaces.
[workspace] members = ["app", "libs/*"]in the rootastra.toml: one lockfile and onetarget/, commands that work from any member, and-p <name>to pick one.
A static package registry v0.13.3
A registry is only files: a folder, or any static web host serving one. There is no central public registry yet.
$ mifa publish --registry ~/astra-registry # add this version; a version never changes
$ mifa add textkit --version "^1.1" # depend on a registry package by name
$ mifa yank 1.2.0 # hide a broken version (--undo brings it back)
$ mifa search text # registry folders only
- Where it lives. An index per package and
checksummed archives, in the spirit of Cargo's sparse index, so a
shared drive, a git repository or a static web host (GitHub Pages,
S3, nginx) can hold it. Name it with
--registry,MIFA_REGISTRYor[registry] url = "..."inastra.toml. - Solved with everything else. A dependency with
only a version (
textkit = "^1.1") comes from the registry, with its own registry dependencies, in the same solver as path and git packages. Yanked versions are skipped unlessastra.lockpins them. - Checked. Each archive's SHA-256 is checked on
download and pinned in
astra.lock; a replaced archive stops the build. Downloads are cached, so--offlineworks. - Its limits. Mifa publishes only into a folder,
which you then upload; web registries are read with
curland are read-only, andmifa searchworks on folders only.
The lockfile
mifa lock resolves the full dependency graph and writes
astra.lock: versioned, sorted, and content-hashed. Two
machines with the same manifest resolve identical graphs, byte for
byte. This was validated as differentiator D5: repeated locks of the
same workspace produce sha256-identical files.
Reproducibility matters twice over for Astra's mission. Humans get reliable CI; agents get a guarantee that a build that verified once will verify the same way again, no drifting dependencies invalidating an earlier repair loop.
Mifa, as a globe
Every Mifa feature is a star: the brightest work today, faint dotted ones are planned. Drag to turn it, or pick a magnitude.
- Works today: Projects (init, verify, clean), Build, run and test, Path dependencies, Git dependencies, Version solving (semver), Workspaces, Lockfile (--locked, --offline), JSON output for agents, Package registry (publish, add, yank, search), Registry dependencies by version, Checksums pinned in astra.lock
- New in v0.13.3: Package registry (publish, add, yank, search), Registry dependencies by version, Checksums pinned in astra.lock
- Next: Project-wide verify
- Planned: Project-wide verify, Hosted registry, Package signing
Mifa milestones
Every local milestone has shipped, and a static, self-hosted registry works; a central hosted registry is what remains.
| Milestone | Scope | Status |
|---|---|---|
| M1: Honest local workflow | init / add / build / run / verify; 43-test integration suite |
shipped |
| M2: Lockfile + cache | astra.lock, ~/.mifa/cache, path dependencies, lock / clean |
shipped |
| M5-basics: JSON output | --json on init/add/verify/test/lock/login/publish; stable envelope for agent consumption |
shipped |
| M3: Registry protocol | /v1/packages v1 API, SHA-256 checksums, yanked-version handling, stable REG4xx error codes |
shipped |
| M4: Publish + auth | mifa login (per-registry tokens), publish --dry-run (validation, deterministic archive, checksum) |
shipped |
| M6: Graph, git, workspaces | Transitive resolution with backtracking, git dependencies pinned to commits, update / tree, --locked / --offline, [workspace] |
v0.13.2 |
| Static registry | A folder or static web host: mifa publish into a folder, mifa add <name>, yank, search; SHA-256 pinned in astra.lock |
v0.13.3 |
| mifa.dev: Public registry | Hosted central registry with accounts and uploads | v1.0 |
Honest note: there is no central public registry
yet. A static registry you host yourself
works: publish into a folder, upload it anywhere static, and depend
on its packages by name, with checksums pinned. Uploading to a hosted
registry (mifa.dev) waits on its deployment, and
mifa login tokens are stored but a static registry does
not use them. Local workflows (init, verify, lock, run, path
dependencies, JSON output, login, dry-run publish) are real and
covered by 90+ tests.
Honest about the registry v0.12
Since v0.12.0-alpha:
mifa --versionprints the Mifa version.mifa searchsays the registry is not deployed instead of listing packages. Up to v0.11.2-alpha,mifa searchlisted packages that do not exist. Since v0.13.3-alpha it searches a registry folder.- The Mifa flow is part of the black-box release suite that runs on every platform before a release publishes.
Why not reuse an existing manager?
Mifa is built around two things agents need most: fast verification and builds that never drift.
- Verification-first.
astra verifytype-checks a program without generating code, so an agent can validate a change in milliseconds.mifa verifytoday checks only the manifest and layout; type-checking the whole project graph from Mifa is planned. - Lockfile as a contract. The lock isn't advisory; registry downloads refuse checksum mismatches outright.
- One tool, one mental model. Mifa wraps the same
compiler library the
astraCLI uses. Diagnostics, exit codes, and JSON shapes stay identical between both tools,init,add,verify,test,lock,loginandpublishsupport--jsonand emit the samediagnostics[]envelope.