Skip to content

test(docs): make the renderMarkdown security tests actually load-bearing - #12300

Closed
kozlek wants to merge 4 commits into
devs/kozlek/devs/kozlek/batch-status-data-type/show-accepted-values-api-params-typed-shared-enum--c546133cfrom
devs/kozlek/devs/kozlek/batch-status-data-type/make-rendermarkdown-security-tests-actually-load--63b59daf
Closed

test(docs): make the renderMarkdown security tests actually load-bearing#12300
kozlek wants to merge 4 commits into
devs/kozlek/devs/kozlek/batch-status-data-type/show-accepted-values-api-params-typed-shared-enum--c546133cfrom
devs/kozlek/devs/kozlek/batch-status-data-type/make-rendermarkdown-security-tests-actually-load--63b59daf

Conversation

@kozlek

@kozlek kozlek commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Three of the four assertions passed whether or not rehype-sanitize was
in the pipeline: remark-rehype runs without allowDangerousHtml, so
raw HTML is discarded before either rehype-raw or the sanitizer sees
it, and both raw-HTML cases were not.toContain against an empty
string. A refactor dropping the sanitizer would have kept them green
while re-opening the hole they claim to guard.

Separate the two guarantees so each is pinned by tests that fail when it
breaks: URL-protocol filtering is the sanitizer's own contribution, while
raw HTML never reaching the output comes from the markdown pipeline and
only becomes the sanitizer's job if a caller ever enables
allowDangerousHtml.

Part of MRGFY-8330

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

Depends-On: #12299

kozlek and others added 4 commits August 4, 2026 09:58
A batch's `status.code` appeared on the API reference as a bare list of
values with no explanation, and nowhere else in the docs. Readers seeing
a status in an API response, in the CLI, or on a dashboard chip had no
way to find out what it meant.

Add a Batch Status section to the data-types page, rendering a table
generated from the OpenAPI spec so the codes and their descriptions come
from the engine rather than being hand-maintained, and cross-reference it
from the monitoring and batches pages.

Extend the anchor build gate to scan the API spec alongside the
configuration schema. This is the first data type marked in the API
spec, and schema syncs land as direct pushes to main, so the deploy
build is the only gate they pass through.

Also sanitize `renderMarkdown`. Its output is injected with
`dangerouslySetInnerHTML` by every schema-driven table, and it did not
filter URL protocols, so a `javascript:` link in any synced description
would have rendered as a live link. Raw HTML was already dropped, since
`remark-rehype` runs without `allowDangerousHtml`. The inputs are all
first-party, so this is defence in depth, but the guarantee belongs in
the shared helper rather than in each of its six callers. Verified that
article text and every href on the data-types, file-format and batches
pages are unchanged.

Both bundled schemas are what the sync bot will deliver once the engine
side merges. They carry the per-value documentation as `x-mergify-enum`,
a positional array aligned with `enum` holding a description, an optional
display title and a deprecation flag. `x-enum-descriptions` is gone: that
name is an established openapi-generator convention for a positional
array of strings, and publishing a map under it would mislead the SDK
generators customers run against our spec.

Part of MRGFY-8330

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

Change-Id: Ic5cd08016af10408a80c0d9f72b86dd61abc0a84
The engine is changing how it publishes per-value documentation for a
schema's choice set, moving from an `x-enum-descriptions` map to a
positional `x-mergify-enum` array that also carries a display title and a
deprecation flag. Schema syncs land as direct pushes to main, so the docs
repo cannot assume both sides move together.

Introduce `readEnumChoices`, which tolerates every shape a synced schema
can be in during that migration: values as a flat `enum`, a `const`, or
the `anyOf` of branches a composed `Literal` produces, with the node —
or any single branch of it — either inline or behind a `$ref`. Hoisting
repeated enums into shared components is what removes the duplicated
blocks from the published schema, and a reader that followed only the
property node would silently render an empty table once that happens.

Three things the shape change makes possible that the map could not, and
which are handled explicitly because each fails silently:

- Metadata can sit on the referring node as a `$ref` sibling rather than
  on the target, which is how pydantic publishes an annotation for a
  hoisted type. Both are consulted, nearest first.
- A positional array can fall out of alignment with `enum` in a way a
  keyed map never could. A length mismatch is treated as unusable rather
  than shifting every description onto the wrong value.
- The two shapes can coexist on one node mid-migration, so they are
  merged rather than treated as alternatives.

Both schema-driven tables now go through it, so the engine can migrate
one enum at a time without a lockstep docs change. Ref resolution uses
the `jsonpointer` the sibling readers already use: hand-decoding each
segment raises `URIError` on a pointer containing a stray `%`, which
would break the never-throws contract this reader depends on to degrade
instead of failing the build.

Tests pin each silent-degradation mode, and two of them read the real
synced schemas rather than fixtures, so a sync that changes or reverts a
shape fails here instead of publishing a table of blank cells.

Part of MRGFY-8330

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

Change-Id: Ie539de06bf3391eb4390333810cda6e8f131b1e6
…enum

Deduplicating repeated enums in the OpenAPI spec hoists them into shared
components, so a query parameter's schema becomes a `$ref` instead of an
inline `enum`. `getTypeLabel` returned the component name for any `$ref`,
which is right for an object — the schema tree below expands it — but
wrong for an enum: parameters are rendered from that label alone, with no
tree underneath and no `enum` among their constraints.

Fifteen public parameters were affected. `/api/activity-log`'s
`event_type` listed all 44 accepted values and would have shown
`EventType[]`; `source` on the quarantines endpoint would have shown
`QuarantineSource` instead of `"manual" | "auto"`. The components
themselves are not rendered anywhere on the site, so the values would
have been published nowhere at all.

Resolve the reference when it targets an enum and keep the name
otherwise.

Part of MRGFY-8330

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Change-Id: Ic546133c44ed82ddc0f57c2269b64f6725247e27
Three of the four assertions passed whether or not `rehype-sanitize` was
in the pipeline: `remark-rehype` runs without `allowDangerousHtml`, so
raw HTML is discarded before either `rehype-raw` or the sanitizer sees
it, and both raw-HTML cases were `not.toContain` against an empty
string. A refactor dropping the sanitizer would have kept them green
while re-opening the hole they claim to guard.

Separate the two guarantees so each is pinned by tests that fail when it
breaks: URL-protocol filtering is the sanitizer's own contribution, while
raw HTML never reaching the output comes from the markdown pipeline and
only becomes the sanitizer's job if a caller ever enables
`allowDangerousHtml`.

Part of MRGFY-8330

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Change-Id: I63b59daf0427a2d2bfad0fc008ff14c3730b9553
@mergify
mergify Bot had a problem deploying to Mergify Merge Protections August 4, 2026 07:58 Failure
@kozlek

kozlek commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

This pull request is part of a Mergify stack:

# Pull Request Link
1 feat(docs): document the batch status data type #12263
2 refactor(docs): read documented enum values through one shared reader #12293
3 fix(docs): show accepted values for API parameters typed by a shared enum #12299
4 test(docs): make the renderMarkdown security tests actually load-bearing #12300 👈
5 feat(docs): accept the namespaced documented-data-type marker #12301

@mergify

mergify Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🔴 3 of 7 protections blocking · waiting on 👀 reviews and ⛓️ dependency

Protection Waiting on
🔴 ⛓️ Depends-On Requirements ⛓️ dependency
🔴 👀 Review Requirements 👀 reviews
🔴 🔎 Reviews 👀 reviews
🟢 🤖 Continuous Integration
🟢 Enforce conventional commit
🟢 📕 PR description
🟢 🚦 Auto-queue

🔴 ⛓️ Depends-On Requirements

Waiting for

This rule is failing.

Requirement based on the presence of Depends-On in the body of the pull request

🔴 👀 Review Requirements

Waiting for

  • #approved-reviews-by >= 2
This rule is failing.
  • any of:
    • #approved-reviews-by >= 2
    • author = dependabot[bot]
    • all of:
      • author = mergify-ci-bot
      • -head ~= ^docs-agent/

🔴 🔎 Reviews

Waiting for

  • #review-requested = 0
This rule is failing.
  • #review-requested = 0
  • #changes-requested-reviews-by = 0
  • #review-threads-unresolved = 0

Show 4 satisfied protections

🟢 🤖 Continuous Integration

  • all of:
    • check-success = build
    • check-success = lint
    • check-success = test
    • any of:
      • check-success = test-broken-links
      • label = ignore-broken-links
    • any of:
      • check-success=Cloudflare Pages
      • -head-repo-full-name~=^Mergifyio/

🟢 Enforce conventional commit

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|internal|docs|style|refactor|perf|test|build|ci|chore|revert|ui)(?:\(.+\))?!?:

🟢 📕 PR description

  • body ~= (?ms:.{48,})

🟢 🚦 Auto-queue

When all merge protections are satisfied, this pull request will be queued automatically.

@mergify
mergify Bot requested a review from a team August 4, 2026 08:00
@kozlek
kozlek force-pushed the devs/kozlek/devs/kozlek/batch-status-data-type/show-accepted-values-api-params-typed-shared-enum--c546133c branch from 80eb05a to 85e5029 Compare August 4, 2026 17:10
@mergify
mergify Bot force-pushed the devs/kozlek/devs/kozlek/batch-status-data-type/show-accepted-values-api-params-typed-shared-enum--c546133c branch from 85e5029 to 4e7d3df Compare August 4, 2026 17:10
@kozlek kozlek closed this Aug 4, 2026
@kozlek
kozlek deleted the devs/kozlek/devs/kozlek/batch-status-data-type/make-rendermarkdown-security-tests-actually-load--63b59daf branch August 4, 2026 17:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant