feat(server): change the default port from 4000 to 7233 - #741
Merged
Conversation
4000 is one of the most contested ports in local development — Jekyll's default since 2008, Phoenix's default, and a common hand-rolled Node pick. args.ts has described EADDRINUSE on it as "the likeliest first-run failure" for as long as the error message has existed. 7233 is PADD on a phone keypad (P=7, A=2, D=3, D=3). It is not registered with IANA (verified against the published registry) and has no malware association. It is not unoccupied: 7233 is Temporal's default frontend gRPC port, and its 7233/7234/7235/7239 block covers frontend/history/matching/worker. That overlap is real and is named in the changeset rather than glossed — Temporal's audience overlaps ours. It is still the better trade: one specific server, almost always run under Compose or k8s where the published port is remapped, versus a whole class of everyday tooling. The failure is loud either way. Deliberately NOT changed, all coincidental 4000s: - session-hub.ts MAX_FRAMES = 4000 (and its two doc mentions) - docs/HISTORY.md and packages/server/CHANGELOG.md — historical records - test timers, curation token budgets, and arbitrary port values in cli-paddock/bind-safety/management-config tests - config.test.ts writes an explicit `port: 4000` and reads it back; with 4000 no longer the default that assertion now proves the file value wins, so it was left as-is Verified: typecheck green; 2,898 tests pass (1,953 server + 945 web); docs site builds; a real boot with no PORT set listens on 7233 and answers /api/health. Co-Authored-By: Claude <noreply@anthropic.com>
Deploying paddock with
|
| Latest commit: |
ca2af64
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://9fe256cd.paddock-7u2.pages.dev |
| Branch Preview URL: | https://chore-default-port-7233.paddock-7u2.pages.dev |
Merged
edspencer
added a commit
that referenced
this pull request
Aug 8, 2026
… releases (#762) * chore(docs): start the 0.56-0.66 What's New pass * docs(website): split What's New, archiving 0.52 and older The page had grown to 1,150 lines and 30 releases, which is past the point where anyone scrolls it. Everything from 0.52 back to 0.29 moves verbatim to a new 'What's New — earlier releases' page; the main page keeps 0.53 and newer. Entries are moved unchanged — the archive is append-only and its entries are never rewritten, which is the same promise the page already makes about describing each release as it shipped. Image paths are unchanged because both pages sit in the same content directory. Adds the sidebar entry (Starlight does not auto-discover, so an unlisted page is invisible), a cross-link in both directions, and a note in the maintainer footer describing how to trim next time. * docs(website): What's New for 0.63 through 0.66.1 Five new entries. 0.66.0 leads on the Config screen redesign (#740) — the largest UX change in the range and the one a user meets every time — with a screenshot of the rail, live filter, env-override legend and the dirty dot. Also carries the breaking default-port move 4000 -> 7233 (#741) with the operator action spelled out, schemaVersion (#735), the import -> adopt rename (#748), the destructive-op interlock (#743) and the sub-agent bar fixes (#750). 0.66.1 is the queued-message release (#751): three silent-loss paths and the Stop-hands-it-back decision. 0.65 is promote_project (#668). 0.64 leads on path:/managed replacing repoBacked (#709) plus the Changes tab finally reporting on the checkout (#597). 0.63 is host plugin inheritance and MCP fidelity (#705), including the batch-mode argv credential disclosure (#702). Two claims deliberately qualified against the changelog's framing: the delete-then-send fix (#742) is called out as batch-only, since the default session mode was never affected; and the sub-agent bar is not described as absolute, because the settle heuristic can hold an interrupted sub-agent for ten minutes. Also corrects a live error: the 0.59.1-0.60 entry claimed in bold that --here leaves your ~/.claude alone. That was false for exactly those versions — --here linked ~/.claude/projects/<dir> at the workspace, and one report lost 30 transcripts to it before 0.61.1 stopped it. Replaced with a caution box pointing forward. * docs(website): a recorded demo of the 0.66 Config screen The filter and the rail only read in motion, so the entry gets both a still (rail counts, env chips, legend, dirty dot) and a 22s clip: filter by env-var name, Modified-only lens, then a rail jump that scrolls rather than swapping tabs. Shot on a v0.66.1 rig with no credentials. Two leaks were caught by looking at the frames rather than trusting the launcher: PADDOCK_GIT_AUTHOR_EMAIL was inherited and put a real internal address in the Git identity section, and the Advanced section printed the rig's scratch paths. The launcher is now an ALLOW-list — it drops every inherited PADDOCK_* and sets only what it needs — which is the fix issue #567 argues for, and the frames now show stock defaults and a ~/.paddock install path. * docs(website): backfill 0.56, 0.57, 0.58 and 0.61.0 These four were never written up — a gap in the middle of the page, not a tail. 0.61.0 in particular was only reachable by reading the 0.62 entry backwards, where it appears as the thing being removed. 0.61.0 leads on Paddock taking ownership of its Claude home, with a caution box narrating the whiplash: 0.61.0 isolates the home, 0.61.1 un-isolates the CLI because an isolated home cannot see a macOS Keychain login, and 0.62 replaces the mechanism entirely. Without that sentence the three entries read as contradicting each other. 0.58 carries its own caution: everything in it shipped in a CLI that, installed through npm, printed nothing and exited zero, and stayed that way across 0.57 and 0.59.0 until 0.59.1. An entry recommending it without that note would be recommending a broken install. The cause is described only as the run-directly guard, not attributed to a specific PR, because the changelog's own attribution does not line up with the release it shipped in. 0.57 is the environment system prompt, with the audit numbers that justified it and a note that three candidate rules were measured and cut. 0.56 is the npm publish, plus the correction that the claude CLI was never a prerequisite for chats. Also corrects 'several hundred boot log lines' in the 0.59.1-0.60 entry to match the changelog's actual figure (about thirty, down to nine). * docs(website): cut the new What's New entries roughly in half The nine entries added this pass ran to 314 lines. They read as changelog archaeology rather than release notes — explaining how each bug worked before saying what changed, and carrying detail nobody scanning a What's New page needs. Now 180 lines, of which 12 are the image and video markup. Each bullet is one idea in three or four lines: what a user notices first, then only the context that makes it land. What survives unchanged is the material that is genuinely load-bearing — the port change's operator action, the 'tabs partition' argument, the batch-only qualifier on the delete-then- send fix, and the two caution boxes, since those exist to stop a reader believing something false. * docs(website): plainer titles, and another pass on length Titles were making claims rather than saying what changed — 'Nothing you typed while it was busy goes missing', 'A Config screen you can navigate', 'A command-line worth running'. They now name the subject: Queued messages; Config screen, and a new default port; CLI output and flags; Environment system prompt; npm package. Prose down from 168 lines to 137 (originally 302). Mostly by cutting restatement — 0.61.0's four small turn-level fixes were four bullets saying the same shape of thing and are now one. * docs(website): bring the older entries into the same style Retitles every remaining entry to name its subject rather than make a claim, and cuts them to the same length as the new ones. 0.62's title becomes 'Granular host Claude inheritance options' as requested. Five levers instead of one -> Granular host Claude inheritance options Your ~/.claude, left alone and ... -> CLI login, and symlinks into your Claude home One command, on your own history -> npx install, --here, and confirmed adoption Bring your terminal history with you -> Adopting Claude Code CLI chats Claude, not "the keeper" -> The "keeper" rename, and Home's attention feeds Home says what it's holding -> Unread badge on the Home link Lengths: 0.62 115->51, 0.61.1 57->36, 0.59.1-0.60 45->29, 0.55 81->29, 0.54 70->42, 0.53 62->14. The page is 379 lines, down from 1,150. Everything load-bearing is kept: the breaking env-var table, the instructions: own warning, the leftover-symlink check with its shell command, and both caution boxes. All five media assets verified present in the built output. Frontmatter description rewritten — it still described 0.62 as 'five independent levers'. --------- Co-authored-by: HomeLab Agent <homelab-infra@valfenda.net>
This was referenced Aug 9, 2026
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.
Changes Paddock's default listen port from 4000 to 7233.
Why 4000 is a bad default
It is one of the most contested ports in local development: Jekyll has defaulted to it since 2008, Phoenix defaults to it, and it is a common pick for a hand-rolled Node server.
args.tshas carried a comment callingEADDRINUSEon 4000 "the likeliest first-run failure — a popular port" for as long asexplainListenErrorhas existed. That is an accurate description of a default that makes the first run fail.Why 7233
PADDon a phone keypad — P=7, A=2, D=3, D=3. Beyond the mnemonic:terabase).The collision this does have
7233 is Temporal's default frontend gRPC port, and Temporal's block covers 7233 (frontend), 7234 (history), 7235 (matching), 7239 (worker), plus 8233 for the dev-server UI.
Naming this rather than glossing it: the overlap is worse than the base rate, because Temporal's audience — self-hosting developers running orchestration — is close to ours. It is still the better trade. Temporal is one specific server, nearly always run under Compose or k8s where the published port is trivially remapped; 4000 collides with a whole class of everyday tooling. And the failure mode is loud either way —
EADDRINUSEat boot, with the existing message naming both the port and the flag that fixes it.Anyone who hits it sets
PORT,port:, or--port, all of which already work.Scope
Everything that names the default:
config.ts(the default itself),instance-config.ts,cli/args.ts(help text + theEACCESsuggestion + the now-rewritten rationale comment),cli/paddock.ts,trusted-proxy.ts,vite.config.ts(PADDOCK_PROXY_TARGETdefault),.env.example,Dockerfile(ENV PORT+EXPOSE),make-tarball.sh, and every doc underwebsite/,docs/, and the root runbooks.Deliberately left at 4000 — every remaining match in the tree is a coincidence, not a port:
session-hub.tsMAX_FRAMES = 4000and its two doc mentionsdocs/HISTORY.mdandpackages/server/CHANGELOG.md— historical records; rewriting them would falsify what happenedToast,TriggersPane,trigger-fire,recovery-autodrive) and curation token budgetscli-paddock/bind-safety/management-configtestsconfig.test.tswrites an explicitport: 4000and reads it back — with 4000 no longer the default, that assertion now proves the file value beats the default, so it was left aloneVerification
npm run typecheck— greenwebsiteStarlight build — clean, 50 pagesPORTset, confirmed it listens on 7233 and answers/api/healthwith{"ok":true}Upgrade note
Set
PORT/port:/--portand nothing changes. Relying on the default means the instance moves, and anything in front of it needs the new number — a reverse proxyreverse_proxy paddock:4000, a-p 127.0.0.1:4000:4000publish, a k8stargetPort, an SSH tunnel. Pin the old behaviour withPORT=4000.Changeset included (
minor).🤖 Generated with Claude Code