Merge pull request 'Correct TODO.md milestone state and record seventeen landed units' (#192) from todo-md-milestone-state into next
All checks were successful
check / check (push) Successful in 6s
All checks were successful
check / check (push) Successful in 6s
This commit was merged in pull request #192.
This commit is contained in:
78
TODO.md
78
TODO.md
@@ -24,8 +24,9 @@ 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).
|
(#55), and fail-loud configuration parsing (#80).
|
||||||
|
|
||||||
`next` holds the completed 1.0.0 milestone: every issue in it is closed,
|
`next` holds the 1.0.0 milestone less its final four issues (#176, #178,
|
||||||
and it is verified green by cache-defeated container runs
|
#186, #187 — all in review or held on merge order), and is verified
|
||||||
|
green by cache-defeated container runs
|
||||||
(`docker build --no-cache-filter=lint --no-cache-filter=builder`). The
|
(`docker build --no-cache-filter=lint --no-cache-filter=builder`). The
|
||||||
CI status is not independently claimed here: a superseded run is
|
CI status is not independently claimed here: a superseded run is
|
||||||
recorded as `skipped` and still rolls up green, so a commit status on
|
recorded as `skipped` and still rolls up green, so a commit status on
|
||||||
@@ -39,15 +40,78 @@ of 2026-07-06.
|
|||||||
|
|
||||||
# Next Step
|
# Next Step
|
||||||
|
|
||||||
Merge the milestone PR to `main` and tag 1.0.0 from it.
|
Land the last four 1.0.0 issues, then merge the milestone PR to `main`
|
||||||
|
and tag 1.0.0 from it. Merge order is forced by a real conflict on
|
||||||
|
`README.md` and `internal/middleware/middleware.go`: #186, then #176,
|
||||||
|
then #178, then #187.
|
||||||
|
|
||||||
Two decisions are open and belong to the owner, neither blocking the
|
Two items belong to the owner, neither blocking the tag. #150 was
|
||||||
tag: #115 (mask the `http` target's destination URL, implemented
|
decided by the manager rather than left to stall the queue and is
|
||||||
speculatively and awaiting a yes or no) and #125 (whether IPv6
|
flagged on the issue for reversal if that call was wrong. #112 (whether
|
||||||
rate-limit keys should bucket by `/64`).
|
`Completed Steps` should exist at all, given it once conflicted on every
|
||||||
|
unit) is unanswered; the provisional ruling in force is that issue
|
||||||
|
branches do not touch this file.
|
||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
|
- 2026-08-18 Send the chi route pattern to Sentry rather than the
|
||||||
|
concrete path. The receiver's path carries the entrypoint capability
|
||||||
|
token, so every Sentry event from `/webhook/{uuid}` shipped a live
|
||||||
|
credential to a third party. Request `Data`, `QueryString`, `Cookies`
|
||||||
|
and `Env` are dropped and headers reduced to an allowlist (#179)
|
||||||
|
- 2026-08-18 Read form fields from the POST body only. `r.FormValue`
|
||||||
|
merges the query string, so a login could be driven by URL parameters
|
||||||
|
— putting the password somewhere that lands in access logs, proxy
|
||||||
|
logs and browser history (#160)
|
||||||
|
- 2026-08-18 Verify login credentials before spending rate-limit
|
||||||
|
budget, so a flood of wrong passwords cannot lock out the account it
|
||||||
|
is guessing at. The manager took this decision rather than stall the
|
||||||
|
queue; it is flagged on the issue for reversal (#150)
|
||||||
|
- 2026-08-18 Run all linting in Docker via `Dockerfile.lint`. Host lint
|
||||||
|
was wrong in both directions from version skew and shared caches.
|
||||||
|
`script/lint` asserts the summary line, because `--no-cache-filter`
|
||||||
|
silently ignores a stage name it does not match — the flag that makes
|
||||||
|
the gate meaningful fails open (#109)
|
||||||
|
- 2026-08-18 Serve an event's full stored body over HTTP. The list
|
||||||
|
query truncates for rendering, and that truncated value was the only
|
||||||
|
way to read a body, so the full payload was unreachable (#157)
|
||||||
|
- 2026-08-18 Bound the access log line against client-chosen text.
|
||||||
|
`internal/logfield` budgets by *encoded* bytes, not runes, so a
|
||||||
|
handler's JSON escaping cannot multiply a field past its allowance
|
||||||
|
(#146)
|
||||||
|
- 2026-08-18 Mark superseded CI commits `failure` rather than
|
||||||
|
`skipped`. A skipped run rolls up green, so a commit that was never
|
||||||
|
tested reported success (#152)
|
||||||
|
- 2026-08-18 Set `fx.StopTimeout` inside the container stop grace, so
|
||||||
|
shutdown hooks are bounded by a deadline the orchestrator will
|
||||||
|
actually honour rather than being killed mid-flush (#134)
|
||||||
|
- 2026-08-17 Bucket IPv6 rate-limit keys by `/64`. A single allocation
|
||||||
|
hands out 2^64 addresses, so per-address keying let one client mint
|
||||||
|
unlimited buckets. Manager decision, recorded on the issue (#125)
|
||||||
|
- 2026-08-17 Correct release-blocking README and startup-warning
|
||||||
|
inaccuracies, including claims about behaviour the code does not have
|
||||||
|
(#151)
|
||||||
|
- 2026-08-17 Fetch and verify Alpine.js at build time against
|
||||||
|
`static/vendor.sha256` instead of committing the minified blob, so
|
||||||
|
the dependency is pinned by hash rather than by trust (#145)
|
||||||
|
- 2026-08-17 Bound the event log's rendered bodies in the query itself,
|
||||||
|
so a large stored payload cannot be read into memory just to be
|
||||||
|
truncated for display (#135)
|
||||||
|
- 2026-08-17 Mask the `http` target's destination URL in the UI: it can
|
||||||
|
carry a bearer credential in its path or query, and was rendered
|
||||||
|
verbatim. Manager decision to mask unconditionally (#115)
|
||||||
|
- 2026-08-14 Bound shutdown hooks by their stop context, so a hook that
|
||||||
|
hangs cannot hold the process past its grace period (#102)
|
||||||
|
- 2026-08-14 Render templates via a buffer rather than the
|
||||||
|
`ResponseWriter`, so a template error part-way through cannot commit
|
||||||
|
a 200 and then fail — the response is written only once it is whole
|
||||||
|
(#123)
|
||||||
|
- 2026-08-14 Align the session codec's max-age with the 7-day absolute
|
||||||
|
cap. The codec accepted cookies the session layer considered expired,
|
||||||
|
so the cap was enforced in one place and not the other (#108)
|
||||||
|
- 2026-08-12 Warn when `TRUSTED_PROXIES` is empty in production, where
|
||||||
|
the safe default silently discards forwarded headers and every client
|
||||||
|
rate-limits as the proxy's address (#149)
|
||||||
- 2026-08-12 Bound the receiver rate limit per client IP across the
|
- 2026-08-12 Bound the receiver rate limit per client IP across the
|
||||||
whole `/webhook/*` route. The existing limiter keyed on the request
|
whole `/webhook/*` route. The existing limiter keyed on the request
|
||||||
path and `/webhook/{uuid}` matches any single segment, so a client
|
path and `/webhook/{uuid}` matches any single segment, so a client
|
||||||
|
|||||||
Reference in New Issue
Block a user