2026-06-02 - 2026-09-02

Overview

95 Active Pull Requests
159 Active Issues
Excluding merges, 2 authors have pushed 12 commits to main and 97 commits to all branches. On main, 62 files have changed and there have been 4859 additions and 1335 deletions.

95 Pull requests merged by 2 users

Merged #302 State the UUID-is-the-credential rule as a rule (closes #301) 2026-08-30 04:05:38 +02:00

Merged #111 Milestone 1.0.0: internet-facing readiness 2026-08-30 04:05:00 +02:00

Merged #300 Render unknown for a zero CreatedAt in Slack/Mattermost messages (closes #298) 2026-08-24 17:52:26 +02:00

Merged #297 Carry the event's receipt time into every delivery (closes #257) 2026-08-24 06:44:24 +02:00

Merged #296 Correct four documentation claims ahead of the 1.0.0 tag 2026-08-24 06:25:09 +02:00

Merged #292 Close the two remaining delivery terminal-state gaps (closes #107) 2026-08-24 05:12:03 +02:00

Merged #287 Create every SQLite file 0600 (closes #255) 2026-08-24 04:33:40 +02:00

Merged #289 Fail loudly on an unparseable SENTRY_DSN and a malformed .env (closes #283) 2026-08-24 04:25:30 +02:00

Merged #286 Derive the source detail BaseURL scheme from reqtls (closes #272) 2026-08-24 04:04:04 +02:00

Merged #263 Make SQLite durable under concurrent readers and stop re-delivering stranded webhooks (closes #256) 2026-08-24 03:49:18 +02:00

Merged #284 Record landed 1.0.0 work and drop the removed signing roadmap in TODO.md 2026-08-24 03:43:17 +02:00

Merged #277 Bind the app port deliberately and document the proxy deployment (closes #268) 2026-08-24 03:38:44 +02:00

Merged #281 Remove inbound request signature verification (closes #279) 2026-08-24 03:25:10 +02:00

Merged #260 Stamp the build version into the binary (closes #253) 2026-08-24 03:15:21 +02:00

Merged #276 Decide request TLS in one place, per request (closes #269) 2026-08-24 03:01:38 +02:00

Merged #273 Check every statement in the webhook deletion transaction (closes #262) 2026-08-24 03:01:34 +02:00

Merged #266 Name a deleted target on its historical deliveries (closes #211) 2026-08-24 02:03:23 +02:00

Merged #264 Bound the /metrics method label (closes #261) 2026-08-24 02:03:19 +02:00

Merged #259 Validate max_retries on both target forms (closes #221) 2026-08-24 01:32:48 +02:00

Merged #258 Label HTTP metrics with the chi route pattern (closes #254) 2026-08-24 01:32:45 +02:00

Merged #251 Resubmit a stored event as a new undelivered event (closes #250) 2026-08-24 00:53:38 +02:00

Merged #249 Record the completed 1.0.0 milestone in TODO.md 2026-08-20 11:16:51 +02:00

Merged #242 Harden operator-set target headers (closes #233) 2026-08-20 10:54:43 +02:00

Merged #217 Add an egress CIDR allowlist to the SSRF guard (closes #204) 2026-08-20 10:34:42 +02:00

Merged #219 Render delivery attempt detail in the event log (closes #202) 2026-08-20 08:36:26 +02:00

Merged #240 Add per-delivery replay to the event log (closes #203) 2026-08-20 08:11:36 +02:00

Merged #239 Add a webhooker resetpw subcommand and a bootstrap banner (closes #208) 2026-08-20 08:01:42 +02:00

Merged #228 Add optional inbound webhook signature verification (closes #67) 2026-08-20 08:01:33 +02:00

Merged #223 Stop target credentials leaking into event databases (closes #206) 2026-08-20 07:55:35 +02:00

Merged #237 Read queue depths with Find, not Scan (closes #234) 2026-08-20 07:55:20 +02:00

Merged #229 Add a target edit form and reachable header/timeout fields (closes #127) 2026-08-20 07:24:13 +02:00

Merged #220 Lock DATA_DIR against a second instance (closes #201) 2026-08-20 07:23:01 +02:00

Merged #222 Log SQL with placeholders, never bound values (closes #207) 2026-08-20 07:21:00 +02:00

Merged #224 Expose delivery metrics on /metrics (closes #209) 2026-08-20 07:19:05 +02:00

Merged #218 Exit non-zero when the HTTP listener fails (closes #200) 2026-08-20 06:42:37 +02:00

Merged #216 Fail startup on half-set metrics credentials (closes #205) 2026-08-20 06:30:25 +02:00

Merged #214 Document backup, restore and upgrade procedures (closes #210) 2026-08-20 06:05:15 +02:00

Merged #213 Record the reopened 1.0.0 milestone in TODO.md 2026-08-20 05:58:03 +02:00

Merged #199 Record the 1.0.0 milestone as complete in TODO.md 2026-08-18 10:50:01 +02:00

Merged #195 Raise script/test's per-package timeout to 90s (closes #194) 2026-08-18 10:44:05 +02:00

Merged #197 Re-sync REPO_POLICIES.md from prompts (closes #196) 2026-08-18 09:33:29 +02:00

Merged #189 Report handler panics through the logger and answer 500 (closes #187) 2026-08-18 08:33:13 +02:00

Merged #182 Route GORM's logger through slog and bound it (closes #178) 2026-08-18 07:17:44 +02:00

Merged #180 Bound every slog line against client-chosen text (closes #176) 2026-08-18 06:03:11 +02:00

Merged #188 Stop a slow host turning a login-guard test into a segfault (closes #186) 2026-08-18 05:01:14 +02:00

Merged #192 Correct TODO.md milestone state and record seventeen landed units 2026-08-18 04:07:40 +02:00

Merged #181 Send the chi route pattern to Sentry, not the concrete path (closes #179) 2026-08-18 02:42:58 +02:00

Merged #174 Read form fields from the POST body only (closes #160) 2026-08-18 02:04:10 +02:00

Merged #171 Verify login credentials before spending rate-limit budget (closes #150) 2026-08-18 01:55:42 +02:00

Merged #165 Run all linting in Docker via Dockerfile.lint (closes #109) 2026-08-18 01:07:17 +02:00

Merged #167 Serve an event's full stored body over HTTP (closes #157) 2026-08-18 00:41:32 +02:00

Merged #155 Bound the access log line against client-chosen text (closes #146) 2026-08-18 00:32:29 +02:00

Merged #161 Mark superseded commits honestly instead of skipped (closes #152) 2026-08-18 00:31:55 +02:00

Merged #159 Set fx.StopTimeout inside the container stop grace (closes #134) 2026-08-18 00:12:52 +02:00

Merged #162 Bucket IPv6 rate-limit keys by /64 (closes #125) 2026-08-17 23:52:16 +02:00

Merged #156 Correct release-blocking README and startup-warning inaccuracies (closes #151) 2026-08-17 23:44:59 +02:00

Merged #164 Fetch Alpine.js at build time under a verified hash (closes #145) 2026-08-17 23:12:17 +02:00

Merged #158 Bound the event log's rendered bodies in the query (closes #135) 2026-08-17 22:57:09 +02:00

Merged #126 Mask the http target's destination URL in the UI (closes #115) 2026-08-17 22:50:27 +02:00

Merged #130 Bound shutdown hooks by their stop context (closes #102) 2026-08-14 06:18:34 +02:00

Merged #131 Render templates via a buffer, not the ResponseWriter (closes #123) 2026-08-14 06:18:22 +02:00

Merged #132 Align session codec max-age with the 7-day cap (closes #108) 2026-08-14 06:17:43 +02:00

Merged #153 Warn when production shares one rate-limit bucket (closes #149) 2026-08-12 13:49:39 +02:00

Merged #148 Record the last four milestone units in TODO.md 2026-08-12 13:21:39 +02:00

Merged #143 Bound the receiver rate limit per client IP across /webhook/* (closes #139) 2026-08-12 13:19:43 +02:00

Merged #144 Correct release-blocking documentation inaccuracies (closes #141) 2026-08-12 13:15:06 +02:00

Merged #138 Make the CI gate execute the checks it reports on (closes #119) 2026-08-12 13:00:52 +02:00

Merged #142 Require a positive RETENTION_SWEEP_INTERVAL (closes #140) 2026-08-12 12:46:40 +02:00

Merged #137 Update TODO.md for the completed 1.0.0 milestone 2026-08-12 12:20:34 +02:00

Merged #136 Scan the X-Forwarded-For chain without splitting it (closes #133) 2026-08-12 12:19:14 +02:00

Merged #129 Cap the X-Forwarded-For hop walk at 64 entries (closes #124) 2026-08-12 11:53:48 +02:00

Merged #122 Gate forwarded-header trust behind trusted-proxy config (closes #88) 2026-08-12 11:36:11 +02:00

Merged #116 Clarify web UI terminology, copy, and the entrypoint URL (closes #57) 2026-08-11 15:42:09 +02:00

Merged #121 Mask the target URL in delivery errors, SSRF logs and log page data (closes #118) 2026-08-11 15:11:58 +02:00

Merged #87 Rate-limit the public webhook receiver endpoint (closes #64) 2026-08-11 14:47:22 +02:00

Merged #91 Enforce the body size limit before CSRF parses the form (closes #90) 2026-08-11 14:37:39 +02:00

Merged #114 Mask target config on the source detail page (closes #113) 2026-08-11 14:37:10 +02:00

Merged #96 Allow retention_days of 0 to mean retain forever (closes #79) 2026-08-11 14:35:35 +02:00

Merged #105 Add inactivity-based session timeout (closes #66) 2026-08-10 16:12:40 +02:00

Merged #92 Fail loudly on set-but-unparseable env config values (closes #80) 2026-08-10 16:06:12 +02:00

Merged #104 Terminally fail retrying deliveries with a non-retry target type (closes #82) 2026-08-10 16:00:04 +02:00

Merged #95 Evict archive writers on deletion and sweep idle archives (closes #89) 2026-08-10 15:52:21 +02:00

Merged #100 Root background loops at context.Background() (closes #97) 2026-08-10 15:44:56 +02:00

Merged #83 Add admin password change flow (closes #65) 2026-08-07 23:23:05 +02:00

Merged #86 Update golangci-lint to v2.12.2 with canonical config 2026-08-07 23:18:49 +02:00

Merged #84 Implement the database archiving target (closes #43) 2026-08-07 22:50:08 +02:00

Merged #81 Refactor delivery targets to a Target interface (closes #77) 2026-08-07 17:07:49 +02:00

Merged #78 Add per-webhook event retention reaper (closes #63) 2026-08-07 16:15:14 +02:00

Merged #75 Add NoCache middleware for authenticated pages (closes #61) 2026-08-07 15:33:44 +02:00

Merged #73 Validate Slack target URLs at creation time (closes #68) 2026-08-07 14:03:56 +02:00

Merged #74 Keep the SSRF-safe transport in clientForConfig (closes #69) 2026-08-07 14:03:38 +02:00

Merged #71 Wrap /user/{username} in RequireAuth middleware (closes #60) 2026-08-07 14:00:17 +02:00

Merged #72 Raise HTTP WriteTimeout above the request middleware timeout (closes #62) 2026-08-07 13:58:29 +02:00

Merged #59 scripts-to-rule-them-all 2026-07-07 02:14:09 +02:00

Merged #58 Restore TODO.md and move TODO content out of README 2026-07-06 21:14:03 +02:00

94 Issues closed from 2 users

Closed #304 SQLite concurrency: cache=shared, no busy_timeout, no WAL, unbounded pool — concurrent writers get SQLITE_BUSY, deliveries stick pending 2026-08-30 06:11:52 +02:00

Closed #301 Document that the entrypoint UUID is the authentication and shared secrets are never used 2026-08-30 04:05:38 +02:00

Closed #147 CI gate follow-ups: script/cibuild has drifted from the model script, and the status-rewrite context string is hardcoded 2026-08-30 04:05:01 +02:00

Closed #298 The reaped-row fallback renders the exact zero timestamp that #257 was filed against 2026-08-24 17:52:26 +02:00

Closed #257 Every Slack message shows a zero timestamp of 0001-01-01T00:00:00Z 2026-08-24 06:44:24 +02:00

Closed #107 Two remaining delivery terminal-state gaps: opaque failure and deletion-orphaned retries 2026-08-24 05:12:03 +02:00

Closed #255 SQLite files are created 0644 with plaintext credentials, and the documented Docker deployment supplies the parent directory 0755 2026-08-24 04:33:41 +02:00

Closed #283 Two config paths fail silently: an unparseable SENTRY_DSN starts anyway, and a malformed .env is discarded whole 2026-08-24 04:25:30 +02:00

Closed #272 BaseURL on the source detail page uses the raw X-Forwarded-Proto value as the URL scheme 2026-08-24 04:04:05 +02:00

Closed #256 A concurrent reader wedges the per-webhook database, stranding delivered webhooks at pending and re-delivering them on restart 2026-08-24 03:49:18 +02:00

Closed #226 SIGTERM during startup panics on a nil httpServer, and cleanShutdown reads two fields with no happens-before edge 2026-08-24 03:39:13 +02:00

Closed #268 The plaintext app port binds all interfaces and the README has no reverse-proxy deployment section 2026-08-24 03:38:44 +02:00

Closed #241 README understates who can replay a signed request: forwarding X-Hub-Signature-256 hands every target a valid (body, signature) pair 2026-08-24 03:25:28 +02:00

Closed #279 Remove inbound request signature verification: the entrypoint UUID is the authentication secret 2026-08-24 03:25:10 +02:00

Closed #253 The shipped binary reports version "dev": no -X ldflags in the Makefile or Dockerfile 2026-08-24 03:15:21 +02:00

Closed #269 The session cookie silently loses Secure in the default environment, and X-Forwarded-Proto parsing is exact-match 2026-08-24 03:01:38 +02:00

Closed #262 Webhook deletion commits a partial delete and reports success when a delete statement fails 2026-08-24 03:01:34 +02:00

Closed #211 Deleting a target blanks its name on every historical delivery in the event log 2026-08-24 02:03:24 +02:00

Closed #261 The /metrics method label is still unbounded: 300 requests with random method tokens mint 7,525 permanent series 2026-08-24 02:03:19 +02:00

Closed #221 max_retries is unbounded at target creation, and unparseable input silently becomes 0 2026-08-24 01:32:48 +02:00

Closed #254 Enabling /metrics lets an unauthenticated client grow the process without bound, and publishes live entrypoint UUIDs 2026-08-24 01:32:45 +02:00

Closed #247 Invalid target header name error no longer indicates which line was rejected 2026-08-24 00:58:35 +02:00

Closed #250 Resubmit a stored event as a new undelivered event, so backends can be tested against real captured traffic 2026-08-24 00:53:38 +02:00

Closed #243 Forwarded inbound event headers are not stripped on a cross-origin redirect, unlike operator-configured ones 2026-08-20 10:55:03 +02:00

Closed #233 Operator-set target headers: credential headers survive a cross-host redirect, Trailer is not reserved, and an invalid header name error can quote a secret 2026-08-20 10:54:43 +02:00

Closed #204 The SSRF blocklist has no escape hatch, so a self-hosted proxy cannot forward to your own network 2026-08-20 10:34:42 +02:00

Closed #236 next ships a target edit form whose Tailwind classes are missing from the committed CSS 2026-08-20 08:36:37 +02:00

Closed #202 Delivery failures are invisible in the UI: nothing renders status_code, response_body, error or attempt_num 2026-08-20 08:36:26 +02:00

Closed #203 No replay: a delivery that exhausts max_retries is failed forever, and store-and-forward is the point 2026-08-20 08:11:36 +02:00

Closed #208 No admin password recovery path: lose the one-time bootstrap line and the deployment is unreachable 2026-08-20 08:01:42 +02:00

Closed #67 Optional inbound webhook HMAC signature verification 2026-08-20 08:01:33 +02:00

Closed #206 Target credentials leak into the per-webhook event databases via GORM association upsert 2026-08-20 07:55:35 +02:00

Closed #234 next is red: queue_depth.go calls (*gorm.DB).Scan, which interpolates bound values into logged SQL 2026-08-20 07:55:21 +02:00

Closed #235 next is red: queue_depth.go calls (*gorm.DB).Scan, tripping the scan guard 2026-08-20 07:41:25 +02:00

Closed #127 No target edit form: a target's destination URL, headers and timeout are write-once 2026-08-20 07:24:13 +02:00

Closed #201 No lock on DATA_DIR: two instances both run delivery recovery and both deliver 2026-08-20 07:23:01 +02:00

Closed #207 DEBUG=true prints the session encryption key and the admin password hash to the log 2026-08-20 07:21:00 +02:00

Closed #209 No delivery metrics: /metrics cannot tell you whether the product is doing its job 2026-08-20 07:19:05 +02:00

Closed #200 A failed listen leaves a live, non-serving process that fx still reports RUNNING 2026-08-20 06:42:37 +02:00

Closed #205 METRICS_USERNAME set with an empty METRICS_PASSWORD publishes /metrics unauthenticated 2026-08-20 06:30:25 +02:00

Closed #210 No backup, restore or upgrade guidance anywhere in the README 2026-08-20 06:05:16 +02:00

Closed #194 internal/handlers runs at 22s against script/test's 30s per-package timeout, and has already reded a build under load 2026-08-18 10:44:05 +02:00

Closed #196 REPO_POLICIES.md is a stale copy: it mandates a 30s test timeout the org policy replaced with 90s 2026-08-18 09:33:29 +02:00

Closed #187 chi's Recoverer panics instead of handling a handler panic, so a panicking request drops the connection instead of answering 500 2026-08-18 08:33:13 +02:00

Closed #178 GORM's default logger prints the full interpolated SQL, including the client-chosen path and username, on every record-not-found 2026-08-18 07:17:44 +02:00

Closed #176 MaxBodySize logs the full client-chosen path ahead of RequireAuth, sidestepping the access-log line budget 2026-08-18 06:03:11 +02:00

Closed #186 A timing-sensitive login-guard test panics on a nil release and reds the whole internal/middleware package 2026-08-18 05:01:14 +02:00

Closed #179 The receiver's capability URL is sent to Sentry in full 2026-08-18 02:42:59 +02:00

Closed #160 Target create reads the destination URL via r.FormValue, so a query-string credential lands in the access log and Sentry 2026-08-18 02:04:10 +02:00

Closed #150 Decision: should login rate limiting survive a shared bucket, or should TRUSTED_PROXIES be mandatory in production? 2026-08-18 01:55:42 +02:00

Closed #106 script/lint uses the host golangci-lint and a shared cache, so lint results can be wrong in either direction 2026-08-18 01:07:29 +02:00

Closed #109 Run all linting in Docker via Dockerfile.lint + script/lint 2026-08-18 01:07:17 +02:00

Closed #157 No in-app way to retrieve an event body larger than the event log's 8 KB render cap 2026-08-18 00:41:32 +02:00

Closed #146 The access log writes one INFO line with the full attacker-controlled URL per request, including rejected ones 2026-08-18 00:32:29 +02:00

Closed #152 Superseded-run status laundering: a never-tested commit reads green in the combined status 2026-08-18 00:31:55 +02:00

Closed #134 fx.StopTimeout is never set, so the bounded-shutdown fix does not fire under a default docker stop 2026-08-18 00:12:52 +02:00

Closed #125 Decision: should IPv6 rate-limit keys bucket by /64 rather than per-address? 2026-08-17 23:52:16 +02:00

Closed #151 Release-blocking accuracy: README describes a build and an endpoint that do not exist, and the lockout warning misses the default environment 2026-08-17 23:44:59 +02:00

Closed #145 A minified vendored bundle is committed to the repo, which REPO_POLICIES forbids 2026-08-17 23:12:18 +02:00

Closed #135 The event-log page renders stored bodies untruncated, so buffered rendering can hold ~25 MB per request 2026-08-17 22:57:09 +02:00

Closed #115 HTTP target destination URL is rendered in full and can itself be a bearer credential 2026-08-17 22:50:27 +02:00

Closed #102 Shutdown hooks ignore their context and wg.Wait() unbounded 2026-08-14 06:18:34 +02:00

Closed #123 renderTemplate streams to the ResponseWriter, so a mid-render template error ships a partial page 2026-08-14 06:18:23 +02:00

Closed #108 Session codec max-age still 30 days: bring securecookie codecs in line with the 7-day cap 2026-08-14 06:17:43 +02:00

Closed #149 Default config allows a remote stranger to lock the operator out of the admin UI, and nothing warns about it 2026-08-12 13:49:39 +02:00

Closed #139 The receiver rate limit is per-URL-path, so an attacker gets unlimited aggregate rate against /webhook/* 2026-08-12 13:19:43 +02:00

Closed #141 Release-readiness accuracy: docs contradict the code, TODO.md omits landed units, debug logging in the production asset 2026-08-12 13:15:06 +02:00

Closed #119 CI can report success without running lint or tests, because script/cibuild replays a cached image 2026-08-12 13:00:52 +02:00

Closed #140 RETENTION_SWEEP_INTERVAL is not range-checked, so a non-positive value panics two goroutines after startup reports success 2026-08-12 12:46:41 +02:00

Closed #133 The hop cap bounds the walk but not the Split: a 1 MB X-Forwarded-For still allocates ~8 MB per request 2026-08-12 12:19:14 +02:00

Closed #124 Cap the X-Forwarded-For hop walk: an unbounded chain burns CPU on every request 2026-08-12 11:53:49 +02:00

Closed #88 Gate forwarded-header trust behind trusted-proxy config in rate limiters 2026-08-12 11:36:11 +02:00

Closed #57 Clean up and clarify the web UI 2026-08-11 15:42:09 +02:00

Closed #118 Slack webhook credential still leaks via delivery errors, SSRF logs, and the source_logs template data 2026-08-11 15:11:58 +02:00

Closed #64 Rate-limit the public webhook receiver endpoint 2026-08-11 14:47:22 +02:00

Closed #90 Enforce request body size limit before CSRF middleware parses the form 2026-08-11 14:37:39 +02:00

Closed #113 Source detail page renders raw target config, exposing the Slack webhook URL credential 2026-08-11 14:37:10 +02:00

Closed #79 RetentionDays cannot be set to 0 (retain forever) via the normal create path 2026-08-11 14:35:35 +02:00

Closed #110 TOP PRIORITY: consolidate all open PRs onto one next branch, one PR 2026-08-11 13:56:44 +02:00

Closed #66 Add inactivity-based session timeout 2026-08-10 16:12:40 +02:00

Closed #80 Config parsing should fail loudly on set-but-unparseable env values (envInt, etc.) 2026-08-10 16:06:12 +02:00

Closed #82 Recovery skips orphaned retrying deliveries whose target type changed to a non-retry type 2026-08-10 16:00:04 +02:00

Closed #89 Archive writer lifecycle: evict writers on webhook deletion and sweep idle archives 2026-08-10 15:52:21 +02:00

Closed #97 CRITICAL: delivery engine and retention reaper both die ~15s after startup (fx OnStart context) 2026-08-10 15:44:56 +02:00

Closed #65 Add an admin password change flow in the web UI 2026-08-07 23:23:05 +02:00

Closed #43 configure db target type for archiving 2026-08-07 22:50:08 +02:00

Closed #77 Refactor delivery targets to a Target interface 2026-08-07 17:07:49 +02:00

Closed #63 Enforce per-webhook event retention (RetentionDays reaper) 2026-08-07 16:15:14 +02:00

Closed #61 Set Cache-Control: no-store on authenticated pages 2026-08-07 15:33:45 +02:00

Closed #70 Implement the log delivery target 2026-08-07 15:26:46 +02:00

Closed #68 Validate Slack target URLs at creation time (SSRF parity with HTTP targets) 2026-08-07 14:03:56 +02:00

Closed #69 Keep the SSRF-safe Transport in clientForConfig when a per-target timeout is set 2026-08-07 14:03:38 +02:00

Closed #60 Wrap the /user/{username} route in RequireAuth middleware 2026-08-07 14:00:17 +02:00

Closed #62 Reconcile HTTP WriteTimeout with the request middleware timeout 2026-08-07 13:58:29 +02:00

157 Issues created by 1 user

Opened #60 Wrap the /user/{username} route in RequireAuth middleware 2026-08-07 13:10:51 +02:00

Opened #61 Set Cache-Control: no-store on authenticated pages 2026-08-07 13:10:55 +02:00

Opened #62 Reconcile HTTP WriteTimeout with the request middleware timeout 2026-08-07 13:10:59 +02:00

Opened #63 Enforce per-webhook event retention (RetentionDays reaper) 2026-08-07 13:11:03 +02:00

Opened #64 Rate-limit the public webhook receiver endpoint 2026-08-07 13:11:08 +02:00

Opened #65 Add an admin password change flow in the web UI 2026-08-07 13:11:13 +02:00

Opened #66 Add inactivity-based session timeout 2026-08-07 13:11:16 +02:00

Opened #67 Optional inbound webhook HMAC signature verification 2026-08-07 13:11:19 +02:00

Opened #68 Validate Slack target URLs at creation time (SSRF parity with HTTP targets) 2026-08-07 13:16:06 +02:00

Opened #69 Keep the SSRF-safe Transport in clientForConfig when a per-target timeout is set 2026-08-07 13:16:10 +02:00

Opened #70 Implement the log delivery target 2026-08-07 13:16:13 +02:00

Opened #77 Refactor delivery targets to a Target interface 2026-08-07 15:05:53 +02:00

Opened #79 RetentionDays cannot be set to 0 (retain forever) via the normal create path 2026-08-07 15:26:51 +02:00

Opened #80 Config parsing should fail loudly on set-but-unparseable env values (envInt, etc.) 2026-08-07 15:29:22 +02:00

Opened #82 Recovery skips orphaned retrying deliveries whose target type changed to a non-retry type 2026-08-07 17:12:07 +02:00

Opened #85 Design: should delivery targets own their recovery/sweep loop, not just backoff? 2026-08-07 18:07:15 +02:00

Opened #88 Gate forwarded-header trust behind trusted-proxy config in rate limiters 2026-08-07 19:11:38 +02:00

Opened #89 Archive writer lifecycle: evict writers on webhook deletion and sweep idle archives 2026-08-07 19:11:43 +02:00

Opened #90 Enforce request body size limit before CSRF middleware parses the form 2026-08-07 19:12:08 +02:00

Opened #93 Follow-ups from the PR #91 review: body-limit docs and route-ordering test coverage 2026-08-09 04:03:32 +02:00

Opened #94 Follow-ups from the PR #92 review: config test hygiene and env docs 2026-08-09 04:08:12 +02:00

Opened #97 CRITICAL: delivery engine and retention reaper both die ~15s after startup (fx OnStart context) 2026-08-09 04:43:26 +02:00

Opened #98 Deprecated gomodguard linter in the org-standard .golangci.yml (needs an upstream decision) 2026-08-09 05:01:01 +02:00

Opened #99 Follow-ups from the PR #96 re-review: retention bound docs and untested normalisation 2026-08-09 05:11:44 +02:00

Opened #101 Archive sweep repeats open/prune/close once per database target instead of once per webhook 2026-08-09 07:26:46 +02:00

Opened #102 Shutdown hooks ignore their context and wg.Wait() unbounded 2026-08-09 07:27:39 +02:00

Opened #103 Pin the pre-reopen close in archiveWriter.sweepExpired (unprotected connection-leak guard) 2026-08-09 07:44:18 +02:00

Opened #106 script/lint uses the host golangci-lint and a shared cache, so lint results can be wrong in either direction 2026-08-09 08:09:02 +02:00

Opened #107 Two remaining delivery terminal-state gaps: opaque failure and deletion-orphaned retries 2026-08-09 08:13:05 +02:00

Opened #108 Session codec max-age still 30 days: bring securecookie codecs in line with the 7-day cap 2026-08-09 08:19:57 +02:00

Opened #109 Run all linting in Docker via Dockerfile.lint + script/lint 2026-08-10 13:14:12 +02:00

Opened #110 TOP PRIORITY: consolidate all open PRs onto one next branch, one PR 2026-08-10 14:30:12 +02:00

Opened #112 Decision: TODO.md Completed Steps guarantees a merge conflict on every unit landing on next 2026-08-10 15:46:14 +02:00

Opened #113 Source detail page renders raw target config, exposing the Slack webhook URL credential 2026-08-11 13:56:16 +02:00

Opened #115 HTTP target destination URL is rendered in full and can itself be a bearer credential 2026-08-11 14:28:51 +02:00

Opened #117 Page {{define "title"}} blocks never render; every browser tab reads "Webhooker" 2026-08-11 14:32:36 +02:00

Opened #118 Slack webhook credential still leaks via delivery errors, SSRF logs, and the source_logs template data 2026-08-11 14:37:28 +02:00

Opened #119 CI can report success without running lint or tests, because script/cibuild replays a cached image 2026-08-11 14:38:28 +02:00

Opened #120 No JS linting, so the styleguide REPO_POLICIES binds us to is unenforced 2026-08-11 14:45:30 +02:00

Opened #123 renderTemplate streams to the ResponseWriter, so a mid-render template error ships a partial page 2026-08-11 15:20:53 +02:00

Opened #124 Cap the X-Forwarded-For hop walk: an unbounded chain burns CPU on every request 2026-08-12 11:36:41 +02:00

Opened #125 Decision: should IPv6 rate-limit keys bucket by /64 rather than per-address? 2026-08-12 11:36:52 +02:00

Opened #127 No target edit form: a target's destination URL, headers and timeout are write-once 2026-08-12 11:42:26 +02:00

Opened #128 Form-error paths commit a 4xx before rendering, so a failed render there cannot report 500 2026-08-12 11:46:09 +02:00

Opened #133 The hop cap bounds the walk but not the Split: a 1 MB X-Forwarded-For still allocates ~8 MB per request 2026-08-12 11:54:06 +02:00

Opened #134 fx.StopTimeout is never set, so the bounded-shutdown fix does not fire under a default docker stop 2026-08-12 11:55:48 +02:00

Opened #135 The event-log page renders stored bodies untruncated, so buffered rendering can hold ~25 MB per request 2026-08-12 11:56:52 +02:00

Opened #139 The receiver rate limit is per-URL-path, so an attacker gets unlimited aggregate rate against /webhook/* 2026-08-12 12:29:51 +02:00

Opened #140 RETENTION_SWEEP_INTERVAL is not range-checked, so a non-positive value panics two goroutines after startup reports success 2026-08-12 12:30:00 +02:00

Opened #141 Release-readiness accuracy: docs contradict the code, TODO.md omits landed units, debug logging in the production asset 2026-08-12 12:30:13 +02:00

Opened #145 A minified vendored bundle is committed to the repo, which REPO_POLICIES forbids 2026-08-12 12:53:08 +02:00

Opened #146 The access log writes one INFO line with the full attacker-controlled URL per request, including rejected ones 2026-08-12 12:57:46 +02:00

Opened #147 CI gate follow-ups: script/cibuild has drifted from the model script, and the status-rewrite context string is hardcoded 2026-08-12 13:00:16 +02:00

Opened #149 Default config allows a remote stranger to lock the operator out of the admin UI, and nothing warns about it 2026-08-12 13:32:06 +02:00

Opened #150 Decision: should login rate limiting survive a shared bucket, or should TRUSTED_PROXIES be mandatory in production? 2026-08-12 13:32:25 +02:00

Opened #151 Release-blocking accuracy: README describes a build and an endpoint that do not exist, and the lockout warning misses the default environment 2026-08-12 13:32:46 +02:00

Opened #152 Superseded-run status laundering: a never-tested commit reads green in the combined status 2026-08-12 13:33:05 +02:00

Opened #154 middleware tests construct cookie stores by hand, so they no longer match the production store 2026-08-14 06:17:56 +02:00

Opened #157 No in-app way to retrieve an event body larger than the event log's 8 KB render cap 2026-08-17 22:45:06 +02:00

Opened #160 Target create reads the destination URL via r.FormValue, so a query-string credential lands in the access log and Sentry 2026-08-17 22:50:53 +02:00

Opened #163 Consider dropping Alpine.js and writing its 19 directive uses directly 2026-08-17 23:01:56 +02:00

Opened #166 static.go embeds the js directory, so a missing fetched asset silently produces a binary with no Alpine 2026-08-17 23:12:31 +02:00

Opened #168 Rate-limit key collapses every peer with an empty RemoteAddr into one bucket 2026-08-17 23:38:48 +02:00

Opened #169 Restrict /s/* to GET and HEAD — it currently answers POST, PUT and DELETE with 200 2026-08-17 23:45:16 +02:00

Opened #170 Clamp the HTTP drain by the tail-hook reserve, not just the Sentry flush 2026-08-18 00:13:14 +02:00

Opened #172 Assert the access-log encoded-byte charge against every Unicode code point 2026-08-18 00:32:55 +02:00

Opened #173 The receiver's 1 MB body cap lives in the handler, not the middleware the other route groups use 2026-08-18 00:41:49 +02:00

Opened #175 The CI workflow step is named "runs make check", which the image has never done 2026-08-18 01:07:52 +02:00

Opened #176 MaxBodySize logs the full client-chosen path ahead of RequireAuth, sidestepping the access-log line budget 2026-08-18 01:09:18 +02:00

Opened #177 Target.Webhook and Webhook.Targets form a reference cycle that will recurse once anything marshals a preloaded model 2026-08-18 01:10:13 +02:00

Opened #178 GORM's default logger prints the full interpolated SQL, including the client-chosen path and username, on every record-not-found 2026-08-18 01:40:55 +02:00

Opened #179 The receiver's capability URL is sent to Sentry in full 2026-08-18 01:41:07 +02:00

Opened #183 Two writers bypass internal/logger: fx's console logger and the Go runtime 2026-08-18 02:31:57 +02:00

Opened #184 Nothing bounds username length, and an account with a multi-KB username cannot log in at all 2026-08-18 02:33:32 +02:00

Opened #185 If tracing is ever enabled, every Sentry transaction will collapse into one bucket named POST /(redacted) 2026-08-18 02:34:32 +02:00

Opened #186 A timing-sensitive login-guard test panics on a nil release and reds the whole internal/middleware package 2026-08-18 03:14:50 +02:00

Opened #187 chi's Recoverer panics instead of handling a handler panic, so a panicking request drops the connection instead of answering 500 2026-08-18 03:15:07 +02:00

Opened #190 Last wall-clock-dependent test: two writes must land inside a real 2s debounce window or correct code reds 2026-08-18 03:59:56 +02:00

Opened #191 loggingResponseWriter has no Unwrap, so http.ResponseController cannot reach the real writer through the shipped chain 2026-08-18 04:02:58 +02:00

Opened #193 Headers set before an uncommitted panic survive onto the recovered 500, including Set-Cookie 2026-08-18 04:18:05 +02:00

Opened #194 internal/handlers runs at 22s against script/test's 30s per-package timeout, and has already reded a build under load 2026-08-18 06:48:33 +02:00

Opened #196 REPO_POLICIES.md is a stale copy: it mandates a 30s test timeout the org policy replaced with 90s 2026-08-18 09:31:04 +02:00

Opened #198 make test is past the org 20s target and arguably past the 60s hard cap, driven almost entirely by internal/handlers 2026-08-18 09:59:17 +02:00

Opened #200 A failed listen leaves a live, non-serving process that fx still reports RUNNING 2026-08-20 05:46:55 +02:00

Opened #201 No lock on DATA_DIR: two instances both run delivery recovery and both deliver 2026-08-20 05:47:02 +02:00

Opened #202 Delivery failures are invisible in the UI: nothing renders status_code, response_body, error or attempt_num 2026-08-20 05:47:14 +02:00

Opened #203 No replay: a delivery that exhausts max_retries is failed forever, and store-and-forward is the point 2026-08-20 05:47:22 +02:00

Opened #204 The SSRF blocklist has no escape hatch, so a self-hosted proxy cannot forward to your own network 2026-08-20 05:47:37 +02:00

Opened #205 METRICS_USERNAME set with an empty METRICS_PASSWORD publishes /metrics unauthenticated 2026-08-20 05:47:43 +02:00

Opened #206 Target credentials leak into the per-webhook event databases via GORM association upsert 2026-08-20 05:47:57 +02:00

Opened #207 DEBUG=true prints the session encryption key and the admin password hash to the log 2026-08-20 05:48:04 +02:00

Opened #208 No admin password recovery path: lose the one-time bootstrap line and the deployment is unreachable 2026-08-20 05:48:21 +02:00

Opened #209 No delivery metrics: /metrics cannot tell you whether the product is doing its job 2026-08-20 05:48:28 +02:00

Opened #210 No backup, restore or upgrade guidance anywhere in the README 2026-08-20 05:48:41 +02:00

Opened #211 Deleting a target blanks its name on every historical delivery in the event log 2026-08-20 05:48:49 +02:00

Opened #212 Encrypt credential-bearing target config at rest in webhooker.db 2026-08-20 05:52:42 +02:00

Opened #215 make fmt does not format Markdown, so the org prettier settings are unenforced here 2026-08-20 06:05:22 +02:00

Opened #221 max_retries is unbounded at target creation, and unparseable input silently becomes 0 2026-08-20 06:23:21 +02:00

Opened #225 internal/handlers tests are load-fragile: both the fx start budget and the 90s package timeout blow under host load, so the gate reports failures unrelated to the change 2026-08-20 06:38:14 +02:00

Opened #226 SIGTERM during startup panics on a nil httpServer, and cleanShutdown reads two fields with no happens-before edge 2026-08-20 06:42:47 +02:00

Opened #227 go test -count=2 ./internal/server/... panics on duplicate metrics collector registration 2026-08-20 06:44:18 +02:00

Opened #230 Data race in internal/handlers/logbound_test.go: fx testutil.WriteSyncer calls t.Logf from a start hook after the test goroutine has finished 2026-08-20 07:16:00 +02:00

Opened #231 tailwindcss is unpinned, so the committed static/css/tailwind.css is not reproducible from the repo's own tooling 2026-08-20 07:16:52 +02:00

Opened #232 Harden the (*gorm.DB).Scan guard test: three evasions, an overstated doc comment, and a weak file-count floor 2026-08-20 07:21:18 +02:00

Opened #233 Operator-set target headers: credential headers survive a cross-host redirect, Trailer is not reserved, and an invalid header name error can quote a secret 2026-08-20 07:24:32 +02:00

Opened #234 next is red: queue_depth.go calls (*gorm.DB).Scan, which interpolates bound values into logged SQL 2026-08-20 07:31:29 +02:00

Opened #235 next is red: queue_depth.go calls (*gorm.DB).Scan, tripping the scan guard 2026-08-20 07:39:19 +02:00

Opened #236 next ships a target edit form whose Tailwind classes are missing from the committed CSS 2026-08-20 07:40:29 +02:00

Opened #238 The event-DB sweep marker is monotonic and trusts itself, so a downgrade re-leaks target rows permanently 2026-08-20 07:49:37 +02:00

Opened #241 README understates who can replay a signed request: forwarding X-Hub-Signature-256 hands every target a valid (body, signature) pair 2026-08-20 07:56:32 +02:00

Opened #243 Forwarded inbound event headers are not stripped on a cross-origin redirect, unlike operator-configured ones 2026-08-20 08:34:50 +02:00

Opened #244 blockedNetworks does not cover in-cloud provider service networks on public unicast, e.g. IBM Cloud 161.26.0.0/16 and 166.8.0.0/14 2026-08-20 08:35:40 +02:00

Opened #245 Default-block the public-unicast cloud metadata endpoints (Azure WireServer, Equinix Metal) 2026-08-20 10:05:03 +02:00

Opened #246 A delivery can carry Content-Type twice when the inbound event also supplied one 2026-08-20 10:16:01 +02:00

Opened #247 Invalid target header name error no longer indicates which line was rejected 2026-08-20 10:29:52 +02:00

Opened #248 Migrate .golangci.yml from the deprecated gomodguard to gomodguard_v2 2026-08-20 11:07:12 +02:00

Opened #250 Resubmit a stored event as a new undelivered event, so backends can be tested against real captured traffic 2026-08-24 00:23:54 +02:00

Opened #252 Follow-ups from the PR 251 review: two comments state the wrong mechanism, and the resubmit route's middleware is untested 2026-08-24 00:53:49 +02:00

Opened #253 The shipped binary reports version "dev": no -X ldflags in the Makefile or Dockerfile 2026-08-24 00:56:09 +02:00

Opened #254 Enabling /metrics lets an unauthenticated client grow the process without bound, and publishes live entrypoint UUIDs 2026-08-24 00:56:31 +02:00

Opened #255 SQLite files are created 0644 with plaintext credentials, and the documented Docker deployment supplies the parent directory 0755 2026-08-24 00:56:47 +02:00

Opened #256 A concurrent reader wedges the per-webhook database, stranding delivered webhooks at pending and re-delivering them on restart 2026-08-24 00:58:15 +02:00

Opened #257 Every Slack message shows a zero timestamp of 0001-01-01T00:00:00Z 2026-08-24 00:58:32 +02:00

Opened #261 The /metrics method label is still unbounded: 300 requests with random method tokens mint 7,525 permanent series 2026-08-24 01:33:03 +02:00

Opened #262 Webhook deletion commits a partial delete and reports success when a delete statement fails 2026-08-24 01:39:43 +02:00

Opened #265 script/docker is no longer byte-identical to the model script, and CI-built images stamp version "unknown" 2026-08-24 01:48:03 +02:00

Opened #267 webhooker_delivery_duration_seconds is absent from a scrape until the first delivery occurs 2026-08-24 02:00:12 +02:00

Opened #268 The plaintext app port binds all interfaces and the README has no reverse-proxy deployment section 2026-08-24 02:11:12 +02:00

Opened #269 The session cookie silently loses Secure in the default environment, and X-Forwarded-Proto parsing is exact-match 2026-08-24 02:11:31 +02:00

Opened #270 The access log records the proxy's address, never the client's, so abuse cannot be traced from webhooker's own logs 2026-08-24 02:11:49 +02:00

Opened #271 HSTS is a hardcoded 2-year includeSubDomains preload commitment with no opt-out and no documentation of its value 2026-08-24 02:11:58 +02:00

Opened #272 BaseURL on the source detail page uses the raw X-Forwarded-Proto value as the URL scheme 2026-08-24 02:15:44 +02:00

Opened #274 Split internal/handlers/source_management.go along its three CRUD seams 2026-08-24 02:18:07 +02:00

Opened #275 DeleteDB returns on the first failing suffix, so it can report a leftover file when the history is already destroyed 2026-08-24 02:28:48 +02:00

Opened #278 Changing the password neither regenerates the current session nor invalidates any other one 2026-08-24 02:48:41 +02:00

Opened #279 Remove inbound request signature verification: the entrypoint UUID is the authentication secret 2026-08-24 02:58:36 +02:00

Opened #280 Archive writers are never closed at shutdown, so their -wal survives a clean stop 2026-08-24 03:05:51 +02:00

Opened #282 make check fails on a fresh clone because script/check does not fetch the vendored assets 2026-08-24 03:15:04 +02:00

Opened #283 Two config paths fail silently: an unparseable SENTRY_DSN starts anyway, and a malformed .env is discarded whole 2026-08-24 03:17:05 +02:00

Opened #285 The withRetry bookkeeping-failure branch is unpinned: removing its error check leaves the suite green 2026-08-24 03:49:30 +02:00

Opened #288 Two constants define the data directory mode, in two packages that both create it 2026-08-24 04:14:25 +02:00

Opened #290 File-sourced configuration paths have never been audited for silent defaults 2026-08-24 04:25:42 +02:00

Opened #291 GetDB can open the same event database twice, and closing the loser drops the winner's file locks 2026-08-24 04:29:13 +02:00

Opened #293 A pending delivery whose target was deleted is stranded forever 2026-08-24 04:33:12 +02:00

Opened #294 TestProcessRetryTask_LargeBody_FetchFromDB stays green when the fetch it exists to exercise is deleted 2026-08-24 05:13:05 +02:00

Opened #295 Observation, not a defect: one unreproducible SQLITE_IOERR_SHORT_READ storm under load on ZFS-backed storage 2026-08-24 06:17:39 +02:00

Opened #298 The reaped-row fallback renders the exact zero timestamp that #257 was filed against 2026-08-24 06:44:38 +02:00

Opened #299 Startup recovery races the receiver and can deliver a fresh event twice 2026-08-24 06:44:52 +02:00

Opened #301 Document that the entrypoint UUID is the authentication and shared secrets are never used 2026-08-25 22:34:36 +02:00

Opened #303 Independent code audit 2026-08-30 03:48:37 +02:00

Opened #304 SQLite concurrency: cache=shared, no busy_timeout, no WAL, unbounded pool — concurrent writers get SQLITE_BUSY, deliveries stick pending 2026-08-30 03:57:12 +02:00

Opened #305 Notify drops tasks on full channel; pending deliveries only recover on process restart 2026-08-30 03:57:14 +02:00

Opened #306 Circuit breaker half-open state busy-loops queued tasks with a DB write per spin 2026-08-30 03:57:20 +02:00

Opened #307 WEBHOOKER_ENVIRONMENT defaults to dev, silently shipping insecure prod (no Secure cookies, CORS *) 2026-08-30 03:57:23 +02:00

Opened #308 Listener bind failure leaves the process running with no listener instead of exiting non-zero 2026-08-30 03:57:27 +02:00

Opened #309 SSRF blocking has no opt-out: cannot deliver to RFC1918/LAN targets — needs ALLOWED_TARGET_CIDRS 2026-08-30 03:57:30 +02:00

Opened #310 Replay/redelivery does not exist and the UI shows no per-attempt results, despite README promises 2026-08-30 03:57:36 +02:00

2 Unresolved Conversations

Open #33 1.0/mvp 2026-08-24 00:59:13 +02:00

Open #56 Move schema_migrations table creation into 000.sql with INTEGER version column 2026-08-07 18:07:44 +02:00