Correct four documentation claims ahead of the 1.0.0 tag
All checks were successful
check / check (push) Successful in 7s
All checks were successful
check / check (push) Successful in 7s
Final pre-tag verification found four places where the docs did not
match the shipped artifact.
`TODO.md` `# Status` said the tag was held on a durability defect that
has since landed. Rewritten to record that it landed, without naming a
remaining blocker whose issue number would falsify the file the moment
it closes. `# Next Step` opened with "Land <that issue>" and is
corrected the same way.
The README Package Layout tree omitted `internal/reqtls`,
`internal/ciscript` and `internal/versionscript`, all three of which
exist; `reqtls` is named repeatedly in the surrounding prose as the
TLS predicate.
The README Authenticated Endpoints table omitted three live routes,
verified against `internal/server/routes.go`: `GET` and `POST` on
`/source/{id}/targets/{targetID}/edit`, and `GET
/source/{id}/logs/{eventID}/body`.
The Rationale section sold "Guaranteed delivery" without saying which
guarantee. The engine deliberately implements at-least-once: a send
whose bookkeeping write fails is left recoverable and sent again by
the pending sweep or the next restart. Stated plainly, with the
consequence for receivers.
Documentation only; no behaviour change.
This commit is contained in:
25
README.md
25
README.md
@@ -1234,6 +1234,16 @@ webhooker solves this by acting as a durable intermediary:
|
||||
backoff. Every delivery attempt is logged with status codes, response
|
||||
bodies, and timing.
|
||||
|
||||
**That guarantee is at-least-once, not exactly-once.** When a send
|
||||
reaches its target but the write recording that outcome fails, the
|
||||
delivery is deliberately left in a recoverable state rather than
|
||||
marked done — losing a delivery is the worse failure — so the
|
||||
pending sweep picks it up about fifteen minutes later, or the next
|
||||
restart does, and the target receives a payload it already got.
|
||||
webhooker adds no delivery identifier of its own to an outbound
|
||||
request, so **make your receiver idempotent** against whatever the
|
||||
payload itself carries.
|
||||
|
||||
3. **Observability** — Full request/response logging for every webhook
|
||||
received and every delivery attempted. Prometheus metrics expose
|
||||
volume, latency, and error rates. The web UI provides real-time
|
||||
@@ -2616,12 +2626,15 @@ abuse limit later; they are tracked as future work.
|
||||
| `POST` | `/source/{id}/edit` | Edit webhook submission |
|
||||
| `POST` | `/source/{id}/delete` | Delete webhook |
|
||||
| `GET` | `/source/{id}/logs` | Webhook event logs |
|
||||
| `GET` | `/source/{id}/logs/{eventID}/body` | Download an event's full stored body. The log page renders each body only up to its cap, so this is the only route that serves a whole one; it is offered wherever a body is shown truncated |
|
||||
| `POST` | `/source/{id}/deliveries/{deliveryID}/replay` | Replay a finished delivery: creates a new delivery for the same event against the target's current configuration (30 per minute per bucket, then `429`) |
|
||||
| `POST` | `/source/{id}/events/{eventID}/resubmit` | Resubmit a stored event: creates a new event copying it and fans that out to every currently active target (30 per minute per bucket, then `429`) |
|
||||
| `POST` | `/source/{id}/entrypoints` | Add entrypoint to webhook |
|
||||
| `POST` | `/source/{id}/entrypoints/{entrypointID}/delete` | Delete an entrypoint |
|
||||
| `POST` | `/source/{id}/entrypoints/{entrypointID}/toggle` | Enable or disable an entrypoint |
|
||||
| `POST` | `/source/{id}/targets` | Add target to webhook |
|
||||
| `GET` | `/source/{id}/targets/{targetID}/edit` | Edit target form. The one page that renders a target's destination URL and header values in full, rather than masked |
|
||||
| `POST` | `/source/{id}/targets/{targetID}/edit` | Edit target submission |
|
||||
| `POST` | `/source/{id}/targets/{targetID}/delete` | Delete a target |
|
||||
| `POST` | `/source/{id}/targets/{targetID}/toggle` | Enable or disable a target |
|
||||
|
||||
@@ -2660,6 +2673,8 @@ webhooker/
|
||||
├── internal/
|
||||
│ ├── banner/
|
||||
│ │ └── banner.go # Ruled block for the one credential shown in the clear
|
||||
│ ├── ciscript/
|
||||
│ │ └── doc.go # Tests for the CI shell scripts in script/; no runtime code
|
||||
│ ├── resetpw/
|
||||
│ │ └── resetpw.go # `webhooker resetpw`: set an account's password, stopped deployments only
|
||||
│ ├── config/
|
||||
@@ -2729,13 +2744,17 @@ webhooker/
|
||||
│ │ ├── ratelimit.go # Per-IP rate limiting middleware (go-chi/httprate)
|
||||
│ │ ├── loginguard.go # Login failure counters and the Argon2id verification semaphore
|
||||
│ │ └── testing.go # NewForTest: Middleware without the fx lifecycle
|
||||
│ ├── reqtls/
|
||||
│ │ └── reqtls.go # IsTLS: the one TLS predicate, r.TLS or X-Forwarded-Proto
|
||||
│ ├── server/
|
||||
│ │ ├── server.go # Server struct, fx lifecycle, signal handling
|
||||
│ │ ├── http.go # HTTP server setup with timeouts
|
||||
│ │ └── routes.go # All route definitions
|
||||
│ └── session/
|
||||
│ ├── session.go # Cookie-based session management
|
||||
│ └── testing.go # NewForTest: Session without the fx lifecycle
|
||||
│ ├── session/
|
||||
│ │ ├── session.go # Cookie-based session management
|
||||
│ │ └── testing.go # NewForTest: Session without the fx lifecycle
|
||||
│ └── versionscript/
|
||||
│ └── doc.go # Tests for script/version and the build files that use it
|
||||
├── static/
|
||||
│ ├── static.go # //go:embed directive
|
||||
│ ├── css/input.css # Tailwind input, source for tailwind.css (make css)
|
||||
|
||||
Reference in New Issue
Block a user