From 8791ca7efe3be2e6e035c3771310e0d0a3f4b146 Mon Sep 17 00:00:00 2001 From: Jeff Huber Date: Wed, 2 Sep 2026 10:20:51 -0700 Subject: [PATCH] docs: align v0.8 adoption release guidance --- docs/build-loop.md | 8 ++++-- docs/cloud-benchmarking.md | 18 ++++++------ docs/current-state-and-roadmap.md | 11 +++---- docs/early-adopter-invite-runbook.md | 8 ++++-- docs/early-adopter-v05.md | 31 ++++++++++++-------- docs/friendly-user-rollout-v05.md | 17 +++++++---- docs/pypi-release.md | 12 ++++---- docs/v08-release-notes.md | 2 +- tests/test_release_hygiene.py | 43 +++++++++++++++++++++++----- 9 files changed, 101 insertions(+), 49 deletions(-) diff --git a/docs/build-loop.md b/docs/build-loop.md index 5336a0c5..bd9a46b1 100644 --- a/docs/build-loop.md +++ b/docs/build-loop.md @@ -132,7 +132,8 @@ and the next action. It is read-only and metadata-only. Local cwd paths are redacted by default; pass `--show-local-paths` only when you are debugging locally. -Use `lanes status` as the pasteable visibility surface during v0.7 adoption. +Use `lanes status` as the pasteable visibility surface during v0.8 adoption and +later. Use `board serve` when you want the same state in a local browser. The board is read-only, serves on loopback by default, and does not require a separate observer setup. @@ -151,8 +152,9 @@ Minimum token permissions: - Issues: read/write - Pull requests: read/write -Set `DISPATCH_TOKEN_EXPIRES_AT` as a repository variable in `YYYY-MM-DD` format -so `code-mower doctor --github` can report expiry posture. +Set `DISPATCH_TOKEN_EXPIRES_AT` as a repository variable in `YYYY-MM-DD` format, +or `never` for a non-expiring token, so `code-mower doctor --github` can report +expiry posture. ## Rehearsal diff --git a/docs/cloud-benchmarking.md b/docs/cloud-benchmarking.md index ecc8c14e..e6cf8269 100644 --- a/docs/cloud-benchmarking.md +++ b/docs/cloud-benchmarking.md @@ -29,20 +29,22 @@ observability/evaluation backend. ## Release Stages -### v0.6: Early-Adopter Upload Beta +### Current Beta: Metadata-Only Upload And Board Mirror -The current beta path keeps cloud sharing opt-in for early adopters who -explicitly want to share sanitized benchmark metadata with Code Mower Cloud. -The OSS tool is still local-first: +The current v0.8 beta keeps cloud sharing opt-in for early adopters who +explicitly want to share sanitized benchmark metadata or a summarized Board +mirror with Code Mower Cloud. The OSS tool is still local-first: ```bash code-mower cloud upload .code-mower/cloud-benchmark-bundle --dry-run --json code-mower cloud upload .code-mower/cloud-benchmark-bundle --yes --json +code-mower cloud dogfood --json +code-mower cloud board-snapshot --repo-slug OWNER/REPO --json ``` Dry run is the first-class experience. A network upload only happens when the caller passes `--yes`, and the default payload is metadata-only. Rich report -text requires `--include-reports`. +text requires `--include-reports`; Board snapshot uploads contain zero reports. ### v1.0: Local-First, Cloud-Ready @@ -78,10 +80,10 @@ Reports and future bundle extensions should use the cloud vocabulary: The current v1.0 manifest remains intentionally small. Do not document a field as part of the manifest until the exporter emits it and tests cover it. -### v1.1: Opt-In Upload Beta +### v1.1: Broader Opt-In Upload -Promote upload beyond alpha only after the bundle schema and hosted ingestion -path have real early-adopter mileage: +Promote upload beyond friendly-user beta only after the bundle schema, Board +snapshot event, and hosted ingestion path have real early-adopter mileage: ```bash open https://codemower.com/login diff --git a/docs/current-state-and-roadmap.md b/docs/current-state-and-roadmap.md index e306917c..c7b631f4 100644 --- a/docs/current-state-and-roadmap.md +++ b/docs/current-state-and-roadmap.md @@ -121,11 +121,12 @@ The beta line has proved: - a friendly-user rollout plan that turns install, doctor, first report, optional cloud dry-run/upload, and dashboard usefulness into explicit acceptance criteria for the first 5-10 users; and -- a public PyPI package-install rehearsal from beta.52 - `code-mower==0.5.0b52` with a +- the current public PyPI package-install rehearsal from `v0.8.0-beta.1` / + `code-mower==0.8.0b1` with a 10/10 first-user readiness score, proving install, generated setup, doctor, draft calibration, value-report, cloud export, and dry-run dogfood without a - local Code Mower checkout; and + local Code Mower checkout. The earlier beta.52 package rehearsal remains + historical evidence, not the current adoption proof; and - stable CodeMower.com evidence URLs for signed-in users, with per-upload and per-event detail pages plus token-safe JSON export links for support, debugging, and dashboard trust checks; and @@ -257,8 +258,8 @@ operator-issued developer/team token when they opt into cloud sharing. ## Current Early-Adopter Goal -The next beta should be shareable with 20-50 early OSS users who can follow a -guide without knowing the original reference repos. +The current v0.8 beta is the shareable package line for 20-50 early OSS users +who can follow a guide without knowing the original reference repos. The early-adopter experience should be: diff --git a/docs/early-adopter-invite-runbook.md b/docs/early-adopter-invite-runbook.md index c2907324..871b2e6a 100644 --- a/docs/early-adopter-invite-runbook.md +++ b/docs/early-adopter-invite-runbook.md @@ -9,7 +9,7 @@ The first invite cohort should prove that a new user can get value without knowing the history of the reference repos: 1. install Code Mower from the tagged beta; -2. run `init --easy` and the preflight doctor preset; +2. run `init --easy` and the repository-targeted adoption doctor preset; 3. generate the starter calibration/value report; 4. optionally connect a CodeMower.com team token; and 5. upload sanitized metadata after reviewing the local bundle. @@ -51,7 +51,9 @@ Before inviting a user: 1. Verify the tagged install command in a fresh repo: ```bash - pipx install --python python3.12 code-mower==0.8.0b1 + python3.12 --version + export CODE_MOWER_PYTHON="$(command -v python3.12)" + pipx install --python "$CODE_MOWER_PYTHON" code-mower==0.8.0b1 code-mower --version ``` @@ -74,7 +76,7 @@ Before inviting a user: The user is successful when they can send back: - `code-mower --version` output; -- `code-mower doctor --preflight --json` status; +- `code-mower doctor --adoption --repo OWNER/REPO --json` status; - the generated `reviewer-value-report.md`; and - if they opted into cloud, the upload ID from `code-mower cloud upload --yes --json`. diff --git a/docs/early-adopter-v05.md b/docs/early-adopter-v05.md index 534dfb21..5ed66c43 100644 --- a/docs/early-adopter-v05.md +++ b/docs/early-adopter-v05.md @@ -1,15 +1,21 @@ -# Code Mower v0.5 Early Adopter Guide +# Code Mower Early Adopter Guide -The v0.5 goal is to make Code Mower useful for 20-50 early OSS users without -requiring them to understand every provider or lane. +This document records the historical v0.5 early-adopter product plan. The +current public install path is the v0.8 package beta; use +[Install And Bootstrap](install.md), [Try Code Mower In 10 Minutes](try-in-10-minutes.md), +and [Quickstart](quickstart.md) for live adoption steps. + +The original v0.5 goal was to make Code Mower useful for 20-50 early OSS users +without requiring them to understand every provider or lane. ## Two Setup Personas Code Mower has two setup paths, and v0.5 docs should keep them separate. **Code Mower OSS user setup** is the early-adopter path. A user installs Code -Mower, runs `code-mower init --easy`, runs `code-mower doctor --preflight`, -runs a local audit or value report, and optionally pastes a CodeMower.com +Mower, runs `code-mower init --easy`, runs +`code-mower doctor --adoption --repo OWNER/REPO`, runs a local audit or value +report, and optionally pastes a CodeMower.com developer/team token into `code-mower cloud setup --token-stdin`. OSS users do not configure Supabase, Vercel, OAuth apps, DNS, service-role keys, database migrations, or hosted secrets. @@ -36,13 +42,14 @@ The one-command first-run diagnostic is: code-mower doctor --v05 --json ``` -For friendlier user-facing docs, prefer the equivalent alias: +For current user-facing docs, prefer the repository-targeted adoption preset: ```bash -code-mower doctor --preflight --json +code-mower doctor --adoption --repo OWNER/REPO --json ``` -Both expand to `--easy --profile recommended --probe-runtime --github --cloud`. +`doctor --preflight` and `doctor --v05` remain compatibility aliases for +scripts and older runbooks. ## Recommended First-Run Profile @@ -82,8 +89,8 @@ Before inviting users: migration, or hosted-secret setup. - CodeMower.com operator docs clearly own hosted setup, token administration, and production secrets. -- `code-mower doctor --preflight --json` works as the recommended early-adopter - preset. +- `code-mower doctor --adoption --repo OWNER/REPO --json` works as the + recommended early-adopter preset. - `code-mower cloud upload --dry-run` previews without network transfer. - `code-mower cloud doctor --probe-service` verifies CodeMower.com health and returns dashboard/setup guidance without echoing tokens. @@ -152,8 +159,8 @@ dogfood. The current beta also carries the provider-contract hardening queue, the `code-mower lanes status` operator snapshot, Antigravity/Gemini lane separation, builder-experiment metadata capture, and the hosted Cursor lane id as `cursor` while accepting legacy `grok-bot` inputs during the migration -window. The beta.52 dogfood follow-up keeps owner-bound work out of lane WIP, -adds lane-liveness and fix-round template support, makes human-token posture +window. Later v0.5 beta dogfood follow-ups keep owner-bound work out of lane WIP, +add lane-liveness and fix-round template support, make human-token posture first-class in setup/doctor, separates owner-decision escalation from raw owner notifications, and teaches provider-integration prompts to avoid ambiguous sandbox/live shared namespaces. Earlier alpha hardening also keeps the package diff --git a/docs/friendly-user-rollout-v05.md b/docs/friendly-user-rollout-v05.md index c3b4430d..218d64d2 100644 --- a/docs/friendly-user-rollout-v05.md +++ b/docs/friendly-user-rollout-v05.md @@ -3,6 +3,9 @@ This is the operating plan for the first 5-10 friendly users before Code Mower widens to 20-50 early adopters. +The filename is historical from the v0.5 planning pass. The live baseline in +this document is the current v0.8 package beta. + Code Mower is beta, bring-your-own-agent-loop software for teams willing to calibrate reviewers. It is not a drop-in autonomous merge gate. @@ -23,7 +26,9 @@ Use the current beta install pin unless a newer release is explicitly called out in the invite: ```bash -pipx install --python python3.12 code-mower==0.8.0b1 +python3.12 --version +export CODE_MOWER_PYTHON="$(command -v python3.12)" +pipx install --python "$CODE_MOWER_PYTHON" code-mower==0.8.0b1 ``` The current package-index beta baseline is `v0.8.0-beta.1`, with pinned package install spec `code-mower==0.8.0b1`. Release evidence is recorded on the GitHub release and in the first-user install rehearsal. @@ -33,7 +38,8 @@ The current package-index beta baseline is `v0.8.0-beta.1`, with pinned package Start with users who have: - a GitHub repository they can safely run diagnostics against; -- Python 3.12 available through Homebrew, pyenv, or system package manager; +- Python 3.12 available through Homebrew, pyenv, uv, or a system package + manager; - willingness to run a local-first tool before enabling any cloud upload; and - patience to report rough edges in install, doctor, or first report output. @@ -46,8 +52,9 @@ Ask each user to run: ```bash code-mower init --easy -code-mower doctor --preflight --json +code-mower doctor --adoption --repo OWNER/REPO --json code-mower lanes status --repo OWNER/REPO +code-mower board serve --repo OWNER/REPO code-mower next-steps --profile recommended ``` @@ -99,9 +106,9 @@ For each friendly user, capture: Do not collect source code, raw diffs, raw model transcripts, auth output, or secrets. -## Exit Criteria For v0.6 +## Exit Criteria For Wider Beta -The friendly-user loop is good enough for a wider v0.6 push when: +The friendly-user loop is good enough for a wider v0.8/v1.0 push when: - at least 5 fresh users complete install, doctor, and first report; - at least 3 private repositories complete package-install rehearsal or diff --git a/docs/pypi-release.md b/docs/pypi-release.md index f2c12772..5595a90b 100644 --- a/docs/pypi-release.md +++ b/docs/pypi-release.md @@ -67,7 +67,7 @@ for manual release rehearsals: | --- | --- | --- | | `false` | `false` | Build, upload, download, and verify distributions only. | | `true` | `false` | Build, verify, then publish to TestPyPI using the `testpypi` environment. | -| `false` | `true` | Build, verify, then publish to production PyPI using the `pypi` environment. Use only after TestPyPI passes. | +| `false` | `true` | Build, verify, then publish to production PyPI using the `pypi` environment. Use only after the no-publish verification run is green; run TestPyPI first for trusted-publishing setup changes or risky packaging changes. | | `true` | `true` | Avoid this for normal releases; publish to TestPyPI and PyPI as separate, auditable runs. | Manual dispatch inputs are the only publish controls for manual runs. Repository @@ -94,7 +94,7 @@ gh api repos/codemower-ai/code-mower/releases/latest \ `DEC-427-LATEST` records the 2026-08-23 owner decision in [PR #427](https://github.com/codemower-ai/code-mower/pull/427#issuecomment-5388373205): -beta.52 (and future newest betas until 1.0) are published as **regular +beta.52 established that future newest betas until 1.0 are published as **regular releases** (prerelease flag off), not prerelease-flagged releases, so GitHub's `/releases/latest` endpoint resolves for early adopters, automation, and package-index release checks. A prerelease-flagged release cannot be returned by @@ -121,9 +121,11 @@ project pages, and trusted-publishing setup pages: - [TestPyPI trusted publishers](https://test.pypi.org/manage/project/code-mower/settings/publishing/) - [PyPI trusted publishers](https://pypi.org/manage/project/code-mower/settings/publishing/) -Before publishing to TestPyPI, run the release workflow once with both publish -inputs set to `false` and confirm `build-distributions` and -`verify-distributions` are green. +Before publishing to TestPyPI or PyPI, run the release workflow once with both +publish inputs set to `false` and confirm `build-distributions` and +`verify-distributions` are green. TestPyPI remains useful for first-time +trusted-publishing setup or risky packaging changes; routine beta publishing +can go from the green no-publish verification run to production PyPI. ## Cache Bypass And Propagation Triage diff --git a/docs/v08-release-notes.md b/docs/v08-release-notes.md index a2c9cc2e..f3dc4820 100644 --- a/docs/v08-release-notes.md +++ b/docs/v08-release-notes.md @@ -9,7 +9,7 @@ Install the pinned beta with Code Mower v0.8 is a better first install for supervised multi-agent adoption: clearer Python/install expectations, less noisy doctor output for hosted builders, a one-command lane status snapshot, and a native local Board for -operator visibility without AgentTrail or hook setup. +operator visibility without third-party hook setup. ## What's New diff --git a/tests/test_release_hygiene.py b/tests/test_release_hygiene.py index f0697bbf..9762d3e5 100644 --- a/tests/test_release_hygiene.py +++ b/tests/test_release_hygiene.py @@ -207,7 +207,7 @@ def test_pypi_runbook_publishes_newest_beta_as_regular_release(self) -> None: runbook, ) self.assertIn( - "beta.52 (and future newest betas until 1.0) are published as " + "beta.52 established that future newest betas until 1.0 are published as " "**regular releases** (prerelease flag off)", rendered_text, ) @@ -7156,10 +7156,7 @@ def test_public_release_baseline_helpers_derive_announcement_links(self) -> None def test_public_announcement_docs_use_current_release_helpers(self) -> None: baseline_sentence = code_mower_versioning.public_baseline_sentence(__version__) - install_command = ( - "pipx install --python python3.12 " - f"{code_mower_versioning.public_package_spec(__version__)}" - ) + package_spec = code_mower_versioning.public_package_spec(__version__) announcement_url = code_mower_versioning.tagged_doc_url(__version__) current_state = (ROOT / "docs/current-state-and-roadmap.md").read_text( @@ -7173,7 +7170,9 @@ def test_public_announcement_docs_use_current_release_helpers(self) -> None: self.assertIn(normalized_baseline, " ".join(current_state.split())) self.assertIn(normalized_baseline, " ".join(rollout.split())) - self.assertIn(install_command, rollout) + self.assertIn(package_spec, rollout) + self.assertIn('export CODE_MOWER_PYTHON="$(command -v python3.12)"', rollout) + self.assertIn('pipx install --python "$CODE_MOWER_PYTHON"', rollout) self.assertIn(announcement_url, readme) def test_public_docs_have_no_stale_beta_baselines(self) -> None: @@ -7605,6 +7604,36 @@ def test_primary_adoption_docs_do_not_claim_python_311_support(self) -> None: for pattern in stale_patterns: self.assertNotIn(pattern, text) + def test_active_docs_use_current_beta_release_language(self) -> None: + active_docs = { + "docs/build-loop.md": ROOT / "docs" / "build-loop.md", + "docs/cloud-benchmarking.md": ROOT / "docs" / "cloud-benchmarking.md", + "docs/current-state-and-roadmap.md": ROOT / "docs" / "current-state-and-roadmap.md", + "docs/early-adopter-invite-runbook.md": ROOT + / "docs" + / "early-adopter-invite-runbook.md", + "docs/friendly-user-rollout-v05.md": ROOT / "docs" / "friendly-user-rollout-v05.md", + "docs/pypi-release.md": ROOT / "docs" / "pypi-release.md", + "docs/v08-release-notes.md": ROOT / "docs" / "v08-release-notes.md", + } + stale_phrases = ( + "Use only after TestPyPI passes.", + "beta.52 (and future newest betas until 1.0)", + "during v0.7 adoption", + "Exit Criteria For v0.6", + "wider v0.6 push", + "without AgentTrail or hook setup", + "doctor --preflight --json` status", + "preflight doctor preset", + ) + + for label, path in active_docs.items(): + text = path.read_text(encoding="utf-8") + with self.subTest(path=label): + self.assertIn("0.8", text) + for phrase in stale_phrases: + self.assertNotIn(phrase, text) + def test_orchestrator_prompt_pack_preserves_adoption_guardrails(self) -> None: readme = (ROOT / "README.md").read_text(encoding="utf-8") quickstart = (ROOT / "docs" / "quickstart.md").read_text(encoding="utf-8") @@ -7628,7 +7657,7 @@ def test_orchestrator_prompt_pack_preserves_adoption_guardrails(self) -> None: self.assertIn("metadata-only", prompt_pack) self.assertIn("Do not upload source, raw diffs, transcripts", prompt_pack) - def test_v06_adoption_polish_docs_cover_cold_start_surface(self) -> None: + def test_v08_adoption_polish_docs_cover_cold_start_surface(self) -> None: readme = (ROOT / "README.md").read_text(encoding="utf-8") quickstart = (ROOT / "docs" / "quickstart.md").read_text(encoding="utf-8") troubleshooting = (ROOT / "docs" / "troubleshooting.md").read_text(