Skip to content

Spec-sync pipeline (Problem 3) — build first, before V2 #97

Description

@yzld2002

Full plan: docs/superpowers/plans/2026-07-07-spec-sync-pipeline-ade-python.md (10 tasks with complete scripts + workflow YAML). This is the summary.

Scope: ade-python only (the doc says prove the loop here first, then port to ade-typescript). This is Problem 3 — sequenced first, before the V2 SDK code (Problem 2), per the build-order note on #95.

Goal

Replace Stainless's codegen/release machinery with an unattended pipeline that mechanically tracks the live OpenAPI spec, opens a two-phase PR on drift, and gates it so the released public surface can never change silently.

How it works

A scheduled workflow (spec-sync.yml, cron ~6h + manual dispatch) fetches + normalizes the live spec, diffs vs a committed snapshot (specs/v1-ade.json), and on drift creates one branch with two attributed commits:

  1. Mechanical — updated snapshot + regenerated reference models (datamodel-code-generator).
  2. AIanthropics/claude-code-action (automation mode) wires resources/methods/tests/docs from the diff, following existing conventions.

PR gates (ordinary checks, human review required to merge):

  • surface-lock (griffe) — baseline = last release tag; any change to released surface fails mechanically. This is what makes the AI step safe to run unattended.
  • contract-tests vs staging · existing lint/test/typecheck.

Staging in, production out: automation targets the staging spec; a release gate checks the production spec, so a staging-only feature holds the release train until it reaches prod or is reverted.

Key adaptation from the design doc

This repo's V1 types are Stainless-shaped, hand-maintained, backward-compat-guaranteed. So datamodel-code-generator output is committed under specs/_generated/ as a reference the AI phase reads and reviewers skim — not shipped, not a replacement for src/landingai_ade/types/*. The AI writes the actual shipped code in existing conventions (mirror resources/parse_jobs.py); surface-lock guarantees it stays additive.

Verified during planning

  • V1 specs return 200 at both api.va.landing.ai (prod) and api.va.staging.landing.ai (staging) → the V1 loop is unblocked today, no aide dependency.
  • Real drift exists: the spec has /v1/ade/extract/jobs routes the SDK doesn't implement — the doc's named inaugural proof-run.

Token gotcha (baked in)

Commits pushed with the default GITHUB_TOKEN don't trigger other workflows (anti-recursion), so gates wouldn't run on the sync PR. The workflow mints a GitHub App installation token and uses it for checkout/push/PR — which does trigger the gate workflows.

Task breakdown (10)

  1. Fetch/normalize script + committed specs/v1-ade.json baseline.
  2. Drift detector (check-drift.sh, exit 10 = drift).
  3. Reference-model codegen (datamodel-code-generator, deterministic).
  4. Surface-lock gate (griffe vs last release tag).
  5. Contract tests vs staging (contract marker, skips without key).
  6. Two-phase spec-sync.yml (mechanical + AI, app-token push, opens PR).
  7. pr-gates.yml (surface-lock + contract-tests).
  8. Inaugural proof run — supersede PR feat: add async extract jobs support to SDK #93 (generate extract/jobs via the pipeline, compare to feat: add async extract jobs support to SDK #93, close feat: add async extract jobs support to SDK #93). Decision: supersede.
  9. Release gate — staging-in/production-out (depends on Problem 1 release-please).
  10. Docs + ade-typescript port note.

Dependencies

  • Problem 1 (get off Stainless) needed for the publish tail: self-hosted release-please (Task 9), removing stainless-sdks/* CI conditionals + pkg.stainless.com upload, retiring .stats.yml. Tasks 1–8 (sync PR generation + gates) do not depend on it.
  • Secrets: GitHub App (SPEC_SYNC_APP_ID/_PRIVATE_KEY), ANTHROPIC_API_KEY, LANDINGAI_ADE_STAGING_APIKEY.
  • V2 spec: add specs/v2-aide.json + URL to the workflow only after aide serves the curated spec unauthenticated (the Problem 2 aide ask). One env var + one step; machinery unchanged.

Related: #95 (Problem 2 — V2 SDK plan), PR #96 (V2 plan doc).

🤖 Generated with Claude Code

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions