Skip to content

Commit 472761b

Browse files
committed
ci(release): add prepared-not-fired release.yml + close D-541/542/543
ADR-0167. Release-artifact + version-staging + dep-pin coherence: - .github/workflows/release.yml (D-542): native matrix (macos-15 aarch64 + ubuntu-22.04 x86_64) builds `cljw` with -Dwasm -Doptimize=ReleaseSafe -Dcpu=baseline, tar.gz + sha256, attaches to the GitHub Release. Fires ONLY on a user-pushed `v*` tag (the loop never tags). actionlint clean. - D-541 version staging: convention set + honoured (.version stays 1.0.0-alpha.1; all rc.1 strings staged under CHANGELOG `## [Unreleased]`); user owns the bump. - D-543 dep-pin: THIRD_PARTY records exact pins; the eager zlinter fetch is confirmed structural (build.zig:5 top-level @import, cf. zwasm D-274) and documented as a named pre-1.0 limitation. zwasm-pin bump = user-owned CODEV. D-541/542/543 discharged; D-538 narrowed (settings.json = user action). rc.1 readiness gate: only D-536 (debt code-truth reconcile) remains loop-ownable.
1 parent e327e46 commit 472761b

4 files changed

Lines changed: 124 additions & 59 deletions

File tree

.dev/debt.yaml

Lines changed: 30 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -38,63 +38,24 @@ active:
3838
last_reviewed: "2026-07-01"
3939
- id: "D-538"
4040
status: |-
41-
open (2026-07-01, user-directed; ADR-0167 S2). Personal-environment
42-
decoupling: scripts/run_remote_ubuntu.sh host → ${CLJW_UBUNTU_HOST:-ubuntunote}
43-
(behavior-preserving default); the 2 src path-leak comments
44-
(agent.zig:213 ubuntunote, stm/tval.zig:17 ~/Documents/OSS path) generalized;
45-
personal additionalDirectories in .claude/settings.json moved to the
46-
gitignored settings.local.json.
47-
category: "infra"
48-
quality_floor: "release-mechanics: env decoupling (ADR-0167)"
49-
barrier: |-
50-
rc.1 readiness gate (finite). NOTE: .claude/** edits may hit the auto-mode
51-
self-modification block — surface those to the user (memory
41+
PARTIAL 2026-07-01 (ADR-0167 S2). Loop-ownable parts DONE:
42+
scripts/run_remote_ubuntu.sh host+dir → ${CLJW_UBUNTU_HOST:-ubuntunote} /
43+
${CLJW_REMOTE_DIR:-...} (behavior-preserving defaults; all `ssh $HOST`);
44+
the 2 src path-leak comments generalized (agent.zig:213 "Mac vs ubuntunote"
45+
→ "host- and scheduler-dependent"; stm/tval.zig:17 dropped the author-local
46+
`~/Documents/OSS/.../Ref.java:64-69` absolute path, kept the useful
47+
`clojure.lang.Ref.TVal` upstream reference). REMAINING (non-autonomous,
48+
`.claude/`-edit-blocked): move the personal `additionalDirectories`
49+
(`~/Documents/MyProducts/`, `~/Documents/OSS/`) in .claude/settings.json to
50+
the gitignored settings.local.json — surfaced to the user (the auto-mode
51+
self-modification classifier denies `.claude/` edits; memory
5252
claude_rules_edit_permission_block).
53-
last_reviewed: "2026-07-01"
54-
- id: "D-541"
55-
status: |-
56-
open (2026-07-01, user-directed; ADR-0167). Version staging (USER-OWNED
57-
boundary): all rc.1 prep lands while build.zig.zon .version stays
58-
1.0.0-alpha.1; every 1.0.0-rc.1 string in CHANGELOG/THIRD_PARTY/docs is
59-
STAGED text that the user's single .version bump + git tag activates
60-
(CHANGELOG rc.1 under `## [Unreleased]`). The loop NEVER tags/publishes.
61-
category: "infra"
62-
quality_floor: "release-mechanics: version staging (ADR-0167)"
63-
barrier: |-
64-
rc.1 readiness gate (finite). The final bump + tag is the user's action.
65-
Avoids the transient SSOT contradiction zwasm hit (fix-CHANGELOG-version).
66-
last_reviewed: "2026-07-01"
67-
- id: "D-542"
68-
status: |-
69-
open (2026-07-01, user-directed; ADR-0167). Release-artifact workflow
70-
(PREPARED-not-fired): a tag-triggered .github/workflows/release.yml building
71-
the static cljw binary for macOS + Linux
72-
(-Dwasm -Doptimize=ReleaseSafe -Dcpu=baseline, ADR-0132) attached to the
73-
GitHub release. For a single-static-binary product (F-013) a pre-built cljw
74-
is most of what a non-Zig user needs. Fires ONLY on a user-pushed tag.
75-
category: "infra"
76-
quality_floor: "release-mechanics: release-artifact workflow (ADR-0167)"
77-
barrier: |-
78-
rc.1 readiness gate (finite). Depends on D-539 CI SSOT. Mirrors zwasm's
79-
release.yml. -Dcpu=baseline for the deploy artifact (memory
80-
fly_deploy_zig_binary_gotchas: SIGILL on shared-cpu otherwise).
81-
last_reviewed: "2026-07-01"
82-
- id: "D-543"
83-
status: |-
84-
open (2026-07-01, user-directed; ADR-0167). Dependency-pin coherence /
85-
reproducibility. (a) The incoherent story of a 1.0.0-rc.1 embedding zwasm
86-
v2.0.0-alpha.3: bump the pin to a coherent zwasm release once one exists
87-
(user-owned CODEV) OR document the version relationship in THIRD_PARTY.md +
88-
zwasm_capabilities.md as a known pre-1.0 coupling. (b) zlinter dev-dep is
89-
fetched EAGERLY (a doc-reader's first `zig build` pulls an external repo —
90-
offline/reproducibility footgun): make lazy/dev-only if the build.zig
91-
restructure is tractable, else record as a NAMED pre-1.0 wart with this row.
9253
category: "infra"
93-
quality_floor: "release-mechanics: dep-pin coherence (ADR-0167)"
54+
quality_floor: "release-mechanics: env decoupling (ADR-0167)"
9455
barrier: |-
95-
rc.1 readiness gate (finite). (a) is partly user-owned (zwasm tag = CODEV);
96-
the doc half is loop-ownable. (b) zlinter lazy-fetch is a known Zig
97-
build-graph limit (cf. zwasm D-274) — may resolve to the documented-wart form.
56+
rc.1 readiness gate (finite) — but the residual (settings.json move) is
57+
the `.claude/`-edit-blocked non-autonomous remainder; a USER action, not a
58+
loop blocker. The finite gate treats D-538's loop-ownable half as done.
9859
last_reviewed: "2026-07-01"
9960
- id: "D-522"
10061
status: |-
@@ -2608,6 +2569,21 @@ standing:
26082569
barrier: "open after the D-440 arc completes (R4 + R5 must first rewrite the bulk of 'Phase N' citations to gap-area terms). Premature adoption = ~70 dangling citations with no 1:1 redirect. Trigger: D-440 R4/R5 done + a user nod to re-architect the planning axis (it is depth-4, the project's organizing metaphor)."
26092570
last_reviewed: "2026-06-15"
26102571
discharged:
2572+
- id: "D-543"
2573+
status: "DISCHARGED 2026-07-01 (ADR-0167; loop-ownable part). (a) Dep pins recorded exactly in THIRD_PARTY.md (zwasm Apache-2.0 @fc7ff0b3b/v2.0.0-alpha.3, -Dwasm-only; zlinter MIT @9b4d67b9). Resolving the '1.0.0-rc.1 embeds zwasm v2.0.0-alpha.3' stability story by BUMPING the pin to a coherent zwasm release is USER-OWNED CODEV (needs zwasm to cut one — tracked via handover north-star + .dev/zwasm_capabilities.md), not a loop task. (b) Confirmed the eager zlinter fetch is STRUCTURAL: build.zig:5 has a top-level comptime `@import(\"zlinter\")`, which the Zig build graph resolves eagerly (matches zwasm's ratified D-274 — lazy needs an upstream b.lazyDependency-able builder). Recorded as a NAMED pre-1.0 limitation in THIRD_PARTY.md (accepted development-time fetch, not a runtime dep). Both parts resolved to the loop's extent; the zwasm-bump residual is user/upstream-gated."
2574+
category: "infra"
2575+
barrier: "none — DISCHARGED (zwasm-pin bump residual is user-owned CODEV)."
2576+
last_reviewed: "2026-07-01"
2577+
- id: "D-542"
2578+
status: "DISCHARGED 2026-07-01 (ADR-0167). Release-artifact workflow .github/workflows/release.yml (PREPARED-not-fired): native matrix (macos-15 aarch64 + ubuntu-22.04 x86_64 — native, not cross-compile, to keep the embedded zwasm JIT's arch-specific codegen honest) builds cljw with `-Dwasm -Doptimize=ReleaseSafe -Dcpu=baseline` (baseline CPU = shipped/deploy config, avoids SIGILL on shared hosts per memory fly_deploy_zig_binary_gotchas), verifies `cljw --version`, tar.gz + .sha256, attaches to the GitHub Release (idempotent create + upload --clobber). Triggers ONLY on a user-pushed `v*` tag or manual dispatch (the loop never tags). permissions contents:write; TAG_NAME via env (no injection). actionlint clean. First-tag validation (each artifact runs, reports ReleaseSafe) noted in the workflow header."
2579+
category: "infra"
2580+
barrier: "none — DISCHARGED (fires on the user's tag; first-tag validation noted)."
2581+
last_reviewed: "2026-07-01"
2582+
- id: "D-541"
2583+
status: "DISCHARGED 2026-07-01 (ADR-0167). Version-staging convention established + honoured: build.zig.zon .version stays `1.0.0-alpha.1` (verified — no premature rc.1 bump); every `1.0.0-rc.1` string in CHANGELOG/THIRD_PARTY/docs is STAGED text under `## [Unreleased]` (+ a CHANGELOG STAGING NOTE spelling out the maintainer's bump+tag step). This avoids the transient SSOT contradiction zwasm hit (their dedicated fix-CHANGELOG-version commit). The final `.version` bump + `git tag`/publish is USER-OWNED — the loop prepares everything and never tags. Nothing left for the loop to do here until the user cuts the tag."
2584+
category: "infra"
2585+
barrier: "none — DISCHARGED (convention set; the bump/tag is the user's action)."
2586+
last_reviewed: "2026-07-01"
26112587
- id: "D-540"
26122588
status: "DISCHARGED 2026-07-01 (ADR-0167). CHANGELOG.md (Keep-a-Changelog; the rc.1 entry sits under `## [Unreleased]` per the D-541 staging convention + a STAGING NOTE explaining the maintainer's tag/bump step). THIRD_PARTY.md naming exact license + pinned commit per fetched dep (zwasm Apache-2.0 @fc7ff0b3b/v2.0.0-alpha.3, -Dwasm-only; zlinter MIT @9b4d67b9, dev-only) — an EPL-2.0 project building against non-EPL deps (none vendored in-tree; fetched by the Zig pkg mgr) + the EPL clj lineage cross-ref to NOTICE. .gitattributes (LF normalize + .wasm/.png binary + docs/ja/archive linguist-documentation) + .editorconfig. build.zig.zon .paths now ships LICENSE + NOTICE + THIRD_PARTY.md + CHANGELOG.md + README + src (NOTICE was absent despite EPL src/lang/clj/** shipping inside src). zlinter MIT verified against the fetched LICENSE."
26132589
category: "docs"

.dev/handover.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@
1818
via `scripts/ci_gate.sh` SSOT + versions.lock + dependabot; repo made zig-fmt-clean.
1919
First GitHub run verified post-push. Follow-ups (non-blocking): gitleaks job, API canary.
2020
- [ ] **D-536** debt-ledger code-truth reconcile (zwasm S0 pattern).
21-
- [ ] **D-538** personal-env decoupling (SSH host→env default; 2 src leaks;
22-
settings.local.json). *`.claude/**` edits may hit auto-mode block → surface.*
21+
- [~] **D-538** personal-env decoupling — SSH host+dir→env default + 2 src leaks
22+
*DONE 2026-07-01*; **settings.json `additionalDirectories` move = USER action**
23+
(`.claude/`-edit-blocked, non-autonomous; surfaced — not a loop blocker).
2324
- [x] **D-540** CHANGELOG (`## [Unreleased]`) + THIRD_PARTY + .gitattributes/.editorconfig + ship NOTICE/CHANGELOG/THIRD_PARTY in .paths *DISCHARGED 2026-07-01*.
24-
- [ ] **D-542** release.yml (prepared-not-fired, static cljw binary).
25-
- [ ] **D-543** dep-pin coherence (zwasm alpha.3 vs rc.1; eager zlinter fetch).
26-
- [ ] **D-541** version staging convention (all rc.1 strings = staged text).
25+
- [x] **D-542** release.yml (prepared-not-fired, native matrix, cljw tar.gz+sha) *DONE 2026-07-01; fires on user tag*.
26+
- [x] **D-543** dep-pin coherence *DONE 2026-07-01 (loop part)* — pins in THIRD_PARTY;
27+
eager zlinter fetch confirmed structural (build.zig:5 top-level @import) → documented
28+
pre-1.0 wart; **zwasm-pin bump = user-owned CODEV** (needs a zwasm release).
29+
- [x] **D-541** version staging convention (rc.1 strings staged; .version stays alpha.1) *DONE 2026-07-01*.
2730
- **Track B (parallel, non-blocking for the tag):** the easiest-first `active:`
2831
drain continues — D-522 de-pointer / D-523 doc-audit / D-526 interop / D-527
2932
parity / D-528 real-deps.edn / D-529 / D-305 / D-470 / D-222 / D-460 / D-439 sqrt.

.github/workflows/release.yml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Release — build the ReleaseSafe, Wasm-enabled `cljw` binary for each supported
2+
# target on its NATIVE runner and attach it to the GitHub Release. Native builds
3+
# (not cross-compile) keep the embedded zwasm JIT's arch-specific codegen honest.
4+
#
5+
# TRIGGER: a maintainer pushing a `v*` tag (a deliberate human act — the
6+
# autonomous loop never tags or releases; build.zig.zon .version is the SSOT),
7+
# or manual dispatch. PREPARED-not-fired: this workflow only runs on such a tag.
8+
#
9+
# NOTE (first-tag validation): the artifact build uses
10+
# `-Dwasm -Doptimize=ReleaseSafe -Dcpu=baseline` (baseline CPU avoids SIGILL on
11+
# shared/older hosts, the shipped/deploy config). Validate each artifact runs
12+
# (`cljw --version` reports `(ReleaseSafe)`) on the first real release.
13+
14+
name: release
15+
16+
on:
17+
push:
18+
tags: ['v*']
19+
workflow_dispatch:
20+
21+
permissions:
22+
contents: write
23+
24+
concurrency:
25+
group: release-${{ github.ref }}
26+
cancel-in-progress: false
27+
28+
jobs:
29+
build:
30+
name: build (${{ matrix.name }})
31+
runs-on: ${{ matrix.runs-on }}
32+
timeout-minutes: 60
33+
strategy:
34+
fail-fast: true
35+
matrix:
36+
include:
37+
- name: macos-aarch64
38+
runs-on: macos-15
39+
zig-dir: zig-aarch64-macos-0.16.0
40+
artifact: cljw-macos-aarch64
41+
- name: linux-x86_64
42+
runs-on: ubuntu-22.04
43+
zig-dir: zig-x86_64-linux-0.16.0
44+
artifact: cljw-linux-x86_64
45+
steps:
46+
- name: Checkout
47+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
48+
49+
- name: Install Zig 0.16.0
50+
shell: bash
51+
run: |
52+
set -euo pipefail
53+
source .github/versions.lock
54+
mkdir -p ~/.local
55+
curl -fsSL "https://ziglang.org/download/${ZIG_VERSION}/${{ matrix.zig-dir }}.tar.xz" -o /tmp/zig.tar.xz
56+
tar -xJf /tmp/zig.tar.xz -C ~/.local
57+
echo "$HOME/.local/${{ matrix.zig-dir }}" >> "$GITHUB_PATH"
58+
59+
- name: Build cljw (ReleaseSafe, Wasm-enabled, baseline CPU)
60+
shell: bash
61+
run: |
62+
set -euo pipefail
63+
zig build -Dwasm -Doptimize=ReleaseSafe -Dcpu=baseline
64+
zig-out/bin/cljw --version
65+
mkdir -p dist
66+
tar -C zig-out/bin -czf "dist/${{ matrix.artifact }}.tar.gz" cljw
67+
( cd dist && shasum -a 256 "${{ matrix.artifact }}.tar.gz" > "${{ matrix.artifact }}.tar.gz.sha256" )
68+
69+
- name: Attach to GitHub Release
70+
if: startsWith(github.ref, 'refs/tags/')
71+
env:
72+
GH_TOKEN: ${{ github.token }}
73+
TAG_NAME: ${{ github.ref_name }}
74+
shell: bash
75+
run: |
76+
set -euo pipefail
77+
# Create the release once (idempotent — later matrix legs just upload).
78+
gh release view "$TAG_NAME" >/dev/null 2>&1 || \
79+
gh release create "$TAG_NAME" --title "$TAG_NAME" --generate-notes
80+
gh release upload "$TAG_NAME" dist/* --clobber

THIRD_PARTY.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ language lineage separately.
2121
Pinned to commit `9b4d67b9725e7137ac876cc628fe5dd2ca5a2681`
2222
(`ref=0.16.x`). Not part of the runtime; it participates in the gate only.
2323
Source: <https://github.com/kurtwagner/zlinter>.
24+
_Known pre-1.0 limitation_: `zlinter` exposes its builder through a top-level
25+
`@import("zlinter")` in `build.zig`, which the Zig build graph resolves
26+
**eagerly** — so even a plain `zig build` that never runs `lint` fetches it
27+
once. Making it lazy needs the dependency to expose a `b.lazyDependency`-able
28+
builder (upstream); until then this is an accepted development-time fetch, not
29+
a runtime dependency.
2430

2531
## Clojure language lineage (EPL, see NOTICE)
2632

0 commit comments

Comments
 (0)