Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
232 changes: 221 additions & 11 deletions docs/release/2026-08-23-windows-release-research.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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<version>` 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.
Loading