maand push
Push a user-owned bucket into an existing maand server bucket:
maand init
# edit workspace/ and templates/
maand build
MAAND_SERVE_TOKEN=... maand push https://maand.example \
--bucket 6ba7b810-9dad-11d1-80b4-00c04fd430c8
The local data/maand.db is a disposable build artifact. maand build records
maand.conf, workspace job files, core workspace configuration, templates, a
bundle-format version, and the producing binary's Git hash. Push sends a
consistent sanitized SQLite snapshot; local KV, CA keys, and runtime state are
not transferred.
Replacement behavior
The target bucket must already exist. Push authoritatively replaces:
maand.confworkspace/templates/
It preserves server-owned state:
data/, including the server catalog, identity, KV, and deployment historylogs/secrets/.ssh/bucket.json.maand/(immutable source revisions)
tmp/ is cleared. Other non-reserved root entries are removed. Arbitrary
Git-root files and executable modes are not part of the bundle.
After the filesystem commit, the server runs build against its existing database. Push does not deploy. If extraction fails, the previous source tree is restored. If build fails, the new source remains installed as current while last successful stays pointed at the prior good revision. Inspect the run in Activity, then either fix the user-owned bucket and push again, or roll back:
MAAND_SERVE_TOKEN=... maand push rollback \
--server https://maand.example \
--bucket 6ba7b810-9dad-11d1-80b4-00c04fd430c8
If the server process stops mid-push, the next maand server start recovers
orphan upload directories and incomplete rollback staging before accepting traffic.
Source revisions
Every accepted push retains an immutable revision keyed by the SHA-256 of the
uploaded bundle under .maand/source-revisions/. The server tracks:
| Pointer | Meaning |
|---|---|
current |
Live source tree after the latest commit |
last_successful |
Latest revision whose server-side build succeeded |
List them:
MAAND_SERVE_TOKEN=... maand push revisions \
--server https://maand.example \
--bucket 6ba7b810-9dad-11d1-80b4-00c04fd430c8
maand push rollback atomically restores a retained revision (default:
last_successful; optional --revision <hash>), rebuilds the server catalog,
and writes an audited run. It does not deploy. The server keeps the newest 10
revisions and never prunes current or last_successful.
Ownership and operations
Push and source rollback are the only server APIs that change user-owned source.
The UI and remaining API expose source as read-only. They still manage
server-owned bucket metadata, SSH private keys, .ssh/known_hosts,
catalog/runtime state, and operational actions such as trust, build, deploy,
health checks, hooks, job control, snapshots, GC, and init/upgrade.
Worker facts over the server API only reports facts; it cannot generate or update
workspace/workers.json. To refresh worker definitions, run local
maand worker facts --generate-workers, commit the result, build, and push.
Durable push history
Every accepted push is an asynchronous server run. Its live output appears in
Activity, while durable structured history is written to
logs/runs/<run-id>/maand.log. The terminal event records the SHA-256 hash of
the exact uploaded bundle, producer build hash, bundle version, current and
last-successful revision pointers, timestamp, build result, and exit status for
success, validation/extraction failure, cancellation, and build failure.
Flags and authentication
| Flag / bucket | Description |
|---|---|
--bucket <uuid> |
Required existing server bucket |
--token / MAAND_SERVE_TOKEN |
Server bearer token |
--totp / MAAND_SERVE_TOTP |
Optional current TOTP code; the client creates a session before upload |
--timeout |
Total upload and server-build timeout; default 30m |
Subcommands revisions and rollback take --server <url> instead of a
positional URL. rollback accepts optional --revision <hash>.
TLS certificates use the operating system trust store. Credentials must not be
placed in the server URL. The server rejects incompatible schemas or bundle
versions, corrupt databases, unsafe paths, excessive entries, oversized
payloads, and pushes attempted while that bucket already has an active run
(409). Runs on unrelated buckets do not conflict.
Build identity
make build embeds the current Git hash in the binary. maand init and
maand build record their binary hashes in the bucket row, and maand info
shows the running, initializer, and content-producer hashes. Compatibility is
decided by the bundle-format version and structural validation, not by requiring
client and server Git hashes to be identical.