Skip to content

docs(api): fill 10 empty op descriptions + mark disabled endpoints deprecated (#4599 C+D)#4667

Merged
koala73 merged 2 commits into
mainfrom
fix/openapi-descriptions-and-deprecated
Jul 3, 2026
Merged

docs(api): fill 10 empty op descriptions + mark disabled endpoints deprecated (#4599 C+D)#4667
koala73 merged 2 commits into
mainfrom
fix/openapi-descriptions-and-deprecated

Conversation

@koala73

@koala73 koala73 commented Jul 3, 2026

Copy link
Copy Markdown
Owner

What & why

Second follow-up PR from the adversarial re-audit of the merged OpenAPI docs (#4657, umbrella #4599). These are the plugin-gated items (proto changes + a real regen with the pinned sebuf v0.11.1). Companion to #4666 (items A+B, version-independent).

C — 10 operations shipped empty descriptions

GetForecasts, GetSimulationOutcome, GetSimulationPackage, GetOilInventories, SearchImagery, GetResilienceRuntimeManifest, GetCriticalMinerals, GetShippingRates, GetWebcamImage, ListWebcams had no leading proto comment, so the sebuf generator emitted description: null and they rendered description-less on the docs site (#4624 filled param descriptions, not operation ones).

Fix: an accurate one-line // comment above each RPC, each sourced from the RPC's real response payload (e.g. GetOilInventories → "US crude weeks, the SPR snapshot, natural-gas weeks, EU gas storage, and IEA stocks"). The generator now emits the operation description.

D — disabled endpoints rendered as active

GetCompanyEnrichment and ListCompanySignals are DISABLED empty stubs whose routes are kept "for contract stability" — but they carried only prose "DISABLED" and no machine-readable flag, so Mintlify rendered them as normal, usable endpoints. (Confirmed these are the only 2 disabled endpoints — every other empty-ish handler returns real data or degrades gracefully.)

Fix: option deprecated = true; on the 2 proto RPCs (source of truth) + a new post-generation injector scripts/openapi-inject-deprecated.mjs that propagates it to OpenAPI deprecated: truesebuf v0.11.1 does not emit it. The injector is proto-sourced, so any future RPC that gains the option is covered automatically. The routes stay documented (they still serve 200) but now carry the deprecated badge.

Regen safety

Verified the pinned v0.11.1 plugin reproduces the committed docs byte-for-byte (make generate on clean main = 0 diff) before any proto change, so the regenerated diff is exactly these changes. make generate idempotent; JSON + YAML + bundle parity; src/generated unchanged.

Tests

New openapi-deprecated-contract guard: every operation has a non-empty description (C), and deprecated: true ⟺ description marks DISABLED (D — an independent cross-check against the injector's proto-option source). 383 contract tests pass; all 5 injectors --check idempotent; biome clean.

Wired: make generate chain + npm run gen:openapi:deprecated. Follow-up: #4658.

…precated (#4599 C+D)

Adversarial-audit follow-ups on the merged OpenAPI docs (#4657):

C — 10 RPCs (GetForecasts, GetSimulationOutcome, GetSimulationPackage,
GetOilInventories, SearchImagery, GetResilienceRuntimeManifest, GetCriticalMinerals,
GetShippingRates, GetWebcamImage, ListWebcams) lacked a leading proto comment, so
the generator emitted `description: null` and they rendered description-less on the
docs site. Add an accurate one-line comment (sourced from each RPC's real response
payload) above each; the generator now emits the operation description.

D — GetCompanyEnrichment and ListCompanySignals are DISABLED empty stubs whose
routes are preserved for contract stability, but they carried only prose "DISABLED"
and rendered as normal, usable endpoints. Add `option deprecated = true;` (proto
source of truth) and a new post-generation injector (openapi-inject-deprecated.mjs)
that propagates it to OpenAPI `deprecated: true` — sebuf v0.11.1 does not. The
injector is proto-sourced, so any future RPC gaining the option is covered
automatically. Wired into `make generate` + `npm run gen:openapi:deprecated`.

Regenerated with the pinned sebuf v0.11.1 plugin (verified reproducible: make
generate on clean main is byte-identical). All 34 JSON + 34 YAML + bundle updated
with full parity; make generate idempotent; new guard asserts every op has a
description and deprecated ⟺ DISABLED; 383 contract tests pass; src/generated
unchanged.

Answers #4657 review D ("why document disabled endpoints"): exactly 2 exist; they
stay documented (routes still serve 200) but are now machine-readable deprecated.

Claude-Session: https://claude.ai/code/session_01EsjtheWqt8GxEZfd3DyTMu
@vercel

vercel Bot commented Jul 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
worldmonitor Ready Ready Preview, Comment Jul 3, 2026 3:52pm

Request Review

@mintlify

mintlify Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
WorldMonitor 🟢 Ready View Preview Jul 3, 2026, 3:12 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@greptile-apps

greptile-apps Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fills missing operation descriptions for 10 proto RPCs (C) and propagates option deprecated = true from GetCompanyEnrichment / ListCompanySignals to all OpenAPI artifacts via a new post-generation injector (scripts/openapi-inject-deprecated.mjs), since sebuf v0.11.1 does not emit the flag itself (D).

  • C fix: Adds a leading // proto comment to each of the 10 RPCs; the generator picks it up as the OpenAPI description.
  • D fix: New openapi-inject-deprecated.mjs parses each service.proto for option deprecated = true, extracts the matching HTTP path suffix, and stamps deprecated: true on those operations in every JSON + YAML artifact; wired into make generate and covered by a new contract test.
  • Test gap: The new contract test's "deprecated iff DISABLED" case mislabels its file list as yamlFiles while actually filtering JSON files, so YAML injection is never exercised by the test; GetRouteImpact in supply_chain/v1/service.proto also lacks a functional proto comment and was not included in the 10-operation fix.

Confidence Score: 4/5

Safe to merge; all changes are documentation and test artifacts with no runtime code path impact.

The core injector logic and proto changes are correct and idempotent. The contract test's deprecated/DISABLED case never reads YAML files, so a regression in the YAML injection path would go undetected. GetRouteImpact was also missed from the 10-operation description fix.

tests/openapi-deprecated-contract.test.mjs (YAML files never read in the deprecation test) and proto/worldmonitor/supply_chain/v1/service.proto (GetRouteImpact missing a functional comment).

Important Files Changed

Filename Overview
scripts/openapi-inject-deprecated.mjs New post-generation injector that reads option deprecated = true from proto files and stamps deprecated: true on matching OpenAPI operations in both JSON and YAML artifacts; idempotent and wired into make generate. Suffix-based path matching is slightly broader than exact-path equality but safe for current paths.
tests/openapi-deprecated-contract.test.mjs New contract test guards operation descriptions (C) and deprecated/DISABLED parity (D); however, the "deprecated iff DISABLED" test misnames its file list as yamlFiles while actually filtering JSON files, so YAML artifacts are never validated by this test.
proto/worldmonitor/intelligence/v1/service.proto Adds option deprecated = true to GetCompanyEnrichment and ListCompanySignals RPCs, matching their prose "DISABLED" comment and serving as the injector's source of truth.
proto/worldmonitor/supply_chain/v1/service.proto Adds leading proto comments for GetShippingRates and GetCriticalMinerals; GetRouteImpact at line 96 still lacks a functional comment and its OpenAPI description is the access-gate-only placeholder.
proto/worldmonitor/forecast/v1/service.proto Adds accurate leading comments for GetForecasts, GetSimulationPackage, and GetSimulationOutcome; all three descriptions are consistent with the response payloads.
docs/api/worldmonitor.openapi.yaml Bundle YAML updated with 10 new operation descriptions and deprecated: true on the two disabled company endpoints; changes look structurally correct.
Makefile Adds openapi-inject-deprecated.mjs to the generate target after the other injectors, maintaining correct ordering.
package.json Adds gen:openapi:deprecated npm script exposing the new injector as a standalone command.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[make generate] --> B[buf generate\nproto to OpenAPI JSON/YAML]
    B --> C[openapi-inject-required.mjs]
    C --> D[openapi-inject-examples.mjs]
    D --> E[openapi-inject-servers.mjs]
    E --> F[openapi-inject-deprecated.mjs]

    F --> G{Walk proto/worldmonitor\nfor option deprecated = true}
    G --> H[Extract HTTP path suffix]
    H --> I[DEPRECATED_SUFFIXES Set]

    I --> J[Patch per-service JSON]
    I --> K[Patch per-service YAML]
    I --> L[Patch bundle YAML]

    J & K & L --> M[Mintlify renders deprecated badge]

    subgraph Test Guard
        N[openapi-deprecated-contract.test.mjs]
        N --> O[C: every op has non-empty description]
        N --> P[D: deprecated=true iff DISABLED in description]
        P -.->|only checks JSON not YAML| Q[YAML coverage gap]
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[make generate] --> B[buf generate\nproto to OpenAPI JSON/YAML]
    B --> C[openapi-inject-required.mjs]
    C --> D[openapi-inject-examples.mjs]
    D --> E[openapi-inject-servers.mjs]
    E --> F[openapi-inject-deprecated.mjs]

    F --> G{Walk proto/worldmonitor\nfor option deprecated = true}
    G --> H[Extract HTTP path suffix]
    H --> I[DEPRECATED_SUFFIXES Set]

    I --> J[Patch per-service JSON]
    I --> K[Patch per-service YAML]
    I --> L[Patch bundle YAML]

    J & K & L --> M[Mintlify renders deprecated badge]

    subgraph Test Guard
        N[openapi-deprecated-contract.test.mjs]
        N --> O[C: every op has non-empty description]
        N --> P[D: deprecated=true iff DISABLED in description]
        P -.->|only checks JSON not YAML| Q[YAML coverage gap]
    end
Loading

Comments Outside Diff (1)

  1. proto/worldmonitor/supply_chain/v1/service.proto, line 96-98 (link)

    P2 GetRouteImpact missing functional proto comment

    This RPC has no leading // comment, so the sebuf generator cannot emit a semantic operation description. The committed artifact has only the injector-appended text "PRO-gated. Requires entitlement tier >= 1." with no description of what the endpoint returns. The contract test C passes because the description is non-empty, but the check cannot distinguish a functional description from a gate-only string — the same gap this PR fixed for the other 10 operations remains here.

Reviews (1): Last reviewed commit: "docs(api): fill 10 empty op descriptions..." | Re-trigger Greptile

Comment on lines +49 to +51
const yamlFiles = readdirSync(apiDir)
.filter((f) => /Service\.openapi\.json$/.test(f))
.sort();

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.

P1 YAML artifacts never validated despite "every artifact" label

The variable is named yamlFiles but is filtered with /Service\.openapi\.json$/, so the test reads exactly the same JSON files as the outer serviceSpecs variable and never touches any YAML files. The injectYaml() code path — which inserts deprecated: true into *Service.openapi.yaml and worldmonitor.openapi.yaml — is therefore not exercised by this test at all. A bug in YAML indentation detection or the "already present" idempotency check would go silently undetected here.

Suggested change
const yamlFiles = readdirSync(apiDir)
.filter((f) => /Service\.openapi\.json$/.test(f))
.sort();
const jsonServiceSpecs = readdirSync(apiDir)
.filter((f) => /Service\.openapi\.json$/.test(f))
.sort();
let deprecatedCount = 0;
for (const file of jsonServiceSpecs) {

Comment thread scripts/openapi-inject-deprecated.mjs Outdated
Comment on lines +64 to +68
function isDeprecatedPath(path) {
for (const suffix of DEPRECATED_SUFFIXES) {
if (path === suffix || path.endsWith(suffix)) return true;
}
return false;

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.

P2 endsWith suffix matching is broader than exact path equality

path.endsWith(suffix) will match any OpenAPI path that ends with a deprecated suffix string. Today's suffixes (/get-company-enrichment, /list-company-signals) are unique, but if a future RPC path happened to share a trailing segment with a deprecated one, it would incorrectly receive deprecated: true. Building the full path from base_path + path at parse time and matching with exact equality would eliminate the ambiguity without much extra complexity.

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