Update TODO.md for the completed 1.0.0 milestone
All checks were successful
check / check (push) Successful in 8s

Records the trusted-proxy gating (#88), the hop cap (#124) and the
bounded scan (#133), and corrects the Workflow section, which still
described branching from main and committing TODO.md alongside the
work — both contradicted by the branch-per-issue-onto-next model and
by the decision on #112 that issue branches leave this file alone.
This commit is contained in:
2026-08-12 10:20:20 +00:00
parent 9bfd033a29
commit 67ce7978c4

59
TODO.md
View File

@@ -1,31 +1,62 @@
# Workflow # Workflow
* branch (from `main`) One issue per unit of work, one branch and one PR per issue:
* do the work in Next Step
* move Next Step to the top of Completed Steps * ensure a tracked issue exists with a definition of done
* move the top item of Future Steps into Next Step * branch from `next` (never from `main`)
* commit (`TODO.md` changes in the same commit as the work) * do the work; open a PR based on `next` (never on `main`)
* merge to `main` if the branch is not protected, otherwise open a PR * pass an independent review, then the manager squash-merges into `next`
* push * push; nothing stays local-only
`next` is the branch for the next milestone and must stay green and
mergeable to `main` without notice. One `next` -> `main` PR accumulates
the milestone; releases are cut from `main` separately.
Issue branches do NOT touch this file — the manager maintains it on
`next`. Every branch editing `TODO.md` conflicts with every other
(#112).
# Status # Status
pre-1.0. No git tags exist. main (4f5ecb1) is a working webhook proxy pre-1.0. No git tags exist. `main` (4f5ecb1) is a working webhook proxy
with auth, CSRF/SSRF protections, login rate limiting, Slack target, with auth, CSRF/SSRF protections, login rate limiting, Slack target,
event retention (#63), the database archiving target (#43), the admin event retention (#63), the database archiving target (#43), the admin
password change flow (#65), policy compliance (#6), pinned lint tooling password change flow (#65), policy compliance (#6), pinned lint tooling
(#55), and fail-loud configuration parsing (#80). Note: TODO.md was (#55), and fail-loud configuration parsing (#80).
deliberately deleted from this repo in f9a9569 (2026-03-01, #6); its
content was folded into the README TODO section, which this draft `next` (9bfd033) holds the completed 1.0.0 milestone: every issue in it
reconstructs as of 2026-07-06. is closed, and it is verified green by cache-defeated container runs
rather than by the CI badge, which can pass without executing anything
(#119). Note: TODO.md was deliberately deleted from this repo in f9a9569
(2026-03-01, #6); its content was folded into the README TODO section,
which this draft reconstructs as of 2026-07-06.
# Next Step # Next Step
Manual event redelivery from the web UI (replay is a core promised Tag 1.0.0 from `main` once the milestone PR merges, then repair the CI
capability in the README rationale). gate (#119) before the next cycle's work lands — a gate that can report
success without running is the one thing every other guarantee here
rests on.
# Completed Steps # Completed Steps
- 2026-08-12 Bound the `X-Forwarded-For` scan's allocation to the hop
cap: the reverse walk cuts entries with `strings.LastIndexByte`
instead of joining and splitting, so a 1 MB header allocates 16 bytes
rather than 1.6 MB per request on the unauthenticated receiver.
Semantics proven unchanged by differential testing against the
previous implementation (#133)
- 2026-08-12 Cap the `X-Forwarded-For` hop walk at 64 entries, so an
attacker-supplied chain cannot burn unbounded CPU in the rate-limit
key function; running off the end falls back to the peer address
(#124)
- 2026-08-12 Gate forwarded-header trust behind a `TRUSTED_PROXIES` CIDR
list: all three rate limiters key on the connection's own address
unless the direct peer is a configured proxy, in which case
`X-Forwarded-For` is walked right to left for the first non-proxy hop.
Default trusts nothing, and a set-but-unparseable value aborts
startup. Before this, any client could mint a fresh bucket or drain
another's by rotating a spoofed header (#88)
- 2026-08-11 Web UI cleanup: nav terminology unified on Webhooks, the - 2026-08-11 Web UI cleanup: nav terminology unified on Webhooks, the
Profile settings placeholder removed, a progressive-enhancement copy Profile settings placeholder removed, a progressive-enhancement copy
button for the entrypoint URL, and retention form copy that states the button for the entrypoint URL, and retention form copy that states the