feat(website): prepare live map rehearsal for production#10
Conversation
Polish pass on the public homepage live map (no schema/API redesign, no deploy). HomeMap: - Faint resting theme tint with a hover/selection ramp (no idle animation). - Cubic "mycelial" selection strands with per-strand width variation. - Chapters open an inspect card with a single "Visit chapter" link; stewards get an in-card chapter-jump cross-link instead of a map thread. - Deselect re-reveals the default state and captures arrivals added while a node was open. - 72-char tagline (with counter) replaces the long public intro. - Pin-first location with a bundled ~65-city datalist and free-text fallback. - Mobile dialog close bumped to a 44x44 touch target. shared/map-state: - Recolour the public theme palette. - Relationships are person-to-person only (steward<->steward, steward<->member, member<->member); chapters stay geographic anchors with no relationship thread. Prefer a specific shared theme over the near-ubiquitous "public" for edge colour. Public payload shape unchanged. Homepage shell: - GpLayout gains backgroundMode; homepage renders a plain background (drops the hero topo overlay and section border rules). Data/tests: - world-land-rings: Natural Earth 110m land silhouette for the SVG dot world. - map-node contract suite (37) and browser smoke updated; live e2e gains an --expanded 9-member/4-steward scenario. - DESIGN.md + website CLAUDE.md motion standard: no idle/looping map animation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codify the local browser-QA policy and enforce it in tooling: - AGENTS.md, root CLAUDE.md, website CLAUDE.md: local agentic browser QA must use the authenticated Brave QA profile. Isolated Browser/Playwright/DevTools MCP and the ui:verify / browser-proof lanes are CI/clean-room only and must not be reported as authenticated verification; report QA blocked if authenticated Brave is unreachable. - scripts/check-browser-verification-policy.mjs: static guard asserting the policy text is present in the policy files; wired into agentic:check. - scripts/require-authenticated-browser-qa.mjs: runtime gate that fails agentic:browser-proof / agentic:verify outside CI (CI=true passes as clean-room). - package.json: wire both guards into the agentic:* scripts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sheet mobile) Same-city people share an exact coordinate, so their pins stacked into an unreadable blob. Overlapping people pins now collapse into a count bubble while they overlap: - Desktop: clicking a spread-out group zooms to frame it (reusing the existing viewBox framing); a coincident group on an identical coordinate fans out into radial satellites with leader lines, each an individually selectable button. - Touch / narrow viewports: tapping opens a bottom-sheet list of the co-located people (44px targets), reusing the on-map sheet language. - The bubble is a real role=button with a count and an "N people near <place>" label; clustered pins are hidden and removed from the tab order + a11y tree. - One-shot motion only (gpMapClusterPop), reduced-motion safe. Client-only — no /map/state payload change; clustering recomputes on zoom/filter/arrival. JS-created elements are Astro-scoped (applyScope) so the scoped CSS applies. Adds a focused contract test (38 pass) and one baselined SVG count font-size. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds POST /map-nodes/edit-link-request so a returning owner who cannot find or select their pin (cache cleared, new device, still-pending node) can request a manage link by email alone — the per-node /map-nodes/:id/edit-link path requires a node id. Reuses the existing hash-only edit-token issuing + Resend send path. Privacy boundary: - Always returns the same neutral 202; never reveals whether the email matched, how many nodes, or any node detail. - Approved/public submissions only (never pending or private rows); asserts !containsPrivateMapNodeField before building any send. - Email-keyed rate limit: cooldown on email + IP, sharing the per-node daily IP and email caps, plus a per-request match cap so one request can't be turned into an unbounded email amplifier. - A no-match request still records an attempt row, so a no-match is not observable by absence. Tokens stay hash-only. Contract tests prove uniform response, approved-only lookup, hash-only token, rate-limit behavior, and no input/provider leakage on failure. Also corrects a stale edge assertion in the app-routes test left by the earlier person-to-person edge change (chapters are anchors and no longer carry relationship threads). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…dialog
Closes the cache-clear recovery gap from the public side. The add-node dialog
footer now offers "Already added yourself and lost access? — Email me a manage
link": a collapsed email form that posts to the new /map-nodes/edit-link-request
route. Mirrors the per-node "Edit this node" form — validates, shows the same
neutral confirmation immediately ("If that email matches a published node, we've
emailed a manage link."), clears the input so no email lingers in the DOM, and
fire-and-forgets the request so the UI never reveals whether the email matched.
Tokens-only styling, 44px touch targets, aria-expanded toggle.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Address two medium-severity issues found in the live-map review. Poll hardening (HomeMap.astro): /map/state polling had no in-flight guard, no fetch timeout, and no abort, so under latency requests could stack against the agent and a late response could clobber a newer one. Add an in-flight guard plus an AbortController timed out at 8s and cleared on settle. Dormant in moderated mode (the poll only runs in live mode), but unbounded once live onboarding is enabled. Cluster-expand keyboard focus (HomeMap.astro): activating a spread-out cluster only zoomed, and the debounced recompute then removed the focused bubble, dropping focus to <body>; a single-link chain that zoom cannot separate also made Enter a silent no-op. Settle the recompute synchronously after framing, fan out when framing cannot separate the group, and re-home keyboard focus to the first now-separated pin. Also fixes a mouse dead-end on an inseparable cluster. Contract tests (map-node-contract.test.ts) updated to lock both behaviours and the new fetch signature; map-node suite 38 pass. Verified test:map-nodes, ui:check (0/0), build:website. Rendered cluster-keyboard QA in authenticated Brave was blocked by the backgrounded-tab setTimeout pause (the debounced recompute that builds the bubble cannot fire while the tab is hidden); the built page otherwise loaded with zero page-level console errors and a working interactive map. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds production-ready live map activity contracts, ecoregion metadata, pending-node storage, and rehearsal tooling for the public website rollout.
|
Warning Review limit reached
More reviews will be available in 30 minutes and 51 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (9)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (5)
packages/shared/src/map-node-storage.ts (1)
32-63: ⚖️ Poor tradeoffSignificant duplication with
map-nodes.ts.
PUBLIC_MAP_THEME_ALIASES,normalizePublicMapThemeSlug(s),PENDING_NODE_STORAGE_KEY,PENDING_NODE_UPDATED_EVENT, andlocalPendingNodeSignatureare duplicated between this file andmap-nodes.ts. This creates maintenance burden and potential for drift.Consider having one module re-export from the other, or extracting shared utilities to a common internal module.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/shared/src/map-node-storage.ts` around lines 32 - 63, The constants PUBLIC_MAP_THEME_ALIASES, PENDING_NODE_STORAGE_KEY, PENDING_NODE_UPDATED_EVENT, and the functions normalizePublicMapThemeSlug, normalizePublicMapThemeSlugs, and localPendingNodeSignature are duplicated between map-node-storage.ts and map-nodes.ts. Remove these duplicated definitions from one of the files and have that file import and re-export them from the other file to maintain a single source of truth, or extract all these shared utilities into a new common internal module that both files can import from. This will eliminate maintenance burden and prevent potential drift between the two implementations.scripts/generate-public-ecoregions.ts (2)
210-212: 💤 Low valueNon-null assertions in sort callback may throw if filter produces unexpected nulls.
The
.filter(Boolean)should remove nulls, but the!assertions are fragile if filter logic changes.Safer alternative using type guard
- .filter(Boolean) - .sort((a, b) => Number(a!.id) - Number(b!.id)); + .filter((r): r is NonNullable<typeof r> => Boolean(r)) + .sort((a, b) => Number(a.id) - Number(b.id));🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/generate-public-ecoregions.ts` around lines 210 - 212, The sort callback is using non-null assertions (the `!` operator on `a!.id` and `b!.id`) after filtering with `.filter(Boolean)`, which is fragile and relies on runtime behavior. Replace the `.filter(Boolean)` call with a more explicit type guard function that properly filters out null or undefined values and narrows the type to ensure the sort callback receives only valid items, eliminating the need for non-null assertions in the comparison logic where you access the id properties.
145-151: ⚡ Quick winConsider adding a timeout to fetch calls for CI reliability.
Long-running or hanging network requests could stall CI pipelines. A fetch timeout guards against upstream service issues.
Add AbortController timeout
-const fetchText = async (url: string): Promise<string> => { - const response = await fetch(url); +const fetchText = async (url: string, timeoutMs = 30_000): Promise<string> => { + const controller = new AbortController(); + const id = setTimeout(() => controller.abort(), timeoutMs); + const response = await fetch(url, { signal: controller.signal }); + clearTimeout(id); if (!response.ok) { throw new Error(`Failed to fetch ${url}: ${response.status}`); } return response.text(); };🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/generate-public-ecoregions.ts` around lines 145 - 151, The fetchText function lacks a timeout mechanism for its fetch call, which could cause the function to hang indefinitely and stall CI pipelines. Add an AbortController to implement a timeout by creating a new AbortController instance, passing its signal to the fetch call in the options parameter, and using setTimeout to call abort() on the controller after a reasonable timeout duration (such as 30 seconds). Update the error handling in the catch block to differentiate between abort errors (from timeout) and other fetch errors so appropriate error messages can be logged.scripts/directus-steward-sync-prep.test.ts (1)
63-135: ⚡ Quick winAdd a dry-run regression test to assert no POST writes.
Current coverage only validates
dryRun: false. A focuseddryRun: truetest would lock in the non-mutating contract.Suggested test addition
+test('prepareChapterUpdateRequests does not POST when dryRun is true', async () => { + const posts: any[] = []; + const client = { + url: 'http://directus.test', + async request(path: string, options: any = {}) { + if (path === '/collections?limit=-1') { + return { data: [{ collection: 'chapters' }, { collection: 'chapter_update_requests' }] }; + } + const url = new URL(path, 'http://directus.test'); + if (url.pathname === '/items/chapters') { + return { + data: [{ slug: 'brasil', name: 'Greenpill Brasil', city: '', country: '', summary: '', primary_link: '', image: '' }], + }; + } + if (url.pathname === '/items/chapter_update_requests' && options.method !== 'POST') { + return { data: [] }; + } + if (url.pathname === '/items/chapter_update_requests' && options.method === 'POST') { + posts.push(options.body); + return { data: { id: 'created-1' } }; + } + throw new Error(`Unexpected request: ${path}`); + }, + }; + + const results = await prepareChapterUpdateRequests( + [{ email: 'one@example.com', kind: 'chapter', slug: 'brasil' }], + { titlePrefix: 'Refresh', dryRun: true }, + client as any + ); + + assert.equal(posts.length, 0); + assert.deepEqual(results.map((result) => result.status), ['dry-run']); +});🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/directus-steward-sync-prep.test.ts` around lines 63 - 135, Add a regression test to validate the dryRun: true behavior. Create a new test case that calls prepareChapterUpdateRequests with dryRun: true instead of false, using the same mocked client and chapter data. Assert that when dryRun is enabled, the posts array remains empty (length equals 0) to confirm that no POST requests were made to the Directus API, thereby locking in the non-mutating contract of the dry-run mode.scripts/directus-steward-sync-prep.ts (1)
197-205: ⚡ Quick winFilter active statuses in the Directus query before reading results.
This currently pulls all requests for a chapter (
limit=-1) and filters statuses in memory. Push the status filter into the query and cap at one row.Suggested change
async function getExistingActiveRequest(client, collection: string, chapterSlug: string) { const params = new URLSearchParams(); params.set('filter[chapter_slug][_eq]', chapterSlug); + params.set('filter[request_status][_in]', ACTIVE_REQUEST_STATUSES.join(',')); params.set('fields', 'id,title,request_status,updated_at'); params.set('sort', '-updated_at'); - params.set('limit', '-1'); + params.set('limit', '1'); const response = await client.request(`/items/${encodeCollection(collection)}?${params.toString()}`); - return (response?.data ?? []).find((request) => ACTIVE_REQUEST_STATUSES.includes(request.request_status)); + return response?.data?.[0] ?? null; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/directus-steward-sync-prep.ts` around lines 197 - 205, In the getExistingActiveRequest function, move the status filtering from client-side to the Directus query by adding the ACTIVE_REQUEST_STATUSES filter to the params URLSearchParams object using the appropriate filter syntax, change the limit parameter from -1 to 1 since only one active request is needed, and simplify the response handling by removing the in-memory find() call since the API will now return only the filtered active request.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
@.plans/active/public-website-design-implementation/handoffs/homepage-live-map-ux-honing-round-2.md:
- Around line 11-13: Replace the machine-specific absolute path in the cd
command with a portable, repository-agnostic alternative. Instead of using
/Users/afo/Code/greenpill/network, use cd "$(git rev-parse --show-toplevel)"
which dynamically resolves to the repository root regardless of the
contributor's local filesystem structure. This ensures the instructions work for
all developers regardless of where they have cloned the repository.
In `@packages/shared/src/map-node-storage.ts`:
- Around line 143-146: The functions removeLocalPendingNode and
reconcileLocalPendingNodes have inconsistent error handling compared to
saveLocalPendingNode. Both functions call storage.setItem() without wrapping it
in a try/catch block, which means they will throw if localStorage is full or
disabled. Add try/catch blocks around the storage.setItem() call in
removeLocalPendingNode (line 144) and the storage.setItem() call in
reconcileLocalPendingNodes (line 188) to match the error handling pattern used
in saveLocalPendingNode, ensuring proper exception handling if storage writes
fail.
In `@packages/website/src/components/shell/SiteFooter.astro`:
- Around line 139-140: Replace all physical text-align values with logical CSS
properties for proper RTL language support. In the `.gp-footer-bottom
span:nth-child(3)` CSS rule and other occurrences mentioned at lines 163-166,
change `text-align: right` to `text-align: end` and any `text-align: left` to
`text-align: start` to ensure proper text alignment for translated RTL layouts.
In `@packages/website/src/pages/index.astro`:
- Around line 373-376: The font-size property in the .gp-home-hero-inner
:global(.gp-home-hero-title) selector uses a hardcoded clamp value instead of
leveraging the tokenized design system from gp-tokens.css. Replace the hardcoded
clamp(40px, calc(30.1px + 2.65vw), 64px) with a reference to an existing display
token (such as a --gp-display-* token), or define a new --gp-* token in
gp-tokens.css if no suitable existing token matches this size requirement, then
reference that token using var() instead of the hardcoded value.
In `@packages/website/src/scripts/webmcp.ts`:
- Around line 102-106: The visibleTypes constant currently includes all legend
rows with the [data-legend-type] attribute regardless of their visibility state.
Add a filter using the isVisible function to the Array.from result before
mapping over the elements, so that only visible legend rows are included in the
visibleTypes array. This ensures the WebMCP summary reflects only the visible
public UI state by filtering out any legend items hidden by responsive behavior
or user-applied filters.
In `@scripts/directus-content-access.ts`:
- Around line 594-621: The updateRequestChildCreatePermissionScope and
updateRequestChildCreateValidation objects at lines 594-621 lack request_status
gating that exists in the read/update/delete permission scopes, allowing editors
to create child rows for requests in non-editable states. Add a request_status
check to both objects (similar to how read/update/delete operations gate on
status) to enforce the same parent request_status validation. This same fix must
also be applied to the duplicate objects mentioned at lines 709-717.
In `@scripts/home-map-live-rehearsal.ts`:
- Around line 41-55: The usage() function is missing documentation for the
--agent-url and --database-url flags that are actually supported by the script,
which should be added to the help text array in the usage() function.
Additionally, the flag parsing logic at the locations where --agent-url and
--database-url values are consumed (around lines 104 and 112) does not validate
that the next token is actually a value and not another flag, causing flags like
--cleanup to be incorrectly consumed as values. Add validation in the argument
parsing to check that the next token does not start with -- before treating it
as a flag value, and add documentation for both --agent-url and --database-url
to the usage string with their descriptions and expected value formats.
---
Nitpick comments:
In `@packages/shared/src/map-node-storage.ts`:
- Around line 32-63: The constants PUBLIC_MAP_THEME_ALIASES,
PENDING_NODE_STORAGE_KEY, PENDING_NODE_UPDATED_EVENT, and the functions
normalizePublicMapThemeSlug, normalizePublicMapThemeSlugs, and
localPendingNodeSignature are duplicated between map-node-storage.ts and
map-nodes.ts. Remove these duplicated definitions from one of the files and have
that file import and re-export them from the other file to maintain a single
source of truth, or extract all these shared utilities into a new common
internal module that both files can import from. This will eliminate maintenance
burden and prevent potential drift between the two implementations.
In `@scripts/directus-steward-sync-prep.test.ts`:
- Around line 63-135: Add a regression test to validate the dryRun: true
behavior. Create a new test case that calls prepareChapterUpdateRequests with
dryRun: true instead of false, using the same mocked client and chapter data.
Assert that when dryRun is enabled, the posts array remains empty (length equals
0) to confirm that no POST requests were made to the Directus API, thereby
locking in the non-mutating contract of the dry-run mode.
In `@scripts/directus-steward-sync-prep.ts`:
- Around line 197-205: In the getExistingActiveRequest function, move the status
filtering from client-side to the Directus query by adding the
ACTIVE_REQUEST_STATUSES filter to the params URLSearchParams object using the
appropriate filter syntax, change the limit parameter from -1 to 1 since only
one active request is needed, and simplify the response handling by removing the
in-memory find() call since the API will now return only the filtered active
request.
In `@scripts/generate-public-ecoregions.ts`:
- Around line 210-212: The sort callback is using non-null assertions (the `!`
operator on `a!.id` and `b!.id`) after filtering with `.filter(Boolean)`, which
is fragile and relies on runtime behavior. Replace the `.filter(Boolean)` call
with a more explicit type guard function that properly filters out null or
undefined values and narrows the type to ensure the sort callback receives only
valid items, eliminating the need for non-null assertions in the comparison
logic where you access the id properties.
- Around line 145-151: The fetchText function lacks a timeout mechanism for its
fetch call, which could cause the function to hang indefinitely and stall CI
pipelines. Add an AbortController to implement a timeout by creating a new
AbortController instance, passing its signal to the fetch call in the options
parameter, and using setTimeout to call abort() on the controller after a
reasonable timeout duration (such as 30 seconds). Update the error handling in
the catch block to differentiate between abort errors (from timeout) and other
fetch errors so appropriate error messages can be logged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 2193efd0-b17d-45c0-8e8b-7c13be967d8f
⛔ Files ignored due to path filters (1)
scripts/data/ui-source-baseline.tsvis excluded by!**/*.tsv
📒 Files selected for processing (59)
.plans/active/public-website-design-implementation/handoffs/homepage-live-map-ux-honing-round-2.md.plans/active/public-website-design-implementation/plan.todo.md.plans/active/public-website-design-implementation/reports/public-map-recovery-2026-05-21.md.plans/active/public-website-design-implementation/spec.md.plans/active/public-website-design-implementation/status.jsonAGENTS.mdCLAUDE.mdREADME.mdpackage.jsonpackages/admin/.dockerignorepackages/admin/Dockerfilepackages/admin/README.mdpackages/admin/STEWARD_GUIDE.mdpackages/admin/STEWARD_SYNC_INVITE.mdpackages/admin/templates/user-invitation.liquidpackages/agent/migrations/015_chapter_update_requests.sqlpackages/agent/migrations/016_chapter_update_request_structured_fields.sqlpackages/agent/migrations/017_map_node_edit_link_delivery_claims.sqlpackages/agent/src/app.tspackages/agent/src/impact.tspackages/agent/src/map-nodes.tspackages/agent/src/server.tspackages/shared/package.jsonpackages/shared/src/index.tspackages/shared/src/map-node-storage.tspackages/shared/src/map-nodes.tspackages/shared/src/map-state.tspackages/shared/src/public-ecoregions.jsonpackages/shared/src/public-ecoregions.tspackages/website/CLAUDE.mdpackages/website/DESIGN.mdpackages/website/astro.config.mjspackages/website/src/components/page-sections/HomeMap.astropackages/website/src/components/shell/SiteFooter.astropackages/website/src/data/world-land-rings.tspackages/website/src/layouts/GpLayout.astropackages/website/src/pages/index.astropackages/website/src/scripts/webmcp.tsscripts/agent-contract.test.tsscripts/check-browser-verification-policy.mjsscripts/dev-website.tsscripts/dev.mjsscripts/directus-content-access.test.tsscripts/directus-content-access.tsscripts/directus-operational-content-setup.tsscripts/directus-steward-smoke.tsscripts/directus-steward-sync-prep.test.tsscripts/directus-steward-sync-prep.tsscripts/directus-studio-setup.test.tsscripts/directus-studio-setup.tsscripts/directus-users.test.tsscripts/generate-public-ecoregions.tsscripts/home-map-browser-smoke.tsscripts/home-map-live-e2e.tsscripts/home-map-live-rehearsal.tsscripts/map-node-contract.test.tsscripts/map-node-edit-link-delivery.tsscripts/run-agent-dev.tsscripts/ui-verify.ts
💤 Files with no reviewable changes (1)
- packages/admin/.dockerignore
📜 Review details
🧰 Additional context used
📓 Path-based instructions (17)
packages/agent/src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Every new public agent route must have an exported route constant, a shared public payload contract in
packages/shared, a public-safe normalizer or assertion, and a focused contract test
Files:
packages/agent/src/impact.tspackages/agent/src/app.tspackages/agent/src/server.tspackages/agent/src/map-nodes.ts
packages/agent/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Every new public agent route must have an exported route constant, a shared public payload contract in packages/shared, a public-safe normalizer or assertion, and a focused contract test
Files:
packages/agent/src/impact.tspackages/agent/src/app.tspackages/agent/src/server.tspackages/agent/src/map-nodes.ts
packages/agent/migrations/**/*.{sql,ts}
📄 CodeRabbit inference engine (AGENTS.md)
Directus may manage
directus_*system tables, roles, permissions, and Data Studio views, but Greenpill-owned schema migrations remain inpackages/agent/migrations
Files:
packages/agent/migrations/017_map_node_edit_link_delivery_claims.sqlpackages/agent/migrations/015_chapter_update_requests.sqlpackages/agent/migrations/016_chapter_update_request_structured_fields.sql
packages/agent/migrations/**
📄 CodeRabbit inference engine (CLAUDE.md)
Directus-owned schema migrations for content, intake, and impact schemas must remain in packages/agent/migrations
Files:
packages/agent/migrations/017_map_node_edit_link_delivery_claims.sqlpackages/agent/migrations/015_chapter_update_requests.sqlpackages/agent/migrations/016_chapter_update_request_structured_fields.sql
{package.json,bun.lockb,bunfig.toml,.npmrc,.yarnrc,.pnpmfile.cjs,.github/workflows/**,AGENTS.md,CLAUDE.md,.codex/**,.claude/**}
📄 CodeRabbit inference engine (CLAUDE.md)
Treat package.json, lockfiles, package-manager config, .github/workflows/, AGENTS.md, CLAUDE.md, .codex/, and .claude/** as security-sensitive surfaces and call out changes in final summaries
Files:
AGENTS.mdpackage.jsonCLAUDE.md
packages/website/src/**/*.{astro,html,css,scss,ts,tsx,js}
📄 CodeRabbit inference engine (AGENTS.md)
Prefer semantic HTML, native controls, platform CSS, and browser primitives before custom JavaScript in website work
Files:
packages/website/src/data/world-land-rings.tspackages/website/src/layouts/GpLayout.astropackages/website/src/scripts/webmcp.tspackages/website/src/components/shell/SiteFooter.astropackages/website/src/pages/index.astro
packages/website/src/**/*.{astro,tsx,ts}
📄 CodeRabbit inference engine (AGENTS.md)
Keep landmarks, headings, links, forms, accessible names, focus states, touch targets, empty/error/loading states, and reduced-motion behavior clear in the rendered DOM and accessibility tree in website work
Files:
packages/website/src/data/world-land-rings.tspackages/website/src/layouts/GpLayout.astropackages/website/src/scripts/webmcp.tspackages/website/src/components/shell/SiteFooter.astropackages/website/src/pages/index.astro
packages/website/src/**/*.{astro,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
packages/website/src/**/*.{astro,ts,tsx,js,jsx}: Prefer semantic HTML, native controls, platform CSS, and browser primitives before custom JavaScript in website code
Keep landmarks, headings, links, forms, accessible names, focus states, touch targets, empty/error/loading states, and reduced-motion behavior clear in the rendered DOM and accessibility tree
Files:
packages/website/src/data/world-land-rings.tspackages/website/src/layouts/GpLayout.astropackages/website/src/scripts/webmcp.tspackages/website/src/components/shell/SiteFooter.astropackages/website/src/pages/index.astro
packages/website/src/**/*.{astro,ts,tsx,js,jsx,css}
📄 CodeRabbit inference engine (CLAUDE.md)
Apply packages/website/DESIGN.md and the website token system for UI changes
Files:
packages/website/src/data/world-land-rings.tspackages/website/src/layouts/GpLayout.astropackages/website/src/scripts/webmcp.tspackages/website/src/components/shell/SiteFooter.astropackages/website/src/pages/index.astro
packages/website/src/**/*.{css,astro,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use design tokens from packages/website/src/styles/gp-tokens.css as the canonical design system
Files:
packages/website/src/data/world-land-rings.tspackages/website/src/layouts/GpLayout.astropackages/website/src/scripts/webmcp.tspackages/website/src/components/shell/SiteFooter.astropackages/website/src/pages/index.astro
packages/website/src/**/*.{css,astro,jsx,tsx}
📄 CodeRabbit inference engine (packages/website/CLAUDE.md)
packages/website/src/**/*.{css,astro,jsx,tsx}: Every color/size/space must use avar(--gp-*)token (or anrgba()/color-mix()of one). Never hardcode hex values. Exception: data-viz colors (e.g.,HomeMaptheme hues) are data, not chrome.
Usevar(--gp-font-display)(Spectral) for display and headlines only;var(--gp-font-body)(Manrope) for all UI and body text;var(--gp-font-mono)(JetBrains Mono) for overlines and technical metadata only. Never use a literal font-family.
Use--gp-primary(lime) as the single primary action per screen. Headlines must use--gp-secondary(gold); body text must use--gp-fg(off-white). Gold is never interactive.
Do not use grey, pure white, or pure black. Use--gp-off-white(#FAF7EE) as the warmest neutral and--gp-green-950as the darkest. Step the green scale (--gp-bg→--gp-surface→--gp-card→--gp-card-elev) for hierarchy before reaching for shadow. Only use chromatic colors: forest green, lime, gold, and terracotta--gp-error.
Ensure contrast meets WCAG 4.5:1 for small/dim text.--gp-fg-dimfails on elevated cards; prefer--gp-fg-mutedfor small metadata.
Use--gp-radius-pillfor buttons, chips, inputs, and avatars. Other radii must match--gp-radius-{sm,md,lg,xl}. Never mix sharp 4px corners with the pill language.
Use fluid type withclamp()tokens for display and headline sizes. Never hardcode font-size or add viewport@mediafor type. Body, label, and overline sizes are fixed.
Responsive layouts must use@containerqueries, not viewport@media. Everything inside#main-content(the page-level container inGpLayout) reflows via@container. A component that must reflow on its own width setscontainer-typeon its root.
Global type scale uses fluidclamp(); touch-target sizing uses@media (pointer: coarse)(device-driven); and top-level full-viewport chrome (sticky site header and footer) uses viewport@media. Do not convert these to@container.
Standalone interac...
Files:
packages/website/src/layouts/GpLayout.astropackages/website/src/components/shell/SiteFooter.astropackages/website/src/pages/index.astro
packages/website/src/**/*.{astro,jsx,tsx}
📄 CodeRabbit inference engine (packages/website/CLAUDE.md)
packages/website/src/**/*.{astro,jsx,tsx}: Every layout must be correct at 375px (mobile) / 1024px (tablet) / 1440px (desktop). Implement the reflow-matrix row for the page. Verify responsive behavior rather than eyeballing it.
Use semantic HTML markup:<button>and<a>elements (never div+onclick);<label for>on every input;cursor:pointeron actionables; one<main>landmark per page; ensure stable layout with no load-time shift.
Files:
packages/website/src/layouts/GpLayout.astropackages/website/src/components/shell/SiteFooter.astropackages/website/src/pages/index.astro
packages/website/src/scripts/webmcp.ts
📄 CodeRabbit inference engine (AGENTS.md)
Keep WebMCP tools visible, page-scoped, and public-safe in
packages/website/src/scripts/webmcp.ts; do not expose Directus private state, database credentials, pending intake, steward notes, hidden admin actions, destructive operations, or background-only actionsKeep WebMCP tools visible, page-scoped, and public-safe; do not expose Directus private state, database credentials, pending intake, steward notes, hidden admin actions, destructive operations, or background-only actions
Files:
packages/website/src/scripts/webmcp.ts
packages/website/src/components/**/*.{astro,jsx,tsx}
📄 CodeRabbit inference engine (packages/website/CLAUDE.md)
Reuse primitives from
src/components/ui/*(Button, Card, Chip, StatusChip, Container, Text, Overline, ArrowLink, Avatar, AvatarStack, EmailInput, RailArrows, SectionHeader, Meta, ImagePlaceholder, LinkRow, CtaStrip) +shell/+page-sections/before writing raw markup. Never re-implement a button/card/chip/input.
Files:
packages/website/src/components/shell/SiteFooter.astro
packages/website/src/components/**/*.astro
📄 CodeRabbit inference engine (packages/website/CLAUDE.md)
New components must be
.astrofiles with a scoped<style>block,gp--prefixed classes, andvar(--gp-*)values only. Template offsrc/components/ui/Button.astro,Card.astro,Chip.astro.
Files:
packages/website/src/components/shell/SiteFooter.astro
packages/agent/src/**/*{intake,map,node}*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Private map/member node intake must never expose emails, raw notes, IP addresses, user agents, spam metadata, steward review notes, pending submissions, or raw upstream EAS/Green Goods work and media feedback
Files:
packages/agent/src/map-nodes.ts
packages/website/src/pages/**/*.{astro,jsx,tsx}
📄 CodeRabbit inference engine (packages/website/CLAUDE.md)
Pages must wrap content in
Container.astroinsideGpLayout.astro, which setsbody.gp-rootand the container context.
Files:
packages/website/src/pages/index.astro
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Keep the default local Codex posture at `sandbox_mode = "workspace-write"` and `approval_policy = "on-request"`
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Keep `approvals_reviewer = "auto_review"` and the `balanced` default permissions profile enabled unless the user explicitly asks to change them
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Do not add project-level `sandbox_mode = "danger-full-access"` or `approval_policy = "never"` overrides unless the user explicitly requests that exception
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Prefer exact trusted project roots over broad home-directory trust entries
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Run installs and validation from the repo root using `bun run` commands
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: When dispatched from a Linear issue, read the issue in full as your spec, plus AGENTS.md and any `.plans/<feature>/` lane it references
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Implement only if the Linear issue gives all of: clear acceptance criteria, a named surface/package (`website`, `agent`, `admin`, `shared`, `workspace`), and validation. If anything is missing, stop and comment on the issue; do not guess.
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Implement only the scoped unit in the smallest package boundary; do not expand past acceptance criteria or make sequencing decisions that belong to the human
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Work on the integration branch named in the Linear issue; PR body must link it (`Closes PRD-NNN` / `Linear: PRD-NNN`). One issue per PR; never self-merge.
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Before the PR, run matching validation: `bun run typecheck`, focused `bun run test:*` for the surface, `bun run agentic:check` for website/UI work, then `bun run build` — produce evidence of passing output/rendered proof, not 'should work'
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Honor the Privacy Boundary: do not expose emails, raw notes, IP addresses, user agents, spam metadata, steward review notes, pending submissions, or raw upstream work and media feedback
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Use `packages/shared` contracts for public/private projections instead of duplicating privacy filters inside the website or agent
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Before UI or CSS work in `packages/website`, load design system sources in order: `packages/website/DESIGN.md`, `packages/website/src/styles/gp-tokens.css`, and relevant primitives in `packages/website/src/components/ui/*`
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Use `bun run ui:check` as the fast static guardrail for source CSS drift in `packages/website`
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Use `bun run ui:verify <route>` when the rendered surface must be proven in-browser in `packages/website`
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Before frontend, UI, CSS, accessibility, browser proof, or web-design changes in `packages/website`, run `bun run agentic:guidance` and apply `packages/website/DESIGN.md` and the website token system
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Run `bun run agentic:check` for hard guidance-readiness and advisory source proof path before website or UI work
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Local agentic browser QA must use the authenticated Brave QA profile; do not fall back to isolated Browser, Playwright, or DevTools MCP profiles for local verification
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: For June website work and MCP/tool selection, use `docs/agentic-mcp-tooling-runbook.md` as the role map before adding tools, changing proof lanes, or expanding WebMCP
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Keep website source and configuration files organized under `packages/website` with specific subdirectories: `src/pages/` for routes, `src/content/` for editorial content, `src/data/` for operational content snapshots, `src/components/ui/` for primitives, and `src/scripts/` for browser interactions
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Maintain editorial and site-composition content in `packages/website/src/content/` with Astro content schema validation in `packages/website/src/content/config.ts`
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Use `packages/website/src/styles/gp-tokens.css` as the canonical source for global design tokens and base styles
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Configure Keystatic in `packages/website/keystatic.config.ts` for local editorial and site-composition content authoring only; Keystatic is not deployed to production
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: The public website remains static; Keystatic is enabled only during local website dev for editorial and site-composition content; there is no deployed Keystatic server or public website database connection
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Operational content for chapters, chapter initiatives, public steward profiles, guilds, guild-owned projects, locations, and impact source bindings is Directus/Postgres-owned after the one-time migration
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Chapter initiatives are chapter-owned local programs, campaigns, events, impact efforts, education series, cleanups, and work; `projects` remain guild-owned tools, products, and workstreams
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: The website consumes the approved public snapshot from `packages/website/src/data/operational-content-snapshot.json` by default, or from `OPERATIONAL_CONTENT_SNAPSHOT_URL` during production builds
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Do not add ad hoc website fetch shapes, public database access, or route-local privacy filters; use shared contracts for public/private projections
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: For local stack proof after `bun run dev`, validate `http://localhost:3302/server/ping`, `http://localhost:3303/ready`, and `http://localhost:3303/content/public-snapshot` before assuming services are connected
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Directus can edit the Greenpill-owned `content`, `intake`, and `impact` schemas only through role-scoped admin access configured by `bun run directus:content:setup`
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: `bun run directus:studio:setup` owns the Data Studio labels, field ordering, interfaces, displays, and hidden technical collections that make the schema usable for stewards
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Directus must not become the public API
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Do not expose `DATABASE_URL` to the public website deploy, Keystatic content, generated JSON, browser bundles, or any future Vercel project
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Do not install or upgrade Bun, Python, or package-manager dependencies unless the user explicitly approves that install in the current task
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Prefer existing repo tooling, checked-in lockfiles, and standard library options over adding new packages
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:14.601Z
Learning: Respond in a manner that is friendly, grounded, realistic, rationale, encouraging, and engaged; keep inner optimism focused on solutions and the path forward
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:26.863Z
Learning: Run `bun run agentic:guidance` before frontend, UI, CSS, accessibility, browser proof, or web-design changes in packages/website
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:26.863Z
Learning: Use packages/shared contracts for public/private projections instead of duplicating privacy filters inside the website or agent
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:26.863Z
Learning: Do not install or upgrade Bun, Python, or package-manager dependencies unless the user explicitly approves that install in the current task
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:26.863Z
Learning: Prefer existing repo tooling, checked-in lockfiles, and standard library options over adding new packages
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:26.863Z
Learning: Do not expose DATABASE_URL to the public website deploy, Keystatic content, generated JSON, browser bundles, or any future Vercel project
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:57.524Z
Learning: Before touching any UI, open `DESIGN.md` including the Modern CSS Standard and the per-page reflow matrix. State the desktop/tablet/mobile behaviour required before writing CSS. Read `src/styles/gp-tokens.css` and inspect relevant `src/components/ui/*` primitives before writing raw markup.
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:57.524Z
Learning: After any UI change, run `bun run ui:check` (static/source-only check) and `bun run ui:verify /your-route` (renders at 375/1024/1440 and checks layout, accessibility, axe-core, CLS, and semantic lint). Read the 375px PNG first. Fix every HARD violation before declaring UI work done.
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:57.524Z
Learning: For local agentic browser QA, use the authenticated Brave QA profile via Codex browser-extension path or Claude Code Chrome/Chromium extension. Do not use isolated Browser, Playwright, or DevTools MCP profiles. If authenticated Brave access is blocked, report QA as blocked.
Learnt from: CR
Repo: greenpill-dev-guild/network
Timestamp: 2026-06-17T11:03:57.524Z
Learning: Runtime WebMCP is approved only for the public read-only pilot in `src/scripts/webmcp.ts`. Keep tools scoped to visible public page/map state and do not expose private Directus data, pending intake, steward notes, edit links, emails, credentials, writes, or background-only actions.
🪛 ast-grep (0.43.0)
packages/agent/src/app.ts
[warning] 282-310: Avoid using unsanitized user input with sendFile
Context: app.post(MAP_NODE_EDIT_LINK_REQUEST_ROUTE, async (context) => {
let input: UnknownRecord = {};
try {
input = await context.req.json() as UnknownRecord;
} catch {
input = {};
}
const email = normalizeOwnerEmail(input?.email);
if (!isValidOwnerEmail(email)) {
return context.json({
error: {
code: 'invalid_email',
message: 'A valid email is required.',
},
}, 400);
}
try {
await mapNodeRepository.requestEditLinkByEmail?.(
email,
getRequestMeta(context)
);
} catch (error) {
reportSanitizedEditLinkError(reportEditLinkError, error);
}
return context.json(MAP_NODE_EDIT_LINK_NEUTRAL_RESPONSE, 202);
})
Note: Security best practice.
(external-filename-upload-typescript)
scripts/map-node-contract.test.ts
[warning] 937-937: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${escaped}\\s*{([\\s\\S]*?)\\n })
Note: [CWE-1333] Inefficient Regular Expression Complexity
(regexp-from-variable)
[warning] 1209-1209: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${escaped}\\s*{([\\s\\S]*?)\\n })
Note: [CWE-1333] Inefficient Regular Expression Complexity
(regexp-from-variable)
🪛 LanguageTool
packages/admin/README.md
[style] ~232-~232: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...un bun run directus:content:setup. 3. Run bun run directus:studio:setup to appl...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
.plans/active/public-website-design-implementation/handoffs/homepage-live-map-ux-honing-round-2.md
[style] ~100-~100: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...that are not in the public map state. - Do not expose emails, raw notes, IP addres...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~105-~105: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... migrations, or Directus permissions. - Do not install new dependencies or upgrade...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~106-~106: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...rade package manager/runtime tooling. - Do not deploy or commit. - Do not replace ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~107-~107: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...e tooling. - Do not deploy or commit. - Do not replace the homepage or the whole H...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~203-~203: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...s from the SSR chapter node template. - Remove ripple circles from client-created subm...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~478-~478: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ... not open the in-flow selected panel. - Desktop selection does not scroll the page. - M...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🔇 Additional comments (63)
packages/agent/migrations/017_map_node_edit_link_delivery_claims.sql (1)
1-14: LGTM!packages/agent/src/impact.ts (1)
11-13: LGTM!packages/agent/src/map-nodes.ts (10)
71-93: LGTM!
126-126: LGTM!
388-398: LGTM!
666-669: LGTM!
740-798: LGTM!
832-871: LGTM!
954-1065: LGTM!
1144-1252: LGTM!
1276-1331: LGTM!
1550-1600: LGTM!packages/agent/src/server.ts (1)
22-71: LGTM!packages/agent/src/app.ts (1)
280-311: LGTM!scripts/map-node-edit-link-delivery.ts (1)
1-13: LGTM!package.json (1)
32-32: LGTM!Also applies to: 59-59
scripts/agent-contract.test.ts (7)
119-150: LGTM!
152-160: LGTM!
734-734: LGTM!Also applies to: 929-929
767-773: LGTM!
1409-1475: LGTM!
1548-1622: LGTM!
1691-1928: LGTM!scripts/generate-public-ecoregions.ts (1)
232-276: LGTM!packages/shared/package.json (1)
27-34: LGTM!packages/shared/src/index.ts (1)
1-5: LGTM!packages/shared/src/map-nodes.ts (3)
1-14: LGTM!Also applies to: 24-25, 130-131, 158-166
202-315: LGTM!
317-349: LGTM!Also applies to: 359-370, 387-421, 449-483
packages/shared/src/map-node-storage.ts (1)
65-96: LGTM!Also applies to: 98-114, 116-132, 148-156, 158-191
packages/shared/src/map-state.ts (4)
1-10: LGTM!Also applies to: 39-40, 62-63, 149-166, 228-228
287-325: LGTM!Also applies to: 327-357
382-390: LGTM!Also applies to: 397-516
518-538: LGTM!Also applies to: 682-727
packages/website/src/data/world-land-rings.ts (1)
1-138: LGTM!packages/website/src/layouts/GpLayout.astro (1)
14-14: LGTM!Also applies to: 26-26, 33-33, 66-66
packages/website/astro.config.mjs (1)
42-46: LGTM!.plans/active/public-website-design-implementation/status.json (1)
313-313: LGTM!Also applies to: 341-341
AGENTS.md (1)
101-101: LGTM!scripts/dev.mjs (1)
13-13: LGTM!Also applies to: 34-34, 44-44, 51-51, 58-58, 207-207, 234-234
scripts/map-node-contract.test.ts (1)
4-24: LGTM!Also applies to: 62-87, 276-290, 332-392, 431-547, 728-813, 821-929, 931-980, 988-1046, 1048-1166, 1174-1201, 1203-1418
scripts/home-map-browser-smoke.ts (1)
51-78: LGTM!Also applies to: 356-387, 446-449, 563-568, 573-628, 639-891, 943-1001, 1002-1170, 1195-1277, 1278-1697
scripts/home-map-live-e2e.ts (1)
9-24: LGTM!Also applies to: 32-46, 56-72, 218-410, 448-547
scripts/home-map-live-rehearsal.ts (1)
136-442: LGTM!.plans/active/public-website-design-implementation/plan.todo.md (1)
71-71: LGTM!.plans/active/public-website-design-implementation/reports/public-map-recovery-2026-05-21.md (1)
24-24: LGTM!.plans/active/public-website-design-implementation/spec.md (1)
74-74: LGTM!scripts/run-agent-dev.ts (1)
10-10: LGTM!Also applies to: 47-56, 70-70
scripts/ui-verify.ts (1)
23-24: LGTM!Also applies to: 50-52, 816-817, 911-911, 933-933
CLAUDE.md (1)
66-69: Excellent clarity on agentic browser QA lanes and dev-surfaces role.Line 66 now clearly separates local authenticated verification (authenticated Brave QA profile via the specific extension paths) from CI/clean-room proof lanes (
agentic:browser-proof,agentic:verify), with an explicit statement that the latter must not be reported as local authenticated verification. The reinforcement ofdev-surfacesas the cross-repo/global doctor for MCP readiness aligns with the learned guidance and prevents confusion about which tools/verification paths are safe for local vs. CI contexts.LGTM!
Source: Learnings
README.md (1)
199-203: Accurate test description aligned with home-map-live-e2e.ts contract.The updated description of
test:home-map:live-e2ecorrectly reflects the test assertions: it verifies people-to-person shared-theme edges, chapter anchors without relationship edges, and no private leakage. This matches the assertions in the actual test code (home-map-live-e2e.ts lines 479–514) exactly.LGTM!
packages/website/CLAUDE.md (1)
33-33: Accurate clarification of motion constraints for map animations.Rule 16 now explicitly forbids "idle or looping animation in the map," which is supported by the HomeMap.astro implementation (selection strands are explicitly idempotent with "no loop" logic). The clarification aligns the guidance with the actual implementation and prevents future deviations.
LGTM!
Source: Coding guidelines
packages/website/DESIGN.md (3)
492-492: Clarified pulse token usage away from infinite map animation.The pulse token (2400ms) is now correctly described as reserved for deliberate loading/status states with reduced-motion support, explicitly forbidding idle map animation. This prevents misuse of the token for background/ambient animations and aligns with the tightened motion constraints throughout the design system.
LGTM!
509-509: Good clarification that page transitions have no motion by default.Adding "Page transitions — none by default. Astro's native page navigation behavior is preserved" to the "Where motion is allowed" section clearly documents the expected behavior and prevents misunderstanding that page-level navigation should be animated.
LGTM!
516-516: Tightened motion constraint for map: no idle/infinite animation; static or one-shot only.The updated rule removes any allowance for infinite/idle loops in the map and requires all animation to be static or one-shot (event-driven). This is supported by HomeMap.astro's explicit "no loop" design in the selection strand rendering and aligns the guidance with implementation reality.
LGTM!
scripts/dev-website.ts (1)
111-111: Minor improvement: switched Astro dev server host from IP to hostname.Changing
--hostfrom127.0.0.1tolocalhostis a minor dev UX improvement that aligns with the PR objective to "uniformly switch from127.0.0.1tolocalhost" and follows conventional practice. Both resolve identically; no breaking changes.LGTM!
scripts/check-browser-verification-policy.mjs (1)
110-110: Strong policy enforcement for authenticated browser QA script prefixes.The stricter validation on line 110 requires
--no-env-fileflag for the policy check itself (preventing env.local pollution), and line 120 enforces the guard prefix (require-authenticated-browser-qa.mjs &&) beforeagentic:browser-proofruns. Both prevent accidental misuse of CI-only verification lanes and enforce the authenticated Brave QA profile requirement at the package.json level.LGTM!
Also applies to: 120-120
Source: Learnings
packages/admin/STEWARD_GUIDE.md (1)
1-197: LGTM!packages/admin/STEWARD_SYNC_INVITE.md (1)
1-48: LGTM!packages/admin/templates/user-invitation.liquid (1)
1-37: LGTM!packages/admin/Dockerfile (1)
3-3: LGTM!packages/admin/README.md (1)
172-180: LGTM!Also applies to: 210-248
scripts/directus-users.test.ts (1)
2-10: LGTM!Also applies to: 66-72
|
@coderabbitai review |
✅ Action performedReview finished.
|
Addressed all seven CodeRabbit threads in 79427f9, resolved the conversations, and CodeRabbit rerun status is passing.
Summary
Validation
bun run test:map-nodesbun run test:agentbun run ui:checkbun run plans:validatebun run build:websitebun run agentic:check