Skip to content

fix: address the review of the contribution routes - #46

Merged
matbrgz merged 1 commit into
mainfrom
fix/routes-review
Oct 11, 2026
Merged

matbrgz merged 1 commit into
mainfrom
fix/routes-review

Conversation

@matbrgz

@matbrgz matbrgz commented Oct 11, 2026

Copy link
Copy Markdown
Member

Summary

Fixes from an independent review of #41–#44 (the reviewer ran npm run check too).

# Finding Fix
1 A suggestion named fixes #12 closed issue #12 on merge (title and commit subject were not escaped) neutralizeGitHubText on titles and commit subjects: @, #n, GH-n, owner/repo#n, closing keywords, URLs
2 GET /v1/contributions listed other people's PRs whose text contained the marker words Only bodies ending in the exact marker, which reader text cannot produce (< is escaped)
3 A failed label call returned 502 for an opened PR, inviting duplicates and skipping the quota Labelling is best effort (labelled: false)
4 Link check followed redirects to http, localhost or IPs (blind SSRF); failed checks were free Manual redirects, each hop re-validated as public https, ≤ 3 hops; 50 link checks a day per identity
5 Open-PR slots never freed when the repository name differed in case Case-insensitive keys; release needs the marker on the last line
6 A GitHub-side stale sha returned 409 without the current content Re-read and include content and sha
7 Failures after branch creation left orphan contribute/* branches Best-effort branch deletion on failure
8 Caps were check-then-act Daily slot reserved before GitHub and rolled back on failure; KV's non-atomic limits documented (README, code)
9 Bodies without Content-Length were fully buffered before the size check Streamed read that stops past the limit
10 Spec said "open/merged", route returns closed too Spec updated

ELI5

A second review found ten loose ends in the new API, including a way to close our issues from a suggestion's name; all are tied up and each has a test.

Tests

npm run check: lint ✓, typecheck ✓, 411 tests ✓ (review-regressions.test.ts covers every row above).

AI disclosure

  • Built with AI assistance (Claude Code: implementation and an independent review agent); to be reviewed by code owners.

Stacked on #44.

🤖 Generated with Claude Code

- titles and commit subjects neutralise @mentions, #refs, GH-n, owner/repo#n, closing keywords and URLs from reader text
- GET /v1/contributions keeps only pull requests whose body ends with the exact identity marker, which reader text cannot produce
- labelling is best effort once the pull request exists, so a failure no longer returns an error that invites a duplicate
- failures after the branch is created delete it, leaving no orphan contribute/* branch
- the link check follows redirects by hand, re-validating every hop as a public https address (at most 3), and is capped at 50 a day per identity
- quota keys are case-insensitive, so slots are released whatever the repository's case; the release needs the marker on the last line
- the daily slot is reserved before GitHub and given back on failure; KV's non-atomic counters are documented
- a GitHub-side stale sha returns 409 with the current content, as the contract says
- JSON bodies are read as a stream and abandoned once over the limit
- spec: contributions list open, closed and merged

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@matbrgz
matbrgz changed the base branch from feat/abuse-limits to main October 11, 2026 12:19
@matbrgz
matbrgz merged commit e3f837a into main Oct 11, 2026
1 check passed
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