Documentation
¶
Overview ¶
`mache install` / `mache uninstall` — provisioning that ships INSIDE the binary.
Until now provisioning lived only in the Taskfile: `task install` copies bin/mache to ~/.local/bin and `task leyline:ensure` fetches the pinned ley-line-open release. Both require a repo checkout. A user who installed from a GitHub release asset or a Homebrew tap has neither, so the shipped binary could not provision its own REQUIRED backend — leyline is mache's sole parser since ADR-0012 step 4, and without it `mache build` has nothing to project from.
That gap is not theoretical. On the reporter's machine a stale leyline 0.10.3 sat on PATH at ~/.local/bin/leyline while the pin was v0.13.0, so `leyline cdc enable --db x.db` typed at a shell ran a parser three minors off from the one that built the .db. Both binaries are named `leyline`; neither warns (bead mache-19326d).
What this deliberately does NOT do ¶
- It never writes ~/.mache/bin/leyline, the UNVERSIONED path. That was a shared mutable resource concurrent mache builds overwrote, silently changing _ast shape between runs, and mache-0acdf6 made it read-only-never-written. Provisioning goes through leyline.EnsureCachedBinary, which only ever writes the pin-namespaced path; nothing here touches the cache directly.
- It never puts leyline on PATH, by symlink, shim or otherwise. A shim reintroduces "which version does bare `leyline` mean" the moment the pin moves. `mache leyline path` / `mache leyline exec` answer that question without the ambiguity.
- It never edits your shell rc behind your back. rustup's posture: print the line, let the human run it. --update-rc is an explicit opt-in and writes one idempotent, marked block it can also remove.
- `uninstall` refuses to delete a Homebrew-managed mache. Removing a file brew believes it owns leaves brew's manifest lying, and the next `brew upgrade` silently restores it.
`mache leyline path` / `mache leyline exec` — invoking the PINNED leyline.
mache resolves leyline through one pin-checked chokepoint (leyline.ResolveBinary: MACHE_LEYLINE_BINARY → PATH → version-namespaced ~/.mache/bin cache → SHA-verified download, each tier accepted only on the EXACT pinned version). A human or agent typing bare `leyline` gets none of that — they get whatever PATH happens to hold.
Measured on a machine that had run `task install` (bead mache-19326d):
~/.local/bin/leyline 0.10.3 ON PATH <- what `leyline` meant ~/.mache/bin/leyline-v0.13.0 0.13.0 not on PATH <- what mache actually used
`~/.mache/bin` is not on PATH, so `leyline cdc enable --db x.db` typed at a shell ran a 0.10.3 parser against a db mache built with 0.13.0. Both binaries are named `leyline` and neither announces the mismatch. Since v0.13.0 shipped `leyline cdc enable` / `leyline cdc gc`, invoking leyline directly is a real workflow, so this is a real skew — the same defect class as mache-0acdf6 (silently changing _ast shape between runs), relocated from the cache to PATH.
These two subcommands make the version question UNASKABLE rather than answered-by-PATH-convention:
$(mache leyline path) cdc enable --db x.db # shell interpolation mache leyline exec -- cdc enable --db x.db # direct invocation
Deliberately NOT done here (both re-open shipped bugs):
- No write to ~/.mache/bin/leyline (the unversioned path). mache-0acdf6 made that path read-only-never-written because it was a shared mutable resource concurrent mache builds overwrote; see binary_cache_path.go. Nothing in this file writes to the cache at all — ResolveBinary owns provisioning, and it only ever writes the pin-namespaced path.
- No PATH or shell-rc mutation. A shim dir on PATH just reintroduces "which version does bare `leyline` mean" the moment the pin moves.
Resolution failures are returned verbatim from ResolveBinary so there is one error vocabulary for "no pinned leyline", not two.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // Version is the binary's build version, shown by `mache version` and // stamped into build artifacts (_mache_meta, the build-cache lockfile // producer field, the MCP server version). `task build` and release.yml // inject it from `git describe --tags` via -ldflags, so it tells the truth // about the built code: a clean tag (0.10.0) on a tagged release, a // git-distance string (0.9.0-9-gabc1234) between releases. A bare // `go build` / `go test` (no ldflags) falls back to the clean release base // in internal/buildinfo (version.txt). // // NOTE: server.json and melange.yaml derive from buildinfo.Version (the // clean, committed, drift-checked release base) — never from this string — // so a dev-distance build version can't break the server-json drift gate or // produce an invalid apk package version. Version = resolveBuildVersion() Commit = "none" Date = "unknown" )
Functions ¶
Types ¶
This section is empty.