fix(remixer): only treat pure pointer pages as transclusion stubs - #959
Conversation
|
Severity: Medium — Severity: Low — |
There was a problem hiding this comment.
🔵 Needs a closer look
It changes core publishing/source-resolution and license/tagging heuristics in a way that’s correctness-critical and difficult to fully validate without running real fixture-driven tests against representative MindTouch content.
Pull request overview
This PR fixes Remixer/Restacker transclusion handling so only pure pointer pages (true transclusion stubs) resolve onward for publishing, tagging, and license inheritance—while pages that merely embed content-reuse blocks remain their own source.
Changes:
- Added
server/util/transclusion.tswithdetectTranscludeStub()(Cheerio-based) plus helpers to safely detect whole-page pointer stubs and avoid URI decode crashes. - Updated
resolveTranscludeSource(Remixer) to follow stub chains only when the page body is nothing but transclusion machinery. - Updated
RestackerService.isTranscludedto gatetranscluded:yestagging and source-license inheritance on stub detection, while still pinning quotation rate for any reuse markup.
File summaries
| File | Description |
|---|---|
| server/util/transclusion.ts | New shared stub-detection and reuse-markup utilities, including safe path decoding and JSON-body unwrapping. |
| server/util/Restackerutil.ts | Switches Restacker transclusion heuristic to stub-based detection; separates “reuses markup” from “is stub” behavior. |
| server/api/services/remixer-service.ts | Switches source resolution to detectTranscludeStub() so embedded reuse blocks don’t redirect the publish source incorrectly. |
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Transcluding a page that embedded content-reuse blocks published the wrong page. resolveTranscludeSource decided "is this page a transclusion?" by regex-testing the raw wikitext for the presence of a content-reuse widget, unanchored and ignoring data-section. A page containing 34 sectional reuse blocks matched on the first one, so the copy pointed at that block's target instead of at the source page, dropping all of the page's real content. Add server/util/transclusion.ts with detectTranscludeStub(), which parses the body with cheerio and reports a source only when the page is nothing but transclusion machinery: exactly one whole-page pointer (empty data-section, wiki.page(path, NULL), or CrossTransclude/Web), template scaffolding removed, and no remaining text or visual content. A widget naming a section counts against stub-ness rather than for it. Paths decode through a guard so a bare % in a title cannot throw a URIError into the publish job. RestackerService.isTranscluded carried the same heuristic and was stamping transcluded:yes onto authored pages and giving them the embedded block's license. It now gates tagging and license inheritance on the stub, while the quotation rate stays pinned at 1 for any page carrying reuse markup, since getQuotationRate only counts lt-<library>-<id> classed text and reads reuse widgets as zero.
86176c9 to
fe5297f
Compare
There was a problem hiding this comment.
🔵 Needs a closer look
It changes high-impact source-resolution and licensing/tagging behavior in publish/restack flows using nuanced content heuristics, warranting final human verification against real-world page variants.
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 0 new
- Review effort level: Lite
|
🎉 This PR is included in version 2.151.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Transcluding a page that embedded content-reuse blocks published the wrong page. resolveTranscludeSource decided "is this page a transclusion?" by regex-testing the raw wikitext for the presence of a content-reuse widget, unanchored and ignoring data-section. A page containing 34 sectional reuse blocks matched on the first one, so the copy pointed at that block's target instead of at the source page, dropping all of the page's real content.
Add server/util/transclusion.ts with detectTranscludeStub(), which parses the body with cheerio and reports a source only when the page is nothing but transclusion machinery: exactly one whole-page pointer (empty data-section, wiki.page(path, NULL), or CrossTransclude/Web), template scaffolding removed, and no remaining text or visual content. A widget naming a section counts against stub-ness rather than for it. Paths decode through a guard so a bare % in a title cannot throw a URIError into the publish job.
RestackerService.isTranscluded carried the same heuristic and was stamping transcluded:yes onto authored pages and giving them the embedded block's license. It now gates tagging and license inheritance on the stub, while the quotation rate stays pinned at 1 for any page carrying reuse markup, since getQuotationRate only counts lt-- classed text and reads reuse widgets as zero.