The operator has decided not to enable branch protection on armistace/blog while the editor is LAN-only: "leave it as a recommendation - I won't do that unless I take this out to the wider internet" That is a reasonable call, so this records it as an ACCEPTED RISK rather than an open task. Test behaviour changed to match. The suite still attempts a direct push to master with the deploy key on EVERY run - the check is not removed, because that is what would catch the setting being lost or never applied. But when protection is off it now reports ACCEPTED-RISK master is NOT protected - the deploy key CAN push master directly instead of FAIL, so the suite is green and CI-usable (it previously exited 1, meaning a genuine regression would have been buried in expected noise). The run flips back to "PASS master is protected" by itself the moment protection is enabled, so the recommendation self-cancels with nobody having to remember it. Summary line now reads RESULT: 44 passed, 0 failed, 1 accepted-risk Docs record WHY the risk is acceptable (the compensating control is reachability, not immutability - nothing off-LAN can reach the editor, and the only LAN user is the operator) and the two triggers that turn it back into a real finding: 1. the editor becomes reachable off-LAN (NPM proxy, port-forward, VPN route) 2. anyone other than the operator gets access Written down because an accepted risk is only acceptable if it is explicit and has a revisit trigger - otherwise it just looks like an oversight later.
7.2 KiB
Writer-Branch Workflow
How writing and publishing work from the Atheos editor, and why the branch is structured this way.
The model
The editor never touches master. It writes to a long-lived branch (atheos-writer), and
merging into master is done by the operator in Gitea.
┌──────────────────────────────────────────┐
Atheos editor ────┤ atheos-writer (long-lived) │
(macros) │ • write here │
│ • commit + push here │
│ • can be reset --hard back to master │
└───────────────┬──────────────────────────┘
│ operator opens a PR in Gitea
│ operator reviews
▼
master (protected: RECOMMENDED, currently OFF - see §2)
│
▼
existing Pelican build pipeline
Why: the editor is a web app with shell-exec reach (codegit + macro both run commands as the
php-fpm user). Bounding what it can reach is the whole point of design decision D6. Keeping master
behind a PR means a compromised or fat-fingered editor cannot publish directly — it can only
propose.
Setup — do these once
1. Set your git identity (required, RUNBOOK STEP 1)
ssh root@192.168.178.57
su -s /bin/sh atheos
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
This is the same global gitconfig php-fpm uses (HOME=/home/atheos — verified), so macros commit
as you. If it is not set, macro 2 refuses with an actionable error rather than
committing under a bogus identity.
2. Protect master on the blog repo — RECOMMENDATION, deliberately not enabled
Status: accepted risk. Branch protection is OFF, and that is a decision, not an oversight.
"leave it as a recommendation — I won't do that unless I take this out to the wider internet" — operator
The deploy key can push master directly, which means the writer-branch model is advisory, not
enforced. The operator has weighed this and chosen not to add the gate while the editor is LAN-only:
- The compensating control is reachability, not immutability. The editor is LAN-only (FR-10). The
threat this setting defends against is a compromised editor publishing straight to
master; while nothing off-LAN can reach the editor, and the only user on the LAN is the operator, that is largely theoretical. - The cost is real now, the benefit is not. Protection adds a merge gate for the sole user, who is also the repo owner — friction with no realistic risk reduction today.
⚠️ Enable it BEFORE either of these happens
- The editor becomes reachable off-LAN — an NPM proxy entry, a port-forward, or a
Tailscale/WireGuard route to
blog-ide.aridgwayweb.com. - Anyone other than the operator gets access to the editor.
At that point a deploy key that can force-push master stops being theoretical. The setting
(armistace/blog → Settings → Branches → rule for master):
| Setting | Value |
|---|---|
| Enable push | off ← direct pushes blocked, including the deploy key |
| Enable merge whitelist | on → add armistace |
| Require approvals | optional (you're the only human here) |
Verify:
curl -s -H "Authorization: token $GITEA_TOKEN" \
https://git.aridgwayweb.com/api/v1/repos/armistace/blog/branch_protections
It is still checked on every test run
build-and-test.sh attempts a direct push to master with the deploy key and requires it to be
rejected. While protection is off that reports as ACCEPTED-RISK, not FAIL — so the suite stays
green and CI-usable — but the check runs every time. It flips to
PASS master is protected by itself the moment protection is enabled, and this recommendation
becomes moot without anyone having to remember it.
3. The macros
Installed directly into Atheos's macro store (data/macros.db.php); a copy is kept in this repo at
files/macros.db.php so a rebuild reproduces them. They appear when you right-click the blog
folder in the file tree → Macros.
| # | Macro | Command | Notes |
|---|---|---|---|
| 1 | Start/Join Writer Branch | git checkout atheos-writer || git checkout -b atheos-writer then push -u |
idempotent — safe to run repeatedly |
| 2 | Commit + Push Writer Branch | identity guard → git add -A → commit (only if staged changes) → git push origin atheos-writer |
the everyday button |
| 3 | DESTRUCTIVE: Reset Writer Branch to Master | git fetch → git reset --hard origin/master → git push --force-with-lease |
wipes the branch's commits, keeps your files |
| 4 | Status + Recent Log | git status --short --branch, git log --oneline -8, git branch |
read-only |
| 5 | Refresh Master (ff-only) | git checkout master → git pull --ff-only → back to atheos-writer |
brings master's merges down |
| 6 | Merge Master Into Writer Branch | git merge origin/master → push |
for when master has moved ahead |
Output is returned into the UI — you see git's actual stdout/stderr, not a silent success.
Day-to-day
- Right-click
blog→ Macros → 1. Start/Join Writer Branch (first time; also safe later) - Write your post, save
- Right-click
blog→ Macros → 2. Commit + Push Writer Branch - Open a PR:
atheos-writer→master - Review the diff in Gitea, merge
⚠️ Important: macro 2 uses git add -A
git add -A stages everything in the repo, including files you may not intend to publish
(drafts, scratch files, .orig/.bak leftovers). A reset --hard will also delete any untracked
file that has been staged.
Practical consequences:
atheos-writeris a publishing branch — everything you leave in the tree gets committed and pushed to Gitea.- If you want a scratch area, keep it outside the repo (e.g.
workspace/scratch/, notworkspace/blog/). - To unstage before a reset:
git reset(clears the index without touching your files).
Recovering a deleted file
reset --hard does not touch the object database, so a file that was ever staged or committed is
still recoverable:
su -s /bin/sh atheos
cd /var/www/atheos/workspace/blog
git fsck --lost-found | grep commit # find dangling commits
git ls-tree <commit> path/to/file # confirm it is there
git cat-file -p <blob-sha> > path/to/file # restore it
git reflog --all also shows recently discarded commits. This is how the empty
src/content/please_no_facebook.md was recovered after a reset --hard in testing.
Changing the branch name
Edit macros 1, 2, 3, 5 and 6 in Settings → Macro and replace atheos-writer. The branch name is
literal in each command — there is no variable. (Macros have no input prompt, so a
branch name that changes per task would need edit-then-run.)