Changelog
What changed and why it matters. Reverse-chronological. Internal refactors, dependency bumps, and lint fixes are intentionally omitted.
2026-05-01 — Posture and operability hardening
- Tests stop hitting third-party APIs by default. The
pytest -qsuite no longer burns Resend, Anthropic, OpenAI, or Stripe quotas on every run. Provider-touching tests are marker-gated and opt-in. lcl-{env}mode hydrates real Secrets Manager values. Running the BE locally against a deployed stage now fetches the same Anthropic, OpenAI, Resend, and invitation-secret values that the deployed Lambda uses, instead of placeholder strings. Fixes a class of silent 404s on token preview / accept paths againstlcl-prd.- Cognito new-password challenge wired through login. Admin-created accounts (
FORCE_CHANGE_PASSWORD) now get a follow-up password-set step instead of throwing a SDK callback error and stranding the user. - Resend sender pinned to a verified domain. The
fromaddress ships in thegf/prd/resendsecret next to the API key; both rotate together. Stops the silent rejection where Resend's sandbox sender refused every recipient except the account owner.
2026-05-01 — AI persona pipeline on its own runtime
- Persona runs moved to a worker Lambda + SQS queue. Long-running rubric pipelines no longer block the API request lifecycle. The dashboard shows progress and the API returns immediately.
- Demo card simplified. Three-step header, larger spacing, nine more personas to sample. Closer to what a first-time visitor needs to evaluate the product in 30 seconds.
- Landing and signed-in copy restructured around the website-feedback loop. The pitch leads with widget feedback paired against AI-persona critique, not with the persona catalog.
2026-05-01 — Auto-fix and resolution evidence
- Annotations carry an
auto_fixflag. Whentrue, the submitter authorised an agent / CI bot / engineering team to apply a change without further discussion. Anonymous submitters always landfalse— the server coerces, regardless of the client. - Stakeholder tokens get an
auto_fix_default. Per-rownever | optional_off | optional_oncontrols whether the toggle renders for that reviewer at all and what state it starts in. - Resolution rows. A new
RESOLUTIONentity records what changed to address an annotation: before/after screenshots, adiff_url, anexplanation. New endpoints under/api/v1/annotations/{id}/resolutions{,/upload-url}. Multiple resolutions per annotation (fix → revert → re-fix) are supported. - Submitter notification. When a resolution lands, the original submitter is notified — Resend email if their address is on file, otherwise a REPLY row appended to the thread that anonymous submitters see when they revisit the page.
- MCP tools extended.
get_resolution_upload_url,attach_resolution, andlist_resolutionsround out the agent's payday loop end to end.
2026-05-01 — Stakeholder reviews without account creation
- Stakeholder identity surfaces in the widget and the dashboard. When the loader resolves a
stk_*token from the embed attribute or?gf_st=URL parameter, the reviewer's name lands on the annotation and shows up in the inbox. - Stakeholder gating lives on the BE. The roster of named reviewers is enforced server-side; unknown or revoked tokens on submit return 400 instead of being silently downgraded to anonymous.
- Owner-only share-link controls. Generating and revoking the public share token is now restricted to the workspace owner; member-level callers see the read-only state.
2026-05-01 — IA and route renames
/widget→/websites→/feedback. The site-owner inbox is now/feedbackeverywhere — left-nav menu, route table, and breadcrumbs. The legacy paths still resolve so existing bookmarks survive.- Owners can rename their workspace from
/team. Was previously an admin-only operation.
2026-04-30 — Private beta gate and access requests
- Signup is now a waitlist.
/signupcollects access requests; agent self-registration atPOST /api/v1/agents/registerreturns 403 with{ "reason": "private_beta" }untilsettings.public_signup_enabledflips. - Branded invite emails. Operator-side
python -m app.cli grant-accessprovisions a tier and emails a Resend invite that lands the invitee on a working/joinflow. - Per-IP signup rate-limit on the agent register route (5/24h) caps abuse without paywalling honest callers.
2026-04-30 — Hero demo, calibrated AI, and abuse defenses
- Hero demo on the homepage.
POST /api/demo/runextracts a URL or ingests pasted text and runs a one-shot Haiku critique. Per-IP daily quota, 24-hour URL-result cache, Cloudflare Turnstile gate, and a demo-scoped WAF rate-limit rule keep the page free of cost runaway. - Vision for image and image-only PDF reviews. Real Claude vision instead of the prior text-only stub.
- Audio and video transcription. OpenAI Whisper API for the first cut;
faster-whisperworker on the roadmap. - Haiku-by-default routing for the agent tier. Auto-promote to Sonnet on low-confidence runs only, which keeps unit economics positive while preserving rubric quality.
2026-04-30 — Persona marketplace (publish-only) and public showcase
- Persona marketplace listing at
/marketplace. Publish, unpublish, and clone endpoints; cloned personas recordclonedFromso the royalty rail can land later without a data migration. - Public showcase pages at
/showcase/{slug}. Opt-in only; admin moderation queue at/admin/showcase; anonymous abuse reporting on the public view. Inbound link to the user's landing page (SEO win for them, viral content for us). - Per-user usage telemetry at
/admin/usage. Pair-data score is computed per user; Top-N tables for reviews, submissions, and ratings drive the future Top-1% comp tier.
2026-04-30 — Agent-discoverable surface
/llms.txt,/llms-full.txt,/mcp.jsonship as cacheable, anonymous, idempotent endpoints. An LLM agent can discover the API and MCP server in three GETs without auth.POST /api/v1/agents/registerwire shape is documented and live behind the private-beta gate. Future contract: a freshgfat_*token, a prepaid wallet, and awallet_topup_urlcome back in one call.gfat_*API tokens with workspace-scoped Bearer auth. Mint via the dashboard or the agent register route; revoke by row id; tokens are clamped at MEMBER role at issuance.- MCP server gains write tools.
patch_annotation,run_personas,acknowledge,reply,resolve— a Claude Code or Cursor session can drive the inbox without leaving the agent surface.
2026-04-30 — Workspaces, invitations, and soft-delete
- Workspace as the unit of access. Routes and services authorise on
workspace_id; user-id ownership is gone. New/teampage for member management;/joinpage accepts an invitation token. - Resend-backed invitations. Invitation tokens are HMAC-signed against
gf/prd/invitation-secret; rotation invalidates outstanding invites and is documented in the runbook. - Soft-delete with a 30-day grace window. A daily sweeper Lambda cascades the deletion after the window expires. API-token callers see 401, session callers see 403, and the FE renders a "restore" banner.
2026-04-30 — Prd cutover
- Single-stage repo.
devandstgwere decommissioned; the project ships fromprdonly. Local development still useslcl(offline JSON store) andlcl-prd(local code, deployed AWS) modes. - GHA-driven CDK + Cloudflare Pages deploy. Push to
prd→ infra, FE, and widget CDN all roll forward in one workflow. bb.mdcarries the prd infra IDs. The DynamoDB table, media bucket, widget CDN, API Gateway, Lambdas, WAF, and Cognito user pool are public; secrets stay inbb.lcl.mdand Secrets Manager.
2026-04-29 — Widget v2 and prd hardening
- Widget merged into a single bundle. Agent and visitor modes share one runtime; the host site picks the default per page via
data-gf-mode. - CDN script tag with content-hashed bundle.
loader.jsreadsdata-*attributes, fetches a manifest, and injects the immutable bundle. Hosts pick up updates on next page load with no redeploy. - Click-with-comment, area select, video reaction, voice memo. The widget captures clicks, text ranges, freeform rectangles, screenshots, and short audio / video reactions, plus the user agent, viewport, and computed styles for the captured element.
- Loader nonce on every write.
POST /api/widget/feedbackandPOST /api/widget/upload-urlrequire anX-GF-Loadernonce minted byGET /api/widget/sites/by-token/{token}. 30-minute TTL; secret rotates via Secrets Manager. - Per-asset payload caps and mime allowlist. Screenshot 2 MB, audio 4 MB, video 8 MB, comment 4 000 chars. Enforced on inline data URLs and on the presigned upload route.
- DDB-backed sliding-window rate limiter replaces the in-memory deque; 30/min/IP and 600/min/site. WAF is the safety net for storage errors.
- AWS WAF in front of API Gateway. Per-IP rate-based rule (2 000/5min on prd) plus the Known-Bad-Inputs managed rule set.
2026-04-28 — Persona catalog and IA polish
- Default persona catalog expanded to 60 across 10 orthogonal lenses. Consumer, domain expert, enterprise buyer, investor, communicator, designer, engineer, skeptic, compliance, educator — six personas each. Edit the catalog by editing markdown files in
data/seeds/personas/; review is a normal PR. - Sidebar nav matches the most-specific entry on activate so deep links light up the right item instead of the parent.