Skip to content

ci: add Delimit governance check for schema changes#39

Open
infracore wants to merge 4 commits intoagents-oss:mainfrom
infracore:add-delimit-governance
Open

ci: add Delimit governance check for schema changes#39
infracore wants to merge 4 commits intoagents-oss:mainfrom
infracore:add-delimit-governance

Conversation

@infracore
Copy link
Copy Markdown

Per the discussion in #21, here's a workflow that runs Delimit on every PR touching the manifest schema. It performs two checks and posts a single PR comment summarizing both.

What it does

1. Generator drift — runs pnpm run schema:export in a sandbox and diffs the regenerated schemas/v1/agent.schema.json against the committed file. Catches the case where the Zod source has been updated but the committed JSON Schema artifact is stale, or vice versa. The committed file is restored before the workflow exits, so the working tree is unmodified.

2. Schema classification — diffs the committed JSON Schema against the base branch and classifies each change as breaking or non-breaking using JSON Schema semantics: property add/remove, required add/remove, type widen/narrow, enum value add/remove, const change, additionalProperties flip, pattern, minLength/maxLength, minimum/maximum, and items type. $ref to #/definitions is resolved.

Advisory mode by default — never fails CI. No API keys, no external services. The action is published at delimit-ai/delimit-action.

Sample output (from a real run on infracore/agentspec)

I ran this workflow on a fork before opening this PR to verify it works end-to-end. Here is the actual rendered PR comment from that run:

### Delimit governance — JSON Schema

**Generator drift:** 2 change(s), 1 breaking

#### Generator drift

Artifact `schemas/v1/agent.schema.json` is stale vs `pnpm run schema:export` output (2 drift change(s), 0.728s to regen).

Re-run the generator and commit the result, or revert the source change.

- 🔴 const_changed at `/properties/apiVersion` — const value changed: 'agentspec.io/v1' → 'agentspec.io/v1alpha1'
- 🟢 enum_value_added at `/properties/spec/properties/compliance/properties/packs/items` — enum value added: 'metadata-quality'

> Advisory mode — CI will not fail. Set `fail_on_breaking: true` or `mode: enforce` to block on breaking changes.

The first change is the v1 → v1alpha1 rename I simulated by editing the Zod source on a test branch.

The second change is real and was already on main when I ran the test. Someone added metadata-quality to the compliance packs enum in the Zod source but the committed schemas/v1/agent.schema.json was not regenerated. The workflow caught it on the first run. Worth a separate cleanup commit.

Notes

  • SHA pin. This pins to a specific commit of delimit-action because it relies on JSON Schema support that lands in the upcoming v1.9.0 release. Once v1.9.0 ships I will follow up to switch the pin to delimit-ai/delimit-action@v1.
  • Pre-1.0 breaking changes are expected on agentspec; the action stays advisory by default and won't fail your CI. Set fail_on_breaking: true later if you want to enforce.
  • Runtime is dominated by pnpm run schema:export (~0.7s in the test run, plus pnpm install). The Delimit diff itself is sub-100ms. Total workflow runtime under 30 seconds on the test fork.
  • Permissions are scoped to contents: read and pull-requests: write for posting the comment.

Closes the spirit of the discussion in #21. Happy to iterate on the trigger paths, broader artifact set, or stricter mode if you want a different shape.

Adds a workflow that runs Delimit on PRs touching the manifest
schema. Two checks: generator drift between Zod source and committed
JSON Schema, plus breaking-change classification on the committed
schema diff. Advisory only, no API keys, runs in under 30 seconds.

Pinned to a SHA pending the v1.9.0 release of delimit-action which
adds first-class JSON Schema support. Will switch to @v1 after that
release ships.

Refs: agents-oss#21
@infracore
Copy link
Copy Markdown
Author

Quick follow-up: v1.9.0 of delimit-action just shipped with the JSON Schema support, so I pushed a commit to this branch switching the pin from the SHA to delimit-ai/delimit-action@v1. No other changes.

with:
spec: schemas/v1/agent.schema.json
mode: advisory
generator_command: pnpm run schema:export
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

thanks @infracore - looked in the meantime to the github repo documentation https://github.com/delimit-ai/delimit-action and couldn't see anything about generator_command and generator_artifact fields, what are they about ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks for flagging that. Both inputs shipped in v1.9.0 but haven't landed in the README yet. I'll get that fixed this week and link back here.

Here's what they do.

generator_command is an optional shell command that regenerates a committed artifact. For agentspec the relevant one is pnpm run schema:export, which rebuilds schemas/v1/agent.schema.json from the Zod source under packages/sdk/src/schema/.

generator_artifact is the path to the file that command produces, for example schemas/v1/agent.schema.json.

When both are set, the action runs generator_command inside the CI sandbox, diffs the regenerated output against the committed generator_artifact, and flags drift. It catches the case where someone edits the Zod source but forgets to re-run the exporter, so the committed JSON Schema silently lags behind the source of truth.

Both checks in this workflow (schema classification vs base branch, and generator drift) are independent. My preference is to keep both since the workflow already has them wired up, but if you'd rather keep scope minimal for the initial merge I can drop the generator_* pair and send drift detection as a follow-up PR. The schema classification check on its own still delivers the breaking-change guard from #21.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Quick follow-up: the README is updated. Both inputs are now in the Inputs table, and there's a new Generator drift detection section with a minimal example and notes on supported generators (Zod → zodToJsonSchema, protobuf, TypeBox).

Shipped in delimit-ai/delimit-action#4. Let me know if anything still looks unclear.

Copy link
Copy Markdown
Contributor

@skokaina skokaina Apr 9, 2026

Choose a reason for hiding this comment

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

Thank you for the update, i have activated the PR build, it failed on the delim governance check

infracore added a commit to delimit-ai/delimit-action that referenced this pull request Apr 8, 2026
Adds rows to the Inputs table for generator_command, generator_artifact,
fail_on_breaking, and webhook_url (all shipped in v1.9.0 but never
documented in the README). Adds a new "Generator drift detection"
section with a minimal YAML example and notes on supported generators
(Zod/zodToJsonSchema, protobuf, TypeBox).

Reported by @skokaina in agents-oss/agentspec#39.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
infracore added a commit to delimit-ai/delimit-action that referenced this pull request Apr 8, 2026
…ing (#4)

* docs: restore README newline rendering

Regression from 0ae02e8 (JSON Schema feature merge) — the committed
README contained literal backslash-n escape sequences instead of real
newlines, so the entire file rendered as one giant paragraph on GitHub
and in the Marketplace listing.

Decodes \n and \t back to real characters. No content changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: document generator_command and generator_artifact inputs

Adds rows to the Inputs table for generator_command, generator_artifact,
fail_on_breaking, and webhook_url (all shipped in v1.9.0 but never
documented in the README). Adds a new "Generator drift detection"
section with a minimal YAML example and notes on supported generators
(Zod/zodToJsonSchema, protobuf, TypeBox).

Reported by @skokaina in agents-oss/agentspec#39.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* ci: grant pull-requests write permission to self-test jobs

The self-test jobs run delimit-action on fixtures and the action
attempts to post a PR comment. Without an explicit permissions block,
GITHUB_TOKEN defaults to read-only under the current org settings, so
the comment POST 403s and the job fails with "Resource not accessible
by integration".

Adds the minimum scopes each job needs: contents:read + pull-requests:write.
Root-cause fix, not a workaround.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: infracore <infracore@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@infracore
Copy link
Copy Markdown
Author

Good news first: the check actually caught a real drift. When it ran pnpm run schema:export it found that schemas/v1/agent.schema.json is stale compared to what the generator produces. The specific change is an added metadata-quality enum value at /properties/spec/properties/compliance/properties/packs/items. That's classified as 🟢 non-breaking (enum additions don't break consumers), and it's advisory, so the intent was "heads up, please regen" rather than "block the PR".

The actual FAILURE is that the step that posts the PR comment got 403 Resource not accessible by integration trying to hit /issues/39/comments. That's a permissions issue on the workflow token. You need to add this to .github/workflows/delimit.yml under the delimit job:

permissions:
  contents: read
  pull-requests: write
  issues: write

Without that, GITHUB_TOKEN defaults to read-only for comments and the bot can't post. On our side, we also have a bug: the action shouldn't fail the whole check when the comment step throws, as long as the analysis verdict is advisory. I'm fixing that this week.

Two things you can do right now to resolve the check:

  1. Run pnpm run schema:export and commit the updated schemas/v1/agent.schema.json — that clears the drift detection
  2. Add the permissions block above — that lets Delimit post its comment on future runs

Let me know if you want me to open a PR against your workflow file with the permissions fix, happy to do it.

infracore added a commit to delimit-ai/delimit-action that referenced this pull request Apr 10, 2026
…D-807)

LED-807 (P0 fix): unblocks agents-oss/agentspec#39 outreach conversion.

External maintainer @skokaina hit a live 403 hang on 2026-04-09 when
the comment-post step in action.yml unhandled-threw on
'Resource not accessible by integration'. The cause: consumer
workflows that do not grant 'permissions: pull-requests: write' get
a 403 from github.rest.issues.createComment, which the github-script
step did not handle.

Fix:
- Both comment paths (JSON Schema branch + OpenAPI branch) are now
  wrapped in try/catch.
- 403 → emits core.warning and continues (the dedicated 'Enforce
  breaking change policy' step still runs and still gates).
- Non-403 → rethrows so real errors still surface.

Tests: 9 new tests in tests/test_action_yml_comment_403.py covering
both branches and the no-rethrow guarantee. Suite total: 195 passing.

LED-807

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

2 participants