From efcf8fa93ed6abc7b193badf069067d69f36f0a3 Mon Sep 17 00:00:00 2001 From: Juan Sugg Date: Wed, 15 Jul 2026 05:15:43 -0300 Subject: [PATCH] docs: correct env claims, the Postman full tier, and Quick Start model examples MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three documented facts that were not facts. RATE_LIMIT_REDIS_TOPOLOGY: the doc asserted the Render deployment "keeps RATE_LIMIT_REDIS_TOPOLOGY=external". The variable is not set on the service at all. The behaviour it describes is right — external is the code default — but stating it as configuration sends anyone auditing the dashboard looking for a variable that was never there. SCRAPER_REQUEST_TIMEOUT_MS: the documented 10000 default matches the code; the service runs 90000 and the doc never said so. Hosted vision models routinely take longer than 10s per image, so the deviation is deliberate and now recorded with its reason, rather than looking like drift to the next reader. postman:full was described as the harness "for main and production". It is neither: the tier appears in exactly one workflow (Local Provider Integration), whose triggers are manual dispatch, a weekly schedule, and paths-filtered push/PR to main — there is no production trigger. CI does run on production pushes, but hardcodes NEWMAN_MODE: smoke with no branch conditional, so production gets smoke and never full. The sibling tiers are all written as trigger policy, so this bullet read as trigger policy too, and promised production coverage that does not exist. It now separates capability from execution policy. Quick Start hardcoded model=replicate. Providers register only when their keys are set, and an unregistered model throws Unknown model -> 400 UNKNOWN_MODEL (descriptionController.js:215-221), so an install configured for any other provider got a 400 following the README verbatim. The examples now name a placeholder and say the value must be a provider configured in .env. --- DEVELOPMENT.md | 4 ++-- README.md | 8 +++++--- docs/postman-standards.md | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 16ae21aa75..b9bbae586b 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -507,7 +507,7 @@ method, or protocol. | `CLUSTER_MAX_CRASHES` | No | `5` | Maximum unexpected worker exits allowed inside the crash window before the primary exits non-zero. | | `CLUSTER_SHUTDOWN_TIMEOUT_MS` | No | `10000` | Time the cluster primary waits for worker disconnect during shutdown before forcing exit. | | `REDIS_URL` | No | unset | Shared Redis URL used automatically for rate limiting when `RATE_LIMIT_STORE=auto` and no explicit `RATE_LIMIT_REDIS_URL` is provided. | -| `SCRAPER_REQUEST_TIMEOUT_MS` | No | `10000` | Timeout for outbound page fetches and provider HTTP calls. | +| `SCRAPER_REQUEST_TIMEOUT_MS` | No | `10000` | Timeout for outbound page fetches and provider HTTP calls. The Render service raises this to `90000`: hosted vision models routinely take more than 10s per image, and the free-tier instance is slower still. | | `SCRAPER_MAX_REDIRECTS` | No | `5` | Redirect limit for outbound page fetches. | | `SCRAPER_MAX_CONTENT_LENGTH_BYTES` | No | `2097152` | Maximum response body size accepted when scraping HTML. | @@ -610,7 +610,7 @@ At least one provider must be configured at startup: `REPLICATE_API_TOKEN`, Azur - `/api/health` is the readiness signal used by Render. It returns `200` while the instance is ready and `503` once graceful shutdown begins. - Status routes use their own limiter so health probes are protected without sharing the main API request budget. - Clustered mode (`WORKER_COUNT > 1`) requires a Redis-backed limiter. Startup validation fails fast if clustered mode is enabled without `RATE_LIMIT_STORE=redis|auto` and a resolvable Redis endpoint. -- The current Render deployment keeps `RATE_LIMIT_REDIS_TOPOLOGY=external`, so the future pod-local Redis path is explicitly disabled for now. +- The current Render deployment runs the `external` topology — it does not set `RATE_LIMIT_REDIS_TOPOLOGY` at all, and `external` is the code default (`config/rateLimitStore.js`) — so the future pod-local Redis path is inactive for now. - Horizontal instance scaling should use an external/shared Redis-backed limiter, and `STATUS_RATE_LIMIT_MAX` should be sized for the aggregate health-probe budget across instances. - The future `RATE_LIMIT_REDIS_TOPOLOGY=unit-local` mode is meant for a Docker/Kubernetes-style resilient unit where several worker processes intentionally share one pod-local Redis instance. - Redis-backed limiter errors fail open at request time to preserve availability, but startup still fails fast when Redis is explicitly required and unreachable during bootstrap. diff --git a/README.md b/README.md index 7f1984dfe9..e483939a11 100644 --- a/README.md +++ b/README.md @@ -270,10 +270,12 @@ GET `/api/accessibility/description` or `/api/v1/accessibility/description` - fast providers return `200` with the description array immediately - slow async providers such as `replicate` can return `202` with `jobId`, `status`, `pollAfterMs`, and `statusUrl` -Example: +Example — replace `` with a provider you configured in `.env`. +A provider registers only when its keys are set, and an unregistered one returns +`400 UNKNOWN_MODEL`: ```bash -curl -sk "https://localhost:8443/api/accessibility/description?image_source=https%3A%2F%2Fwww.google.com%2Fimages%2Fbranding%2Fgooglelogo%2F1x%2Fgooglelogo_color_272x92dp.png&model=replicate" +curl -sk "https://localhost:8443/api/accessibility/description?image_source=https%3A%2F%2Fwww.google.com%2Fimages%2Fbranding%2Fgooglelogo%2F1x%2Fgooglelogo_color_272x92dp.png&model=" ``` GET `/api/accessibility/description-jobs/:jobId` or `/api/v1/accessibility/description-jobs/:jobId` @@ -304,7 +306,7 @@ GET `/api/accessibility/descriptions` or `/api/v1/accessibility/descriptions` Example: ```bash -curl -sk "https://localhost:8443/api/accessibility/descriptions?url=https%3A%2F%2Fdeveloper.chrome.com%2F&model=replicate" +curl -sk "https://localhost:8443/api/accessibility/descriptions?url=https%3A%2F%2Fdeveloper.chrome.com%2F&model=" ``` GET `/api/accessibility/page-description-jobs/:jobId` or `/api/v1/accessibility/page-description-jobs/:jobId` diff --git a/docs/postman-standards.md b/docs/postman-standards.md index 952d54d066..4a609e0733 100644 --- a/docs/postman-standards.md +++ b/docs/postman-standards.md @@ -12,7 +12,8 @@ Use the Postman/Newman layer for external HTTP contract validation, not for re-t - Fast deterministic checks required on pull requests - Covers core health/docs/routing, protected-endpoint auth, and one representative provider path - `full` - - Full deterministic harness for `main` and `production` + - Full deterministic harness. Runs on manual dispatch, weekly schedule, and paths-filtered push/PR to `main` (`Local Provider Integration`) + - Not run on `production` — CI runs the `smoke` tier there - Adds broader contract, negative-path, and page-description coverage - `live` - Manual or scheduled validation against real providers