Skip to content

Move the published-release pins to v1.2.0 - #919

Merged
pengfei-threemoonslab merged 1 commit into
mainfrom
claude/pins-1.2.0
Oct 2, 2026
Merged

pengfei-threemoonslab merged 1 commit into
mainfrom
claude/pins-1.2.0

Conversation

@pengfei-threemoonslab

Copy link
Copy Markdown
Contributor

Refs #778

Problem

agents-shipgate 1.2.0 was published on 2026-10-01 on the advisory channel. Every surface that names the newest release still named v1.1.0 (contract 40):

  • LATEST_PUBLISHED_VERSION / LATEST_PUBLISHED_CONTRACT_VERSION;
  • .well-known's release_status.latest_release and package.github_action;
  • the Action, pip, uvx and shipgate_version pins in about 50 examples, docs, skills, plugins and rendered adoption prompts;
  • the channel tables and status lines in the README, quickstart, pilot runbook, FAQ, ROADMAP and llms.txt.

The README and quickstart still labelled their diff answers "not yet released" source-tree output, compared with 1.1.0. The pilot ledger's route readiness dry run was a measurement of 1.1.0, and test_design_partner_pilot now fails until it is re-taken. Several pages and two source comments still called contract v41 and diff --application unreleased.

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" and LATEST_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_contract 61;
  • test_distribution_surface_parity 38;
  • test_agent_instructions_renderers 4;
  • test_host_diff_entry_docs 3;
  • test_adopter_pins_resolve 1;
  • test_host_only_advisory_recipe 1.

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.

  • 13 copies changed: prompts/, skills/, .agents/skills/ and the plugins/ mirrors.
  • The script asserted that each copy differs from the v1.2.0 tag only by 1.1.0 → 1.2.0.
  • The five render hashes move in tests/test_agent_instructions_renderers.py.
  • The outgoing hashes (82e290ef…, 160256b5…, ab28dd4f…, 45a9b3bf…, 0ece178f…) are the renders the v1.2.0 tag carries, so they equal that tag's test pins. They are appended to prior_render_sha256 in both adoption-kits/*/.agents-shipgate-kit-metadata.json files, so an unmodified install still upgrades.

Statements about the newest release.

  • v1.2.0 is described as advisory, contract 41, with no qualification claim.
  • v1.1.0 becomes "the previous release".
  • The "unreleased, ahead of" qualifier is gone from llms.txt, and docs/ai-search-summary.md now gives equal contracts.
  • llms-full.txt was regenerated with scripts/build-llms-full.py.
  • The ROADMAP latest-release line names v1.2.0 and 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.md and the README: "until 1.2.0 is published, use a source build" now says it is the newest release and to pipx upgrade an older install.
  • src/agents_shipgate/schemas/contract.py and cli/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.

  • What runs now names 7fc61ef43d8ec5c906bc690765f4a1297dff4fda. That is what init --write --ci from the PyPI 1.2.0 wheel wrote on a scratch copy of samples/openapi_only_agent, with shipgate_version: "1.2.0". The wheel's _meta/release-source.json names the same commit.
  • The engine-identity log note said it was "not present in historical Action tags such as v1.1.0; use the immutable commit … until it is released". fix: log installed engine identity for version-based Actions #892 is in v1.2.0, so the note now says the v1.2.0 Action logs it and older tags do not.

Entry-page quotes. I re-captured all five documented diff answers with agents-shipgate 1.2.0.

  • It was installed from PyPI into a clean Python 3.13 virtualenv outside any checkout.
  • I ran it on the bare-remote, clone and branches arrangement tests/test_host_diff_entry_docs.py builds, from inside each clone.
  • The same capture run on PyPI 1.1.0 reproduces all five digests already recorded in _PUBLISHED_ANSWERS for 1.1.0, so the method matches the test's.
  • PyPI 1.2.0 and the source tree print identical normalized answers.
  • Against 1.1.0, only the change answer moved: it appends the conditional permission review guidance and the launch source is mutable note.
  • The quoted blocks are the published output verbatim, with fresh commit ids and agents-shipgate 1.2.0. on every Compared: / Inputs: line.
  • "Not yet released" became "Released in 1.2.0". The 1.1.0 comparison sentence stays, as "the previous release". "This source tree, and not the published 1.1.0" / "Not in 1.1.0" became "Since 1.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:

  • PyPI 1.2.0;
  • the source tree via ./shipgate;
  • PyPI 1.1.0.

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 and check, and Route A init then verify in 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. The Status date stays 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 that diff --application is a route the runbook does not teach yet.

Runbook. Step 8 now names two more steps:

  • the render-hash step: re-render, move the hashes, append the outgoing renders to prior_render_sha256;
  • the search for "unreleased" prose that no test enumerates.

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.md changes one prose word ("v1.2.0 today"); no claim or parity row moves.

Deliberately not changed:

Tests added

  • tests/test_host_diff_entry_docs.py::test_the_published_quote_guard_catches_a_stale_capture now also seeds the labels the pages carried at the v1.2.0 tag (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. The v1.1.0-tag controls stay.
  • _PUBLISHED_ANSWERS and _PUBLISHED_ANSWERS_VERSION = "1.2.0" are re-recorded from the PyPI wheel. Only change moved; its comment says so.

Tests run

  • Enumerating, directly affected and adjacent suites: 2571 passed, 2 skipped. This is the precedent's Move the published-release pins to v1.1.0 #853 set: public surface, pins, entry docs, pilot, renderers, distribution parity, fixture, host-only recipe, 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:
    • the rendering-rule skip while source and published are both 1.2.0;
    • the n8n script-parity gap.
  • ruff check .: clean.
  • Full suite locally (-n 10):
    • Every test passed except two cases of test_check_unmodelled_host_config_keys.py::test_check_answers_an_unmodelled_settings_key_in_every_format[local_settings_enabled_plugins-*].
    • Both fail because this machine's global gitignore (~/.config/git/ignore) lists **/.claude/settings.local.json, so the fixture's git commit has nothing to commit.
    • With XDG_CONFIG_HOME pointed at an empty directory, the whole file passes.
    • This is a test-isolation gap independent of this change, tracked separately.
  • CI runs the full suite.

Before / after evidence

Entry quotes. Normalized-answer digests per build:

Answer PyPI 1.1.0 PyPI 1.2.0 Source tree
change 536d404f… (recorded) 098d8e27… 098d8e27…
no change 4735bd24… same same
not compared 73d814a7… same same
cannot compare 6be1e130… same same
no compared grant 88531dd0… same same

Pilot dry run (2026-10-01).

Cell PyPI 1.2.0 Source tree PyPI 1.1.0
contract_version / host-grants inventory 41 / 0.7 41 / 0.7 40 / 0.6
check --agent claude-code block / critical, 4 violations, host_coverage + excluded_scopes same same
init --write --ci exit 0, host audit handoff, no manifest, no workflow same same
manifest-free verify exit 0, comparable, 6 rows same same
drift after out-of-tree base snapshot 6 signals: 4 expansion signals + 2 permission_widened same 4 expansion signals
diff exit 0, comparable, 6 rows, 4 widening; review.summary {changes 4, rows 6, widenings 4} byte-identical 6 rows, 4 widening; {changes 6, rows 6, widenings 4}

Post-publication checks

Observed from here on 2026-10-01. Nothing outside this repository was changed by this PR.

  • Tag: v1.2.0 is an annotated tag (33f01e6c) that peels to 7fc61ef43d8ec5c906bc690765f4a1297dff4fda.
  • PyPI JSON:
    • info.version is 1.2.0, not yanked, requires_python >=3.12.
    • There is one file, agents_shipgate-1.2.0-py3-none-any.whl, sha256 26ee2a309c7229b90773f0e12cf0d7d4a9e5c247ed1c4bd5f219ac4d1b16dff7, uploaded 2026-10-01T16:49:16Z.
    • A fresh pip download hashes to the same digest.
  • Installed wheel: contract --json reports cli_version 1.2.0, contract_version 41, host_grants_inventory_schema_version 0.7 and verifier_schema_version 0.21. _meta/release-source.json names 7fc61ef4….
  • GitHub Release v1.2.0: releases/latest returns it; draft false, prerelease false, immutable true, published 2026-10-01T16:51:32Z.
    • Assets: the wheel, the SBOM, advisory-statement.json, provenance.json and candidate-manifest.json.
    • Sigstore bundles: for the wheel, the SBOM and the statement.
  • External website (owned outside this repository): it still reports v1.0.0. Its release-sync is ThreeMoonsLab/web#55, open with green CI.
  • Immutable PyPI description: the 1.2.0 project description carries the tag's README, including the "not yet released" label this PR removes. It cannot be changed for 1.2.0; the corrected README ships with the next release.

🤖 Generated with Claude Code

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 pengfei-threemoonslab left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.0 is 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 names 7fc61ef43d8ec5c906bc690765f4a1297dff4fda, 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.0 replaced by 1.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 . and git diff --check also 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.

@pengfei-threemoonslab
pengfei-threemoonslab merged commit 0e98f41 into main Oct 2, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant