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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ Why: keep static guard releases auditable while the package is still alpha.

## Unreleased

## 0.3.5 - 2026-08-13

- The published 0.3.4 context scanner can be made unavailable by adversarial
repository-controlled regex, and this patch bounds that matching.
- Isolated repository-controlled context-policy regular-expression matching
behind the existing bounded scanner worker and added fixed pattern-count and
pattern-length limits. Timeout and limit failures remain deterministic,
Expand Down
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

> Deterministic static evidence for repositories maintained with coding agents.

**Status**: `0.3.4` alpha. Vendor-neutral, static-only, Python 3.11.4+, with one
**Status**: `0.3.5` alpha. Vendor-neutral, static-only, Python 3.11.4+, with one
runtime dependency (`PyYAML`).

Coding agents can change more than application code. They can also change the
Expand Down Expand Up @@ -65,7 +65,7 @@ If `uv` is available, preview the current alpha without a persistent install or
target-repository writes:

```bash
uvx --python 3.12 --from yui-agent-guard==0.3.4 agent-guard init --root . --print
uvx --python 3.12 --from yui-agent-guard==0.3.5 agent-guard init --root . --print
```

This pinned command may populate caches outside the repository, but it does not
Expand All @@ -79,7 +79,7 @@ starter files, and generate the recommended sanitized evidence. The scanned
repository can use any runtime:

```bash
python -m pip install yui-agent-guard==0.3.4
python -m pip install yui-agent-guard==0.3.5
agent-guard init --root . --print
# Review the proposed policies and workflow before the write step.
agent-guard init --root . --write
Expand Down Expand Up @@ -278,7 +278,7 @@ JSON output uses a shared result envelope across scanners:
```json
{
"schema_version": "agent-guard.result.v1",
"tool": {"name": "agent-guard", "version": "0.3.4"},
"tool": {"name": "agent-guard", "version": "0.3.5"},
"scanner": "context",
"status": "ok",
"exit_code": 0,
Expand Down Expand Up @@ -418,7 +418,7 @@ than a single scanner:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/yui-stingray/agent-guard
rev: v0.3.4
rev: v0.3.5
hooks:
- id: agent-guard-context
- id: agent-guard-path
Expand Down Expand Up @@ -1073,7 +1073,7 @@ import urllib.request
from pathlib import Path
from urllib.parse import urlparse

version = "0.3.4"
version = "0.3.5"
target = Path(sys.argv[1])
request_timeout_seconds = 20
metadata_url = f"https://pypi.org/pypi/yui-agent-guard/{version}/json"
Expand Down Expand Up @@ -1126,14 +1126,14 @@ for filename in sorted(expected):
with (target / filename).open("xb") as destination:
shutil.copyfileobj(response, destination)
PY
gh attestation verify "$verify_dir/yui_agent_guard-0.3.4-py3-none-any.whl" \
gh attestation verify "$verify_dir/yui_agent_guard-0.3.5-py3-none-any.whl" \
--repo yui-stingray/agent-guard \
--signer-workflow yui-stingray/agent-guard/.github/workflows/release.yml \
--source-ref refs/tags/v0.3.4
gh attestation verify "$verify_dir/yui_agent_guard-0.3.4.tar.gz" \
--source-ref refs/tags/v0.3.5
gh attestation verify "$verify_dir/yui_agent_guard-0.3.5.tar.gz" \
--repo yui-stingray/agent-guard \
--signer-workflow yui-stingray/agent-guard/.github/workflows/release.yml \
--source-ref refs/tags/v0.3.4
--source-ref refs/tags/v0.3.5
)
```

Expand Down
4 changes: 2 additions & 2 deletions docs/evidence-consumer-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: "3.12"
- run: python -m pip install yui-agent-guard==0.3.4
- run: python -m pip install yui-agent-guard==0.3.5
- name: Consume sanitized evidence
run: sh examples/evidence_contracts_ci.sh consume
```
Expand Down Expand Up @@ -156,7 +156,7 @@ jobs:
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: "3.12"
- run: python -m pip install yui-agent-guard==0.3.4
- run: python -m pip install yui-agent-guard==0.3.5
- name: Strict release gate
run: sh examples/evidence_contracts_ci.sh strict-release
```
Expand Down
2 changes: 1 addition & 1 deletion docs/evidence-samples/agent-guard-report.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/quickstart-existing-repo.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ If `uv` is available, preview the starter plan without installing a persistent
tool or changing the repository:

```console
uvx --python 3.12 --from yui-agent-guard==0.3.4 agent-guard init --root . --print
uvx --python 3.12 --from yui-agent-guard==0.3.5 agent-guard init --root . --print
```

This pinned `uvx` path is for evaluation and human review without a persistent
Expand All @@ -30,7 +30,7 @@ recommended conformance and its evidence-pack manifest:
python3 -c 'import sys; sys.exit(0 if sys.version_info >= (3, 11, 4) else "agent-guard requires Python 3.11.4+")' && \
python3 -m venv .venv && \
. .venv/bin/activate && \
python -m pip install yui-agent-guard==0.3.4
python -m pip install yui-agent-guard==0.3.5
agent-guard init --root . --print
# Review the proposed starter policies and workflow before writing them.
agent-guard init --root . --write
Expand All @@ -57,7 +57,7 @@ reviewed write, and sanitized report sequence is:

```powershell
py -3.12 -m venv .venv
.\.venv\Scripts\python.exe -m pip install yui-agent-guard==0.3.4
.\.venv\Scripts\python.exe -m pip install yui-agent-guard==0.3.5
.\.venv\Scripts\agent-guard.exe init --root . --print
# Review the proposed starter policies and workflow before writing them.
.\.venv\Scripts\agent-guard.exe init --root . --write
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ build-backend = "hatchling.build"

[project]
name = "yui-agent-guard"
version = "0.3.4"
version = "0.3.5"
description = "Static repository guardrails for agent-touched codebases."
readme = "README.md"
requires-python = ">=3.11.4"
Expand Down
2 changes: 1 addition & 1 deletion src/agent_guard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@
"WorkflowGuardFinding",
]

__version__ = "0.3.4"
__version__ = "0.3.5"
59 changes: 33 additions & 26 deletions tests/test_contract_stability.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,36 +139,43 @@ def test_changelog_records_latest_release_entry() -> None:
changelog = CHANGELOG.read_text(encoding="utf-8")
headings = [line for line in changelog.splitlines() if line.startswith("## ")]
unreleased = changelog.split("## Unreleased", maxsplit=1)[1].split(
"## 0.3.5 - 2026-08-13", maxsplit=1
)[0]
latest_release = changelog.split("## 0.3.5 - 2026-08-13", maxsplit=1)[1].split(
"## 0.3.4 - 2026-08-01", maxsplit=1
)[0]
latest_release = changelog.split("## 0.3.4 - 2026-08-01", maxsplit=1)[1].split(
previous_release = changelog.split("## 0.3.4 - 2026-08-01", maxsplit=1)[1].split(
"## 0.3.3 - 2026-07-27", maxsplit=1
)[0]
previous_release = changelog.split("## 0.3.3 - 2026-07-27", maxsplit=1)[1].split(
earlier_release = changelog.split("## 0.3.3 - 2026-07-27", maxsplit=1)[1].split(
"## 0.3.2 - 2026-07-19", maxsplit=1
)[0]
earlier_release = changelog.split("## 0.3.2 - 2026-07-19", maxsplit=1)[1].split(
older_release = changelog.split("## 0.3.2 - 2026-07-19", maxsplit=1)[1].split(
"## 0.3.1 - 2026-07-17", maxsplit=1
)[0]
older_release = changelog.split("## 0.3.1 - 2026-07-17", maxsplit=1)[1].split(
oldest_release = changelog.split("## 0.3.1 - 2026-07-17", maxsplit=1)[1].split(
"## 0.3.0 - 2026-07-17", maxsplit=1
)[0]
normalized_latest = " ".join(latest_release.split())
normalized_previous = " ".join(previous_release.split())
normalized_earlier = " ".join(earlier_release.split())
normalized_older = " ".join(older_release.split())
normalized_oldest = " ".join(oldest_release.split())
normalized_unreleased = " ".join(unreleased.split())

assert headings[:6] == [
assert headings[:7] == [
"## Unreleased",
"## 0.3.5 - 2026-08-13",
"## 0.3.4 - 2026-08-01",
"## 0.3.3 - 2026-07-27",
"## 0.3.2 - 2026-07-19",
"## 0.3.1 - 2026-07-17",
"## 0.3.0 - 2026-07-17",
]
assert normalized_unreleased == " ".join(
assert normalized_unreleased == ""
assert normalized_latest == " ".join(
[
"- The published 0.3.4 context scanner can be made unavailable by adversarial repository-controlled regex, and this patch bounds that matching.",
"- Isolated repository-controlled context-policy regular-expression matching behind the existing bounded scanner worker and added fixed pattern-count and pattern-length limits. Timeout and limit failures remain deterministic, sanitized configuration errors; no raw pattern or context text is emitted.",
"- Content-bound optional `agent-policy` audit-event references with a canonical-JSON, profile-bound, public-safe digest. Producers require a caller-designated repo-local JSON event and explicit profile; maintainer review and event-schema validation remain external. Consumers require the separately supplied event and reject missing, malformed, or replaced content. Audit-event binding uses report and manifest v2; the released v1 schemas remain unchanged and their path-and-role references remain readable as explicitly unbound legacy metadata. The event body remains outside the fixed seven-file public bundle.",
"- Defined a bounded demand-validation window through 2026-09-20 and froze feature releases pending an explicit maintainer decision after the 2026-09-21 review. Marketplace publication remains separately prohibited without explicit authorization.",
Expand All @@ -178,26 +185,26 @@ def test_changelog_records_latest_release_entry() -> None:
"- Aligned self-dogfood CI with the canonical public evidence filenames and required fail-closed bundle validation before artifact upload.",
]
)
assert "Bound API, content, and path policy inputs and scan work" in normalized_latest
assert "bounded packaged public-bundle consumer mode" in normalized_latest
assert "fresh runner-temporary staging" in normalized_latest
assert "bounded P0 public-artifact hygiene patch" in normalized_previous
assert "standalone evidence-pack command recursively sanitizes" in normalized_previous
assert "recognized HTTP(S)- or file-scheme artifact inputs" in normalized_previous
assert "mixed-case URLs" in normalized_previous
assert "mapping-key collisions fail closed" in normalized_previous
assert "explicit repository-root commands" in normalized_previous
assert "Released ahead of the default batch" in normalized_earlier
assert "repository-root containment fixes" in normalized_earlier
assert "Agent-Guard Bench fail closed on guard runner errors" in normalized_earlier
assert "top-level `--version` command" in normalized_earlier
assert "write-capable GitHub Release job" in normalized_earlier
assert "credentials in its working copy" in normalized_earlier
assert "dedicated least-privilege job" in normalized_earlier
assert "Hardened the packaged evidence consumer" in normalized_older
assert "AWS access-key-ID-shaped" in normalized_older
assert "lower-bound token" in normalized_older
assert "WSL-mounted Windows user paths" in normalized_older
assert "Bound API, content, and path policy inputs and scan work" in normalized_previous
assert "bounded packaged public-bundle consumer mode" in normalized_previous
assert "fresh runner-temporary staging" in normalized_previous
assert "bounded P0 public-artifact hygiene patch" in normalized_earlier
assert "standalone evidence-pack command recursively sanitizes" in normalized_earlier
assert "recognized HTTP(S)- or file-scheme artifact inputs" in normalized_earlier
assert "mixed-case URLs" in normalized_earlier
assert "mapping-key collisions fail closed" in normalized_earlier
assert "explicit repository-root commands" in normalized_earlier
assert "Released ahead of the default batch" in normalized_older
assert "repository-root containment fixes" in normalized_older
assert "Agent-Guard Bench fail closed on guard runner errors" in normalized_older
assert "top-level `--version` command" in normalized_older
assert "write-capable GitHub Release job" in normalized_older
assert "credentials in its working copy" in normalized_older
assert "dedicated least-privilege job" in normalized_older
assert "Hardened the packaged evidence consumer" in normalized_oldest
assert "AWS access-key-ID-shaped" in normalized_oldest
assert "lower-bound token" in normalized_oldest
assert "WSL-mounted Windows user paths" in normalized_oldest
assert "minimum supported Python version from 3.11 to 3.11.4" in changelog
assert "surface delta --base-ref <ref>" in changelog
assert "Recursively sanitized standalone Surface Inventory output" in changelog
Expand Down
6 changes: 3 additions & 3 deletions tests/test_workflow_release_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -856,11 +856,11 @@ def test_release_workflow_attests_built_distributions() -> None:
assert "trap 'rm -rf -- \"$verify_dir\"' EXIT" in readme
assert 'python - "$verify_dir"' in readme
assert (
'gh attestation verify "$verify_dir/yui_agent_guard-0.3.4-py3-none-any.whl"'
'gh attestation verify "$verify_dir/yui_agent_guard-0.3.5-py3-none-any.whl"'
in readme
)
assert 'gh attestation verify "$verify_dir/yui_agent_guard-0.3.4.tar.gz"' in readme
assert "--source-ref refs/tags/v0.3.4\n)\n```" in readme
assert 'gh attestation verify "$verify_dir/yui_agent_guard-0.3.5.tar.gz"' in readme
assert "--source-ref refs/tags/v0.3.5\n)\n```" in readme
assert "https://pypi.org/pypi/yui-agent-guard/" in readme
assert 'f"yui_agent_guard-{version}-py3-none-any.whl": "bdist_wheel"' in readme
assert 'f"yui_agent_guard-{version}.tar.gz": "sdist"' in readme
Expand Down