diff --git a/TODO.md b/TODO.md index 3d60b15..785f13b 100644 --- a/TODO.md +++ b/TODO.md @@ -24,10 +24,23 @@ event retention (#63), the database archiving target (#43), the admin password change flow (#65), policy compliance (#6), pinned lint tooling (#55), and fail-loud configuration parsing (#80). -`next` holds the **complete 1.0.0 milestone**: every issue in it is -closed, and it is verified green both by CI and by cache-defeated -container runs (`docker build --no-cache-filter=lint ---no-cache-filter=builder`). +`next` is green — verified both by CI and by cache-defeated container +runs (`docker build --no-cache-filter=lint --no-cache-filter=builder`) — +but the **1.0.0 milestone is no longer complete**. It was reopened on +2026-08-20 by a code-level deployability audit that ran the service end +to end (verdict: +https://git.eeqj.de/sneak/webhooker/issues/33#issuecomment-66686). + +The bar for 1.0 is not "the milestone is empty" but "sneak can deploy +this and use it in low-volume production". The audit found the gap +between those two: two instances on one `DATA_DIR` both deliver +(reproduced), a failed listen leaves a live non-serving process that +restart policies never fire on, there is no inbound authentication of +any kind, delivery failures render as a bare word with no status code or +error, a terminally failed delivery can never be replayed, the SSRF +blocklist has no escape hatch so the proxy cannot forward to your own +network at all, and target credentials leak into the per-webhook event +databases. One caveat on reading a green check, narrower than it used to be. A docs-only commit deliberately replays from the layer cache (#119), so a @@ -44,8 +57,13 @@ of 2026-07-06. # Next Step -Merge the milestone PR (#111) to `main` and tag 1.0.0 from it. The -milestone is empty and `next` is green; nothing else blocks the tag. +Clear the reopened 1.0.0 milestone. The milestone PR +(https://git.eeqj.de/sneak/webhooker/pulls/111) is held: it carries a +`WIP: ` prefix, no labels and is assigned to `clawbot`, and it stays +that way until the milestone is empty. Correctness first — the +duplicate-delivery lock and the listen-failure shutdown — then the +operability gaps that make the service usable in production, then the +three credential exposures. Three items belong to the owner, none of them blocking. #150 was decided by the manager rather than left to stall the queue and is flagged on the @@ -59,8 +77,9 @@ bug the 20-60s band requires, and should be milestoned instead if the cap is read as covering the whole invocation. After the tag, the largest open cluster is the unmilestoned follow-up -backlog these units generated: #183, #184, #185, #190, #191, #193 and -#198. +backlog these units generated: #183, #184, #185, #190, #191, #193, #198, +#211 and #212 (encrypting target config at rest, split out of the +credential-leak fix because it needs a key-rotation and re-wrap story). # Completed Steps