Skip to content
Open
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
48 changes: 48 additions & 0 deletions STABILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,54 @@ for reproducible CI.

---

<a id="migration-note-unreleased-verifier-explanations"></a>

## Migration Note: unreleased — verifier explanations name the cause that acted

No schema or runtime-contract version moves. Three adopter-facing prose
projections become more specific; consumers must continue to branch on typed
fields rather than matching these sentences.

- Every completed blocked verifier run now routes its plain headline through
the same deterministic blocker picker already used by the adoption and
self-approval branches. `verifier.headline`, `control.reason`, and
`control.next_action.why` therefore append `Most severe: <title>.` even when
the diff introduces no manifest and touches no trust root. The picker is
unchanged: severity, then check id, then title. Runs with no blocker are
byte-identical on this clause.
- An `incomplete_surface` row raised for a surface the adapter did enumerate
now says that no reviewed inventory attests the lower-confidence extraction.
The older “could not be fully enumerated” wording remains only for a surface
whose enumeration is actually incomplete.
- Policy-evidence gap prose no longer prefixes `why` with an engine-owned
`builtin-*` policy id. Public `SHIP-*` and organization-defined check ids
remain as stable labels. `mixed_policy_evidence` names the authoritative and
heuristic evidence in tension and the reviewed action that closes the gap;
machine consumers keep using the structured gap kind, subject, source, and
target path.

<a id="migration-note-unreleased-embedded-trigger-routing"></a>

## Migration Note: unreleased — embedded trigger advice is consumed by verifier control

No schema or runtime-contract version moves, and standalone
`agents-shipgate trigger --json` output is unchanged. When the same trigger
evaluation is embedded in `verifier.json`, `verify-run.json`, or preview
output, its generic `trigger.next_action` is replaced by a
non-command `kind: "none"` row carrying `authoritative: false` and
`authoritative_path: "control.next_action"`. Its explanation says the verifier
already consumed the trigger route.

This prevents `verify --preview --json` from publishing a self-referential
preview command above the initialize/verify command that actually governs the
run. Embedded `trigger` remains relevance evidence; `control.next_action` and
`control.allowed_next_commands` remain the only operational route. Consumers
that used embedded `trigger.next_action.command` must switch to
`control.next_action.command`. Consumers of the standalone trigger command do
not change.

---

<a id="migration-note-unreleased-pre-1-0-evidence-bar"></a>

## Migration Note: unreleased — the pre-1.0 release evidence bar
Expand Down
44 changes: 37 additions & 7 deletions docs/agent-contract-current.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,29 @@ Verify the installed CLI contract locally before relying on hard-coded docs:
agents-shipgate contract --json
```

### Unreleased projection-only migration

No schema or runtime-contract version moves for the current projection fixes.
Completed blocked verifier runs now append the deterministically selected worst
blocker to the plain headline as well as the adoption/self-approval branches;
that same headline feeds `control.reason` and `control.next_action.why`. Runs
with no blocker do not gain the clause. `incomplete_surface` prose now
distinguishes a genuinely incomplete enumeration from a fully enumerated but
lower-confidence surface that has no reviewed inventory attestation, and
policy-evidence gap prose no longer prefixes `why` with an engine-owned
`builtin-*` policy id. Public and organization-defined check ids remain stable
labels. These are prose changes only; never branch on them. See the
[verifier-explanation migration note](../STABILITY.md#migration-note-unreleased-verifier-explanations).

Standalone trigger evaluation is unchanged. Inside a verifier artifact,
however, its generic route has already been consumed. Embedded
`trigger.next_action` is therefore a non-command `kind: "none"` row with
`authoritative: false` and
`authoritative_path: "control.next_action"`; the self-referential preview
command is not repeated. In verifier, verify-run, and preview output, follow
only `control.next_action` and `control.allowed_next_commands`. See the
[embedded-trigger migration note](../STABILITY.md#migration-note-unreleased-embedded-trigger-routing).

Runtime contract v27 finishes the v24 rollout on the stream v24 left out.
**Every** agent-mode error line from `detect`, `init`, and `doctor` now carries
the same `shipgate.agent_control/v1` object those commands publish on
Expand Down Expand Up @@ -809,14 +832,18 @@ operational overlay and cannot change those fields.
- `trigger` — the run/skip evaluation. Read `evaluation_status` first; two of
its three values withhold the verdict, and in both `should_run` /
`run_shipgate` / `skip` / `skip_reason` are `null`. Never read `null` as
`false`.
- `"not_evaluated"` — the diff could not be read. `next_action.kind` is
`"input_required"`; repair the input. `skip_reason` is never `"no_match"`
for inputs that were not fully read.
`false`. The embedded `next_action` is diagnostic only: it is always a
non-command `kind: "none"` row with `authoritative: false` and points at
`control.next_action`, which is the route to follow. The standalone
`agents-shipgate trigger --json` command retains its own actionable
`next_action`.
- `"not_evaluated"` — the diff could not be read. Repair the input through
`control.next_action`; `skip_reason` is never `"no_match"` for inputs that
were not fully read.
- `"unclassified"` — the diff *was* read in full and no rule classified some
or all of the changed files. That is a fact about the catalog, not about
the PR, so the skip is withheld and `next_action` routes forward to the
scan. `surface_exclusions.entries[]` lists the unclassified files.
the PR, so the skip is withheld and `control.next_action` routes forward
to the scan. `surface_exclusions.entries[]` lists the unclassified files.

`stop_conditions_fired` is the raw block result; `stop_conditions_terminal`
says whether it decided. A matched `run_shipgate`/`force_run` rule overrides
Expand Down Expand Up @@ -847,7 +874,10 @@ operational overlay and cannot change those fields.
additive and locked to `"verified"` whenever a `release_decision` is present.
- `can_merge_without_human` — `bool`.
- `decision` — mirror of `release_decision.decision` (or `null` when no scan ran).
- `headline` — single-sentence, PR-comment-friendly summary (or `null`).
- `headline` — single-sentence, PR-comment-friendly summary (or `null`). Every
completed blocked run names the deterministically selected worst blocker as
`Most severe: <title>.`, ordered by severity, check id, then title. A run
with no blocker adds no cause clause.
- `authorization` — the
`shipgate.human_authorization_evaluation/v1` result. Only `accepted` can
expose a command, and that command must exactly match both
Expand Down
44 changes: 37 additions & 7 deletions llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,29 @@ Verify the installed CLI contract locally before relying on hard-coded docs:
agents-shipgate contract --json
```

### Unreleased projection-only migration

No schema or runtime-contract version moves for the current projection fixes.
Completed blocked verifier runs now append the deterministically selected worst
blocker to the plain headline as well as the adoption/self-approval branches;
that same headline feeds `control.reason` and `control.next_action.why`. Runs
with no blocker do not gain the clause. `incomplete_surface` prose now
distinguishes a genuinely incomplete enumeration from a fully enumerated but
lower-confidence surface that has no reviewed inventory attestation, and
policy-evidence gap prose no longer prefixes `why` with an engine-owned
`builtin-*` policy id. Public and organization-defined check ids remain stable
labels. These are prose changes only; never branch on them. See the
[verifier-explanation migration note](../STABILITY.md#migration-note-unreleased-verifier-explanations).

Standalone trigger evaluation is unchanged. Inside a verifier artifact,
however, its generic route has already been consumed. Embedded
`trigger.next_action` is therefore a non-command `kind: "none"` row with
`authoritative: false` and
`authoritative_path: "control.next_action"`; the self-referential preview
command is not repeated. In verifier, verify-run, and preview output, follow
only `control.next_action` and `control.allowed_next_commands`. See the
[embedded-trigger migration note](../STABILITY.md#migration-note-unreleased-embedded-trigger-routing).

Runtime contract v27 finishes the v24 rollout on the stream v24 left out.
**Every** agent-mode error line from `detect`, `init`, and `doctor` now carries
the same `shipgate.agent_control/v1` object those commands publish on
Expand Down Expand Up @@ -2247,14 +2270,18 @@ operational overlay and cannot change those fields.
- `trigger` — the run/skip evaluation. Read `evaluation_status` first; two of
its three values withhold the verdict, and in both `should_run` /
`run_shipgate` / `skip` / `skip_reason` are `null`. Never read `null` as
`false`.
- `"not_evaluated"` — the diff could not be read. `next_action.kind` is
`"input_required"`; repair the input. `skip_reason` is never `"no_match"`
for inputs that were not fully read.
`false`. The embedded `next_action` is diagnostic only: it is always a
non-command `kind: "none"` row with `authoritative: false` and points at
`control.next_action`, which is the route to follow. The standalone
`agents-shipgate trigger --json` command retains its own actionable
`next_action`.
- `"not_evaluated"` — the diff could not be read. Repair the input through
`control.next_action`; `skip_reason` is never `"no_match"` for inputs that
were not fully read.
- `"unclassified"` — the diff *was* read in full and no rule classified some
or all of the changed files. That is a fact about the catalog, not about
the PR, so the skip is withheld and `next_action` routes forward to the
scan. `surface_exclusions.entries[]` lists the unclassified files.
the PR, so the skip is withheld and `control.next_action` routes forward
to the scan. `surface_exclusions.entries[]` lists the unclassified files.

`stop_conditions_fired` is the raw block result; `stop_conditions_terminal`
says whether it decided. A matched `run_shipgate`/`force_run` rule overrides
Expand Down Expand Up @@ -2285,7 +2312,10 @@ operational overlay and cannot change those fields.
additive and locked to `"verified"` whenever a `release_decision` is present.
- `can_merge_without_human` — `bool`.
- `decision` — mirror of `release_decision.decision` (or `null` when no scan ran).
- `headline` — single-sentence, PR-comment-friendly summary (or `null`).
- `headline` — single-sentence, PR-comment-friendly summary (or `null`). Every
completed blocked run names the deterministically selected worst blocker as
`Most severe: <title>.`, ordered by severity, check id, then title. A run
with no blocker adds no cause clause.
- `authorization` — the
`shipgate.human_authorization_evaluation/v1` result. Only `accepted` can
expose a command, and that command must exactly match both
Expand Down
6 changes: 3 additions & 3 deletions samples/conductor_agent/expected/current-control.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"artifacts": {
"report": {
"path": "report.json",
"sha256": "sha256:cd87ed0b4ec0f2ad288d7f3417d248a39aaa0de71052b86b190012564ac4d024",
"size_bytes": 50809
"sha256": "sha256:cf431c90bb19237bf1faaf466814ee8f0ce5864aceb1bd8aecf0eae294321828",
"size_bytes": 50990
},
"report_markdown": {
"path": "report.md",
Expand All @@ -25,7 +25,7 @@
"reason": "A standalone scan produced the current report set. A scan does not authorize completion or merge; run `agents-shipgate verify` to obtain a merge decision.",
"state": "agent_action_required"
},
"current_control_id": "sha256:e372a1e281ce340953611965a52008cb5a7f389615bddf4598abb994429eaa77",
"current_control_id": "sha256:8c7ccbdd645c2528375b1bc98c389980c2699dc65f4bea3174cc1cd891dbf3b2",
"decision_id": null,
"lifecycle_state": "terminal",
"operation": "scan",
Expand Down
12 changes: 6 additions & 6 deletions samples/conductor_agent/expected/report.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"schema_version": "0.1",
"report_schema_version": "0.42",
"run_id": "agents_shipgate_7a7430f9672871d1",
"run_id": "agents_shipgate_e0f0e1c2098bc335",
"request_id": null,
"subject_id": null,
"input_set_id": null,
Expand Down Expand Up @@ -155,7 +155,7 @@
"subject_kind": "action",
"source_type": "conductor_mcp_call",
"source_ref": "/tasks/3",
"why": "tool surface enumeration is incomplete or not high confidence",
"why": "tool surface is fully enumerated, but no reviewed tool inventory attests it (extraction_confidence=medium)",
"next_action": {
"kind": "provide_complete_inventory",
"command": "agents-shipgate verify --workspace . --config shipgate.yaml --ci-mode advisory --format json",
Expand Down Expand Up @@ -622,7 +622,7 @@
{
"kind": "incomplete_surface",
"dimension": "effect",
"message": "tool surface enumeration is incomplete or not high confidence",
"message": "tool surface is fully enumerated, but no reviewed tool inventory attests it (extraction_confidence=medium)",
"source": "tool_extraction",
"source_pointer": "/tasks/3"
}
Expand Down Expand Up @@ -1047,7 +1047,7 @@
{
"kind": "incomplete_surface",
"dimension": "effect",
"message": "tool surface enumeration is incomplete or not high confidence",
"message": "tool surface is fully enumerated, but no reviewed tool inventory attests it (extraction_confidence=medium)",
"source": "tool_extraction",
"source_pointer": "/tasks/3"
}
Expand Down Expand Up @@ -1229,7 +1229,7 @@
{
"kind": "incomplete_surface",
"dimension": "effect",
"message": "tool surface enumeration is incomplete or not high confidence",
"message": "tool surface is fully enumerated, but no reviewed tool inventory attests it (extraction_confidence=medium)",
"source": "tool_extraction",
"source_pointer": "/tasks/3"
}
Expand Down Expand Up @@ -1425,4 +1425,4 @@
"gap_backed": 1,
"truncated": false
}
}
}
12 changes: 6 additions & 6 deletions samples/declaration_repair_agent/expected/report.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"schema_version": "0.1",
"report_schema_version": "0.42",
"run_id": "agents_shipgate_036ea97ed643dd47",
"run_id": "agents_shipgate_ef0028285245d596",
"request_id": null,
"subject_id": null,
"input_set_id": null,
Expand Down Expand Up @@ -202,7 +202,7 @@
"subject_kind": "action",
"source_type": null,
"source_ref": "tools.json",
"why": "builtin-effect-control-applicability: Policy applicability mixes authoritative and heuristic evidence.",
"why": "Policy applicability combines a reviewed declaration with keyword inference. Confirm the reviewed declaration or provide structural evidence, then rerun verification.",
"next_action": {
"kind": "review_policy_evidence",
"command": "agents-shipgate verify --workspace . --config shipgate.yaml --ci-mode advisory --format json",
Expand Down Expand Up @@ -231,7 +231,7 @@
"subject_kind": "action",
"source_type": null,
"source_ref": "tools.json",
"why": "builtin-effect-control-applicability: Policy applicability mixes authoritative and heuristic evidence.",
"why": "Policy applicability combines a reviewed declaration with keyword inference. Confirm the reviewed declaration or provide structural evidence, then rerun verification.",
"next_action": {
"kind": "review_policy_evidence",
"command": "agents-shipgate verify --workspace . --config shipgate.yaml --ci-mode advisory --format json",
Expand Down Expand Up @@ -2435,7 +2435,7 @@
"subject_kind": "action",
"source_type": null,
"source_ref": "tools.json",
"why": "builtin-effect-control-applicability: Policy applicability mixes authoritative and heuristic evidence.",
"why": "Policy applicability combines a reviewed declaration with keyword inference. Confirm the reviewed declaration or provide structural evidence, then rerun verification.",
"next_action": {
"kind": "review_policy_evidence",
"command": "agents-shipgate verify --workspace . --config shipgate.yaml --ci-mode advisory --format json",
Expand Down Expand Up @@ -2464,7 +2464,7 @@
"subject_kind": "action",
"source_type": null,
"source_ref": "tools.json",
"why": "builtin-effect-control-applicability: Policy applicability mixes authoritative and heuristic evidence.",
"why": "Policy applicability combines a reviewed declaration with keyword inference. Confirm the reviewed declaration or provide structural evidence, then rerun verification.",
"next_action": {
"kind": "review_policy_evidence",
"command": "agents-shipgate verify --workspace . --config shipgate.yaml --ci-mode advisory --format json",
Expand Down Expand Up @@ -2593,4 +2593,4 @@
"gap_backed": 0,
"truncated": false
}
}
}
Loading
Loading