From 6d0eebdf998857dd8d4d9ce0c77b2067de25674c Mon Sep 17 00:00:00 2001 From: div0-space Date: Mon, 24 Aug 2026 07:55:09 +0200 Subject: [PATCH] [codex/interactive] docs(release): close 0.14.4 research log Record the Windows-inclusive release chronology, public registry evidence, repaired publish workflow, production installer truth, and the remaining account-level OIDC hardening boundary. Authored-By: codex --- .../2026-08-23-windows-release-research.md | 232 +++++++++++++++++- 1 file changed, 221 insertions(+), 11 deletions(-) diff --git a/docs/release/2026-08-23-windows-release-research.md b/docs/release/2026-08-23-windows-release-research.md index 397cd142..26d22a4d 100644 --- a/docs/release/2026-08-23-windows-release-research.md +++ b/docs/release/2026-08-23-windows-release-research.md @@ -1,9 +1,10 @@ # Windows-inclusive release research log — 2026-08-23 -Status: corrective releases in progress. The immutable `v0.14.3` tag exposed +Status: corrective releases complete. The immutable `v0.14.3` tag exposed Windows release-contract failures after four other targets passed. The fixes -are merged to public `main`; AICX `0.12.5` and Loctree `0.14.4` preserve the -failed-tag provenance instead of rewriting it. +landed through reviewed public-main commits; AICX `0.12.5` and Loctree +`0.14.4` preserve the failed-tag provenance instead of rewriting it. Public +GitHub, crates.io, npm, installer, and production-web surfaces are verified. ## Research question @@ -102,18 +103,21 @@ and a bundled archive. The branch was preserved for archaeology, but PR #15 was closed and will not be deployed. Site advancement will be rebuilt as a narrow clean-main change after release assets exist. -## Remaining proof before corrective publish +## Corrective publish result 1. AICX 0.12.5 is complete: signed merged-main release, GitHub assets, npm packages, hosted cold installs on all three OSes, and a real SSH Windows cold install all passed. -2. The synchronized Loctree 0.14.4 branch rehearsal with AICX 0.12.5 passed all - five bundles. Merge the release PR, sign the exact merged-main tag, and - repeat the five-platform proof on the immutable tag before publication. -3. Advance the public installer and release registry through the merged, - deprivatized `loctree-com` VM deployment contract. -4. Re-run real client verification on Windows plus macOS and Debian/Linux - against the final corrective versions. +2. Loctree 0.14.4 is complete: the immutable tag passed the five-platform + combined-bundle matrix, the public release carries nineteen artifacts, the + eight-job thin/npm matrix passed from repaired main, and all four crates and + seven npm identities are public. +3. The public installer and signed release registry were advanced through the + merged, deprivatized `loctree-com` VM deployment contract. The canonical + live index reports both current and stable as 0.14.4. +4. Real client proofs passed on Windows, macOS, and Debian/Linux. The remaining + Windows PATH preference for older operator Cargo binaries is documented as + local installation ownership, not release failure. ## npm first-publish bootstrap finding @@ -312,3 +316,209 @@ publish boundary. The follow-up repair makes the contract single-valued: manual recovery may reach publish only after the verify job proves that HEAD is the exact `v` tag and every platform build succeeds. Preflight now locks both the exact-tag proof and manual publish reachability. + +## Corrective publication and npm bootstrap proof + +Recovery run `32681440907` completed successfully from the repaired workflow +while still checking out the immutable `v0.14.4` source. The public release in +`Loctree/loctree-release` was published on 2026-08-24 with nineteen +assets: five platform bundles, five per-bundle checksums, four raw LSP binaries, +four raw-LSP checksums, and aggregate `SHA256SUMS`. The platform set is macOS +arm64/x64, Linux GNU/musl x64, and Windows MSVC x64. + +The one-time npm bootstrap then published all seven identities at 0.14.4: + +- `@loctree/loctree`, `@loctree/loct`, and `loctree`; +- `@loctree/loctree-darwin-arm64` and `@loctree/loctree-darwin-x64`; +- `@loctree/loctree-linux-x64-gnu`; +- `@loctree/loctree-win32-x64-msvc`. + +All three wrapper names passed isolated macOS installs. The canonical package +shape is script-free: npm selects one platform package through +`optionalDependencies`, and npm 11 emits no lifecycle-script approval warning. +This is now the reference packaging shape for companion binaries. + +A real Windows host supplied two independent proofs. First, an isolated npm +prefix installed 0.14.4 without touching the active toolchain; all four +executables reported `0.14.4+g3e9eb0a7`, and a committed one-file Git fixture +scanned with exit 0. Later, an operator installed the short `loctree` wrapper +into the active global prefix. Direct invocation of its four npm shims again +reported `0.14.4+g3e9eb0a7`. The ordinary PATH still selected older Cargo +installs (`loct`/`loctree` 0.14.2 and `loctree-mcp` 0.8.16) ahead of those +shims. This is an ownership/shadowing finding, not a package-content failure; +the release process did not delete the operator's Cargo installation. + +The production Linux host also installed `loctree@0.14.4`, reported all four +Loctree executables as `0.14.4+g3e9eb0a7`, and completed a real committed +fixture scan. Its first install met an existing global-bin entry and failed +closed with npm `EEXIST`; the operator explicitly resolved that active-prefix +collision. Release acceptance continues to use empty prefixes so `--force` +is never required as evidence. + +## Main publish workflow hardening + +The first post-bootstrap `Publish Releases` dispatch (`32683897382`) failed in +the full release quality gate because the hosted publish job installed +`protoc` but not `rg`. The parity fixture +`scorecard_rg_parity_fixture_matrix` correctly requires ripgrep, so this was a +workflow-image dependency defect rather than a Rust regression. PR #74 installs +both release-gate dependencies when absent; all hosted checks, dogfood jobs, +CodeQL, and Semgrep passed before squash merge as +`f0c0217bfdfd3109b10bc9d12cbdd7e0183cd9d4`. + +Dispatch `32685354153` then passed the release gate and reached crates.io. Its +first two attempts failed at the upload boundary with `403 authentication +failed`. Packaging and verification had both completed, proving that this was +credential state rather than crate content. The configured GitHub secret and +the operator's local `cio...` token were both expired. A crate-restricted token +was generated for update publication of `report-leptos`, `loctree`, and +`loctree-mcp`, saved without printing it, and installed in both Cargo and the +GitHub Actions secret. The final attempt and its downstream thin-release jobs +are recorded in the terminal evidence section below. + +Attempt 3 proved that the replacement token could upload: `report-leptos +0.14.4` became public. It did not publish `loctree`. Cargo stopped during local +packaging because `loctree` requires `loctree-ast = "^0.14.4"`, while the +workflow and the local release driver both omitted `loctree-ast` from their +publish sequence. The old recovery branch then hid that failure: fuzzy +`cargo search loctree | grep 0.14.4` matched an unrelated search result and +reported `loctree 0.14.4` as already published. `loctree-mcp` consequently +failed while resolving the still-absent `loctree = "^0.14.4"` dependency. + +PR #75 replaces that incomplete model with the real crates.io dependency +chain: `report-leptos -> loctree-ast -> loctree -> loctree-mcp`. Exact +availability probes run from a neutral directory with the crates.io registry +named explicitly, so a same-name local workspace package cannot satisfy the +check. Tagged release source and release-control source are also separated: +the immutable tag remains under test and publication, while the poller is +pinned to the exact commit containing the running workflow. This matters for +recovery after a tag because the tag cannot contain a repair written later. +A fresh dispatch from merged main is required; rerunning an earlier failed run +would preserve its old workflow definition. + +## Terminal publish closure + +PR #75 was squash-merged as +`4e742584b31053010399957ab48d37c0544ec466`. Fresh dispatch `32689652655` +then proved the corrected Rust dependency chain end to end: all four crates +became public, all eight CLI/MCP artifact jobs succeeded, and both thin-repo +releases were published. The run failed later, before npm authentication, +because its npm job combined Node 20.20.2 with the moving `npm@latest` tag. +That tag had advanced to npm 12.0.2, whose engine rejected the selected Node +runtime. The monorepo release was consequently skipped. + +PR #76 removed that toolchain drift. It pins Node 24 and the tested npm +11.17.0 trusted-publishing client, and its preflight contract rejects a return +to the moving latest tag. Local preflight, actionlint, ShellCheck, Semgrep, and +diff checks passed; vc-deprivatize reported no findings in the two changed +files. Hosted Linux/macOS, Linux/macOS dogfood, CodeQL, and Semgrep were all +green. The PR was squash-merged as +`690de4c04f87f1377cdb0790ad716406be523d52`. + +Fresh dispatch `32692794671` ran from that exact main commit and completed +successfully. Its release gate passed; neutral crates.io probes found +`report-leptos`, `loctree-ast`, `loctree`, and `loctree-mcp` 0.14.4 already +published and preserved the immutable versions. All eight rebuilt artifacts +passed, including the complete Windows CLI and MCP jobs. The npm job reported +npm 11.17.0, verified all four platform packages and all three wrapper +identities as already public at 0.14.4, and performed no overwrite. Both thin +releases passed idempotently, and the final job created the public monorepo +release. + +Independent public checks after the workflow completed found: + +- `Loctree/loctree-release` v0.14.4: nineteen assets across macOS arm64/x64, + Linux GNU/musl x64, and Windows MSVC x64; +- `Loctree/loct` v0.14.4: twelve CLI/MCP assets; +- `Loctree/loctree-mcp` v0.14.4: six MCP assets; +- `Loctree/loctree` v0.14.4: public source/orchestration release; +- all seven npm identities at 0.14.4; +- all four crates at 0.14.4 through neutral `cargo info --registry crates-io`. + +The successful idempotent npm run proves the repaired Node/npm toolchain and +the package-presence path. It does not independently exercise an OIDC upload, +because immutable 0.14.4 packages already existed before that run. Registering +the seven npm trusted publishers remains an operator-authenticated hardening +step: npm requires a fresh TOTP even to inspect that account-level trust +configuration. This does not change the publication state of 0.14.4. + +The mandatory post-release vc-deprivatize scan remained exactly at the +inherited repository baseline: 1,337 findings in the full review scan and 560 +unambiguous findings in fail-closed verification. This research document +produced zero findings. The historical repository-wide hygiene debt is not +waived or misreported as release-introduced exposure. + +## Stable web registry and installer truth + +The release registry was published to the production VM through the repository +Make contract, not by copying ad hoc files. Its signed 0.14.4 manifest contains +all five platform targets and uses GPG fingerprint +`8868139E8A9A2291D067135FB979B60C7079E4D4`. Live +`releases/index.json` reports both `current` and `channels.stable` as 0.14.4. + +PR #18, merged as `f39d311fa801d81ccbefa68d2f8933f80e3931c6`, +makes that registry reproducible: the default target set is the complete +five-platform matrix, release date is explicit, target names are validated, +and manifest plus index metadata are generated deterministically from verified +artifact bytes. Determinism, tamper, coverage, and unsafe-target tests passed, +as did the full local site gate and mandatory deprivatization pass. + +Repository inspection nevertheless found a P0 split brain: the live release +index was current while the public bootstrap script still selected 0.13.1. +PR #19, merged as `2cd2a5322b4fb12c3216e3cfb6f4628c2a9194fb`, removes the numeric installer +default. The script now resolves `index.current`, preserves an exact +`LOCTREE_VERSION=x.y.z` override, and fails closed for an unavailable, missing, +or malformed version. Its regression proves dynamic resolution, offline exact +override, and invalid-version rejection on macOS Bash 3.2-compatible gates. + +The first production `make deploy` then exposed an unrelated build-tool +split brain: Cargo.lock selected Wasm schema 0.2.120 while the machine-global +`wasm-bindgen-cli` was 0.2.122. PR #20, merged as +`1a9d3ec2814b9f18a55bef692a464799a4d60ec9`, provisions the exact locked CLI in +a versioned repository-local build-tools directory and routes build, watch, and +deploy through one wrapper. Its test proves first install, cache reuse, +stale-tool replacement, and PATH precedence. The real Wasm build and Linux +cross-build then passed. + +The first atomic deployment restarted the service successfully but returned +non-zero while deleting its old rollback: exactly two retired files carried +the Linux immutable attribute. Their paths and count were verified, the +attribute was cleared only on those two files, and only the old rollback tree +was removed. A complete repeat of `make deploy` then passed build, rsync, +atomic swap, service restart, and direct upstream HTTP smoke (`200`). Release +files remained outside the site rsync and were not overwritten. + +Finally, a fresh live macOS install used the public URL with an isolated install +directory and cache. It selected 0.14.4 from the index, verified the per-asset +checksum, aggregate checksum, detached GPG signature, and all six Apple code +signatures, then installed: + +- `loct`, `loctree`, `loctree-mcp`, and `loctree-lsp` at + `0.14.4+g3e9eb0a7`; +- `aicx` and `aicx-mcp` at `0.12.5+gced57997`. + +The installed `loct` scanned a committed fixture with `Status: OK`. The entire +temporary install, fixture, and isolated cache were moved to Trash afterward. + +## Research intake after release + +These observations are inputs to the next research sprint, not changes folded +into the corrective release: + +1. The curl bundle already carries Loctree and AICX together, but the public + npm description promises "one npm install" while exporting only the four + Loctree binaries. If AICX overlay becomes a required Loctree capability, + all wrapper identities need a six-binary contract plus a real overlay cold + smoke. +2. AICX 0.12.5 installs successfully on macOS and Windows, but npm 11.17 warns + that its wrapper and platform package run unapproved postinstall scripts. + npm 11.5 runs the same hooks without that warning. The accepted follow-up + direction is script-free platform packages carrying ready binaries, modeled + on Loctree's current npm shape. AICX owns that implementation separately. +3. MCP/HTTP service configuration and launchd/systemd definitions may be useful + distribution artifacts, but network installs must not silently create boot + persistence. Installation and start must remain an explicit opt-in command. +4. The Codex post-compaction recall is functionally correct but renders as a + nested box with awkward wrapping and a decorative brain pictogram. This is + an apparatus-quality finding for the research sprint. The protected recall + hooks were not modified during release.