Skip to content

ci: add contract lint and example gate - #11

Merged
jaavid merged 5 commits into
mainfrom
agent/document-repository-entrypoints
Jul 25, 2026
Merged

ci: add contract lint and example gate#11
jaavid merged 5 commits into
mainfrom
agent/document-repository-entrypoints

Conversation

@jaavid

@jaavid jaavid commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add dependency-free public contract lint
  • validate Postman collection/environment JSON in the workflow
  • document structural gate versus runtime parity

Verification

  • ruby scripts/lint_contracts.rb passed
  • OpenAPI YAML parse passed
  • public compatibility checker passed
  • git diff --check passed

Advances #3; API-05 remains open until API-02 through API-04 and runtime parity are complete.

@jaavid
jaavid merged commit 7cc2132 into main Jul 25, 2026
1 check passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2c01992125

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/lint_contracts.rb
require "yaml"

PUBLIC_SPEC = "openapi/corelink-public-v1.yaml"
OPERATIONS = %w[get put post patch delete head options].freeze

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include TRACE in the operation lint

OpenAPI 3.1.1 permits trace operations, but this allowlist omits that method. If a public path adds a TRACE operation, the lint reports success even when the operation lacks operationId, x-corelink-stability, or responses, bypassing the checks this gate is intended to enforce.

Useful? React with 👍 / 👎.

Comment thread scripts/lint_contracts.rb
require "json"
require "yaml"

PUBLIC_SPEC = "openapi/corelink-public-v1.yaml"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Lint every versioned public contract

When a breaking change is correctly introduced in a new document such as corelink-public-v2.yaml, the workflow runs because its path filter matches corelink-public-v*.yaml, but this constant still points only to v1; the parse step in .github/workflows/contract-compatibility.yml is also hard-coded to v1. Consequently, the new major document receives no YAML or operation lint and the job can pass even if that document is malformed or lacks the required operation metadata.

Useful? React with 👍 / 👎.

| Public HTTP API | `openapi/corelink-public-v1.yaml` | `1.0.0-draft` | OpenAPI syntax + public diff checker | Draft reviewed; runtime parity is a separate gate |
| Admin HTTP API | `openapi/corelink-admin-v1.yaml` | `1.0.0-draft` | OpenAPI syntax + authorization review | Internal draft; not a public release |
| Internal HTTP API | `openapi/corelink-internal-v1.yaml` | `1.0.0-draft` | OpenAPI syntax + service ownership review | Internal draft; not a public release |
| Events | `asyncapi/corelink-events-v1.yaml` | `1.0.0-draft` | AsyncAPI validation + event envelope review | Draft; delivery/replay evidence remains platform-owned |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not claim AsyncAPI validation before it runs

The checked workflow only calls YAML.safe_load for asyncapi/corelink-events-v1.yaml at .github/workflows/contract-compatibility.yml:28; neither the new lint nor another repository check validates the document against the AsyncAPI specification. An AsyncAPI-invalid but syntactically valid YAML document therefore passes while this matrix tells release consumers that AsyncAPI validation is a gate, so this should say YAML syntax parsing or the workflow should add a real validator.

Useful? React with 👍 / 👎.

Comment thread README.md
contract. SDKs and the mock server may consume this draft only in prerelease
channels; it is not a release claim until runtime parity and CI checks land.

The immutable baseline tag is `v1.0.0-draft`. See the

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Publish the baseline tag before advertising it

The reviewed repository has no refs/tags/v1.0.0-draft, and the target commit is not pointed to by such a tag. SDK, CLI, and mock-server consumers directed here to pin the immutable baseline therefore cannot resolve it; publish the tag as part of this release or describe the draft by an existing commit until the tag is available.

Useful? React with 👍 / 👎.

Comment on lines +9 to +10
| Admin HTTP API | `openapi/corelink-admin-v1.yaml` | `1.0.0-draft` | OpenAPI syntax + authorization review | Internal draft; not a public release |
| Internal HTTP API | `openapi/corelink-internal-v1.yaml` | `1.0.0-draft` | OpenAPI syntax + service ownership review | Internal draft; not a public release |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Trigger checks for admin and internal contract changes

These rows state that the admin and internal contracts have OpenAPI syntax gates, but the pull-request path filters in .github/workflows/contract-compatibility.yml:4-12 only match public OpenAPI files. A PR that changes only corelink-admin-v1.yaml or corelink-internal-v1.yaml therefore skips the workflow entirely and can merge malformed YAML despite the documented gate; add those files to the trigger or do not report the gate as active.

Useful? React with 👍 / 👎.

Comment thread scripts/lint_contracts.rb
Comment on lines +18 to +20
paths.each do |path, path_item|
OPERATIONS.each do |method|
operation = path_item[method]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Dereference reusable path items before linting

OpenAPI 3.1 permits a path entry to reference a reusable Path Item, but this loop only inspects HTTP-method keys directly present on the entry. If an operation is moved under a $ref such as one targeting components.pathItems, no operation is visited and the lint passes even when the referenced operation lacks the required ID, stability marker, or responses; resolve path-item references before iterating or reject them explicitly.

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant