question: is rproxy ready to be put live on the internet? #381

Closed
opened 2026-11-13 19:53:54 +01:00 by clawbot · 6 comments
Collaborator

sneak asked on #223 (comment):

> is rproxy ready to be put live on the internet?

Task

Answer that question with a yes or no and the reasons, as one comment here. Assess rproxy and what it needs from waf and servewaf at the head of next, as an internet-facing reverse proxy: TLS and certificates, request limits and timeouts, behaviour when waf or the backend is down, trusted-proxy handling (the RFC 1918 default), logging of client addresses, the open bugs on this tracker, and how it is configured and run under upaas. No code change and no PR.

Definition of done

One comment here that starts with yes or no, lists every blocker found (what, where, what acceptable looks like) and, for each, whether an issue already covers it. Each blocker without an issue gets one, filed by this session, linked from the comment.

Model: opus-5-5

sneak asked on https://git.eeqj.de/sneak/smallwebwaf/pulls/223#issuecomment-180671: > is rproxy ready to be put live on the internet? ## Task Answer that question with a yes or no and the reasons, as one comment here. Assess `rproxy` and what it needs from `waf` and `servewaf` at the head of `next`, as an internet-facing reverse proxy: TLS and certificates, request limits and timeouts, behaviour when `waf` or the backend is down, trusted-proxy handling (the RFC 1918 default), logging of client addresses, the open bugs on this tracker, and how it is configured and run under upaas. No code change and no PR. ## Definition of done One comment here that starts with yes or no, lists every blocker found (what, where, what acceptable looks like) and, for each, whether an issue already covers it. Each blocker without an issue gets one, filed by this session, linked from the comment. Model: opus-5-5
Author
Collaborator

Yes, once an image is built from this code. rproxy at the head of next (50c50bf) has no blocker in its code or its documents. The one blocker is outside the code: the registry's only image is from 6 November and predates the settings renames, so an app built FROM it and configured from next's documents gets a rproxy that stops at start.

Blocker

  • The published image is stale. git.eeqj.de/sneak/smallwebwaf:latest was pushed on 6 November from c402926. That binary wants SWRP_WAF_BACKEND, which next renamed to SWW_RPROXY_WAF_BACKEND on 12 November; it also lacks the WebDAV methods and the removal of an untrusted peer's forwarded headers. Acceptable: make publish from a clean checkout at the head of next, or of main once #223 is merged, and the app Dockerfiles naming that digest. It builds on your Docker host. No issue covered it; filed as #383. The package pulls anonymously, so an upaas build can use it.

Why yes

  • TLS and certificates: not rproxy's job, by design. traefik terminates TLS and reaches rproxy over plain HTTP on the private network; traefik's X-Forwarded-Proto goes to the app and into waf's log. SWW_RPROXY_WAF_BACKEND and SWW_RPROXY_UPSTREAM_URL take https too, and the certificate is verified.
  • Limits and timeouts: every request has a size limit each way (100M in, 1G out), 60 s to arrive, 30 min to be answered, 32 KiB of headers and 120 s idle. Each limit has a defined answer (413, 408, 431, 502, 504) and nothing streams unbounded. For Gitea or Nextcloud, raise SWW_RPROXY_MAX_REQUEST_SIZE and SWW_RPROXY_MAX_REQUEST_TIME_MS: a push over 100 MiB, or one that takes over a minute to send, is refused at the defaults.
  • waf or the app down: with waf unreachable, rproxy passes the request to the app (SWW_RPROXY_WAF_BACKEND_NO_ANSWER_DISPOSITION=allow). A refused connection costs nothing; a hung waf costs each request the full 2 s of SWW_RPROXY_WAF_BACKEND_TIMEOUT_MS. The container's health check does not ask waf, so traefik keeps routing, and waf can be redeployed under traffic. With the app down, the visitor gets 502.
  • Trusted proxies: the default is the RFC 1918 set. From a peer outside it, every X-Forwarded-* header (underscore spellings included), Forwarded and X-Real-IP are removed and replaced with the peer's own facts. From a peer inside it, they pass with the peer appended to X-Forwarded-For, and the visitor is read from the right of that header, so a visitor cannot name another address. The end-to-end trial on #321 (next at f7e3190, 11 November) found nothing blocking; the five issues it filed are closed.
  • Client addresses in the log: rproxy writes one line per request with client_ip, host, method, path, query, status, bytes and durations; waf's lines add peer_ip and forwarded_for. Authorization and Cookie are never logged.
  • Open issues: none is a bug in rproxy. Related: #380 (waf refuses 8 KiB lines first, as decided on issue 339) is in review and closes the cheapest way to overload waf; #216 is cosmetic and its PR is merge-ready; #379 asks for ASN and country headers to the app, which SWW_WAF_ADD_LOOKUP_HEADERS=true already gives.
  • Under upaas: the app's Dockerfile builds FROM the image by digest and adds its own run script; SWW_RPROXY_WAF_BACKEND and the traefik labels go in the app's upaas settings; upaas honours the image's health check. waf is its own container: a one-line FROM Dockerfile as an upaas app, with SWW_COMMAND=waf and a host directory mounted at /var/lib/sww, does it. Set the app's docker_network in upaas to the network traefik and waf are on. Left empty, the container lands on Docker's default bridge, where waf cannot be reached by name, and rproxy passes everything to the app with only a process warning and waf_backend_no_answer on each log line to show for it. The README's "Checking that it works" catches this on the first deploy.

Limitations to deploy with (design, not defects)

  • Failing open means whoever keeps waf busy past 2 s switches the protection off for that long, rate limits and bans included. deny trades that for 503 while waf is slow.
  • Any container on the private network can ask waf a question, and so ban any address: a question needs no token. The network holds only what you trust.
  • An app that accepts a request and never answers holds the visitor for the whole response limit, 30 min by default, before 504. There is no separate first-byte limit.
  • If the Docker network has IPv6, or anything but traefik is in front, traefik's peer address is outside the RFC 1918 set. Every visitor is then seen as that one address, and the first broken rate limit bans the whole site. Name those ranges in SWW_RPROXY_TRUSTED_PROXIES.
  • A restart of rproxy refuses new connections for a few seconds and cuts requests in progress after 5 s, WebSockets included.

Disclosures

  • Read-only: the code and documents at 50c50bf, the tracker, the registry and upaas's code. Nothing was built or run. The last run was issue 321's trial; rproxy has fourteen commits since, five of them behaviour fixes, read but not exercised.
  • Not checked: your traefik configuration and the Docker networks on your hosts.
  • Judgement call: the stale image is the one blocker and is filed; the limitations above are design and are not.
  • Confidence: high on the code reading and the registry's state; medium on the upaas default-bridge behaviour, read from upaas's code and not run.

Model: fable-5-1

**Yes, once an image is built from this code.** `rproxy` at the head of `next` (`50c50bf`) has no blocker in its code or its documents. The one blocker is outside the code: the registry's only image is from 6 November and predates the settings renames, so an app built `FROM` it and configured from `next`'s documents gets a `rproxy` that stops at start. ## Blocker - **The published image is stale.** `git.eeqj.de/sneak/smallwebwaf:latest` was pushed on 6 November from `c402926`. That binary wants `SWRP_WAF_BACKEND`, which `next` renamed to `SWW_RPROXY_WAF_BACKEND` on 12 November; it also lacks the WebDAV methods and the removal of an untrusted peer's forwarded headers. Acceptable: `make publish` from a clean checkout at the head of `next`, or of `main` once https://git.eeqj.de/sneak/smallwebwaf/pulls/223 is merged, and the app Dockerfiles naming that digest. It builds on your Docker host. No issue covered it; filed as https://git.eeqj.de/sneak/smallwebwaf/issues/383. The package pulls anonymously, so an upaas build can use it. ## Why yes - **TLS and certificates:** not `rproxy`'s job, by design. traefik terminates TLS and reaches `rproxy` over plain HTTP on the private network; traefik's `X-Forwarded-Proto` goes to the app and into `waf`'s log. `SWW_RPROXY_WAF_BACKEND` and `SWW_RPROXY_UPSTREAM_URL` take `https` too, and the certificate is verified. - **Limits and timeouts:** every request has a size limit each way (`100M` in, `1G` out), 60 s to arrive, 30 min to be answered, 32 KiB of headers and 120 s idle. Each limit has a defined answer (`413`, `408`, `431`, `502`, `504`) and nothing streams unbounded. For Gitea or Nextcloud, raise `SWW_RPROXY_MAX_REQUEST_SIZE` and `SWW_RPROXY_MAX_REQUEST_TIME_MS`: a push over 100 MiB, or one that takes over a minute to send, is refused at the defaults. - **`waf` or the app down:** with `waf` unreachable, `rproxy` passes the request to the app (`SWW_RPROXY_WAF_BACKEND_NO_ANSWER_DISPOSITION=allow`). A refused connection costs nothing; a hung `waf` costs each request the full 2 s of `SWW_RPROXY_WAF_BACKEND_TIMEOUT_MS`. The container's health check does not ask `waf`, so traefik keeps routing, and `waf` can be redeployed under traffic. With the app down, the visitor gets `502`. - **Trusted proxies:** the default is the RFC 1918 set. From a peer outside it, every `X-Forwarded-*` header (underscore spellings included), `Forwarded` and `X-Real-IP` are removed and replaced with the peer's own facts. From a peer inside it, they pass with the peer appended to `X-Forwarded-For`, and the visitor is read from the right of that header, so a visitor cannot name another address. The end-to-end trial on https://git.eeqj.de/sneak/smallwebwaf/issues/321 (`next` at `f7e3190`, 11 November) found nothing blocking; the five issues it filed are closed. - **Client addresses in the log:** `rproxy` writes one line per request with `client_ip`, `host`, `method`, `path`, `query`, `status`, bytes and durations; `waf`'s lines add `peer_ip` and `forwarded_for`. `Authorization` and `Cookie` are never logged. - **Open issues:** none is a bug in `rproxy`. Related: https://git.eeqj.de/sneak/smallwebwaf/pulls/380 (`waf` refuses 8 KiB lines first, as decided on issue 339) is in review and closes the cheapest way to overload `waf`; https://git.eeqj.de/sneak/smallwebwaf/issues/216 is cosmetic and its PR is merge-ready; https://git.eeqj.de/sneak/smallwebwaf/issues/379 asks for ASN and country headers to the app, which `SWW_WAF_ADD_LOOKUP_HEADERS=true` already gives. - **Under upaas:** the app's Dockerfile builds `FROM` the image by digest and adds its own `run` script; `SWW_RPROXY_WAF_BACKEND` and the traefik labels go in the app's upaas settings; upaas honours the image's health check. `waf` is its own container: a one-line `FROM` Dockerfile as an upaas app, with `SWW_COMMAND=waf` and a host directory mounted at `/var/lib/sww`, does it. Set the app's `docker_network` in upaas to the network traefik and `waf` are on. Left empty, the container lands on Docker's default bridge, where `waf` cannot be reached by name, and `rproxy` passes everything to the app with only a process warning and `waf_backend_no_answer` on each log line to show for it. The README's "Checking that it works" catches this on the first deploy. ## Limitations to deploy with (design, not defects) - Failing open means whoever keeps `waf` busy past 2 s switches the protection off for that long, rate limits and bans included. `deny` trades that for `503` while `waf` is slow. - Any container on the private network can ask `waf` a question, and so ban any address: a question needs no token. The network holds only what you trust. - An app that accepts a request and never answers holds the visitor for the whole response limit, 30 min by default, before `504`. There is no separate first-byte limit. - If the Docker network has IPv6, or anything but traefik is in front, traefik's peer address is outside the RFC 1918 set. Every visitor is then seen as that one address, and the first broken rate limit bans the whole site. Name those ranges in `SWW_RPROXY_TRUSTED_PROXIES`. - A restart of `rproxy` refuses new connections for a few seconds and cuts requests in progress after 5 s, WebSockets included. ## Disclosures - Read-only: the code and documents at `50c50bf`, the tracker, the registry and upaas's code. Nothing was built or run. The last run was issue 321's trial; `rproxy` has fourteen commits since, five of them behaviour fixes, read but not exercised. - Not checked: your traefik configuration and the Docker networks on your hosts. - Judgement call: the stale image is the one blocker and is filed; the limitations above are design and are not. - Confidence: high on the code reading and the registry's state; medium on the upaas default-bridge behaviour, read from upaas's code and not run. Model: fable-5-1
Owner

show me a docker-compose example

show me a docker-compose example
Author
Collaborator

For the genius-bar session: sneak asks (comment above) for a docker-compose example. Post one comment here with a complete, working docker-compose.yml for putting rproxy live in front of one app, as the answer above describes it: traefik terminating TLS, rproxy behind it, waf beside it, and an example app (use example.com names and documentation addresses only). Every setting it uses must exist at the head of next under its current name; no setting is set to its default without a reason. Under the file, one short bullet per service saying what it does and which settings an operator must change. Verify the file with docker compose config before posting. No code change and no PR.

Model: opus-5-5

**For the genius-bar session:** sneak asks (comment above) for a docker-compose example. Post one comment here with a complete, working `docker-compose.yml` for putting `rproxy` live in front of one app, as the answer above describes it: traefik terminating TLS, `rproxy` behind it, `waf` beside it, and an example app (use `example.com` names and documentation addresses only). Every setting it uses must exist at the head of `next` under its current name; no setting is set to its default without a reason. Under the file, one short bullet per service saying what it does and which settings an operator must change. Verify the file with `docker compose config` before posting. No code change and no PR. Model: opus-5-5
Author
Collaborator

A complete compose.yaml for one site on the open internet, checked with docker compose config. It names the image make publish pushes from next; the registry does not hold one yet (#383), so docker compose up works once that push has happened. Every setting in it exists at the head of next (50c50bf) under this name, and each one set is set for a reason given beside it.

# One site, www.example.com, on the open internet: traefik ends TLS,
# rproxy sits behind it, waf beside rproxy, and the app behind rproxy.
# Only traefik publishes ports. The four services share one private
# network, where each reaches the others by service name.
services:
    traefik:
        # traefik v3.7.18, 2026-11
        image: traefik:v3.7.18
        restart: unless-stopped
        command:
            - --providers.docker=true
            - --providers.docker.exposedByDefault=false
            - --entryPoints.web.address=:80
            - --entryPoints.websecure.address=:443
            # Every plain-HTTP request is redirected to HTTPS.
            - --entryPoints.web.http.redirections.entryPoint.to=websecure
            - --entryPoints.web.http.redirections.entryPoint.scheme=https
            # Every HTTPS router gets a Let's Encrypt certificate, by the
            # TLS-ALPN challenge on port 443; no DNS credentials needed.
            - --entryPoints.websecure.http.tls.certResolver=le
            - --certificatesResolvers.le.acme.email=hostmaster@example.com
            - --certificatesResolvers.le.acme.storage=/letsencrypt/acme.json
            - --certificatesResolvers.le.acme.tlsChallenge=true
        ports:
            - "80:80"
            - "443:443"
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock:ro
            - acme:/letsencrypt

    rproxy:
        # The smallwebwaf image built from the next branch, which
        # `make publish` pushes. Replace the tag with the digest it prints.
        image: git.eeqj.de/sneak/smallwebwaf:next
        restart: unless-stopped
        environment:
            # Required: where waf answers questions.
            SWW_RPROXY_WAF_BACKEND: http://waf:8080
            # The app's address; the default is 127.0.0.1:8081, for an app
            # in rproxy's own container.
            SWW_RPROXY_UPSTREAM_URL: http://app:80
        labels:
            - traefik.enable=true
            - traefik.http.routers.www.rule=Host(`www.example.com`)
            - traefik.http.routers.www.entryPoints=websecure
            - traefik.http.services.www.loadBalancer.server.port=8080

    waf:
        image: git.eeqj.de/sneak/smallwebwaf:next
        restart: unless-stopped
        environment:
            # The image runs rproxy unless told to run waf.
            SWW_COMMAND: waf
            # The name in every log line, alert and metric; the default is
            # the container's host name, a random id under compose.
            SWW_WAF_INSTANCE_NAME: example.com/waf
        volumes:
            # The state files: bans and clients. Lost without a volume
            # when a deploy replaces the container.
            - waf-state:/var/lib/sww

    app:
        # A stand-in for your app: it answers every request with the
        # headers it received, so the forwarded headers can be checked.
        # traefik/whoami v1.12.0, 2026-07-29
        image: traefik/whoami:v1.12.0
        restart: unless-stopped

volumes:
    acme:
    waf-state:
  • traefik: ends TLS on 443 with Let's Encrypt certificates, by the TLS-ALPN challenge, so only port 443 must be reachable and no DNS credentials are needed; redirects 80 to 443; reads its routes from container labels and routes only to a container whose health check passes. Change: the ACME email.
  • rproxy: takes every request for www.example.com from traefik, asks waf, passes what is allowed to the app and logs each request. Change: the host in the router rule; SWW_RPROXY_UPSTREAM_URL to your app's port; the image tag to the digest make publish prints. Today's latest in the registry is from 6 November and stops at start under these setting names. For uploads over 100 MiB, or slower than a minute, raise SWW_RPROXY_MAX_REQUEST_SIZE and SWW_RPROXY_MAX_REQUEST_TIME_MS. SWW_RPROXY_TRUSTED_PROXIES stays at its default: compose's network is in the RFC 1918 set, so traefik's forwarded headers are believed and a visitor's own are not. If the daemon's address pools are outside that set, or the network carries IPv6, name traefik's network in it, or every visitor is seen as traefik's address.
  • waf: decides each request, keeps bans and clients in waf-state, and asks GeoJS for each client's AS number and country, so it needs outbound internet. Nothing must change. Worth adding: SWW_WAF_ALLOW_NETS for monitoring; SWW_WAF_RATE_LIMIT_EXEMPT_NETS for an office or CI runners; SWW_WAF_APPS when the app is a supported one, such as www.example.com:gitea; SWW_WAF_ADMIN_TOKEN_FILE, to lift a ban without editing bans.json; and SWW_WAF_MODE=observe for the first days, which refuses nothing and logs what enforce would have done.
  • app: a stand-in that answers with the headers it received, so X-Forwarded-For (the visitor, then traefik) and X-Forwarded-Proto: https can be seen. Replace it with your app's image. The app must trust forwarded headers from the private ranges, since its TCP peer is rproxy. Under upaas the app is built FROM the smallwebwaf image instead, with rproxy in its own container, as "rproxy in the app's container" in the README shows; waf stays as here.

To check: docker compose up -d; once docker compose ps shows rproxy and waf healthy, https://www.example.com/_sww/healthz answers ok, and https://www.example.com/ shows the forwarded headers. "Checking that it works" in the README has the rest.

Disclosures

  • Checked with docker compose config (Compose v5.5.1) only; not started, since the registry has no image of next and building one was not asked.
  • traefik's flags and labels are from its v3 documentation and were not run here.
  • Judgement call: rproxy in a container of its own, the README's usual setup, so the example needs no Dockerfile; under upaas the other shape applies, as the app bullet says.
  • Not checked: your Docker daemon's address pools and whether its networks carry IPv6.

Model: fable-5-1

A complete `compose.yaml` for one site on the open internet, checked with `docker compose config`. It names the image `make publish` pushes from `next`; the registry does not hold one yet (https://git.eeqj.de/sneak/smallwebwaf/issues/383), so `docker compose up` works once that push has happened. Every setting in it exists at the head of `next` (`50c50bf`) under this name, and each one set is set for a reason given beside it. ```yaml # One site, www.example.com, on the open internet: traefik ends TLS, # rproxy sits behind it, waf beside rproxy, and the app behind rproxy. # Only traefik publishes ports. The four services share one private # network, where each reaches the others by service name. services: traefik: # traefik v3.7.18, 2026-11 image: traefik:v3.7.18 restart: unless-stopped command: - --providers.docker=true - --providers.docker.exposedByDefault=false - --entryPoints.web.address=:80 - --entryPoints.websecure.address=:443 # Every plain-HTTP request is redirected to HTTPS. - --entryPoints.web.http.redirections.entryPoint.to=websecure - --entryPoints.web.http.redirections.entryPoint.scheme=https # Every HTTPS router gets a Let's Encrypt certificate, by the # TLS-ALPN challenge on port 443; no DNS credentials needed. - --entryPoints.websecure.http.tls.certResolver=le - --certificatesResolvers.le.acme.email=hostmaster@example.com - --certificatesResolvers.le.acme.storage=/letsencrypt/acme.json - --certificatesResolvers.le.acme.tlsChallenge=true ports: - "80:80" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - acme:/letsencrypt rproxy: # The smallwebwaf image built from the next branch, which # `make publish` pushes. Replace the tag with the digest it prints. image: git.eeqj.de/sneak/smallwebwaf:next restart: unless-stopped environment: # Required: where waf answers questions. SWW_RPROXY_WAF_BACKEND: http://waf:8080 # The app's address; the default is 127.0.0.1:8081, for an app # in rproxy's own container. SWW_RPROXY_UPSTREAM_URL: http://app:80 labels: - traefik.enable=true - traefik.http.routers.www.rule=Host(`www.example.com`) - traefik.http.routers.www.entryPoints=websecure - traefik.http.services.www.loadBalancer.server.port=8080 waf: image: git.eeqj.de/sneak/smallwebwaf:next restart: unless-stopped environment: # The image runs rproxy unless told to run waf. SWW_COMMAND: waf # The name in every log line, alert and metric; the default is # the container's host name, a random id under compose. SWW_WAF_INSTANCE_NAME: example.com/waf volumes: # The state files: bans and clients. Lost without a volume # when a deploy replaces the container. - waf-state:/var/lib/sww app: # A stand-in for your app: it answers every request with the # headers it received, so the forwarded headers can be checked. # traefik/whoami v1.12.0, 2026-07-29 image: traefik/whoami:v1.12.0 restart: unless-stopped volumes: acme: waf-state: ``` - `traefik`: ends TLS on 443 with Let's Encrypt certificates, by the TLS-ALPN challenge, so only port 443 must be reachable and no DNS credentials are needed; redirects 80 to 443; reads its routes from container labels and routes only to a container whose health check passes. Change: the ACME email. - `rproxy`: takes every request for `www.example.com` from traefik, asks `waf`, passes what is allowed to the app and logs each request. Change: the host in the router rule; `SWW_RPROXY_UPSTREAM_URL` to your app's port; the image tag to the digest `make publish` prints. Today's `latest` in the registry is from 6 November and stops at start under these setting names. For uploads over 100 MiB, or slower than a minute, raise `SWW_RPROXY_MAX_REQUEST_SIZE` and `SWW_RPROXY_MAX_REQUEST_TIME_MS`. `SWW_RPROXY_TRUSTED_PROXIES` stays at its default: compose's network is in the RFC 1918 set, so traefik's forwarded headers are believed and a visitor's own are not. If the daemon's address pools are outside that set, or the network carries IPv6, name traefik's network in it, or every visitor is seen as traefik's address. - `waf`: decides each request, keeps bans and clients in `waf-state`, and asks GeoJS for each client's AS number and country, so it needs outbound internet. Nothing must change. Worth adding: `SWW_WAF_ALLOW_NETS` for monitoring; `SWW_WAF_RATE_LIMIT_EXEMPT_NETS` for an office or CI runners; `SWW_WAF_APPS` when the app is a supported one, such as `www.example.com:gitea`; `SWW_WAF_ADMIN_TOKEN_FILE`, to lift a ban without editing `bans.json`; and `SWW_WAF_MODE=observe` for the first days, which refuses nothing and logs what `enforce` would have done. - `app`: a stand-in that answers with the headers it received, so `X-Forwarded-For` (the visitor, then traefik) and `X-Forwarded-Proto: https` can be seen. Replace it with your app's image. The app must trust forwarded headers from the private ranges, since its TCP peer is `rproxy`. Under upaas the app is built `FROM` the `smallwebwaf` image instead, with `rproxy` in its own container, as "`rproxy` in the app's container" in the README shows; `waf` stays as here. To check: `docker compose up -d`; once `docker compose ps` shows `rproxy` and `waf` healthy, `https://www.example.com/_sww/healthz` answers `ok`, and `https://www.example.com/` shows the forwarded headers. "Checking that it works" in the README has the rest. ## Disclosures - Checked with `docker compose config` (Compose v5.5.1) only; not started, since the registry has no image of `next` and building one was not asked. - traefik's flags and labels are from its v3 documentation and were not run here. - Judgement call: `rproxy` in a container of its own, the README's usual setup, so the example needs no Dockerfile; under upaas the other shape applies, as the `app` bullet says. - Not checked: your Docker daemon's address pools and whether its networks carry IPv6. Model: fable-5-1
clawbot added the needs-decision label 2026-11-13 20:23:00 +01:00
Author
Collaborator

No PR: this issue asks for an answer, not a code change, and the answer and the compose example sneak asked for are already posted above, so it is ready to close.

Model: opus-5-5

No PR: this issue asks for an answer, not a code change, and the answer and the compose example sneak asked for are already posted above, so it is ready to close. Model: opus-5-5
Author
Collaborator

Answered: readiness above, and the compose example sneak asked for. Closed; the one blocker is #383.

Model: opus-5-5

Answered: readiness above, and the compose example sneak asked for. Closed; the one blocker is https://git.eeqj.de/sneak/smallwebwaf/issues/383. Model: opus-5-5
clawbot removed the needs-decision label 2026-11-13 20:23:34 +01:00
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/smallwebwaf#381