Move the published-release pins to v1.2.0 - #919
Conversation
docs/release-runbook.md § Cutting the release, step 8, done after the v1.2.0 Release was public (precedents e2ab000 #777, daa4ad5 #853). Moving these pins before the tag existed is the #506 failure. Constants. LATEST_PUBLISHED_VERSION = "1.2.0" and LATEST_PUBLISHED_CONTRACT_VERSION = "41". Every other pin follows from what the enumerating tests then required: the Action, pip, uvx and shipgate_version pins in the GitHub Actions, CircleCI and GitLab examples, incidents, samples, docs, the bug-report template and .well-known. Rendered prompts and kits. The bundled prompts and CI recipes were re-rendered by the package's own renderer (13 copies; each differs from the tag only by the version). The five render hashes move, and the renders the v1.2.0 tag carries are appended to prior_render_sha256 in both adoption-kit metadata files, so an unmodified install still upgrades. Statements. v1.2.0 is the newest release (advisory, contract 41, no qualification claim) in the README, quickstart, ROADMAP, FAQ, distribution, pilot runbook, llms.txt, ai-search-summary, agent-contract-current and the regenerated llms-full.txt; the "unreleased, ahead of" qualifier is dropped now that the contracts are equal. Prose that still called contract v41 or diff --application unreleased is corrected, including two src comments that justified extending v41 in place. Measured surfaces, re-taken on PyPI 1.2.0 in a clean virtualenv outside any checkout: - The five README/quickstart diff answers, on the fixtures test_host_diff_entry_docs.py builds. The method reproduces all five digests recorded for 1.1.0; 1.2.0 and the source tree print identical answers. Only the change answer differs from 1.1.0 (review guidance and the launch-source note). _PUBLISHED_ANSWERS and its version move; the v1.2.0-tag labels join the negative controls. - The pilot ledger's route readiness dry run against PyPI 1.2.0, the source tree and PyPI 1.1.0. 1.2.0 and the tree match byte for byte modulo paths, commit ids and launcher names. Against 1.1.0: the same six rows; 1.2.0 reads them as 4 changes, not 6, and drift adds two permission_widened signals, both from #858. A dated factual checkpoint is added under the standing decision. - The Action README's What runs names 7fc61ef..., which init --ci from the 1.2.0 wheel writes; the engine-identity log note now says v1.2.0 carries it. The runbook's step 8 now also names the render-hash step and the unreleased prose no test enumerates. Deliberately not changed: .github/release-channels.json, tags and releases, the 1.2.0 CHANGELOG section (the entry is under a new ## Unreleased), the pre-commit rev pins left to #796, and historical records. Refs #778 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pengfei-threemoonslab
left a comment
There was a problem hiding this comment.
Reviewed 1c9963d909e6b399f8a9ca9387db07ac687d71f3 against 7fc61ef43d8ec5c906bc690765f4a1297dff4fda.
No actionable correctness findings. The changes consistently move the published-release pins to 1.2.0 / contract 41. The only executable source changes are those two constants; the other Python source edits clarify release history. I found no unintended changes to workflow permissions, gating policy, or generated prompt behavior.
Independent validation:
- Inspected the 69-file diff, including release availability claims, the pilot ledger updates, generated mirrors, render hash changes, and regression-test changes.
- Confirmed GitHub release
v1.2.0is published, non-draft, non-prerelease, and immutable. - Downloaded the 1.2.0 wheel from PyPI. Its SHA-256 is
26ee2a309c7229b90773f0e12cf0d7d4a9e5c247ed1c4bd5f219ac4d1b16dff7, and its release-source record names7fc61ef43d8ec5c906bc690765f4a1297dff4fda, matching the documented Action commit. Running that wheel's code outside the checkout reproduced all five documented answer shapes using the test fixtures and normalization. It reports CLI 1.2.0, contract 41, host inventory 0.7, and verifier 0.21. This check used the downloaded wheel with the existing test environment's dependencies, not a fresh dependency installation. - Verified that all 13 changed generated mirrors are exactly their previous bytes with
1.1.0replaced by1.2.0. Each of the five appended prior-render hashes matches the corresponding outgoing file at the release commit. - Local focused and adjacent suites: 1,039 passed, 4 skipped across public-surface contracts, distribution parity, renderers, entry-page captures, adopter pins, host-only recipe, pilot documentation, instruction application, release-source handling, CI recipes, and CI initialization.
ruff check .andgit diff --checkalso pass. All reported PR CI checks passed; the main-only release-tag-consistency job was skipped. I did not independently repeat the full three-build pilot dry run.
Merge control still requires a human. I ran the repository's boundary check, followed its exact verifier route, and refreshed agent control. The result is control_state: review_publishable, release decision review_required, merge verdict human_review_required, update_pr: true, and merge: false. There are no release blockers and 20 review items: two findings for each of ten protected paths. Those paths are the Codex skill's advisory workflow asset and the three changed prompts (add-shipgate-to-repo, decide-shipgate-relevance, stabilize-strict-mode) in each of prompts/, skills/agents-shipgate/prompts/, and plugins/claude-code/skills/agents-shipgate/prompts/.
Posting this as a comment review. The validation above does not replace the human trust-root review required by the repository's control result.
Refs #778
Problem
agents-shipgate1.2.0 was published on 2026-10-01 on the advisory channel. Every surface that names the newest release still namedv1.1.0(contract 40):LATEST_PUBLISHED_VERSION/LATEST_PUBLISHED_CONTRACT_VERSION;.well-known'srelease_status.latest_releaseandpackage.github_action;shipgate_versionpins in about 50 examples, docs, skills, plugins and rendered adoption prompts;The README and quickstart still labelled their
diffanswers "not yet released" source-tree output, compared with1.1.0. The pilot ledger's route readiness dry run was a measurement of1.1.0, andtest_design_partner_pilotnow fails until it is re-taken. Several pages and two source comments still called contract v41 anddiff --applicationunreleased.This is
docs/release-runbook.md§ Cutting the release, step 8. It is done only now, after the Release is public (precedents: #777, #853).Design
Constants.
LATEST_PUBLISHED_VERSION = "1.2.0"andLATEST_PUBLISHED_CONTRACT_VERSION = "41". Every other pin follows from what the enumerating tests then required. Moving only the constants failed 108 cases:test_public_surface_contract61;test_distribution_surface_parity38;test_agent_instructions_renderers4;test_host_diff_entry_docs3;test_adopter_pins_resolve1;test_host_only_advisory_recipe1.Rendered prompts and kits. I re-rendered the bundled prompts and CI recipes with the package's own renderer (
render_adoption_kit), not by hand.prompts/,skills/,.agents/skills/and theplugins/mirrors.v1.2.0tag only by1.1.0→1.2.0.tests/test_agent_instructions_renderers.py.82e290ef…,160256b5…,ab28dd4f…,45a9b3bf…,0ece178f…) are the renders thev1.2.0tag carries, so they equal that tag's test pins. They are appended toprior_render_sha256in bothadoption-kits/*/.agents-shipgate-kit-metadata.jsonfiles, so an unmodified install still upgrades.Statements about the newest release.
v1.2.0is described as advisory, contract 41, with no qualification claim.v1.1.0becomes "the previous release".llms.txt, anddocs/ai-search-summary.mdnow gives equal contracts.llms-full.txtwas regenerated withscripts/build-llms-full.py.v1.2.0and the commit it came from.Prose that still said "unreleased". No test enumerates these, so I found them by search:
docs/agent-contract-current.md: "Runtime contract v41, unreleased" (three places) now reads "new in 1.2.0".docs/application-comparison.mdand the README: "until 1.2.0 is published, use a source build" now says it is the newest release and topipx upgradean older install.src/agents_shipgate/schemas/contract.pyandcli/diff.py: comments only. "v41, unreleased" now reads "shipped in 1.2.0", and "extended in place because v41 is unreleased" now reads "…was then unreleased". This one matters, because a comment saying a shipped contract is unreleased invites the next change to extend it in place.Action examples README.
7fc61ef43d8ec5c906bc690765f4a1297dff4fda. That is whatinit --write --cifrom the PyPI 1.2.0 wheel wrote on a scratch copy ofsamples/openapi_only_agent, withshipgate_version: "1.2.0". The wheel's_meta/release-source.jsonnames the same commit.v1.1.0; use the immutable commit … until it is released". fix: log installed engine identity for version-based Actions #892 is inv1.2.0, so the note now says thev1.2.0Action logs it and older tags do not.Entry-page quotes. I re-captured all five documented
diffanswers withagents-shipgate1.2.0.tests/test_host_diff_entry_docs.pybuilds, from inside each clone._PUBLISHED_ANSWERSfor 1.1.0, so the method matches the test's.launch source is mutablenote.agents-shipgate 1.2.0.on everyCompared:/Inputs:line.1.2.0". The1.1.0comparison sentence stays, as "the previous release". "This source tree, and not the published1.1.0" / "Not in1.1.0" became "Since1.2.0".Pilot ledger. I re-ran the route readiness dry run on 2026-10-01 against three builds, each on its own fresh fixture:
./shipgate;Each run executed the runbook's command blocks: the install record, Git-backed Route H
diff, baseline Route H with an out-of-tree snapshot, drift andcheck, and Route Ainitthenverifyin a separate clone. I updated only the factual rows, the published-build line, the matrix, the findings, the blocker-table status line and the build-dated limitation. TheStatus datestays 2026-09-14, because no research observation was re-counted. The standing research decision (2026-09-14, narrow) is unchanged, and its text is the owner's to confirm. I added only a dated factual checkpoint under it. It also notes thatdiff --applicationis a route the runbook does not teach yet.Runbook. Step 8 now names two more steps:
prior_render_sha256;Surface discipline. No public surface is added. This moves existing published-release pins through the one existing rule (
published_release.py), as the runbook prescribes.docs/distribution-surfaces.mdchanges one prose word ("v1.2.0today"); no claim or parity row moves.Deliberately not changed:
.github/release-channels.json, tags and releases.## Unreleasedabove it.rev:pins, left to Offer optional workflow retention after first value; repair the existing pre-commit example pin #796.Tests added
tests/test_host_diff_entry_docs.py::test_the_published_quote_guard_catches_a_stale_capturenow also seeds the labels the pages carried at thev1.2.0tag (README and quickstart, verbatim). Over answers 1.2.0 prints, each must be rejected for comparing with['1.1.0']and for calling published output not yet released. Thev1.1.0-tag controls stay._PUBLISHED_ANSWERSand_PUBLISHED_ANSWERS_VERSION = "1.2.0"are re-recorded from the PyPI wheel. Onlychangemoved; its comment says so.Tests run
init --ci, release pipeline, docs links, release source, packaging, CI recipes, prompt parity, plus the plugin, kit, release and adoption suites. The two skips are documented:1.2.0;ruff check .: clean.-n 10):test_check_unmodelled_host_config_keys.py::test_check_answers_an_unmodelled_settings_key_in_every_format[local_settings_enabled_plugins-*].~/.config/git/ignore) lists**/.claude/settings.local.json, so the fixture'sgit commithas nothing to commit.XDG_CONFIG_HOMEpointed at an empty directory, the whole file passes.Before / after evidence
Entry quotes. Normalized-answer digests per build:
536d404f…(recorded)098d8e27…098d8e27…4735bd24…73d814a7…6be1e130…88531dd0…Pilot dry run (2026-10-01).
contract_version/ host-grants inventorycheck --agent claude-codeblock/critical, 4 violations,host_coverage+excluded_scopesinit --write --civerifycomparable, 6 rowspermission_wideneddiffcomparable, 6 rows, 4 widening;review.summary{changes 4, rows 6, widenings 4}audit_id.Bash(npm test)→Bash(*),Read(src/**)→Read(**)) into an addition and a removal, because a rule for the other tool changed beside it; 1.2.0 joins each into onewidenedchange.WebFetch(*), 1.1.0 still splits both.Post-publication checks
Observed from here on 2026-10-01. Nothing outside this repository was changed by this PR.
v1.2.0is an annotated tag (33f01e6c) that peels to7fc61ef43d8ec5c906bc690765f4a1297dff4fda.info.versionis1.2.0, not yanked,requires_python >=3.12.agents_shipgate-1.2.0-py3-none-any.whl, sha25626ee2a309c7229b90773f0e12cf0d7d4a9e5c247ed1c4bd5f219ac4d1b16dff7, uploaded 2026-10-01T16:49:16Z.pip downloadhashes to the same digest.contract --jsonreportscli_version 1.2.0,contract_version 41,host_grants_inventory_schema_version 0.7andverifier_schema_version 0.21._meta/release-source.jsonnames7fc61ef4….v1.2.0:releases/latestreturns it;draft false,prerelease false,immutable true, published 2026-10-01T16:51:32Z.advisory-statement.json,provenance.jsonandcandidate-manifest.json.v1.0.0. Its release-sync is ThreeMoonsLab/web#55, open with green CI.🤖 Generated with Claude Code