Skip to content
18 changes: 18 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,24 @@ repos:
^generated/provider_dependencies\.json$
require_serial: true
pass_filenames: false
- id: extract-agent-skills
name: Extract and validate Agent Skills from AGENTS.md
language: python
entry: python scripts/ci/pre_commit/extract_agent_skills.py
files: ^AGENTS\.md$|^contributing-docs/.*\.rst$
pass_filenames: false
- id: check-agent-skills-drift
name: Check Agent Skills manifest is in sync
language: python
entry: python scripts/ci/pre_commit/extract_agent_skills.py --check
files: ^AGENTS\.md$|^contributing-docs/.*\.rst$|^contributing-docs/agent_skills/skills\.json$
pass_filenames: false
- id: generate-skill-graph
name: Generate Agent Skills dependency graph
language: python
entry: python scripts/ci/pre_commit/skill_graph.py
files: ^contributing-docs/agent_skills/skills\.json$
pass_filenames: false
- id: check-example-dags-urls
name: Check that example dags url include provider versions
entry: ./scripts/ci/prek/update_example_dags_paths.py
Expand Down
130 changes: 130 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,133 @@ Remind the user to:
- [`contributing-docs/08_static_code_checks.rst`](contributing-docs/08_static_code_checks.rst)
- [`contributing-docs/12_provider_distributions.rst`](contributing-docs/12_provider_distributions.rst)
- [`contributing-docs/19_execution_api_versioning.rst`](contributing-docs/19_execution_api_versioning.rst)

## Agent Skills

The following structured skill blocks extend this document
with machine-readable, executable workflow definitions.
See `contributing-docs/agent_skills/` for the full
generated manifest.

.. agent-skill::
:id: setup-breeze-environment
:context: host
:category: environment
:prereqs: docker, python>=3.9
:validates: breeze-env-ready
:description: Start the Airflow Breeze development
environment

.. code-block:: bash

breeze start-airflow

.. agent-skill-expected-output::

Airflow webserver at http://localhost:28080
Login: admin / admin

.. agent-skill::
:id: run-single-test
:context: host
:category: testing
:prereqs: setup-breeze-environment
:validates: tests-pass
:fallback: breeze run pytest {test_path} -xvs
:fallback_condition: missing_system_deps
:description: Run a single test with uv, falling back
to breeze if system deps are missing

.. code-block:: bash

# Primary: uv (no Docker needed, faster)
uv run --project {project} pytest {test_path} -xvs
# Fallback: only when system deps missing
# breeze run pytest {test_path} -xvs

.. agent-skill-expected-output::

PASSED

.. agent-skill::
:id: run-static-checks
:context: host
:category: linting
:prereqs: setup-breeze-environment
:validates: static-checks-pass
:description: Run fast static checks with prek

.. code-block:: bash

prek run --from-ref main --stage pre-commit

.. agent-skill-expected-output::

All checks passed.

.. agent-skill::
:id: run-manual-checks
:context: host
:category: linting
:prereqs: run-static-checks
:validates: manual-checks-pass
:description: Run slower manual checks with prek

.. code-block:: bash

prek run --from-ref main --stage manual

.. agent-skill-expected-output::

All checks passed.

.. agent-skill::
:id: build-docs
:context: host
:category: documentation
:prereqs: setup-breeze-environment
:validates: docs-build-clean
:description: Build Airflow documentation locally

.. code-block:: bash

breeze build-docs

.. agent-skill-expected-output::

Build finished. The HTML pages are in _build/html.

.. agent-skill::
:id: run-provider-tests
:context: host
:category: testing
:prereqs: setup-breeze-environment
:validates: provider-tests-pass
:description: Run complete test suite for a
specific provider

.. code-block:: bash

breeze testing providers-tests
--test-type "Providers[{provider}]"

.. agent-skill-expected-output::

All tests passed.

.. agent-skill::
:id: run-type-check
:context: host
:category: linting
:prereqs: setup-breeze-environment
:validates: type-check-pass
:description: Run mypy type checking on
changed files

.. code-block:: bash

breeze run mypy {path}

.. agent-skill-expected-output::

Success: no issues found
37 changes: 37 additions & 0 deletions contributing-docs/03_contributors_quick_start.rst
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,43 @@ can be sure that all the tests are run in the same environment as tests in CI.

All Tests are inside ./tests directory.

The following agent-skill documents the recommended way to run tests (uv first, then Breeze fallback):

.. agent-skill::
:id: run-tests-uv-first
:context: host
:category: testing
:prereqs: setup-breeze-environment
:validates: tests-pass
:description: Run tests with uv, fall back to
Breeze if system deps missing

.. code-block:: bash

uv run --project {project} pytest {test_path} -xvs
# fallback: breeze run pytest {test_path} -xvs

.. agent-skill-expected-output::

PASSED

.. agent-skill::
:id: run-static-checks-prek
:context: host
:category: linting
:prereqs: setup-breeze-environment
:validates: static-checks-pass
:description: Run fast pre-commit static checks
on changed files using prek

.. code-block:: bash

prek run --from-ref main --stage pre-commit

.. agent-skill-expected-output::

All checks passed.

- Running Unit tests inside Breeze environment.

Just run ``pytest filepath+filename`` to run the tests.
Expand Down
90 changes: 90 additions & 0 deletions contributing-docs/agent_skills/DX_REPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Developer Experience Report: Agent Skills Impact

## Overview

This report documents the practical difference between
an AI agent contributing to Airflow with and without
Agent Skills, based on the workflows defined in AGENTS.md.

## Test Scenario

New contributor task: "Fix a bug in the Kafka provider
and run the relevant tests."

## Without Agent Skills

An AI agent reading only prose documentation encounters
these failure points:

### Failure 1: Host vs Container Confusion
AGENTS.md says "Never run pytest directly on host"
but does not structure this as machine-readable context.
An agent reading the file may miss this constraint and
suggest:
pytest providers/apache/kafka/tests/ -xvs
Result: fails with missing system dependencies or
wrong environment error.

Correct command (from AGENTS.md):
uv run --project providers/apache/kafka pytest
providers/apache/kafka/tests/ -xvs
Or if system deps missing:
breeze run pytest providers/apache/kafka/tests/ -xvs

### Failure 2: Wrong Static Check Command
Agent may suggest running ruff directly:
ruff check .
Instead of the correct prek-based workflow:
prek run --from-ref main --stage pre-commit
Result: misses project-specific hook configuration,
produces different results than CI.

### Failure 3: Unclear Execution Order
Without structured prereqs, agent cannot determine
that static checks should pass before running tests,
or that Breeze must be running before breeze-context
commands work.
Result: agent suggests commands in wrong order,
contributor gets confusing errors.

## With Agent Skills

Each skill block in AGENTS.md provides:
- :context: field — agent knows exactly where to run
- :prereqs: field — agent knows correct execution order
- :validates: field — agent knows what success looks like
- :expected_output: — agent can verify the command worked

### Resolution of Failure 1
run-single-test skill specifies :context: host and
provides both uv and breeze fallback commands explicitly.
Agent always suggests the correct command for the context.

### Resolution of Failure 2
run-static-checks skill specifies the exact prek command
with correct flags. No ambiguity about which tool to use.

### Resolution of Failure 3
Dependency graph from prereqs fields gives agent a
clear execution order:
setup-breeze-environment → run-static-checks →
run-manual-checks

## Measured Improvement

| Failure Mode | Without Skills | With Skills |
|---|---|---|
| Host/container confusion | High risk | Eliminated |
| Wrong tool suggestion | Medium risk | Eliminated |
| Wrong execution order | High risk | Eliminated |
| Unverifiable success | Always | Never |

## Limitations & Next Steps

Current skills cover 5 workflows. Full coverage of
Airflow's contributor workflows would require ~20 skills.
Once the extraction pipeline is stable, adding skills
is a "copy & paste" operation as Jason noted.

The verification suite (confirming skills stay accurate
as Airflow evolves) is the most important remaining piece.
31 changes: 31 additions & 0 deletions contributing-docs/agent_skills/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Agent Skills

Machine-readable contributor workflow skills extracted
automatically from contributing-docs/*.rst files.

## What is a Skill?

A `.. agent-skill::` block embedded in an RST contributing
doc. Skills extend AGENTS.md with executable,
schema-validated, verifiable workflow steps.

## The :context: field

The most critical field. Tells an AI agent whether a
command runs on the HOST or inside BREEZE:

- `host` — run on your local machine
- `breeze` — run inside `breeze shell`
- `either` — works in both

This directly addresses the warning in AGENTS.md:
"Never run pytest, python, or airflow commands directly
on the host — always use breeze."

## How skills.json is generated

A pre-commit hook (extract-agent-skills) runs automatically
when contributing-docs/*.rst files change. It extracts all
agent-skill blocks and regenerates this file.

Mirrors the update-breeze-cmd-output hook pattern.
71 changes: 71 additions & 0 deletions contributing-docs/agent_skills/skill_graph.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"nodes": [
{
"id": "setup-breeze-environment",
"category": "environment",
"context": "host"
},
{
"id": "run-single-test",
"category": "testing",
"context": "host"
},
{
"id": "run-static-checks",
"category": "linting",
"context": "host"
},
{
"id": "run-manual-checks",
"category": "linting",
"context": "host"
},
{
"id": "build-docs",
"category": "documentation",
"context": "host"
},
{
"id": "run-provider-tests",
"category": "testing",
"context": "host"
},
{
"id": "run-type-check",
"category": "linting",
"context": "host"
}
],
"edges": [
{
"from": "run-single-test",
"to": "setup-breeze-environment",
"type": "requires"
},
{
"from": "run-static-checks",
"to": "setup-breeze-environment",
"type": "requires"
},
{
"from": "run-manual-checks",
"to": "run-static-checks",
"type": "requires"
},
{
"from": "build-docs",
"to": "setup-breeze-environment",
"type": "requires"
},
{
"from": "run-provider-tests",
"to": "setup-breeze-environment",
"type": "requires"
},
{
"from": "run-type-check",
"to": "setup-breeze-environment",
"type": "requires"
}
]
}
Loading
Loading