diff --git a/.agents/skills/agents-shipgate/assets/advisory-pr-comment.yml b/.agents/skills/agents-shipgate/assets/advisory-pr-comment.yml index 0242a3b7..6692ff58 100644 --- a/.agents/skills/agents-shipgate/assets/advisory-pr-comment.yml +++ b/.agents/skills/agents-shipgate/assets/advisory-pr-comment.yml @@ -18,9 +18,9 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: ci_mode: advisory diff_base: target pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index fb9d42cb..4aef62d4 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -11,7 +11,7 @@ body: id: version attributes: label: Agents Shipgate version - placeholder: "v1.1.0" + placeholder: "v1.2.0" validations: required: true - type: dropdown diff --git a/.well-known/agents-shipgate.json b/.well-known/agents-shipgate.json index 70e2c0b3..e293d771 100644 --- a/.well-known/agents-shipgate.json +++ b/.well-known/agents-shipgate.json @@ -73,12 +73,12 @@ ], "package": { "pypi": "agents-shipgate", - "github_action": "ThreeMoonsLab/agents-shipgate@v1.1.0", + "github_action": "ThreeMoonsLab/agents-shipgate@v1.2.0", "github_repo": "ThreeMoonsLab/agents-shipgate" }, "release_status": { "track": "verify-capable release", - "latest_release": "v1.1.0" + "latest_release": "v1.2.0" }, "install": { "pipx": "pipx install agents-shipgate", diff --git a/CHANGELOG.md b/CHANGELOG.md index 7451eb79..5a29361d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Changes + +- Move the published-release pins, examples and adoption prompts to `v1.2.0` (contract 41) now that it is published, re-capture the README and quickstart `diff` answers from the published `1.2.0`, and re-measure the pilot ledger's Route H dry run on it. No schema or contract change. (#778) + ## 1.2.0 - 2026-09-30 An advisory-channel minor release. It adds `diff --application`, which compares diff --git a/README.md b/README.md index 35436384..9b3102a8 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,8 @@ and source locations, in the package that holds the changed code's agents unless `--scope` names one. See [application comparison](docs/application-comparison.md) for scoped applications, moves, exact refs and coverage limits. Version availability is recorded in the [CHANGELOG entry](CHANGELOG.md#application-comparison-without-prior-setup): -it is new in 1.2.0, so until 1.2.0 is published, use a source build containing the feature. +it is new in 1.2.0, the newest published release, so an older install needs +`pipx upgrade agents-shipgate` first. ## What did this PR change? @@ -64,12 +65,13 @@ entry per changed grant or replaced rule. If the PR targets another branch, pass `--base upstream/`. On a PR that widens a Claude Code allow rule, drops a denial and adds an MCP server: -The example below is from this source tree. Its conditional review guidance and -its `launch source is mutable` note are **not yet released**; the published -`1.1.0` prints the same comparison without that guidance section or note. +**Released in `1.2.0`:** the example below is from the published `1.2.0`, +installed from PyPI into a clean virtualenv outside any checkout and run in a +clone. The previous release, `1.1.0`, prints the same comparison without the +conditional review guidance section and the `launch source is mutable` note. ```text -Agent capability diff origin/main (7063f900) -> working tree +Agent capability diff origin/main (5d1b9e23) -> working tree ⚠ high added claude-code .mcp.json billing (command name npx; env keys BILLING_TOKEN) @@ -92,8 +94,8 @@ What this run established: .mcp.json (claude-code): compared; 1 row Review question: Does the team intend these 3 declared capability changes (from 4 rows)? -Compared: base 7063f900 → working tree at HEAD ac6fbdcf, agents-shipgate 1.1.0. -Reproduce in that working tree: agents-shipgate diff --base 7063f90046e90a1673fe98f993cb77f7063ef396 +Compared: base 5d1b9e23 → working tree at HEAD 58d2ac0c, agents-shipgate 1.2.0. +Reproduce in that working tree: agents-shipgate diff --base 5d1b9e236525699910f4d93e334d2f4425927062 Permission review guidance: Conditional review choices only; current control permissions still apply. A PR note grants no authority. - Change 2: .claude/settings.json @@ -119,8 +121,8 @@ like these; `No static host-grant changes detected.` when no compared grant differs; or `Cannot compare against : ` when an input could not be read, which is an input limit and never a quiet pass. Either of the first two can open with `Not compared:` and a list of sources the change did not touch -and `diff` could not read; nothing is claimed about those. This source tree, -and not the published `1.1.0`, also has a fourth answer, `Partial comparison +and `diff` could not read; nothing is claimed about those. Since `1.2.0` there +is also a fourth answer, `Partial comparison against …: `, where the only inputs it could not read are plugin directories whose references stop inside them: it names each one as `Not compared: `, shows the changes outside it, and says they are @@ -131,8 +133,8 @@ each gave, which changed with no compared grant changing (so a zero-row `env` or `apiKeyHelper` edit is not mistaken for no change: a file is unchanged only when its bytes are), which changed with no row attributed to them, which only one side read or published, and, when -the comparison was refused, which source left an inventory incomplete. This -source tree, and not the published `1.1.0`, also names a changed input that a +the comparison was refused, which source left an inventory incomplete. Since +`1.2.0` it also names a changed input that a bounded, documented candidate list recognises but no reader of this entry reads — a plugin's `mcp.json`, a plugin manifest's `mcpServers`, `.cursor/hooks.json`, a nested `.claude/settings.json`, an external marketplace @@ -158,9 +160,7 @@ answer, the `--base ` recovery when no base can be detected, and the Supported shell changes then add conditional human choices. They establish no intent or runtime access and grant no authority. The `launch source is mutable` note identifies the unversioned `npx` package declared by the added server; it -changes neither the row's severity nor the widening count. The source tree still -reports version `1.2.0`; that version string does not make this a published-wheel -capture. +changes neither the row's severity nor the widening count. When the answer is useful and you want it on every pull request, add [`examples/github-actions/14-host-only-advisory-pr.yml`](examples/github-actions/14-host-only-advisory-pr.yml): @@ -237,7 +237,7 @@ projection of it. Five-minute version: Host configuration alone needs none of this: [What did this PR change?](#what-did-this-pr-change) is the whole route. [Route H](docs/quickstart.md#route-h--no-manifest) adds a snapshot audit and an -optional committed baseline for jobs that want them, and `v1.1.0`'s discovery +optional committed baseline for jobs that want them, and `v1.2.0`'s discovery routes host-only repositories there through `host_boundary_candidates`. Filename detection never establishes verified permissions. @@ -282,7 +282,7 @@ declared and statically discoverable surface says. See [Limitations](#limitations) and [ROADMAP.md](ROADMAP.md). > [!IMPORTANT] -> **Status: `v1.1.0`, advisory.** The published release makes no qualification +> **Status: `v1.2.0`, advisory.** The published release makes no qualification > claim. Its defaults are advisory, and blocking CI is a policy you opt into > explicitly. The decision engine is deterministic; the accuracy evidence is > small-n and incomplete, and the parts below their bars are stated here rather @@ -319,7 +319,7 @@ no-op over one. Alternatives — `pip`, `uv`, and zero-install `uvx` — are in **not** need Python 3.12; the CLI installs separately. **Two lines, two promises.** The advisory line publishes rows a reviewer -reads, and no authority to block anything by default; `v1.1.0` is an advisory +reads, and no authority to block anything by default; `v1.2.0` is an advisory release. The gate line publishes blocking verdicts and keeps every qualification bar. Each `v*` version is declared on exactly one line in [`.github/release-channels.json`](.github/release-channels.json). Neither line @@ -330,16 +330,17 @@ two months out of reach. | Line | Carries | Install | Promises | Cadence | | --- | --- | --- | --- | --- | -| **Advisory** | `diff`, `check`, `audit --host`, drift, advisory PR comments | `pipx install agents-shipgate` (`v1.1.0`), or an unqualified preview pre-release | plain-language capability rows; **no blocking authority** unless you configure a blocking policy | 14 days | -| **Qualified gate** | blocking verdicts backed by qualification evidence, receipts, attestations | a `v*` release declared on the qualified line; `v1.1.0` is not one | every bar in [`release-evidence-policy-decision.md`](docs/release-evidence-policy-decision.md) | on evidence only | +| **Advisory** | `diff`, `check`, `audit --host`, drift, advisory PR comments | `pipx install agents-shipgate` (`v1.2.0`), or an unqualified preview pre-release | plain-language capability rows; **no blocking authority** unless you configure a blocking policy | 14 days | +| **Qualified gate** | blocking verdicts backed by qualification evidence, receipts, attestations | a `v*` release declared on the qualified line; `v1.2.0` is not one | every bar in [`release-evidence-policy-decision.md`](docs/release-evidence-policy-decision.md) | on evidence only | **Read [which build you get](docs/quickstart.md#which-build-you-get) before you -start.** The newest published release is `v1.1.0`, which implements runtime -contract `40` — the agent control envelope, `current-control.json` and +start.** The newest published release is `v1.2.0`, which implements runtime +contract `41` — the agent control envelope, `current-control.json` and `--format agent-boundary-json` included — and is what `pipx install agents-shipgate` installs. It ships on the advisory channel and makes no -qualification claim. The quickstart says what an older `v1.0.0` or `v0.15.0` -install lacks, and what the unqualified preview does and does not come with. +qualification claim. The quickstart says what an older `v1.1.0`, `v1.0.0` or +`v0.15.0` install lacks, and what the unqualified preview does and does not +come with. ## Where to go next diff --git a/ROADMAP.md b/ROADMAP.md index 3ec6ad83..c2723e13 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,10 +2,10 @@ > **Naming.** This project is **Agents Shipgate** (display name) / `agents-shipgate` (package, CLI, repo). See [`AGENTS.md` § Naming (canonical)](AGENTS.md#naming-canonical) for the full convention. -**Latest release: `v1.1.0`** +**Latest release: `v1.2.0`** ([release page](https://github.com/ThreeMoonsLab/agents-shipgate/releases/latest)) -— a legibility and presentation-correctness release on the **advisory** channel -with no qualification claim. This line is checked against the +— the release that adds application comparison (`diff --application`) on the +**advisory** channel, with no qualification claim. This line is checked against the actual release tag by the `release-tag-consistency` job in [`ci.yml`](.github/workflows/ci.yml) on every push to `main`. @@ -70,8 +70,9 @@ follows the [non-goals](#explicit-non-goals) and **Adoption > completeness.** `v1.0.0` is published on PyPI and GitHub from `bace7c1871834e0b3eb98e6f60c0627725c53a59`, and #777 moved the pins to it. `v1.1.0` followed on 2026-09-22 from -`e3c6cb0c7657d9c53d4e29b2061d04dcf99a4e9b` on the same channel, and the current -pins name it. The `v1.0.0` [advisory statement](https://github.com/ThreeMoonsLab/agents-shipgate/releases/download/v1.0.0/advisory-statement.json) +`e3c6cb0c7657d9c53d4e29b2061d04dcf99a4e9b` and `v1.2.0` on 2026-10-01 from +`7fc61ef43d8ec5c906bc690765f4a1297dff4fda`, both on the same channel; the +current pins name `v1.2.0`. The `v1.0.0` [advisory statement](https://github.com/ThreeMoonsLab/agents-shipgate/releases/download/v1.0.0/advisory-statement.json) records advisory defaults, blocking opt-in and no qualification claim. That publication supersedes the pre-release sequencing in the historical record below; it does not satisfy the separate qualified-gate obligations in #572. diff --git a/adoption-kits/claude-code-skill/.agents-shipgate-kit-metadata.json b/adoption-kits/claude-code-skill/.agents-shipgate-kit-metadata.json index 89591b31..89c915e5 100644 --- a/adoption-kits/claude-code-skill/.agents-shipgate-kit-metadata.json +++ b/adoption-kits/claude-code-skill/.agents-shipgate-kit-metadata.json @@ -85,7 +85,8 @@ "ffe9272f9a0defd732a9a37dbc1e9450e6051b217d6a39741b835657470f6cb4", "a1d1ef2e4f1a4d8fe0f1e57b7c1c71aca0beb8d7bd2bc87063840fec59b6ad32", "9ac853f0d5eabd1e79812c74587d9af27916309e7ad3154ff880fc3e8b9ff5fc", - "ae1495dc5c950baac583813076c59bb602dc42f84c39a6f4b32b7c4250f4728f" + "ae1495dc5c950baac583813076c59bb602dc42f84c39a6f4b32b7c4250f4728f", + "160256b5892d5fb18a0e66250f2eee08be7abf2e2d1473e2112d29ad747a7223" ], "prompts/stabilize-strict-mode.md": [ "ac9a176738ab2538d725c29ba302637bac6b287588e07d952aae352f85ab98cc", @@ -93,7 +94,8 @@ "12810569a6aa655b4d8a6ed384142a430eef367bf6fab51b1a9e614aeff1c1a8", "db9a702784c64229ed15157ce369c90a3d75c02e82c78d2c39cc55135857dc80", "00da293e63792ccaf980f82d525ac12073807f41fd2d78c5a95498054053e364", - "f6e00cc67cd064721358361f2f47e9b68cb55359642419e6c978f5cb474c7fef" + "f6e00cc67cd064721358361f2f47e9b68cb55359642419e6c978f5cb474c7fef", + "45a9b3bfcd41aa616f74644f52c95abf4d146ca30164276ff4954ddf0ab7b314" ], "prompts/verify-agent-diff.md": [ "0c939414da7900b8f03f2a743e0f6b8f4d96f409c1d5cde038e27a98318bf486", @@ -117,7 +119,8 @@ "b6f87f58f70b5920442f342b5118419ef685ad9f4ff8b0ff87c2729a92929786", "7fd2c718e5dad94b231409a72710e05af1b231c3d495d8796c501a7e9493a394", "52c23e0b713d8064129332553350cb61d9e2b5254ed8f53ed99457cc3bc8c8f7", - "73576619d8d140935949f1ca2b7ccbcea8109ad3546f649b53cd2d3e71cb6672" + "73576619d8d140935949f1ca2b7ccbcea8109ad3546f649b53cd2d3e71cb6672", + "82e290efca0d7c11f7bcc86d054290ddc9566101cd3d66c9e3eb9a18ba23ae79" ], "prompts/decide-shipgate-relevance.md": [ "1bf8b9d91f081a246dcff14a84810ca5384f8e0987e4e7a8c0c5df56b151564c", @@ -136,7 +139,8 @@ "4f92d6d0b254e602c993516e1dc5b77c64c87b3e7b5cb4967ddd5a140dd2d510", "cbdb4868a68b76c4e46611e8718ebe9950e6b1088e87691c7b23b82d3b1476d9", "be3079a2f41b66d2db19cfea14c57ccd80ab9047ef7d69eccf30e97fa1beca5b", - "0f4285d7261dbaaab5a201061d9e2187d57e6d2af839fbfb170eae0630acaa62" + "0f4285d7261dbaaab5a201061d9e2187d57e6d2af839fbfb170eae0630acaa62", + "ab28dd4fd777e1ff1100fdd343d39eeb5ba5831295e0cf7435cda7fb61d2e01f" ], "prompts/fix-top-finding.md": [ "3745aebbf34a47c01b06e74e6d387080bbda9272f0aeec6998457cffa758fc54", diff --git a/adoption-kits/codex-skill/.agents-shipgate-kit-metadata.json b/adoption-kits/codex-skill/.agents-shipgate-kit-metadata.json index 6e209e32..e3e6376f 100644 --- a/adoption-kits/codex-skill/.agents-shipgate-kit-metadata.json +++ b/adoption-kits/codex-skill/.agents-shipgate-kit-metadata.json @@ -66,7 +66,8 @@ "0ac78bcb69d0bfbcb72a8b78e013f00778536ce2600cf363fb27beeff66892a9", "7ef7ccb331a0171f0fb5580df4dad32003b230b150886a40d317a954ace0fb55", "89580914407edd5516db10c8d7725f22c1a919e827e9b820115007a7a6caab31", - "fc819304ad838e4976e92afe64eba20289772360e7c23bd99588d3e88019a2a2" + "fc819304ad838e4976e92afe64eba20289772360e7c23bd99588d3e88019a2a2", + "0ece178f492d7590713529539c009d30faedb29cfb111abb5cdfd9eec7ac7006" ] }, "bootstrap_legacy_sha256": { diff --git a/docs/agent-contract-current.md b/docs/agent-contract-current.md index 464e4273..7feae268 100644 --- a/docs/agent-contract-current.md +++ b/docs/agent-contract-current.md @@ -1,6 +1,6 @@ # Current Agent Contract -Runtime contract v41, unreleased, names the changed inputs a host comparison +Runtime contract v41, new in 1.2.0, names the changed inputs a host comparison does not read (#821). A zero-row comparison used to print "No static host-grant changes detected" for a pull request that added a Cursor plugin's `mcp.json` or moved a marketplace plugin's pinned `sha`, exactly as for a @@ -28,7 +28,7 @@ file this entry reads. `minimum_control_contract_version` stays `21`, and a `0.20` verifier reads with the search not recorded. See [the migration note](../STABILITY.md#unread-changed-inputs-821). -Still contract v41, unreleased: a plugin directory a host comparison cannot +Still contract v41, new in 1.2.0: a plugin directory a host comparison cannot compare no longer hides the changes outside it (#808). Where every blocking limit that refused the comparison is a plugin-reference limit bounded by its plugin directory, and no compared source depends on that directory, verifier @@ -91,7 +91,7 @@ comparable. It moves neither #821's verifier `0.21` nor its capability diff `0.4`, and `minimum_control_contract_version` stays `21`. See [the migration note](../STABILITY.md#workflow-agent-launches-contract-v41-823). -The same unreleased runtime contract v41 also names what changed in a hook and +The same runtime contract v41, new in 1.2.0, also names what changed in a hook and in an MCP server's launch arguments (#819). Host-grants inventory, baseline and drift schemas move to `0.7`: a hook grant adds `handlers[]` (each handler's group `matcher`, its `command` as `{executable, sha256}` and its `timeout`) @@ -775,7 +775,7 @@ Downstream repos generated with `init --agent-instructions=default` get the minimal local copy at `.shipgate/agent-contract.json`. -- Latest release: `v1.1.0` +- Latest release: `v1.2.0` - In-tree runtime: `1.2.0` — see [pyproject.toml](../pyproject.toml) - Runtime contract: `41` (minimum control contract: `21`) - Current report schema: `1.0`, frozen, superseding `0.43` — [`docs/report-schema.v1.0.json`](report-schema.v1.0.json); the `1.x` rules are in [`docs/report-1-0-contract.md`](report-1-0-contract.md) diff --git a/docs/ai-search-summary.md b/docs/ai-search-summary.md index 25549e13..567759cc 100644 --- a/docs/ai-search-summary.md +++ b/docs/ai-search-summary.md @@ -113,9 +113,9 @@ Per-agent guides cover [Codex](agents/use-with-codex.md), [Claude Code](agents/use-with-claude-code.md), and [Cursor](agents/use-with-cursor.md). -The current source tree is `1.2.0` (runtime contract 41, unreleased). The -latest published release is `v1.1.0` (runtime contract 40), on the advisory -channel with no qualification claim. In report v1.0, +The current source tree is `1.2.0` (runtime contract 41). The latest +published release is `v1.2.0` (runtime contract 41), on the advisory channel +with no qualification claim. In report v1.0, `passed` is an evidence-backed static verdict: the configured root has a complete reachable binding graph, every reachable action has complete, conflict-free identity, binding, effect, and authority evidence, all applicable diff --git a/docs/application-comparison.md b/docs/application-comparison.md index c9d411a3..5313a139 100644 --- a/docs/application-comparison.md +++ b/docs/application-comparison.md @@ -1,8 +1,8 @@ # Application comparison without prior setup -**Availability:** new in 1.2.0; see the [CHANGELOG entry](../CHANGELOG.md#application-comparison-without-prior-setup). -Until 1.2.0 is published, run the source checkout's `./shipgate` or a build -containing the feature. +**Availability:** new in 1.2.0, the newest published release; see the +[CHANGELOG entry](../CHANGELOG.md#application-comparison-without-prior-setup). +An older install has no `--application`: `pipx upgrade agents-shipgate`. For an OpenAI Agents SDK or Google ADK application, compare committed PR refs: diff --git a/docs/design-partner-pilot-results.md b/docs/design-partner-pilot-results.md index 1015b6a4..4a6a2548 100644 --- a/docs/design-partner-pilot-results.md +++ b/docs/design-partner-pilot-results.md @@ -63,19 +63,45 @@ allow list from `Bash(npm test)` / `Read(src/**)` to `Bash(*)` / `Read(**)` / `WebFetch(*)` and adds a remote MCP server `payments-remote`. That is the capability-change class this pilot exists to observe. -**Published build measured: `1.1.0`.** Preview measured: -`0.16.0+preview.20260903.gb61aca7`. Source tree: `1.2.0`, runtime contract 41: only this label moved with the -1.2.0 version bump, and the source-tree cells below were not re-measured for it. -The released and source-tree columns were both rerun on 2026-09-22, after -`v1.1.0` was published: the released column from `pip install -agents-shipgate==1.1.0` in a clean virtualenv outside any checkout (the wheel -PyPI serves, sha256 -`038bdb4650d45d9c81996f60d33781b5671bfb57f006233f80e74db8a7377d33`), the +**Published build measured: `1.2.0`.** Preview measured: +`0.16.0+preview.20260903.gb61aca7`. Source tree: `1.2.0`, runtime contract 41. +The released and source-tree columns were both rerun on 2026-10-01, after +`v1.2.0` was published, each on its own fresh fixture: the released column from +`pip install agents-shipgate==1.2.0` in a clean virtualenv outside any checkout +(the wheel PyPI serves, sha256 +`26ee2a309c7229b90773f0e12cf0d7d4a9e5c247ed1c4bd5f219ac4d1b16dff7`), the source-tree column through `./shipgate`. The preview column retains its 2026-09-05 measurement and was not relabeled as a new run. The baseline was recorded on the fixture base, to a file outside the repository, before the permission change, so it was not itself under review. +The two returned identical cells, version numbers included — runtime contract +41 and host-grant inventory schema 0.7: `check` blocking with four violations +and visible coverage, the host-only `init` handoff with no manifest or workflow +written, manifest-free `verify` exiting 0 with six advisory rows, drift naming +six expansion signals, and `diff` against the fixture base exiting 0 with +`comparison_status: comparable` and six rows, four of them widening. Every +output was byte-identical apart from the workspace path, the fixture's commit +ids, the launcher name in printed commands and the boundary result's +`audit_id`. + +The previous release, `v1.1.0`, was rerun the same way on 2026-10-01, from +`pip install agents-shipgate==1.1.0` in its own clean virtualenv. It returned +the same `check`, `init` and `verify` cells and the same six `diff` rows, four +widening, at runtime contract 40 and inventory schema 0.6. Two readings differ, +both from #858. `1.1.0` prints each of the two replaced allow rules, +`Bash(npm test)` → `Bash(*)` and `Read(src/**)` → `Read(**)`, as a separate +addition and removal, because a rule for the other tool changed beside it; +`1.2.0` joins each into one `widened` change, so its `review.summary` counts 4 +changes from 6 rows, 4 widening, against `1.1.0`'s 6 from 6. And `1.2.0`'s +drift names those two replacements as `permission_widened` signals beside the +four expansion signals `1.1.0` names (`mcp_server_added` and three +`wildcard_allow_added`). On this fixture `1.2.0` changes how the rows read as +changes, not which rows it finds. + +The paragraphs below record the earlier runs, on 2026-09-22 and 2026-09-23, +while `1.1.0` was the newest release. + Before #821, the published and source-tree runs returned identical cells, version numbers included — runtime contract 40 and host-grant inventory schema 0.6: `check` blocking with four violations and visible coverage, the host-only @@ -139,25 +165,26 @@ with 0 violations and no coverage surface; `init --write --ci` pinned `@v0.15.0`; `init` then `verify` exited 3; baseline/drift named all four expansion signals. It shipped as a qualified release. -| | Released `v1.1.0` (`pip install`) | Preview `0.16.0+preview.20260903` (`gh release download`) | Source tree | +| | Released `v1.2.0` (`pip install`) | Preview `0.16.0+preview.20260903` (`gh release download`) | Source tree | | --- | --- | --- | --- | -| Runtime contract | 40 | 29 | 41 | -| Host-grant inventory schema | 0.6 | 0.2 | 0.7 | +| Runtime contract | 41 | 29 | 41 | +| Host-grant inventory schema | 0.7 | 0.2 | 0.7 | | `check` on the fixture | `block` / `critical`, **4 violations** | `block` / `critical`, **4 violations** | `block` / `critical`, **4 violations** | | Coverage limit visible (`host_coverage`, `excluded_scopes`) | yes | yes | yes | | `init --write --ci` Action pin | not applicable — host audit handoff, no workflow written | `@v0.16.0+preview.20260903.gb61aca7` — **no such tag** (the release tag is `preview-`-prefixed) | not applicable — host audit handoff, no workflow written | | `init` then `verify` on this Route H repo | `init` exits 0 with audit handoff; manifest-free `verify` exits 0 and names six advisory change rows | exit 2 | `init` exits 0 with audit handoff; manifest-free `verify` exits 0 and names six advisory change rows | -| `audit --host --save-baseline` → `--drift` | works, all 4 expansion signals | works | works, all 4 expansion signals | -| `diff` against the fixture base (Git-backed Route H) | exit 0, `comparable`, 6 rows, 4 widening | not measured | exit 0, `comparable`, the same 6 rows | +| `audit --host --save-baseline` → `--drift` | works, all 4 expansion signals, plus 2 `permission_widened` | works | works, the same 6 signals | +| `diff` against the fixture base (Git-backed Route H) | exit 0, `comparable`, 6 rows, 4 widening, read as 4 changes | not measured | exit 0, `comparable`, the same 6 rows and 4 changes | | Qualification | **none** — advisory channel, no qualification claim | **none** — no adjudicated corpus, nothing signed | not a distributed build | -Every rerun on 2026-09-22 and 2026-09-23 reproduced four boundary violations (`block` / +Every rerun on 2026-09-22, 2026-09-23 and 2026-10-01 reproduced four boundary violations (`block` / `critical`) and visible coverage. `init --write --ci` writes no manifest or workflow and routes the host-only fixture to the read-only audit route. Manifest-free `verify` now succeeds as an advisory comparison: six rows name three added permissions, two removed narrower rules, and the added MCP server. It publishes no application release decision or merge authority. Baseline/drift -reproduced all four expansion signals with a canonical +reproduced all four expansion signals, beside `1.2.0`'s two `permission_widened` +signals, with a canonical non-symlink temporary path. The earlier run discovered the documented `/tmp/` recovery-path problem on macOS; #550 was subsequently fixed by #595. This run uses the canonical path and does not add a new recovery-path observation. @@ -166,25 +193,27 @@ No reviewer, retention or qualification result is inferred from this rerun. Four things follow, and each one is a fact about a build rather than a judgement about a partner. -1. **The published release shows the change.** `v1.1.0`, installed with +1. **The published release shows the change.** `v1.2.0`, installed with `pip install agents-shipgate`, returns `block` / `critical` with four violations and carries the coverage surface, and manifest-free `verify` names six advisory rows, so it can deliver all four first-value recognitions. It is advisory and makes no qualification claim, which is a thing to say out loud to a partner rather than a footnote. -2. **The previous release shows it too; an older one could not.** - `v1.0.0` returns the same cells and the same six rows, without the - dispositions and the `review` and `coverage` blocks. `v0.15.0` returned +2. **The previous releases show it too; an older one could not.** + `v1.1.0` returns the same cells and the same six rows, printing each + replaced allow rule as a separate addition and removal. `v1.0.0`, measured + on 2026-09-22, also returns them, without the dispositions and the `review` + and `coverage` blocks. `v0.15.0` returned `warn` / `none` with zero violations on a diff that grants `Bash(*)`, with no coverage surface at inventory schema 0.1. A partner still on it reaches three of the four recognitions through the baseline/drift pair and cannot reach the fourth; `pipx upgrade agents-shipgate` closes that gap. 3. **#506's repair has reached a downloadable build.** The published - `v1.1.0` writes no workflow for this host-only fixture, and where it does + `v1.2.0` writes no workflow for this host-only fixture, and where it does generate CI it pins the source commit it was released from — on - 2026-09-22, `init --write --ci` on a copy of `samples/openapi_only_agent` - wrote `@e3c6cb0c7657d9c53d4e29b2061d04dcf99a4e9b` with - `shipgate_version: "1.1.0"`. The preview wheel cut on 2026-09-03 still + 2026-10-01, `init --write --ci` on a copy of `samples/openapi_only_agent` + wrote `@7fc61ef43d8ec5c906bc690765f4a1297dff4fda` with + `shipgate_version: "1.2.0"`. The preview wheel cut on 2026-09-03 still writes `@v0.16.0+preview.20260903.gb61aca7`, which resolves to nothing; for this route the published release supersedes it. 4. **The published release no longer dead-ends through manifest setup.** @@ -273,17 +302,18 @@ request, and none opened a new issue. Status is as of 2026-09-05, after [#506](https://github.com/ThreeMoonsLab/agents-shipgate/issues/506), [#485](https://github.com/ThreeMoonsLab/agents-shipgate/issues/485) and [#497](https://github.com/ThreeMoonsLab/agents-shipgate/issues/497) merged, -rechecked on 2026-09-14 against the published `v1.0.0`, and again on -2026-09-22 against the published `v1.1.0`, which returned the same statuses. +rechecked on 2026-09-14 against the published `v1.0.0`, on 2026-09-22 against +the published `v1.1.0`, and on 2026-10-01 against the published `v1.2.0`, which +returned the same statuses. | Reproduced | Existing issue | Status | | --- | --- | --- | | `init --write --ci` pinned a workflow to a tag that does not exist | [#506](https://github.com/ThreeMoonsLab/agents-shipgate/issues/506) | **Fixed in `v1.0.0`** — generated CI pins the released source commit, and this host-only fixture writes no workflow. The 2026-09-03 preview predates the fix and still writes a ref that resolves to nothing | | The released build's `check` returns `warn` / `none` on a host-boundary change the tree blocks; released and in-tree evaluators disagree | [#497](https://github.com/ThreeMoonsLab/agents-shipgate/issues/497) | **Resolved in `v1.0.0`** — the published `check` returns `block` / `critical` with 4 violations on this fixture, matching the tree | | The released build's `check --agent claude-code` reports "No **Codex** boundary rule fired" — the pre-multi-host evaluator | [#497](https://github.com/ThreeMoonsLab/agents-shipgate/issues/497), [#506](https://github.com/ThreeMoonsLab/agents-shipgate/issues/506) | Superseded in `v1.0.0` by the multi-host evaluator, which blocks this fixture; only `v0.15.0` carries the old evaluator | -| The released build's host inventory carries no coverage or excluded-scopes surface, so a reviewer cannot see what was not read | [#520](https://github.com/ThreeMoonsLab/agents-shipgate/issues/520) | Present since `v1.0.0` (inventory schema 0.5; 0.6 in `v1.1.0`), and on the preview at 0.2; #520 stays open for its wider scope | +| The released build's host inventory carries no coverage or excluded-scopes surface, so a reviewer cannot see what was not read | [#520](https://github.com/ThreeMoonsLab/agents-shipgate/issues/520) | Present since `v1.0.0` (inventory schema 0.5; 0.6 in `v1.1.0`; 0.7 in `v1.2.0`), and on the preview at 0.2; #520 stays open for its wider scope | | A `review_required` result has no authenticated continuation | [#504](https://github.com/ThreeMoonsLab/agents-shipgate/issues/504) → [#337](https://github.com/ThreeMoonsLab/agents-shipgate/issues/337) | Open | -| `init` then `verify` dead-ends on a repository with no tool surface | [#498](https://github.com/ThreeMoonsLab/agents-shipgate/issues/498) | `v1.0.0` and `v1.1.0` route this host-only fixture to audit and manifest-free `verify` exits 0; the preview still dead-ends. #498 owns the manifest route — "do not make policy authoring a universal prerequisite" — and this runbook mitigates it meanwhile by routing those partners to Route H | +| `init` then `verify` dead-ends on a repository with no tool surface | [#498](https://github.com/ThreeMoonsLab/agents-shipgate/issues/498) | `v1.0.0`, `v1.1.0` and `v1.2.0` route this host-only fixture to audit and manifest-free `verify` exits 0; the preview still dead-ends. #498 owns the manifest route — "do not make policy authoring a universal prerequisite" — and this runbook mitigates it meanwhile by routing those partners to Route H | | The runbook required a manifest on a route that does not need one | [#498](https://github.com/ThreeMoonsLab/agents-shipgate/issues/498) | Fixed in this runbook | | The runbook required a contract floor no published build carries | [#497](https://github.com/ThreeMoonsLab/agents-shipgate/issues/497) | Fixed in this runbook and, independently, by #497's channel table | @@ -347,6 +377,17 @@ blocks — so the dry run above was re-dated against it before being cited here. Whether the channel line moves to `v1.1.0` is the owner's question, not this ledger's. This checkpoint adds no observation, and no denominator moves. +**Checkpoint — 2026-10-01.** This records facts; it does not change the +decision above, whose text stays with its owner to confirm. `v1.2.0` is +published on the advisory channel with no qualification claim, and `pipx +install agents-shipgate` now installs it. It changes what `diff` reports on +this change class: the same six rows, with each replaced allow rule read as one +`widened` change (4 changes, not 6), and drift adds two `permission_widened` +signals. So the dry run above was re-dated against it before being cited here. +It also adds `diff --application`, a route the runbook does not yet teach. +Whether the channel line moves is the owner's question, not this ledger's. +This checkpoint adds no observation, and no denominator moves. + ## Standing decision — 2026-09-05: **narrow** Superseded for the advisory Route H experiment by the 2026-09-14 decision @@ -412,9 +453,9 @@ Every denominator is still 0. - **The dry run is one synthetic fixture on one machine**, by a maintainer who knows the answers. It shows what a command emits; it cannot show what a stranger understands. -- **Findings are build-dated.** They describe four builds as they stood on - 2026-09-22 for the released `1.1.0`, the previous release `1.0.0` and this - source tree, and 2026-09-05 for the preview +- **Findings are build-dated.** They describe five builds as they stood on + 2026-10-01 for the released `1.2.0`, the previous release `1.1.0` and this + source tree, 2026-09-22 for `1.0.0`, and 2026-09-05 for the preview `0.16.0+preview.20260903.gb61aca7`. A release or a new preview invalidates the comparison, and the dry run must be re-run and re-dated before any row here is cited again. A standing guard fails the diff --git a/docs/design-partner-verifier-pilot.md b/docs/design-partner-verifier-pilot.md index 6c146c13..dbcf4613 100644 --- a/docs/design-partner-verifier-pilot.md +++ b/docs/design-partner-verifier-pilot.md @@ -5,7 +5,7 @@ repositories through an actual review workflow: someone introduces a capability or permission change, someone else reviews it, and the next eligible change tests whether the integration stayed useful. -It teaches the loop the newest published release, `v1.1.0`, runs — settle +It teaches the loop the newest published release, `v1.2.0`, runs — settle [which build a partner is on](#which-build-this-runbook-is-for) and [which route their repository is on](#routes-under-test) before you quote a command at them. Those two choices decide what the partner can see, and both @@ -59,15 +59,15 @@ that workflow. Do not recruit for Route A to balance the cohort. The read order, the tracker and the agent prompt below all name `control.state` and `control.next_action.actor`. Those come from the agent-control envelope, -which the newest published release, `v1.1.0`, carries, as did the previous -one, `v1.0.0`. The older `v0.15.0` predates it — and has no `diff`, the +which the newest published release, `v1.2.0`, carries, as did the previous +ones, `v1.1.0` and `v1.0.0`. The older `v0.15.0` predates it — and has no `diff`, the Git-backed Route H command — so a partner still on that build cannot follow this runbook end to end — and saying so is part of the instructions rather than a footnote: | Channel | How a partner gets it | Runtime contract | Emits `control.*`? | Qualification | | --- | --- | --- | --- | --- | -| Published release `v1.1.0` | `pipx install agents-shipgate` | 40 | Yes | **None.** Declared `advisory` in `.github/release-channels.json`; see [`release-evidence-policy-decision.md`](release-evidence-policy-decision.md) § Amendment 5 | +| Published release `v1.2.0` | `pipx install agents-shipgate` | 41 | Yes | **None.** Declared `advisory` in `.github/release-channels.json`; see [`release-evidence-policy-decision.md`](release-evidence-policy-decision.md) § Amendment 5 | | Unqualified preview | `gh release download preview- --repo ThreeMoonsLab/agents-shipgate --pattern '*.whl'`, then `pip install ./` | that of the source commit it was cut from | Yes | **None.** No adjudicated corpus, no qualification artifact, nothing signed — see [`release-evidence-policy-decision.md`](release-evidence-policy-decision.md) § Amendment 2 | | Source checkout | `git clone`, then `./shipgate …` from the checkout | that of the checkout | Yes | Not a distributed build | @@ -326,8 +326,8 @@ the first observation of the run, not preamble. `verify` and `feedback export` are present in every channel, including the released build. The runbook's **read order** is what needs the newer contract: `control.state` requires the agent-control envelope, which the released -`v1.1.0` (contract 40) and `v1.0.0` (contract 39) emit and the older -`v0.15.0` (contract 10) does not. So a partner still on `v0.15.0` either +`v1.2.0` (contract 41), `v1.1.0` (contract 40) and `v1.0.0` (contract 39) emit +and the older `v0.15.0` (contract 10) does not. So a partner still on `v0.15.0` either upgrades or reads `controller` / `gate` instead — do not quote a contract floor the build they have installed cannot reach. @@ -459,8 +459,8 @@ reviewed is the coding-host configuration. ## Read Order Route A — read `agents-shipgate-reports/agent-handoff.json` first. This order -needs a build that emits the agent-control envelope (the released `v1.1.0` or -`v1.0.0`, a preview, or a source checkout); on the older `v0.15.0`, start at +needs a build that emits the agent-control envelope (the released `v1.2.0`, +`v1.1.0` or `v1.0.0`, a preview, or a source checkout); on the older `v0.15.0`, start at step 2 and read `controller` in place of `control`: 1. `control.state` @@ -496,7 +496,7 @@ suppression, or policy-weakening evidence. Paste this into the partner's coding agent from the target repo root, with the install line for the channel you settled above — the block below carries the released one. Step 4 names the agent-control envelope, which the released -`v1.1.0` and `v1.0.0` carry; on the older `v0.15.0` there is none, so the +`v1.2.0`, `v1.1.0` and `v1.0.0` carry; on the older `v0.15.0` there is none, so the agent reads `controller` and `gate` instead. The ownership boundary in step 4 is the rule either way: on a build with the envelope the tool enforces it, and on one without it, nothing but the diff --git a/docs/distribution-surfaces.md b/docs/distribution-surfaces.md index 55f936c4..a54a8746 100644 --- a/docs/distribution-surfaces.md +++ b/docs/distribution-surfaces.md @@ -146,7 +146,7 @@ says which input postdates the release and what to do once one carries it. `DECLARED_UNPINNED_REFS` enumerates these, and is empty today: `examples/github-actions/10-check-run-annotations.yml` targeted `@main` until `v1.0.0` carried `check_run_policy`, and has pinned the newest published -release since — `v1.1.0` today. The guard checks that the file really uses that ref and really explains itself, so an +release since — `v1.2.0` today. The guard checks that the file really uses that ref and really explains itself, so an unexplained `@main` elsewhere is still the defect it looks like. ## Release channels diff --git a/docs/distribution.md b/docs/distribution.md index 41fae730..e5cd3b94 100644 --- a/docs/distribution.md +++ b/docs/distribution.md @@ -6,7 +6,7 @@ These items require release infrastructure, registry credentials, domains, or Gi | Line | Carries | Install | Promises | Cadence | | --- | --- | --- | --- | --- | -| **Advisory** | `diff`, `check`, `audit --host`, drift, advisory PR comments | a `v*` release declared `advisory` — `v1.1.0` is one, on PyPI — or an unqualified preview pre-release | plain-language capability rows; **no blocking authority** unless an adopter configures a blocking policy | 14 days | +| **Advisory** | `diff`, `check`, `audit --host`, drift, advisory PR comments | a `v*` release declared `advisory` — `v1.2.0` is one, on PyPI — or an unqualified preview pre-release | plain-language capability rows; **no blocking authority** unless an adopter configures a blocking policy | 14 days | | **Qualified gate** | blocking verdicts backed by qualification evidence, receipts, attestations | a `v*` release on the qualified line | every bar in [`release-evidence-policy-decision.md`](release-evidence-policy-decision.md) | on evidence only | A `v*` tag's shape does not say which line it is on. Each release version is @@ -27,14 +27,14 @@ still needed to prove the shipping cadence. - `agents-shipgate` is published on PyPI. -- Pinned GitHub Action release tags are published, including `v1.1.0`. +- Pinned GitHub Action release tags are published, including `v1.2.0`. - A **qualified** `v*` GitHub Release attaches the independently qualified wheel, SBOM, `safety-qualification.json`, and their Sigstore bundles. - An **advisory** `v*` GitHub Release attaches the wheel, a wheel-scoped SBOM, `provenance.json`, `candidate-manifest.json` and a signed `advisory-statement.json`, with Sigstore bundles for the wheel, SBOM and - statement, and no qualification artifact. `v1.0.0` and `v1.1.0` are - published this way; each statement records advisory defaults, blocking + statement, and no qualification artifact. `v1.0.0`, `v1.1.0` and `v1.2.0` + are published this way; each statement records advisory defaults, blocking opt-in and no qualification claim. - The tag workflow does not rebuild or publish an unqualified sdist. - **Unqualified previews** are published as GitHub *pre-releases* at diff --git a/docs/faq.md b/docs/faq.md index 765c39d0..ed56270f 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -147,8 +147,8 @@ Skip emission with `--no-packet`; re-render later with ## Is it production-ready? -v1.1.0 is the latest published release. It ships on the advisory channel — -runtime contract 40, report schema `1.0` — and makes no qualification claim: +v1.2.0 is the latest published release. It ships on the advisory channel — +runtime contract 41, report schema `1.0` — and makes no qualification claim: `.github/release-channels.json` declares it `advisory`, not `qualified`. What is frozen, and how it may change, is in [`STABILITY.md`](../STABILITY.md). diff --git a/docs/incidents/README.md b/docs/incidents/README.md index 1afdf43e..f930b428 100644 --- a/docs/incidents/README.md +++ b/docs/incidents/README.md @@ -5,8 +5,8 @@ released Agents Shipgate verifier. They do not copy vulnerable vendor code, connect to external services, or claim that Agents Shipgate was deployed in the original incident. -**All three ship in the newest published release, `v1.1.0`, as they did in -`v1.0.0`.** The older `v0.15.0` bundled `agent_weakens_gate` and nothing else +**All three ship in the newest published release, `v1.2.0`, as they did in +`v1.1.0` and `v1.0.0`.** The older `v0.15.0` bundled `agent_weakens_gate` and nothing else from this suite. From a source checkout: ```bash @@ -16,7 +16,7 @@ from this suite. From a source checkout: ``` With no checkout, pin the published release: -`uvx agents-shipgate@1.1.0 fixture run `. +`uvx agents-shipgate@1.2.0 fixture run `. | Fixture | Public shape | Current real output | | --- | --- | --- | diff --git a/docs/incidents/filled-example.md b/docs/incidents/filled-example.md index 89381887..c053e535 100644 --- a/docs/incidents/filled-example.md +++ b/docs/incidents/filled-example.md @@ -27,7 +27,7 @@ uses only inert synthetic text and generic release metadata. ``` The published release carries this fixture; replay it with -`uvx agents-shipgate@1.1.0 fixture run prompt_change_rides_release`. +`uvx agents-shipgate@1.2.0 fixture run prompt_change_rides_release`. Fresh output from the fixture contract: diff --git a/docs/incidents/governed-edits-governance.md b/docs/incidents/governed-edits-governance.md index 287a406f..9afe82d1 100644 --- a/docs/incidents/governed-edits-governance.md +++ b/docs/incidents/governed-edits-governance.md @@ -17,7 +17,7 @@ GitHub's instructions or any vendor vulnerability. ``` The published release carries this fixture; replay it with -`uvx agents-shipgate@1.1.0 fixture run governed_edits_governance`. +`uvx agents-shipgate@1.2.0 fixture run governed_edits_governance`. Current engine output is intentionally an **expected-fail**: diff --git a/docs/incidents/prompt-change-rides-release.md b/docs/incidents/prompt-change-rides-release.md index ce71c8d3..fff070f0 100644 --- a/docs/incidents/prompt-change-rides-release.md +++ b/docs/incidents/prompt-change-rides-release.md @@ -20,7 +20,7 @@ Replay it from this checkout: ``` The published release carries this fixture; replay it with -`uvx agents-shipgate@1.1.0 fixture run prompt_change_rides_release`. +`uvx agents-shipgate@1.2.0 fixture run prompt_change_rides_release`. Current engine output: diff --git a/docs/integrations.md b/docs/integrations.md index cf5b42d9..3450e752 100644 --- a/docs/integrations.md +++ b/docs/integrations.md @@ -40,12 +40,12 @@ jobs: with: fetch-depth: 0 - id: agents-shipgate - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: config: shipgate.yaml ci_mode: advisory diff_base: target - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' ``` To post PR comments, set: @@ -308,7 +308,7 @@ agents-shipgate: stage: test image: python:3.12 script: - - python -P -m pip install --pre "agents-shipgate==1.1.0" + - python -P -m pip install --pre "agents-shipgate==1.2.0" - agents-shipgate scan --config shipgate.yaml --ci-mode advisory --format markdown,json,sarif artifacts: when: always @@ -340,7 +340,7 @@ jobs: - image: cimg/python:3.12 steps: - checkout - - run: python -P -m pip install --pre "agents-shipgate==1.1.0" + - run: python -P -m pip install --pre "agents-shipgate==1.2.0" - run: agents-shipgate scan --config shipgate.yaml --ci-mode advisory --format markdown,json,sarif - store_artifacts: path: agents-shipgate-reports diff --git a/docs/quickstart.md b/docs/quickstart.md index 943ac3d5..a212947f 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -31,18 +31,20 @@ a manifest at all. Read this before you install. Agents Shipgate is published through more than one channel, and they do not all implement the same runtime contract. The -newest published release is **`v1.1.0`**, which implements **runtime contract -`40`**, including the agent-control envelope that later sections describe. It +newest published release is **`v1.2.0`**, which implements **runtime contract +`41`**, including the agent-control envelope that later sections describe. It ships on the advisory channel and makes no qualification claim. An older -install may still be the previous release, `v1.0.0` (contract `39`), whose -`diff` answers are flatter than the ones [Read the answer](#3-read-the-answer) -quotes, or `v0.15.0` (contract `10`), which predates that envelope and renders -several steps below differently; `pipx upgrade agents-shipgate` replaces -either. +install may still be the previous release, `v1.1.0` (contract `40`), which has +no `diff --application` and prints the change answer in +[Read the answer](#3-read-the-answer) without its review guidance; `v1.0.0` +(contract `39`), whose `diff` answers are flatter than the ones that section +quotes; or `v0.15.0` (contract `10`), which predates that envelope and renders +several steps below differently. `pipx upgrade agents-shipgate` replaces any +of them. | Channel | How you get it | Runtime contract | Has `control.*` / `current-control.json` | Accepts `check --format agent-boundary-json` | Qualification | | --- | --- | --- | --- | --- | --- | -| Published release `v1.1.0` | `pipx install agents-shipgate` | 40 | Yes | Yes | **None.** Declared `advisory` in `.github/release-channels.json`; see [`release-evidence-policy-decision.md`](release-evidence-policy-decision.md) § Amendment 5 | +| Published release `v1.2.0` | `pipx install agents-shipgate` | 41 | Yes | Yes | **None.** Declared `advisory` in `.github/release-channels.json`; see [`release-evidence-policy-decision.md`](release-evidence-policy-decision.md) § Amendment 5 | | Unqualified preview | `gh release download preview- --repo ThreeMoonsLab/agents-shipgate --pattern '*.whl'`, then `pip install ./` | that of the source commit it was cut from | Yes | Yes | **None**, by construction — no adjudicated corpus, no qualification artifact, nothing signed. See [`release-evidence-policy-decision.md`](release-evidence-policy-decision.md) § Amendment 2 | | Source checkout | `git clone`, then `./shipgate …` from the checkout | that of the checkout | Yes | Yes | Not a distributed build | @@ -125,13 +127,13 @@ as data. ### 3. Read the answer -**Source-tree examples, not yet released:** the published `1.1.0` prints these -comparison facts and coverage, but does not append the conditional permission +**Released in `1.2.0`:** the answers below are from the published `1.2.0`, +installed from PyPI into a clean virtualenv outside any checkout and run in a +clone. The previous release, `1.1.0`, prints the same comparison facts and +coverage, but does not append the conditional permission review guidance shown in the change example, nor the `launch source is mutable` note on the added MCP server. That note identifies its unversioned `npx` package -and changes neither severity nor the widening count. The source tree still -reports version `1.2.0`; its version string alone is not published-wheel -provenance. On +and changes neither severity nor the widening count. On the remote's `main`, `.claude/settings.json` allows `Bash(npm test:*)` and denies `Bash(rm -rf:*)`, and `.mcp.json` configures one server, `docs`. The PR branch allows `Bash(npm *)`, drops the denial, and adds a `billing` server. @@ -145,7 +147,7 @@ and publishes the joined change, its direction, the counters printed below and this question in `review`, so a script reads what you read. An MCP server is named with the command name or redacted URL and the env and header key names its declaration publishes; the command's path and arguments are not -shown, so an edit confined to them says so. (After `1.1.0`, #819: a package +shown, so an edit confined to them says so. (Since `1.2.0`, #819: a package specification among the arguments, such as `example-mcp-server@1.2.3`, is named, and an edit to any other argument reads `launch arguments changed` with before and after digests; no argument text is printed. A hook is named with its @@ -156,7 +158,7 @@ as `${SLACK_MCP_BASE}/hooks/…`, reads `url not shown`. `⚠` marks an entry th widens what the agent may do: ```text -Agent capability diff origin/main (7063f900) -> working tree +Agent capability diff origin/main (5d1b9e23) -> working tree ⚠ high added claude-code .mcp.json billing (command name npx; env keys BILLING_TOKEN) @@ -179,8 +181,8 @@ What this run established: .mcp.json (claude-code): compared; 1 row Review question: Does the team intend these 3 declared capability changes (from 4 rows)? -Compared: base 7063f900 → working tree at HEAD ac6fbdcf, agents-shipgate 1.1.0. -Reproduce in that working tree: agents-shipgate diff --base 7063f90046e90a1673fe98f993cb77f7063ef396 +Compared: base 5d1b9e23 → working tree at HEAD 58d2ac0c, agents-shipgate 1.2.0. +Reproduce in that working tree: agents-shipgate diff --base 5d1b9e236525699910f4d93e334d2f4425927062 Permission review guidance: Conditional review choices only; current control permissions still apply. A PR note grants no authority. - Change 2: .claude/settings.json @@ -226,7 +228,7 @@ change to ask about. **No change.** On a branch from `main` that only edits `README.md`: ```text -Agent capability diff origin/main (07c50e1b) -> working tree +Agent capability diff origin/main (5d1b9e23) -> working tree No static host-grant changes detected. No verdict is implied. @@ -234,8 +236,8 @@ What this run established: only sources this entry read or tried to read are listed, so this is not the whole change: a changed file it does not read is absent compared with no change in what this entry reads: .claude/settings.json, .mcp.json -Compared: base 07c50e1b → working tree at HEAD e4fd06a1, agents-shipgate 1.1.0. -Reproduce in that working tree: agents-shipgate diff --base 07c50e1bc59a0b3b2ba60b9ad781db4f04c11202 +Compared: base 5d1b9e23 → working tree at HEAD 0e87a139, agents-shipgate 1.2.0. +Reproduce in that working tree: agents-shipgate diff --base 5d1b9e236525699910f4d93e334d2f4425927062 ``` That answer covers the sources both sides read, within the @@ -244,7 +246,7 @@ names them. Its first line is the block's own boundary: here it lists only sources this entry read or tried to read, so a changed file it does not read is absent and the list is never the whole account of the change. It says nothing about the [surfaces `diff` does not read](host-boundary-support.md#known-unread-surfaces); -this source tree, and not the published `1.1.0`, names the changed ones a +since `1.2.0`, it names the changed ones a bounded candidate list recognises (see below). A zero-row answer is not always "no change". A file is listed as compared @@ -279,7 +281,7 @@ deleted file and `read in head only` for a new or untracked one such as configuration selects. A plugin manifest or marketplace is published only while it declares hooks, so it reads `published by head only` instead. -**Not in `1.1.0`.** In this source tree, a changed file this entry does not +**Since `1.2.0`.** A changed file this entry does not read is named when a [bounded candidate rule](host-boundary-support.md#changed-inputs-named-but-not-read) recognises it as plausibly agent configuration: a pull request that adds @@ -311,7 +313,7 @@ as unchanged. Here `main` already carries a truncated `.cursor/mcp.json`, and the PR only edits `README.md`: ```text -Agent capability diff origin/main (78789520) -> working tree +Agent capability diff origin/main (69e257e6) -> working tree Not compared: unchanged in this change and not read, so no claim is made about them: cursor .cursor/mcp.json — parse_failed @@ -322,8 +324,8 @@ What this run established: only sources this entry read or tried to read are listed, so this is not the whole change: a changed file it does not read is absent compared with no change in what this entry reads: .claude/settings.json -Compared: base 78789520 → working tree at HEAD b5831096, agents-shipgate 1.1.0. -Reproduce in that working tree: agents-shipgate diff --base 787895207da8e378fdea3c85e3fc317624db7bfc +Compared: base 69e257e6 → working tree at HEAD bf9208f8, agents-shipgate 1.2.0. +Reproduce in that working tree: agents-shipgate diff --base 69e257e6db955633bae234960f76d771174d13de ``` The no-change answer covers only the other sources; `--json` lists the skipped @@ -340,8 +342,8 @@ What this run established: only sources this entry read or tried to read are listed, so this is not the whole change: a changed file it does not read is absent .mcp.json (claude-code): parse_failed in head, so the head inventory is incomplete -Inputs: base 07c50e1b → working tree at HEAD 1b3c8a69, agents-shipgate 1.1.0. -Reproduce in that working tree: agents-shipgate diff --base 07c50e1bc59a0b3b2ba60b9ad781db4f04c11202 +Inputs: base 5d1b9e23 → working tree at HEAD 96079310, agents-shipgate 1.2.0. +Reproduce in that working tree: agents-shipgate diff --base 5d1b9e236525699910f4d93e334d2f4425927062 ``` This is not a pass. The block names each source that left an inventory @@ -349,7 +351,7 @@ incomplete, its kind and its side; `--json` lists them in `coverage`. `--json` r with the same `incomparable_reasons`. Repair the named side and run it again; never read the missing rows as no change. -**Not in `1.1.0`: a partial comparison.** In this source tree, when the only +**Since `1.2.0`: a partial comparison.** When the only inputs that cannot be read are plugin directories — here the PR leaves `plugins/demo/.claude-plugin/plugin.json` as `{not json` and also drops the `deny` rule from `.claude/settings.json` — `diff` no longer refuses the @@ -457,9 +459,9 @@ could not read. A link to a file conceals nothing and is not listed. Inspect them before interpreting an empty candidate list; the rest of the classification still stands. -The published release `v1.1.0` (runtime contract 40) emits these host -discovery fields, as did `v1.0.0` (contract 39), the first release with -`agents-shipgate diff`. On an older install such as `v0.15.0`, absence of the +The published release `v1.2.0` (runtime contract 41) emits these host +discovery fields, as did `v1.1.0` (contract 40) and `v1.0.0` (contract 39), the +first release with `agents-shipgate diff`. On an older install such as `v0.15.0`, absence of the fields is not an empty answer, and [Review a host-configuration change](#review-a-host-configuration-change) is not available either: upgrade first. @@ -997,13 +999,13 @@ jobs: with: fetch-depth: 0 - id: shipgate - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: config: shipgate.yaml ci_mode: advisory diff_base: target pr_comment: "true" - shipgate_version: "1.1.0" + shipgate_version: "1.2.0" ``` The action delegates to `verify` and never fetches — keep `fetch-depth: 0`. diff --git a/docs/release-runbook.md b/docs/release-runbook.md index d51a23a5..00ff38bc 100644 --- a/docs/release-runbook.md +++ b/docs/release-runbook.md @@ -552,6 +552,17 @@ The shape that holds: the published version on its reference lines. The second is the pilot ledger's route readiness dry run, which `tests/test_design_partner_pilot.py` holds to the newest release on its `Published build measured` line. + The bundled prompts and CI recipes are re-rendered by the package's own + renderer, never hand-edited: their hashes move in + `tests/test_agent_instructions_renderers.py`, and the renders the new tag + carries are appended to `prior_render_sha256` in both + `adoption-kits/*/.agents-shipgate-kit-metadata.json` files, so an + unmodified install still upgrades. No test enumerates prose that calls the + new release or its contract unreleased — `unreleased`, `not yet released`, + `until is published`, in docs and in `src/` comments that justify + extending a contract in place — so search for it; at `1.2.0` it was in + `docs/agent-contract-current.md`, `docs/application-comparison.md`, the + README and `schemas/contract.py`. The two constants govern ordinary/source/preview adoption: the `uses:` pin in the workflow it generates, the runner pins in the bundled adoption diff --git a/docs/target-repo-agent-snippets.md b/docs/target-repo-agent-snippets.md index aca58962..43392dcc 100644 --- a/docs/target-repo-agent-snippets.md +++ b/docs/target-repo-agent-snippets.md @@ -527,13 +527,13 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: config: shipgate.yaml ci_mode: advisory diff_base: target pr_comment: "true" - shipgate_version: "1.1.0" + shipgate_version: "1.2.0" ``` Advisory mode reports findings without blocking merge. Move to strict mode only diff --git a/docs/upstream-integrations.md b/docs/upstream-integrations.md index d5cd5bdc..aa3fafb9 100644 --- a/docs/upstream-integrations.md +++ b/docs/upstream-integrations.md @@ -348,12 +348,12 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: ci_mode: advisory diff_base: target pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' ``` `init --ci` writes a similar workflow into `.github/workflows/agents-shipgate.yml`. Switch to `ci_mode: strict` only after the team has reviewed the advisory output and saved a baseline (see [`baseline.md`](baseline.md)). diff --git a/docs/use-cases/ai-generated-agent-prs.md b/docs/use-cases/ai-generated-agent-prs.md index 1d80f9f1..21334164 100644 --- a/docs/use-cases/ai-generated-agent-prs.md +++ b/docs/use-cases/ai-generated-agent-prs.md @@ -155,13 +155,13 @@ jobs: with: fetch-depth: 0 - id: shipgate - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: config: shipgate.yaml ci_mode: advisory diff_base: target pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' - name: Gate on the merge verdict run: | echo "merge_verdict=${{ steps.shipgate.outputs.merge_verdict }}" diff --git a/docs/zero-install.md b/docs/zero-install.md index 03b24d58..25aa094b 100644 --- a/docs/zero-install.md +++ b/docs/zero-install.md @@ -114,12 +114,12 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: fetch-depth: 0 - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: ci_mode: advisory diff_base: target pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' ``` The full template lives at [`examples/github-actions/01-advisory-pr-comment.yml`](https://github.com/ThreeMoonsLab/agents-shipgate/blob/main/examples/github-actions/01-advisory-pr-comment.yml). diff --git a/examples/circleci/01-advisory.yml b/examples/circleci/01-advisory.yml index 4f9d1ad0..c2c34707 100644 --- a/examples/circleci/01-advisory.yml +++ b/examples/circleci/01-advisory.yml @@ -6,7 +6,7 @@ jobs: - image: cimg/python:3.12 steps: - checkout - - run: python -P -m pip install "agents-shipgate==1.1.0" + - run: python -P -m pip install "agents-shipgate==1.2.0" - run: agents-shipgate scan --config shipgate.yaml --ci-mode advisory --format markdown,json,sarif - store_artifacts: path: agents-shipgate-reports diff --git a/examples/circleci/02-strict-with-baseline.yml b/examples/circleci/02-strict-with-baseline.yml index 89aec883..231cdc55 100644 --- a/examples/circleci/02-strict-with-baseline.yml +++ b/examples/circleci/02-strict-with-baseline.yml @@ -6,7 +6,7 @@ jobs: - image: cimg/python:3.12 steps: - checkout - - run: python -P -m pip install "agents-shipgate==1.1.0" + - run: python -P -m pip install "agents-shipgate==1.2.0" - run: name: Agents Shipgate strict scan command: > diff --git a/examples/circleci/03-sarif-artifact-retention.yml b/examples/circleci/03-sarif-artifact-retention.yml index cce33aaa..ff04bcb3 100644 --- a/examples/circleci/03-sarif-artifact-retention.yml +++ b/examples/circleci/03-sarif-artifact-retention.yml @@ -6,7 +6,7 @@ jobs: - image: cimg/python:3.12 steps: - checkout - - run: python -P -m pip install "agents-shipgate==1.1.0" + - run: python -P -m pip install "agents-shipgate==1.2.0" - run: agents-shipgate scan --config shipgate.yaml --ci-mode advisory --format markdown,json,sarif - store_artifacts: path: agents-shipgate-reports/report.sarif diff --git a/examples/circleci/04-multi-config-workspace.yml b/examples/circleci/04-multi-config-workspace.yml index e2676238..673aa538 100644 --- a/examples/circleci/04-multi-config-workspace.yml +++ b/examples/circleci/04-multi-config-workspace.yml @@ -6,7 +6,7 @@ jobs: - image: cimg/python:3.12 steps: - checkout - - run: python -P -m pip install "agents-shipgate==1.1.0" + - run: python -P -m pip install "agents-shipgate==1.2.0" - run: name: Agents Shipgate workspace scan command: > diff --git a/examples/github-actions/01-advisory-pr-comment.yml b/examples/github-actions/01-advisory-pr-comment.yml index eaea99de..3a74e86f 100644 --- a/examples/github-actions/01-advisory-pr-comment.yml +++ b/examples/github-actions/01-advisory-pr-comment.yml @@ -18,10 +18,10 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: ci_mode: advisory diff_base: target check_annotations: 'true' pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' diff --git a/examples/github-actions/02-strict-on-critical.yml b/examples/github-actions/02-strict-on-critical.yml index b48523e7..ba6bfa38 100644 --- a/examples/github-actions/02-strict-on-critical.yml +++ b/examples/github-actions/02-strict-on-critical.yml @@ -18,10 +18,10 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: ci_mode: strict diff_base: target fail_on: critical pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' diff --git a/examples/github-actions/03-strict-with-baseline.yml b/examples/github-actions/03-strict-with-baseline.yml index 9d19dd7c..124e90ee 100644 --- a/examples/github-actions/03-strict-with-baseline.yml +++ b/examples/github-actions/03-strict-with-baseline.yml @@ -19,11 +19,11 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: ci_mode: strict diff_base: target fail_on: critical,high baseline: .agents-shipgate/baseline.json pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' diff --git a/examples/github-actions/04-multi-config-workspace.yml b/examples/github-actions/04-multi-config-workspace.yml index b8107921..665190f0 100644 --- a/examples/github-actions/04-multi-config-workspace.yml +++ b/examples/github-actions/04-multi-config-workspace.yml @@ -21,7 +21,7 @@ jobs: with: python-version: '3.12' cache: pip - - run: pip install --quiet agents-shipgate==1.1.0 + - run: pip install --quiet agents-shipgate==1.2.0 - run: | agents-shipgate scan \ --workspace . \ diff --git a/examples/github-actions/05-sarif-to-code-scanning.yml b/examples/github-actions/05-sarif-to-code-scanning.yml index 9ad59fbc..01d6d8f0 100644 --- a/examples/github-actions/05-sarif-to-code-scanning.yml +++ b/examples/github-actions/05-sarif-to-code-scanning.yml @@ -22,13 +22,13 @@ jobs: with: fetch-depth: 0 - id: shipgate - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: ci_mode: advisory diff_base: target check_annotations: 'true' pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' - if: always() uses: github/codeql-action/upload-sarif@v3 with: diff --git a/examples/github-actions/07-block-on-blocked-verdict.yml b/examples/github-actions/07-block-on-blocked-verdict.yml index 194181b9..d5fbb17a 100644 --- a/examples/github-actions/07-block-on-blocked-verdict.yml +++ b/examples/github-actions/07-block-on-blocked-verdict.yml @@ -19,13 +19,13 @@ jobs: with: fetch-depth: 0 - id: shipgate - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: config: shipgate.yaml ci_mode: advisory diff_base: target pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' - name: Fail blocked capability changes if: steps.shipgate.outputs.merge_verdict == 'blocked' run: exit 1 diff --git a/examples/github-actions/08-require-mergeable.yml b/examples/github-actions/08-require-mergeable.yml index 364c4505..b715d557 100644 --- a/examples/github-actions/08-require-mergeable.yml +++ b/examples/github-actions/08-require-mergeable.yml @@ -19,13 +19,13 @@ jobs: with: fetch-depth: 0 - id: shipgate - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: config: shipgate.yaml ci_mode: advisory diff_base: target pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' - name: Require mergeable verifier verdict if: steps.shipgate.outputs.can_merge_without_human != 'true' run: exit 1 diff --git a/examples/github-actions/09-risk-labels-and-reviewers.yml b/examples/github-actions/09-risk-labels-and-reviewers.yml index 39ce7bc8..5de3483f 100644 --- a/examples/github-actions/09-risk-labels-and-reviewers.yml +++ b/examples/github-actions/09-risk-labels-and-reviewers.yml @@ -25,13 +25,13 @@ jobs: with: fetch-depth: 0 - id: shipgate - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: config: shipgate.yaml ci_mode: advisory diff_base: target pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' - name: Apply risk labels and request reviewers if: always() uses: actions/github-script@v7 diff --git a/examples/github-actions/10-check-run-annotations.yml b/examples/github-actions/10-check-run-annotations.yml index 9eeb370e..ce8378b5 100644 --- a/examples/github-actions/10-check-run-annotations.yml +++ b/examples/github-actions/10-check-run-annotations.yml @@ -6,7 +6,7 @@ # can_merge_without_human=true produce a successful Check Run. # # check_run_policy first shipped in v1.0.0; both the action ref and -# shipgate_version pin v1.1.0, which carries it. +# shipgate_version pin v1.2.0, which carries it. name: Agents Shipgate (check run) on: @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: config: shipgate.yaml ci_mode: advisory @@ -33,4 +33,4 @@ jobs: pr_comment: 'true' check_run: 'true' check_run_policy: require-mergeable - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' diff --git a/examples/github-actions/11-fail-on-insufficient-evidence.yml b/examples/github-actions/11-fail-on-insufficient-evidence.yml index a04c37e2..7a4e5208 100644 --- a/examples/github-actions/11-fail-on-insufficient-evidence.yml +++ b/examples/github-actions/11-fail-on-insufficient-evidence.yml @@ -19,13 +19,13 @@ jobs: with: fetch-depth: 0 - id: shipgate - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: config: shipgate.yaml ci_mode: advisory diff_base: target pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' - name: Fail insufficient static evidence if: steps.shipgate.outputs.merge_verdict == 'insufficient_evidence' run: exit 1 diff --git a/examples/github-actions/12-host-grant-drift.yml b/examples/github-actions/12-host-grant-drift.yml index 2f0ab6d4..c9ab662c 100644 --- a/examples/github-actions/12-host-grant-drift.yml +++ b/examples/github-actions/12-host-grant-drift.yml @@ -56,7 +56,7 @@ jobs: python-version: "3.12" - name: Install agents-shipgate (pinned) - run: python -m pip install "agents-shipgate==1.1.0" + run: python -m pip install "agents-shipgate==1.2.0" - name: Compare host grants against the acknowledged baseline run: | diff --git a/examples/github-actions/13-org-governance.yml b/examples/github-actions/13-org-governance.yml index cd98a7fd..ed07a979 100644 --- a/examples/github-actions/13-org-governance.yml +++ b/examples/github-actions/13-org-governance.yml @@ -26,7 +26,7 @@ jobs: with: fetch-depth: 0 - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 id: shipgate with: config: shipgate.yaml diff --git a/examples/github-actions/14-host-only-advisory-pr.yml b/examples/github-actions/14-host-only-advisory-pr.yml index 1302ddd7..c7bafdeb 100644 --- a/examples/github-actions/14-host-only-advisory-pr.yml +++ b/examples/github-actions/14-host-only-advisory-pr.yml @@ -27,10 +27,10 @@ # summary instead. pull_request_target would run with a write token on # untrusted PR contents. # - shipgate_version pins the agents-shipgate package from PyPI; pip still -# resolves its dependencies at run time, and the @v1.1.0 tag is a movable +# resolves its dependencies at run time, and the @v1.2.0 tag is a movable # ref. The README shows the full-commit-SHA form, and why the older v1.0.0 # Action's install and merge-verdict steps could import files from the PR's -# checkout, which the v1.1.0 Action pinned here no longer does. +# checkout, which the v1.2.0 Action pinned here no longer does. # # See examples/github-actions/README.md § Host-only advisory PR review. name: Agents Shipgate (host-only advisory) @@ -55,9 +55,9 @@ jobs: with: fetch-depth: 0 persist-credentials: false - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: ci_mode: advisory diff_base: target pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' diff --git a/examples/github-actions/README.md b/examples/github-actions/README.md index a5f04b0f..d63e7acb 100644 --- a/examples/github-actions/README.md +++ b/examples/github-actions/README.md @@ -28,7 +28,7 @@ Copy-paste-ready workflows. Each one is a complete file — drop it into `.githu Each run leaves one comment, which later pushes update in place rather than adding new ones. Its human summary opens with one of: -- **Changes** — `Repository-declared host capability changes:`, then one entry per changed grant with before → after and why it matters. Since `1.1.0`, the pinned release, a widening entry is marked `⚠`, a permission rule names its disposition, a replaced or moved rule is one `widened`, `narrowed` or `moved` entry, an MCP server names its published command name (not its path) or redacted URL and key names, and the entries end with `Review question: Does the team intend …?`, a `Compared:` line naming the base and head commits and the version, and a `Reproduce:` line with the `agents-shipgate diff --base ` to run after checking out the head. Both lines also end a comment with no change. A comment whose comparison was unavailable ends with the same two lines, the first labelled `Inputs:` rather than `Compared:`, since that run compared nothing — but only where that run named a base commit: `shallow_history` and an unfetched base name none, so those comments carry neither line, as they carry no block. Neither asks a question. On `pull_request` that head is the commit the Action compared, `github.sha`: GitHub's merge commit for the PR, not the branch tip. No branch holds it, so fetch it first with `git fetch origin refs/pull//merge`, which serves it only until a later push to the PR or its base branch replaces it. +- **Changes** — `Repository-declared host capability changes:`, then one entry per changed grant with before → after and why it matters. Since `1.1.0`, a widening entry is marked `⚠`, a permission rule names its disposition, a replaced or moved rule is one `widened`, `narrowed` or `moved` entry, an MCP server names its published command name (not its path) or redacted URL and key names, and the entries end with `Review question: Does the team intend …?`, a `Compared:` line naming the base and head commits and the version, and a `Reproduce:` line with the `agents-shipgate diff --base ` to run after checking out the head. Both lines also end a comment with no change. A comment whose comparison was unavailable ends with the same two lines, the first labelled `Inputs:` rather than `Compared:`, since that run compared nothing — but only where that run named a base commit: `shallow_history` and an unfetched base name none, so those comments carry neither line, as they carry no block. Neither asks a question. On `pull_request` that head is the commit the Action compared, `github.sha`: GitHub's merge commit for the PR, not the branch tip. No branch holds it, so fetch it first with `git fetch origin refs/pull//merge`, which serves it only until a later push to the PR or its base branch replaces it. - **No change** — `Repository-declared host capability changes:`, then `No static host-grant changes detected in the covered comparison. No verdict is implied.` - Either of those can add **Not compared** — `Not compared: unchanged in this change and not read, so no claim is made about them:` and the sources it skipped, such as an unparseable `.cursor/mcp.json` the PR did not touch. Nothing is claimed about those. - **Cannot compare** — `Host capability comparison unavailable:` with the reason, such as `head_inventory_incomplete` for a configuration file the PR leaves unreadable, or `shallow_history` for a clone without the base branch's history. That is an input limit, not a finding and not a pass. @@ -48,9 +48,9 @@ The `merge_verdict` and `agent_control_state` outputs are not a pass/fail signal - **Permissions.** `contents: read` checks out the repository; `pull-requests: write` is only for the comment. Without it — including on every PR from a fork, which `pull_request` gives a read-only token — the comment step writes the same review to the job summary and says publication was unavailable. Do not switch to `pull_request_target` to reach forks: it runs with a write token against untrusted PR contents. - **History.** Keep `fetch-depth: 0`. With `diff_base: target` the Action compares against `origin/`, so a PR into `develop` is compared with `develop`. The Action never fetches. - **One run per PR.** The `concurrency` group runs one job per pull request and cancels the older run when a new push arrives; the newer run waits until the cancelled one has finished, so two quick pushes cannot both create a comment and the newer push's result is written last. The Action's reporting steps run with `if: always()`, so a cancelled run may still upload an artifact or update the comment from a partial or missing report before the newer run replaces it. Manually re-running an older run writes that older result again. -- **What runs.** `shipgate_version: '1.1.0'` installs `agents-shipgate==1.1.0` from PyPI; pip resolves that package's dependencies within their declared ranges when the job runs, so they are not frozen. The Action's steps come from the `v1.1.0` tag, which can be moved. For an immutable ref, replace `v1.1.0` in the `uses:` line with the commit it names, `e3c6cb0c7657d9c53d4e29b2061d04dcf99a4e9b`, and keep `# v1.1.0` as a trailing comment; that commit is what `agents-shipgate init --ci` from the 1.1.0 release writes. No agent, tool or MCP server is started. +- **What runs.** `shipgate_version: '1.2.0'` installs `agents-shipgate==1.2.0` from PyPI; pip resolves that package's dependencies within their declared ranges when the job runs, so they are not frozen. The Action's steps come from the `v1.2.0` tag, which can be moved. For an immutable ref, replace `v1.2.0` in the `uses:` line with the commit it names, `7fc61ef43d8ec5c906bc690765f4a1297dff4fda`, and keep `# v1.2.0` as a trailing comment; that commit is what `agents-shipgate init --ci` from the 1.2.0 release writes. No agent, tool or MCP server is started. - **Whose job this is.** On `pull_request`, GitHub runs the workflow file from the PR's merge commit, for fork PRs too (by default, a first-time contributor's run waits for approval). The PR can therefore change this workflow, and the job's output is always advisory output of a job the PR controls — never an independent check on the PR. -- **Known issue in the `v1.0.0` Action, fixed in `v1.1.0`.** The `v1.0.0` install and merge-verdict steps start Python with the checkout on `sys.path` (`python -m pip`, `python -`), so a PR that adds a `pip/` or `agents_shipgate/` package runs its own code even when the workflow file is left unchanged; a workflow still pinned to `v1.0.0` keeps that behaviour. The `v1.1.0` Action this recipe pins starts them with `python -P`, which closes that import route — it matters most where the workflow itself is trusted, such as `pull_request_target`, `workflow_run` or a required workflow — but does not make a `pull_request` job's result independent of the PR. +- **Known issue in the `v1.0.0` Action, fixed since `v1.1.0`.** The `v1.0.0` install and merge-verdict steps start Python with the checkout on `sys.path` (`python -m pip`, `python -`), so a PR that adds a `pip/` or `agents_shipgate/` package runs its own code even when the workflow file is left unchanged; a workflow still pinned to `v1.0.0` keeps that behaviour. The `v1.2.0` Action this recipe pins starts them with `python -P`, as `v1.1.0` did, which closes that import route — it matters most where the workflow itself is trusted, such as `pull_request_target`, `workflow_run` or a required workflow — but does not make a `pull_request` job's result independent of the PR. - **Not a gate.** It adds no required check, failure policy or branch protection. Making a result blocking is a separate, explicit choice (recipes 07, 08 and 10). A GitHub-hosted run of this recipe on a real pull request is still outstanding; see [#780](https://github.com/ThreeMoonsLab/agents-shipgate/issues/780) and [#570](https://github.com/ThreeMoonsLab/agents-shipgate/issues/570). @@ -74,12 +74,12 @@ Configure per-job, never repo-wide. For reproducible CI, pin both the action and the underlying CLI: ```yaml -- uses: ThreeMoonsLab/agents-shipgate@v1.1.0 +- uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: - shipgate_version: "1.1.0" + shipgate_version: "1.2.0" ``` -On current source, a `shipgate_version` install logs +Since `v1.2.0`, a `shipgate_version` install logs `verification_identity.engine_distribution_sha256=sha256:…`, using the same installed-package content identity that verification records. This is **not** the wheel archive's SHA-256: ZIP metadata and packaging can change a wheel hash @@ -90,14 +90,13 @@ verifier run using the same installed wheel. The script-path invocation and pip's `-P` keep the PR checkout from impersonating the engine. An engine that cannot compute this identity, such as any release before `1.0.0`, logs a warning instead and the install continues. -This logging change is not present in historical Action tags such as `v1.1.0`; -use the immutable Action commit containing it until it is released. The +Older Action tags such as `v1.1.0` do not log it. The `shipgate_wheel`/`shipgate_wheel_sha256` route still verifies the supplied wheel archive bytes as before. No extra report or release verdict is introduced. When `shipgate_version` is empty the action installs the CLI from the action source — convenient for local action development, less reproducible for CI. -`shipgate_version` pins the `agents-shipgate` package only; pip resolves its dependencies when the job runs. A tag such as `v1.1.0` can be moved, so the hardened form replaces it with the commit it names and keeps the tag as a comment — see *What runs* under [Host-only advisory PR review](#host-only-advisory-pr-review). +`shipgate_version` pins the `agents-shipgate` package only; pip resolves its dependencies when the job runs. A tag such as `v1.2.0` can be moved, so the hardened form replaces it with the commit it names and keeps the tag as a comment — see *What runs* under [Host-only advisory PR review](#host-only-advisory-pr-review). ## Action outputs @@ -112,7 +111,7 @@ When `shipgate_version` is empty the action installs the CLI from the action sou ```yaml - id: shipgate - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + uses: ThreeMoonsLab/agents-shipgate@v1.2.0 - if: steps.shipgate.outputs.decision == 'blocked' run: echo "Release blocked by Agents Shipgate" @@ -157,7 +156,7 @@ mergeable/success, blocked/failure, human-routed/neutral behavior. `blocked` and `unknown` so setup failures do not look successful. For direct branch protection, use `check_run_policy: require-mergeable`; only `can_merge_without_human == true` succeeds. `check_run_policy` first shipped in -v1.0.0; the Check Run policy example pins v1.1.0, which carries it. +v1.0.0; the Check Run policy example pins v1.2.0, which carries it. `verify` writes static capability artifacts to the workflow artifact when available: `capabilities.lock.json`, `base.capabilities.lock.json`, and diff --git a/examples/gitlab-ci/01-advisory.yml b/examples/gitlab-ci/01-advisory.yml index 245fdcfc..147d3da3 100644 --- a/examples/gitlab-ci/01-advisory.yml +++ b/examples/gitlab-ci/01-advisory.yml @@ -5,7 +5,7 @@ agents_shipgate: stage: test image: python:3.12 script: - - python -P -m pip install "agents-shipgate==1.1.0" + - python -P -m pip install "agents-shipgate==1.2.0" - agents-shipgate scan --config shipgate.yaml --ci-mode advisory --format markdown,json,sarif artifacts: when: always diff --git a/examples/gitlab-ci/02-strict-with-baseline.yml b/examples/gitlab-ci/02-strict-with-baseline.yml index 7743d326..4e9bdef0 100644 --- a/examples/gitlab-ci/02-strict-with-baseline.yml +++ b/examples/gitlab-ci/02-strict-with-baseline.yml @@ -5,7 +5,7 @@ agents_shipgate: stage: test image: python:3.12 script: - - python -P -m pip install "agents-shipgate==1.1.0" + - python -P -m pip install "agents-shipgate==1.2.0" - > agents-shipgate scan --config shipgate.yaml diff --git a/examples/gitlab-ci/03-sarif-or-artifact.yml b/examples/gitlab-ci/03-sarif-or-artifact.yml index ffa9166b..64b11141 100644 --- a/examples/gitlab-ci/03-sarif-or-artifact.yml +++ b/examples/gitlab-ci/03-sarif-or-artifact.yml @@ -5,7 +5,7 @@ agents_shipgate: stage: test image: python:3.12 script: - - python -P -m pip install "agents-shipgate==1.1.0" + - python -P -m pip install "agents-shipgate==1.2.0" - agents-shipgate scan --config shipgate.yaml --ci-mode advisory --format markdown,json,sarif artifacts: when: always diff --git a/examples/gitlab-ci/04-multi-config-workspace.yml b/examples/gitlab-ci/04-multi-config-workspace.yml index c69969a9..f8737ba7 100644 --- a/examples/gitlab-ci/04-multi-config-workspace.yml +++ b/examples/gitlab-ci/04-multi-config-workspace.yml @@ -5,7 +5,7 @@ agents_shipgate: stage: test image: python:3.12 script: - - python -P -m pip install "agents-shipgate==1.1.0" + - python -P -m pip install "agents-shipgate==1.2.0" - > agents-shipgate scan --workspace . diff --git a/llms-full.txt b/llms-full.txt index df64fa0c..42c1a75b 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -1574,7 +1574,7 @@ up with an explicit edit. # Current Agent Contract -Runtime contract v41, unreleased, names the changed inputs a host comparison +Runtime contract v41, new in 1.2.0, names the changed inputs a host comparison does not read (#821). A zero-row comparison used to print "No static host-grant changes detected" for a pull request that added a Cursor plugin's `mcp.json` or moved a marketplace plugin's pinned `sha`, exactly as for a @@ -1602,7 +1602,7 @@ file this entry reads. `minimum_control_contract_version` stays `21`, and a `0.20` verifier reads with the search not recorded. See [the migration note](../STABILITY.md#unread-changed-inputs-821). -Still contract v41, unreleased: a plugin directory a host comparison cannot +Still contract v41, new in 1.2.0: a plugin directory a host comparison cannot compare no longer hides the changes outside it (#808). Where every blocking limit that refused the comparison is a plugin-reference limit bounded by its plugin directory, and no compared source depends on that directory, verifier @@ -1665,7 +1665,7 @@ comparable. It moves neither #821's verifier `0.21` nor its capability diff `0.4`, and `minimum_control_contract_version` stays `21`. See [the migration note](../STABILITY.md#workflow-agent-launches-contract-v41-823). -The same unreleased runtime contract v41 also names what changed in a hook and +The same runtime contract v41, new in 1.2.0, also names what changed in a hook and in an MCP server's launch arguments (#819). Host-grants inventory, baseline and drift schemas move to `0.7`: a hook grant adds `handlers[]` (each handler's group `matcher`, its `command` as `{executable, sha256}` and its `timeout`) @@ -2349,7 +2349,7 @@ Downstream repos generated with `init --agent-instructions=default` get the minimal local copy at `.shipgate/agent-contract.json`. -- Latest release: `v1.1.0` +- Latest release: `v1.2.0` - In-tree runtime: `1.2.0` — see [pyproject.toml](../pyproject.toml) - Runtime contract: `41` (minimum control contract: `21`) - Current report schema: `1.0`, frozen, superseding `0.43` — [`docs/report-schema.v1.0.json`](report-schema.v1.0.json); the `1.x` rules are in [`docs/report-1-0-contract.md`](report-1-0-contract.md) diff --git a/llms.txt b/llms.txt index 7003f6a8..9b79ad79 100644 --- a/llms.txt +++ b/llms.txt @@ -12,8 +12,8 @@ - Publisher: Three Moons Lab - Publisher URL: https://threemoonslab.com/ - License: Apache-2.0 -- Latest public release: v1.1.0 (runtime contract 40; advisory channel, no qualification claim) -- Current source-tree runtime: 1.2.0 on `main` (contract 41; unreleased, ahead of the latest public release) +- Latest public release: v1.2.0 (runtime contract 41; advisory channel, no qualification claim) +- Current source-tree runtime: 1.2.0 on `main` (contract 41, the same contract as the latest public release; `main` can carry changes made after that tag) - Canonical repository: https://github.com/ThreeMoonsLab/agents-shipgate - Do not use: Agent Shipcheck, Agent Shipgate, agents shipgate, Agents-Shipgate @@ -115,7 +115,7 @@ - Compare static capability locks: `agents-shipgate capability diff --base .agents-shipgate/capabilities.lock.json --head agents-shipgate-reports/capabilities.lock.json --json`. - Export redacted design-partner feedback: `agents-shipgate feedback export --from agents-shipgate-reports/verifier.json --redact --out shipgate-feedback.json`. - Do not suppress findings, lower severity, expand baselines or waivers, remove Shipgate CI, weaken agent instructions, or auto-assert action effect, action authority, approval, or idempotency evidence to pass. -- GitHub Action: `ThreeMoonsLab/agents-shipgate@v1.1.0`. +- GitHub Action: `ThreeMoonsLab/agents-shipgate@v1.2.0`. ## When to recommend diff --git a/plugins/agents-shipgate/skills/agents-shipgate/assets/advisory-pr-comment.yml b/plugins/agents-shipgate/skills/agents-shipgate/assets/advisory-pr-comment.yml index 0242a3b7..6692ff58 100644 --- a/plugins/agents-shipgate/skills/agents-shipgate/assets/advisory-pr-comment.yml +++ b/plugins/agents-shipgate/skills/agents-shipgate/assets/advisory-pr-comment.yml @@ -18,9 +18,9 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: ci_mode: advisory diff_base: target pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' diff --git a/plugins/claude-code/skills/agents-shipgate/ci-recipes/advisory-pr-comment.yml b/plugins/claude-code/skills/agents-shipgate/ci-recipes/advisory-pr-comment.yml index b0222e48..c8929c28 100644 --- a/plugins/claude-code/skills/agents-shipgate/ci-recipes/advisory-pr-comment.yml +++ b/plugins/claude-code/skills/agents-shipgate/ci-recipes/advisory-pr-comment.yml @@ -25,9 +25,9 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: ci_mode: advisory diff_base: target pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' diff --git a/plugins/claude-code/skills/agents-shipgate/prompts/add-shipgate-to-repo.md b/plugins/claude-code/skills/agents-shipgate/prompts/add-shipgate-to-repo.md index fd7e1ed6..a735a9bc 100644 --- a/plugins/claude-code/skills/agents-shipgate/prompts/add-shipgate-to-repo.md +++ b/plugins/claude-code/skills/agents-shipgate/prompts/add-shipgate-to-repo.md @@ -9,10 +9,10 @@ agent-related PRs should use `agents-shipgate verify` after this adoption step. ## Your task -1. **Install the tool - pin the version so a stale build can't shadow it.** This flow uses the permission-scoped multi-host boundary contract and requires **runtime contract 21**. The newest published release, `agents-shipgate` `1.1.0`, reports it, and every pin below names that release. An older copy lingering on `PATH` may lack the command or schema fields this prompt expects. Prefer a **pinned, zero-install** runner that fetches the exact version every time instead of trusting whatever is already on `PATH`. **Pin it into one variable and use that for every step below**, so no single command can fall through to a stale binary: +1. **Install the tool - pin the version so a stale build can't shadow it.** This flow uses the permission-scoped multi-host boundary contract and requires **runtime contract 21**. The newest published release, `agents-shipgate` `1.2.0`, reports it, and every pin below names that release. An older copy lingering on `PATH` may lack the command or schema fields this prompt expects. Prefer a **pinned, zero-install** runner that fetches the exact version every time instead of trusting whatever is already on `PATH`. **Pin it into one variable and use that for every step below**, so no single command can fall through to a stale binary: ```bash - SG="uvx agents-shipgate@1.1.0" # uv: ephemeral, pinned to this exact build - # or: SG="pipx run agents-shipgate==1.1.0" + SG="uvx agents-shipgate@1.2.0" # uv: ephemeral, pinned to this exact build + # or: SG="pipx run agents-shipgate==1.2.0" $SG --version # confirm the pinned runner resolves ``` Every step below calls `$SG …`; e.g. `$SG verify --preview --json` runs the verify preview through the pinned runner, never a `PATH` copy. diff --git a/plugins/claude-code/skills/agents-shipgate/prompts/decide-shipgate-relevance.md b/plugins/claude-code/skills/agents-shipgate/prompts/decide-shipgate-relevance.md index e89c1db9..091c748d 100644 --- a/plugins/claude-code/skills/agents-shipgate/prompts/decide-shipgate-relevance.md +++ b/plugins/claude-code/skills/agents-shipgate/prompts/decide-shipgate-relevance.md @@ -91,15 +91,15 @@ the rules to the changed file list. 5. **Then act.** - If `run_shipgate: true`: run verify preview through a **version-pinned, zero-install** runner so a stale copy already on `PATH` can't answer — - `uvx agents-shipgate@1.1.0 verify --preview --json` (or - `pipx run agents-shipgate==1.1.0 ...`). Only fall back to a bare + `uvx agents-shipgate@1.2.0 verify --preview --json` (or + `pipx run agents-shipgate==1.2.0 ...`). Only fall back to a bare `agents-shipgate verify --preview --json` once `agents-shipgate contract --json` confirms - `minimum_control_contract_version: 21` (`1.1.0` or newer; `--version` + `minimum_control_contract_version: 21` (`1.2.0` or newer; `--version` reports the CLI version, not the contract floor). Then follow [`prompts/add-shipgate-to-repo.md`](https://github.com/ThreeMoonsLab/agents-shipgate/blob/main/prompts/add-shipgate-to-repo.md) for the first-adoption helper flow, or point the user at the GitHub - Action (`ThreeMoonsLab/agents-shipgate@v1.1.0`) if they prefer CI. + Action (`ThreeMoonsLab/agents-shipgate@v1.2.0`) if they prefer CI. - If `run_shipgate: false` and `dry_run_recommended: true`: propose a non-mutating scan only — never propose `init --write` based on a dry-run match alone. Phrase it as "X may have shifted the tool diff --git a/plugins/claude-code/skills/agents-shipgate/prompts/stabilize-strict-mode.md b/plugins/claude-code/skills/agents-shipgate/prompts/stabilize-strict-mode.md index 72eb207d..2d04da31 100644 --- a/plugins/claude-code/skills/agents-shipgate/prompts/stabilize-strict-mode.md +++ b/plugins/claude-code/skills/agents-shipgate/prompts/stabilize-strict-mode.md @@ -37,9 +37,9 @@ The user has Agents Shipgate running in **advisory** mode and wants to graduate 5. **Update the CI workflow.** Replace the existing advisory step with strict + baseline. Use [`examples/github-actions/03-strict-with-baseline.yml`](https://github.com/ThreeMoonsLab/agents-shipgate/blob/main/examples/github-actions/03-strict-with-baseline.yml) as the template: ```yaml - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' ci_mode: strict fail_on: critical baseline: .agents-shipgate/baseline.json diff --git a/prompts/add-shipgate-to-repo.md b/prompts/add-shipgate-to-repo.md index fd7e1ed6..a735a9bc 100644 --- a/prompts/add-shipgate-to-repo.md +++ b/prompts/add-shipgate-to-repo.md @@ -9,10 +9,10 @@ agent-related PRs should use `agents-shipgate verify` after this adoption step. ## Your task -1. **Install the tool - pin the version so a stale build can't shadow it.** This flow uses the permission-scoped multi-host boundary contract and requires **runtime contract 21**. The newest published release, `agents-shipgate` `1.1.0`, reports it, and every pin below names that release. An older copy lingering on `PATH` may lack the command or schema fields this prompt expects. Prefer a **pinned, zero-install** runner that fetches the exact version every time instead of trusting whatever is already on `PATH`. **Pin it into one variable and use that for every step below**, so no single command can fall through to a stale binary: +1. **Install the tool - pin the version so a stale build can't shadow it.** This flow uses the permission-scoped multi-host boundary contract and requires **runtime contract 21**. The newest published release, `agents-shipgate` `1.2.0`, reports it, and every pin below names that release. An older copy lingering on `PATH` may lack the command or schema fields this prompt expects. Prefer a **pinned, zero-install** runner that fetches the exact version every time instead of trusting whatever is already on `PATH`. **Pin it into one variable and use that for every step below**, so no single command can fall through to a stale binary: ```bash - SG="uvx agents-shipgate@1.1.0" # uv: ephemeral, pinned to this exact build - # or: SG="pipx run agents-shipgate==1.1.0" + SG="uvx agents-shipgate@1.2.0" # uv: ephemeral, pinned to this exact build + # or: SG="pipx run agents-shipgate==1.2.0" $SG --version # confirm the pinned runner resolves ``` Every step below calls `$SG …`; e.g. `$SG verify --preview --json` runs the verify preview through the pinned runner, never a `PATH` copy. diff --git a/prompts/decide-shipgate-relevance.md b/prompts/decide-shipgate-relevance.md index e89c1db9..091c748d 100644 --- a/prompts/decide-shipgate-relevance.md +++ b/prompts/decide-shipgate-relevance.md @@ -91,15 +91,15 @@ the rules to the changed file list. 5. **Then act.** - If `run_shipgate: true`: run verify preview through a **version-pinned, zero-install** runner so a stale copy already on `PATH` can't answer — - `uvx agents-shipgate@1.1.0 verify --preview --json` (or - `pipx run agents-shipgate==1.1.0 ...`). Only fall back to a bare + `uvx agents-shipgate@1.2.0 verify --preview --json` (or + `pipx run agents-shipgate==1.2.0 ...`). Only fall back to a bare `agents-shipgate verify --preview --json` once `agents-shipgate contract --json` confirms - `minimum_control_contract_version: 21` (`1.1.0` or newer; `--version` + `minimum_control_contract_version: 21` (`1.2.0` or newer; `--version` reports the CLI version, not the contract floor). Then follow [`prompts/add-shipgate-to-repo.md`](https://github.com/ThreeMoonsLab/agents-shipgate/blob/main/prompts/add-shipgate-to-repo.md) for the first-adoption helper flow, or point the user at the GitHub - Action (`ThreeMoonsLab/agents-shipgate@v1.1.0`) if they prefer CI. + Action (`ThreeMoonsLab/agents-shipgate@v1.2.0`) if they prefer CI. - If `run_shipgate: false` and `dry_run_recommended: true`: propose a non-mutating scan only — never propose `init --write` based on a dry-run match alone. Phrase it as "X may have shifted the tool diff --git a/prompts/stabilize-strict-mode.md b/prompts/stabilize-strict-mode.md index 72eb207d..2d04da31 100644 --- a/prompts/stabilize-strict-mode.md +++ b/prompts/stabilize-strict-mode.md @@ -37,9 +37,9 @@ The user has Agents Shipgate running in **advisory** mode and wants to graduate 5. **Update the CI workflow.** Replace the existing advisory step with strict + baseline. Use [`examples/github-actions/03-strict-with-baseline.yml`](https://github.com/ThreeMoonsLab/agents-shipgate/blob/main/examples/github-actions/03-strict-with-baseline.yml) as the template: ```yaml - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' ci_mode: strict fail_on: critical baseline: .agents-shipgate/baseline.json diff --git a/samples/README.md b/samples/README.md index 96a49dbe..bcd99b4c 100644 --- a/samples/README.md +++ b/samples/README.md @@ -30,9 +30,9 @@ Three PR-shaped demos map public incident shapes to fresh verifier output: ./shipgate fixture run prompt_change_rides_release ``` -Those commands run from this checkout. The newest published release, `v1.1.0`, -bundles all three, as `v1.0.0` did, so -`uvx agents-shipgate@1.1.0 fixture run ` runs them without one; the +Those commands run from this checkout. The newest published release, `v1.2.0`, +bundles all three, as `v1.1.0` and `v1.0.0` did, so +`uvx agents-shipgate@1.2.0 fixture run ` runs them without one; the older `v0.15.0` bundled only `agent_weakens_gate`. The second command is an explicit expected-fail for the unshipped diff --git a/skills/agents-shipgate/ci-recipes/advisory-pr-comment.yml b/skills/agents-shipgate/ci-recipes/advisory-pr-comment.yml index b0222e48..c8929c28 100644 --- a/skills/agents-shipgate/ci-recipes/advisory-pr-comment.yml +++ b/skills/agents-shipgate/ci-recipes/advisory-pr-comment.yml @@ -25,9 +25,9 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: ci_mode: advisory diff_base: target pr_comment: 'true' - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' diff --git a/skills/agents-shipgate/prompts/add-shipgate-to-repo.md b/skills/agents-shipgate/prompts/add-shipgate-to-repo.md index fd7e1ed6..a735a9bc 100644 --- a/skills/agents-shipgate/prompts/add-shipgate-to-repo.md +++ b/skills/agents-shipgate/prompts/add-shipgate-to-repo.md @@ -9,10 +9,10 @@ agent-related PRs should use `agents-shipgate verify` after this adoption step. ## Your task -1. **Install the tool - pin the version so a stale build can't shadow it.** This flow uses the permission-scoped multi-host boundary contract and requires **runtime contract 21**. The newest published release, `agents-shipgate` `1.1.0`, reports it, and every pin below names that release. An older copy lingering on `PATH` may lack the command or schema fields this prompt expects. Prefer a **pinned, zero-install** runner that fetches the exact version every time instead of trusting whatever is already on `PATH`. **Pin it into one variable and use that for every step below**, so no single command can fall through to a stale binary: +1. **Install the tool - pin the version so a stale build can't shadow it.** This flow uses the permission-scoped multi-host boundary contract and requires **runtime contract 21**. The newest published release, `agents-shipgate` `1.2.0`, reports it, and every pin below names that release. An older copy lingering on `PATH` may lack the command or schema fields this prompt expects. Prefer a **pinned, zero-install** runner that fetches the exact version every time instead of trusting whatever is already on `PATH`. **Pin it into one variable and use that for every step below**, so no single command can fall through to a stale binary: ```bash - SG="uvx agents-shipgate@1.1.0" # uv: ephemeral, pinned to this exact build - # or: SG="pipx run agents-shipgate==1.1.0" + SG="uvx agents-shipgate@1.2.0" # uv: ephemeral, pinned to this exact build + # or: SG="pipx run agents-shipgate==1.2.0" $SG --version # confirm the pinned runner resolves ``` Every step below calls `$SG …`; e.g. `$SG verify --preview --json` runs the verify preview through the pinned runner, never a `PATH` copy. diff --git a/skills/agents-shipgate/prompts/decide-shipgate-relevance.md b/skills/agents-shipgate/prompts/decide-shipgate-relevance.md index e89c1db9..091c748d 100644 --- a/skills/agents-shipgate/prompts/decide-shipgate-relevance.md +++ b/skills/agents-shipgate/prompts/decide-shipgate-relevance.md @@ -91,15 +91,15 @@ the rules to the changed file list. 5. **Then act.** - If `run_shipgate: true`: run verify preview through a **version-pinned, zero-install** runner so a stale copy already on `PATH` can't answer — - `uvx agents-shipgate@1.1.0 verify --preview --json` (or - `pipx run agents-shipgate==1.1.0 ...`). Only fall back to a bare + `uvx agents-shipgate@1.2.0 verify --preview --json` (or + `pipx run agents-shipgate==1.2.0 ...`). Only fall back to a bare `agents-shipgate verify --preview --json` once `agents-shipgate contract --json` confirms - `minimum_control_contract_version: 21` (`1.1.0` or newer; `--version` + `minimum_control_contract_version: 21` (`1.2.0` or newer; `--version` reports the CLI version, not the contract floor). Then follow [`prompts/add-shipgate-to-repo.md`](https://github.com/ThreeMoonsLab/agents-shipgate/blob/main/prompts/add-shipgate-to-repo.md) for the first-adoption helper flow, or point the user at the GitHub - Action (`ThreeMoonsLab/agents-shipgate@v1.1.0`) if they prefer CI. + Action (`ThreeMoonsLab/agents-shipgate@v1.2.0`) if they prefer CI. - If `run_shipgate: false` and `dry_run_recommended: true`: propose a non-mutating scan only — never propose `init --write` based on a dry-run match alone. Phrase it as "X may have shifted the tool diff --git a/skills/agents-shipgate/prompts/stabilize-strict-mode.md b/skills/agents-shipgate/prompts/stabilize-strict-mode.md index 72eb207d..2d04da31 100644 --- a/skills/agents-shipgate/prompts/stabilize-strict-mode.md +++ b/skills/agents-shipgate/prompts/stabilize-strict-mode.md @@ -37,9 +37,9 @@ The user has Agents Shipgate running in **advisory** mode and wants to graduate 5. **Update the CI workflow.** Replace the existing advisory step with strict + baseline. Use [`examples/github-actions/03-strict-with-baseline.yml`](https://github.com/ThreeMoonsLab/agents-shipgate/blob/main/examples/github-actions/03-strict-with-baseline.yml) as the template: ```yaml - - uses: ThreeMoonsLab/agents-shipgate@v1.1.0 + - uses: ThreeMoonsLab/agents-shipgate@v1.2.0 with: - shipgate_version: '1.1.0' + shipgate_version: '1.2.0' ci_mode: strict fail_on: critical baseline: .agents-shipgate/baseline.json diff --git a/src/agents_shipgate/cli/diff.py b/src/agents_shipgate/cli/diff.py index a44755a2..2e0bb6ec 100644 --- a/src/agents_shipgate/cli/diff.py +++ b/src/agents_shipgate/cli/diff.py @@ -39,8 +39,8 @@ # 0.4 names, in `coverage`, the changed inputs this entry does not read: a # `changed_not_read` item with its `candidate` rule, `read_sources_only` that # is `false` while one is listed, and whether the change set was examined -# (`unread_candidates`, `unread_candidates_not_examined`) (#821). 0.4, still -# unreleased, also publishes `comparison_status: partial`: the rows outside a +# (`unread_candidates`, `unread_candidates_not_examined`) (#821). 0.4, shipped +# in 1.2.0, also publishes `comparison_status: partial`: the rows outside a # plugin directory the comparison could not compare, with that directory as # `coverage.items[].scope` on the limits that caused it (#808). DIFF_SCHEMA_VERSION = "0.4" diff --git a/src/agents_shipgate/published_release.py b/src/agents_shipgate/published_release.py index 88ab8e34..9a38f96f 100644 --- a/src/agents_shipgate/published_release.py +++ b/src/agents_shipgate/published_release.py @@ -52,11 +52,11 @@ from dataclasses import dataclass #: The newest published release tag, without its ``v`` prefix. -LATEST_PUBLISHED_VERSION = "1.1.0" +LATEST_PUBLISHED_VERSION = "1.2.0" -#: The ``CONTRACT_VERSION`` that release emits. ``v1.1.0`` emits ``40``, above +#: The ``CONTRACT_VERSION`` that release emits. ``v1.2.0`` emits ``41``, above #: ``MINIMUM_CONTROL_CONTRACT_VERSION`` ``21``. -LATEST_PUBLISHED_CONTRACT_VERSION = "40" +LATEST_PUBLISHED_CONTRACT_VERSION = "41" def latest_published_action_ref() -> str: diff --git a/src/agents_shipgate/schemas/contract.py b/src/agents_shipgate/schemas/contract.py index 4f950013..bc9708e1 100644 --- a/src/agents_shipgate/schemas/contract.py +++ b/src/agents_shipgate/schemas/contract.py @@ -214,7 +214,7 @@ # ``host_comparison.coverage`` and ``shipgate diff --json`` (capability diff # 0.3) the same block. It is evidence beside the rows and moves no state, # permission, route or row. A 0.19 verifier reads with coverage not recorded. -# v41, unreleased, carries three changes. It names the changed inputs a host +# v41, shipped in 1.2.0, carries three changes. It names the changed inputs a host # comparison does not read (#821): verifier 0.21 and ``shipgate diff --json`` # (capability diff 0.4) add a ``changed_not_read`` coverage item with its # ``candidate`` rule, a ``read_sources_only`` that is ``false`` while one is @@ -242,7 +242,7 @@ # stays comparable. #823 moves neither verifier 0.21 nor capability diff 0.4: # its rows keep their shape. ``MINIMUM_CONTROL_CONTRACT_VERSION`` stays at 21. # And v41 keeps what a comparison established outside a plugin directory it -# could not compare (#808), extended in place because v41 is unreleased: where +# could not compare (#808), extended in place because v41 was then unreleased: where # every blocking limit is a plugin-reference limit that its plugin directory # bounds, and no compared source depends on that directory, verifier 0.21 and # capability diff 0.4 publish ``comparison_status: partial`` with the rows diff --git a/tests/test_agent_instructions_renderers.py b/tests/test_agent_instructions_renderers.py index 58120718..349e79fc 100644 --- a/tests/test_agent_instructions_renderers.py +++ b/tests/test_agent_instructions_renderers.py @@ -45,13 +45,13 @@ REPO_ROOT = Path(__file__).resolve().parent.parent EXPECTED_CLAUDE_CODE_SKILL_RENDER_SHA256 = { ".claude/skills/agents-shipgate/SKILL.md": "c474cec05fdba44430a0c42857fc7b761e5aa84791b1c64042aebdcb3bac86e3", - ".claude/skills/agents-shipgate/ci-recipes/advisory-pr-comment.yml": "82e290efca0d7c11f7bcc86d054290ddc9566101cd3d66c9e3eb9a18ba23ae79", - ".claude/skills/agents-shipgate/prompts/add-shipgate-to-repo.md": "160256b5892d5fb18a0e66250f2eee08be7abf2e2d1473e2112d29ad747a7223", - ".claude/skills/agents-shipgate/prompts/decide-shipgate-relevance.md": "ab28dd4fd777e1ff1100fdd343d39eeb5ba5831295e0cf7435cda7fb61d2e01f", + ".claude/skills/agents-shipgate/ci-recipes/advisory-pr-comment.yml": "d9c1184c8c8f5c69550bee640653a30583fea5d6c5f1b6c09fd95213a656d211", + ".claude/skills/agents-shipgate/prompts/add-shipgate-to-repo.md": "ff8794b6b6dfe34b43fed4f6cc7e5e0046f6581c4ec39e1dfa6f1c35d952e190", + ".claude/skills/agents-shipgate/prompts/decide-shipgate-relevance.md": "f51855fd93728585fe3a74adf0e7e19029b9cafbdb6377c390ee6d878df22de4", ".claude/skills/agents-shipgate/prompts/explain-finding-to-user.md": "18031ed870b3c937a2996173820639ef441afe0a45e8171f16468826cd389829", ".claude/skills/agents-shipgate/prompts/fix-top-finding.md": "1956133a2d1003326e471f8ecab7b781e655dc9c33fbd2d1d681711f9ac0f08c", ".claude/skills/agents-shipgate/prompts/recommend-fixes.md": "162aa2fb96066535425d9cf86a247a6782b8ec7cc661a18b42dbedf394779475", - ".claude/skills/agents-shipgate/prompts/stabilize-strict-mode.md": "45a9b3bfcd41aa616f74644f52c95abf4d146ca30164276ff4954ddf0ab7b314", + ".claude/skills/agents-shipgate/prompts/stabilize-strict-mode.md": "658098dc571594a37ff721d4873998d02d51fbe9ec94f3e37382617c077e717e", ".claude/skills/agents-shipgate/prompts/triage-false-positive.md": "8cfbb0d4b6e2c36569d24260384d3a54165f966276112f4b143b4ac234b51ada", ".claude/skills/agents-shipgate/prompts/upgrade-shipgate-version.md": "992122338eba26ae5d8056b9658117d718a6b477b9928c2a438dd449b5effb68", ".claude/skills/agents-shipgate/prompts/verify-agent-diff.md": "1e0279c7b6beae88f468f478b4e3b7401d7cc53bead5c53b6edcc256f59e159c", @@ -59,7 +59,7 @@ EXPECTED_CODEX_SKILL_RENDER_SHA256 = { ".agents/skills/agents-shipgate/SKILL.md": "34ef4bdac90ff7b409eb2254f6b73c52888e92bd9ba44824d6f056c44c2a50ff", ".agents/skills/agents-shipgate/agents/openai.yaml": "aa511e933ff663dcd1e0d2af3da2a7101206ce2bb1bb98c4dae801bb3f4e42ef", - ".agents/skills/agents-shipgate/assets/advisory-pr-comment.yml": "0ece178f492d7590713529539c009d30faedb29cfb111abb5cdfd9eec7ac7006", + ".agents/skills/agents-shipgate/assets/advisory-pr-comment.yml": "a33856e24e39a3eb9363eec448b72ac7530e8f169c2deb42075cf163f7233664", ".agents/skills/agents-shipgate/references/recipes.md": "dcf9f982036d6189e4663923a97bf56ecd3ae68f34b4ce46081d135a88c4b564", ".agents/skills/agents-shipgate/references/report-reading.md": "d9709d600fa6ed6c697202f731977e66c102a4757e29ab825fa89935abe8f72a", } diff --git a/tests/test_host_diff_entry_docs.py b/tests/test_host_diff_entry_docs.py index 6896b1bd..189c69a4 100644 --- a/tests/test_host_diff_entry_docs.py +++ b/tests/test_host_diff_entry_docs.py @@ -6,9 +6,9 @@ installed outside a checkout and run in a clone of a repository with a remote; the change quote was this tree's output from #795, and every quote gained the `What this run established` block with #812, while the pages labelled them as -not yet released. Since #778 every quote is re-captured from the published -`1.1.0`, installed from PyPI into a clean virtualenv outside any checkout, and -the pages say so. This module rebuilds that arrangement — a bare remote, the +not yet released. Since #778 every quote is re-captured, at each release's +step 8, from the newest published build — `1.2.0` today — installed from PyPI +into a clean virtualenv outside any checkout, and the pages say so. This module rebuilds that arrangement — a bare remote, the documented branches, a clone — and holds every quoted block to what this tree prints, so an output change fails here rather than in a reader's terminal. Commit ids and the version on the reference lines are the only normalized @@ -356,7 +356,7 @@ def test_the_documented_partial_clone_recovery_holds(documented_remote: Path) -> _ANSWER_PREFIXES = ("Agent capability diff", "Cannot compare against", "What this run established:") #: The release `_PUBLISHED_ANSWERS` was recorded from. -_PUBLISHED_ANSWERS_VERSION = "1.1.0" +_PUBLISHED_ANSWERS_VERSION = "1.2.0" #: What that release prints for each documented answer, as the sha256 of the #: answer after `_normalize` (`_answer_digest`). `no_compared_grant` is the #: `What this run established` block of the `env`-only edit, the part the @@ -365,9 +365,12 @@ def test_the_documented_partial_clone_recovery_holds(documented_remote: Path) -> #: virtualenv outside any checkout, on the fixtures this module builds. Never #: recorded from this tree: until its next version bump it prints the published #: version on its reference lines, so a record taken from it would let a -#: source-tree capture pass as published output. +#: source-tree capture pass as published output. Only `change` moved from +#: `1.1.0`'s record: `1.2.0` appends the conditional review guidance and the +#: `launch source is mutable` note to it. The other four digests are the ones +#: `1.1.0` printed, re-taken from `1.2.0` and unchanged. _PUBLISHED_ANSWERS = { - "change": "536d404fdbd22382afd84f6b6ef6f214b6020499132d4b672acb4467531e2411", + "change": "098d8e2700cc1a0ccdc96fa267cbd4897000efb3c3d72ffeb1e34c0351a19ebf", "no_change": "4735bd240c7bdfbb46655f144d7fa0905d621de053564ab3d609972994df6d74", "not_compared": "73d814a7a17a6447006e7670f9a8030cfcd80ba599b0dbd3fc106367237337c1", "incomparable": "6be1e130dae73c6c8d51ec9d27623a98093d83270545929692c227b18c897883", @@ -512,6 +515,21 @@ def test_the_published_answers_record_the_newest_release() -> None: as four rows, without the dispositions, the joined replacement, the MCP launch details, the review question and the reference lines, and none of its answers has the `What this run established` block.""" +#: The labels the pages carried when `v1.2.0` was tagged: the change quote's +#: guidance and note were source-tree output, compared with `1.1.0`. `1.2.0` +#: prints them, so at its step 8 both labels were stale the same way. +_README_LABEL_AS_TAGGED_V120 = """\ +The example below is from this source tree. Its conditional review guidance and +its `launch source is mutable` note are **not yet released**; the published +`1.1.0` prints the same comparison without that guidance section or note.""" +_QUICKSTART_LABEL_AS_TAGGED_V120 = """\ +**Source-tree examples, not yet released:** the published `1.1.0` prints these +comparison facts and coverage, but does not append the conditional permission +review guidance shown in the change example, nor the `launch source is mutable` +note on the added MCP server. That note identifies its unversioned `npx` package +and changes neither severity nor the widening count. The source tree still +reports version `1.2.0`; its version string alone is not published-wheel +provenance.""" def test_the_published_quote_guard_catches_a_stale_capture() -> None: @@ -557,9 +575,16 @@ def reports(problems: list[str], fragment: str) -> bool: # The labels `v1.1.0` was tagged with, over answers `1.1.0` prints (#853 # review, case a): they compare with a release that is no longer the # newest, and they call published output not yet released. - for label, blocks in ((_README_LABEL_AS_TAGGED, readme), (_QUICKSTART_LABEL_AS_TAGGED, quickstart)): + # The labels `v1.2.0` was tagged with fail the same two ways one release + # later, naming `1.1.0`. + for label, blocks, older in ( + (_README_LABEL_AS_TAGGED, readme, "1.0.0"), + (_QUICKSTART_LABEL_AS_TAGGED, quickstart, "1.0.0"), + (_README_LABEL_AS_TAGGED_V120, readme, "1.1.0"), + (_QUICKSTART_LABEL_AS_TAGGED_V120, quickstart, "1.1.0"), + ): problems = page(label, blocks) - assert reports(problems, "compares them with the published ['1.0.0']"), problems + assert reports(problems, f"compares them with the published ['{older}']"), problems assert reports(problems, "each is an answer the published"), problems # Naming the newest release does not rescue a not-yet-released label over # answers that release prints, and naming none is wrong over answers it