Skip to content

Conversation

@Umair0343
Copy link

@Umair0343 Umair0343 commented Sep 30, 2025

User description

What’s included

  • New agent api-contract-guardian to detect and gate breaking API changes across OpenAPI 3.x and GraphQL SDL
  • CI example for GitHub Actions
  • Local sample schemas for quick smoke tests
  • README with usage, cross-repo instructions, allowlist format, and outputs

Why

  • Breaking API changes are costly and often slip through code review
  • This agent provides a contract-first safety net for multi-service and multi-repo setups
  • Aligns with contest guidance by verifying function/tool flows and structured outputs

How it works

  • Diffs current branch schemas against a baseline (default main)
  • Flags breaking vs non-breaking by spec-aware rules:
    • OpenAPI: operation/response removals, required property adds, enum removals, status/content-type removals, type narrowing
    • GraphQL: field/type removals, non-null tightening, enum removals, required arg additions w/o defaults
  • Supports allowlist exceptions with IDs and optional expirations
  • Enforces policy via fail_on and exit_expression

Key features

  • Multi-spec support: OpenAPI + GraphQL
  • Monorepo-aware: groups by service/workspace
  • Structured JSON output: summary, findings[], approved, requires_changes
  • CI-ready, zero-code setup (TOML-only)

Local usage

npm i -g @qodo/command
qodo api_contract_guardian \
  --agent-file=agents/api-contract-guardian/agent.toml \
  --set openapi_paths="**/openapi.{yml,yaml,json}" \
  --set graphql_paths="**/*.{graphql,gql}" \
  --set target_branch=main \
  --set fail_on=major

Diagram Walkthrough

flowchart TD
    A[Start: Run Agent] --> B[Load agent.toml config]
    B --> C{Discover schema globs provided?}
    C -->|Yes| D[Find OpenAPI/GraphQL files via globs]
    C -->|No| E[Use sensible default globs and discover files]
    D --> F[Checkout/read baseline from target_branch - default main]
    E --> F
    F --> G{Baseline available?}
    G -->|Yes| H[Parse schemas - current vs baseline]
    G -->|No| I[Treat as initial introduction; mark non-breaking unless configured]
    H --> J{Any parse errors?}
    J -->|Yes| K[Record critical findings and continue]
    J -->|No| L[Diff schemas with spec-aware rules]
    I --> M[Summarize as non-breaking introductions]
    L --> N{Breaking changes found?}
    N -->|Yes| O[Check allowlist IDs/expirations; downgrade/ignore where matched]
    N -->|No| M
    O --> P[Compile findings + migration guidance]
    M --> Q[Build summary: files, services, severities]
    P --> Q
    Q --> R[Emit structured JSON: summary, findings, approved, requires_changes]
    R --> S[Apply policy: fail_on + exit_expression]
    S --> T{Approved?}
    T -->|Yes| U[Pass CI/CD]
    T -->|No| V[Requires changes; block merge]
    U --> W[End]
    V --> W[End]
Loading

PR Type

Enhancement


Description

  • Add API contract guardian agent for OpenAPI/GraphQL breaking changes

  • Include CI integration example for GitHub Actions

  • Provide sample schemas for testing and validation

  • Support allowlist exceptions with expiration dates


Diagram Walkthrough

flowchart LR
  A["Schema Discovery"] --> B["Baseline Comparison"]
  B --> C["Breaking Change Detection"]
  C --> D["Allowlist Filtering"]
  D --> E["CI Policy Enforcement"]
Loading

File Walkthrough

Relevant files
Documentation
README.md
Complete documentation for API contract guardian                 

agents/api-contract-guardian/README.md

  • Add comprehensive documentation for API contract guardian
  • Include installation, usage, and CI integration instructions
  • Provide examples for local testing and cross-repo usage
  • Document allowlist format and GitHub Actions workflow
+111/-0 
Enhancement
agent.toml
Core agent configuration and schema definition                     

agents/api-contract-guardian/agent.toml

  • Define agent configuration with OpenAPI/GraphQL support
  • Implement breaking change detection rules and severity levels
  • Configure structured JSON output schema with findings
  • Set up git and filesystem tools for schema comparison
+102/-0 
Configuration changes
github-actions.yml
GitHub Actions CI integration example                                       

agents/api-contract-guardian/examples/ci/github-actions.yml

  • Add GitHub Actions workflow for PR validation
  • Configure checkout with full git history for comparison
  • Set up Node.js environment and Qodo command installation
+24/-0   
Tests
openapi.yaml
Sample OpenAPI specification for testing                                 

agents/api-contract-guardian/examples/samples/openapi.yaml

  • Add sample OpenAPI 3.0.3 specification for testing
  • Define basic users API with GET endpoint
  • Include response schema with user object properties
+23/-0   
schema.graphql
Sample GraphQL schema for testing                                               

agents/api-contract-guardian/examples/samples/schema.graphql

  • Add sample GraphQL schema definition for testing
  • Define User type with required ID and name fields
  • Include Query type with users field returning array
+9/-0     

@qodo-merge-for-open-source
Copy link
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Hardcoded Paths

Local usage docs include absolute, user-specific paths which can confuse users and break copy-paste; consider using repo-relative paths or environment variables.

cd /Users/muhammadumairshahid/agents
qodo api_contract_guardian \
  --agent-file=agents/api-contract-guardian/agent.toml \
  --set openapi_paths="**/openapi.{yml,yaml,json}" \
  --set graphql_paths="**/*.{graphql,gql}" \
  --set target_branch=main \
  --set fail_on=major

</details>

<details><summary><a href='https://github.com/qodo-ai/agents/pull/34/files#diff-3abfeb4c7a4f9a506c1d7a02ee5c7427c1ea92edc9ae4ff40c2f309f7e9968dfR70-R95'><strong>Missing Input Docs</strong></a>

README references allowlist and CI flags but omits explanation for the --ci flag behavior and allowlist file discovery/format nuances; clarify usage and precedence with examples.
</summary>

```markdown
### CI: GitHub Actions (example)
```yaml
name: API Contract Guardian
on:
  pull_request:
    branches: [ main ]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm i -g @qodo/command
      - name: Run API Contract Guardian
        run: |
          qodo api_contract_guardian \
            --agent-file=agents/api-contract-guardian/agent.toml \
            --set openapi_paths="**/openapi.{yml,yaml,json}" \
            --set graphql_paths="**/*.{graphql,gql}" \
            --set target_branch=${{ github.base_ref || 'main' }} \
            --ci

</details>

<details><summary><a href='https://github.com/qodo-ai/agents/pull/34/files#diff-f03897bf1f22262a419ed7327b8b3aa2d5a4272ca94554141f1ac28b5b9a18e0R56-R101'><strong>Output Schema Strictness</strong></a>

output_schema requires summary and findings, but does not constrain numeric minimums or handle empty baselines; ensure generator can always populate required fields to avoid runtime validation failures.
</summary>

```toml
output_schema = """
{
  "type": "object",
  "properties": {
    "summary": {
      "type": "object",
      "description": "Summary statistics for files and services compared, and severities encountered",
      "properties": {
        "services": {"type": "number"},
        "files_compared": {"type": "number"},
        "breaking": {"type": "number"},
        "non_breaking": {"type": "number"},
        "severity_max": {"type": "string", "enum": ["none","minor","moderate","major","critical"]}
      },
      "required": ["files_compared","breaking","non_breaking","severity_max"]
    },
    "findings": {
      "type": "array",
      "description": "List of detected API contract changes with severity and recommendations",
      "items": {
        "type": "object",
        "properties": {
          "type": {"type": "string", "enum": ["openapi","graphql"]},
          "service": {"type": "string"},
          "file": {"type": "string"},
          "path": {"type": "string", "description": "Schema path, e.g., /users GET or GraphQL Type.Field"},
          "category": {"type": "string"},
          "severity": {"type": "string", "enum": ["minor","moderate","major","critical"]},
          "title": {"type": "string"},
          "description": {"type": "string"},
          "recommendation": {"type": "string"},
          "allowed_by": {"type": "string", "description": "Allowlist rule id if matched"}
        },
        "required": ["type","file","category","severity","title","description"]
      }
    },
    "approved": {"type": "boolean", "description": "True if the change set passes the configured severity policy"},
    "requires_changes": {"type": "boolean", "description": "True if authors must address reported breaking changes"}
  },
  "required": ["summary","findings","approved","requires_changes"]
}
"""

exit_expression = "approved"


@qodo-merge-for-open-source
Copy link
Contributor

qodo-merge-for-open-source bot commented Sep 30, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Use programmatic tools for diffing

The agent's reliance on an LLM for detecting breaking API changes is unreliable
for CI. It should instead orchestrate deterministic, specialized tools like
openapi-diff and graphql-inspector for this task.

Examples:

agents/api-contract-guardian/agent.toml [6-43]
instructions = """
You are an API contract guardian. Your job is to detect, explain, and gate breaking API changes across services and repositories.

Scope:
- Compare current branch API schemas (OpenAPI 3.x JSON/YAML and GraphQL SDL) against the target branch (default: main) or a baseline file.
- Report all breaking changes with severity, location, and human‑readable guidance.
- Suggest migration notes and safe upgrade paths.
- Optionally allow documented exceptions via an allowlist file.

Inputs:

 ... (clipped 28 lines)

Solution Walkthrough:

Before:

# agent.toml
instructions = """
You are an API contract guardian. Your job is to detect, explain, and gate breaking API changes...

Process:
1. Discover schema files from provided paths...
2. Checkout and read baseline schemas from target_branch.
3. Diff schemas using specialized rules per spec.
4. Summarize breaking vs non‑breaking deltas...
...
"""
tools = ["git", "filesystem"]
execution_strategy = "act" # LLM-driven execution

After:

# Conceptual agent logic (not in TOML)
function run_api_guardian(args) {
  // 1. Discover files using filesystem tool
  const files = find_files(args.openapi_paths, args.graphql_paths);
  
  // 2. Get baseline versions using git tool
  const baseline_files = get_baseline_files(files, args.target_branch);

  // 3. Diff using specialized, deterministic tools
  let findings = [];
  for (file in files) {
    const diff_output = shell.exec(`specialized-diff-tool ${baseline_files[file]} ${file}`);
    findings.push(...parse_tool_output(diff_output));
  }

  // 4. Apply allowlist and generate report
  // ...
}
Suggestion importance[1-10]: 10

__

Why: This suggestion correctly identifies a critical architectural flaw, as using an LLM for a deterministic task like API schema diffing is unreliable for a CI gate, making the agent's core purpose fundamentally unviable.

High
Possible issue
Make finding path a required field

In the agent.toml output schema, make the path property a required field within
the findings items to ensure all reported changes are actionable.

agents/api-contract-guardian/agent.toml [89]

-"required": ["type","file","category","severity","title","description"]
+"required": ["type","file","path","category","severity","title","description"]
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies that the path field, which is crucial for locating a reported API change, is missing from the required fields in the output schema, making findings potentially unactionable.

Medium
Remove hardcoded user-specific paths

Replace the hardcoded absolute paths in the README.md file's examples with
relative paths or placeholders to make them universally applicable.

agents/api-contract-guardian/README.md [36-42]

-cd /Users/muhammadumairshahid/agents
+# Assuming this command is run from the root of the repository
 qodo api_contract_guardian \
   --agent-file=agents/api-contract-guardian/agent.toml \
   --set openapi_paths="**/openapi.{yml,yaml,json}" \
   --set graphql_paths="**/*.{graphql,gql}" \
   --set target_branch=main \
   --set fail_on=major
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies that the documentation examples contain hardcoded, user-specific absolute paths, which makes them non-portable and unusable for other developers.

Low
  • Update

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant