Skip to content

fix(backend): name the surface in the OpenAPI regenerate hint#10455

Merged
kodjima33 merged 2 commits into
BasedHardware:mainfrom
aryanorastar:fix/10217-openapi-stale-hint-surface
Jul 25, 2026
Merged

fix(backend): name the surface in the OpenAPI regenerate hint#10455
kodjima33 merged 2 commits into
BasedHardware:mainfrom
aryanorastar:fix/10217-openapi-stale-hint-surface

Conversation

@aryanorastar

@aryanorastar aryanorastar commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

What

The OpenAPI contract checker tells you how to fix a stale contract, and the command it prints is wrong for every non-public surface.

Fixes #10217.

Why it matters

check_spec printed:

<path> is stale; run backend/scripts/export_openapi.py --write <path>

--surface defaults to public. So running that hint verbatim against the app-client contract exports the public surface into the app-client file — it doesn't refresh the contract, it guts it (~53k lines). The hint actively causes the damage it claims to repair.

I hit this myself regenerating contracts today: you have to already know to pass --surface app-client, which is precisely what the error message exists to tell you.

Fix

Thread the surface into check_spec and build both the missing- and stale-file messages from one regenerate_hint helper, so the printed command is exactly the command that regenerates that path:

<path> is stale; run backend/scripts/export_openapi.py --surface app-client --write <path>

Verified live by making the app-client contract stale and running the checker (contract restored afterwards, not part of the diff):

OpenAPI contract check failed: .../app-client-openapi.json is stale;
run backend/scripts/export_openapi.py --surface app-client --write .../app-client-openapi.json

Tests

backend/tests/unit/test_export_openapi_hint.py — 7 cases:

  • every surface's hint names that surface and its own path
  • both the missing-file and stale-file errors carry the surface
  • the regression itself: the app-client hint is never the bare --write <path> form that defaults to public

Note on prior attempts

#10255 and #10294 both targeted this and were closed unmerged, so the issue is still live on main — I verified the surface-less hint is still there before writing anything.

Product invariants affected

none

Failure-Class: none

Review in cubic

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@Git-on-my-level Git-on-my-level added needs-tests PR introduces logic that should be covered by tests workflow-review Needs maintainer review for workflow, automation, hooks, or CI behavior labels Jul 24, 2026

@Git-on-my-level Git-on-my-level left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for tightening this hint — including the explicit --surface is the right direction and the new regression coverage captures the damaging non-public default case.

One blocking issue before this can merge: the PR changes check_spec to require a keyword-only surface, but an existing unit test/call contract still invokes it with the old signature. CI is failing in tests/unit/test_openapi_contract.py::test_check_spec_detects_stale_file with:

TypeError: check_spec() missing 1 required keyword-only argument: 'surface'

Please either keep check_spec backward-compatible with a safe default such as surface='public', or update the existing test/call sites in the same PR so the backend unit suite is green. The core fix looks sound once that compatibility/test failure is resolved.


by AI on behalf of David — if you need David’s attention urgently, please @Git-on-my-level and escalate with need human response.

aryanorastar added a commit to aryanorastar/omi that referenced this pull request Jul 24, 2026
…ce default

Review (BasedHardware#10455): making `surface` keyword-only-required broke an existing
caller — tests/unit/test_openapi_contract.py::test_check_spec_detects_stale_file
called check_spec(path, generated) and hit
`TypeError: check_spec() missing 1 required keyword-only argument: 'surface'`.

Default surface='public', matching the --surface argparse default. The
production caller in this module still passes surface=args.surface
explicitly, so a non-public surface never silently gets the public hint
(the BasedHardware#10217 defect). Added a regression test pinning the no-surface call.

Verify (.openapi-venv): check_spec(path, generated) now raises the stale
error with a `--surface public` hint; surface='app-client' still names it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@aryanorastar
aryanorastar force-pushed the fix/10217-openapi-stale-hint-surface branch from 07f3e11 to bc027ed Compare July 24, 2026 09:34
@aryanorastar

Copy link
Copy Markdown
Contributor Author

Fixed — check_spec now defaults surface='public' (matching the --surface argparse default), so check_spec(path, generated) works again and test_check_spec_detects_stale_file is green. The production caller still passes surface explicitly, so a non-public surface never silently gets the public hint. Added a regression test pinning the no-surface call.

The remaining app-client-openapi.json is stale failure is pre-existing main drift from the baseline toggle (#8728), fixed separately in #10482 — not from this diff.

@kodjima33 kodjima33 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

fix(backend) name surface in OpenAPI regenerate hint — approve only (workflow-review, CHANGES_REQUESTED)

aryanorastar and others added 2 commits July 25, 2026 09:19
The stale/missing contract errors printed `export_openapi.py --write <path>` with no
surface. `--surface` defaults to `public`, so following that hint verbatim for a
non-public contract writes the PUBLIC surface into it — the app-client spec loses ~53k
lines and the "fix" silently guts the file instead of refreshing it (BasedHardware#10217).

Thread the surface into check_spec and build both messages from one regenerate_hint
helper, so the printed command is exactly the command that regenerates that path.

Refs BasedHardware#10217.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ce default

Review (BasedHardware#10455): making `surface` keyword-only-required broke an existing
caller — tests/unit/test_openapi_contract.py::test_check_spec_detects_stale_file
called check_spec(path, generated) and hit
`TypeError: check_spec() missing 1 required keyword-only argument: 'surface'`.

Default surface='public', matching the --surface argparse default. The
production caller in this module still passes surface=args.surface
explicitly, so a non-public surface never silently gets the public hint
(the BasedHardware#10217 defect). Added a regression test pinning the no-surface call.

Verify (.openapi-venv): check_spec(path, generated) now raises the stale
error with a `--surface public` hint; surface='app-client' still names it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@aryanorastar
aryanorastar force-pushed the fix/10217-openapi-stale-hint-surface branch from bc027ed to 2f6a56c Compare July 25, 2026 03:51

@Git-on-my-level Git-on-my-level left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the follow-up. I re-reviewed the current head and the earlier blocker is resolved: check_spec is backward-compatible again with surface='public', while the CLI check path now passes the parsed surface explicitly so non-public OpenAPI contracts get a safe regenerate hint.

I also ran the targeted backend coverage locally:

.venv/bin/python -m pytest tests/unit/test_export_openapi_hint.py tests/unit/test_openapi_contract.py::test_check_spec_detects_stale_file -q
9 passed in 0.33s

This looks like the right fix for #10217, with regression coverage for the app-client/public-surface failure mode. Because this touches the backend OpenAPI contract-generation workflow, I’m leaving it as a positive maintainer signal rather than a formal approval; a human maintainer should still do the final workflow/API-contract signoff before merge.


by AI on behalf of David — if you need David’s attention urgently, please @Git-on-my-level and escalate with need human response.

@Git-on-my-level Git-on-my-level added needs-maintainer-review Needs a human maintainer to sign off before merge and removed needs-tests PR introduces logic that should be covered by tests labels Jul 25, 2026
@Git-on-my-level
Git-on-my-level dismissed their stale review July 25, 2026 08:18

Superseded by 2f6a56c: check_spec now defaults surface="public", the production caller passes surface explicitly, and targeted backend tests pass.

@kodjima33 kodjima33 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Regenerate hint now names --surface, so following it can't gut a non-public contract (#10217). Tested.

@kodjima33
kodjima33 merged commit f3f57f4 into BasedHardware:main Jul 25, 2026
38 of 39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-maintainer-review Needs a human maintainer to sign off before merge workflow-review Needs maintainer review for workflow, automation, hooks, or CI behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

export_openapi.py stale-contract error message omits the required --app-client flag

3 participants