Skip to content

[quality] Decision: folded MDX grammar finding after SVG acceptance repair #1764

Closed

Description

@hivecommons-hive

SVG acceptance finding: completed

The original finding concerned supported SVG policy names that could be
removed without failing an acceptance test. PR #1765 now uses
independent fixture names instead of deriving test cases from the same
production Sets being checked.

The repaired PR merged through the protected queue at
2026-10-22T17:06:36Z as a37c1490ba46f47cb0b8e6be12d3c2868c7843b8.
All 365 focused cases pass. A session-only counterfactual probe independently
deleted every one of the 236 entries across the nine exported policy Sets
in fresh processes; all 236 deletions caused actual assertion failures,
including circle. No production policy changed.

  • Supported entries in all nine exported Sets have independent acceptance
    fixtures with the proper SVG/XHTML/metadata context.
  • Removing a supported entry fails an assertion rather than removing its
    generated case.
  • Required checks pass and the repair merged through normal protections.

The original 104 surviving policy-string mutants were historical evidence
from full-tree run 39556947541 at 3bbac0d. The deletion probe above is not a
new full-module Stryker score and must not be presented as one.

Separately folded MDX finding: unresolved decision

A Hive comment on 2026-10-22 folded an unrelated
scripts/lib/mdx-escape.mjs grammar-intersection/assertion finding into this
SVG tracker. That finding has a different cause and proposed implementation.
The SVG repair does not implement or validate it.

Keep this issue open for that remaining scope/validity decision. No
codeRanges() export, additional validator extraction, new mutation
harness or MDX production change was authorized by the bounded SVG repair
or by the separately approved architecture-assets extraction.

  • Assess the folded MDX reproduction and whether it needs production
    changes or can be addressed through existing public behavior.
  • Decide its independently bounded disposition before implementation.

GitHub retained the original SVG PR's closing association despite its body
being changed to Refs; the automatic closure has therefore been corrected
so it cannot hide the separately folded item.

Activity

  1. added
    testingApproved by a Hive merger/owner for auto-merge on green CI
    agent/qualityApproved by a Hive merger/owner for auto-merge on green CI
    stage/020-claimedClaimed by the scanner or a relay contributor
    on Oct 22, 2026
  2. hivecommons-hive commented on Oct 22, 2026

    @hivecommons-hive
    ContributorAuthor

    🛠️ Hive agent quality (hive hosted-available-lke648397-260827-5n31) started work on this issue at 2026-10-22T06:20:55Z. A pull request referencing this issue supersedes this mark; it lapses on its own at 2026-10-22T08:20:55Z if none appears.

  3. hivecommons-hive commented on Oct 22, 2026

    @hivecommons-hive
    ContributorAuthor

    Folded finding. This was filed as a separate issue, but 2 open agent-filed issues (plus 2 closed as completed in the last 14 days) already cite scripts/lib/mdx-escape.mjs, so it was folded into the oldest of them instead of opening another. Treat this issue as the tracker for that component: prefer one structural fix that covers every folded variant over a PR per variant.

    [quality] escapeMdx's re-escape fallback masks the grammar intersection: deleting the second grammar leaves 140 tests green

    Finding

    escapeMdx() in scripts/lib/mdx-escape.mjs classifies code spans with a
    list of grammars and keeps only the intersection. The module's own docstring
    treats that as a security property:

    The first entry is what @docusaurus/mdx-loader actually builds pages with —
    MDX plus GFM — and it is not interchangeable with MDX alone.

    Only the intersection is preserved verbatim. A span that is code under one
    grammar and live JSX under another is not code for this module's purposes, so
    it falls through to escaping.

    No test distinguishes that behaviour. I deleted the entire second grammar
    from GRAMMARS — the MDX-without-GFM entry, which is the only reason
    intersectRanges() and the loop in codeRanges() exist at all — and ran the
    suite:

    $ TZ=UTC node --test tests/mdx-escape.test.mjs tests/mdx-escape-gfm.test.mjs \
        tests/mdx-active-content.test.mjs tests/architecture-content-clean-markdown.test.mjs
    ℹ pass 140
    ℹ fail 0
    

    The cause is that escapeMdx() verifies its own result:

    return hasActiveMdx(escaped) ? escapePlain(text) : escaped;

    Whenever the classification is wrong in the dangerous direction, the verifier
    catches it and re-escapes the whole document. The assertions in
    tests/mdx-escape-gfm.test.mjs check only that the output is inert and that the
    element did not survive — which stays true via the fallback. So the intersection
    is a defence-in-depth layer whose removal is invisible, and a regression in it
    would be caught by nothing but the fallback it exists to avoid relying on.

    The mutation report agrees. From the full-tree scheduled lane
    (run 39556947541,
    head 3bbac0d, artifact mutation-report id 12327530324, 2026-10-21T06:41Z),
    scripts/lib/mdx-escape.mjs scores 73.9% with 42 surviving mutants, the
    worst score of any file in the mutation scope that has in-process tests. The
    survivors cluster exactly on the masked machinery:

    Lines Code Survivors
    76, 78-80 GRAMMARS[0] mdastExtensions, and the whole plain fallback 4
    84-88 GRAMMARS[1] — both mdx and plain 6
    107, 113 the code/inlineCode offset guard and the mdx-code-block skip in treeCodeRanges() 7
    117 the ranges.sort() comparator 3
    129-133 the intersectRanges() loop bounds and tie-breaks 4
    156-157 the codeRanges() grammar loop and its break 5

    Emptying the grammar loop body, deleting the second grammar, and reversing the
    tie-break in intersectRanges() are all survivable, because each one can only
    move output from "surgically escaped" to "wholly escaped", and no assertion
    looks at which of the two happened.

    Recommendation

    These mutants cannot be killed through the public API, because the public API is
    precisely what launders the difference. The fix is the pattern this repository
    already used in #1757 ("expose awards validation core for mutation
    attribution"): export the classification core so it can be asserted directly.

    • export codeRanges(text) from scripts/lib/mdx-escape.mjs (named export, no behaviour change)
    • assert codeRanges() returns the intersection, not GRAMMARS[0]'s ranges, for a span the two grammars disagree about
    • assert escapeMdx() escapes surgically for that input — i.e. an unrelated genuine fenced code block in the same document survives verbatim, proving the hasActiveMdx() fallback did not fire
    • assert the intersectRanges() tie-break and loop bounds on adjacent and equal-ended ranges

    The third box is the one that matters most: asserting which path produced the
    safe output is what stops the fallback from masking a regression in the layer in
    front of it.

    This needs a production change (a new export), so the quality lane cannot open
    the PR for it — it needs a human or an agent permitted to change
    scripts/lib/.
    The test-only part of this file's backlog is handled
    separately in #1781.

    Priority

    • Impact: high (a security-relevant classifier whose regressions are invisible to the suite)
    • Effort: medium

    🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5n31 | SHA: 1cbe3ca

    — hive: agent=quality backend=copilot model=claude-opus-5 copilot=1.0.88

  4. mrbobbytables commented on Oct 22, 2026

    @mrbobbytables
    Member

    P2 scope reconciliation under explicit maintainer approval: the original SVG acceptance finding is repaired in the existing PR1765 with independent fixtures. All 236 isolated entry deletions across the nine exported Sets, including circle, now trigger actual acceptance-test assertion failures; the previous Set-derived loops could silently drop deleted cases. The PR uses Refs rather than an automatic closing reference because this issue also received a folded scripts/lib/mdx-escape.mjs grammar finding. SVG and MDX are different causes and implementations. The folded MDX work is outside the approved P2/P3 scope, is not implemented by PR1765, and must remain explicitly unresolved rather than being hidden by SVG completion. No MDX export, new harness or production SVG-policy change is included.

  5. mrbobbytables commented on Oct 22, 2026

    @mrbobbytables
    Member

    The SVG acceptance repair merged in PR1765, but this tracker also contains the unrelated folded MDX grammar finding. GitHub retained the original closing association even after the PR body was changed to Refs. Reopening only to preserve that unresolved item; the SVG work is complete and must not be reimplemented. Its scope and validity need a separate maintainer decision.

  6. changed the title [-][quality] SVG active-content allowlists are untested policy: 104 allowlist entries can each be blanked with the suite still green[/-] [+][quality] Decision: folded MDX grammar finding after SVG acceptance repair[/+] on Oct 22, 2026
  7. added
    stage/045-needs-decisionIssue parked on a person: needs-human or a maintainer decision is owed before the hive picks it up
    and removed
    stage/010-actionableTriaged; eligible for the hive to pick up
    on Oct 22, 2026
  8. hivecommons-hive commented on Oct 22, 2026

    @hivecommons-hive
    ContributorAuthor

    What to reply

    • /hive approve: go with the recommendation
    • /hive decision <your instructions>: go ahead, following your instructions
    • /hive help: show these again

    If this issue is waiting only for reporter confirmation after a merged fix, the reporter or a maintainer can reply /fixed instead.

    Only a maintainer with write access can un-park; everything else is ignored. Full command reference: https://github.com/hivecommons/hive/blob/v5/src/docs/maintainer-commands.md.

  9. hivecommons-hive commented on Oct 22, 2026

    @hivecommons-hive
    ContributorAuthor

    To start work, reply /hive approve (or /hive decision A). A plain reply acknowledges the issue but leaves it parked.

  10. mrbobbytables commented on Oct 22, 2026

    @mrbobbytables
    Member

    The folded mdx-escape.mjs grammar-intersection finding is addressed through test changes only in #1808 (Group F of the surviving-mutant backlog): the file goes from 40 survivors to 142/161 killed, and each remaining mutant was verified equivalent and is marked with a Stryker disable directive carrying its reason, so it reports as Ignored. No production change, codeRanges() export or new harness was needed. The SVG scope was already completed above.

  11. removed
    stage/045-needs-decisionIssue parked on a person: needs-human or a maintainer decision is owed before the hive picks it up
    on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent/qualityApproved by a Hive merger/owner for auto-merge on green CIneeds-humantestingApproved by a Hive merger/owner for auto-merge on green CI

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions