Repository navigation
meta: round 2 — pristine rust-pypi-app template (resolve every #6 follow-up against template-python-rust-cmd) #52
Description
Goal: run the #6 loop again. Use
zackees/template-python-rust-cmdto produce a pristinerust-pypi-apptemplate, with every follow-up from round 1 resolved in it and proven by run evidence, and evolve the fleet policy andci_lintfrom what works.Previous loop: #6, closed. Its evidence is in
docs/case-studies/template-python-rust-cmd.md. Every open follow-up is attached below as a sub-issue.
Where we start (measured 2026-09-29)
- Green, protected template. Template
mainis green,CI OKis required, and the repo is marked as a GitHub template. - Fast lanes. Precheck takes 5–8 s. The Dylint lane is 49 s on a new commit, after setup-soldr v0.9.81/v0.9.82.
- Working release dry-run. The Linux wheel's glibc requirement measures 2.16; the OIDC mock publish passes.
- Cache waste. 1.58 GB in 29 entries, of which ~550 MB (~35%) is waste nothing cleans up: the janitor only runs nightly, the nightly has never run, and cache keys carry no
pr-<N>. See template#40. - Violations the template carries:
- wheels built with
uv build, notsoldr wheel(policy(rust-pypi): build wheels withsoldr wheel(abi3-py310); ban maturin CLI and zig (--zig, maturin[zig], ziglang, cargo-zigbuild) in CI #17); - an exact
soldr==0.9.25pin (policy(rust): avoid pinning soldr — float by default (soldr>=floor, setup-soldr@v0), exact pins only as recorded exceptions #18); - the old
ci-precheck.ymlshape (ci-pre.yml: rename from ci-precheck, job-level concurrency (janitor only), cache janitor on every push, PR-numbered cache keys #23); - the
ci.shexception (template#15).
- wheels built with
Definition of pristine
The template passes ci_lint precheck with zero exceptions and zero needs_review. It follows every open policy decision (#16–#19, #23, #30, #50). Every sub-issue below is closed with merged PRs and run IDs. Its cache stays steady under the budget: superseded, retired and closed-PR entries are deleted on the push that creates them. The example ci.toml shows 0 policy drift.
Work, in order
Phase 1: policy decisions become ci-lint rules (zackees/ci.yml)
- ci-pre.yml: rename from ci-precheck, job-level concurrency (janitor only), cache janitor on every push, PR-numbered cache keys #23 / ci-lint: implement ci.yml#23 rules (ci-pre.yml name, janitor concurrency, pr-<N> keys, install-free) #51:
ci-pre.ymlrename, a janitor on every push with a job-level concurrency group,pr-<N>keys, no installs - policy(python): never plain
uv runin CI steps of a repo with a [build-system] — it silently rebuilds the package per step #16 / policy+ci-lint: ban plainuv runin Rust apps/libs — require --no-project (or --no-sync / --script) #50: ban plainuv runin Rust repos - policy(rust-pypi): build wheels with
soldr wheel(abi3-py310); ban maturin CLI and zig (--zig, maturin[zig], ziglang, cargo-zigbuild) in CI #17:soldr wheelonly, no maturin CLI and no zig - policy(rust): avoid pinning soldr — float by default (soldr>=floor, setup-soldr@v0), exact pins only as recorded exceptions #18: float soldr by default; exact pins only as recorded exceptions
- policy(rust-pypi): release Linux wheels are manylinux_2_17, enforced by soldr wheel --release and verified — never the host's glibc floor #19: release Linux wheels are
manylinux_2_17 - rule: require CARGO_BUILD_JOBS / SOLDR_JOBS to be unset in workflows #30:
CARGO_BUILD_JOBS/SOLDR_JOBSmust be unset - Cross-compiled CI: job and runner names must show where it builds and where it runs #12: cross-compiled job names show where a lane builds and where it runs
- policy(cache): detect kill-switched layers and green default-branch runs that save nothing (fleet-wide) #7: detect kill-switched cache layers, and green runs that save nothing
- policy(rust): enforce cached cross-platform Dylint and make it a setup-soldr default for every Rust app #9: cached cross-platform Dylint as a setup-soldr default
- release gate: lessons from the mimalloc-pprof v1.0.1 exact-SHA release pilot (4 latent publisher bugs) #8: release-gate lessons from mimalloc-pprof
- Implement the remaining candidate rules in ci-lint #44: the remaining candidate rules
Phase 2: make the template pristine (zackees/template-python-rust-cmd)
- template#40: adopt
ci-pre.yml, reclaim the ~550 MB - template#37:
soldr wheel - template#38: float soldr
- template#39:
soldr wheel --releasefor manylinux_2_17 (soldr#3432 is closed, so this is unblocked) - template#15: replace
ci.sh, removing the last exception - template#13: ban
unwrapby default
Phase 3: prove what round 1 couldn't
- verify: scheduled nightly flow has never run on template-python-rust-cmd #45: a scheduled nightly run
- verify: [ci-windows]/[ci-macos]/[ci-linux] group tags and [ci-perf][no-test] on real runs #46: group tags, and
[ci-perf][no-test] - verify: Dylint lane under bosn → act locally (#6 D7) #47: the Dylint lane under bosn → act
- investigate: does dylint-driver compile through zccache? (#6 D8) #48: does
dylint-drivercompile through zccache? - fixture: restored read-only Dylint output tree (#1 acceptance) #49: a fixture for a read-only restored tree
- Re-probe preserve-source-mtimes on a leaf-crate edit #41:
preserve-source-mtimeson a leaf-crate edit - Guidance: [cache.pr].max-per-pr sizing for large repos (clud-scale) #42:
max-per-prsizing at clud scale - musllinux wheels for rust-pypi-app #43: musllinux wheels
Phase 4: upstream blockers
- setup-soldr#543: the build-cache save gate skips after a large compile
- soldr#3433: the
WHEELGenerator:doesn't name soldr - soldr#3444: sdist → wheel fails with
bundle-bins - soldr-toolchain#191: the Rust 1.95 bucket has no Dylint driver
- setup-soldr: promote v0 floating tag to v0.9.82 (needs FastLED/fbuild canary) #40: promote setup-soldr's
v0tag (needs the fbuild canary)
Phase 5: fleet rollout (after the template is pristine)
- Sweep: bump setup-soldr past v0.9.81 fleet-wide so Dylint caches save (RUST-004) #31 / Fleet repos not on setup-soldr@v0 miss critical fixes: add a periodic sweep or a scoped exception to SHA pinning #33: bump setup-soldr fleet-wide and handle SHA pinning
- kernal-api phase 2: private-crate/units + cache model #37: kernal-api phase 2
- fbuild coverage-preservation fixture #39: the fbuild coverage fixture
- Fleet rollout: ci.toml adoption, central scanner, sync-issues, fleet inventory #38: fleet rollout, central scanner and
sync-issues
How we iterate
Same loop as #6:
- Roles. The main agent writes the round briefs, and Sonnet workers implement them under the worker contract.
- Evidence. Every guard is proven RED → GREEN, and every claim cites a run ID.
- Merging. ci.yml PRs merge once selftest passes with and without PyYAML; template PRs merge when
CI OKis green. - Lessons. Each round's lessons are appended to the case study.
- Drift. The example
ci.tomland the template's stay in sync, with 0 policy drift.
Activity
uv runin CI steps of a repo with a [build-system] — it silently rebuilds the package per step #16uv runin Rust apps/libs — require --no-project (or --no-sync / --script) #50soldr wheel(abi3-py310); ban maturin CLI and zig (--zig, maturin[zig], ziglang, cargo-zigbuild) in CI #17soldr wheelinstead ofuv build(ci.yml#17) template-python-rust-cmd#3739 remaining items
zackees commentedon Sep 29, 2026
Round 2 wrap-up (2026-09-29)
51/67 sub-issues closed (76%). The session is ending. The remaining items stay open, each with its own status comment.
In flight at wrap-up
is_templateflag, cleared with owner approval. A temporary */15 cron is being used to capture a scheduled run and will then be reverted (template PR feat(ci-lint): PKG-007 -- release Linux wheel manylinux_2_17 floor (ci.yml#19) #58 plus a revert PR).soldr wheelignores bundle-bins). The fix is in progress; after it, soldr v0.9.27.Blocked on owner
--apply(feat(ci-lint): sync-issues --apply write path (ci.yml#98, M2-42) #129): choose the first repo to opt in live.Remaining work
uv runin Rust apps/libs — require --no-project (or --no-sync / --script) #50 (pristine precheck; after kernal-api phase 2: private-crate/units + cache model #37/fbuild coverage-preservation fixture #39, and check the new live CACHE-004 findings from feat(ci-lint): live CACHE-004 reports family entries beyond declared per/max (ci.yml#139, M2-45) #146), release: reuse frozen release-candidate bytes on resume (REL-004 automation) #109 (REL-004 reuse automation), policy(rust-pypi): build wheels withsoldr wheel(abi3-py310); ban maturin CLI and zig (--zig, maturin[zig], ziglang, cargo-zigbuild) in CI #17 (maturin/zig ban; after kernal-api phase 2: private-crate/units + cache model #37).Next phase (not tracked in #52): #110 Dylint cache (deps-only plus checksum freshness; PRs must hit), #111 unified lint lane, #112 per-platform sharding, #120 third-party-hash cook cache.
docs(fleet): the cache-policy rollout, recorded (#349)