Skip to content

feat(review): viewport x theme completeness matrix for the screenshot-table gate #4540

Description

@JSONbored

Problem

The deterministic screenshot-table gate (screenshotTableGate, #2006) only checks that a PR body contains some markdown table with any image inside it. It has no concept of viewport or color-mode coverage. metagraphed's own public contributor skill (.claude/skills/metagraphed/SKILL.md, Phase C2, landed in #3770) documents an exact 3-viewport x 2-theme x before/after = 12-image contract for visual PRs, but nothing in the review engine enforces it, and metagraphed's deterministic gate is currently disabled entirely (relies on AI judgment only).

Confirmed live example: metagraphed PR #4661 shipped with 4/12 images (desktop only, light+dark) and the AI reviewer's comment stated "before/after screenshots for both themes are included as required," treating partial coverage as compliant. Root cause: the private review-context copy the AI reviewer reads its instructions from was never updated to mention viewport/theme completeness, even though the public skill file already documents it precisely.

Fix

  • screenshotTableGate config gains requireViewports/requireThemes (string arrays, empty by default -- opt-in per repo, byte-identical for repos that don't set them).
  • When requireViewports is non-empty, the evaluator matches each required (viewport, theme) pair against a labeled table row (case-insensitive substring match on the row's first cell, e.g. "Desktop · Light") and requires at least two image-bearing cells in that row (before + after). Missing pairs are named in the rejection reason.
  • action gains a real advisory value (distinct from the request_changes/comment values feat(review): wire bot-generated visual captures into screenshotTableGate #4110 removed as dead/unwired config -- this one is actually wired: advisory computes the violation but never contributes to the close-triggering match, exactly like close already only fires when action === "close").
  • Full config-as-code wiring: DB migration + Drizzle schema + settings resolver + .gittensory.yml manifest parser + OpenAPI, per the repo's own config-field-parity convention.

Scope

Not building in this PR: extending the bot's own automated visual-capture pipeline to actually shoot a tablet viewport or iterate themes (src/review/visual/*) -- this PR is about detecting and enforcing what a contributor submits, not automating capture. A skill-file link in the rejection message is handled via the existing per-repo message override (already fully custom text), not a new config field.

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:featureGittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions