From b8bfda02b4ed997ade4fdd68629af7157af96b88 Mon Sep 17 00:00:00 2001 From: Jim Cresswell Date: Thu, 18 Jun 2026 14:13:45 +0100 Subject: [PATCH] docs(release): record the continuous-release model and the CI-skip gotcha Closeout for PR #44 (continuous release on merge). Refresh continuity, the program memory, and the napkin to reflect that the release-PR pattern is retired in favour of the Oak Semantic Release Bot pushing the bump to protected main, and document the gotcha that bit #44's own merge: a feature commit or PR message that quotes the CI-skip marker in prose makes the squash-merge skip CI, so no release fires. Adds a dev-tooling note so template adopters avoid it. Merging this (with a clean message) is the first clean push to main since #44, so it should trigger the first continuous release (the computed minor, v0.4.0) and verify the bot's push to protected main. Co-Authored-By: Claude Opus 4.8 (1M context) --- .agent/memory/active/napkin.md | 36 ++++++++++++++++ .agent/memory/operational/repo-continuity.md | 43 +++++++++++++------- docs/dev-tooling.md | 5 +++ 3 files changed, 69 insertions(+), 15 deletions(-) diff --git a/.agent/memory/active/napkin.md b/.agent/memory/active/napkin.md index d23d50b..2cc7117 100644 --- a/.agent/memory/active/napkin.md +++ b/.agent/memory/active/napkin.md @@ -1,5 +1,41 @@ # Napkin +## Session: 2026-06-18 (final+) — continuous release on merge (PR #44) + +### What Was Done + +- Replaced the release-PR/`--auto` pattern with **continuous release on merge** + via the Oak Semantic Release Bot (app 2995796, ruleset bypass actor): trigger + on `workflow_run` after CI succeeds on main; `create-github-app-token`; compute + increment; `cz bump`; push bump+tag straight to protected main; publish Release. + Added `prevent_accidental_major` commit-msg hook (majors stay manual). Retired + #43 + `release/next`. + +### Surprises & corrections (critically assess — incl. sub-agents AND analysers) + +- **The literal CI-skip token in a feature commit/PR message skips CI on the + squash-merge.** My `feat` commit body *described* the loop-guard token in prose, + so #44's merge skipped CI → no `workflow_run` → no release; main stayed 0.3.0. + Keep the literal token out of feature messages. Documented in dev-tooling. +- **SonarCloud is a source to critically assess too.** It flagged `S8707` (argv + path → file read = path injection) on the commit-msg hook. Real impact is ~nil + (git supplies the path; 1-bit output), but fix-at-source beat suppression: + confined the path to the worktree-aware git dir with an `allowed_base` test + seam. Query Sonar via the MCP (`get_project_quality_gate_status` / + `search_sonar_issues_in_projects`, projectKey `oaknational_oak-python-starter`). +- **Critically rejected two reviewer findings** (premises wrong): pin checkout to + `workflow_run.head_sha` would make the bump push non-fast-forward under + concurrent merges (incompatible with direct-push); `create-github-app-token` + already defaults to current-repo scope, so it is not over-scoped. +- **`git add -A` swept untracked IDE dirs** (`.sonarlint/`, `.vscode/`) into the + commit — amended them out and gitignored them. Stage explicit paths. +- **ruff `--ignore-noqa` + B009 autofix:** a `getattr(x, "literal")` is rewritten + to `x.literal` (then pyright reportPrivateUsage fails). Use a *variable* attr + name: `name = "_fn"; getattr(x, name)`. +- The harness auto-mode classifier **blocks `gh workflow run Release -f + increment=...`** — agent-forced release version. Rely on the computed increment + from a real merge. + ## Session: 2026-06-18 (final) — program COMPLETE: F6 + Tier 3 + Tier 2 + deps + v0.3.0 ### What Was Done diff --git a/.agent/memory/operational/repo-continuity.md b/.agent/memory/operational/repo-continuity.md index 72de528..5ba9120 100644 --- a/.agent/memory/operational/repo-continuity.md +++ b/.agent/memory/operational/repo-continuity.md @@ -1,8 +1,19 @@ # Repo Continuity -**Last refreshed**: 2026-06-18 (final) — **the "highest proportionate bar" -program is COMPLETE; `v0.3.0` is cut** (tag + GitHub Release with wheel + sdist). -`main` is green. Landed this session: **F6** agent-hook hardening (#37, owner +**Last refreshed**: 2026-06-18 (final+) — the "highest proportionate bar" program +is COMPLETE (`v0.3.0` cut). **NEW: the release model is now CONTINUOUS release on +merge (PR #44)** — the release-PR/`--auto` pattern is retired. After CI passes on +`main`, the Oak Semantic Release Bot (app 2995796, a ruleset bypass actor) bumps + +tags + pushes to `main` and publishes the Release; every qualifying merge advances +the version. **Not yet live-verified:** PR #44's own merge skipped CI (its squash +message contained the literal CI-skip token in prose), so no release fired and +`main` is still `0.3.0`. The next clean merge (message free of the CI-skip token) +will cut the first continuous release (**v0.4.0**, the computed minor from #44's +feat) and verify the bot's push-to-protected-main. Do NOT force it via +`workflow_dispatch` — the harness blocks an agent-forced increment, and the owner +wants the computed one. + +(Earlier this session, pre-#44:) `main` is green. Landed: **F6** agent-hook hardening (#37, owner chose recurse-and-check), **Tier 3** branch coverage + floor 86 (#38), Hypothesis property tests (#39), single-version ADR-0002 (#40), **Tier 2** governance checklist `docs/repository-governance.md` (#41), **Dependabot** #29 (actions) + @@ -114,18 +125,20 @@ over-block). Full state in the ## Next Safe Step -- **The program is complete — no queued program work remains.** If resuming: - (1) the only outstanding items are **owner-only GitHub settings** in - `docs/repository-governance.md` (required status checks, release-PR token, Code - Quality preview, `v*` tag protection) — I cannot do these; (2) **F6 residuals** - (glued shell operators like `ok|git`, bare subshells `(...)`, and heredoc-prose - over-block) are documented and deferred to a future owner-authorised session — - fixing the glued-operator one needs a quote-aware raw tokeniser, a - safety-critical change; (3) **Tier 4** (SBOM, SLSA, Scorecard, mutation testing) - stays deferred unless the owner asks. Steady-state: a new `chore(release)` PR - will accrue future feat/fix — merge it with `gh pr merge --squash --auto` - (bot PR sits UNSTABLE; `code_quality` is the only required check). Normal PRs - merge with `gh pr merge --squash --delete-branch` once green. +- **Verify the first continuous release.** When this closeout PR (or any clean + merge) lands, watch the `Release` `workflow_run` run: it should bump to + **v0.4.0**, push the bump commit + tag to `main`, and publish the Release. If + it fails, the likely cause is the bot app lacking `Contents: write` (the one + unverified prerequisite) — main stays intact; fix the app perms and re-merge. +- **Remaining work otherwise:** (1) **owner-only GitHub settings** in + `docs/repository-governance.md` (required status checks, Code Quality preview, + `v*` tag protection — the release-bot secrets + bypass actor are already set); + (2) **F6 residuals** (glued shell operators like `ok|git`, bare subshells, and + heredoc-prose over-block) — deferred, the glued-operator one needs a quote-aware + raw tokeniser; (3) **PyPI publishing guide** for template adopters (owner asked; + docs-only, deferred — see Open Side-Tasks); (4) **Tier 4** stays deferred. + Normal PRs merge with `gh pr merge --squash --delete-branch` once green — + keep the literal CI-skip token out of the message or the release won't fire. ## Open Side-Tasks diff --git a/docs/dev-tooling.md b/docs/dev-tooling.md index fcd4f44..a5c5d94 100644 --- a/docs/dev-tooling.md +++ b/docs/dev-tooling.md @@ -210,6 +210,11 @@ uv run cz check --message "docs: explain the Commitizen workflow" - the version stays committed in the tree; releases publish to GitHub Releases only (no PyPI). `audit_release_workflow` keeps the workflow (trigger, `cz bump`, the increment tool, the `[skip ci]` loop guard) and the bump policy honest +- **gotcha:** because the loop guard relies on GitHub's CI-skip marker, a feature + commit or PR title/body that contains that literal marker in prose will make a + squash-merge skip CI too — so no `workflow_run` fires and no release is cut. + Keep the literal marker out of feature commit/PR messages; only the bump commit + should carry it ## Hydration guidance