|
| 1 | +--- |
| 2 | +phase: 09.1-bootstrap-artifact-and-abi-alignment-for-default-installs |
| 3 | +plan: 02 |
| 4 | +subsystem: release |
| 5 | +tags: [release, distribution, bootstrap, abi, recovery, validation] |
| 6 | + |
| 7 | +requires: |
| 8 | + - phase: 09.1-bootstrap-artifact-and-abi-alignment-for-default-installs |
| 9 | + provides: Plan 01 source-state preparation (bootstrap.Version pin, ABI canary, strict-readiness ABI gate, dated CHANGELOG section) |
| 10 | +provides: |
| 11 | + - Published v0.1.4 release across the full platform matrix (linux-amd64, linux-arm64, darwin-amd64, darwin-arm64, windows-amd64) with binaries, certificates, signatures, and SHA256SUMS{,.pem,.sig} |
| 12 | + - Validated default-install path: NewParser() resolves v0.1.4 artifacts via bootstrap with no PURE_SIMDJSON_LIB_PATH override |
| 13 | + - Public bootstrap validation evidence (workflow_dispatch run 24990348339) |
| 14 | + - Operator-recorded validation evidence in 09.1-RELEASE-VALIDATION.md |
| 15 | + - README de-hedged from "upcoming-release" framing to validated v0.1.4 default-install statement |
| 16 | + - Recovery cycle precedent: v0.1.2 -> v0.1.3 -> v0.1.4 with no tag mutation |
| 17 | +affects: [release, bootstrap, distribution, README, docs/bootstrap.md, docs/releases.md, CHANGELOG] |
| 18 | + |
| 19 | +tech-stack: |
| 20 | + added: [] |
| 21 | + patterns: |
| 22 | + - "Tag-mutation-free recovery: each failed publish creates a new patch version; failing tags remain in place as evidence" |
| 23 | + - "ABI/version pin lock-step: bootstrap.Version, ffi.ABIVersion, and the abi_assertion.go canary all advance together per recovery" |
| 24 | + - "Strict-readiness gate as the only pre-publish source check; release.yml as the only publish path" |
| 25 | + |
| 26 | +key-files: |
| 27 | + created: |
| 28 | + - .planning/phases/09.1-bootstrap-artifact-and-abi-alignment-for-default-installs/09.1-RELEASE-VALIDATION.md |
| 29 | + - .planning/phases/09.1-bootstrap-artifact-and-abi-alignment-for-default-installs/09.1-UAT.md |
| 30 | + modified: |
| 31 | + - internal/bootstrap/version.go (0.1.2 -> 0.1.3 -> 0.1.4) |
| 32 | + - internal/bootstrap/abi_assertion.go (canary version advances per recovery) |
| 33 | + - internal/bootstrap/checksums.go (per-version comments) |
| 34 | + - src/native/simdjson_bridge.cpp (macOS allocator telemetry; manylinux libstdc++ allocator workaround) |
| 35 | + - scripts/release/verify_glibc_floor.sh (Linux symbol-visibility hardening) |
| 36 | + - scripts/release/test_release_workflow_contracts.py (new contract tests for recovery scenarios) |
| 37 | + - docs/bootstrap.md (consumer examples updated to v0.1.4) |
| 38 | + - docs/releases.md (release-runbook examples updated to v0.1.4) |
| 39 | + - CHANGELOG.md (dated [0.1.3] and [0.1.4] sections added) |
| 40 | + - README.md (line 67 de-hedged for shipped v0.1.4) |
| 41 | + |
| 42 | +key-decisions: |
| 43 | + - "Tag mutation is forbidden under stress: when v0.1.2 failed during release.yml, the path forward was v0.1.3 (then v0.1.4), never re-tagging v0.1.2." |
| 44 | + - "Recovery scope stayed bounded to the publish pipeline: macOS allocator-cleanup telemetry, Linux symbol visibility, manylinux libstdc++ basic_string allocator behavior. No parse/materialize hot-path changes." |
| 45 | + - "v0.1.2 benchmark snapshot remains the validated baseline; v0.1.3/v0.1.4 are recovery releases with no parse/materialize drift, so re-running the full benchmark suite was not required." |
| 46 | + - "Operator-recorded validation evidence is required even retroactively: 09.1-RELEASE-VALIDATION.md was produced after the recovery cycles to close the Plan 02 must_have artifact gap." |
| 47 | + |
| 48 | +patterns-established: |
| 49 | + - "Recovery cycles are first-class workflow events, not exception handling: each recovery merges through a separate PR with its own dated CHANGELOG section, version pin advance, and ABI-canary advance." |
| 50 | + - "Post-ship documentation must be re-attacked against the actual shipped version, not the originally-targeted version." |
| 51 | + |
| 52 | +requirements-completed: [DIST-01, DIST-02, DIST-03, DIST-04, DIST-05, CI-05, CI-06, DOC-01, DOC-05, DOC-06] |
| 53 | + |
| 54 | +duration: distributed (PR #22 + recovery PRs #23 #24 over 2026-04-25 to 2026-04-27, plus post-ship gap closure in PR #25) |
| 55 | +completed: 2026-04-27 |
| 56 | +--- |
| 57 | + |
| 58 | +# Phase 09.1 Plan 02: Release Publication and Public Bootstrap Validation Summary |
| 59 | + |
| 60 | +**v0.1.4 published as the validated default-install version after two tag-mutation-free recovery cycles from the originally-targeted v0.1.2.** |
| 61 | + |
| 62 | +## Performance |
| 63 | + |
| 64 | +- **Started:** 2026-04-25 (Plan 01 landed; first publish attempt) |
| 65 | +- **Completed:** 2026-04-27 (v0.1.4 published, public bootstrap validation passed, evidence captured) |
| 66 | +- **Originally targeted version:** 0.1.2 |
| 67 | +- **Shipped version:** 0.1.4 |
| 68 | +- **Recovery cycles:** 2 (v0.1.2 -> v0.1.3 -> v0.1.4) |
| 69 | +- **PRs delivering Plan 02 outcome:** #22 (initial attempt), #23 (v0.1.3 recovery), #24 (v0.1.4 recovery), #25 (post-ship evidence/doc gap closure) |
| 70 | + |
| 71 | +## Accomplishments |
| 72 | + |
| 73 | +- Published `v0.1.4` GitHub Release with the full platform matrix: 5 binaries (linux-amd64.so, linux-arm64.so, darwin-amd64.dylib, darwin-arm64.dylib, windows-amd64-msvc.dll) plus per-binary cosign certificates and signatures plus SHA256SUMS{,.pem,.sig} = 18 release assets total. |
| 74 | +- Confirmed `release.yml` (run 24990180166) succeeded as the sole publish path; no hand-uploaded artifacts; tag commit anchored on `origin/main` per the Phase 06 verify-tag-source gate. |
| 75 | +- Dispatched `public-bootstrap-validation.yml` against `version=0.1.4` (run 24990348339): full `validate-r2` matrix success across all 5 platforms plus `validate-gh-fallback` subset success on linux-amd64, darwin-arm64, windows-amd64. |
| 76 | +- End-to-end verified default install on darwin-arm64: a fresh consumer module with `PURE_SIMDJSON_LIB_PATH` unset and an empty `PURE_SIMDJSON_CACHE_DIR` bootstrapped `v0.1.4/darwin-arm64/libpure_simdjson.dylib` from the published release, verified its SHA256SUMS entry, loaded it, and parsed JSON correctly (UAT 09.1-UAT.md test 1). |
| 77 | +- Advanced `bootstrap.Version` and the `abi_assertion.go` canary in lock-step per recovery (0.1.2 -> 0.1.3 -> 0.1.4) so every shipped version preserves the `ffi.ABIVersion = 0x00010001` invariant at compile time. |
| 78 | +- Captured operator-recorded validation evidence in `09.1-RELEASE-VALIDATION.md` with all six required Plan 02 headings (Strict Readiness, Release Workflow, Public Bootstrap Validation, Outcome, Recovery Notes) and the literal `Outcome: PASSED` evidence lines for the validated version 0.1.4. |
| 79 | +- De-hedged `README.md:67` from the "upcoming-release evidence; Phase 09.1 still owns ... before a release tag" framing to a validated-v0.1.4 default-install statement. |
| 80 | +- Documented the recovery cycle in dated `CHANGELOG.md [0.1.3]` and `[0.1.4]` sections per the no-mutate policy. |
| 81 | + |
| 82 | +## Recovery Cycle Detail |
| 83 | + |
| 84 | +| Tag | release.yml | Outcome | Recovery driver | |
| 85 | +|-----|-------------|---------|-----------------| |
| 86 | +| v0.1.2 | run 24988998092 | failure | Linux release artifact rejected: macOS placement-new clash plus manylinux libstdc++ basic_string allocator incompatibility. | |
| 87 | +| v0.1.3 | run 24989789933 | failure | Symbol-visibility audit flagged non-public dynamic symbols in Linux artifacts; macOS native-string cleanup telemetry attribution issue surfaced. PR #23. | |
| 88 | +| v0.1.4 | run 24990180166 | success | manylinux libstdc++ basic_string allocator workaround in `src/native/simdjson_bridge.cpp`; full release matrix produced and signed. PR #24. | |
| 89 | + |
| 90 | +Each recovery preserved the failed tag in place; no mutation, no re-tag. |
| 91 | + |
| 92 | +## Task Commits |
| 93 | + |
| 94 | +Plan 02 had a single `checkpoint:human-verify` task (release publication + validation evidence). Its outcome was delivered across multiple merged PRs rather than a single linear commit chain: |
| 95 | + |
| 96 | +- PR #22 (`19d2c5c`) — Plan 01 landed alongside the v0.1.2 publication attempt. |
| 97 | +- PR #23 (`c17db54`) — v0.1.3 recovery: macOS allocator telemetry, Linux symbol-visibility hardening, version/ABI advance to 0.1.3. |
| 98 | +- PR #24 (`0f53f3f`) — v0.1.4 recovery: manylinux libstdc++ basic_string allocator workaround, version/ABI advance to 0.1.4. **Final shipped version.** |
| 99 | +- PR #25 (`6277e70`, commit `a0c3e40`) — post-ship gap closure: `09.1-RELEASE-VALIDATION.md` written, README de-hedged, `09.1-UAT.md` recorded. |
| 100 | + |
| 101 | +## Files Created/Modified |
| 102 | + |
| 103 | +**Recovery (PR #23, v0.1.3):** |
| 104 | +- `src/native/simdjson_bridge.cpp` — macOS allocator-cleanup telemetry attribution. |
| 105 | +- `scripts/release/verify_glibc_floor.sh` — Linux symbol-visibility hardening. |
| 106 | +- `scripts/release/test_release_workflow_contracts.py` — new contract tests for the recovery scenario. |
| 107 | +- `internal/bootstrap/{version,abi_assertion,checksums}.go` — version pin advance to 0.1.3. |
| 108 | +- `docs/{bootstrap,releases}.md`, `CHANGELOG.md` — version examples and dated section. |
| 109 | + |
| 110 | +**Recovery (PR #24, v0.1.4):** |
| 111 | +- `src/native/simdjson_bridge.cpp` — manylinux libstdc++ `std::basic_string` allocator workaround. |
| 112 | +- `internal/bootstrap/{version,abi_assertion,checksums}.go` — version pin advance to 0.1.4. |
| 113 | +- `docs/{bootstrap,releases}.md`, `CHANGELOG.md` — version examples and dated section. |
| 114 | + |
| 115 | +**Post-ship gap closure (PR #25):** |
| 116 | +- `.planning/phases/09.1-.../09.1-RELEASE-VALIDATION.md` — Plan 02 must_have evidence artifact. |
| 117 | +- `.planning/phases/09.1-.../09.1-UAT.md` — UAT audit trail (7 pass / 2 issue / both closed in same commit). |
| 118 | +- `README.md` — line 67 de-hedged. |
| 119 | + |
| 120 | +## Decisions Made |
| 121 | + |
| 122 | +- The no-mutate-tag policy (a Plan 02 must_have truth) held under stress: when v0.1.2 publication failed, recovery proceeded as v0.1.3, not as a re-tag. When v0.1.3 also failed, recovery proceeded as v0.1.4. Both failed tags remain in place as evidence. |
| 123 | +- Recovery scope was deliberately bounded to the publish pipeline. macOS allocator-cleanup telemetry, Linux symbol visibility, and manylinux libstdc++ allocator behavior are all build/packaging correctness fixes; the parse/materialize hot path was unchanged across v0.1.2 -> v0.1.4. |
| 124 | +- Re-running the full benchmark suite for v0.1.4 was not required because no parse/materialize code changed. The existing `docs/benchmarks/results-v0.1.2.md` remains the validated benchmark baseline; this is documented in README.md:67. |
| 125 | +- Plan 02's must_have artifact (`09.1-RELEASE-VALIDATION.md`) was produced retroactively after the recovery cycles. Recovery work focused on shipping the publish; the post-ship documentation step was skipped at the time and re-attacked through PR #25 once UAT surfaced the gap. |
| 126 | + |
| 127 | +## Deviations from Plan |
| 128 | + |
| 129 | +- **Version drift (v0.1.2 -> v0.1.4):** Plan 02 targeted v0.1.2 throughout; the actual shipped version is v0.1.4. The plan's must_have truths and acceptance criteria were satisfied with the version label adjusted to reflect what shipped (e.g., `Strict readiness: PASSED` and `validated version: 0.1.4` in the evidence file). |
| 130 | +- **Distributed delivery across 4 PRs:** Plan 02 expected a single human-verify task closure; the actual delivery happened across PR #22 + #23 + #24 + #25 because of the two recovery cycles plus the post-ship gap closure. This was the right outcome under the no-mutate-tag policy. |
| 131 | +- **Post-ship doc gap (closed in PR #25):** Two Plan 02 must_haves (`09.1-RELEASE-VALIDATION.md` existence; README de-hedged) were not produced during the recovery cycles. They were closed in PR #25 after UAT surfaced the divergence between shipped reality and recorded artifacts. |
| 132 | + |
| 133 | +## Issues Encountered |
| 134 | + |
| 135 | +- **v0.1.2 release.yml failure:** macOS placement-new clash and manylinux libstdc++ `std::basic_string` allocator incompatibility blocked the Linux artifact build. Recovery via v0.1.3. |
| 136 | +- **v0.1.3 release.yml failure:** Symbol-visibility audit and macOS native-string-cleanup telemetry attribution surfaced as additional gates after the v0.1.2 fixes. Recovery via v0.1.4. |
| 137 | +- **Post-ship documentation drift:** Recovery PRs focused on the publish-pipeline failure modes; the consumer-facing README and the `09.1-RELEASE-VALIDATION.md` must_have artifact were never re-targeted from v0.1.2 to v0.1.4 during the recovery cycles. Gap surfaced by retroactive UAT and closed in PR #25. |
| 138 | + |
| 139 | +## Verification |
| 140 | + |
| 141 | +- `bash scripts/release/check_readiness.sh --strict --version 0.1.4` from `origin/main`: `bootstrap ABI state ok: version 0.1.4, abi 0x00010001` / `strict release readiness checks passed for version 0.1.4` / exit 0. |
| 142 | +- `go test ./internal/bootstrap ./internal/ffi`: PASS — compile-time ABI canary holds for `bootstrap.Version=0.1.4` <-> `ffi.ABIVersion=0x00010001`. |
| 143 | +- `gh release view v0.1.4`: 18 assets across 5 platforms (binaries + .pem + .sig + SHA256SUMS{,.pem,.sig}). |
| 144 | +- `public-bootstrap-validation.yml` run 24990348339 (workflow_dispatch on `main`, 2026-04-27): all required jobs success; `notify scheduled validation failure` skipped per its conditional. |
| 145 | +- Fresh-consumer end-to-end default install on darwin/arm64 (UAT test 1): `env -u PURE_SIMDJSON_LIB_PATH PURE_SIMDJSON_CACHE_DIR=/tmp/psdj-uat-fresh-cache go run .` succeeded; cache populated with `v0.1.4/darwin-arm64/libpure_simdjson.dylib` from the published release. |
| 146 | +- UAT (`09.1-UAT.md`): 9 tests, 7 pass, 2 issue (both doc-only, both closed in PR #25). |
| 147 | + |
| 148 | +## Known Stubs |
| 149 | + |
| 150 | +None. |
| 151 | + |
| 152 | +## User Setup Required |
| 153 | + |
| 154 | +None going forward. The Plan 02 user_setup (GH_TOKEN for `gh`, GitHub Actions dashboard access for dispatching `release.yml` and `public-bootstrap-validation.yml`) was consumed during the recovery cycles. |
| 155 | + |
| 156 | +## Next Phase Readiness |
| 157 | + |
| 158 | +Phase 09.1 is fully closed end-to-end: |
| 159 | + |
| 160 | +- Plan 01 SUMMARY recorded the source-state preparation (2026-04-25). |
| 161 | +- Plan 02 SUMMARY (this file) records the publish + recovery + validation outcome. |
| 162 | +- 09.1-RELEASE-VALIDATION.md captures operator-recorded evidence with `Outcome: PASSED`. |
| 163 | +- 09.1-UAT.md records 7-pass / 2-issue / both-closed. |
| 164 | +- README.md and bootstrap/release docs reflect the shipped v0.1.4 reality. |
| 165 | + |
| 166 | +Phase 10 (`lightweight-pr-benchmark-regression-signal`) can start from a state where the published default-install path is validated and the no-mutate-tag policy is precedented. Phase 10's PR-time benchmark regression signal will benefit from the Phase 09.1 evidence pattern (CI-anchored, not local; failure surfaces in a workflow run; recovery is via a new patch version, not a re-tag). |
| 167 | + |
| 168 | +## Self-Check: PASSED |
| 169 | + |
| 170 | +- Found created files: `09.1-RELEASE-VALIDATION.md`, `09.1-UAT.md`, and this summary. |
| 171 | +- Found shipping commits: `c17db54` (PR #23), `0f53f3f` (PR #24), `a0c3e40` (PR #25 squash content), `6277e70` (PR #25 merge). |
| 172 | +- Found release tag and run identifiers: `v0.1.4`, release.yml run `24990180166`, public-bootstrap-validation.yml run `24990348339`. |
| 173 | + |
| 174 | +--- |
| 175 | +*Phase: 09.1-bootstrap-artifact-and-abi-alignment-for-default-installs* |
| 176 | +*Completed: 2026-04-27* |
0 commit comments