Repository navigation
Linux/WSL2 bootstrap keeps a newer native Claude Code: the pin is a floor (stacked on #159) - #177
Merged
seathatflowsinourveins merged 7 commits intoSep 25, 2026
Conversation
…ory assistant capture is opt-in, ignore Claude Code local state bootstrap-macos.sh's install_native ran `"$bin" install <pin>` even when Claude Code's native auto-updater had already installed something newer, so re-running the bootstrap downgraded it. It now keeps a ~/.local/bin/<bin> whose --version is at or above the pin (logs "Kept", downloads and installs nothing); a missing, older or unreadable launcher takes the unchanged checksum-verified install. The check lives inside install_native because tests/test_adoption_bootstrap.py runs that function on its own. Bash 3.2 safe. Both claude-code pins move to 2.1.281 together (shared components keep one version on both platforms). darwin-arm64 a922981f... comes from the official 2.1.281 manifest.json and matches, byte for byte, the copy the native updater installed on a Mac. linux-x64 56fe3da8... comes from the same manifest and was not re-hashed; fetch() checks it before running anything. 2.1.281 fixes a recursive rm of command-substitution output running unprompted in auto and --dangerously-skip-permissions mode. The macOS page's pin table and the generated new-host grand list follow the pins. The Claude settings template no longer passes --capture-assistant to ai-memory's Stop hook. render_config.py adds it only when AI_MEMORY_CAPTURE_ASSISTANT=true (host value file or --set) and rejects any value other than true, false or empty. defaultMode and skipDangerousModePermissionPrompt are unchanged. .gitignore adds .claude/settings.local.json and .claude/worktrees/. Not included, because open PRs #116, #145 and #151 own these files: the manifests/evidence.json re-hash of the 12 changed files, and the adoption/bootstrap.md "changed after `v2026.09.23.1`" marker for the three changed install inputs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Records the SHA-256/byte entries for every file this branch changes and adds the "changed after `v2026.09.23.1`" note that the docs-consistency test requires for the new install behavior (pins 2.1.281, floor instead of unconditional reinstall). Both files are also edited by open PRs; whichever lands later re-runs the same host_receipts.register_file helper. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolves the manifests/evidence.json conflict with #161 by regenerating the adoption/bootstrap.md entry through scripts/host_receipts.py register_file(). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Stack the Linux Claude Code floor on #159's macOS floor. Only textual conflict: the manifests/evidence.json hashes of adoption/bootstrap.md and adoption/platforms/macos-arm64.md, both auto-merged; re-hashed with host_receipts.register_file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…re too adoption/bootstrap-linux.sh's install_native ran `"$bin" install <pin>` unconditionally, so on a Linux/WSL2 host whose native updater (latest channel) was ahead of the pin, re-running the bootstrap moved Claude Code back to the pin and dropped newer fixes. install_native is now the same function as bootstrap-macos.sh's (#159): a ~/.local/bin/<bin> whose --version first word is a dotted numeric version at or above the pin is kept (nothing downloaded or installed; install_pin logs "Kept installed ..." instead of "Installed ..."); a missing, older, non-numeric or failing launcher takes the unchanged checksum-verified install. Tests: NativeInstallFloorTests in tests/test_adoption_bootstrap.py run the verbatim fetch/install_native/install_pin against a one-pin fixture (curl shimmed; a shasum-backed sha256sum shim only where GNU --check --status is missing), plus an identity check that both scripts share one install_native. Docs: the Linux claude-code install_note describes the floor; bootstrap.md step 2's stale "Linux/WSL2's script and pins are the same at v2026.09.23 as on main" now says what differs at that tag; the claude-code floor notes on bootstrap.md, linux-wsl2.md and macos-arm64.md name the currently pinned release v2026.09.24.1 (#171), which the docs-consistency test requires. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
seathatflowsinourveins
added a commit
that referenced
this pull request
Sep 24, 2026
…up (#195) Measured on macos-m5pro-20260924 (Apple M5 Pro, 24 GB) on 2026-09-24: - Excluding the gitleaks runaway, processes held 26.84 GiB of footprint plus 3.07 GiB wired on 24 GiB. There were 357.8 GiB of swap writes in 4.81 days, and two Jetsam events (09:45 and 09:46 EDT) killed 405 and then 4,255 processes. - Loading the RAG embedder (qwen3-embedding:4b, 4.09 GiB) leaves 2,079 MB unused with Chrome closed. - The Metal working-set limit is 17.76 GiB, below the 17.67 GiB of the 27B Q4_K_M weights plus any cache. Added: - evidence/artifacts/host-upgrade-20260924/upgrade-evidence.json: the RAM gate, the replacement recommendation (64 GB, M5 Pro) with Apple Store prices read 2026-09-24, and the Mac role. The Mac is the cockpit and coordinator; heavy and always-on lanes run on the WSL2 workstation. It supersedes the projected-64 GB MacBook item of host-upgrade-20260923. - evidence/artifacts/host-upgrade-20260924/foundation-alignment.json: memory, RAG and foundation-layer state on the Mac, the saturation status, and the model candidates. It also records the user's 2026-09-24 license decision and the open items for the replacement Mac. - docs/next-host-stages.md: the macOS role row and upgrade row, and replacement-Mac pickup steps. The pickup steps skip bootstrap-macos launchd agents where the agent-ecosystem services exist, and add the RAM-fit matrix and SSH to the workstation. - manifests/evidence.json: registrations and the updated doc hash. No Mac global state was changed. It has one writer (foundation-lane-setup, agent-ecosystem#28). This leaves the files of #185, #159 and #177 alone. Co-authored-by: seathatflowsinourveins <234074349+seathatflowsinourveins@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # .gitignore # adoption/bootstrap.md # adoption/pins-linux-x86_64.json # adoption/platforms/linux-wsl2.md # docs/new-host-grand-list.md # manifests/evidence.json
seathatflowsinourveins
enabled auto-merge (squash)
September 25, 2026 14:44
…tency) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
seathatflowsinourveins
deleted the
claude/linux-claude-code-floor-20260924
branch
September 25, 2026 15:05
seathatflowsinourveins
pushed a commit
that referenced
this pull request
Sep 25, 2026
…0260925 Two use-stage receipts, native_proven, recorded with scripts/host_receipts.py at origin/main 720e294 on the WSL2 Threadripper/RTX 4090 host from #231, each bound to its layer winner's current pin: - socraticode 1.14.0 (foundation/semantic-rag): through mcporter, the health check reaches Qdrant and the vLLM-served Nemotron embedder, the index of a separate clone of this repository is green, a gate-ladder question returns scripts/trading_gates.py and catalogs/us-equities/gates-20260922.json in the top eight, and an unrelated control query returns neither. The -2 generation supersedes the first recording: it drops an unestablished "read-only clone" wording and asserts the launched package version against the winner pin. - ai-memory 2.3.2 (foundation/durable-memory): read-only status of the host service (counts and flags only), then write, search, read-back and delete of a scoped probe page on a disposable scratch server with its own data directory; after deletion the same search finds nothing and read-page fails. The scratch server and directory are removed. Rebased onto b792d6e (#177) with the docs/lanes.md hot-file protocol: main's manifests/evidence.json plus the three receipts re-registered; the component evidence matrix is regenerated with main's component_matrix.py, and the new-host grand list is unchanged by these receipts. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
7 of 8 tasks
seathatflowsinourveins
pushed a commit
that referenced
this pull request
Sep 25, 2026
…obed install_pin now records a pin in installed_pin_ids before #177's early return for a kept native launcher, so a Claude Code at or above its 2.1.281 floor is still checked by the version report (minimum match). Pins re-taken from main (2.1.281) with the version_probe declarations re-applied; the linux-wsl2 step keeps both changed-after notes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
seathatflowsinourveins
added a commit
that referenced
this pull request
Oct 12, 2026
…e scanned snapshot (#1027 P1) Astra's P1 at d6be1b0 (CHANGES_REQUESTED, reproduced on this PR's own EndToEndTests harness): nas_land.sh and uet_land.sh checked that SQUASH_BODY_FILE was a readable, non-empty regular file and nothing more, so a body holding a home path, an account name, an address that is not a no-reply one or a token shape went into main's permanent history through gh pr merge --body-file (her four synthetic payloads each gave exit 0 and one merge call). gh reads the file when the merge call starts (cli/cli v2.102.0 pkg/cmd/pr/merge/merge.go:146-153; :292-293 and http.go:72-75 send it as CommitBody; pkg/cmdutil/file_input.go:8-16), up to an hour or more after any check, so the scanned bytes must also be the bytes gh reads. When SQUASH_BODY_FILE is set, both scripts now, before the lock and every gh and git call: - copy the file once to a snapshot (mktemp in TMPDIR, mode 0600; an EXIT trap removes it on every exit, SIGTERM and SIGHUP included); - scan the snapshot with the new tools/landing/squash_body_scan.py (the repository's PRIVATE_CONTENT table from scripts/validate.py, a WSL UNC home path that table misses, an address that is not a no-reply one, and the names of the CC's landing-prohibited-names list; the list is parsed, never sourced) and with scripts/validate.py --scan-file (the scan the pre-push hook runs); - stop with exit 2 and one fixed line on a match, a copy or scan that fails, a scanner or names file that is missing or unreadable, and any answer that is not a scan's own clean line (fail closed); nothing of the body, no path and no scanner output is printed; - give gh the same snapshot, never the caller's file. New variables: LANDING_BODY_SCAN, LANDING_SCANNER (default: scripts/validate.py of LANDING_NAS_REPO, which also fits the CC's live copies) and LANDING_NAMES_FILE (default: the file under the coordination tree). Three allowances, the CC's rulings of 2026-10-12, each with its tests: - a names-list entry equal to the running host's own name (compared with hostname when the scan runs, never printed) is a warning count, not a refusal; every other name still refuses; - a systemd unit instance, <name>@<instance>.service|timer|socket|target|path|mount (systemd/systemd man/systemd.unit.xml:121-135), is not an address; - a short list of vendor co-author trailer addresses, each with the vendor source it comes from, passes: codex@openai.com, as the vendor's own repository carries it (openai/codex@db22c91, message line 38). #1002's email registry replaces the list. A real-provider address is still refused (the control). Tests (22 new or changed; at d6be1b0 they give 140 failures and 5 errors, here they pass; the allowance tests also fail on the scan without the allowance): - a body with a home path of each form (Linux, macOS, Windows with either slash, the WSL mount, the WSL UNC forms with one or doubled backslashes, the dash-encoded and graph-id forms, percent-encoded), a name of a synthetic names file, an address that is not a no-reply one (with look-alikes) or a token shape (seven kinds) is refused by both scripts with exit 2 before any call; - a missing or failing scanner, names file or validate.py, a scanner that prints nothing or another line, and every answer of validate.py --scan-file but its clean one refuse the landing; - the valid-body control lands (exit 0, one merge call) with the body's bytes read from a mode-0600 snapshot, after both scans ran on it; - a file rewritten after the scan does not reach the merge; the snapshot exists during the run and is gone after exits 0, 3 and 7 and after SIGTERM and SIGHUP; the defaults of the new variables; the real validate.py --scan-file where Betterleaks is installed; - the allowances: a body naming the host lands with the count printed and the name not, and another listed name still refuses; unit instances land, their look-alikes and a provider address do not; the vendor address lands, another local part at the vendor's domain, the vendor's local part at another domain and a provider address do not; - squash_body_scan.py by itself: the names file's formats and that no line of it runs, the address, unit and vendor rules, the host name, a name as a whole token, and its one output line. Measured on the last 600 commit messages of main at 3a8a846 (counts only): 8 refused: 0 names, 5 addresses, 3 home paths; 26 messages name the host (a warning); 402 carry the vendor noreply trailer, which passes. main's history keeps 3 messages with a home path and 3 with an address at a mail provider; history is immutable, as for CC correction #177, and nothing here rewrites it. The README records the scan, the variables, the exit-2 cases, the known gaps and the sources: cli/cli v2.102.0, MicrosoftDocs/WSL, github/docs, systemd/systemd, openai/codex, the bash manual, CPython's -I and socket. The README digests and manifests/evidence.json follow the changed files. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This was referenced Oct 12, 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.
Stacked on #159
This branch is #159 merged onto current
main(merge commit 939bff6), plus one commit of its own:9e47304. Review only 9e47304. In the merge, the only textual conflict was twomanifests/evidence.jsonhashes, foradoption/bootstrap.mdandadoption/platforms/macos-arm64.md; both files auto-merged and were re-hashed.Merge #159 first. This branch then rebases onto
mainas that one commit. Squash-merging this PR on its own would also land all of #159.#159 also has a semantic conflict with main. #171 moved new machines to
v2026.09.24.1, sotest_pages_mentioning_a_changed_install_input_say_sonow requires "changed afterv2026.09.24.1". Merged onto current main, #159 fails that test with 6 errors, because its notes inadoption/bootstrap.mdstep 2 andadoption/platforms/macos-arm64.mdnamev2026.09.23.1. 9e47304 changes those notes to namev2026.09.24.1. The install inputs are byte-identical at both tags, so the notes stay true. #159 needs the same change when it merges main.Why
adoption/bootstrap-linux.sh'sinstall_nativealways ran"$bin" install <pin>. On a Linux/WSL2 host whose native updater (latest channel) is ahead of the pin, every bootstrap re-run moved Claude Code back to the pin and dropped the newer release's fixes. #159 fixed this downgrade on macOS only; its notes list "Linux can still downgrade" as out of scope.What
install_nativeis now byte-identical to macOS's. It carries Adoption hygiene: native Claude Code pin is a floor (2.1.281), ai-memory assistant capture opt-in, ignore Claude Code local state #159's floor:~/.local/bin/<bin> --versionstarts with a dotted numeric version at or above the pin, that launcher is kept. Versions are compared field by field as base-10 numbers, so 2.1.99 is older than 2.1.281.Kept installed claude-code <v>, andinstall_pinskips itsInstalledline.fetchchecks the SHA-256 before the binary runs.adoption/pins-linux-x86_64.json: the claude-codeinstall_notenow describes the floor. It used to say the Linux script still reinstalls the pin every time.adoption/bootstrap.mdstep 2:v2026.09.23as on main" now says what actually differs at that tag, checked withgit show v2026.09.23:…: the script installs the npmclaude-code2.1.278 pin and has no--configure-claude-user-profilestep, and the pin file has nomarkitdown,tavily-cli,orxoragent-browserpin.v2026.09.24.1and covers both scripts.adoption/platforms/linux-wsl2.mdstep 1 gains the Linux "changed afterv2026.09.24.1" note. The floor paragraph inadoption/platforms/macos-arm64.mdnow namesv2026.09.24.1and says Linux runs the sameinstall_native.manifests/evidence.jsonis re-hashed for every changed file withhost_receipts.register_file, each path passed as a separate argument.manifests/evidence.jsonitself is left off that list. It has no entry for itself, and registering it would add an entry hashing its own pre-write bytes.Change from the request: the task asked for a "changed after
v2026.09.23.1" note. Since #171, the docs test requires the pinned tag,v2026.09.24.1, so the notes name that tag.How verified (locally on macOS arm64, where
/bin/bashis 3.2)scripts/validate.py,scripts/validate_convergence.py --all-recorded --root .(18 records valid) andscripts/host_receipts.py validateall exit 0.release_due.py --strict-if-repinned origin/main,new_host_grand_list.py --check,component_matrix.py --check,build_ecosystem.py --check,validate_catalogs.py,validate_foundation.pyandlandscape.pyall exit 0.shellcheck -S style(0.11.0) on both bootstrap scripts andbash -nare clean.test_adoption_*modules plustest_render_config): 341 tests, 35 skipped. There is 1 failure and 6 errors, none caused by this PR:LlamaWrapperQuotingTestsfails the same way on an untouchedorigin/maintree. On a real Mac, System Integrity Protection stripsDYLD_LIBRARY_PATH; Adoption hygiene: native Claude Code pin is a floor (2.1.281), ai-memory assistant capture opt-in, ignore Claude Code local state #159 recorded the same failure.EmbedAcceptanceScriptTestserrors come from the local session sandbox blocking a bind to 127.0.0.1 (PermissionError: [Errno 1] Operation not permitted). Outside the sandbox, the class passes 8 of 8.NativeInstallFloorTestsintests/test_adoption_bootstrap.py: 6 tests, covering 5 kept launchers and 7 cases that must install.fetch,install_nativeandinstall_pinare extracted unchanged frombootstrap-linux.shand run against a one-pin fixture. Onlycurlis shimmed.sha256sumlacks GNU's--check --status(macOS), asha256sumshim runsshasum -a 256withfetch's own arguments, so the checksum is still really compared.bin_diris~/.local/binis not replaced by the exec wrapper.origin/main'sbootstrap-linux.sh, 7 checks fail: the 5 kept versions, the kept launcher in~/.local/bin, and the shared-function check. The install-path tests pass on both versions, because that path is unchanged.install_pin's early return for a kept launcher makes 6 checks fail.python3 -m unittest, run locally inside the session sandbox: 3946 tests, 510 skipped, 1 failure and 36 errors. None come from this PR:LlamaWrapperQuotingTestsfailure described above.PermissionError: [Errno 1] Operation not permittedfrom the sandbox: loopback binds,psand paths. They are intest_offhost_app_state,test_order_throughput,test_research_workflow,test_adaptive_paper_metrics,test_native_maintenance(the application-delivery portability tests) andEmbedAcceptanceScriptTests. Outside the sandbox, those modules pass 158 of 158.setUpClasserrors intest_catalog_freshness_propose. The test commits a generateddocs/ecosystem/index.htmlin a scratch repository, and this machine's global git pre-commit hook (gitleaks) refuses that commit. The same 2 errors occur on a cleanorigin/maintree (76 tests).CI
validateran the full suite on Linux (3950 tests), where GNUsha256sumis used and no shim is needed.validate-macosgates on the adoption test modules (284 tests) and on the full suite onmacos-15(exit 0).bootstrap-linuxran on a freshubuntu-24.04runner with no~/.local/bin/claude. It loggedInstalled claude-code 2.1.281 (native), andclaude --versionprinted2.1.281 (Claude Code). So the checksum-verified install still runs when no launcher exists (run 36007047862).bootstrap-macosandbootstrap-macos-brewshow the same. A fresh runner never has a launcher to keep, so CI cannot exercise the kept path; the new tests cover it.🤖 Generated with Claude Code