feat(review): add config-driven before/after screenshot-table gate - #3877
Conversation
…2006) Makes the previously documented-only requirement (a contributor visual/ frontend PR needs a before/after screenshot table or it gets auto-closed) a per-repo, config-as-code gate: off by default, scoped by label/path, with a configurable action and contract message, layered the same way as the existing blacklist/review-nag/review-evasion anti-abuse mechanisms.
…g, close coverage gaps Renumbers 0115_screenshot_table_gate.sql to 0117 after a concurrently-merged PR claimed 0115. Raises MAX_FOCUS_MANIFEST_BYTES from 64 KiB to 128 KiB -- gittensory.full.yml (our own reference doc, round-trip tested by config-templates.test.ts) had already reached 65522/65536 bytes on main before this PR's own doc addition, so any concurrent PR's config-doc growth would have tripped the old ceiling next; a real per-repo .gittensory.yml never needs anywhere near this size, so the DoS-guard intent is unaffected. Adds a regression test for parseJsonStringArray's non-array (valid JSON, wrong shape) fail-closed branch, previously only covered by the JSON-syntax- error path.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
gittensory-ui | 5118371 | Commit Preview URL Branch Preview URL |
Jul 07 2026, 12:07 AM |
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3877 +/- ##
==========================================
+ Coverage 93.54% 93.56% +0.02%
==========================================
Files 338 339 +1
Lines 33335 33445 +110
Branches 12192 12242 +50
==========================================
+ Hits 31182 31292 +110
Misses 1528 1528
Partials 625 625
🚀 New features to boost your workflow:
|
|
Tip 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 ✅ Gittensory review result - approve/merge recommendedReview updated: 2026-07-07 00:38:18 UTC
✅ Suggested Action - Approve/Merge
Review summary Nits — 6 non-blocking
Review context
Contributor next steps
Signal definitions
🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.
|
Summary
contributor_blacklist,review_nag,review_evasion_protection): arepository_settingsrow (not a.gittensory.yml review.*knob), off by default, opt-in per repo.migrations/0117_screenshot_table_gate.sql+src/db/schema.ts: addsscreenshot_table_gate_enabled(default off),screenshot_table_gate_when_labels_json/screenshot_table_gate_when_paths_json(either-match scoping, both empty = every PR),screenshot_table_gate_action(close/request_changes/comment, default close),screenshot_table_gate_message(nullable, null = built-in templated message).src/review/screenshot-table-gate.ts: the deterministic (no AI) detector -- a PR "has a screenshot table" when its body contains a markdown table region with at least one image (or<img>). Also flags an image pasted outside any table, or a screenshot file committed to the repo under a scoped path (should be uploaded to the PR body instead).src/db/repositories.ts+src/openapi/schemas.ts+src/settings/agent-actions.ts: settings round-trip (get/upsert), OpenAPI schema, and wiring into the agent-action planner so a violating PR gets the configured action..gittensory.yml.example/config/examples/gittensory.full.yml: documents the new setting.gittensory.full.yml(our own reference doc, round-trip parsed byconfig-templates.test.ts) had already reached 65522/65536 bytes onmainbefore this PR's own doc addition -- any concurrent PR's config-doc growth would have tripped the old 64 KiBMAX_FOCUS_MANIFEST_BYTESceiling next. Raised it to 128 KiB (src/signals/focus-manifest.ts) with a comment explaining why; a real per-repo.gittensory.ymlnever needs anywhere near this size, so the DoS-guard intent is unaffected.parseJsonStringArray's non-array (valid JSON, wrong shape, e.g.{"a":1}) fail-closed branch, previously only covered by the JSON-syntax-error path.Closes #2006.
Scope
type(scope): short summaryConventional Commit format.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
git diff --checknpm run actionlintnpm run typechecknpm run test:coveragelocally -- 100% branch coverage on every changed line/branch in this diff (verified via targeted lcov branch inspection against the exact diff ranges).npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderateSafety
UI Evidencesection. (N/A -- backend-only change, no UI.)Notes