From 8f98bbe2530d8f7ef2e80a394afdf27860d9d1fe Mon Sep 17 00:00:00 2001 From: Ruben van der Linde Date: Mon, 17 Aug 2026 05:48:09 +0200 Subject: [PATCH] fix(phpcs): clear the 2 PHPCS errors in lib/Controller The shared quality gate maps `phpcs` exit 1 to success, so these have been shipping silently. Raw `composer phpcs` exit goes 1 -> 0. Both are PEAR.Commenting.FunctionComment.WrongStyle, and both are the same shape: a real `/** */` docblock, then a `//` block explaining the `#[AnonRateLimit]` choice, then the attribute, then the function. Because the `//` block is what immediately precedes the function, PHPCS reads THAT as the function comment and rejects its style. Fixed by folding the rate-limit rationale into the docblock it belongs to and keeping the attributes contiguous. No prose is deleted -- every sentence is preserved, as a "Rate-limit rationale:" paragraph. Side effect, deliberate and verified: this also removes 2 CustomSniffs.Commenting.SpecTag.MissingMethodSpec warnings (470 -> 468), and drops the same two methods off `composer lint:spec-annotations`. Those reports were false. Both methods already carried an `@spec` tag; the stray `//` block sat between the docblock and the function and hid it. `grep -c '@spec'` is identical before and after in both files -- no tag was added, and none was suppressed. A warning set-diff confirms 0 warnings added. Documentation only -- no executable statement is touched. Verified against a second pristine clone of development: lint, lint:initial-state, lint:licenses, phpmd, psalm, phpstan and phpunit are unchanged (1575 tests, identical failing-test-name set). lint:spec-annotations stays red on its pre-existing Db/Migration backlog, which this branch does not touch. --- lib/Controller/HealthController.php | 4 +++- lib/Controller/PageController.php | 13 +++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/Controller/HealthController.php b/lib/Controller/HealthController.php index d239e5869..ad5bca3da 100644 --- a/lib/Controller/HealthController.php +++ b/lib/Controller/HealthController.php @@ -79,13 +79,15 @@ public function __construct( * which is a meaningful answer for a monitoring probe: the app is reachable, * its declarative health engine is not. * + * Rate-limit rationale: this is a liveness probe — no credential, so a + * ceiling and no counter. + * * @return JSONResponse `{status, app, version, checks}`. * * @spec openspec/changes/adopt-apphost/specs/prometheus-metrics/spec.md — Requirement: Health Check Endpoint (REQ-PROM-007) */ #[PublicPage] #[NoCSRFRequired] - // Liveness probe — no credential, so a ceiling and no counter. #[AnonRateLimit(limit: 120, period: 60)] public function index(): JSONResponse { $appId = $this->appName; diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 85b9986a0..9efe3ef6b 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -555,18 +555,19 @@ private function buildWorkspaceCsp(): ContentSecurityPolicy { * The image CSP is widened to `data:` so the bundled NL Design tile icons * (base64 SVG data URIs) render for anonymous visitors too. * + * Rate-limit rationale: this is the public share page — one of only four + * rendered public pages in the fleet (ADR-081). The share TOKEN is checked by + * PublicShareController, which already has brute-force protection wired + * through PublicShareService::registerAttempt(); this is just the shell that + * hosts it, so a volume ceiling is the right control and it is deliberately + * generous — a recipient reloading the page must not be what trips it. + * * @return TemplateResponse The public page response. * * @spec openspec/changes/dashboard-public-share/specs/dashboard-public-share/spec.md */ #[PublicPage] #[NoCSRFRequired] - // The public share page — one of only four rendered public pages in the - // fleet (ADR-081). The share TOKEN is checked by PublicShareController, - // which already has brute-force protection wired through - // PublicShareService::registerAttempt(); this is just the shell that hosts - // it, so a volume ceiling is the right control and it is deliberately - // generous — a recipient reloading the page must not be what trips it. #[AnonRateLimit(limit: 120, period: 60)] public function publicShare(): TemplateResponse { Util::addScript(application: Application::APP_ID, file: 'launchpad-public');