Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"name": "agents-shipgate",
"source": "./plugins/claude-code",
"description": "Run Agents Shipgate Tool-Use Readiness workflows from Claude Code: detect whether Shipgate applies, bootstrap the advisory gate, verify agent-capability PRs, and triage findings without fabricating human approval. Requires the agents-shipgate CLI (pipx install agents-shipgate, runtime contract 15).",
"version": "0.16.0b6",
"version": "0.16.0b7",
"author": {
"name": "Three Moons Lab",
"url": "https://threemoonslab.com/"
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/agents-shipgate-self.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
name: Agents Shipgate Self Dogfood

on:
Expand All @@ -21,6 +21,9 @@
verify_mode: verify
ci_mode: advisory
diff_base: target
fail_on_merge_verdicts: "blocked,human_review_required,insufficient_evidence,unknown"
# Same advisory semantics as agents-shipgate.yml: fail only on
# blocked/unknown; human_review_required is decided by the PR
# reviewer, not by a CI state nothing can clear.
fail_on_merge_verdicts: "blocked,unknown"
upload_artifact: "true"
pr_comment: "false"
8 changes: 7 additions & 1 deletion .github/workflows/agents-shipgate.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
name: Agents Shipgate

on:
Expand All @@ -20,6 +20,12 @@
config: shipgate.yaml
ci_mode: advisory
diff_base: target
fail_on_merge_verdicts: "blocked,human_review_required,insufficient_evidence,unknown"
# Advisory semantics: human_review_required means "the PR reviewer
# decides" — no verifier mechanism can clear that verdict, so failing
# CI on it makes every trust-root-touching PR (release pin sweeps,
# AGENTS.md edits) permanently red. CI fails only on blocked and on
# unknown (fail-closed against parse/contract breakage); review
# routing stays visible in the uploaded verifier artifact.
fail_on_merge_verdicts: "blocked,unknown"
upload_artifact: "true"
pr_comment: "false"
4 changes: 2 additions & 2 deletions .well-known/agents-shipgate.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "agents-shipgate",
"display_name": "Agents Shipgate",
"tagline": "The deterministic merge gate for AI-generated agent capability changes",
"version": "0.16.0b6",
"version": "0.16.0b7",
"license": "Apache-2.0",
"publisher": {
"name": "Three Moons Lab",
Expand Down Expand Up @@ -195,7 +195,7 @@
"agent_handoff_schema_version": "shipgate.agent_handoff/v6",
"agent_handoff_schema_path": "docs/agent-handoff-schema.v6.json",
"agent_handoff_artifact": "agents-shipgate-reports/agent-handoff.json",
"contract_version": "18",
"contract_version": "19",
"minimum_control_contract_version": "14",
"local_agent_contract_schema_version": "7",
"inputs": [
Expand Down
49 changes: 49 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,55 @@

## Unreleased

- **Graded local boundary stop (UX P0, contract v19, `0.16.0b7`).** The
local `shipgate check` previously projected every `require_review`
boundary violation onto the same `human_review_required` +
`must_stop: true` control state as a `block` — a CLAUDE.md comment, an
unknown `.claude/settings.json` key, and a critical grant expansion were
operationally identical, which routinely hard-stopped coding agents on
user-requested benign edits. Contract v19 routes a `require_review` set
that is entirely low/medium risk to
`control.state: "agent_action_required"` with the exact verify command;
the review obligation is preserved in the new additive `pending_review[]`
field on `shipgate.agent_boundary_result/v1` and re-asserted by PR-time
verify, whose `release_decision` branching is byte-identical. The band is
fail-closed: `block` actions, `critical` risk, incomplete or unparseable
input, gate-weakening rules, experimental surfaces, and every
gate-governing trust-root class (`manifest`, `policy`, `ci_gate`,
`shipgate_state`) keep the human stop, preserving the composite-diff
guarantee from the agent-authored proposal work. The deprecated
`codex-boundary-json` format grades identically; its frozen v2 schema
does not carry the new field.
- **Stop hook follows `control.state` (`0.16.0b7`).** The installed Claude
Code Stop hook blocked the agent's stop on any non-`passed` release
decision — but a Stop-hook block forces the agent to KEEP working, which
is exactly wrong for `human_review_required` (`must_stop: true` means
"end the turn and hand off to a human"). The hook now mirrors the
operational contract: `complete` ends the turn silently,
`agent_action_required` blocks once and names the one exact remaining
command, `human_review_required` prints a hand-off notice and lets the
turn end. Unparseable or unrecognized verifier output warns loudly, is
never cached by the verified-signature short-circuit, and is never
treated as passing; the cold-start no-manifest case advises
`verify --preview` instead of forcing continuation. Reinstall hooks to
pick up the new behavior.
- **Own-repo CI verify gates on `blocked,unknown` again (`0.16.0b7`).** The
0.16.0b3-era expansion of `fail_on_merge_verdicts` to include
`human_review_required` and `insufficient_evidence` (#274) made every
trust-root-touching PR — including routine release pin sweeps that bump the
plugin manifests — permanently red: no verifier mechanism can clear a
`human_review_required` merge verdict, and the verdict's own semantics are
"release is allowed but the human reviewer should weigh in." Both advisory
workflows now fail only on `blocked` and `unknown` (fail-closed against
parse/contract breakage); review routing remains visible in the uploaded
verifier artifact and the PR reviewer stays the deciding human. The
GitHub Action's own defaults are unchanged.
- **Version advances (`0.16.0b7`).** Runtime contract `18 → 19`. All other
schema versions are unchanged; `pending_review[]` is additive on the
regenerated `agent-boundary-result-schema.v1.json`, and
`minimum_control_contract_version` stays `14` — the `AgentControl` union,
its fixed `must_stop`/`completion_allowed` literals, and the release
gating signal are untouched.
- **Reproducible verification identity (P0, `0.16.0b6`).** Verify now binds
the resolved Git subject, exact input blobs, evaluation date, behavior
options, installed engine-content and dependency/adapter/plugin/policy set, normalized task,
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Local-first and static by default — no agent execution, tool calls, LLM calls,

> [!IMPORTANT]
> **Status: pre-1.0 (beta).** The decision engine is deterministic and stable.
> This source tree is `0.16.0b6`; install and GitHub Action examples remain
> This source tree is `0.16.0b7`; install and GitHub Action examples remain
> pinned to the latest published tag, `v0.15.0`, until the beta is released.
> Real-history accuracy numbers (small n, published in full in
> [`benchmark/miner/README.md`](benchmark/miner/README.md)): across 361 mined
Expand Down
48 changes: 47 additions & 1 deletion STABILITY.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Stability Contract · 0.16.0b6
# Stability Contract · 0.16.0b7

What agents and CI integrations can rely on across versions of Agents Shipgate.

Expand All @@ -13,6 +13,52 @@ for reproducible CI.

---

<a id="migration-note-0-16-0b7"></a>

## Migration Note: 0.16.0b7

Runtime contract `18 → 19` grades the LOCAL boundary stop. Under contract
v14–v18 every `require_review` boundary violation projected
`control.state: "human_review_required"` with `must_stop: true` — a
CLAUDE.md prose edit and a critical grant expansion were operationally
identical. As of v19, a `require_review` violation set that is entirely
low/medium risk projects `control.state: "agent_action_required"` with the
exact verify command, and the review obligation is carried in the new
additive `pending_review[]` field on
`shipgate.agent_boundary_result/v1` (each entry: `check_id`, `rule_id`,
`path`, `risk_level`, `title`, `reviewers`, `note`). The deprecated
`codex-boundary-json` format grades identically but its frozen v2 schema
does not carry the new field.

The graded band is deliberately narrow and fail-closed. These keep the
`human_review_required` stop at any scored risk: any `block` action or
`critical` risk in the set; `BOUNDARY-INPUT-INCOMPLETE` and parse-failure
evidence (unparseable content is not reviewable content — only the
parseable `unknown_host_config_key` case is band-eligible);
`CODEX-AGENTS-SHIPGATE-REQUIREMENT-REMOVED` (gate weakening); experimental
adapter surfaces; and every violation touching a gate-governing trust-root
class (`manifest`, `policy`, `ci_gate`, `shipgate_state`), which preserves
the composite-diff guarantee that a safe manifest append bundled with an
unsafe manifest edit still routes to a human.

The v14 control invariants are unchanged: `must_stop` equals
`state == "human_review_required"`, `completion_allowed` equals
`state == "complete"`, and conversation-level acknowledgement cannot clear
control state. PR-time `release_decision` branching is byte-identical —
the graded rows still land in `review_items` and route to a human at the
merge gate; only the local turn-level stop is relaxed.

The installed Claude Code **Stop hook** now follows `verifier.control.state`
instead of the release label: `complete` ends the turn silently,
`agent_action_required` blocks the stop once and names the one exact
remaining command, and `human_review_required` prints a hand-off notice and
lets the turn end — a Stop-hook block forces continued agent work, which
`must_stop` semantics forbid. Unparseable or unrecognized verifier output
warns, is never cached, and is never treated as passing. The cold-start
no-manifest case advises `verify --preview` instead of forcing
continuation. Reinstall hooks (`agents-shipgate install-hooks --target
claude-code --write`) to pick up the new behavior.

<a id="migration-note-0-16-0b6"></a>

## Migration Note: 0.16.0b6
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@
"b2e42bce1eb6892c5207890bd53ab987d0beaac7c9fa2d9de8ba07033a3f2f60",
"2b1d989ee32b8cfee59fb1cc0f51d70277cc16c9f2ad72932a348ecd285b4c38",
"e35be58338a6343c712a6a63aff826f5785040f201aa0d7f5f6f257c27d12532",
"44648891d77a12f562913e4402c08bca4be6cff4aa8c69b7950ea97e7d5cc17b"
"44648891d77a12f562913e4402c08bca4be6cff4aa8c69b7950ea97e7d5cc17b",
"7fcf37dacee5cc64263d21c6be3a5c7e99b4e6fb45d96b3dda7bdd0603aff6cd"
],
"prompts/decide-shipgate-relevance.md": [
"1bf8b9d91f081a246dcff14a84810ca5384f8e0987e4e7a8c0c5df56b151564c",
Expand Down
4 changes: 2 additions & 2 deletions benchmark/safety-qualification/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Evidence-Backed Pass Safety Qualification

This directory is the runbook for the `0.16.0b6` beta safety qualification.
This directory is the runbook for the `0.16.0b7` beta safety qualification.
The repository does **not** ship fabricated human labels or a passing result.
Until a real frozen corpus and its verifier receipts exist,
`safety-qualification.json` must not be published as qualified.
Expand Down Expand Up @@ -53,7 +53,7 @@ are marked `qualification_tier: test` and can never set

```bash
PYTHONPATH=src python scripts/run_safety_qualification.py \
--wheel dist/agents_shipgate-0.16.0b6-py3-none-any.whl \
--wheel dist/agents_shipgate-0.16.0b7-py3-none-any.whl \
--corpus /secure/frozen-corpus.json \
--receipts /secure/receipt-index.json \
--policy /secure/qualification-policy/ \
Expand Down
77 changes: 76 additions & 1 deletion docs/agent-boundary-result-schema.v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,74 @@
"title": "AgentResultDiagnostic",
"type": "object"
},
"AgentResultPendingReviewItem": {
"additionalProperties": false,
"description": "One finding that still owes human review while the agent may continue.\n\nEmitted when the local mapping routes a low/medium ``require_review``\nboundary change onto the coding-agent verify route instead of stopping the\nturn. The obligation is not cleared: it is carried here so the agent can\nreport it, and PR-time verify still routes the same change to a human.\n``reviewers`` holds the reviewer set that a stop would have demanded \u2014\n``control.human_review`` cannot carry it outside a human route.",
"properties": {
"check_id": {
"title": "Check Id",
"type": "string"
},
"note": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Note"
},
"path": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Path"
},
"reviewers": {
"items": {
"type": "string"
},
"title": "Reviewers",
"type": "array"
},
"risk_level": {
"enum": [
"none",
"low",
"medium",
"high",
"critical"
],
"title": "Risk Level",
"type": "string"
},
"rule_id": {
"title": "Rule Id",
"type": "string"
},
"title": {
"title": "Title",
"type": "string"
}
},
"required": [
"check_id",
"rule_id",
"risk_level",
"title"
],
"title": "AgentResultPendingReviewItem",
"type": "object"
},
"AgentResultPolicy": {
"additionalProperties": false,
"properties": {
Expand Down Expand Up @@ -401,7 +469,7 @@
"type": "string"
},
"version": {
"default": "0.16.0b6",
"default": "0.16.0b7",
"title": "Version",
"type": "string"
}
Expand Down Expand Up @@ -1111,6 +1179,13 @@
"title": "Issues",
"type": "array"
},
"pending_review": {
"items": {
"$ref": "#/$defs/AgentResultPendingReviewItem"
},
"title": "Pending Review",
"type": "array"
},
"policies": {
"items": {
"$ref": "#/$defs/AgentResultPolicy"
Expand Down
19 changes: 15 additions & 4 deletions docs/agent-contract-current.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,21 @@ Verify the installed CLI contract locally before relying on hard-coded docs:
agents-shipgate contract --json
```

Runtime contract v18 retains the v17 content-addressed verification identity,
Runtime contract v19 grades the LOCAL boundary stop: a `require_review`
violation set that is entirely low/medium risk projects
`control.state: "agent_action_required"` with the exact verify command, and
the review obligation is carried in the additive
`pending_review[]` field on the agent-boundary result instead of ending the
turn. Block actions, critical risk, gate-weakening rules
(`CODEX-AGENTS-SHIPGATE-REQUIREMENT-REMOVED`), unparseable content,
incomplete input, experimental surfaces, and every gate-governing trust-root
class (manifest, policy, ci_gate, shipgate_state) keep the
`human_review_required` stop. PR-time `release_decision` semantics are
unchanged. It retains the v18 human-authorization overlay, the v17
content-addressed verification identity,
v16 typed policy-evidence, v15 host-neutral
boundary, v14 unambiguous `AgentControl`, and v13 root-reachable binding
contracts. It adds a signed, externally rooted human-authorization overlay for
contracts. v18 added a signed, externally rooted human-authorization overlay for
one exact post-review coding-agent action. Agents
switch on `control.state`; `decision` remains diagnostic and
`release_decision.decision` remains the release gate. Contract v14 requires
Expand Down Expand Up @@ -61,8 +72,8 @@ Downstream repos generated with
`.shipgate/agent-contract.json`.

- Latest release: `v0.15.0`
- In-tree runtime: `0.16.0b6` — see [pyproject.toml](../pyproject.toml)
- Runtime contract: `18` (minimum control contract: `14`)
- In-tree runtime: `0.16.0b7` — see [pyproject.toml](../pyproject.toml)
- Runtime contract: `19` (minimum control contract: `14`)
- Current report schema: `0.34` — [`docs/report-schema.v0.34.json`](report-schema.v0.34.json)
- Current packet schema: `0.12` — [`docs/packet-schema.v0.12.json`](packet-schema.v0.12.json)
- Current shared agent result schema: `agent_result_v2` — [`docs/agent-result-schema.v2.json`](agent-result-schema.v2.json)
Expand Down
2 changes: 1 addition & 1 deletion docs/agent-handoff-schema.v6.json
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@
"type": "string"
},
"version": {
"default": "0.16.0b6",
"default": "0.16.0b7",
"title": "Version",
"type": "string"
}
Expand Down
2 changes: 1 addition & 1 deletion docs/agent-result-schema.v2.json
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@
"type": "string"
},
"version": {
"default": "0.16.0b6",
"default": "0.16.0b7",
"title": "Version",
"type": "string"
}
Expand Down
10 changes: 9 additions & 1 deletion docs/agents/use-with-claude-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,15 @@ Three hooks are installed:
irrelevant docs edits do not nudge every turn.
- **`Stop` (verify).** Full `agents-shipgate verify` only when the
working tree or current branch has a relevant change that has not
already been checked.
already been checked. The outcome follows `verifier.control.state`, the
authoritative operational signal: `complete` ends the turn silently;
`agent_action_required` blocks the stop once and names the one exact
remaining command (a Stop-hook block forces the agent to keep working,
so it is only ever used when a coding-agent action actually remains);
`human_review_required` lets the turn end and prints a hand-off notice —
`must_stop` means "stop and hand off to a human", which a forced
continuation would contradict. Unparseable or unrecognized verifier
output warns loudly, is never cached, and is never treated as passing.

Local setup failures such as a missing CLI or unavailable base ref are
surfaced as context, not as the release gate. CI remains authoritative,
Expand Down
2 changes: 1 addition & 1 deletion docs/ai-search-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ 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 `0.16.0b6` (runtime contract v18); the latest
The current source tree is `0.16.0b7` (runtime contract v19); the latest
published release remains `v0.15.0` until that beta is cut. In report v0.34,
`passed` is an evidence-backed static verdict: the configured root has a
complete reachable binding graph, every reachable action has complete,
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
A single-page summary of the `agents-shipgate` codebase for new
contributors and AI coding agents extending the project. Current as of
2026-07-13; auto-checked against `agents-shipgate contract --json`:
runtime contract `18`, report schema `v0.34`, packet schema `v0.12`.
runtime contract `19`, report schema `v0.34`, packet schema `v0.12`.

For the per-field stability contract, see
[`../STABILITY.md`](../STABILITY.md). For the agent-facing field index,
Expand Down
2 changes: 1 addition & 1 deletion docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ Skip emission with `--no-packet`; re-render later with
## Is it production-ready?

v0.15.0 is the latest published pre-1.0 beta. The in-tree runtime is
`0.16.0b6`, which adds content-addressed verification receipts and reproducible
`0.16.0b7`, which adds content-addressed verification receipts and reproducible
distributed-execution boundaries on top of typed policy evidence, the
multi-host boundary, and root-reachable binding contracts. The manifest schema
remains stable across the 0.x series; see
Expand Down
Loading