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
93 changes: 47 additions & 46 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ jobs:
python-version: "3.13"

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- uses: astral-sh/setup-uv@v5
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.12.5"
enable-cache: true
python-version: ${{ matrix.python-version }}
cache-dependency-glob: uv.lock
Expand All @@ -63,7 +64,7 @@ jobs:

- name: Upload reference coverage
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: coverage-python-3.13
path: coverage.xml
Expand All @@ -76,10 +77,11 @@ jobs:
timeout-minutes: 15

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- uses: astral-sh/setup-uv@v5
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.12.5"
enable-cache: true
python-version: "3.12"
cache-dependency-glob: uv.lock
Expand All @@ -88,10 +90,10 @@ jobs:
run: uv sync --locked --group dev --extra langchain

- name: Check formatting
run: uv run ruff format --check src tests examples benchmarks scripts
run: uv run ruff format --check src tests examples benchmarks demos

- name: Lint
run: uv run ruff check src tests examples benchmarks scripts
run: uv run ruff check src tests examples benchmarks demos

- name: Type-check
run: uv run mypy src/agentdiff
Expand All @@ -105,10 +107,11 @@ jobs:
timeout-minutes: 15

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- uses: astral-sh/setup-uv@v5
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.12.5"
enable-cache: true
python-version: "3.12"
cache-dependency-glob: uv.lock
Expand Down Expand Up @@ -138,79 +141,77 @@ jobs:
contents: read

steps:
- uses: actions/checkout@v4
- uses: actions/dependency-review-action@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0

docs:
name: Documentation
safetybench:
name: Local recovery regression suite
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- uses: astral-sh/setup-uv@v5
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.12.5"
enable-cache: true
python-version: "3.12"
cache-dependency-glob: uv.lock

- name: Install documentation dependencies
run: uv sync --locked --group docs

- name: Build strict documentation
env:
PYTHONWARNINGS: "ignore::UserWarning:mkdocs_autorefs"
run: uv run mkdocs build --strict
- name: Install benchmark dependencies
run: uv sync --locked --group dev

- name: Check built-site links and assets
run: uv run python scripts/check_docs_links.py site
- name: Run adversarial local regression cases
run: uv run python3 benchmarks/safetybench.py --output recovery-regression.json

- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: mkdocs-site
path: site/
name: local-recovery-regression
path: recovery-regression.json
if-no-files-found: error
retention-days: 7

safetybench:
name: Local recovery regression suite
docker-proof:
name: Real Docker proof - OpenAI migration
runs-on: ubuntu-latest
timeout-minutes: 10
timeout-minutes: 15

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- uses: astral-sh/setup-uv@v5
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.12.5"
enable-cache: true
python-version: "3.12"
cache-dependency-glob: uv.lock

- name: Install benchmark dependencies
- name: Install test dependencies
run: uv sync --locked --group dev

- name: Run adversarial local regression cases
run: uv run python3 benchmarks/safetybench.py --output recovery-regression.json
- name: Verify Docker and prefetch proof image
run: |
docker info
docker pull python:3.12-slim

- uses: actions/upload-artifact@v4
with:
name: local-recovery-regression
path: recovery-regression.json
if-no-files-found: error
retention-days: 7
- name: Run real container-backed proof gates
env:
AGENTDIFF_DOCKER_TESTS: "1"
run: uv run pytest -p no:cacheprovider tests/test_docker_integration.py -v -rs

package:
name: Package validation
runs-on: ubuntu-latest
needs: [tests, quality, security, docs, safetybench]
needs: [tests, quality, security, safetybench, docker-proof]
timeout-minutes: 10

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- uses: astral-sh/setup-uv@v5
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.12.5"
enable-cache: true
python-version: "3.12"
cache-dependency-glob: uv.lock
Expand Down Expand Up @@ -238,9 +239,9 @@ jobs:
/tmp/agentdiff-wheel/bin/agentdiff policy validate --policy /tmp/agentdiff.yaml
/tmp/agentdiff-wheel/bin/agentdiff-demo --json > /tmp/agentdiff-demo.json

- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: distributions
path: dist/
if-no-files-found: error
retention-days: 7
retention-days: 7
4 changes: 2 additions & 2 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Initialize CodeQL
uses: github/codeql-action/init@c4dd10e44af883a891fe31ced449bcb4a6728b9b # v3
uses: github/codeql-action/init@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1
with:
languages: python
queries: security-extended

- name: Analyze
uses: github/codeql-action/analyze@c4dd10e44af883a891fe31ced449bcb4a6728b9b # v3
uses: github/codeql-action/analyze@7188fc363630916deb702c7fdcf4e481b751f97a # v4.37.1
with:
category: /language:python
73 changes: 0 additions & 73 deletions .github/workflows/deploy.yml

This file was deleted.

20 changes: 12 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,20 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: astral-sh/setup-uv@e58605a9b6da7c637471fab8847a5e5a6b8df081 # v5
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.11.12"
version: "0.12.5"
python-version: "3.14"
- name: Build from the lockfile
- name: Install build tools from the lockfile
run: uv sync --locked --group build
- name: Build distributions
run: uv build
- name: Validate metadata
run: uvx twine check dist/*
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
run: uv run twine check dist/*
- name: Validate wheel contents
run: uv run check-wheel-contents dist/*.whl
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: release-distributions
path: dist/
Expand All @@ -43,9 +47,9 @@ jobs:
contents: read
id-token: write
steps:
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: release-distributions
path: dist/
- name: Publish through OIDC
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ dmypy.json
# AgentDiff local run artifacts
/.agentdiff/
agentdiff.yaml
!demos/*/agentdiff.yaml
snapshot_*.json
trajectory*.json
report*.json
Expand Down
19 changes: 17 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@

AgentDiff is pre-release software. APIs and artifact schemas may change before the first stable release.

## 0.3.0 (unreleased)
## 0.4.0 (unreleased)

### Added

- **Verified API migration product**: read-only simulation, provider-aware usage scanning, deterministic migration planning, private generation, exact-scope policy, impact analysis, clean-room proof, integrity certificates, and optional verified GitHub pull-request delivery.
- **OpenAI Chat Completions → Responses migration**: current text-only mapping for literal messages and simple response consumers, with explicit fail-closed review gates for tools, streaming, structured output, multimodal content, dynamic messages, wrappers, and other semantic differences.
- **Untrusted generator boundary**: deterministic AST and exact-argv custom generators run against a private sealed source copy; no-op, missing, unexpected, and out-of-policy results cannot inherit a passing raw proof verdict.
- **Migration certificates**: canonical SHA-256 integrity binds the source, repository base, expected and actual files, generator, policy, proof plan/results, patch digest, and evidence capsule; verification distinguishes valid, invalid, stale, and mismatched evidence.
- **Provider intelligence**: data-only provider initialization plus bounded HTTPS fetching with redirect, DNS/IP, time, size, content-type, provenance, cache-validator, and digest controls. Executable plugin code requires trusted metadata and explicit opt-in.
- **Reproducible OpenAI demos**: one supported success fixture and one unsafe-worker fixture that proves unexpected workflow changes force `NOT_PROVEN`.
- **Verified Campaigns (`agentdiff fleet`)**: read-only multi-repository simulation, independent per-repository migration proof, explicit local scope, fail-closed rollup statuses, and a campaign digest bound to child certificate, patch, and proof digests.
- **Zero-touch sidecar (`agentdiff serve` / `wrap` / `hook`)**: a small local HTTP daemon (127.0.0.1, bearer-token auth, no hosted service) that manages transactions, evidence, policy, sandbox selection, proof, retries, promotion, and notifications. `agentdiff wrap -- <agent argv>` runs any coding-agent CLI through the full pipeline; `agentdiff init` bootstraps trust configuration and can start the sidecar.
- **Repository trust compiler (`agentdiff bootstrap` / `init`)**: deterministic inspection of languages, package managers, tests, builds, CI, CODEOWNERS, monorepo layout, agent configs, and lockfiles, compiled into one canonical `agentdiff.yaml`, `.agentdiff/trust.lock`, `.agentdiff/repo-graph.json`, `.agentdiff/proof-plan.json`, and compiled agent instructions (`agentdiff/adapters/*.md`).
- **Impact-aware proof + content-addressed cache**: deterministic import graph (Python/JS-TS/Go/Rust) mapping changed files to affected modules, tests, and build targets; `static`/`targeted`/`full` proof planning with high-risk widening (dependencies, CI, Dockerfiles, build config, agent configs, security paths); integrity-sealed proof cache under `.agentdiff/cache/proof` keyed by base/patch/lock/image/plan digests.
Expand All @@ -15,14 +22,22 @@ AgentDiff is pre-release software. APIs and artifact schemas may change before t

### Changed

- Consolidated API migration verification onto the existing authoritative `ProofEngine`; removed the duplicate verifier path and made `PROVEN` conditional on the combined generator, scope, policy, proof, and evidence result.
- Replaced the MkDocs website with a separate React 19/Vite 8 product and documentation project. Removed MkDocs dependencies, sources, scripts, and deployment workflow from the Python repository.
- Updated package metadata and the public version to 0.4.0; refreshed CI and release actions to pinned Node 24-capable versions.
- `PromotionEngine` accepts an optional `store_root` so a proven patch living in a private workspace capsule can be promoted to the host repository.
- `ProofEngine` accepts an optional content-addressed `cache`, a `base_preparer` (warm snapshot), and a proof `target`; proof results surface `cache_hit`/`cached_from_run`.
- `PatchManifest` exposes a run-independent `content_digest()` so identical patches share proof-cache identity.

### Security

- Verified PR creation replays only sealed patch bytes at the exact certified base, verifies before/after file digests, stages only sealed paths, and never auto-merges.
- Certificates are documented as local integrity evidence, not cryptographic signatures; the default proof backend still requires Docker and fails closed when it is unavailable.
- Trust decisions (policy, risk, proof, promotion, repair routing) remain fully deterministic; Cortex stays outside deterministic trust decisions.
- The host repository is never writable inside the agent sandbox; the proof cache is content-addressed, integrity-sealed, and invalidated by any input change; warm base snapshots are immutable.
- Corrected custom-generator runtime evidence: a private working copy is an observation boundary, not an OS sandbox. Custom commands retain the caller's host permissions and must be trusted until a sandbox-backed generator runtime is configured.
- Campaign config/report/certificate control paths reject symlinks, reports are written atomically, aggregate verdicts are recomputed during verification, and every `PROVEN` child certificate is re-verified against sealed repository evidence.
- Corrected Docker 28 bind-mount syntax so the real container runtime and clean-room proof environment request their writable private workspace without an invalid bare `rw` field.
- The Docker proof backend keeps the host repository unmounted; the proof cache is content-addressed, integrity-sealed, and invalidated by any input change; warm base snapshots are immutable.

## 0.2.0

Expand Down
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ AgentDiff welcomes focused fixes, adversarial tests, documentation improvements,
```bash
git clone https://github.com/kam6l/agentdiff.git
cd agentdiff
uv sync --locked --all-groups
uv sync --locked --all-groups --extra langchain
```

## Change workflow

1. Create a focused branch from `main`.
2. Add a regression test that demonstrates the missing behavior.
3. Implement the smallest complete change.
4. Update `README.md`, `docs_src/`, examples, and security guidance when public behavior changes.
5. Run the local quality gates documented in [the contributor guide](docs_src/contributing.md).
4. Update `README.md`, examples, security guidance, and the separate React documentation project when public behavior changes.
5. Run the local quality gates documented in `README.md`.
6. Open a pull request that states behavior, trust-boundary impact, limitations, and real verification output.

## Security-sensitive changes

Scanner, policy, persistence, process, redaction, and rollback changes require tests for failure and refusal paths—not only success paths. Recovery must preserve current data when identity or post-run equality is uncertain.

Do not commit generated `site/`, coverage, cache, virtual-environment, distribution, or `.agentdiff/` run artifacts.
Do not commit coverage, cache, virtual-environment, distribution, or `.agentdiff/` run artifacts. The product website and React documentation source live in the separate `agentdiff-web` project; this Python repository has no generated website tree.

By participating, you agree to follow the [Code of Conduct](CODE_OF_CONDUCT.md).
Loading