Conversation
…DO) (#987) DigitalOcean image pushes are now opt-in. Each docker-build-publish workflow (dev/stage/prod): - Passes vars.DO_ENABLED into the "Resolve image tags" (meta) step and only appends the registry.digitalocean.com/... tags when DO_ENABLED == 'true', so the push:true build-push-action never tries to push to DO (which would 403) when DO is disabled. - ANDs vars.DO_ENABLED == 'true' into the existing `if:` on the "Install doctl" and "Login to DigitalOcean Container Registry" steps. No DO code is deleted -- it is simply skipped by default and re-enabled by setting the org/repo variable DO_ENABLED=true. GHCR/Docker Hub and all other steps are unchanged. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
apps/docs (@ever-works/docs, Docusaurus) had no Dockerfile / matrix entry, so ghcr.io/ever-works/directory-web-template-docs went stale (last 2026-07-08) while docs-demo-ever-works-prod keeps running it. Add: - apps/docs/Dockerfile: base -> turbo prune @ever-works/docs -> pnpm install -> docusaurus build -> nginx (mirrors the root Dockerfile + ever-works docs build; copies repo-root docs/ since Docusaurus reads ../../docs). - apps/docs/nginx.conf: static serve with clean-URL try_files + Docusaurus 404. - k8s-build.yml: matrix entry directory-web-template-docs -> :dev/:stage/:prod+:sha. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…OSPC on RAM-disk) The first attempt's `docusaurus build` (all locales) rendered every locale of the large API docs, ran ~7480s on the ARC RAM-disk runner (starving the shared pool) and died with ENOSPC mid-way through /pt/. Switch to `build:en` (English only) — a fraction of the disk/time, fits the RAM-disk. Re-enable full-locale later on a disk-backed builder. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…oves Node-20 deprecation warnings) [skip ci]
…oves Node-20 deprecation warnings) [skip ci]
…oves Node-20 deprecation warnings) [skip ci]
…oves Node-20 deprecation warnings) [skip ci]
…oves Node-20 deprecation warnings) [skip ci]
…oves Node-20 deprecation warnings) [skip ci]
…oves Node-20 deprecation warnings) [skip ci]
…oves Node-20 deprecation warnings) [skip ci]
…oves Node-20 deprecation warnings) [skip ci]
…oves Node-20 deprecation warnings) [skip ci]
…oves Node-20 deprecation warnings) [skip ci]
…oves Node-20 deprecation warnings) [skip ci]
…oves Node-20 deprecation warnings) [skip ci]
…oves Node-20 deprecation warnings) [skip ci]
…oves Node-20 deprecation warnings) [skip ci]
Large directories (e.g. the demo's 3271 items ≈ 2.6MB) exceed Next.js
`unstable_cache`'s hard 2MB per-entry limit. Next then SILENTLY drops the
entry and recomputes + re-serializes the whole catalogue on every request
("Failed to set Next.js data cache … items over 2MB can not be cached"),
pegging CPU (demo.ever.works web pod sat at ~1.5 cores sustained, ~49
cache-fail log lines per 500).
The listing wrappers (getCachedItems / getCachedItemsByCategory /
getCachedItemsByTag / getCachedItemsByCategoryAndTag) now size-gate the
Data Cache layer: when a listing exceeds DATA_CACHE_MAX_ITEMS (default
2000, override via CONTENT_DATA_CACHE_MAX_ITEMS) they skip unstable_cache
and serve from the in-memory fetchItems cache (10-min TTL, cleared on
content sync) instead. Listing items are metadata-only (markdown stripped,
~0.8KB each), so item count is a reliable size proxy. Small directories are
unaffected and keep the persistent Data Cache.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Point the two remaining bare `ubuntu-latest` jobs (CodeQL analysis and
the default-CodeQL disabler) at the self-hosted ARC var, keeping the
GitHub-hosted fallback:
runs-on: ${{ vars.RUNNER_LINUX_X64_4 || 'ubuntu-latest' }}
CodeQL/SARIF jobs use the smallest (_4) pool per runner policy. All
other workflows already use the ARC vars.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ci: move CodeQL runners to self-hosted ARC fleet (develop)
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
|
||
| // `fetchItems` is in-memory cached, so this is cheap on the hot path and lets us size-gate | ||
| // the (2MB-capped) Data Cache layer before paying to serialize an oversized catalogue. | ||
| const result = await fetchItems(options); |
There was a problem hiding this comment.
Persistent cache is bypassed before lookup
getCachedItems calls fetchItems(options) before invoking unstable_cache, solely to determine whether the result is small enough to persist. Consequently, a cold process-local cache still walks and parses the full content tree even when the Data Cache already contains this listing. This defeats the persistent-cache layer's purpose of avoiding content-tree work on cold processes and adds avoidable request latency.
Artifacts
Instrumented harness source for persistent Data Cache hit and miss cases
- The authored Node harness extracts the actual wrapper from `content.ts`, instruments its cache seams, and asserts the two target execution paths; it confirms the behavior under test.
Persistent Data Cache hit with cold process-local cache
- Executed `NODE_ENV=production node trex-artifacts/data-cache-eager-fetch-harness.mjs persistent-hit` from `/home/user/repo` with exit code 0; it shows one fetch and one filesystem walk/parse before the persistent hit, confirming the hit does not avoid parsing.
| location ~* \.(js|css|woff2?|ttf|eot|svg|png|jpg|jpeg|gif|webp|ico)$ { | ||
| expires 30d; | ||
| add_header Cache-Control "public, max-age=2592000, immutable"; | ||
| try_files $uri =404; |
There was a problem hiding this comment.
Unhashed images are cached as immutable
This extension-only location applies public, max-age=2592000, immutable to stable image URLs such as /overview.png, not just fingerprinted build assets. When a deployment replaces an image without changing its URL, browsers with a fresh cached copy do not re-request it and continue displaying the old image for up to 30 days. Restrict the immutable policy to content-hashed assets or use a revalidating policy for replaceable image URLs.
Artifacts
Focused Chromium same-name image cache proof script
- The executed proof script builds a local response path around the real docs `/overview.png`, reads the nginx image rule, and tests a same-URL deployment replacement in Chromium; it demonstrates the exact cache scenario.
Chromium same-name image cache proof output
- Output from the executed Playwright Chromium proof shows the immutable Cache-Control header, rendered image, and one origin request across both deployment versions; it confirms the replacement stays cached.
- Output from the executed Docusaurus English build shows static files were generated successfully before the HTTP cache validation; it confirms the tested asset came from a real docs build.
Greptile SummaryThis change adds a size gate for persisted directory listings, refreshes CI and deployment configuration, and introduces nginx delivery for the English documentation site. Runtime checks found that small directory listings still load and parse content before the persistent cache is consulted, and a persistent-cache miss invokes the listing function again through the cache callback. Documentation images served from stable URLs are also cached as immutable for 30 days, so replacing an image without changing its URL leaves returning visitors on the prior version. The English documentation build completed successfully, and focused runtime checks reproduced the cache behavior in both affected areas. Confidence Score: 3/5Not safe to merge until the listing-cache lookup order and immutable caching policy for replaceable documentation images are corrected. Two independent user-facing failures remain: cached directory listings do not avoid cold-process content parsing, and documentation image replacements can remain hidden behind a month-long browser cache. The listing path also makes an unnecessary second listing-function invocation when populating a missing persistent entry. Files Needing Attention: apps/web/lib/content.ts needs its listing-cache admission and lookup flow revised; apps/docs/nginx.conf needs immutable caching restricted to fingerprinted assets or relaxed for replaceable image URLs.
What T-Rex did
|
Cascade
develop→stageso the oversized-listing cache fix can reachmainand then the 14 instance repos generated from this template.Carries 21 commits, of which the one that matters is 9648d62
fix(cache): skip 2MB-capped Data Cache for oversized listings (#988). The rest are CI hygiene already swept fleet-wide (DO gating, x4 runners + Node-24 actions, CodeQL on self-hosted ARC).Why this is urgent
unstable_cachehard-caps one entry at 2MB and silently drops anything larger — the entry is then recomputed and re-serialized on every request. Live effect on the largest catalogue (mcpserver.ever.works, 4065 items, ~2× the new 2000-item threshold): ~35s per request with memory climbing monotonically (1549→2896Mi) while sitting well under a 4-core/4GB ceiling. Not saturation — unbounded recompute.vectordb(32 restarts) andtimetrack(intermittent 20s timeouts) look like the same defect scaling with catalogue size.Note on divergence
developis 21 ahead but 188 behindstage, so these branches have drifted both ways. The two files the fix touches are unaffected by that drift:apps/web/lib/content.tsdiffers between develop and main by only 29 lines (essentially the fix itself), andapps/web/lib/cache-config.tsby exactly 18 added lines. Templatemainis byte-identical to the instance repos for both files.