Some checks failed
Use-case regression gate / usecase-regressions (push) Failing after 8m7s
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a17f16-d99c-7ea3-95f0-8212897fba6b
103 lines
5.1 KiB
Python
103 lines
5.1 KiB
Python
"""Private corpus rendering evidence using the actual product renderer."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import html
|
|
from collections import Counter
|
|
from html.parser import HTMLParser
|
|
from urllib.parse import quote
|
|
|
|
from .content import render_markdown, render_markdown_unfiltered
|
|
|
|
|
|
class _Structure(HTMLParser):
|
|
def __init__(self, value):
|
|
super().__init__(convert_charrefs=True)
|
|
self.tags = Counter()
|
|
self.attributes = Counter()
|
|
self.text = []
|
|
self.feed(value)
|
|
|
|
def handle_starttag(self, tag, attrs):
|
|
self.tags[tag] += 1
|
|
self.attributes.update((tag, key, value) for key, value in attrs)
|
|
|
|
handle_startendtag = handle_starttag
|
|
|
|
def handle_data(self, value):
|
|
self.text.append(value)
|
|
|
|
|
|
def audit_body(body: str):
|
|
raw = render_markdown_unfiltered(body)
|
|
rendered = render_markdown(body)
|
|
before, after = _Structure(raw), _Structure(rendered)
|
|
removed_attrs = before.attributes - after.attributes
|
|
text_changed = " ".join("".join(before.text).split()) != (
|
|
" ".join("".join(after.text).split()))
|
|
markup_changed = before.tags != after.tags or before.attributes != after.attributes
|
|
return {
|
|
"body_sha256": hashlib.sha256(body.encode()).hexdigest(),
|
|
"rendered_sha256": hashlib.sha256(rendered.encode()).hexdigest(),
|
|
"sanitization_changed_html": raw != rendered,
|
|
"markup_changed_by_sanitization": markup_changed,
|
|
"serialization_only_change": raw != rendered and not markup_changed and not text_changed,
|
|
"removed_tag_counts": dict(sorted((before.tags - after.tags).items())),
|
|
"added_tag_counts": dict(sorted((after.tags - before.tags).items())),
|
|
"removed_attributes": [
|
|
{"tag": tag, "attribute": key, "value": value, "count": count}
|
|
for (tag, key, value), count in sorted(
|
|
removed_attrs.items(), key=lambda item: repr(item[0]))
|
|
],
|
|
"visible_text_changed_by_sanitization": text_changed,
|
|
"original_bubble_render_compared": False,
|
|
"productive_fidelity_accepted": False,
|
|
}, rendered
|
|
|
|
|
|
def review_card(title: str, body: str, rendered: str, audit: dict, *, source_id="") -> bytes:
|
|
# Private review files must not load source images, frames, styles or scripts.
|
|
# Inert also prevents links/forms in the rendered sample from being activated.
|
|
original = ('<p><a target="_blank" rel="noopener noreferrer" href="'
|
|
+ html.escape("https://coulomb.social/pg_chunk/" + quote(source_id, safe=""),
|
|
quote=True)
|
|
+ '">Open original Bubble view</a> (opens only when clicked)</p>'
|
|
) if source_id else ""
|
|
return ("<!doctype html><html><head><meta charset=\"utf-8\">"
|
|
'<meta http-equiv="Content-Security-Policy" content="default-src \'none\'; '
|
|
'style-src \'unsafe-inline\'; base-uri \'none\'; form-action \'none\'">'
|
|
"<title>Private rendering review</title><style>"
|
|
"body{font:16px system-ui;margin:2em}main{display:grid;grid-template-columns:1fr 1fr;"
|
|
"gap:2em}pre{white-space:pre-wrap;overflow-wrap:anywhere}section{min-width:0}"
|
|
"</style></head><body><h1>" + html.escape(title) + "</h1><p>"
|
|
"Product rendering only; compare with the original Bubble view before accepting. "
|
|
"Resources and interactive links within the sample are disabled.</p>" + original
|
|
+ "<p>Sanitization changed HTML: "
|
|
+ str(audit["sanitization_changed_html"]).lower()
|
|
+ "</p><main><section><h2>Exact captured source</h2><pre>" + html.escape(body)
|
|
+ "</pre></section><section><h2>Current product rendering</h2><div inert>"
|
|
+ rendered + "</div></section></main></body></html>").encode()
|
|
|
|
|
|
def review_index(records: list[dict]) -> bytes:
|
|
rows = []
|
|
for record in sorted(records, key=lambda r: (
|
|
not (r.get("markup_changed_by_sanitization") or r["status"] == "body_missing"), r["id"]
|
|
)):
|
|
label = html.escape(record["title"])
|
|
if record.get("card"):
|
|
label = '<a href="' + html.escape(record["card"], quote=True) + '">' + label + "</a>"
|
|
status = ("body missing" if record["status"] == "body_missing" else (
|
|
"markup change — review" if record["markup_changed_by_sanitization"] else (
|
|
"text change — review" if record["visible_text_changed_by_sanitization"]
|
|
else "no structural sanitizer change; original comparison still required")))
|
|
rows.append("<li>" + label + " — " + status + "</li>")
|
|
return ('<!doctype html><html><head><meta charset="utf-8">'
|
|
'<meta http-equiv="Content-Security-Policy" content="default-src \'none\'; '
|
|
'base-uri \'none\'; form-action \'none\'">'
|
|
'<title>Private corpus rendering review</title></head><body>'
|
|
'<h1>Private corpus rendering review</h1><p>Compare each card with the original '
|
|
'Bubble view. Sanitizer differences are observations, not acceptance verdicts. '
|
|
'Body-missing and markup-change records come first.</p><ol>'
|
|
+ "".join(rows) + '</ol></body></html>').encode()
|