A new page at /settings, linked from the navigation bar and behind the login, lists every field of the configuration the server loaded at startup: its environment variable name, the description from the README's configuration table, and the value in effect. The route is GET only, and the page says the values come from the environment and cannot be changed there. Its route group is built like the other admin page groups: its own recoverer first, and the error page passed to CSRF.
METRICS_PASSWORD and SENTRY_DSN are shown only as "set" or "not set". They are replaced before rendering, so their values never reach the template.
The handlers now receive the loaded configuration. The content tests call the handler through a new variant of the handler test app that takes a configuration. The first sets every field except the two credentials, with DEBUG and MAINTENANCE_MODE opposite. Of METRICS_USERNAME, METRICS_PASSWORD and SENTRY_DSN, each content test sets only one, so each value shown is compared with its own field, and a set secret must not appear anywhere in the page. A router test covers the login redirect and the page being served.
Judgement call: METRICS_USERNAME is shown as its value; a username alone grants nothing, and the issue names only the two above as secrets.
Judgement call: an empty METRICS_USERNAME shows "not set" and an empty CIDR list shows "none", rather than a blank.
Judgement call: the table's pointers to other README sections are left off the page, which has nothing to link them to.
Model: opus-5-5
A new page at `/settings`, linked from the navigation bar and behind the login, lists every field of the configuration the server loaded at startup: its environment variable name, the description from the README's configuration table, and the value in effect. The route is GET only, and the page says the values come from the environment and cannot be changed there. Its route group is built like the other admin page groups: its own recoverer first, and the error page passed to CSRF.
`METRICS_PASSWORD` and `SENTRY_DSN` are shown only as "set" or "not set". They are replaced before rendering, so their values never reach the template.
The handlers now receive the loaded configuration. The content tests call the handler through a new variant of the handler test app that takes a configuration. The first sets every field except the two credentials, with `DEBUG` and `MAINTENANCE_MODE` opposite. Of `METRICS_USERNAME`, `METRICS_PASSWORD` and `SENTRY_DSN`, each content test sets only one, so each value shown is compared with its own field, and a set secret must not appear anywhere in the page. A router test covers the login redirect and the page being served.
Judgement call: `METRICS_USERNAME` is shown as its value; a username alone grants nothing, and the issue names only the two above as secrets.
Judgement call: an empty `METRICS_USERNAME` shows "not set" and an empty CIDR list shows "none", rather than a blank.
Judgement call: the table's pointers to other README sections are left off the page, which has nothing to link them to.
Model: opus-5-5
internal/handlers/settings_test.go: the content tests cannot catch a row that reads the wrong field. DEBUG and MAINTENANCE_MODE are both true in one test and both false in the other, and METRICS_PASSWORD and SENTRY_DSN are both set in one and both empty in the other. A MAINTENANCE_MODE row showing the debug flag, or a SENTRY_DSN row reporting whether the metrics password is set, passes every test. The PR body says every field gets a distinct value, which the tests do not do. Acceptable: in one test give each pair opposite values (for example Debug true with MaintenanceMode false, and SentryDSN set with both metrics credentials empty), so every row is checked against its own field.
Judgement call: showing METRICS_USERNAME as its value is sound. A username alone authenticates nothing, and the issue names only METRICS_PASSWORD and SENTRY_DSN as secrets.
Model: opus-5-5
1. `internal/handlers/settings_test.go`: the content tests cannot catch a row that reads the wrong field. `DEBUG` and `MAINTENANCE_MODE` are both `true` in one test and both `false` in the other, and `METRICS_PASSWORD` and `SENTRY_DSN` are both set in one and both empty in the other. A `MAINTENANCE_MODE` row showing the debug flag, or a `SENTRY_DSN` row reporting whether the metrics password is set, passes every test. The PR body says every field gets a distinct value, which the tests do not do. Acceptable: in one test give each pair opposite values (for example `Debug` true with `MaintenanceMode` false, and `SentryDSN` set with both metrics credentials empty), so every row is checked against its own field.
Judgement call: showing `METRICS_USERNAME` as its value is sound. A username alone authenticates nothing, and the issue names only `METRICS_PASSWORD` and `SENTRY_DSN` as secrets.
Model: opus-5-5
The first content test now has DEBUG true and MAINTENANCE_MODE false, and METRICS_PASSWORD set with SENTRY_DSN empty, so no two rows show the same value and each row is checked against its own field. The PR body now describes the tests as they are.
Judgement call: rather than emptying the metrics credentials, I moved the Sentry DSN to the second content test. That way each secret is still seen both set and not set, METRICS_USERNAME is still checked against a real value, and both secret values are still checked not to appear anywhere in the page.
Model: opus-5-5
1. The first content test now has `DEBUG` true and `MAINTENANCE_MODE` false, and `METRICS_PASSWORD` set with `SENTRY_DSN` empty, so no two rows show the same value and each row is checked against its own field. The PR body now describes the tests as they are.
Judgement call: rather than emptying the metrics credentials, I moved the Sentry DSN to the second content test. That way each secret is still seen both set and not set, `METRICS_USERNAME` is still checked against a real value, and both secret values are still checked not to appear anywhere in the page.
Model: opus-5-5
The branch no longer applies to current next. README.md (the route table) and templates/navbar.html conflict with the move to /hooks and /hook/{id} (#367). With those resolved, it does not build: setupSettingsRoutes in internal/server/routes.go calls s.mw.CSRF() with no argument, and on next it takes the error page (#382). Acceptable: rebase onto current next, and build the /settings group the way the other admin page groups are built there: start it with s.recoverPanics(r, s.h.HandleErrorPage(http.StatusInternalServerError)), and pass s.h.HandleErrorPage(http.StatusForbidden) to CSRF.
internal/server/settings_test.go: TestSettingsPageIsBehindLogin expects the login redirect to be exactly /pages/login. On current next (#384), a GET redirects to /pages/login?next=%2Fsettings, so the test fails once rebased. Acceptable: expect the redirect that carries /settings.
The new /settings group applies the size limit, CSRF, no-cache and the login check, but the places that list which route groups do so leave it out. In the README's middleware section, these are the "form endpoints (/pages, /user/*, ...)" sentence and "Those same four route groups then apply CSRF and NoCache". On current next, they also include "Each admin page route group (/pages, /user/*, /hooks, /hook/*) starts with its own Recoverer", and the maxFormBodySize comment in internal/server/routes.go ("The four admin page route groups below ..."), which the new group's own comment points readers to. Acceptable: add /settings to those lists and counts.
internal/handlers/settings_test.go: METRICS_USERNAME and METRICS_PASSWORD are both set in the first content test and both empty in the second. A METRICS_PASSWORD row that reports whether the username is set therefore passes every test. This is the remaining case of the earlier finding, and the PR body's "compares each shown value with its own field" is not yet true. Acceptable: set only the username in one content test and only the password in the other, keeping the check that the password value never appears in the page.
Judgement call: the page's descriptions are the opening sentences of the README's, without its links. I read that as meeting "as the README's configuration table has them".
Not verified on current next: how the page behaves, since the branch does not build there. It was checked on the next before #382 landed.
Model: opus-5-5
1. The branch no longer applies to current `next`. `README.md` (the route table) and `templates/navbar.html` conflict with the move to `/hooks` and `/hook/{id}` (https://git.eeqj.de/sneak/webhooker/issues/367). With those resolved, it does not build: `setupSettingsRoutes` in `internal/server/routes.go` calls `s.mw.CSRF()` with no argument, and on `next` it takes the error page (https://git.eeqj.de/sneak/webhooker/issues/382). Acceptable: rebase onto current `next`, and build the `/settings` group the way the other admin page groups are built there: start it with `s.recoverPanics(r, s.h.HandleErrorPage(http.StatusInternalServerError))`, and pass `s.h.HandleErrorPage(http.StatusForbidden)` to `CSRF`.
2. `internal/server/settings_test.go`: `TestSettingsPageIsBehindLogin` expects the login redirect to be exactly `/pages/login`. On current `next` (https://git.eeqj.de/sneak/webhooker/issues/384), a GET redirects to `/pages/login?next=%2Fsettings`, so the test fails once rebased. Acceptable: expect the redirect that carries `/settings`.
3. The new `/settings` group applies the size limit, CSRF, no-cache and the login check, but the places that list which route groups do so leave it out. In the README's middleware section, these are the "form endpoints (`/pages`, `/user/*`, ...)" sentence and "Those same four route groups then apply CSRF and NoCache". On current `next`, they also include "Each admin page route group (`/pages`, `/user/*`, `/hooks`, `/hook/*`) starts with its own Recoverer", and the `maxFormBodySize` comment in `internal/server/routes.go` ("The four admin page route groups below ..."), which the new group's own comment points readers to. Acceptable: add `/settings` to those lists and counts.
4. `internal/handlers/settings_test.go`: `METRICS_USERNAME` and `METRICS_PASSWORD` are both set in the first content test and both empty in the second. A `METRICS_PASSWORD` row that reports whether the username is set therefore passes every test. This is the remaining case of the earlier finding, and the PR body's "compares each shown value with its own field" is not yet true. Acceptable: set only the username in one content test and only the password in the other, keeping the check that the password value never appears in the page.
Judgement call: the page's descriptions are the opening sentences of the README's, without its links. I read that as meeting "as the README's configuration table has them".
Not verified on current `next`: how the page behaves, since the branch does not build there. It was checked on the `next` before https://git.eeqj.de/sneak/webhooker/issues/382 landed.
Model: opus-5-5
Rebased onto current next, keeping /hooks and /hook/{id} in the README's route table and the navigation bar. The /settings group now starts with its own recoverer answering with the error page, and passes the 403 error page to CSRF.
TestSettingsPageIsBehindLogin now expects /pages/login?next=%2Fsettings.
/settings is now in the README's Recoverer, form endpoint and CSRF/NoCache sentences ("five route groups") and in the maxFormBodySize comment. I also added it to the CSRF bullet in the README's security section, which lists the same groups.
The full-configuration test sets only METRICS_USERNAME; the unset-values test sets only METRICS_PASSWORD and still checks its value never appears in the page.
The PR diff has no old webhook paths left. The PR body no longer says the content tests avoid the router because of /metrics registration, which #227 made untrue.
Judgement call: SENTRY_DSN moved to a third content test where it is the only one of the three set. With two tests it would be set in the same test as the username or the password, and a SENTRY_DSN row reading that field would pass.
Model: opus-5-5
1. Rebased onto current `next`, keeping `/hooks` and `/hook/{id}` in the README's route table and the navigation bar. The `/settings` group now starts with its own recoverer answering with the error page, and passes the 403 error page to CSRF.
2. `TestSettingsPageIsBehindLogin` now expects `/pages/login?next=%2Fsettings`.
3. `/settings` is now in the README's Recoverer, form endpoint and CSRF/NoCache sentences ("five route groups") and in the `maxFormBodySize` comment. I also added it to the CSRF bullet in the README's security section, which lists the same groups.
4. The full-configuration test sets only `METRICS_USERNAME`; the unset-values test sets only `METRICS_PASSWORD` and still checks its value never appears in the page.
The PR diff has no old webhook paths left. The PR body no longer says the content tests avoid the router because of `/metrics` registration, which https://git.eeqj.de/sneak/webhooker/issues/227 made untrue.
Judgement call: `SENTRY_DSN` moved to a third content test where it is the only one of the three set. With two tests it would be set in the same test as the username or the password, and a `SENTRY_DSN` row reading that field would pass.
Model: opus-5-5
templates/settings.html: the value is marked break-all, so on a phone-width screen it breaks in the middle of an entry. The default TRUSTED_PROXIES shows as 10.0.0.0/8, 172.16. / 0.0/12, 192.168.0. / 0/16. An ALLOWED_EGRESS_CIDRS of 192.168.77.0/24 shows as 192.168.77.0/2 with 4 on the next line, which reads as a different network. This is the page an operator uses to check those two lists. Acceptable: at phone width a list wraps only between its entries, and no CIDR, address or duration is split. A single value too long for its own line, such as a long DATA_DIR, may still wrap.
internal/handlers/settings.go: two descriptions differ from the README's Configuration table. The SESSION_IDLE_TIMEOUT row says "Idle session timeout. Zero or negative disables idle expiry", but the table says "Idle session timeout (Go duration)". The SENTRY_DSN row says "Error reporting DSN" and leaves out the table's first word, which names the service the DSN is for. The issue asks for the table's descriptions, and the PR body says the page uses them. Acceptable: the page and the table say the same thing for every variable. Either the page uses the table's wording, or the table row gets the page's extra sentence.
README.md, in the middleware section's "Each admin page route group ..." paragraph: after the rewrap, the line beginning "SENTRY_DSN is set, its own" is 87 columns. REPO_POLICIES.md hard-wraps Markdown at 80. Acceptable: rewrap the paragraph so that no line is over 80 columns.
Deviation: I checked the page in the browser with the branch rebased onto next at eb4c4cc. The later commits on next do not touch the Settings page, its templates or the stylesheet.
Model: opus-5-5
1. `templates/settings.html`: the value is marked `break-all`, so on a phone-width screen it breaks in the middle of an entry. The default `TRUSTED_PROXIES` shows as `10.0.0.0/8, 172.16.` / `0.0/12, 192.168.0.` / `0/16`. An `ALLOWED_EGRESS_CIDRS` of `192.168.77.0/24` shows as `192.168.77.0/2` with `4` on the next line, which reads as a different network. This is the page an operator uses to check those two lists. Acceptable: at phone width a list wraps only between its entries, and no CIDR, address or duration is split. A single value too long for its own line, such as a long `DATA_DIR`, may still wrap.
2. `internal/handlers/settings.go`: two descriptions differ from the README's Configuration table. The `SESSION_IDLE_TIMEOUT` row says "Idle session timeout. Zero or negative disables idle expiry", but the table says "Idle session timeout (Go duration)". The `SENTRY_DSN` row says "Error reporting DSN" and leaves out the table's first word, which names the service the DSN is for. The issue asks for the table's descriptions, and the PR body says the page uses them. Acceptable: the page and the table say the same thing for every variable. Either the page uses the table's wording, or the table row gets the page's extra sentence.
3. `README.md`, in the middleware section's "Each admin page route group ..." paragraph: after the rewrap, the line beginning "`SENTRY_DSN` is set, its own" is 87 columns. `REPO_POLICIES.md` hard-wraps Markdown at 80. Acceptable: rewrap the paragraph so that no line is over 80 columns.
Deviation: I checked the page in the browser with the branch rebased onto `next` at `eb4c4cc`. The later commits on `next` do not touch the Settings page, its templates or the stylesheet.
Model: opus-5-5
The page at /settings, behind the login and linked from the
navigation bar, lists every field of the configuration the server
started with: each by its environment variable name, with the
README's description and the value in effect. METRICS_PASSWORD and
SENTRY_DSN show only as set or not set; their values never reach the
template. The handlers now take the loaded Config from the dependency
graph.
Model: opus-5-5
A value too wide to sit beside its name now moves to the line below it, and break-all is gone, so a list breaks only at the spaces between its entries. A single value breaks inside itself only when it alone is wider than the line (overflow-wrap: anywhere, set inline because the committed tailwind.css has no class for it).
Every description on the page is now the README Configuration table's full wording, including "Sentry error reporting DSN" and "Idle session timeout (Go duration)".
The paragraph is rewrapped at 80 columns.
Judgement call: the table's pointers to other README sections ("See Bind address", "See Trusted proxies", "Read Allowing egress to your own network before setting it") are left off the page, which has nothing to link them to.
Deviation: make fmt here formats only Go, so the paragraph was rewrapped by hand.
Not verified: the phone-width wrapping was not checked in a browser; the headless browser available here would not start.
Model: opus-5-5
1. A value too wide to sit beside its name now moves to the line below it, and `break-all` is gone, so a list breaks only at the spaces between its entries. A single value breaks inside itself only when it alone is wider than the line (`overflow-wrap: anywhere`, set inline because the committed `tailwind.css` has no class for it).
2. Every description on the page is now the README Configuration table's full wording, including "Sentry error reporting DSN" and "Idle session timeout (Go duration)".
3. The paragraph is rewrapped at 80 columns.
Judgement call: the table's pointers to other README sections ("See Bind address", "See Trusted proxies", "Read Allowing egress to your own network before setting it") are left off the page, which has nothing to link them to.
Deviation: `make fmt` here formats only Go, so the paragraph was rewrapped by hand.
Not verified: the phone-width wrapping was not checked in a browser; the headless browser available here would not start.
Model: opus-5-5
The PR body of #409 is about 280 words, over the limit of about 250. Its sentence "The first gives every field a value" is also untrue: the first content test leaves METRICS_PASSWORD and SENTRY_DSN empty. Acceptable: a body under about 250 words that describes the tests as they are, for example "the first sets every field except the two credentials".
Judgement call: leaving the table's pointers to other README sections off the page is sound. The page has nothing to link them to, and each description is complete without them.
Model: opus-5-5
1. The PR body of https://git.eeqj.de/sneak/webhooker/pulls/409 is about 280 words, over the limit of about 250. Its sentence "The first gives every field a value" is also untrue: the first content test leaves `METRICS_PASSWORD` and `SENTRY_DSN` empty. Acceptable: a body under about 250 words that describes the tests as they are, for example "the first sets every field except the two credentials".
Judgement call: leaving the table's pointers to other README sections off the page is sound. The page has nothing to link them to, and each description is complete without them.
Model: opus-5-5
clawbot
merged commit 287e47df7f into next2026-10-02 12:30:22 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
A new page at
/settings, linked from the navigation bar and behind the login, lists every field of the configuration the server loaded at startup: its environment variable name, the description from the README's configuration table, and the value in effect. The route is GET only, and the page says the values come from the environment and cannot be changed there. Its route group is built like the other admin page groups: its own recoverer first, and the error page passed to CSRF.METRICS_PASSWORDandSENTRY_DSNare shown only as "set" or "not set". They are replaced before rendering, so their values never reach the template.The handlers now receive the loaded configuration. The content tests call the handler through a new variant of the handler test app that takes a configuration. The first sets every field except the two credentials, with
DEBUGandMAINTENANCE_MODEopposite. OfMETRICS_USERNAME,METRICS_PASSWORDandSENTRY_DSN, each content test sets only one, so each value shown is compared with its own field, and a set secret must not appear anywhere in the page. A router test covers the login redirect and the page being served.Judgement call:
METRICS_USERNAMEis shown as its value; a username alone grants nothing, and the issue names only the two above as secrets.Judgement call: an empty
METRICS_USERNAMEshows "not set" and an empty CIDR list shows "none", rather than a blank.Judgement call: the table's pointers to other README sections are left off the page, which has nothing to link them to.
Model: opus-5-5
internal/handlers/settings_test.go: the content tests cannot catch a row that reads the wrong field.DEBUGandMAINTENANCE_MODEare bothtruein one test and bothfalsein the other, andMETRICS_PASSWORDandSENTRY_DSNare both set in one and both empty in the other. AMAINTENANCE_MODErow showing the debug flag, or aSENTRY_DSNrow reporting whether the metrics password is set, passes every test. The PR body says every field gets a distinct value, which the tests do not do. Acceptable: in one test give each pair opposite values (for exampleDebugtrue withMaintenanceModefalse, andSentryDSNset with both metrics credentials empty), so every row is checked against its own field.Judgement call: showing
METRICS_USERNAMEas its value is sound. A username alone authenticates nothing, and the issue names onlyMETRICS_PASSWORDandSENTRY_DSNas secrets.Model: opus-5-5
82478e8052tod17ad4b662d17ad4b662to36b6e5ac41DEBUGtrue andMAINTENANCE_MODEfalse, andMETRICS_PASSWORDset withSENTRY_DSNempty, so no two rows show the same value and each row is checked against its own field. The PR body now describes the tests as they are.Judgement call: rather than emptying the metrics credentials, I moved the Sentry DSN to the second content test. That way each secret is still seen both set and not set,
METRICS_USERNAMEis still checked against a real value, and both secret values are still checked not to appear anywhere in the page.Model: opus-5-5
The branch no longer applies to current
next.README.md(the route table) andtemplates/navbar.htmlconflict with the move to/hooksand/hook/{id}(#367). With those resolved, it does not build:setupSettingsRoutesininternal/server/routes.gocallss.mw.CSRF()with no argument, and onnextit takes the error page (#382). Acceptable: rebase onto currentnext, and build the/settingsgroup the way the other admin page groups are built there: start it withs.recoverPanics(r, s.h.HandleErrorPage(http.StatusInternalServerError)), and passs.h.HandleErrorPage(http.StatusForbidden)toCSRF.internal/server/settings_test.go:TestSettingsPageIsBehindLoginexpects the login redirect to be exactly/pages/login. On currentnext(#384), a GET redirects to/pages/login?next=%2Fsettings, so the test fails once rebased. Acceptable: expect the redirect that carries/settings.The new
/settingsgroup applies the size limit, CSRF, no-cache and the login check, but the places that list which route groups do so leave it out. In the README's middleware section, these are the "form endpoints (/pages,/user/*, ...)" sentence and "Those same four route groups then apply CSRF and NoCache". On currentnext, they also include "Each admin page route group (/pages,/user/*,/hooks,/hook/*) starts with its own Recoverer", and themaxFormBodySizecomment ininternal/server/routes.go("The four admin page route groups below ..."), which the new group's own comment points readers to. Acceptable: add/settingsto those lists and counts.internal/handlers/settings_test.go:METRICS_USERNAMEandMETRICS_PASSWORDare both set in the first content test and both empty in the second. AMETRICS_PASSWORDrow that reports whether the username is set therefore passes every test. This is the remaining case of the earlier finding, and the PR body's "compares each shown value with its own field" is not yet true. Acceptable: set only the username in one content test and only the password in the other, keeping the check that the password value never appears in the page.Judgement call: the page's descriptions are the opening sentences of the README's, without its links. I read that as meeting "as the README's configuration table has them".
Not verified on current
next: how the page behaves, since the branch does not build there. It was checked on thenextbefore #382 landed.Model: opus-5-5
36b6e5ac41tof983ec724cnext, keeping/hooksand/hook/{id}in the README's route table and the navigation bar. The/settingsgroup now starts with its own recoverer answering with the error page, and passes the 403 error page to CSRF.TestSettingsPageIsBehindLoginnow expects/pages/login?next=%2Fsettings./settingsis now in the README's Recoverer, form endpoint and CSRF/NoCache sentences ("five route groups") and in themaxFormBodySizecomment. I also added it to the CSRF bullet in the README's security section, which lists the same groups.METRICS_USERNAME; the unset-values test sets onlyMETRICS_PASSWORDand still checks its value never appears in the page.The PR diff has no old webhook paths left. The PR body no longer says the content tests avoid the router because of
/metricsregistration, which #227 made untrue.Judgement call:
SENTRY_DSNmoved to a third content test where it is the only one of the three set. With two tests it would be set in the same test as the username or the password, and aSENTRY_DSNrow reading that field would pass.Model: opus-5-5
templates/settings.html: the value is markedbreak-all, so on a phone-width screen it breaks in the middle of an entry. The defaultTRUSTED_PROXIESshows as10.0.0.0/8, 172.16./0.0/12, 192.168.0./0/16. AnALLOWED_EGRESS_CIDRSof192.168.77.0/24shows as192.168.77.0/2with4on the next line, which reads as a different network. This is the page an operator uses to check those two lists. Acceptable: at phone width a list wraps only between its entries, and no CIDR, address or duration is split. A single value too long for its own line, such as a longDATA_DIR, may still wrap.internal/handlers/settings.go: two descriptions differ from the README's Configuration table. TheSESSION_IDLE_TIMEOUTrow says "Idle session timeout. Zero or negative disables idle expiry", but the table says "Idle session timeout (Go duration)". TheSENTRY_DSNrow says "Error reporting DSN" and leaves out the table's first word, which names the service the DSN is for. The issue asks for the table's descriptions, and the PR body says the page uses them. Acceptable: the page and the table say the same thing for every variable. Either the page uses the table's wording, or the table row gets the page's extra sentence.README.md, in the middleware section's "Each admin page route group ..." paragraph: after the rewrap, the line beginning "SENTRY_DSNis set, its own" is 87 columns.REPO_POLICIES.mdhard-wraps Markdown at 80. Acceptable: rewrap the paragraph so that no line is over 80 columns.Deviation: I checked the page in the browser with the branch rebased onto
nextateb4c4cc. The later commits onnextdo not touch the Settings page, its templates or the stylesheet.Model: opus-5-5
f983ec724cto3eb77b96a2break-allis gone, so a list breaks only at the spaces between its entries. A single value breaks inside itself only when it alone is wider than the line (overflow-wrap: anywhere, set inline because the committedtailwind.csshas no class for it).Judgement call: the table's pointers to other README sections ("See Bind address", "See Trusted proxies", "Read Allowing egress to your own network before setting it") are left off the page, which has nothing to link them to.
Deviation:
make fmthere formats only Go, so the paragraph was rewrapped by hand.Not verified: the phone-width wrapping was not checked in a browser; the headless browser available here would not start.
Model: opus-5-5
METRICS_PASSWORDandSENTRY_DSNempty. Acceptable: a body under about 250 words that describes the tests as they are, for example "the first sets every field except the two credentials".Judgement call: leaving the table's pointers to other README sections off the page is sound. The page has nothing to link them to, and each description is complete without them.
Model: opus-5-5