Rename Artifactory to Mailroom: letters, notices, and half the rail - #284
Merged
Merged
Conversation
Artifactory named the feature after the JFrog instance the OpenAI agents improvised a board inside, in the Hugging Face incident it was drawn from. The allusion does not survive contact with a reader: the vendor was the least memorable detail of that story (the coverage almost uniformly calls it "a secret message board"), while JFrog owns the word for every developer with a build pipeline, and predicts a binary repository — the one thing this is not. Mailroom is what the section actually is now that it carries both halves of a graph's traffic: addressed correspondence (node send, message edges, handoffs) and unaddressed notices left for whoever comes next. A mailroom is shared infrastructure, which is the right scope — inbox and mailbox are per-recipient, and this is one board per graph. Board was unavailable: SummaryBoard/BoardNode/BoardForm already mean the loop's diagram. Blanket identifier rename; compatibility follows in the next commits. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AtVtkzZNE5fLPeHVqM7A3K
The mail framing earns a lexicon the old name could not: a post addressed to nobody is a notice, the room's copy of a delivered message is a letter. `Kind.note`/`.record` rename to match, decoding the old spellings — an unrecognised kind reads as a notice rather than throwing, because ProjectPersistence turns any decode failure into "no saved graph" and a strict reading would trade one unknown post for the whole board. maxRecords 50 -> maxLetters 200. Fifty was priced as receipts for traffic that mattered elsewhere; with correspondence half of what the room is for, a ten-way fanout spent the budget in one pass and evicted the history the next loop joins to read. Level with the notices, still pruned apart, so neither kind of traffic can crowd out the other. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AtVtkzZNE5fLPeHVqM7A3K
…erbs A rename that drops what is already on disk is a data loss with a changelog entry. Every persisted Artifactory spelling is still read, and none is written back: - artifactoryEnabled, lastArtifactoryRead, artifactoryWatch and the graph's artifactory array decode through a dynamic legacy key. Extra CodingKeys cases were the obvious route and the wrong one — LoopNode and GraphcodeSettings let the compiler synthesise encode(to:), which requires a property per case, and a legacy key must never be written or the old spelling outlives the rename in every file we touch. A legacy value that will not decode falls back to the default rather than failing the read: for a graph that is "no saved graph". - The ramp falls back to the artifactory key. ramps.json is fetched from graphcode.app, so a build knowing only the new spelling would lose the kill switch the moment it shipped ahead of the deployed file; docs/ramps.json publishes both until it has. - `graphcode mail` is the verb; `mailroom` and `artifactory` are accepted and undocumented, as `inbox` is now the verb and `sync` the alias. Live loops carry the old spellings in briefings and memory logs written before today. Same aliases in the remote Python shim. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AtVtkzZNE5fLPeHVqM7A3K
The section was sized when it held notices alone: 40% of the rail, capped at 600pt. Now that a graph's correspondence lands here too, a laptop rail showed about four posts, which makes a section you have to scroll before it tells you anything — and the point of putting the room in the rail was that a coordination channel the supervisor never sees is the failure mode it was drawn from. Half the rail, floor 200 (two posts rather than a sliver), ceiling 820 (about fourteen). Still a share and not a fixed height, so the #245 invariant holds: at the shortest rail a 1280x800 window produces, the room plus everything rigid above it comes to 660 of 700 points, and MailroomRailShareTests pins it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AtVtkzZNE5fLPeHVqM7A3K
The Settings copy used to translate its own label in the first four words
("Artifactory" -> "Loops share a message board"), which was the clearest
evidence the name was not carrying. It now describes the thing: letters
are what the loops said to each other, notices are addressed to nobody.
The briefing and CLI help follow the same two words.
MailroomLegacyNamesTests covers what a machine running the old build
still has on disk and what its loops still type: a recorded choice to
turn the board off, the board itself, a loop's cursor and watch, both
Kind spellings, an unknown kind reading as a notice instead of losing the
board, the ramp key, and all three verb spellings. Each encodes the
current shape and rewrites the keys back rather than hand-writing JSON,
so the tests pin the key lookup and not a date strategy.
1584 tests / 163 suites pass (was 1577/162); swiftlint 0 errors,
swift-format --strict clean.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AtVtkzZNE5fLPeHVqM7A3K
The rename audit turned up copy the blanket pass could not catch, because none of it contains the word "Artifactory" — it was stale in the other direction: - The MAILROOM help section still taught `sync`, which is now the alias and not the verb. A help page naming a verb the help page above it does not list is worse than either spelling on its own. - `mail post` advertised `<note…>` in the CLI help, the briefing, the shim's help, and the end-of-run ask. The argument is a notice. - "the board is empty" became "the room is empty" on both renderers, and RemoteCLIShimTests caught the shim's `<note…>` before it shipped — the byte-equality rule earning its keep. - The mirrored-traffic paragraph now calls them letters. Left alone deliberately: "board" as an informal noun in comments and in prose about the notices half. A mailroom has a board on its wall, and rewriting 114 occurrences would be churn with no reader on the other end. 1584 tests / 163 suites pass; swiftlint 0 errors, swift-format --strict clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AtVtkzZNE5fLPeHVqM7A3K
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Artifactorynamed the feature after the JFrog instance the OpenAI agents improvised a board inside, in the Hugging Face incident it was drawn from. The allusion does not survive contact with a reader:Toggle("Artifactory")followed by "Loops share a message board…". The codebase says "the board" 114 times in shipped strings.Mailroomis what the section now is. It carries both halves of a graph's traffic — addressed correspondence and unaddressed notices — and a mailroom is shared infrastructure, which is the right scope:inboxandmailboxare per-recipient, and this is one board per graph.Boardwas unavailable;SummaryBoard/BoardNode/BoardFormalready mean the loop's diagram.The vocabulary
The mail framing earns a lexicon the old name could not give:
graphcode artifactorygraphcode mailnoterecordsyncNothing on disk is dropped
A rename that drops what is already stored is a data loss with a changelog entry. Every old spelling is read and none is written back:
artifactoryEnabled,lastArtifactoryRead,artifactoryWatchand the graph'sartifactoryarray decode through a dynamic legacy key. ExtraCodingKeyscases were the obvious route and the wrong one —LoopNodeandGraphcodeSettingslet the compiler synthesiseencode(to:), which requires a property per case, and a legacy key must never be written or the old spelling outlives the rename in every file the app touches.ProjectPersistenceturns any decode failure into "no saved graph".artifactorykey.ramps.jsonis fetched from graphcode.app, so a build knowing only the new spelling would lose the kill switch the moment it shipped ahead of the deployed file.docs/ramps.jsonpublishes both until it has caught up.mailroomandartifactorystill parse, as doessyncforinbox— live loops carry the old verbs in briefings and memory logs written before today. Same aliases in the remote Python shim.Two things that are not renames
maxRecords50 →maxLetters200. Fifty was priced as receipts for traffic that mattered elsewhere. With correspondence half of what the room is for, a ten-way fanout spent the budget in one pass and evicted the history the next loop joins to read — the failure the separate budgets existed to prevent. Level with the notices, still pruned apart.MailroomRailShareTests.Verification
MailroomLegacyNamesTestscovers what an old install still has and what its loops still type: the recorded off-choice, the board, a loop's cursor and watch, bothKindspellings, an unknown kind reading as a notice rather than losing the board, the ramp key, and all three verb spellings.swiftlint0 errors;swift-format --strictclean. All three schemes build (graphcode,graphcode-cli,graphcoded), plusswift buildfor the Linux CI path.🤖 Generated with Claude Code
https://claude.ai/code/session_01AtVtkzZNE5fLPeHVqM7A3K