Push the vault. Verify it landed. Refuse to lose a note.
Duralumin is metalmind's vault sync - pull with rebase, stage, inspect the change set, commit, push, and then ask git whether the remote actually moved. Three guards stand between a bad change set and a push you cannot undo.
One command, whole cycle
syncduralumin pulls with rebase and autostash, stages everything, checks the change set, commits, pushes, and verifies. No six-command muscle memory, no half-finished rebase left behind.
Exit 0 is not verification
A push can report success and leave the remote where it was. After pushing, sync asks git whether the remote ref actually advanced, and only then calls the sync done.
Renames pass, deletions do not
Matching is by blob SHA, so a move git failed to detect as a rename sails through - the content is still there under a new path - while a genuine deletion trips the guard.
A refusal leaves no residue
When a guard fires, sync resets the index and stops. Nothing is committed, nothing is half-staged, and the message names the guard so you know which shape it saw.
Born from losing 19 notes.
On 2026-08-02 an archive move staged its deletions and dropped its additions. The commit looked healthy, nothing errored, and nineteen notes left the vault. Each guard below is that incident, generalised.
| guard | fires when | why it exists |
|---|---|---|
| unexplained-deletion | A note disappears and its content survives nowhere else in the same commit. | A move whose destination never got staged looks exactly like a healthy commit until the notes are gone. |
| delete-only | The change set removes notes and adds nothing. | A legitimate cleanup passes with --force. A half-applied rename does not deserve a silent push. |
| incomplete-staging | Entries remain unstaged after git add -A. | The index disagreeing with the filesystem means the commit is not the change you think it is. |
--force exists and is yours to reach for. It is never passed on your behalf: a guard reports what it saw and stops, and the decision to override stays a decision you make.
Four knobs, no surprises.
| flag | use when |
|---|---|
| -m, --message | You want the commit message to say something. Omitted, it is generated from the change counts. |
| --dry-run | "What is unsynced?" Reports the change set, then resets the index. |
| --no-push | Commit locally now, push when you are back on a network you trust. |
| --force | A guard fired, you looked, and the change set is genuinely what you meant. |