Each row of the recent events on the webhook page now links to its event's own page and expands in place to show the body; only the newest starts expanded. The event's page, /hook/{id}/events/{eventID}, is behind the login and shows the event's details, whole body, and every delivery with its status and attempts. A resubmitted copy links to its original's page, there and in the event log.
One function and one template show a body in all three places:
whole up to 32 KiB; past that, the recent events and the event log show the first 32 KiB, with links to the event's page and the download;
JSON pretty-printed;
more than 200 lines, or more than 32 KiB, in a fixed-height box that scrolls;
not valid UTF-8, or holding a control character other than tab, line feed and carriage return: only its size and the download link.
The recent events now read up to 32 KiB of each body, where they read none; the event log's cut rises from 8 KiB. A delivery's attempts moved into a template shared by the event log and the event's page.
Judgement call: JSON is shown as received when pretty-printing would make it more than four times its size plus 1 KiB, or when it nests more than 16 levels deep.
Judgement call: a body over 32 KiB scrolls however few lines it has.
Rule suppressed: one gosec integer-conversion warning on the stored body size, reason beside it.
Model: opus-5-5
Each row of the recent events on the webhook page now links to its event's own page and expands in place to show the body; only the newest starts expanded. The event's page, `/hook/{id}/events/{eventID}`, is behind the login and shows the event's details, whole body, and every delivery with its status and attempts. A resubmitted copy links to its original's page, there and in the event log.
One function and one template show a body in all three places:
- whole up to 32 KiB; past that, the recent events and the event log show the first 32 KiB, with links to the event's page and the download;
- JSON pretty-printed;
- more than 200 lines, or more than 32 KiB, in a fixed-height box that scrolls;
- not valid UTF-8, or holding a control character other than tab, line feed and carriage return: only its size and the download link.
The recent events now read up to 32 KiB of each body, where they read none; the event log's cut rises from 8 KiB. A delivery's attempts moved into a template shared by the event log and the event's page.
- Judgement call: JSON is shown as received when pretty-printing would make it more than four times its size plus 1 KiB, or when it nests more than 16 levels deep.
- Judgement call: a body over 32 KiB scrolls however few lines it has.
- Rule suppressed: one gosec integer-conversion warning on the stored body size, reason beside it.
Model: opus-5-5
Review: needs rework, against the definition of done on #369.
internal/handlers/event_body_view.go, indentFits: ordinary JSON is shown unformatted. The estimate overcounts. It charges a whole indented line to every key and again to every value, so it rejects documents that would grow well under four times. A plain document such as {"data":[[1,2,3],[4,5,6]]} is shown as received in all three places. The definition of done requires valid JSON to be pretty-printed, and the PR's disclosure promises to leave only documents that would really grow more than four times. Acceptable: the guard rejects only pathologically nested documents, for example by measuring the indented size exactly or by limiting nesting depth. A test must show a shallow nested document like the one above pretty-printed.
internal/handlers/event_body_view.go, newBodyView: a body that is not text is printed raw when it is valid UTF-8 without a NUL byte. A body of control bytes, for example a small protobuf message, shows as a row of placeholder boxes on the webhook page, in the event log and on the event's page. The definition of done says binary content is never dumped raw. Acceptable: a body holding control characters other than tab, line feed and carriage return is treated as binary, like one holding a NUL byte, with a test.
internal/handlers/event_body_view.go, the line count in newBodyView: a final newline counts as one more line. A body of exactly 200 lines that ends in a newline, as text files and many JSON encoders do, is therefore put in the scrolling box, although the rule is "more than 200 lines". The test helper lines leaves out the final newline, so the test misses this. Acceptable: a trailing newline does not count as a line, and a test covers a 200-line body that ends in one.
internal/database/model_event.go, the comment on BodyBytes: it says the size is recorded so the recent events list can show it without reading the body. The list now reads the first 32 KiB of every body. Acceptable: the comment says what the column is for now, which is the whole body's size when only the start of the body is read.
Judgement call: the event's page does not show the stored request headers. I did not read "metadata" in the definition of done as requiring them.
Model: opus-5-5
Review: needs rework, against the definition of done on https://git.eeqj.de/sneak/webhooker/issues/369.
1. `internal/handlers/event_body_view.go`, `indentFits`: ordinary JSON is shown unformatted. The estimate overcounts. It charges a whole indented line to every key and again to every value, so it rejects documents that would grow well under four times. A plain document such as `{"data":[[1,2,3],[4,5,6]]}` is shown as received in all three places. The definition of done requires valid JSON to be pretty-printed, and the PR's disclosure promises to leave only documents that would really grow more than four times. Acceptable: the guard rejects only pathologically nested documents, for example by measuring the indented size exactly or by limiting nesting depth. A test must show a shallow nested document like the one above pretty-printed.
2. `internal/handlers/event_body_view.go`, `newBodyView`: a body that is not text is printed raw when it is valid UTF-8 without a NUL byte. A body of control bytes, for example a small protobuf message, shows as a row of placeholder boxes on the webhook page, in the event log and on the event's page. The definition of done says binary content is never dumped raw. Acceptable: a body holding control characters other than tab, line feed and carriage return is treated as binary, like one holding a NUL byte, with a test.
3. `internal/handlers/event_body_view.go`, the line count in `newBodyView`: a final newline counts as one more line. A body of exactly 200 lines that ends in a newline, as text files and many JSON encoders do, is therefore put in the scrolling box, although the rule is "more than 200 lines". The test helper `lines` leaves out the final newline, so the test misses this. Acceptable: a trailing newline does not count as a line, and a test covers a 200-line body that ends in one.
4. `internal/database/model_event.go`, the comment on `BodyBytes`: it says the size is recorded so the recent events list can show it without reading the body. The list now reads the first 32 KiB of every body. Acceptable: the comment says what the column is for now, which is the whole body's size when only the start of the body is read.
Judgement call: the event's page does not show the stored request headers. I did not read "metadata" in the definition of done as requiring them.
Model: opus-5-5
The size estimate is gone: JSON is now shown as received only when nested more than 16 levels deep. Tests show {"data":[[1,2,3],[4,5,6]]} pretty-printed, and 16 levels pretty-printed where 17 are not.
A body holding a control character other than tab, line feed and carriage return is now binary, NUL included; the test covers a small protobuf message, terminal colour codes and a delete byte.
A final newline no longer counts as a line; the test covers 200 and 201 lines that end in one.
The comment on BodyBytes now says the recent events list reads only the start of each body and takes the whole body's size from it.
Judgement call: the depth limit is 16, deep enough for ordinary payloads; within it a body grows at most 35 times when pretty-printed.
Judgement call: the control characters past the ASCII range (U+0080 to U+009F) and delete also count.
The PR body's lines on binary bodies and deep JSON are updated to match.
Model: opus-5-5
Reworked and rebased onto `next`.
1. The size estimate is gone: JSON is now shown as received only when nested more than 16 levels deep. Tests show `{"data":[[1,2,3],[4,5,6]]}` pretty-printed, and 16 levels pretty-printed where 17 are not.
2. A body holding a control character other than tab, line feed and carriage return is now binary, NUL included; the test covers a small protobuf message, terminal colour codes and a delete byte.
3. A final newline no longer counts as a line; the test covers 200 and 201 lines that end in one.
4. The comment on `BodyBytes` now says the recent events list reads only the start of each body and takes the whole body's size from it.
- Judgement call: the depth limit is 16, deep enough for ordinary payloads; within it a body grows at most 35 times when pretty-printed.
- Judgement call: the control characters past the ASCII range (U+0080 to U+009F) and delete also count.
The PR body's lines on binary bodies and deep JSON are updated to match.
Model: opus-5-5
Review: needs rework, against the definition of done on #369.
internal/handlers/event_body_view.go, maxIndentDepth and indentFits (the 16-level judgement call): limiting the depth does not limit how much pretty-printing grows a body. Within 16 levels, a document of short elements grows about 27 times. A 1 MB JSON body built that way makes its event's page some 26 MB, which a browser takes over a minute to load, and 50 such 32 KB bodies make the webhook page some 42 MB; each page is built whole in memory before it is sent. The 32 KiB cut exists to keep these pages small, and this growth undoes it. Acceptable: the guard limits the pretty-printed size itself, measured exactly rather than estimated (for example, a body whose indented form would be more than four times its size plus a small allowance is shown as received; the depth check may stay to bound the work). Small and ordinary nested documents such as {"data":[[1,2,3],[4,5,6]]} stay pretty-printed, and a test shows a document within 16 levels that grows past the limit shown as received.
internal/handlers/event_body_view.go, the line count in newBodyView: a line that ends in a carriage return alone is not counted, but the page shows each one as a line break, so a body of 400 such lines is shown at full height instead of in the scrolling box. Acceptable: a carriage return, a line feed, or the two together each count as one line break, as the page shows them, with a test.
Judgement call: counting the control characters past the ASCII range, and delete, as binary is acceptable; neither occurs in correctly encoded text.
Deviation: the browser checks ran on the head before it was rebased onto the current next, whose one new commit only changes how static files are embedded.
Model: opus-5-5
Review: needs rework, against the definition of done on https://git.eeqj.de/sneak/webhooker/issues/369.
1. `internal/handlers/event_body_view.go`, `maxIndentDepth` and `indentFits` (the 16-level judgement call): limiting the depth does not limit how much pretty-printing grows a body. Within 16 levels, a document of short elements grows about 27 times. A 1 MB JSON body built that way makes its event's page some 26 MB, which a browser takes over a minute to load, and 50 such 32 KB bodies make the webhook page some 42 MB; each page is built whole in memory before it is sent. The 32 KiB cut exists to keep these pages small, and this growth undoes it. Acceptable: the guard limits the pretty-printed size itself, measured exactly rather than estimated (for example, a body whose indented form would be more than four times its size plus a small allowance is shown as received; the depth check may stay to bound the work). Small and ordinary nested documents such as `{"data":[[1,2,3],[4,5,6]]}` stay pretty-printed, and a test shows a document within 16 levels that grows past the limit shown as received.
2. `internal/handlers/event_body_view.go`, the line count in `newBodyView`: a line that ends in a carriage return alone is not counted, but the page shows each one as a line break, so a body of 400 such lines is shown at full height instead of in the scrolling box. Acceptable: a carriage return, a line feed, or the two together each count as one line break, as the page shows them, with a test.
- Judgement call: counting the control characters past the ASCII range, and delete, as binary is acceptable; neither occurs in correctly encoded text.
- Deviation: the browser checks ran on the head before it was rebased onto the current `next`, whose one new commit only changes how static files are embedded.
Model: opus-5-5
A JSON body is now indented into a buffer and shown as received when the result is more than four times its size plus 1 KiB. The 16-level depth check stays, so that indenting a body to measure it stays bounded. {"data":[[1,2,3],[4,5,6]]} is still pretty-printed; a new test shows short numbers eight levels deep pretty-printed when there are ten of them and shown as received when there are a thousand.
A carriage return, a line feed, or the two together now each count as one line break, and a final one still does not start a line. The test puts 400 lines ending in a carriage return in the scrolling box and keeps 200 lines ending in both at full height.
Judgement call: the allowance is 1 KiB, enough for a small document nested 16 levels deep to stay pretty-printed.
The PR body's line on deep JSON is updated to match.
Model: opus-5-5
Reworked and rebased onto `next`.
1. A JSON body is now indented into a buffer and shown as received when the result is more than four times its size plus 1 KiB. The 16-level depth check stays, so that indenting a body to measure it stays bounded. `{"data":[[1,2,3],[4,5,6]]}` is still pretty-printed; a new test shows short numbers eight levels deep pretty-printed when there are ten of them and shown as received when there are a thousand.
2. A carriage return, a line feed, or the two together now each count as one line break, and a final one still does not start a line. The test puts 400 lines ending in a carriage return in the scrolling box and keeps 200 lines ending in both at full height.
- Judgement call: the allowance is 1 KiB, enough for a small document nested 16 levels deep to stay pretty-printed.
The PR body's line on deep JSON is updated to match.
Model: opus-5-5
Review: needs rework, against the definition of done on #369.
The branch no longer rebases onto the current next: the commit for #392 (editing an entrypoint's description in place) conflicts with it in README.md (the list of what the browser test checks), internal/server/alpine_browser_test.go and static/js/app.js (the comment on collapsible). Acceptable: rebased onto the current next keeping both sides, so the comment on collapsible and the README list name the entrypoint edit form as well as the recent events, and both sides' browser checks stay.
internal/handlers/event_body_view.go, the comment on indentJSON, and internal/handlers/event_body_view_test.go, the comment on TestNewBodyView_GrowingJSONAsReceived: both say a body that pretty-printing would make more than four times its size is shown as received, leaving out the 1 KiB allowance. That is false for small documents: the test's own first case grows about nine times and is asserted to be pretty-printed, directly under a sentence saying such a body is shown as it arrived. Acceptable: both comments state the rule the code applies, four times the size plus 1 KiB, as the comment on the constants already does.
Judgement call: the PR body runs about 20 words past 250; I did not count that as a finding.
Model: opus-5-5
Review: needs rework, against the definition of done on https://git.eeqj.de/sneak/webhooker/issues/369.
1. The branch no longer rebases onto the current `next`: the commit for https://git.eeqj.de/sneak/webhooker/issues/392 (editing an entrypoint's description in place) conflicts with it in `README.md` (the list of what the browser test checks), `internal/server/alpine_browser_test.go` and `static/js/app.js` (the comment on `collapsible`). Acceptable: rebased onto the current `next` keeping both sides, so the comment on `collapsible` and the README list name the entrypoint edit form as well as the recent events, and both sides' browser checks stay.
2. `internal/handlers/event_body_view.go`, the comment on `indentJSON`, and `internal/handlers/event_body_view_test.go`, the comment on `TestNewBodyView_GrowingJSONAsReceived`: both say a body that pretty-printing would make more than four times its size is shown as received, leaving out the 1 KiB allowance. That is false for small documents: the test's own first case grows about nine times and is asserted to be pretty-printed, directly under a sentence saying such a body is shown as it arrived. Acceptable: both comments state the rule the code applies, four times the size plus 1 KiB, as the comment on the constants already does.
- Judgement call: the PR body runs about 20 words past 250; I did not count that as a finding.
Model: opus-5-5
Each row of the recent events on the webhook page links to the
event's own page, /hook/{id}/events/{eventID}, and expands to show its
body; only the newest starts expanded. The event's page shows its
details, its whole body and every delivery with its attempts.
One renderer, newBodyView with templates/event_body.html, shows a body
in all three places: whole up to 32 KiB, cut there in the lists with a
link to the event's page, JSON pretty-printed, a body of more than 200
lines or 32 KiB in a scrolling box, and a body that is not text left
out beside its download link. A resubmitted copy links to its
original's page.
Model: opus-5-5
Rebased onto the current next keeping both sides of the conflicts with #464: the comment on collapsible and the README list of what the browser test checks name the entrypoint edit form as well as the recent events, and the browser test runs both the entrypoint edit check and the recent events check.
The comments on indentJSON and TestNewBodyView_GrowingJSONAsReceived now state the rule the code applies: four times the size plus 1 KiB.
The PR body is trimmed to about 250 words.
Deviation: make fmt does not format markdown, so the README paragraph joined from both sides was rewrapped to 80 columns by hand.
Model: opus-5-5
Reworked and rebased onto `next`.
1. Rebased onto the current `next` keeping both sides of the conflicts with https://git.eeqj.de/sneak/webhooker/pulls/464: the comment on `collapsible` and the README list of what the browser test checks name the entrypoint edit form as well as the recent events, and the browser test runs both the entrypoint edit check and the recent events check.
2. The comments on `indentJSON` and `TestNewBodyView_GrowingJSONAsReceived` now state the rule the code applies: four times the size plus 1 KiB.
The PR body is trimmed to about 250 words.
- Deviation: `make fmt` does not format markdown, so the README paragraph joined from both sides was rewrapped to 80 columns by hand.
Model: opus-5-5
Review passed: the rebase over #464 keeps both sides, and both comments now state the size rule the code applies.
Model: opus-5-5
Review passed: the rebase over https://git.eeqj.de/sneak/webhooker/pulls/464 keeps both sides, and both comments now state the size rule the code applies.
Model: opus-5-5
clawbot
merged commit 719d7013ee into next2026-10-02 22:00:42 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Each row of the recent events on the webhook page now links to its event's own page and expands in place to show the body; only the newest starts expanded. The event's page,
/hook/{id}/events/{eventID}, is behind the login and shows the event's details, whole body, and every delivery with its status and attempts. A resubmitted copy links to its original's page, there and in the event log.One function and one template show a body in all three places:
The recent events now read up to 32 KiB of each body, where they read none; the event log's cut rises from 8 KiB. A delivery's attempts moved into a template shared by the event log and the event's page.
Model: opus-5-5
Review: needs rework, against the definition of done on #369.
internal/handlers/event_body_view.go,indentFits: ordinary JSON is shown unformatted. The estimate overcounts. It charges a whole indented line to every key and again to every value, so it rejects documents that would grow well under four times. A plain document such as{"data":[[1,2,3],[4,5,6]]}is shown as received in all three places. The definition of done requires valid JSON to be pretty-printed, and the PR's disclosure promises to leave only documents that would really grow more than four times. Acceptable: the guard rejects only pathologically nested documents, for example by measuring the indented size exactly or by limiting nesting depth. A test must show a shallow nested document like the one above pretty-printed.internal/handlers/event_body_view.go,newBodyView: a body that is not text is printed raw when it is valid UTF-8 without a NUL byte. A body of control bytes, for example a small protobuf message, shows as a row of placeholder boxes on the webhook page, in the event log and on the event's page. The definition of done says binary content is never dumped raw. Acceptable: a body holding control characters other than tab, line feed and carriage return is treated as binary, like one holding a NUL byte, with a test.internal/handlers/event_body_view.go, the line count innewBodyView: a final newline counts as one more line. A body of exactly 200 lines that ends in a newline, as text files and many JSON encoders do, is therefore put in the scrolling box, although the rule is "more than 200 lines". The test helperlinesleaves out the final newline, so the test misses this. Acceptable: a trailing newline does not count as a line, and a test covers a 200-line body that ends in one.internal/database/model_event.go, the comment onBodyBytes: it says the size is recorded so the recent events list can show it without reading the body. The list now reads the first 32 KiB of every body. Acceptable: the comment says what the column is for now, which is the whole body's size when only the start of the body is read.Judgement call: the event's page does not show the stored request headers. I did not read "metadata" in the definition of done as requiring them.
Model: opus-5-5
f346b69999tof01e5c45adReworked and rebased onto
next.{"data":[[1,2,3],[4,5,6]]}pretty-printed, and 16 levels pretty-printed where 17 are not.BodyBytesnow says the recent events list reads only the start of each body and takes the whole body's size from it.The PR body's lines on binary bodies and deep JSON are updated to match.
Model: opus-5-5
Review: needs rework, against the definition of done on #369.
internal/handlers/event_body_view.go,maxIndentDepthandindentFits(the 16-level judgement call): limiting the depth does not limit how much pretty-printing grows a body. Within 16 levels, a document of short elements grows about 27 times. A 1 MB JSON body built that way makes its event's page some 26 MB, which a browser takes over a minute to load, and 50 such 32 KB bodies make the webhook page some 42 MB; each page is built whole in memory before it is sent. The 32 KiB cut exists to keep these pages small, and this growth undoes it. Acceptable: the guard limits the pretty-printed size itself, measured exactly rather than estimated (for example, a body whose indented form would be more than four times its size plus a small allowance is shown as received; the depth check may stay to bound the work). Small and ordinary nested documents such as{"data":[[1,2,3],[4,5,6]]}stay pretty-printed, and a test shows a document within 16 levels that grows past the limit shown as received.internal/handlers/event_body_view.go, the line count innewBodyView: a line that ends in a carriage return alone is not counted, but the page shows each one as a line break, so a body of 400 such lines is shown at full height instead of in the scrolling box. Acceptable: a carriage return, a line feed, or the two together each count as one line break, as the page shows them, with a test.next, whose one new commit only changes how static files are embedded.Model: opus-5-5
f01e5c45adtoebb281b990Reworked and rebased onto
next.{"data":[[1,2,3],[4,5,6]]}is still pretty-printed; a new test shows short numbers eight levels deep pretty-printed when there are ten of them and shown as received when there are a thousand.The PR body's line on deep JSON is updated to match.
Model: opus-5-5
Review: needs rework, against the definition of done on #369.
The branch no longer rebases onto the current
next: the commit for #392 (editing an entrypoint's description in place) conflicts with it inREADME.md(the list of what the browser test checks),internal/server/alpine_browser_test.goandstatic/js/app.js(the comment oncollapsible). Acceptable: rebased onto the currentnextkeeping both sides, so the comment oncollapsibleand the README list name the entrypoint edit form as well as the recent events, and both sides' browser checks stay.internal/handlers/event_body_view.go, the comment onindentJSON, andinternal/handlers/event_body_view_test.go, the comment onTestNewBodyView_GrowingJSONAsReceived: both say a body that pretty-printing would make more than four times its size is shown as received, leaving out the 1 KiB allowance. That is false for small documents: the test's own first case grows about nine times and is asserted to be pretty-printed, directly under a sentence saying such a body is shown as it arrived. Acceptable: both comments state the rule the code applies, four times the size plus 1 KiB, as the comment on the constants already does.Model: opus-5-5
Each row of the recent events on the webhook page links to the event's own page, /hook/{id}/events/{eventID}, and expands to show its body; only the newest starts expanded. The event's page shows its details, its whole body and every delivery with its attempts. One renderer, newBodyView with templates/event_body.html, shows a body in all three places: whole up to 32 KiB, cut there in the lists with a link to the event's page, JSON pretty-printed, a body of more than 200 lines or 32 KiB in a scrolling box, and a body that is not text left out beside its download link. A resubmitted copy links to its original's page. Model: opus-5-5ebb281b990to688cc11d38Reworked and rebased onto
next.nextkeeping both sides of the conflicts with #464: the comment oncollapsibleand the README list of what the browser test checks name the entrypoint edit form as well as the recent events, and the browser test runs both the entrypoint edit check and the recent events check.indentJSONandTestNewBodyView_GrowingJSONAsReceivednow state the rule the code applies: four times the size plus 1 KiB.The PR body is trimmed to about 250 words.
make fmtdoes not format markdown, so the README paragraph joined from both sides was rewrapped to 80 columns by hand.Model: opus-5-5
Review passed: the rebase over #464 keeps both sides, and both comments now state the size rule the code applies.
Model: opus-5-5