Skip to content

HTML export: single-element-wrapped narration can still clear the #27 structural floor (element-floor residual) #34

Description

@project820

Summary

Residual of the #27 fail-closed structural gate (which shipped in #29). The gate rejects the concrete #27 failure modes — pure prose (0 elements), code fences, and bare preamble text as a top-level sibling — but a model that wraps its entire conversational answer in a single element still clears the floor and finalizes.

The gate (html-export-sanitize.ts, behind requireStructuralDocument) requires:

  • bodyElementCount >= HTML_MIN_BODY_ELEMENT_NODES (floor = 1), and
  • no non-whitespace top-level text node (HTML-ASCII-whitespace predicate).

So Creating a landscape… (pure prose) is rejected, and Sure:<h1>…</h1> (top-level text sibling) is rejected, but:

<div>Creating a landscape document about … Here is your export:</div>

has exactly one element and no top-level text node → passes sanitize → quarantine → finalize, saving the narration as the "export".

Why it is hard (accepted design boundary today)

A single <div>…prose…</div> is structurally indistinguishable from a legitimate intro paragraph / lede that a real document may open with. Hard-rejecting single-element-with-only-text bodies risks false-positives on valid short documents. The current mitigation is the direct-prompt rider forbidding conversational preamble/narration (bare or element-wrapped), plus the top-level-text and element-floor checks. Architect + Grok-QA review classified the element-wrapped case as an accepted residual, not a security hole (no XSS/containment impact — it is a content-quality/trust issue in the family of #27).

Options to consider

  • Heuristic content-identity signal (e.g. reject a body that is a single block element whose only content is text and whose text matches narration markers) — risks false-positives; needs a careful corpus.
  • Provider-side: ensure the Grok/Claude CLI HTML surface disables tool/plan narration so the model cannot emit a chat wrapper in the first place (verify --disallowed-tools / prompt on current CLI versions).
  • Accept as-is and rely on the prompt rider + the existing floor/top-level-text checks (current state).

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions