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

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions