Skip to content

fix(ingestion): structural lxml.html strip; serve posting both ways (closes py/bad-tag-filter) - #19

Merged
David-BS merged 1 commit into
mainfrom
fix/ingestion-lxml-strip-both-ways
Jun 15, 2026
Merged

fix(ingestion): structural lxml.html strip; serve posting both ways (closes py/bad-tag-filter)#19
David-BS merged 1 commit into
mainfrom
fix/ingestion-lxml-strip-both-ways

Conversation

@David-BS

Copy link
Copy Markdown
Owner

Replaces the carrier-enumerating regex ingestion strip with a structural lxml.html parser, and opens load_job_posting to both offer_path and offer_body (finding C).

Why: CodeQL flagged _NON_RENDERED_RE (py/bad-tag-filter). A bench confirmed the bogus-comment class survived the regex and reached the model verbatim. Enumerating carriers is a deny-list by nature; the robust fix is to be the parser.

Changes:

  • _strip_non_rendered: lxml.html, drop non-rendered nodes (comment/PI) + script/style; preserve visible text and tail. Regex removed.
  • load_job_posting: offer_path OR offer_body (exactly one); sanitised path made convenient on the chat surface. Residual named: on offer_body the model already read the raw body (strip defends downstream propagation, not that first read).
  • manifest description synced to the both-ways contract.
  • Floor 258 -> 270: falsify-first [2c] (version-robust invariant 'zero non-rendered node survives'; libxml2 2.11.9 downgrades the bogus end-tag form to the visible channel, the documented visible residual) + [2d] both-ways.

Closes the py/bad-tag-filter sink (regex removed). refs #282 unaffected.

…ing both ways

The HTML-comment regex (_NON_RENDERED_RE) only knew the standard comment, script and style carriers. CodeQL flagged it (py/bad-tag-filter); a bench confirmed the bogus-comment class (bang, processing-instruction and bogus end-tag forms) survived the regex and reached the model verbatim. The robust fix is structural: be the parser.

- _strip_non_rendered parses with lxml.html and drops the nodes the parser classifies as non-rendered (comment / processing-instruction) plus script/style; visible text and trailing tail are preserved. Regex removed.

- load_job_posting accepts offer_path OR offer_body (exactly one), making the sanitised path the convenient one on the chat surface (finding C). Residual named: on offer_body the model already read the raw body, so the strip defends downstream propagation, not that first read.

- manifest load_job_posting description synced to the both-ways contract.

- Floor: falsify-first guards [2c] + [2d] (258 -> 270). [2c] asserts the version-robust invariant "zero non-rendered node survives" (libxml2 2.11.9 downgrades the bogus end-tag form to the visible channel rather than removing it -- the documented visible residual), not "payload dropped".
@David-BS
David-BS merged commit 40c7b41 into main Jun 15, 2026
6 checks passed
@David-BS
David-BS deleted the fix/ingestion-lxml-strip-both-ways branch June 15, 2026 14:12
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