Skip to content

feat(notebooks): require feed tile summary when leading markdown is noisy#4761

Open
leonardthethird wants to merge 1 commit into
mainfrom
feat/notebook-feed-tile-summary-validation
Open

feat(notebooks): require feed tile summary when leading markdown is noisy#4761
leonardthethird wants to merge 1 commit into
mainfrom
feat/notebook-feed-tile-summary-validation

Conversation

@leonardthethird
Copy link
Copy Markdown
Contributor

@leonardthethird leonardthethird commented May 21, 2026

Summary

Adds a conditional validation rule to the notebook create/edit form: if the first ~250 characters of the notebook's markdown contain formatting tokens that the feed tile cannot cleanly render as plain text, feed_tile_summary becomes a required field, with a red inline explanation under the field telling the author why.

Motivation

Notebook feed tiles fall back to getMarkdownSummary(markdown, ...) when feed_tile_summary is empty. That helper runs strip-markdown with keep: ["link"], then walks tokens with a regex that preserves inline code as well. The result: notebooks whose openings include links, inline / fenced code, raw HTML, images, or tables render with visible syntax on feed cards (e.g. [click here](https://...), backticks, <iframe ...>). Authors then have to discover the Feed Tile Summary field on their own to clean it up after the fact.

This shifts the discovery to creation time. The author is told, at submit, exactly why the summary is required and what to do.

Implementation

  • front_end/src/app/(main)/questions/components/notebook_form.tsx
    • New FEED_TILE_PREVIEW_CHAR_LIMIT = 250 constant (conservative upper bound; actual tile budget is width/height-derived at render time).
    • New NOISY_MARKDOWN_PATTERNS list of regexes: images, links, inline code, fenced code, HTML tags, table rows. Plain emphasis (**bold**, *italic*) is intentionally excluded since strip-markdown cleans those up on the tile.
    • createNotebookSchema now wraps its z.object({...}) in a .superRefine() that adds a ZodIssueCode.custom issue with path: ["feed_tile_summary"] when the markdown preview is noisy and the summary is empty / whitespace-only. The existing Textarea already renders field errors as red text via FormError.
  • front_end/messages/en.json
    • New i18n key feedTileSummaryRequiredForFormattedContent with the explainer text shown under the field.

Server-side validation was intentionally skipped — this is a UX rule, not a data integrity rule, and the existing notebook write serializer has no equivalent cross-field validation pattern.

Test plan

  • Create a notebook with a clean plain-text opening — form submits without requiring Feed Tile Summary.
  • Create a notebook whose first paragraph contains a markdown link ([text](url)) — submit blocked, red explainer text appears under Feed Tile Summary.
  • Repeat with: inline code `foo`, fenced code block, raw <iframe> tag, image syntax ![](...), and a markdown table — each should trigger the requirement.
  • Fill in Feed Tile Summary in each case — form submits successfully.
  • Edit an existing notebook with noisy leading markdown but no summary — form correctly requires the summary on save.
  • Confirm field-level error renders red (matching existing form_field styling).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Improvements

    • Feed tile summary is now required when a notebook’s visible start contains formatted content (e.g., tables or raw HTML) that wouldn’t render cleanly in a feed; the form will prompt for a short plain-text summary when needed.
  • Localization

    • Added an English message explaining the feed tile summary requirement for formatted content.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

Warning

Rate limit exceeded

@leonardthethird has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 14 minutes and 31 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 00f6b462-4921-4d6e-8dcc-0ad1d44a6572

📥 Commits

Reviewing files that changed from the base of the PR and between 4ac3388 and 97e6620.

📒 Files selected for processing (2)
  • front_end/messages/en.json
  • front_end/src/app/(main)/questions/components/notebook_form.tsx
📝 Walkthrough

Walkthrough

Adds detection of "noisy" notebook markdown previews (raw HTML or table-like rows) and a Zod cross-field validation that requires a non-empty feed_tile_summary when the truncated preview matches those patterns; also adds an English i18n message key for the validation error.

Changes

Feed Tile Summary Validation for Formatted Content

Layer / File(s) Summary
Noisy tile preview detection
front_end/src/app/(main)/questions/components/notebook_form.tsx
Adds preview sizing constants, NOISY_TILE_PREVIEW_PATTERNS, and hasNoisyTilePreview which uses getMarkdownSummary to render a truncated preview and checks for raw HTML tags and table-like pipe rows.
Feed tile summary cross-field validation
front_end/src/app/(main)/questions/components/notebook_form.tsx
Adds a Zod superRefine to createNotebookSchema that trims feed_tile_summary and, if empty when the preview is noisy, reports a Zod issue on feed_tile_summary using the new translation key.
English localization entry
front_end/messages/en.json
Inserts feedTileSummaryRequiredForFormattedContent after feedTileSummaryPlaceholder with guidance that a short plain-text summary is required when the visible start contains a table or raw HTML.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Metaculus/metaculus#4113: Earlier PR that added the feed_tile_summary field and UI wiring used by this cross-field validation.

Suggested reviewers

  • elisescu
  • ncarazon
  • hlbmtc

Poem

A rabbit reads the notebook light,
Finds tables, tags that block the sight,
"Summarize in plain text, please," it sings,
So feed tiles show the right beginnings. 🐇✨

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding a requirement for feed tile summary when notebook markdown renders noisily.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/notebook-feed-tile-summary-validation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 21, 2026

🚀 Preview Environment

Your preview environment is ready!

Resource Details
🌐 Preview URL https://metaculus-pr-4761-feat-notebook-feed-tile-summar-preview.mtcl.cc
📦 Docker Image ghcr.io/metaculus/metaculus:feat-notebook-feed-tile-summary-validation-97e6620
🗄️ PostgreSQL NeonDB branch preview/pr-4761-feat-notebook-feed-tile-summar
Redis Fly Redis mtc-redis-pr-4761-feat-notebook-feed-tile-summar

Details

  • Commit: 537aec3897f8f235b3c3a5c3e4d66a5e895bd95c
  • Branch: feat/notebook-feed-tile-summary-validation
  • Fly App: metaculus-pr-4761-feat-notebook-feed-tile-summar

ℹ️ Preview Environment Info

Isolation:

  • PostgreSQL and Redis are fully isolated from production
  • Each PR gets its own database branch and Redis instance
  • Changes pushed to this PR will trigger a new deployment

Limitations:

  • Background workers and cron jobs are not deployed in preview environments
  • If you need to test background jobs, use Heroku staging environments

Cleanup:

  • This preview will be automatically destroyed when the PR is closed

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@front_end/src/app/`(main)/questions/components/notebook_form.tsx:
- Around line 272-276: Remove the temporary debug console logging calls in the
notebook_form.tsx onValid handler (the console.log("[FEED_TILE_DEBUG] onValid ->
submitting", ...) lines and the similar debug log at 279-281); delete these
console statements so no console.debug/console.log remains in the onValid
submission path (keep all functional logic unchanged).
- Around line 93-101: Temporary diagnostic console logging inside the
superRefine validation (the console.log call logging "[FEED_TILE_DEBUG]
superRefine fired" and fields like data.markdown, summary, noisy, willAddIssue)
must be removed before merge; delete the console.log statement (or replace it
with a dev-only debug logger behind an environment/feature flag) so no markdown
snippets or internal validation state are emitted to production consoles.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 517260d1-a100-4dc3-8da1-60115213c737

📥 Commits

Reviewing files that changed from the base of the PR and between 8b97652 and c9d44aa.

📒 Files selected for processing (1)
  • front_end/src/app/(main)/questions/components/notebook_form.tsx

Comment thread front_end/src/app/(main)/questions/components/notebook_form.tsx Outdated
Comment thread front_end/src/app/(main)/questions/components/notebook_form.tsx Outdated
When the visible start of a notebook's body would render as raw HTML or
table-like pipe noise on a feed tile, require feed_tile_summary so
authors set a clean plain-text preview at creation time instead of
discovering the broken tile after publish.

Implementation:
- Reuses the tile's own getMarkdownSummary helper to compute exactly what
  a reader sees, sized to the widest realistic tile (~900px / ~450
  rendered chars). Anything past that point is past every tile size and
  doesn't trigger the rule, so a clean intro followed by a table past
  the visible area still submits cleanly.
- Scans the rendered preview for two surviving-after-strip-markdown
  patterns: raw HTML tags (iframes, divs) and 3+ pipes on a line
  (table-like content MDXEditor didn't promote to a real table). Links,
  inline code, fenced code, images, emphasis, and lists all render
  correctly on the tile and are intentionally not flagged.
- A 2000 source-char slice bounds remark parse cost on long notebooks.
- Adds a zod superRefine on the notebook schema that attaches a
  ZodIssueCode.custom issue to feed_tile_summary; the existing Textarea
  + FormError pair already renders field errors as red inline text.
- New i18n key feedTileSummaryRequiredForFormattedContent with the
  explainer copy.

Server-side validation was skipped intentionally: this is a UX rule, not
a data integrity rule, and NotebookWriteSerializer has no equivalent
cross-field validation pattern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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