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
15 changes: 15 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,18 @@ updates:
# with agt_ref as one deliberate change, so a Dependabot bump of the SDK
# alone would always go red in CI.
- dependency-name: "agent-control-specification*"

# The adapters are their own uv project, with their own lockfile, so the docs
# build never resolves NAT's dependency tree.
- package-ecosystem: "uv"
directory: "/adapters"
schedule:
interval: "weekly"
day: "monday"
cooldown:
default-days: 7
open-pull-requests-limit: 5
commit-message:
prefix: "deps"
labels:
- "dependencies"
124 changes: 124 additions & 0 deletions .github/workflows/adapter_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
name: adapter-tests

# Runs the adapter and conformance suites, and checks the built package,
# on every push or PR that touches adapter or spec source.

on:
push:
paths:
- 'adapters/**'
- 'specification/**'
- 'docs/spec/**'
- '.github/workflows/adapter_tests.yml'
pull_request:
paths:
- 'adapters/**'
- 'specification/**'
- 'docs/spec/**'
- '.github/workflows/adapter_tests.yml'

permissions:
contents: read

defaults:
run:
# Explicit bash turns on pipefail, so a failing command in a pipeline fails the step.
shell: bash

jobs:
dco:
# Every commit needs a Signed-off-by trailer (the DCO in CONTRIBUTING.md).
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
fetch-depth: 0
- name: Check Signed-off-by on every PR commit
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
missing=0
while read -r sha; do
if ! git log -1 --format=%B "$sha" | grep -qi '^Signed-off-by: .*<.*@.*>'; then
echo "::error::commit $sha has no Signed-off-by trailer (CONTRIBUTING.md DCO)"
missing=1
fi
done < <(git rev-list "$BASE_SHA..$HEAD_SHA" --no-merges)
exit $missing

tests:
# Every suite, with the NAT extra installed so NAT tests run. run_conformance.py
# reports passed, skipped and failed separately and fails on any skip outside
# its allowlist (only the manual Cursor procedure).
runs-on: ubuntu-latest
timeout-minutes: 30
defaults:
run:
working-directory: adapters
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.9.9"
- name: Install the adapters, the NAT extra and the test group from the lockfile
run: uv sync --locked --python 3.12 --extra nat --group test
- name: Run every suite
run: uv run python run_conformance.py claude cursor nat

tests-without-nat:
# The documented setup for Claude Code and Cursor users, who never install NAT.
runs-on: ubuntu-latest
timeout-minutes: 20
defaults:
run:
working-directory: adapters
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.9.9"
- name: Install the adapters and the test group, without the NAT extra
run: uv sync --locked --python 3.12 --group test
- name: Run the shared and Claude Code and Cursor suites
run: uv run python run_conformance.py claude cursor
- name: Check that imports flow integrations, client, core
run: uv run lint-imports

package:
# Builds the sdist and a wheel from it, then installs the wheel outside the
# repository and checks the console scripts, entry points, bundled schemas
# and NAT discovery that users depend on.
# Runs on the oldest supported Python as well as the one the tests use.
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
python: ["3.11", "3.12"]
env:
PYTHON: ${{ matrix.python }}
defaults:
run:
working-directory: adapters
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
version: "0.9.9"
- name: Build the sdist and a wheel from it
run: uv build --python "$PYTHON" -o dist
- name: Install the wheel outside the repository and check it
run: uv run --no-project --python "$PYTHON" python scripts/check_wheel.py dist/acs_adapters-*-py3-none-any.whl
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,23 @@ references/
# Python build artifacts from `uv pip install -e .`
*.egg-info/
__pycache__/
**/__pycache__/
*.pyc

# Subagent-driven development scratch. Never committed.
.superpowers/
_site/

# Browser session logs. Never committed.
.playwright-mcp/

# Adapter manual-test scratch dirs (project-level hook configs with
# machine-specific paths from local probing — must never land in commits)
adapters/*/.cursor/
adapters/*/.claude/
adapters/*/.acs-handshake-cache/

# Python venvs (NAT manual test environment lives here; the path is
# tied to the machine that built it and must not ship)
adapters/*/.venv/
adapters/*/.nat-venv/
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,16 @@ The guards in `tests/` check things the build itself will not catch, including s

Put new guards in `tests/`. Collection is scoped there by `testpaths` in `pyproject.toml`, so a test written anywhere else never runs in CI and will pass review looking like coverage it does not provide. A suite that needs dependencies outside `uv.lock` belongs in its own workflow with its own environment, because the deploy gate installs only what the lockfile carries.

For changes under `adapters/` (the reference adapters, example Guardian, and their test suites), run the adapter conformance gate before opening a PR — it lives in its own workflow (`.github/workflows/adapter_tests.yml`) with its own environment, per the rule above:

```bash
cd adapters # its own uv project and lockfile
uv sync --locked --extra nat --group test
uv run python run_conformance.py claude cursor nat # shared checks + those adapter suites
```

Without the NAT runtime, sync without `--extra nat` and leave `nat` off the command. The command reports passes, skips, and failures separately, and fails on any failure or unexpected skip. The same workflow also builds the package and checks the installed wheel outside the repository (`adapters/scripts/check_wheel.py`). See `adapters/README.md` for what the suite proves and its scope.

For prose contributions, follow the [editorial style guide](./STYLE.md). For schema contributions, validate `specification/v0.1.0/acs_schema.json` against the JSON Schema spec before submitting.

All submissions go through GitHub pull request review. See [GitHub's PR guide](https://docs.github.com/en/pull-requests) if you're new to the workflow.
Expand Down
3 changes: 3 additions & 0 deletions adapters/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__pycache__/
*.pyc
*.pyo
Loading
Loading