From 40a35ac877db34bcf49b17a0083bbcd19757a813 Mon Sep 17 00:00:00 2001 From: Jeff Huber Date: Fri, 11 Sep 2026 16:43:01 -0700 Subject: [PATCH] release: prepare v1.3.0 optional Coworker context CODE_MOWER_BUILDER:codex --- CHANGELOG.md | 27 +++++ README.md | 17 ++- docs/build-loop-in-30-minutes.md | 2 +- docs/cloud-benchmarking.md | 6 +- docs/context-provider-contract.md | 19 ++-- docs/current-state-and-roadmap.md | 19 ++-- docs/early-adopter-invite-runbook.md | 4 +- docs/early-adopter-v05.md | 4 +- docs/first-run-transcript.md | 4 +- docs/first-user-demo-transcript.md | 6 +- docs/first-user-install-rehearsal.md | 26 ++--- docs/friendly-user-rollout-v05.md | 6 +- docs/install.md | 16 +-- docs/jira-cloud-setup.md | 2 +- docs/mirror-removal-runbook.md | 2 +- docs/oss-v1-checklist.md | 8 +- docs/package-customization.md | 2 +- docs/provider-matrix.md | 2 +- docs/public-release-checklist.md | 4 +- docs/pypi-release.md | 18 +-- docs/quickstart.md | 8 +- docs/sessions.md | 2 +- docs/troubleshooting.md | 4 +- docs/try-in-10-minutes.md | 8 +- docs/v130-context-qualification.md | 103 ++++++++++++++++++ docs/v130-release-notes.md | 77 +++++++++++++ pyproject.toml | 2 +- src/code_mower/__init__.py | 2 +- src/code_mower/package_manifest.py | 2 + .../workflows/builder-provenance.yml.j2 | 2 +- templates/workflows/builder-provenance.yml.j2 | 2 +- tests/test_release_hygiene.py | 94 ++++++++-------- 32 files changed, 360 insertions(+), 140 deletions(-) create mode 100644 docs/v130-context-qualification.md create mode 100644 docs/v130-release-notes.md diff --git a/CHANGELOG.md b/CHANGELOG.md index ec263d27..ef7ad848 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,33 @@ project used alpha/beta prerelease tags while the first-user setup path, provider posture, and optional cloud sharing loop were hardening; v1.0 and later entries are regular releases. +## v1.3.0 + +Code Mower can optionally give its Claude and Codex participants the same bounded, +cited organizational evidence through an explicitly selected Coworker account. +Default setup remains Claude + Codex without a context-provider dependency. + +### Added + +- Provider-neutral context policies, immutable packets, citations, scope/expiry + checks and a synthetic local-graph fixture for future adapters. +- Optional Coworker OAuth with signed account/workspace verification, OS vault + storage, online refresh before retrieval/replay, and local-first disconnect. +- Bounded read-only retrieval, private work-order and reviewer delivery, + context-revision-aware review validity, and private detailed review feedback. +- Optional init selection and shared redacted doctor/status/session readiness. + Explicit unavailable-input declarations distinguish optional outages from + required context; identity inspection is a local-terminal-only operation. +- A bounded two-case frozen-reference qualification with honest relevance and + productivity limits. Graphify remains a separately tracked v1.3.x candidate. + +### Fixed + +- Required-context changes are read from trusted repository configuration on each + gate run, so an older code-only review cannot survive a newly required input. +- Failed context attachment releases its local capacity; optional discovery + failures preserve ordinary no-context audit behavior. + ## v1.2.2 Code Mower v1.2.2 keeps Jira workflow state and Board current-state reporting diff --git a/README.md b/README.md index b6c1d875..f3ed6617 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ The short version: exposure, or GitHub Actions churn; - turn issue text, external docs, and project doctrine into local work orders before an agent starts coding; +- optionally give Claude and Codex the same authorized organizational evidence + through a private Coworker connection, with fresh review when context changes; - generate local reviewer value reports from known-clean and known-blocked PRs; and - optionally share sanitized metadata with [CodeMower.com](https://codemower.com) @@ -26,8 +28,8 @@ Default cloud bundles exclude source code, raw diffs, raw model transcripts, raw stdout/stderr, auth output, and secrets. Documentation on `main` follows the source on `main`. If you install the -published `code-mower==1.2.2` package, use the documentation from the matching -[`v1.2.2` tag](https://github.com/codemower-ai/code-mower/tree/v1.2.2) so the +published `code-mower==1.3.0` package, use the documentation from the matching +[`v1.3.0` tag](https://github.com/codemower-ai/code-mower/tree/v1.3.0) so the commands and package stay aligned as development continues. ## Design Principles @@ -222,7 +224,7 @@ agent report its actual host posture, exact installed version, doctor result, Board URL, and any owner-only click-list before it mutates the repo. The current package-index announcement entry point is the tagged -[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v1.2.2/docs/try-in-10-minutes.md) +[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v1.3.0/docs/try-in-10-minutes.md) guide. The v1.0 supervised-pilot release includes the native Board, the controller dry-run and policy contract, adoption and upgrade hardening from recent install rehearsals, package-index release checks, provider-diversity @@ -337,7 +339,7 @@ Provider-contract baseline for the next release train: For release verification, [First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records -the package-index procedure for `v1.2.2` / `code-mower==1.2.2`. The +the package-index procedure for `v1.3.0` / `code-mower==1.3.0`. The GitHub release records the workflow and rehearsal evidence for the exact tag. After publication, [Release Qualification](docs/release-qualification.md) coordinates provider-specific install and operational checks without treating @@ -531,8 +533,8 @@ measurement work. ## Installation Status -The current package-index release baseline is `v1.2.2`, with pinned package -install spec `code-mower==1.2.2`. Release evidence is recorded on the GitHub +The current package-index release baseline is `v1.3.0`, with pinned package +install spec `code-mower==1.3.0`. Release evidence is recorded on the GitHub release and in the first-user install rehearsal. The public repository is [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and GitHub releases remain the auditable source for tags, build artifacts, and @@ -647,6 +649,9 @@ first so local work exercises the same package entrypoint users install. - [v1.2 Release Notes](docs/v12-release-notes.md) - [v1.2.1 Release Notes](docs/v121-release-notes.md) - [v1.2.2 Release Notes](docs/v122-release-notes.md) +- [v1.3.0 Release Notes](docs/v130-release-notes.md) +- [Optional Coworker Setup](docs/context-setup.md) +- [Context Qualification and Limits](docs/v130-context-qualification.md) - [Post-v0.8 Effectiveness Assessment](docs/post-v08-effectiveness-assessment.md) - [v1.0.1 Effectiveness Assessment](docs/v101-effectiveness-assessment.md) diff --git a/docs/build-loop-in-30-minutes.md b/docs/build-loop-in-30-minutes.md index 17e6781b..f1b3c580 100644 --- a/docs/build-loop-in-30-minutes.md +++ b/docs/build-loop-in-30-minutes.md @@ -60,7 +60,7 @@ audit evidence, skip to section 2. ```bash python3.12 --version export CODE_MOWER_PYTHON="$(command -v python3.12)" -pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 +pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 gh auth status >/dev/null 2>&1 && echo "gh auth ok" || { echo "gh auth NOT ready"; false; } code-mower init --easy code-mower init --easy --apply --output-dir .code-mower.generated diff --git a/docs/cloud-benchmarking.md b/docs/cloud-benchmarking.md index 373e8544..ba1665dc 100644 --- a/docs/cloud-benchmarking.md +++ b/docs/cloud-benchmarking.md @@ -29,9 +29,9 @@ observability/evaluation backend. ## Release Stages -### Current v1.2.2: Metadata-Only Upload, Board, Productivity, And Qualification +### Current v1.3.0: Metadata-Only Upload, Board, Productivity, And Qualification -The current v1.2.2 line keeps cloud sharing opt-in for adopters who explicitly +The current v1.3.0 line keeps cloud sharing opt-in for adopters who explicitly want to share sanitized benchmark metadata, summarized Board mirrors, or aggregate productivity metrics with Code Mower Cloud. The OSS tool is still local-first: @@ -43,7 +43,7 @@ code-mower cloud upload .code-mower/cloud-benchmark-bundle --yes --json code-mower cloud dogfood --json code-mower cloud dogfood --event productivity_summary=productivity-summary.json --json code-mower cloud board-snapshot --repo-slug OWNER/REPO --json -code-mower release qualify --release-tag v1.2.2 --package-spec code-mower==1.2.2 --output adoption-result.json --execute +code-mower release qualify --release-tag v1.3.0 --package-spec code-mower==1.3.0 --output adoption-result.json --execute code-mower cloud export --event adoption_run=adoption-result.json --repo-slug OWNER/REPO --json ``` diff --git a/docs/context-provider-contract.md b/docs/context-provider-contract.md index 91d0131a..4efa49db 100644 --- a/docs/context-provider-contract.md +++ b/docs/context-provider-contract.md @@ -132,14 +132,15 @@ No dependency or credential implementation is introduced by this ADR. The local connection lifecycle and delivery implementations must enforce these rules; a synthetic fixture or structurally valid JSON is not authorization. -## Proposed commands +## Implemented commands -These are design targets, not commands available in v1.2.2: +The qualified connection and delivery path is available in v1.3.0. See the +[setup guide](context-setup.md) for installation and explicit account selection: ```text code-mower context connect coworker --connection example-context code-mower context doctor --connection example-context -code-mower context fetch --connection example-context --work-order PATH +code-mower context fetch --connection example-context --request-stdin --json code-mower context disconnect --connection example-context ``` @@ -158,8 +159,8 @@ use with HTTP 400; the SDK cleared the in-memory credentials. The old access token's earlier successful initialization after access-token revocation shows why offline JWT verification is insufficient for packet replay authorization. -C3 must force an online SDK refresh before every context retrieval or replay, -under a per-connection lock, and require a successful token response with a +The connection runtime forces an online SDK refresh before every context retrieval or replay, +under a per-connection lock, and requires a successful token response with a newly verified principal/workspace/client binding. A failed refresh invalidates the local generation and cached evidence. Do not fall back to the old token, a stored token file, another account, or another connection. A bare MCP GET @@ -171,12 +172,12 @@ remote revocation failures without restoring local access. An already-issued bearer token outside Code Mower may remain usable until its expiry; do not promise immediate global access-token revocation. Preserve other connections. -C3 must test local disconnect, concurrent refresh, generation changes, -wrong-account rejection, expiry, and unavailable refresh. C4 must retain the +The regression suite tests local disconnect, concurrent refresh, generation changes, +wrong-account rejection, expiry, and unavailable refresh. The retrieval adapter retains the observed partial status and citations under strict request/document/byte/time limits. Existing C2 tests cover structural scope/recipient rejection only; -they are not live provider authorization evidence. Complete the private pilot -and runtime qualification before a v1.3 release. Public artifacts contain no +they are not live provider authorization evidence. The [v1.3 qualification scorecard](v130-context-qualification.md) distinguishes +live delivery evidence from frozen reference assessment. Public artifacts contain no private account identities, source text, source IDs, or credentials. ## Later Graphify candidate diff --git a/docs/current-state-and-roadmap.md b/docs/current-state-and-roadmap.md index 0f552dcc..5f2b3abc 100644 --- a/docs/current-state-and-roadmap.md +++ b/docs/current-state-and-roadmap.md @@ -1,7 +1,7 @@ # Code Mower Current State And Roadmap This is the short source-of-truth snapshot for the public OSS package, the -hosted CodeMower.com surface, and the near-term path from the current v1.2.2 +hosted CodeMower.com surface, and the near-term path from the current v1.3.0 line toward broader supervised adoption. ## Positioning @@ -22,19 +22,24 @@ codebase, at what cost, and with which review policy. ## Current OSS State +Version 1.3 adds optional Coworker organizational context with explicit private +account selection, bounded cited packets and context-aware independent review. +The [qualification scorecard](v130-context-qualification.md) reports mixed retrieval +relevance without claiming productivity gains. Graphify remains a later candidate. + The public OSS repository is: ```text https://github.com/codemower-ai/code-mower ``` -The current package-index release baseline is `v1.2.2`, with pinned package -install spec `code-mower==1.2.2`. Release evidence is recorded on the GitHub +The current package-index release baseline is `v1.3.0`, with pinned package +install spec `code-mower==1.3.0`. Release evidence is recorded on the GitHub release and in the first-user install rehearsal. It is intended to be installed from the package index for supervised pilots, with GitHub tag/source installs kept as a fallback and development path. -The v1.2.2 supervised-pilot release keeps the Python 3.12+ runtime contract, +The v1.3.0 supervised-pilot release keeps the Python 3.12+ runtime contract, pipx/uv install matrix, non-expiring dispatch-token diagnostics, native redacted lane status, the local Board, Board history and admin commands, spend/verdict timelines, owner queue, optional metadata-only agent cards, explicit cloud Board @@ -144,8 +149,8 @@ The beta-to-v1.0 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 -- the current public PyPI package-install rehearsal from `v1.2.2` / - `code-mower==1.2.2` with a +- the current public PyPI package-install rehearsal from `v1.3.0` / + `code-mower==1.3.0` 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. The earlier beta.52 package rehearsal remains @@ -324,7 +329,7 @@ these questions in the first few minutes: - Where is the code intentionally structured, and where is it still being refactored from extraction-era shape? -The v1.2.2 line now gives adopters that trust test plus first productivity +The v1.3.0 line now gives adopters that trust test plus first productivity visibility. More provider adapters are useful only when install, doctor, first report, privacy, measurement, and code structure remain boring and credible. diff --git a/docs/early-adopter-invite-runbook.md b/docs/early-adopter-invite-runbook.md index 52065afa..c12e4065 100644 --- a/docs/early-adopter-invite-runbook.md +++ b/docs/early-adopter-invite-runbook.md @@ -38,7 +38,7 @@ It is an OSS local-first tool for setting up AI peer-programmer/reviewer lanes on your real codebase, with optional privacy-first cloud reporting. Start here: -https://github.com/codemower-ai/code-mower/blob/v1.2.2/docs/try-in-10-minutes.md +https://github.com/codemower-ai/code-mower/blob/v1.3.0/docs/try-in-10-minutes.md Cloud sharing is optional. The default bundle excludes source code, raw diffs, model transcripts, raw stdout/stderr, auth output, and secrets. @@ -53,7 +53,7 @@ Before inviting a user: ```bash python3.12 --version export CODE_MOWER_PYTHON="$(command -v python3.12)" - pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 + pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 code-mower --version ``` diff --git a/docs/early-adopter-v05.md b/docs/early-adopter-v05.md index da6a3d8c..da3e865a 100644 --- a/docs/early-adopter-v05.md +++ b/docs/early-adopter-v05.md @@ -1,7 +1,7 @@ # Code Mower Early Adopter Guide This document records the historical v0.5 early-adopter product plan. The -current public install path is the v1.2.2 supervised-pilot release; use +current public install path is the v1.3.0 supervised-pilot release; 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. @@ -145,7 +145,7 @@ Cut a v0.5 alpha or beta only after: ## Current Release -`v1.2.2` is the current supervised-pilot release. It keeps the +`v1.3.0` is the current supervised-pilot release. It keeps the local-first package path from alpha.1, the cloud doctor service-readiness check from alpha.5, the hardened provider-auth doctor diagnostics needed for early-adopter troubleshooting, the dogfood dry-run path that feeds the diff --git a/docs/first-run-transcript.md b/docs/first-run-transcript.md index f03898b5..d11dc4bf 100644 --- a/docs/first-run-transcript.md +++ b/docs/first-run-transcript.md @@ -9,7 +9,7 @@ same provider warnings. ```bash python3.12 --version export CODE_MOWER_PYTHON="$(command -v python3.12)" -pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 +pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 code-mower --version ``` @@ -17,7 +17,7 @@ Expected shape: ```text Python 3.12.x -code-mower 1.2.2 +code-mower 1.3.0 ``` ## Generate Local Setup diff --git a/docs/first-user-demo-transcript.md b/docs/first-user-demo-transcript.md index 4169eb62..b6d12c51 100644 --- a/docs/first-user-demo-transcript.md +++ b/docs/first-user-demo-transcript.md @@ -14,9 +14,9 @@ release. ```bash python3.12 -m venv "$WORK_DIR/venv" "$WORK_DIR/venv/bin/python" -m pip install --upgrade pip -"$WORK_DIR/venv/bin/python" -m pip install code-mower==1.2.2 +"$WORK_DIR/venv/bin/python" -m pip install code-mower==1.3.0 "$WORK_DIR/venv/bin/code-mower" migration package-install-rehearsal \ - --package-spec code-mower==1.2.2 \ + --package-spec code-mower==1.3.0 \ --allow-package-index \ --python "$(command -v python3.12)" \ --json @@ -29,7 +29,7 @@ python3.12 -m venv "$WORK_DIR/venv" "mode": "package-install-rehearsal", "status": "pass", "steps": 27, - "package_spec": "code-mower==1.2.2", + "package_spec": "code-mower==1.3.0", "toy_repo": "$WORK_DIR/toy-repo", "doctor_status": "warn", "generated_artifacts": { diff --git a/docs/first-user-install-rehearsal.md b/docs/first-user-install-rehearsal.md index d0a4b456..794c0b30 100644 --- a/docs/first-user-install-rehearsal.md +++ b/docs/first-user-install-rehearsal.md @@ -48,7 +48,7 @@ Use the current public tag or release candidate: ```bash code-mower migration package-install-rehearsal \ - --package-spec code-mower==1.2.2 \ + --package-spec code-mower==1.3.0 \ --allow-package-index \ --python "$(command -v python3.12)" \ --json @@ -72,7 +72,7 @@ For a fixed output directory: ```bash code-mower migration package-install-rehearsal \ - --package-spec code-mower==1.2.2 \ + --package-spec code-mower==1.3.0 \ --allow-package-index \ --python "$(command -v python3.12)" \ --work-dir /tmp/code-mower-first-user-rehearsal \ @@ -101,7 +101,7 @@ For a GitHub tag fallback, pass the tag URL explicitly: ```bash code-mower migration package-install-rehearsal \ - --package-spec "git+https://github.com/codemower-ai/code-mower.git@v1.2.2" \ + --package-spec "git+https://github.com/codemower-ai/code-mower.git@v1.3.0" \ --python "$(command -v python3.12)" \ --json ``` @@ -113,14 +113,14 @@ deciding the package index or the release is broken. For pipx: ```bash export CODE_MOWER_PYTHON="$(command -v python3.12)" -PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 +PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 code-mower --version ``` For uv: ```bash -uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==1.2.2 +uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==1.3.0 code-mower --version ``` @@ -148,7 +148,7 @@ repository after the package install succeeds: ```bash code-mower migration package-install-rehearsal \ - --package-spec code-mower==1.2.2 \ + --package-spec code-mower==1.3.0 \ --allow-package-index \ --repo-path /path/to/external-repo \ --python "$(command -v python3.12)" \ @@ -240,7 +240,7 @@ When a product repository already has Code Mower wrapper files, the same ```bash code-mower migration package-install-rehearsal \ - --package-spec code-mower==1.2.2 \ + --package-spec code-mower==1.3.0 \ --allow-package-index \ --repo-path /path/to/product-repo \ --python "$(command -v python3.12)" \ @@ -303,7 +303,7 @@ If this fails, fix the first-user path before cutting or promoting a release. Publish and rehearse the package-index artifacts in this order. After the release tag exists at the release commit, dispatch both package-index publication runs with -`--ref v1.2.2`; never substitute mutable `main`, because the TestPyPI +`--ref v1.3.0`; never substitute mutable `main`, because the TestPyPI and production PyPI builds must check out identical source. First, run `release.yml` for TestPyPI only: @@ -311,7 +311,7 @@ First, run `release.yml` for TestPyPI only: ```bash gh workflow run release.yml \ --repo codemower-ai/code-mower \ - --ref v1.2.2 \ + --ref v1.3.0 \ -f publish_testpypi=true \ -f publish_pypi=false ``` @@ -321,7 +321,7 @@ candidate from TestPyPI: ```bash code-mower migration package-install-rehearsal \ - --package-spec code-mower==1.2.2 \ + --package-spec code-mower==1.3.0 \ --allow-package-index \ --upgrade-pip \ --pip-index-url https://test.pypi.org/simple/ \ @@ -336,7 +336,7 @@ Then run `release.yml` for production PyPI only: ```bash gh workflow run release.yml \ --repo codemower-ai/code-mower \ - --ref v1.2.2 \ + --ref v1.3.0 \ -f publish_testpypi=false \ -f publish_pypi=true ``` @@ -346,7 +346,7 @@ production package from PyPI: ```bash code-mower migration package-install-rehearsal \ - --package-spec code-mower==1.2.2 \ + --package-spec code-mower==1.3.0 \ --allow-package-index \ --upgrade-pip \ --python "$(command -v python3.12)" \ @@ -364,7 +364,7 @@ against a private external TypeScript product repository: ```bash code-mower migration package-install-rehearsal \ - --package-spec code-mower==1.2.2 \ + --package-spec code-mower==1.3.0 \ --allow-package-index \ --repo-path "$REPO_PATH" \ --work-dir "$WORK_DIR" \ diff --git a/docs/friendly-user-rollout-v05.md b/docs/friendly-user-rollout-v05.md index e7f66987..2ad31a30 100644 --- a/docs/friendly-user-rollout-v05.md +++ b/docs/friendly-user-rollout-v05.md @@ -4,7 +4,7 @@ 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 v1.2.2 supervised-pilot release. +this document is the current v1.3.0 supervised-pilot release. 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. @@ -28,10 +28,10 @@ out in the invite: ```bash python3.12 --version export CODE_MOWER_PYTHON="$(command -v python3.12)" -pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 +pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 ``` -The current package-index release baseline is `v1.2.2`, with pinned package install spec `code-mower==1.2.2`. Release evidence is recorded on the GitHub release and in the first-user install rehearsal. +The current package-index release baseline is `v1.3.0`, with pinned package install spec `code-mower==1.3.0`. Release evidence is recorded on the GitHub release and in the first-user install rehearsal. ## Invite Criteria diff --git a/docs/install.md b/docs/install.md index 4c2fd7d6..f124d6e0 100644 --- a/docs/install.md +++ b/docs/install.md @@ -63,7 +63,7 @@ Install with pipx and an explicit Python 3.12+ interpreter: ```bash python3.12 --version export CODE_MOWER_PYTHON="$(command -v python3.12)" -pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 +pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 code-mower --version ``` @@ -84,7 +84,7 @@ To replace an existing pipx install with an exact release, use `--force` so the old venv cannot keep serving the previous package: ```bash -PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 +PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 code-mower --version ``` @@ -97,7 +97,7 @@ export PIPX_HOME="$CODE_MOWER_AGENT_TOOLS/pipx" export PIPX_BIN_DIR="$CODE_MOWER_AGENT_TOOLS/bin" export PIPX_LOG_DIR="$CODE_MOWER_AGENT_TOOLS/logs" mkdir -p "$PIPX_HOME" "$PIPX_BIN_DIR" "$PIPX_LOG_DIR" -PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 +PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 "$PIPX_BIN_DIR/code-mower" --version ``` @@ -108,7 +108,7 @@ interactive shell profile: ```bash uv python install 3.12 -uv tool install --python 3.12 code-mower==1.2.2 +uv tool install --python 3.12 code-mower==1.3.0 code-mower --version ``` @@ -118,7 +118,7 @@ installed command directly from the uv tool bin directory for that session. To replace an existing uv tool install with an exact release: ```bash -uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==1.2.2 +uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==1.3.0 code-mower --version ``` @@ -133,7 +133,7 @@ command -v code-mower code-mower --version pipx uninstall code-mower uv python install 3.12 -uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==1.2.2 +uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==1.3.0 hash -r command -v code-mower code-mower --version @@ -153,7 +153,7 @@ For pipx: ```bash python3.12 --version export CODE_MOWER_PYTHON="$(command -v python3.12)" -PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 +PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 code-mower --version ``` @@ -161,7 +161,7 @@ For uv: ```bash uv python install 3.12 -uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==1.2.2 +uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==1.3.0 code-mower --version ``` diff --git a/docs/jira-cloud-setup.md b/docs/jira-cloud-setup.md index c76575d3..20167290 100644 --- a/docs/jira-cloud-setup.md +++ b/docs/jira-cloud-setup.md @@ -214,7 +214,7 @@ GitHub state only. Controller dry-run never dispatches, merges, or writes Jira. This shared session-brief contract, the Jira REST commands, and the double write guard described elsewhere in this guide are available in -`code-mower==1.2.2`. +`code-mower==1.3.0`. `code-mower session start` adds a `tracker` section to the operating brief whenever `tracker.kind` is `jira_cloud`. Codex, Claude, and every other diff --git a/docs/mirror-removal-runbook.md b/docs/mirror-removal-runbook.md index 88c22337..cc41a916 100644 --- a/docs/mirror-removal-runbook.md +++ b/docs/mirror-removal-runbook.md @@ -32,7 +32,7 @@ Run: ```bash code-mower migration package-install-rehearsal \ - --package-spec code-mower==1.2.2 \ + --package-spec code-mower==1.3.0 \ --allow-package-index \ --repo-path /path/to/product-repo \ --json diff --git a/docs/oss-v1-checklist.md b/docs/oss-v1-checklist.md index b41ed3d1..ddf1d4d9 100644 --- a/docs/oss-v1-checklist.md +++ b/docs/oss-v1-checklist.md @@ -46,7 +46,7 @@ history opens the repository. They should be able to confirm: ## Current v1.0 Baseline -The current public-release baseline is `v1.2.2` of the standalone +The current public-release baseline is `v1.3.0` of the standalone package. Before widening the release, record: - non-editable package-install rehearsal in a clean venv; @@ -55,7 +55,7 @@ package. Before widening the release, record: runs: TestPyPI first with `publish_testpypi=true`, `publish_pypi=false`, then production PyPI with `publish_testpypi=false`, `publish_pypi=true`; - package-install rehearsals against the exact TestPyPI and PyPI artifacts as - `code-mower==1.2.2` after those workflow runs finish, with workflow run + `code-mower==1.3.0` after those workflow runs finish, with workflow run links recorded as release evidence; - public-tag/source install validation as a fallback path; - production dogfood uploads from Code Mower OSS, CodeMower.com, and two @@ -187,7 +187,7 @@ It has not yet proved: ```bash CODE_MOWER_PYTHON="$(command -v python3.12)" -pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 +pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 code-mower init --easy code-mower init --easy --apply --output-dir .code-mower.generated code-mower doctor --preflight @@ -197,7 +197,7 @@ code-mower --help-all code-mower next-steps --profile recommended code-mower migration wrapper-rehearsal --repo-path /path/to/product-repo --json code-mower migration package-install-rehearsal \ - --package-spec code-mower==1.2.2 \ + --package-spec code-mower==1.3.0 \ --allow-package-index \ --repo-path /path/to/repo \ --json diff --git a/docs/package-customization.md b/docs/package-customization.md index b99f0775..2888df75 100644 --- a/docs/package-customization.md +++ b/docs/package-customization.md @@ -285,7 +285,7 @@ run: ```bash code-mower migration package-install-rehearsal \ - --package-spec code-mower==1.2.2 \ + --package-spec code-mower==1.3.0 \ --allow-package-index \ --repo-path /path/to/product-repo \ --json diff --git a/docs/provider-matrix.md b/docs/provider-matrix.md index 7e91175c..73985bde 100644 --- a/docs/provider-matrix.md +++ b/docs/provider-matrix.md @@ -29,7 +29,7 @@ agent hosting a session is the default orchestrator. | Devin, Grok Bot, Antigravity, Muse, custom hosts | Recognized host identities for briefs and telemetry; execution remains an explicit handoff or provider-specific transport until separately qualified | No implicit Jira authority; use the guarded Code Mower tracker commands for writes | The lease, shared Jira brief, and explicit Cursor qualification are available -in `code-mower==1.2.2`; see [Participants And Sessions](sessions.md) for the +in `code-mower==1.3.0`; see [Participants And Sessions](sessions.md) for the operating contract. ## Provider Classes diff --git a/docs/public-release-checklist.md b/docs/public-release-checklist.md index c064f5c5..e10e6e6d 100644 --- a/docs/public-release-checklist.md +++ b/docs/public-release-checklist.md @@ -11,11 +11,11 @@ not know the original reference repos. - Apache-2.0 `LICENSE` and `NOTICE` are present. - The package has public releases and reports its version with `code-mower --version`. -- The current package-index release entrypoint is `code-mower==1.2.2`, with +- The current package-index release entrypoint is `code-mower==1.3.0`, with `code-mower doctor --adoption --repo OWNER/REPO` as the human-facing first-run setup diagnostic and `code-mower lanes status --repo OWNER/REPO` as the operator snapshot. The corresponding GitHub tag is - `v1.2.2`; `doctor --preflight` and `doctor --v05` remain + `v1.3.0`; `doctor --preflight` and `doctor --v05` remain compatibility presets for scripts. - The v1.0 supervised-pilot release includes Python 3.12+ install hardening, hosted-builder doctor postures, non-expiring token diagnostics, native diff --git a/docs/pypi-release.md b/docs/pypi-release.md index 90dc1f6a..f52c6529 100644 --- a/docs/pypi-release.md +++ b/docs/pypi-release.md @@ -6,7 +6,7 @@ TestPyPI or production PyPI through trusted publishing. ```bash CODE_MOWER_PYTHON="$(command -v python3.12)" -pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 +pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 ``` ## Current Status @@ -88,7 +88,7 @@ should be the `/releases/latest` result, and exact-version installs should resolve from PyPI. ```bash -gh release view v1.2.2 \ +gh release view v1.3.0 \ --repo codemower-ai/code-mower \ --json tagName,isPrerelease gh api repos/codemower-ai/code-mower/releases/latest \ @@ -139,7 +139,7 @@ For pipx: ```bash python3.12 --version export CODE_MOWER_PYTHON="$(command -v python3.12)" -PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 +PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 code-mower --version ``` @@ -147,7 +147,7 @@ For uv: ```bash uv python install 3.12 -uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==1.2.2 +uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==1.3.0 code-mower --version ``` @@ -176,7 +176,7 @@ For production PyPI verification: ```bash python3.12 -m venv /tmp/code-mower-pypi-smoke /tmp/code-mower-pypi-smoke/bin/python -m pip install --upgrade pip -/tmp/code-mower-pypi-smoke/bin/python -m pip install code-mower==1.2.2 +/tmp/code-mower-pypi-smoke/bin/python -m pip install code-mower==1.3.0 /tmp/code-mower-pypi-smoke/bin/code-mower --version ``` @@ -184,7 +184,7 @@ Then run the release-gate first-user rehearsal against the same package: ```bash code-mower migration package-install-rehearsal \ - --package-spec code-mower==1.2.2 \ + --package-spec code-mower==1.3.0 \ --allow-package-index \ --upgrade-pip \ --python "$(command -v python3.12)" \ @@ -206,8 +206,8 @@ on production PyPI -- see ```bash code-mower release qualify \ - --release-tag v1.2.2 \ - --package-spec code-mower==1.2.2 \ + --release-tag v1.3.0 \ + --package-spec code-mower==1.3.0 \ --output result.json \ --package-source testpypi \ --execute @@ -250,7 +250,7 @@ an agent, and the release rehearsal all install the same artifact: ```bash CODE_MOWER_PYTHON="$(command -v python3.12)" -pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 +pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 ``` An unpinned `pipx install code-mower` may be mentioned as a convenience only diff --git a/docs/quickstart.md b/docs/quickstart.md index 5274ff98..6ec18659 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -23,7 +23,7 @@ is the first-class isolated path: ```bash uv python install 3.12 -uv tool install --python 3.12 code-mower==1.2.2 +uv tool install --python 3.12 code-mower==1.3.0 code-mower --version ``` @@ -32,11 +32,11 @@ For a laptop or workstation that already uses pipx: ```bash python3.12 --version export CODE_MOWER_PYTHON="$(command -v python3.12)" -pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 +pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 code-mower --version ``` -`1.2.2` is the supervised-pilot release. If you want a future prerelease instead +`1.3.0` is the supervised-pilot release. If you want a future prerelease instead of this exact verified release, use: ```bash @@ -437,7 +437,7 @@ export bundle, upload dry run, and CodeMower.com dogfood dry run. ```bash code-mower migration package-install-rehearsal \ - --package-spec code-mower==1.2.2 \ + --package-spec code-mower==1.3.0 \ --allow-package-index \ --python "$(command -v python3.12)" \ --json diff --git a/docs/sessions.md b/docs/sessions.md index 5f928ec3..43fea6ef 100644 --- a/docs/sessions.md +++ b/docs/sessions.md @@ -6,7 +6,7 @@ your conversation is the default orchestrator for that session. The participant picker, host-led session brief, single-orchestrator lease, shared Jira tracker brief, controller host telemetry, and explicit Cursor -qualification documented below are available in `code-mower==1.2.2`. +qualification documented below are available in `code-mower==1.3.0`. Install from the matching tag when following release documentation, or use a contributor checkout when testing later source changes. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index d150b514..e90be94c 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -129,7 +129,7 @@ If pipx should own the command, reinstall the exact beta with cache bypass: ```bash export CODE_MOWER_PYTHON="$(command -v python3.12)" -PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 +PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 hash -r code-mower --version ``` @@ -140,7 +140,7 @@ path: ```bash pipx uninstall code-mower -uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==1.2.2 +uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==1.3.0 hash -r command -v code-mower code-mower --version diff --git a/docs/try-in-10-minutes.md b/docs/try-in-10-minutes.md index 684cdaa3..7dff96f7 100644 --- a/docs/try-in-10-minutes.md +++ b/docs/try-in-10-minutes.md @@ -21,8 +21,8 @@ Use this install matrix: | Environment | Command shape | | --- | --- | -| Laptop/workstation | `pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.2.2` | -| Hosted agent, CI box, or minimal Linux VM | `uv tool install --python 3.12 code-mower==1.2.2` | +| Laptop/workstation | `pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.3.0` | +| Hosted agent, CI box, or minimal Linux VM | `uv tool install --python 3.12 code-mower==1.3.0` | | Code Mower contributor checkout | `scripts/dev-python -m venv .venv` then `.venv/bin/python -m pip install -e ".[test]"` | For a cold laptop install: @@ -30,7 +30,7 @@ For a cold laptop install: ```bash python3.12 --version export CODE_MOWER_PYTHON="$(command -v python3.12)" -pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.2.2 +pipx install --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 command -v code-mower code-mower --version ``` @@ -48,7 +48,7 @@ For a repository that already has generated Code Mower support, follow [Upgrade An Existing Repository](upgrade-existing-repo.md) before copying a new `.code-mower.generated` tree. -`1.2.2` is the supervised-pilot release. To follow a future prerelease line +`1.3.0` is the supervised-pilot release. To follow a future prerelease line instead of pinning this exact build: ```bash diff --git a/docs/v130-context-qualification.md b/docs/v130-context-qualification.md new file mode 100644 index 00000000..27874ca1 --- /dev/null +++ b/docs/v130-context-qualification.md @@ -0,0 +1,103 @@ +# v1.3 context qualification + +The optional Coworker integration is operationally qualified for supervised use. +The pilot demonstrated account-bound delivery and found one useful prior-work +reference across two frozen cases. It did not demonstrate faster delivery or +find a defect requiring either existing patch to change. + +## Evidence boundaries + +Implementation stages C1–C6 shipped independently through the Code Mower gate, +with a Codex builder and independent current-head Claude review. The final +implementation stage passed 2,795 local tests, Python 3.12–3.14 CI, package +checks, cold-clone installation and no-provider smoke. See epic [#868](https://github.com/codemower-ai/code-mower/issues/868) +and PRs [#883](https://github.com/codemower-ai/code-mower/pull/883), +[#884](https://github.com/codemower-ai/code-mower/pull/884), +[#885](https://github.com/codemower-ai/code-mower/pull/885) and +[#886](https://github.com/codemower-ai/code-mower/pull/886). + +The private pilot used two already-implemented PRs as frozen reference cases. +Their repository, work-item text, source, identities and citations remain private. +The existing lane retains tracker and human merge ownership. Qualification made +no GitHub or Jira mutations and did not install a new gate in those repositories. +Local reference input records exercised delivery and review authorization; they +are not live GitHub gate verdicts. + +The existing frozen heads also had Code Mower review evidence: one completed +Codex audit for case A, and completed Claude and Codex audits for case B. Those +pre-existing results are distinct from the context assessment. + +The baseline was each frozen PR description and diff, not a fresh authoritative +tracker read or a blind implementation trial. Claude independently assessed the +Code Mower work orders and the same bounded evidence that Codex inspected. This +was one retrospective model call across both cases. It was not a new source-code +implementation or a substitute for the existing PRs' reviews. + +## Live retrieval and delivery + +| Observation | Case A | Case B | +| --- | --- | --- | +| Selected session host | Codex | Claude | +| Evidence records | 3 | 3 | +| Provider read requests | 2 | 2 | +| Discovery pages | 1 | 1 | +| Response bytes | 1,589 | 1,531 | +| Observed fetch time | 5.474 s | 1.356 s | +| Completeness | Partial | Partial | +| Text truncated | No | No | +| Source revision/confidence | Unknown | Unknown | +| Provider-reported monetary cost | Unavailable | Unavailable | + +Each request performed one discovery page and one bounded search. Neither search +was expanded to improve the score. All six approved Claude/Codex +orchestrator/builder/reviewer roles received identical evidence bytes, with a +fresh online authorization before replay. Subsequent processes resumed from the +private stored packet without another search. Authorization was checked again +before saving the assessment as private feedback. + +An explicit context doctor probe also refreshed the selected connection and +reported ready without searching. The earlier disposable-grant qualification +confirmed refresh-token revocation; the active pilot grant was not revoked to +repeat that experiment. Runtime and regression coverage separately exercise +wrong account/destination, expired or revoked authorization, interruption, +changed context on an unchanged head, required-input failure, optional outages, +malicious source instructions, bounds and private-output handling. + +## Usefulness assessment + +| Case | Added value | Disposition | +| --- | --- | --- | +| A: bounded parser hardening | Retrieved adjacent project work; no direct new requirement, owner question or regression test. | Keep the existing patch scope. | +| B: accessible control wording | Found prior work on a related control with different terminology, raising a possible consistency question. | Source confirmed the difference; record an owner terminology question before changing the patch. | + +The related-control lead came from a memory summary. A subsequent read of source +and its existing regression assertion at the frozen PR head confirmed the +different labels. This is evidence for an owner consistency question, not policy +or a new acceptance criterion. Product tests were not rerun during this frozen +assessment; it made no source changes. Existing targeted +regression tests already covered both patches' stated intent; no additional test +was justified solely by the retrieved material. One model description conflated +partial evidence with truncation; the structured packet correctly reported +partial, untruncated evidence and governs this scorecard. + +The independent assessment took 23.121 seconds wall time and reported $0.0902698 +in model cost. That is the assessment call only, not the complete pilot cost. +Coworker monetary cost and total operator effort were not available. Original +implementation elapsed time, time to reviewed PR attributable to context, defect +escape rate and time saved were not measured. Two retrospective cases cannot +establish a productivity improvement. + +## Adoption implications + +Keep context optional by default. Read the cited packet before treating it as a +constraint, especially when the provider reports partial results or unresolved +entities. Narrow work-item scope and explicit refresh are useful controls; +retrieval relevance and source verification remain areas to improve. + +The base install requires no Coworker SDK, account or login. Configured use needs +an explicit private account/workspace, an available supported OS vault and +approved repository/recipient destinations. Hosted reviewers need equivalent +local authorization to consume private context; they cannot fall back to an +unrelated account. See [setup](context-setup.md) and [delivery](context-delivery.md). +Graphify remains a separate candidate under [#876](https://github.com/codemower-ai/code-mower/issues/876), +with a synthetic local-graph contract fixture rather than a shipped adapter. diff --git a/docs/v130-release-notes.md b/docs/v130-release-notes.md new file mode 100644 index 00000000..14e27007 --- /dev/null +++ b/docs/v130-release-notes.md @@ -0,0 +1,77 @@ +# Code Mower v1.3.0 Release Notes + +Code Mower v1.3.0 adds optional organizational context through Coworker. Claude +and Codex can receive the same bounded, cited evidence from an explicitly +selected account, and reviews become stale when that evidence changes. + +The default remains Claude + Codex with no Coworker dependency or login. The +calling host remains the orchestrator; a context provider gains no builder, +reviewer, tracker-write or merge authority. The supervised-pilot posture remains. + +## Optional Coworker context + +- Select a generic connection reference during init. Keep the actual account, + workspace, credentials and destination permissions in private local storage. +- Authenticate through OAuth and verify signed account/workspace identity. + Credentials use macOS Keychain or Linux Secret Service, without a plaintext + fallback or import from the host's unrelated MCP account. +- Fetch a bounded read-only packet with citations, completeness and expiry. + Every retrieval and recipient replay reauthorizes online. +- Deliver the same packet to approved participants. Private detailed findings + stay local; public review comments contain only allowlisted verdict metadata. +- Bind review validity to both code head and context input revision. A changed + required-context policy is read from trusted repository configuration on every + gate run; old code-only reviews cannot silently satisfy it. +- Diagnose readiness offline by default, with explicit online verification. + Optional outages can be acknowledged as a new input requiring a fresh code-only + review; required context pauses dependent work. + +See the [setup guide](context-setup.md), [connection lifecycle](context-connections.md) +and [review delivery protocol](context-delivery.md). + +## Qualification and limits + +The [two-case qualification](v130-context-qualification.md) demonstrated live +account-bound delivery to both host roles and fresh authorization across process +restarts. It found useful prior art in one case and mostly adjacent material in +the other. Neither case justified changing the existing patch solely from the +retrieved evidence. No time-saving or general productivity claim is made. + +Packets may be partial, and a citation from memory does not establish current +source truth. Required context cannot be reviewed offline or by a runner without +the selected authorization. The gate is event-driven, not a continuous revocation +monitor. Revoking a refresh grant prevents subsequent Code Mower use; already-issued +bearer tokens outside Code Mower may persist until expiry. + +Graphify is anticipated by the provider-neutral packet contract and a synthetic +local-graph fixture. Its production adapter is a separate v1.3.x candidate. + +## Install or upgrade + +```bash +CODE_MOWER_PYTHON="$(command -v python3.12)" +PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==1.3.0 +code-mower --version +``` + +For optional Coworker support, use the same version with the extra: + +```bash +PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" 'code-mower[coworker]==1.3.0' +code-mower init --easy --context-connection example-context --dry-run +``` + +Expected version output: `code-mower 1.3.0`. Inspect the init preview and apply the +selected policy, then connect the intended account as described in the setup +guide. Existing repositories should review generated support-file/workflow drift +when adopting context-aware gates. Restart long-running Boards after upgrading. + +## Privacy + +The privacy boundary is unchanged. Cloud upload remains optional and does not +collect organization context, account/workspace identity, queries, source text, +private citations, prompts, transcripts, credentials or packet fingerprints. +Default readiness output uses fixed redacted metadata. Identity inspection is an +explicit local-terminal operation. Disconnect disables access before remote +revocation and private packet/feedback cleanup; it cannot recall already-delivered +text from a recipient. diff --git a/pyproject.toml b/pyproject.toml index 1105c472..db7849e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "code-mower" -version = "1.2.2" +version = "1.3.0" description = "Multi-reviewer AI code audit orchestration" requires-python = ">=3.12" readme = "README.md" diff --git a/src/code_mower/__init__.py b/src/code_mower/__init__.py index 6fd6ead5..19fd4f3a 100644 --- a/src/code_mower/__init__.py +++ b/src/code_mower/__init__.py @@ -1,3 +1,3 @@ """Code Mower package.""" -__version__ = "1.2.2" +__version__ = "1.3.0" diff --git a/src/code_mower/package_manifest.py b/src/code_mower/package_manifest.py index 90807174..c3aa08d5 100644 --- a/src/code_mower/package_manifest.py +++ b/src/code_mower/package_manifest.py @@ -537,6 +537,8 @@ ("docs/context-provider-contract.md", "docs/context-provider-contract.md", "doc"), ("docs/context-connections.md", "docs/context-connections.md", "doc"), ("docs/context-setup.md", "docs/context-setup.md", "doc"), + ("docs/v130-release-notes.md", "docs/v130-release-notes.md", "doc"), + ("docs/v130-context-qualification.md", "docs/v130-context-qualification.md", "doc"), ("docs/context-packet-schema.md", "docs/context-packet-schema.md", "doc"), ("docs/context-delivery.md", "docs/context-delivery.md", "doc"), ("tools/CODE_MOWER_CLOUD_BENCHMARKING.md", "docs/cloud-benchmarking.md", "doc"), diff --git a/src/code_mower/templates/workflows/builder-provenance.yml.j2 b/src/code_mower/templates/workflows/builder-provenance.yml.j2 index ce75be1f..116e84bc 100644 --- a/src/code_mower/templates/workflows/builder-provenance.yml.j2 +++ b/src/code_mower/templates/workflows/builder-provenance.yml.j2 @@ -8,7 +8,7 @@ permissions: contents: read env: - CODE_MOWER_PACKAGE_SPEC: code-mower==1.2.2 + CODE_MOWER_PACKAGE_SPEC: code-mower==1.3.0 jobs: auto-record: diff --git a/templates/workflows/builder-provenance.yml.j2 b/templates/workflows/builder-provenance.yml.j2 index ce75be1f..116e84bc 100644 --- a/templates/workflows/builder-provenance.yml.j2 +++ b/templates/workflows/builder-provenance.yml.j2 @@ -8,7 +8,7 @@ permissions: contents: read env: - CODE_MOWER_PACKAGE_SPEC: code-mower==1.2.2 + CODE_MOWER_PACKAGE_SPEC: code-mower==1.3.0 jobs: auto-record: diff --git a/tests/test_release_hygiene.py b/tests/test_release_hygiene.py index 0b5fb564..94d6882d 100644 --- a/tests/test_release_hygiene.py +++ b/tests/test_release_hygiene.py @@ -65,7 +65,7 @@ class ReleaseHygieneTests(unittest.TestCase): def test_version_is_current_supervised_pilot_release(self) -> None: - self.assertEqual(__version__, "1.2.2") + self.assertEqual(__version__, "1.3.0") def test_dogfood_repo_has_real_root_config(self) -> None: config_path = ROOT / "code-mower.yml" @@ -216,7 +216,7 @@ def test_install_and_upgrade_docs_cover_agent_paths(self) -> None: self.assertIn("Cold Install Vs Upgrade", install) self.assertIn("Switching Between pipx And uv", install) self.assertIn("uv tool install --python 3.12 --reinstall --refresh-package", install) - self.assertIn("code-mower==1.2.2", troubleshooting) + self.assertIn("code-mower==1.3.0", troubleshooting) self.assertNotIn("code-mower==0.8.0b1", troubleshooting) self.assertIn("pipx uninstall code-mower", install) for env_name in ("PIPX_HOME", "PIPX_BIN_DIR", "PIPX_LOG_DIR"): @@ -1100,7 +1100,7 @@ def test_direct_cli_execution_points_to_package_or_dev_wrapper(self) -> None: ) self.assertNotEqual(completed.returncode, 0) - self.assertIn("pipx install code-mower==1.2.2", completed.stderr) + self.assertIn("pipx install code-mower==1.3.0", completed.stderr) self.assertIn("scripts/dev-python -m venv .venv", completed.stderr) self.assertIn(".venv/bin/code-mower", completed.stderr) self.assertNotIn("PYTHONPATH=src", completed.stderr) @@ -3260,10 +3260,10 @@ def test_setup_drift_reports_standalone_pin_states(self) -> None: cases = ( ( - 'CODE_MOWER_STANDALONE_REF="v1.2.2"\n', + 'CODE_MOWER_STANDALONE_REF="v1.3.0"\n', "pass", "matches_running_package", - "v1.2.2", + "v1.3.0", ), ( 'CODE_MOWER_STANDALONE_REF="v0.9.1-beta.1"\n', @@ -3294,12 +3294,12 @@ def test_setup_drift_reports_standalone_pin_states(self) -> None: payload = migration._standalone_pin_drift_summary( repo, - package_version="1.2.2", + package_version="1.3.0", ) self.assertEqual(payload["status"], status) self.assertEqual(payload["reason"], reason) - self.assertEqual(payload["expected_ref"], "v1.2.2") + self.assertEqual(payload["expected_ref"], "v1.3.0") if current_ref is None: self.assertNotIn("current_ref", payload) else: @@ -3320,7 +3320,7 @@ def test_setup_drift_warns_on_non_utf8_standalone_pin(self) -> None: payload = migration._standalone_pin_drift_summary( repo, - package_version="1.2.2", + package_version="1.3.0", ) self.assertEqual(payload["status"], "warn") @@ -3383,7 +3383,7 @@ def test_setup_drift_text_prints_absent_standalone_pin_line(self) -> None: "standalone_pin": { "status": "skip", "reason": "pin_file_absent", - "expected_ref": "v1.2.2", + "expected_ref": "v1.3.0", }, "builder_hint": { "status": "skip", @@ -3395,7 +3395,7 @@ def test_setup_drift_text_prints_absent_standalone_pin_line(self) -> None: rendered = migration.render_setup_drift_text(payload) - self.assertIn("Standalone pin: SKIP pin_file_absent expected=v1.2.2", rendered) + self.assertIn("Standalone pin: SKIP pin_file_absent expected=v1.3.0", rendered) def test_setup_drift_reports_builder_hint_when_builders_omitted(self) -> None: from code_mower import migration @@ -5575,11 +5575,11 @@ def test_package_materializer_can_run_from_extracted_checkout(self) -> None: (output_dir / "src/code_mower/cloud_client/dogfood.py").is_file() ) self.assertIn( - 'version = "1.2.2"', + 'version = "1.3.0"', (output_dir / "pyproject.toml").read_text(encoding="utf-8"), ) self.assertIn( - '__version__ = "1.2.2"', + '__version__ = "1.3.0"', (output_dir / "src/code_mower/__init__.py").read_text( encoding="utf-8" ), @@ -7584,7 +7584,7 @@ def _run_mocked_pip_install( "pip", "install", "--no-cache-dir", - "code-mower==1.2.2", + "code-mower==1.3.0", ] def fake_run_step(*args: object, **kwargs: object) -> subprocess.CompletedProcess[str]: @@ -7651,7 +7651,7 @@ def test_package_install_rehearsal_classifies_package_index_specs(self) -> None: self.assertTrue(code_mower_migration._package_spec_uses_package_index("code-mower")) self.assertTrue( code_mower_migration._package_spec_uses_package_index( - "code-mower==1.2.2" + "code-mower==1.3.0" ) ) self.assertFalse(code_mower_migration._package_spec_uses_package_index(".")) @@ -7660,7 +7660,7 @@ def test_package_install_rehearsal_classifies_package_index_specs(self) -> None: ) self.assertFalse( code_mower_migration._package_spec_uses_package_index( - "git+https://github.com/codemower-ai/code-mower.git@v1.2.2" + "git+https://github.com/codemower-ai/code-mower.git@v1.3.0" ) ) @@ -7670,7 +7670,7 @@ def test_package_install_rehearsal_requires_package_index_opt_in(self) -> None: with self.assertRaisesRegex(ValueError, "--allow-package-index"): code_mower_migration.run_package_install_rehearsal( - package_spec="code-mower==1.2.2", + package_spec="code-mower==1.3.0", work_dir=work_dir, ) @@ -7698,7 +7698,7 @@ def test_package_install_rehearsal_cli_passes_network_opt_ins(self) -> None: [ "package-install-rehearsal", "--package-spec", - "code-mower==1.2.2", + "code-mower==1.3.0", "--allow-package-index", "--upgrade-pip", "--pip-no-cache", @@ -7754,10 +7754,10 @@ def test_release_readiness_reports_package_index_promotion_gate(self) -> None: payload = release_readiness.render_release_readiness(ROOT) self.assertEqual(payload["status"], "pass") - self.assertEqual(payload["version"], "1.2.2") - self.assertEqual(payload["release_tag"], "v1.2.2") - self.assertEqual(payload["alpha_tag"], "v1.2.2") - self.assertEqual(payload["package_index_spec"], "code-mower==1.2.2") + self.assertEqual(payload["version"], "1.3.0") + self.assertEqual(payload["release_tag"], "v1.3.0") + self.assertEqual(payload["alpha_tag"], "v1.3.0") + self.assertEqual(payload["package_index_spec"], "code-mower==1.3.0") check_ids = {check["id"]: check for check in payload["checks"]} self.assertEqual(check_ids["package-version-consistency"]["status"], "pass") self.assertEqual( @@ -7773,9 +7773,9 @@ def test_release_readiness_reports_package_index_promotion_gate(self) -> None: self.assertEqual(check_ids["public-support-redaction-guidance"]["status"], "pass") commands = {action["id"]: action["command"] for action in payload["next_actions"]} urls = {action["id"]: action.get("url", "") for action in payload["next_actions"]} - self.assertIn("--ref v1.2.2", commands["dry-run-release-workflow"]) + self.assertIn("--ref v1.3.0", commands["dry-run-release-workflow"]) self.assertNotIn("--ref main", commands["dry-run-release-workflow"]) - self.assertIn("--ref v1.2.2", commands["publish-testpypi-candidate"]) + self.assertIn("--ref v1.3.0", commands["publish-testpypi-candidate"]) self.assertNotIn("--ref main", commands["publish-testpypi-candidate"]) self.assertIn("publish_testpypi=true", commands["publish-testpypi-candidate"]) self.assertIn("publish_pypi=false", commands["publish-testpypi-candidate"]) @@ -7812,7 +7812,7 @@ def test_release_readiness_fails_on_materialized_package_version_drift( check_ids = {check["id"]: check for check in payload["checks"]} check = check_ids["materialized-package-version-consistency"] self.assertEqual(check["status"], "fail") - self.assertEqual(check["detail"]["source_version"], "1.2.2") + self.assertEqual(check["detail"]["source_version"], "1.3.0") self.assertEqual(check["detail"]["generated_init_version"], "0.0.0") def test_public_support_docs_are_packaged_and_privacy_forward(self) -> None: @@ -7916,20 +7916,20 @@ def test_release_readiness_tag_derivation_supports_release_stages(self) -> None: "v1.0.0-rc.1", ) self.assertEqual( - release_readiness._release_tag_for_version("1.2.2"), - "v1.2.2", + release_readiness._release_tag_for_version("1.3.0"), + "v1.3.0", ) self.assertEqual( - code_mower_versioning.release_tag_for_version("1.2.2"), - "v1.2.2", + code_mower_versioning.release_tag_for_version("1.3.0"), + "v1.3.0", ) def test_public_release_baseline_helpers_derive_announcement_links(self) -> None: self.assertEqual( code_mower_versioning.public_baseline_sentence(__version__), ( - "The current package-index release baseline is `v1.2.2`, " - "with pinned package install spec `code-mower==1.2.2`. " + "The current package-index release baseline is `v1.3.0`, " + "with pinned package install spec `code-mower==1.3.0`. " "Release evidence is recorded on the GitHub release and in the " "first-user install rehearsal." ), @@ -7938,7 +7938,7 @@ def test_public_release_baseline_helpers_derive_announcement_links(self) -> None code_mower_versioning.tagged_doc_url(__version__), ( "https://github.com/codemower-ai/code-mower/blob/" - "v1.2.2/docs/try-in-10-minutes.md" + "v1.3.0/docs/try-in-10-minutes.md" ), ) @@ -7991,12 +7991,12 @@ def test_public_docs_match_current_commands_and_privacy_boundary(self) -> None: readme = (ROOT / "README.md").read_text(encoding="utf-8") sessions = (ROOT / "docs" / "sessions.md").read_text(encoding="utf-8") - release_notes = (ROOT / "docs" / "v122-release-notes.md").read_text( + release_notes = (ROOT / "docs" / "v130-release-notes.md").read_text( encoding="utf-8" ) self.assertIn("Documentation on `main` follows the source on `main`", readme) - self.assertIn("available in `code-mower==1.2.2`", sessions) - self.assertIn("# Code Mower v1.2.2 Release Notes", release_notes) + self.assertIn("available in `code-mower==1.3.0`", sessions) + self.assertIn("# Code Mower v1.3.0 Release Notes", release_notes) self.assertIn("The privacy boundary is unchanged.", release_notes) self.assertLess( readme.index("[v1.1 Release Notes](docs/v11-release-notes.md)"), @@ -8035,15 +8035,15 @@ def test_current_release_docs_record_package_index_procedure(self) -> None: ) current_status = ( - "The current package-index release baseline is `v1.2.2`, with " - "pinned package install spec `code-mower==1.2.2`. Release " + "The current package-index release baseline is `v1.3.0`, with " + "pinned package install spec `code-mower==1.3.0`. Release " "evidence is recorded on the GitHub release and in the first-user " "install rehearsal." ) for text in (readme, current_state, rollout): self.assertIn(current_status, " ".join(text.split())) self.assertIn( - "The current package-index release entrypoint is `code-mower==1.2.2`", + "The current package-index release entrypoint is `code-mower==1.3.0`", public_release, ) self.assertIn("The v1.0 supervised-pilot release includes", public_release) @@ -8053,7 +8053,7 @@ def test_current_release_docs_record_package_index_procedure(self) -> None: ) self.assertIn( - "The current public-release baseline is `v1.2.2`", + "The current public-release baseline is `v1.3.0`", oss_checklist, ) self.assertIn( @@ -8084,7 +8084,7 @@ def test_current_release_docs_record_package_index_procedure(self) -> None: " ".join(first_user.split()), ) self.assertIn("never substitute mutable `main`", first_user) - self.assertEqual(first_user.count(" --ref v1.2.2 \\"), 2) + self.assertEqual(first_user.count(" --ref v1.3.0 \\"), 2) self.assertNotIn(" --ref main \\", first_user) self.assertIn("-f publish_testpypi=true", first_user) self.assertIn("-f publish_pypi=false", first_user) @@ -8096,23 +8096,23 @@ def test_current_release_docs_record_package_index_procedure(self) -> None: first_user, ) self.assertNotIn( - "The latest public-package rehearsal for `v1.2.2` was run", + "The latest public-package rehearsal for `v1.3.0` was run", first_user, ) - self.assertNotIn("TestPyPI is not\npublished for `1.2.2`", first_user) + self.assertNotIn("TestPyPI is not\npublished for `1.3.0`", first_user) for text in (readme, current_state, rollout): self.assertNotIn( - "published on PyPI as `code-mower==1.2.2`", + "published on PyPI as `code-mower==1.3.0`", text, ) self.assertNotIn( "latest 10/10 public-package readiness proof for " - "`code-mower==1.2.2`", + "`code-mower==1.3.0`", text, ) self.assertNotIn( "public PyPI package-install rehearsal from " - "`code-mower==1.2.2`", + "`code-mower==1.3.0`", text, ) self.assertNotIn("beta.52: 10/10 first-user readiness", text) @@ -8412,7 +8412,7 @@ def test_install_docs_cover_supported_adoption_paths(self) -> None: self.assertIn("Python 3.12 or newer", install) self.assertIn('pipx install --python "$CODE_MOWER_PYTHON"', install) - self.assertIn("uv tool install --python 3.12 code-mower==1.2.2", install) + self.assertIn("uv tool install --python 3.12 code-mower==1.3.0", install) self.assertIn( 'PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON"', install, @@ -8506,7 +8506,7 @@ def test_active_docs_use_current_release_language(self) -> None: / "v101-effectiveness-assessment.md", } stale_phrases = ( - "pipx install --python python3.12 code-mower==1.2.2", + "pipx install --python python3.12 code-mower==1.3.0", "Use only after TestPyPI passes.", "future newest betas until 1.0", "during v0.7 adoption", @@ -8806,7 +8806,7 @@ def test_next_steps_includes_cloud_upload_dry_run_after_export(self) -> None: "doctor --adoption --repo codemower-ai/code-mower", doctor_step["command"], ) - self.assertIn("code-mower==1.2.2", package_step["command"]) + self.assertIn("code-mower==1.3.0", package_step["command"]) self.assertIn("--allow-package-index", package_step["command"]) self.assertIn("current published PyPI package", package_step["why"]) self.assertIn("first_user_readiness", package_step["why"])