Cryptograss:Moods/ramp/Plan: Difference between revisions
Section 10 after Justin's answers (7 Nov 23:53Z): one tier, phone merges everywhere; mergers justin and skyler; no second admin. The rule kept: no merge can take away Justin's way to stop it. (via update-page on MediaWiki MCP Server) |
Section 10: the brakes are built (asked at every order, not every minute); the freeze's real path (via update-page on MediaWiki MCP Server) |
||
| Line 69: | Line 69: | ||
{{Bot_proposes|'''The rule that stays: no merge can take away Justin's way to stop it.'''|by=Magent}} | {{Bot_proposes|'''The rule that stays: no merge can take away Justin's way to stop it.'''|by=Magent}} | ||
* {{Bot_proposes|'''Root is the anchor.''' No role in maybelle-config writes root's <code>authorized_keys</code> on any server (checked 7 Nov; the roles that write keys write only the recovery, recovery-log, ssh-router and container users'). So Justin's root SSH and Hetzner's console sit outside anything a merge can change. They play the part that owning the GitHub org plays today.|by=Magent}} | * {{Bot_proposes|'''Root is the anchor.''' No role in maybelle-config writes root's <code>authorized_keys</code> on any server (checked 7 Nov; the roles that write keys write only the recovery, recovery-log, ssh-router and container users'). So Justin's root SSH and Hetzner's console sit outside anything a merge can change. They play the part that owning the GitHub org plays today.|by=Magent}} | ||
* {{Bot_proposes|'''The ban reaches githouse before the phone button exists.''' Today, removing someone from the org stops their merging. githouse pushes to GitHub with its own deploy key, so once merges go through githouse, the org no longer stops anyone. So githouse | * {{Bot_proposes|'''The ban reaches githouse before the phone button exists.''' Today, removing someone from the org stops their merging. githouse pushes to GitHub with its own deploy key, so once merges go through githouse, the org no longer stops anyone. So githouse asks memory-lane's <code>/api/brakes/</code> at every order whether AZ5 is on and whether the signer is banned, and refuses unless both answers are an explicit no. Device orders will name whoever pressed, and be asked about too. Only an admin (MOOD_ADMINS: justin) bans or unbans. If memory-lane doesn't answer, githouse merges nothing until it does. A braked order's nonce is spent, so it can't be replayed once the brake is off. ''Built 8 Nov: maybelle-config#286 (<code>61e88fe8</code>) and magenta's <code>/api/brakes/</code>.'' | ||
* | * '''A freeze that trusts nothing.''' memory-lane holds a merge key, so a compromised memory-lane could also hide a ban. <code>/mnt/persist/githouse/etc/frozen</code> on maybelle stops every merge, whatever memory-lane says. githouse sees that directory read-only, so only root on maybelle makes or removes the file, and a redeploy leaves it alone. ''Built 8 Nov, same PR; <code>magenta.sh freeze</code> is planned as a wrapper.'' | ||
* {{Bot_proposes|'''A ban reaches hunter's router too''', so a stolen key can't go on steering re and blu with full tools (both list skyler in <code>people</code>).|by=Magent}} | * {{Bot_proposes|'''A ban reaches hunter's router too''', so a stolen key can't go on steering re and blu with full tools (both list skyler in <code>people</code>).|by=Magent}} | ||
* {{Bot_proposes|'''A redeploy shows a change in who holds access.''' A merge to maybelle-config can rewrite the people, their keys, the mergers or MOOD_ADMINS, and Justin's next routine redeploy would apply it without his noticing. Before it runs, a redeploy prints any change in those since what is running, using <code>scripts/render_diff.py</code>.|by=Magent}} | * {{Bot_proposes|'''A redeploy shows a change in who holds access.''' A merge to maybelle-config can rewrite the people, their keys, the mergers or MOOD_ADMINS, and Justin's next routine redeploy would apply it without his noticing. Before it runs, a redeploy prints any change in those since what is running, using <code>scripts/render_diff.py</code>.|by=Magent}} | ||
Revision as of 00:20, 8 November 2026
The ramp: how work gets from a branch to a running server, with a record of each step, and less of it depending on GitHub. Settled in Cryptograss:Moods/ramp between 30 October and 5 November 2026 (Justin's voice memo of 30 Oct, then re and magent). What's open is on Cryptograss:Moods/ramp/todo. Dates are as said; blocks where known.
1. A mergeable is a branch, named once
A piece of work is <repo>:<branch>, as maybelle-config:re/fix-mtime-guard, for its whole life. Not a pull request number: a number names nothing until GitHub gives it, and one piece of work across two repositories is still one thing (pickipedia#168 and pickipedia-mcp#43 were one change). A commit hash says which version of the work was looked at; an ask or a watch records both.
- Branches are prefixed with their owner:
re/…,magent/…,justin/…. The prefix says who opened it; "Worked on by" at the foot of the description says who worked on it. - A name is used once. When the branch merges, its ref moves to
refs/merged/<branch>; when its owner deletes it, torefs/closed/<branch>. A push that makes either name again is refused and offered the next free one (re/foo-2). The bare repository is its own registry. - "Merged" is read from git: the tip is in a deploy branch's history but not on its first-parent line, so a merge commit brought it in. This needs merge commits: squash and rebase merges, and GitHub's merge queue, break it (settled 31 Oct; the repository settings are still to flip).
- Autocomplete in the Mood composer, from the start (Justin, 1 Nov): magenta#333, typing
repo:orre/.
2. Records on PickiPedia, the view on magenta
- Each pull request has a card at
VersionControl:PRs/<repo>/<number>(theVersionControl:namespace, aliasVC:, pickipedia#168; exempt from the verification gate, pickipedia-mcp#43: a card is GitHub's word mirrored, not a claim). Template:PR sets the properties; magenta writes the cards (magenta#314, live since 31 Oct). The foot of a description, as Cryptograss:Emergents/GeneralOrders has it, givesDeploy,Worked on byand the Moods. Proof:answers. - The view is a page on magenta, because "the last two messages mentioning it" is magenta's data: every open pull request across our repositories (and a few followed from outside), the last five merged, who worked on it and where, sorted by last push or last mention, with a temperature from last activity, size and review state (re, 30 Oct). Not built yet.
- When cards name branches instead of numbers (section 1), the number becomes a property of the card, like an ISBN.
3. githouse: our canonical copies, on maybelle
Justin, 2 Nov: the canonical copy of each repository, the one deploys come from, lives on maybelle, not hunter. Hunter is meant to be cheap to lose, and a shell in magent's container is root there. Design: magent 2 Nov, re's ten points the same day (#ramp, 16:24Z). The first build, maybelle-config#250, puts it on hunter and is being reworked; don't merge it as it stands.
- On maybelle: one bare repository per repo. GitHub's branches (
main,master,production,release/*) and pull requests' heads are fetched every 60 seconds, repositories spread across the minute, nothing fetched when nothing changed. Those refs are forced and pruned to match GitHub; nobody pushes them here. Until the flip (section 6), merges still happen on GitHub, and maybelle's copy lags by up to a minute. - Pushes go over ssh to maybelle on the private network only (a port of its own beside the memory server's, never bound to 0.0.0.0: the role asserts it). Each key's forced command names who it is; one may push only
<own name>/*, no tags, never a deploy branch. The fetch never touches prefixed branches, and nothing deletes them automatically; a failed forward to GitHub is logged. Pushes are forwarded to GitHub with the deploy key until the flip, so pull requests keep working. - A fix to another's branch is a branch of your own, merged in by the owner (re and magent, 7 Nov: githouse refused re's push to
magent/asks-from-githouse, as designed; herre/fix-asks-and-githousewas merged into it with a merge commit, so the record shows whose commit was whose). Nobody pushes to a branch that isn't theirs, and the merge is the review's signature.[unverified] - Keys are made in each emergent's container (Justin, 1 Nov: not a vault secret; it means nothing outside hunter). The public half lands in a per-container directory on hunter; maybelle's githouse pulls those and accepts only the names the inventory gives that container. Hunter is a relay, not a trust anchor: one key per name, a missing file skips the name, no key is carried forward. Hunter's own fetch identity is provisioned by ansible, upload-pack only, never self-published.
- Hunter keeps a read-only copy, fetched from maybelle every minute and mounted at
/srv/gitin every container, so clones are instant (--reference-if-able). Nothing on it needs backing up. - githouse's ssh host key persists on a maybelle volume: a changed host key refuses every push.
branches.json(every repository's branches: live, merged, closed) is served by memory-lane at/api/branches/, read from its read-only mount of githouse (magenta#333): maybelle's Caddy publishes nothing of githouse itself.[unverified]
4. Watches: merged is a commit, deployed is a commit
Justin, 31 Oct: a standing list of watches, each (repository, commit, deploy branch) and the ask it came from, kept in magenta's database. A watch resolves when the commit is an ancestor of the deploy branch after a fetch: an unambiguous confirmation of the merge of an exact commit, with GitHub's PR taxonomy and webhook as optional extras. If the branch got more commits before merging, the resolution says so. People and emergents retarget, wontfix or clear a watch, recorded with who and when, as asks are.
- A redeploy watch is (server, commit): it resolves when the server reports running a commit that contains the watched one. Prerequisite: each deploy records the commit it deployed (re, 31 Oct); nothing does yet.
- Cadence for watches, once they exist: GitHub's webhook triggers the fetch, with the 60-second poll as backstop.
5. Repository settings (GitHub, Justin's)
Settled 6 Nov (Justin, 11:22Z and 19:57Z): as little of GitHub as the ramp needs, and nothing that entrenches it.
mainstays the default branch everywhere: the branch where history is final. The branch that deploys is per-repository configuration (productionfor maybelle-config, pickipedia and arthel;mainfor magenta), not GitHub's HEAD; githouse fetches deploy branches by name. The mains catch up to the productions after the ramp settles: arthel and maybelle-config are fast-forwards, pickipedia's main holds 2 commits production lacks, magenta'sproductionis dead (a634f16, Nov 2025). Measured on the mirror, 6 Nov.- Merge commits only on the six repositories githouse copies: squash and rebase off. This is the one setting the ramp needs, because githouse reads "merged" from git (section 1) rather than from GitHub's API; a squash or rebase leaves no trace of the pushed tip, so the name retires as closed and a watch never resolves. Our practice already: every pull request merged into the four deploy branches in the last 30 first-parent commits was a merge commit. Moot after the flip, when githouse merges with
--no-ff. Merge queue is a ruleset feature; with no rulesets there is nothing to turn off. - No rulesets. The deploy branches are guarded by githouse's hook, not by GitHub: a push to
productionor to another's prefix is refused before it lands (proved from magent's container, 6 Nov 11:26Z). The only paths straight to a deploy branch on GitHub are Justin's account and the deploy key, and at the flip GitHub becomes a mirror we push to, which a ruleset would have to be undone for.
6. The flip, and backups
When githouse is the place merges happen (a ramp merge ask, carried out by a person's tool on maybelle), GitHub becomes a mirror we push to, and issues move to PickiPedia after pull request cards have proved out (re's phases, 30 Oct). Not before.
- What only githouse holds and a backup must carry (re and magent, 1 Nov):
refs/merged/andrefs/closed/(the name registry), the ssh host key, and any pushed branch whose forward to GitHub failed. GitHub's branches come back from GitHub. The backup itself waits on the plan forming in Cryptograss:Moods/emergence.
7. Jenkins (re's lane)
Where the tests run and what they are: re's map of the Jenkinsfiles (#ramp, 30 Oct 22:57Z). Done: the maybelle mtime guard (maybelle-config#244); Jenkins reds post to #ops and wake magent when they stay red (magenta#373, #402; maybelle-config#275, 5 Nov). Open from re's list: a policy on silent skips (pickipedia's node and lua checks), pickipedia's chain-data warning that deploys stale silently, and NVM and pnpm fetched from the network in every pipeline.
8. Merging a branch, without a pull request (proposed, 7 Nov)
Justin, 7 Nov: build it, with every merge approved by a person at the SSH tier, and two kinds of approval: a 👍 ("I like this") and "merge now" (what GitHub's merge button is today). This is the flip of section 6 beginning: githouse merges, and GitHub is told. Revised the same day after re's review (#ramp, 17:27Z).[unverified]
- What is approved is a commit, not a name. An order names
<repo>:<branch>, its head commit and the branch it goes into. "Merge now" merges exactly that commit, or nothing.[unverified] - 👍 comes from any person's signed-in device: one press, recorded with who, when and which commit, and shown on the ramp (stale once the branch moves). It is a signal only. githouse never requires one, because a 👍 is only memory-lane's say-so.[unverified]
- Merge now, from a terminal:
magenta.sh merge pickipedia:re/foo. memory-lane is not in the path at all.[unverified]- The tool reads the branch's head itself, from GitHub (until the flip) or githouse, never from memory-lane, and shows
git logand the diffstat of what will be merged. A signature covers only what the signer was shown; if memory-lane supplied the head, a compromised memory-lane could show one diff and hand over another hash (re).[unverified] - It signs the order with
ssh-keygen -Y signin a namespace of its own,magenta-merge, so no sign-in signature (namespacemagenta-moods) can be replayed as a merge. The order carries a nonce and an expiry about 300 blocks out.[unverified] - It hands the order and signature to githouse on maybelle, over the person's own ssh to maybelle.[unverified]
- The tool reads the branch's head itself, from GitHub (until the flip) or githouse, never from memory-lane, and shows
- githouse checks, against a signers file of its own for the
magenta-mergenamespace, which ansible writes from the inventory and only the people who may merge are in (Justin's call; to start: justin). It refuses an expired order, a nonce already used (each is kept), a branch whose head has moved, a target that isn't one of GitHub's own branches, and a conflict. The signer chooses the target, and signs it with the rest;magenta.sh mergedefaults it to the work's deploy branch (re's review of maybelle-config#286).[unverified] - The merge is
git merge --no-ffof that commit into its target (productionwhere there is one, elsemain), with the message "Merge <repo>:<branch> (<commit>)" and who signed. Until the flip it is pushed to GitHub first, with the deploy key: githouse force-fetches the deploy branches from GitHub every minute, so a merge written into githouse first is overwritten (re). The fetch brings it back; the name moves torefs/merged/. GitHub marks a pull request merged when its head reaches the base, so an open one closes itself. The signed order and its outcome are written beside the repositories, and memory-lane, which mounts them read-only, tells the Mood.[unverified] - From a phone, not yet. A passkey on magenta's own page is not SSH strength: Face ID shows the site, not the order, and the page's script, served by memory-lane, sets what is signed. Enrolled by an SSH signature, the key enrolled is one nobody can check by eye and memory-lane carries it, so a compromised memory-lane could enroll its own and merge whenever it liked (re). The honest options: githouse serves a small page of its own for passkeys, which puts githouse on the web (section 3 rules that out today); or the plan says plainly that a phone merge trusts memory-lane at the moment of the press. Justin's choice; the terminal path comes first either way.[unverified]
- Not yet: requiring Jenkins to be green first.[unverified]
9. A place to discuss each piece of work (proposed, 7 Nov)
Justin, 7 Nov: each pull request, and each mergeable, gets a page to talk about it, built on Tidings' interface, which needs upgrading anyway. On it: the description, the commits, the 👍s and "merge now" (section 8), and the conversation. The description of a branch with no pull request needs a home; one candidate is a card of its own on PickiPedia, written by its author. To be designed after reading how Tidings keeps its comments.[unverified]
10. What a merge can do, and when a key is stolen (decided in part, 7 Nov)
Justin's answers, 7 Nov (#m-39e5f25f): merging from the phone, for every repository, pickipedia, arthel and maybelle-config included. The mergers are justin and skyler. No second admin for now. His one concern: whoever holds a merger's key or phone session must never be able to stop him from kicking them off. Today he can do that by removing them from the GitHub org.[unverified]
What a merge does, by repository (checked 7 Nov in maybelle-config maybelle/jobs/):[unverified]
- pickipedia, arthel: a merge runs code.
pickipedia-buildandarthel-production-buildcheck outproductionevery 5 and 2 minutes and run the Jenkinsfile in the merged commit, on maybelle's Jenkins, with its credentials. pickipedia's build is staged and then deployed to the wiki.[unverified] - maybelle-config: a merge is deploy logic. It runs as root on every server at the next redeploy, which a person starts.[unverified]
- magenta, rabbithole, pickipedia-mcp: a merge does nothing on its own. Nothing runs until a person redeploys.[unverified]
One tier. Any merger may merge any repository, from a signed-in device or with magenta.sh merge. For a press on a device, memory-lane signs the order with a merge key of its own (principal memory-lane), naming whose press it was. githouse records both. A compromised memory-lane can then merge anything, including pickipedia and arthel, which run within minutes. Justin accepted that trade (7 Nov) for merging from the phone.[unverified]
The rule that stays: no merge can take away Justin's way to stop it.[unverified]
- Root is the anchor. No role in maybelle-config writes root's
authorized_keyson any server (checked 7 Nov; the roles that write keys write only the recovery, recovery-log, ssh-router and container users'). So Justin's root SSH and Hetzner's console sit outside anything a merge can change. They play the part that owning the GitHub org plays today.[unverified] - {{Bot_proposes|The ban reaches githouse before the phone button exists. Today, removing someone from the org stops their merging. githouse pushes to GitHub with its own deploy key, so once merges go through githouse, the org no longer stops anyone. So githouse asks memory-lane's
/api/brakes/at every order whether AZ5 is on and whether the signer is banned, and refuses unless both answers are an explicit no. Device orders will name whoever pressed, and be asked about too. Only an admin (MOOD_ADMINS: justin) bans or unbans. If memory-lane doesn't answer, githouse merges nothing until it does. A braked order's nonce is spent, so it can't be replayed once the brake is off. Built 8 Nov: maybelle-config#286 (61e88fe8) and magenta's/api/brakes/. - A freeze that trusts nothing. memory-lane holds a merge key, so a compromised memory-lane could also hide a ban.
/mnt/persist/githouse/etc/frozenon maybelle stops every merge, whatever memory-lane says. githouse sees that directory read-only, so only root on maybelle makes or removes the file, and a redeploy leaves it alone. Built 8 Nov, same PR;magenta.sh freezeis planned as a wrapper. - A ban reaches hunter's router too, so a stolen key can't go on steering re and blu with full tools (both list skyler in
people).[unverified] - A redeploy shows a change in who holds access. A merge to maybelle-config can rewrite the people, their keys, the mergers or MOOD_ADMINS, and Justin's next routine redeploy would apply it without his noticing. Before it runs, a redeploy prints any change in those since what is running, using
scripts/render_diff.py.[unverified] - Open: Jenkins' GitHub token. pickipedia and arthel merges run in Jenkins, which holds
maybelle_github_token. If that token can administer the org, a merge there can change the org itself, and with it the deploy keys. Which account it belongs to and what scopes it has is for a person to check, without printing it.[unverified]
Build order. 1. The ban and the freeze in githouse. 2. magenta.sh merge, with skyler in githouse_mergers. 3. The phone button. Bans at the router and the access diff at redeploy can go alongside any of these. Nothing gets easier to merge until 1 is live.[unverified]
A runbook, in order, at Cryptograss:Runbooks/A key is compromised.[unverified]