From 4076821f89993bee45cbf16f7a731adcf9574abb Mon Sep 17 00:00:00 2001 From: Geoff Whatley Date: Thu, 3 Sep 2026 02:30:07 +1000 Subject: [PATCH 1/3] feat: ban jsdoc blocks and cap line-comment runs Adopts @zgeoff/oxlint-config 0.1.0, whose zgeoff/no-jsdoc and zgeoff/max-consecutive-line-comments rules replace the prose comment rules in the code-style skill. Deletes every JSDoc block lint covers and cuts every comment run over three lines, keeping only the facts whose cause lives outside the file as line comments. --- .claude/skills/code-style/SKILL.md | 43 ++--- .oxlintrc.json | 7 +- AGENTS.md | 5 +- apps/web-e2e/benchmarks/drag-pan.spec.ts | 52 +----- apps/web-e2e/playwright.bench.config.ts | 5 - apps/web-e2e/playwright.stack.config.ts | 6 - apps/web-e2e/specs/avatar-roster.spec.ts | 5 - apps/web-e2e/specs/avatar-satellite.spec.ts | 5 - apps/web-e2e/specs/canvas-persistence.spec.ts | 5 - .../specs/checkpoint-hash-parity.spec.ts | 5 - apps/web-e2e/specs/home-smoke.spec.ts | 7 - .../specs/production-boot-smoke.spec.ts | 4 - apps/web-e2e/specs/signup-journey.spec.ts | 31 +--- apps/web-e2e/specs/web-locks-fallback.spec.ts | 12 +- apps/web-e2e/src/create-stack-seed.ts | 6 - apps/web-e2e/src/load-e2e-environment.ts | 28 +--- apps/web-e2e/src/serve-mock-services.ts | 12 -- apps/web-e2e/src/serve-resend-stub.ts | 8 +- apps/web-e2e/src/test.ts | 9 - apps/web-e2e/src/wait-for-honeypot-window.ts | 6 - apps/web-e2e/src/wait-for-stable-frames.ts | 28 +--- apps/web/augment-bun-test.ts | 5 - apps/web/reset-zustand-stores.ts | 11 +- apps/web/src/components/auth-layout.tsx | 3 - .../src/components/avatar-switched-notice.tsx | 6 - .../src/components/game-updated-notice.tsx | 8 +- apps/web/src/components/hydration-marker.tsx | 5 - apps/web/src/components/placeholder-grid.tsx | 4 - apps/web/src/components/root-error-screen.tsx | 5 - apps/web/src/components/screen-layout.tsx | 4 - apps/web/src/components/screen-panel.tsx | 3 - .../src/components/step-up-challenge-form.tsx | 5 - .../src/lib/account/get-account-content.tsx | 4 - .../build-activity-rewards-query-options.ts | 4 - .../build-avatar-progression-query-options.ts | 16 -- .../build-current-activity-query-options.ts | 3 - .../activity/build-optimistic-progression.ts | 16 +- .../build-revealed-nodes-query-options.ts | 12 -- .../lib/activity/merge-revealed-rewards.ts | 6 - .../lib/activity/require-active-activity.ts | 5 - apps/web/src/lib/activity/types.ts | 10 -- .../src/lib/activity/use-activity-rewards.ts | 10 -- .../lib/activity/use-is-activity-ingested.ts | 14 -- .../src/lib/auth/build-auth-session-config.ts | 9 - .../src/lib/auth/build-honeypot-valid-from.ts | 8 - .../lib/auth/build-verify-session-config.ts | 6 - apps/web/src/lib/auth/check-honeypot.ts | 6 - apps/web/src/lib/auth/check-step-up.ts | 10 -- .../auth/create-step-up-transaction-token.ts | 20 --- apps/web/src/lib/auth/find-step-up-token.ts | 3 - apps/web/src/lib/auth/get-auth-session.ts | 5 - .../src/lib/auth/get-honeypot-valid-from.ts | 10 +- .../lib/auth/get-login-path-with-redirect.ts | 6 - apps/web/src/lib/auth/get-verify-session.ts | 3 - apps/web/src/lib/auth/honeypot-field-names.ts | 7 - apps/web/src/lib/auth/honeypot-inputs.tsx | 10 -- apps/web/src/lib/auth/read-session-secret.ts | 3 - apps/web/src/lib/auth/remove-auth-session.ts | 3 - apps/web/src/lib/auth/require-anonymous.ts | 3 - apps/web/src/lib/auth/require-auth.ts | 5 - apps/web/src/lib/auth/run-logout.ts | 5 - apps/web/src/lib/auth/run-session-sign-in.ts | 6 - apps/web/src/lib/auth/spam-error.ts | 3 - .../web/src/lib/auth/to-safe-redirect-path.ts | 8 +- apps/web/src/lib/auth/types.ts | 10 -- apps/web/src/lib/auth/update-auth-session.ts | 6 - .../web/src/lib/auth/update-verify-session.ts | 3 - .../src/lib/auth/verify-step-up-handler.ts | 5 - apps/web/src/lib/auth/verify-step-up.ts | 3 - apps/web/src/lib/avatar/find-active-avatar.ts | 5 - .../web/src/lib/avatar/get-avatar-content.tsx | 4 - apps/web/src/lib/avatar/read-avatars.ts | 4 - .../src/lib/avatar/require-active-avatar.ts | 5 - apps/web/src/lib/build-umami-scripts.ts | 6 - apps/web/src/lib/forms/to-field-errors.ts | 4 - apps/web/src/lib/forms/types.ts | 10 -- .../src/lib/forms/use-form-submit.test.tsx | 5 - apps/web/src/lib/forms/use-form-submit.ts | 15 -- .../src/lib/idle/run-ignoring-rejection.ts | 5 - .../lib/idle/send-idle-cache-node-seeds.ts | 5 - apps/web/src/lib/idle/send-idle-initialize.ts | 4 - .../src/lib/idle/send-idle-report-online.ts | 5 - .../src/lib/idle/send-idle-start-activity.ts | 4 - .../src/lib/idle/send-idle-stop-activity.ts | 5 - .../src/lib/idle/use-idle-worker-handle.ts | 6 - .../metrics/record-service-call-failure.ts | 6 - .../lib/metrics/record-service-call-retry.ts | 5 - .../lib/product-events/emit-product-event.ts | 5 - .../product-events/product-event-schema.ts | 5 - .../run-product-event-ingest.ts | 5 - .../lib/product-events/send-product-event.ts | 4 - .../send-stamped-product-event.ts | 9 - apps/web/src/lib/proxy/send-rpc-request.ts | 22 +-- apps/web/src/lib/query/build-query-client.ts | 11 -- .../web/src/lib/query/rsc-query-key-prefix.ts | 7 +- .../lib/query/subscribe-to-query-broadcast.ts | 46 +---- .../src/lib/rpc/build-proxy-service-link.ts | 6 - apps/web/src/lib/rpc/build-service-link.ts | 7 - .../rpc/clients/session-existence-client.ts | 13 +- .../lib/rpc/clients/session-refresh-client.ts | 8 +- .../src/lib/rpc/clients/user-client.test.ts | 9 +- .../src/lib/rpc/create-edge-service-token.ts | 9 - apps/web/src/lib/rpc/load-session-actor.ts | 59 +------ apps/web/src/lib/rpc/make-bounded-fetch.ts | 9 - apps/web/src/lib/rpc/service-dispatcher.ts | 14 +- apps/web/src/lib/rpc/service-urls.ts | 4 - apps/web/src/lib/rpc/types.ts | 19 +-- .../lib/scene/build-scene-transition-types.ts | 7 - .../scene/resolve-scene-state-for-location.ts | 9 +- apps/web/src/lib/send-analytics-event.ts | 10 -- apps/web/src/lib/session/load-current-user.ts | 4 - apps/web/src/lib/session/read-current-user.ts | 8 - apps/web/src/lib/umami-paths.ts | 6 - .../lib/validation/confirm-password-schema.ts | 3 - apps/web/src/mocks/browser.ts | 5 - apps/web/src/mocks/node.ts | 4 - apps/web/src/router.tsx | 3 - .../load-two-factor-setup.ts | 5 - .../two-factor-setup-form.tsx | 4 - .../src/routes/-account-2fa-verify/types.ts | 4 - .../verify-two-factor-setup-handler.ts | 5 - .../verify-two-factor-setup.ts | 3 - .../change-email-form.tsx | 5 - .../-account-change-email/change-email.ts | 3 - .../-account-change-email/run-change-email.ts | 7 - .../src/routes/-account-change-email/types.ts | 5 - .../change-password-form.tsx | 5 - .../change-password.ts | 3 - .../run-change-password.ts | 6 - .../routes/-account-change-password/types.ts | 5 - .../src/routes/-account/account-content.tsx | 3 - .../src/routes/-account/account-screen.tsx | 5 - .../-account/disable-two-factor-auth-form.tsx | 5 - .../-account/disable-two-factor-auth.ts | 3 - .../-account/run-disable-two-factor-auth.ts | 4 - apps/web/src/routes/-account/types.ts | 4 - .../src/routes/-activity/activity-panel.tsx | 12 +- .../routes/-avatar-create/avatar-create.ts | 3 - .../-avatar-create/run-avatar-create.ts | 3 - apps/web/src/routes/-avatar-create/types.ts | 4 - apps/web/src/routes/-avatar/avatar-panel.tsx | 5 - .../src/routes/-avatar/avatar-progression.tsx | 5 - apps/web/src/routes/-avatar/avatar-viewer.tsx | 7 - .../web/src/routes/-avatars/avatar-roster.tsx | 4 - .../routes/-avatars/find-ongoing-run-owner.ts | 11 -- .../src/routes/-avatars/run-avatar-select.ts | 4 - apps/web/src/routes/-avatars/types.ts | 4 - .../activity-rewards-panel.tsx | 8 - .../approaching-cap-warning.tsx | 5 - .../explore-current-panel.test.tsx | 7 +- .../explore-current-panel.tsx | 26 +-- .../-explore-node/explore-node-focus.tsx | 6 - .../web/src/routes/-explore/explore-panel.tsx | 4 - .../-forgot-password/forgot-password.ts | 3 - .../-forgot-password/run-forgot-password.ts | 6 - apps/web/src/routes/-game/ambient-sheet.tsx | 9 - apps/web/src/routes/-game/avatar-chip.tsx | 4 - .../src/routes/-game/game-canvas-mount.tsx | 9 - .../routes/-game/game-simulation-mount.tsx | 16 +- apps/web/src/routes/-game/game-world.tsx | 4 - apps/web/src/routes/-game/nav-rail.tsx | 8 - .../routes/-game/playing-elsewhere-notice.tsx | 6 - apps/web/src/routes/-game/respite-scene.tsx | 4 - apps/web/src/routes/-game/satellite-stack.tsx | 4 - apps/web/src/routes/-game/scene-root.tsx | 3 - .../web/src/routes/-game/scene-state-sync.tsx | 9 +- .../routes/-game/use-avatar-region-graph.ts | 59 +------ .../-game/use-offline-cleared-node-ids.ts | 11 -- .../web/src/routes/-game/use-seed-prefetch.ts | 31 +--- .../src/routes/-game/welcome-back-modal.tsx | 15 -- .../-login-force-logout/force-logout-form.tsx | 3 - .../-login-force-logout/force-logout.ts | 3 - .../require-force-logout-pending.ts | 3 - .../-login-force-logout/run-force-logout.ts | 6 - apps/web/src/routes/-login/login-form.tsx | 3 - apps/web/src/routes/-login/login.ts | 3 - apps/web/src/routes/-login/run-login.ts | 7 - apps/web/src/routes/-login/types.ts | 4 - apps/web/src/routes/-logout/run-logout.ts | 4 - .../-market-listing/market-listing-panel.tsx | 3 - .../routes/-onboarding/onboarding-form.tsx | 3 - apps/web/src/routes/-onboarding/onboarding.ts | 3 - .../-onboarding/require-onboarding-session.ts | 3 - .../src/routes/-onboarding/run-onboarding.ts | 4 - .../require-reset-password-access.ts | 3 - .../-reset-password/reset-password-form.tsx | 3 - .../-reset-password/reset-password-handler.ts | 5 - .../routes/-reset-password/reset-password.ts | 3 - apps/web/src/routes/-signup/run-signup.ts | 6 - apps/web/src/routes/-signup/signup-form.tsx | 3 - apps/web/src/routes/-signup/signup.ts | 3 - apps/web/src/routes/-verify-otp/run-2fa.ts | 4 - .../routes/-verify-otp/run-change-email.ts | 6 - .../src/routes/-verify-otp/run-onboarding.ts | 3 - .../src/routes/-verify-otp/run-unsupported.ts | 4 - .../routes/-verify-otp/run-verification.ts | 5 - apps/web/src/routes/-verify-otp/types.ts | 3 - .../routes/-verify-otp/verify-otp-form.tsx | 3 - .../routes/-verify-otp/verify-otp-handler.ts | 6 - apps/web/src/routes/-verify-otp/verify-otp.ts | 3 - apps/web/src/routes/api/rpc/$service/$.ts | 6 - apps/web/src/routes/health.ts | 3 - apps/web/src/routes/logout.tsx | 4 - .../web/src/routes/reset-password-started.tsx | 3 - apps/web/src/server.ts | 4 - apps/web/src/server/build-csp-header-value.ts | 5 - apps/web/src/server/csp-nonce-header.ts | 8 +- apps/web/src/server/get-client-ip-address.ts | 9 +- apps/web/src/server/make-rate-limiter.ts | 9 - apps/web/src/server/make-request-logger.ts | 16 +- apps/web/src/server/make-secure-headers.ts | 9 - apps/web/src/server/make-umami-proxy.ts | 17 +- apps/web/src/server/middleware.ts | 8 - apps/web/src/server/redirect-to-https.ts | 4 - apps/web/src/server/remove-trailing-slash.ts | 4 - apps/web/src/server/start-sentry-node.ts | 7 +- apps/web/src/server/with-request-trace.ts | 14 -- apps/web/src/start-sentry-react.ts | 5 - apps/web/src/test-utils/build-deferred.ts | 8 +- apps/web/src/test-utils/build-form-data.ts | 3 - .../src/test-utils/create-active-avatar.ts | 5 - .../src/test-utils/create-signed-in-user.ts | 5 - .../test-utils/create-stub-worker-client.ts | 5 - .../src/test-utils/idle-worker-handle-stub.ts | 5 - .../register-avatar-viewer-mock.tsx | 4 - .../test-utils/register-game-canvas-mock.tsx | 5 - .../register-idle-checkpoint-db-reset.ts | 5 - .../register-idle-worker-handle-mock.ts | 6 - .../register-request-context-mock.ts | 7 - .../register-respite-scene-mock.tsx | 4 - ...egister-world-map-node-codex-slot-mock.tsx | 4 - .../register-worldmap-scene-mock.tsx | 9 +- apps/web/src/test-utils/render-hook.tsx | 7 - .../web/src/test-utils/render-with-router.tsx | 19 --- apps/web/src/test-utils/render.tsx | 12 -- .../src/test-utils/request-context-holder.ts | 11 -- .../test-utils/resolve-idle-checkpoint-db.ts | 16 -- .../src/test-utils/set-idle-worker-handle.ts | 5 - .../src/test-utils/with-request-context.ts | 19 --- apps/web/test-setup.ts | 10 +- apps/web/vite.config.ts | 38 ++--- bun.lock | 18 +- bunfig.toml | 3 +- contracts/activity/src/activity-contract.ts | 88 ---------- .../activity/src/activity-data-schema.ts | 18 -- .../src/activity-failure-action-schema.ts | 4 - .../activity/src/activity-status-schema.ts | 6 - ...dvance-checkpoint-invalid-reason-schema.ts | 8 - .../src/build-checkpoint-hash-from-entry.ts | 5 - .../activity/src/build-checkpoint-hash.ts | 6 - ...build-offline-activity-start-submission.ts | 6 - .../activity/src/build-snapshot-schema.ts | 11 -- contracts/activity/src/build-start-hash.ts | 8 - .../src/catch-up-continuation-schema.ts | 9 - .../src/checkpoint-batch-entry-schema.ts | 4 - .../src/checkpoint-invalid-reason-schema.ts | 5 - .../activity/src/checkpoint-payload-schema.ts | 5 - contracts/activity/src/checkpoint-schema.ts | 4 - .../activity/src/content-document-schema.ts | 7 - contracts/activity/src/create-genesis-seed.ts | 7 +- .../activity/src/encounter-content-schema.ts | 5 - .../activity/src/encounter-node-schema.ts | 9 - .../activity/src/entropy-source-schema.ts | 4 - contracts/activity/src/loot-tables-schema.ts | 5 - .../src/max-catch-up-batch-checkpoints.ts | 7 - .../activity/src/max-reveal-batch-nodes.ts | 5 - contracts/activity/src/node-seed-schema.ts | 6 - ...ffline-activity-start-submission-schema.ts | 20 --- .../activity/src/offline-progress-cap-ms.ts | 7 - .../activity/src/reveal-viewport-cell-cap.ts | 6 - .../activity/src/reward-item-affix-schema.ts | 4 - contracts/activity/src/reward-slot-schema.ts | 4 - .../activity/src/scope-identifier-schema.ts | 6 - .../create-mock-catch-up-continuation.ts | 5 - contracts/avatar/src/avatar-contract.ts | 7 - contracts/avatar/src/avatar-data-schema.ts | 3 - contracts/avatar/src/avatar-mode-cap.ts | 4 - contracts/avatar/src/avatar-mode-schema.ts | 3 - contracts/avatar/src/avatar-name-schema.ts | 3 - contracts/avatar/src/avatar-roster-schema.ts | 5 - contracts/base/src/authed-route.ts | 3 - contracts/base/src/define-errors.ts | 5 - contracts/base/src/public-route.ts | 4 - contracts/base/src/standard-errors.ts | 7 - contracts/email/src/email-contract.ts | 8 - .../email/src/email-job-output-schema.ts | 5 - ...-change-email-notification-input-schema.ts | 3 - ...-change-email-verification-input-schema.ts | 4 - .../src/send-existing-account-input-schema.ts | 5 - .../src/send-password-changed-input-schema.ts | 5 - .../email/src/send-welcome-input-schema.ts | 4 - contracts/keys/src/keys-contract.ts | 5 - contracts/keys/src/population-schema.ts | 4 - contracts/keys/src/secret-ref-schema.ts | 3 - .../replay/src/activity-checkpoint-schema.ts | 10 -- contracts/replay/src/activity-input-schema.ts | 4 - contracts/replay/src/attack-data-schema.ts | 3 - contracts/replay/src/avatar-data-schema.ts | 3 - .../replay/src/encounter-definition-schema.ts | 4 - contracts/replay/src/enemy-data-schema.ts | 3 - .../replay/src/equipment-weapon-schema.ts | 3 - contracts/replay/src/replay-contract.ts | 5 - .../replay/src/replay-segment-input-schema.ts | 13 -- .../src/replay-segment-output-schema.ts | 8 - .../create-mock-replay-segment-input.ts | 4 - contracts/replay/src/wake-output-schema.ts | 4 - .../src/pending-transaction-data-schema.ts | 3 - contracts/session/src/secure-action-schema.ts | 3 - contracts/session/src/session-contract.ts | 5 - contracts/session/src/session-data-schema.ts | 3 - .../session/src/session-tokens-schema.ts | 3 - contracts/user/src/name-schema.ts | 3 - contracts/user/src/password-schema.ts | 3 - contracts/user/src/user-contract.ts | 3 - contracts/user/src/user-data-schema.ts | 3 - contracts/user/src/user-email-schema.ts | 3 - contracts/user/src/username-schema.ts | 3 - .../verification/src/verification-contract.ts | 3 - .../src/verification-data-schema.ts | 3 - .../src/verification-type-schema.ts | 3 - deploy.config.ts | 4 - infra/axiom.ts | 68 ++------ infra/github.ts | 36 +--- infra/index.ts | 6 +- infra/neon.ts | 39 +---- libs/core/email/augment-bun-test.ts | 5 - libs/core/email/scripts/preview.ts | 6 - libs/core/email/src/create-email-client.ts | 9 - .../src/mocks/handlers/http/resend-emails.ts | 9 - libs/core/email/src/previews.ts | 6 - libs/core/email/src/render-email.ts | 11 +- libs/core/flags/src/env-flag-provider.ts | 6 - libs/core/flags/src/flags.ts | 4 - libs/core/flags/src/get-flag-client.ts | 4 - libs/core/flags/src/is-flag-key.ts | 3 - libs/core/flags/src/orpc/require-flag.ts | 6 - libs/core/flags/src/resolve-flags.ts | 6 - libs/core/flags/src/to-flag-env-var.ts | 4 - libs/core/flags/src/types.ts | 6 - libs/core/trace/src/build-traceparent.ts | 4 - libs/core/trace/src/create-trace-context.ts | 4 - libs/core/trace/src/parse-traceparent.ts | 4 - libs/core/trace/src/types.ts | 4 - libs/core/utils/src/unreachable-code-error.ts | 6 - .../active-avatar/src/find-active-avatar.ts | 4 - .../src/find-live-activity-avatar.ts | 4 - .../active-avatar/src/upsert-active-avatar.ts | 4 - .../src/create-content-version.ts | 5 - .../src/find-content-document.ts | 5 - .../src/find-current-content-version.test.ts | 7 +- .../src/find-current-content-version.ts | 4 - .../src/make-content-document-loader.ts | 5 - libs/data/db/kysely.config.ts | 6 - .../data/db/migrations/1783000000001_users.ts | 4 - .../db/migrations/1783000000002_sessions.ts | 5 - .../migrations/1783000000003_verifications.ts | 4 - .../1783000000004_step_up_transactions.ts | 5 - .../db/migrations/1783000000005_avatars.ts | 4 - .../1783000000006_sessions_user_id_index.ts | 4 - .../db/migrations/1783774951592_activities.ts | 5 - .../1783841492812_drop_avatar_class.ts | 4 - .../1783900000000_activity_chains.ts | 5 - ...3900000001_activities_start_chain_index.ts | 4 - .../1783900000002_generalize_chain_scope.ts | 5 - .../1783957774984_replay_pipeline.ts | 7 - .../1784026943796_activities_key_version.ts | 4 - .../1784027000000_offline_progress_meter.ts | 9 - .../migrations/1784027000001_sim_versions.ts | 6 - ...784030090542_add_parked_activity_status.ts | 14 +- .../1784108335096_add_avatar_mode.ts | 4 - .../1784109603045_add_avatar_items.ts | 6 - .../db/migrations/1784198842155_releases.ts | 7 - ...1784200000000_activities_encounter_node.ts | 5 - .../1784357566065_avatars_failure_action.ts | 4 - .../1784541880118_activities_start_key.ts | 4 - .../1784643637283_active_avatars.ts | 6 - .../1784715446972_activities_parked_from.ts | 5 - .../1784723149793_activities_settled_xp.ts | 14 -- ...25414770_activities_settled_xp_catch_up.ts | 10 -- ...1784728873775_activity_snapshot_sources.ts | 12 -- ...1784852824301_purge_activity_chain_data.ts | 19 +-- .../1786249778921_activities_scope_secret.ts | 7 - ...2400000_require_activities_scope_secret.ts | 20 +-- .../1786294009362_content_registry.ts | 5 - .../1786328921111_max_content_version.ts | 11 -- .../1786353600000_avatars_world_seed.ts | 23 +-- ...6400000000_activities_predecessor_order.ts | 11 -- libs/data/db/seeds/1783262629921_dev_user.ts | 7 +- libs/data/db/src/apply-migrations.test.ts | 4 - libs/data/db/src/apply-migrations.ts | 10 -- .../src/content-seed/content-document-v1.ts | 3 - .../src/content-seed/content-document-v2.ts | 3 - libs/data/db/src/create-db.ts | 61 ++----- .../test-support/build-advisory-lock-key.ts | 8 +- .../build-test-template-db-name.ts | 10 +- .../test-support/create-cloned-database.ts | 10 +- .../db/src/test-support/create-test-db.ts | 6 - .../src/test-support/create-test-template.ts | 12 +- .../is-test-container-reachable.ts | 5 - .../test-support/is-test-template-db-name.ts | 5 - .../db/src/test-support/normalize-db-part.ts | 6 - .../src/test-support/read-current-branch.ts | 3 - .../require-safe-db-identifier.ts | 8 +- .../test-support/resolve-test-db-target.ts | 11 -- .../test-support/test-template-db-prefix.ts | 5 - libs/data/db/src/to-json.ts | 15 +- libs/data/db/src/types.ts | 8 +- libs/data/db/test-setup.ts | 8 - .../src/find-latest-release.ts | 4 - .../release-registry/src/record-release.ts | 5 - .../src/test-utils/create-release-row.ts | 5 - .../factories/create-mock-release-row.ts | 3 - libs/data/release-registry/src/types.ts | 7 - .../src/find-current-sim-version.ts | 5 - .../data/sim-registry/src/find-sim-version.ts | 4 - .../src/test-utils/create-sim-version-row.ts | 5 - .../factories/create-mock-sim-version-row.ts | 5 - libs/data/sim-registry/src/types.ts | 7 - .../src/update-expired-sim-versions.ts | 4 - .../sim-registry/src/upsert-sim-version.ts | 9 - libs/design/design-system/augment-bun-test.ts | 5 - .../src/components/button/button.tsx | 5 - .../src/components/cast-bar/cast-bar.tsx | 12 -- .../src/components/dialog/dialog.tsx | 14 -- .../components/resource-bar/resource-bar.tsx | 16 -- .../src/components/sheet/sheet.tsx | 10 -- .../src/components/sigil/sigil.tsx | 8 - .../status-button/status-button.stories.tsx | 3 - .../components/status-pill/status-pill.tsx | 7 - .../src/components/tabs/tabs.tsx | 4 - libs/design/design-system/src/scene-colors.ts | 7 +- .../src/bundled-content-version.ts | 5 - libs/game/game-rendering/augment-bun-test.ts | 5 - .../game-rendering/src/create-game-loop.ts | 6 - .../game/game-rendering/src/create-tunnel.tsx | 7 - libs/game/game-rendering/src/game-canvas.tsx | 8 +- .../game-rendering/src/game-loop-driver.tsx | 12 +- .../game-rendering/src/get-scene-state.ts | 4 - .../src/register-game-loop-callback.ts | 5 - .../src/register-renderer-diagnostics.ts | 8 +- .../game-rendering/src/register-satellite.ts | 4 - .../game-rendering/src/remove-satellite.ts | 3 - .../game-rendering/src/resolve-scene-state.ts | 6 - .../game-rendering/src/satellite-host.tsx | 3 - libs/game/game-rendering/src/scene-tunnel.ts | 4 - libs/game/game-rendering/src/to-frameloop.ts | 4 - libs/game/game-rendering/src/use-renderer.ts | 7 - libs/game/game-rendering/src/use-satellite.ts | 5 - .../game-rendering/src/use-scene-state.ts | 5 - libs/game/game-utils/src/build-encounter.ts | 7 - .../game-utils/src/build-state-from-seed.ts | 5 - libs/game/game-utils/src/decode-state.ts | 5 - libs/game/game-utils/src/encode-state.ts | 4 - .../src/roll-encounter-from-stream.ts | 13 -- libs/game/game-utils/src/types.ts | 12 -- libs/game/idle-client/augment-bun-test.ts | 5 - .../src/components/avatar-unit-plate.tsx | 10 -- .../src/components/build-swing-progress.ts | 5 - .../src/components/enemy-unit-plate.tsx | 8 - .../src/components/mission-header.tsx | 4 - .../idle-client/src/components/swing-bar.tsx | 5 - .../src/components/use-swing-charge.ts | 6 - .../content/find-cached-content-document.ts | 5 - .../src/content/load-content-document.ts | 9 - .../content/write-content-document-cache.ts | 3 - libs/game/idle-client/src/mocks/node.ts | 5 - .../src/resync/drain-offline-batches.ts | 27 --- .../src/resync/plan-offline-continuations.ts | 34 +--- .../idle-client/src/resync/plan-resync.ts | 12 -- .../src/resync/run-fast-forward.test.ts | 4 - .../src/resync/run-fast-forward.ts | 24 +-- .../src/resync/run-reconstruction.ts | 13 -- .../idle-client/src/resync/run-resync.test.ts | 5 - .../game/idle-client/src/resync/run-resync.ts | 76 +-------- .../split-continuations-into-batches.ts | 8 - libs/game/idle-client/src/resync/types.ts | 26 --- .../src/state/advance-writer-generation.ts | 5 - .../src/state/create-sync-slice.ts | 17 -- .../src/state/create-worker-slice.ts | 18 -- .../src/state/set-checkpoint-stream-error.ts | 4 - .../state/set-last-completed-activity-id.ts | 4 - .../state/set-last-ingested-activity-id.ts | 5 - .../src/state/set-reward-slot-ledger.ts | 4 - .../src/state/set-simulation-snapshot.ts | 6 - .../src/state/update-reward-slot-ledger.ts | 9 - .../src/state/use-idle-store.test.ts | 6 +- .../submission/build-activity-key-range.ts | 7 +- .../build-checkpoint-batch-entry.ts | 7 - .../src/submission/build-machine-types.ts | 8 +- .../submission/checkpoint-activity-machine.ts | 53 ------ .../checkpoint-submitter-machine.ts | 9 - .../idle-client/src/submission/constants.ts | 70 -------- .../create-activity-service-client.ts | 18 -- .../submission/create-checkpoint-submitter.ts | 157 ------------------ .../src/submission/ingest-activity-start.ts | 48 ------ .../src/submission/read-activity-start.ts | 4 - .../submission/read-all-activity-starts.ts | 4 - .../src/submission/read-cached-node-ids.ts | 5 - .../submission/read-failure-action-cache.ts | 4 - .../submission/read-last-started-activity.ts | 4 - .../src/submission/read-node-seed.ts | 10 -- .../read-offline-cleared-node-ids.ts | 8 - .../submission/read-pending-stop-intent.ts | 3 - .../src/submission/read-queued-checkpoints.ts | 3 - .../src/submission/read-start-stamps.ts | 4 - .../src/submission/remove-activity-start.ts | 5 - .../remove-confirmed-checkpoints.ts | 4 - .../remove-last-started-activity.ts | 4 - .../src/submission/remove-offline-work.ts | 14 -- .../submission/remove-pending-stop-intent.ts | 5 - .../submission/remove-queued-checkpoints.ts | 4 - .../resolve-checkpoint-queue-db.test.ts | 9 +- .../submission/resolve-checkpoint-queue-db.ts | 4 - .../run-checkpoint-flush-attempt.ts | 33 +--- .../submission/subscribe-to-shutdown-abort.ts | 4 - .../src/submission/sweep-stale-checkpoints.ts | 6 - libs/game/idle-client/src/submission/types.ts | 62 ------- .../submission/upgrade-checkpoint-queue-db.ts | 25 --- .../src/submission/write-activity-start.ts | 5 - .../submission/write-failure-action-cache.ts | 3 - .../submission/write-last-started-activity.ts | 5 - .../src/submission/write-node-anchor.ts | 12 -- .../src/submission/write-node-seeds.ts | 9 - .../submission/write-pending-stop-intent.ts | 3 - .../src/submission/write-queued-checkpoint.ts | 4 - .../src/submission/write-start-stamps.ts | 4 - .../src/test-utils/create-fake-web-locks.ts | 16 -- .../src/test-utils/create-fast-clock.ts | 12 -- .../src/test-utils/create-stub-submitter.ts | 4 - .../test-utils/create-stub-worker-context.ts | 12 -- .../src/test-utils/create-test-client.ts | 12 -- .../create-mock-started-checkpoint.ts | 4 - .../make-fail-first-match-handler.ts | 5 - .../idle-client/src/transport/constants.ts | 16 -- .../src/transport/create-broadcast-port.ts | 13 +- .../transport/create-shared-worker-client.ts | 8 +- .../src/transport/create-web-locks-client.ts | 14 +- .../src/transport/create-worker-client.ts | 4 - .../src/transport/is-web-locks-supported.ts | 4 - .../src/transport/pick-transport-kind.ts | 5 - libs/game/idle-client/src/transport/types.ts | 4 - .../use-simulation-transport.test.ts | 9 - .../src/transport/use-simulation-transport.ts | 22 +-- libs/game/idle-client/src/types.ts | 4 - .../idle-client/src/worker/apply-eviction.ts | 6 - .../src/worker/build-activity-start.ts | 43 ----- .../idle-client/src/worker/build-deferred.ts | 5 - .../src/worker/bundled-engine-hash.ts | 4 - .../src/worker/create-worker-demux.ts | 23 +-- .../src/worker/create-worker-router.ts | 3 - .../src/worker/create-worker-runtime.test.ts | 18 +- .../src/worker/create-worker-runtime.ts | 45 +---- .../src/worker/drain-activity-starts.ts | 27 --- .../src/worker/flush-pending-stop.ts | 12 -- .../worker/handle-cache-node-seeds-message.ts | 6 - .../src/worker/handle-disconnect-message.ts | 6 - .../src/worker/handle-initialize-message.ts | 5 - .../worker/handle-report-online-message.ts | 6 - .../handle-set-failure-action-message.test.ts | 4 - .../handle-set-failure-action-message.ts | 8 - .../worker/handle-start-activity-message.ts | 5 - .../worker/handle-stop-activity-message.ts | 6 - .../ingest-and-broadcast-activity-start.ts | 11 -- .../idle-client/src/worker/is-abort-error.ts | 5 - .../src/worker/offline-cap-warning-ms.ts | 4 - .../src/worker/pick-post-terminal-action.ts | 7 - .../worker/register-simulation-listeners.ts | 5 - .../src/worker/report-worker-fault.ts | 6 - .../src/worker/reset-simulation.ts | 6 - .../src/worker/run-continuation.test.ts | 5 - .../src/worker/run-continuation.ts | 25 --- .../src/worker/run-reconnect-recovery.ts | 18 -- .../idle-client/src/worker/run-resync-flow.ts | 80 +-------- .../src/worker/run-resync-turn.test.ts | 25 +-- .../idle-client/src/worker/run-resync-turn.ts | 11 -- .../src/worker/run-simulation.test.ts | 5 - .../idle-client/src/worker/run-simulation.ts | 7 - .../idle-client/src/worker/run-start-flow.ts | 19 +-- .../idle-client/src/worker/sentry-handle.ts | 6 - .../src/worker/simulation-snapshot-schema.ts | 5 - .../src/worker/start-error-reporting.ts | 25 +-- .../src/worker/start-writer-election.ts | 6 - .../src/worker/submit-stop-intent.ts | 4 - libs/game/idle-client/src/worker/types.ts | 111 ------------- .../worker/update-writer-displaced-status.ts | 6 - .../idle-client/src/worker/worker-contract.ts | 13 -- .../worker/worker-lifecycle-machine.test.ts | 9 - .../src/worker/worker-lifecycle-machine.ts | 76 --------- .../worker/worker-to-client-message-schema.ts | 22 --- .../src/core/build-simulation-input.ts | 18 -- .../src/core/create-combat-executor.test.ts | 12 +- .../src/core/create-simulation-driver.ts | 9 - libs/game/idle-core/src/core/run-attempt.ts | 18 -- .../game/idle-core/src/core/run-simulation.ts | 17 -- .../src/core/simulation-timestep-ms.ts | 6 - .../src/core/utils/build-kill-rewards.ts | 7 - .../utils/build-wave-clear-reward-slots.ts | 6 - .../src/core/utils/create-event-sorter.ts | 5 - .../core/utils/create-progress-checkpoint.ts | 7 - .../core/utils/create-started-checkpoint.ts | 3 - .../idle-core/src/core/utils/create-wave.ts | 5 - .../idle-core/src/entities/create-enemy.ts | 9 - .../src/progression/build-completion-xp.ts | 3 - .../src/progression/build-failure-xp-loss.ts | 4 - .../src/progression/build-level-from-xp.ts | 3 - .../src/progression/build-life-from-level.ts | 4 - .../src/progression/build-unsettled-xp.ts | 17 -- .../src/progression/build-xp-threshold.ts | 4 - .../idle-core/src/progression/constants.ts | 21 --- .../src/progression/fold-optimistic-build.ts | 14 -- .../parse-terminal-checkpoint-xp.ts | 6 - libs/game/idle-core/src/replay.bench.ts | 7 - libs/game/idle-core/src/replay.test.ts | 22 --- libs/game/idle-core/src/replay.ts | 9 +- libs/game/idle-core/src/types/activity.ts | 15 -- libs/game/idle-core/src/types/combat.ts | 7 - libs/game/idle-core/src/types/simulation.ts | 18 -- .../src/utils/is-terminal-checkpoint-type.ts | 4 - libs/game/idle-core/src/utils/logger.ts | 4 - libs/game/item-gen/src/build-affix-pool.ts | 4 - .../item-gen/src/build-position-stream.ts | 5 - libs/game/item-gen/src/build-salt-stream.ts | 5 - .../item-gen/src/encode-position-bytes.ts | 9 +- .../item-gen/src/roll-affixes-from-stream.ts | 12 -- .../item-gen/src/roll-item-from-stream.ts | 5 - libs/game/item-gen/src/types.ts | 38 ----- .../game/roll-crypto/src/build-roll-digest.ts | 5 - .../game/roll-crypto/src/build-roll-stream.ts | 7 - .../game/roll-crypto/src/derive-avatar-key.ts | 10 -- .../roll-crypto/src/derive-scope-secret.ts | 10 -- libs/game/roll-crypto/src/types.ts | 10 -- libs/game/worldmap-client/augment-bun-test.ts | 5 - .../src/build-viewport-graph.ts | 17 -- .../src/chunk-stream/build-chunk-key.ts | 4 - .../src/chunk-stream/create-chunk-cache.ts | 24 --- .../src/chunk-stream/parse-chunk-key.ts | 5 - .../src/chunk-stream/resolve-chunk-stream.ts | 33 +--- .../src/chunk-stream/use-chunk-stream.ts | 28 ---- .../components-three/biome-ground.test.tsx | 16 +- .../src/components-three/biome-ground.tsx | 50 ------ .../src/components-three/fog-of-war.test.tsx | 6 +- .../src/components-three/fog-of-war.tsx | 69 +------- .../src/components-three/isometric-camera.tsx | 60 +------ .../src/components-three/perf-probe.tsx | 27 +-- .../src/components-three/scene-tsl.ts | 19 +-- .../use-make-default-camera.ts | 5 - .../src/components-three/viewport-tracker.tsx | 6 - .../components-three/world-map-nodes.test.tsx | 6 +- .../src/components-three/world-map-nodes.tsx | 9 +- .../src/components-ui/node-tooltip.tsx | 4 - libs/game/worldmap-client/src/consts.ts | 18 -- .../src/scatter-build-stats.ts | 8 - .../state/set-completed-node-projections.ts | 6 - .../src/state/set-world-region.ts | 16 -- .../src/state/use-fog-viewport.ts | 5 - .../src/state/use-selected-node.ts | 6 - libs/game/worldmap-client/src/types.ts | 13 -- .../src/utils/build-chunk-aligned-viewport.ts | 8 - .../utils/build-viewport-from-camera.test.ts | 6 +- .../src/utils/build-viewport-from-camera.ts | 11 -- .../game/worldmap-client/src/utils/lru-map.ts | 13 -- .../src/derive-worldmap-content.ts | 11 -- .../src/derive-worldmap-descriptor.ts | 8 - .../game/worldmap-content/src/mocks/server.ts | 5 - .../worldmap-content/src/read-scope-secret.ts | 10 -- .../worldmap-core/src/build-biome-field.ts | 30 +--- .../game/worldmap-core/src/build-cell-node.ts | 6 - libs/game/worldmap-core/src/build-chunk.ts | 4 - .../worldmap-core/src/build-coord-hash.ts | 57 ------- .../src/build-reveal-distance-field.ts | 35 +--- .../worldmap-core/src/build-reveal-sources.ts | 9 - .../worldmap-core/src/build-value-noise.ts | 6 - .../src/can-encode-morton-key.ts | 6 - .../worldmap-core/src/collect-node-edges.ts | 24 --- .../src/collect-revealed-cells.ts | 12 -- .../src/collect-selectable-node-ids.ts | 8 - libs/game/worldmap-core/src/consts.ts | 110 ------------ .../worldmap-core/src/decode-morton-key.ts | 13 -- .../worldmap-core/src/encode-morton-key.ts | 13 -- .../game/worldmap-core/src/find-cell-coord.ts | 7 - .../src/find-edge-neighbour-id.ts | 5 - libs/game/worldmap-core/src/get-biome.ts | 40 +---- libs/game/worldmap-core/src/get-difficulty.ts | 4 - .../worldmap-core/src/get-hex-distance.ts | 4 - libs/game/worldmap-core/src/is-edge-owner.ts | 7 - .../worldmap-core/src/is-node-revealed.ts | 7 - .../worldmap-core/src/is-node-selectable.ts | 9 - .../get-nearest-base-id-by-wide-scan.ts | 6 - libs/game/worldmap-core/src/to-cell-coord.ts | 5 - libs/game/worldmap-core/src/to-chunk-coord.ts | 4 - .../game/worldmap-core/src/to-hex-position.ts | 4 - libs/game/worldmap-core/src/to-node-id.ts | 5 - libs/game/worldmap-core/src/types.ts | 61 ------- libs/service/jobs/src/create-job-queue.ts | 57 +------ libs/service/jobs/src/define-jobs.ts | 5 - libs/service/jobs/src/types.ts | 6 - .../src/encode-product-event-row.ts | 10 -- .../src/make-product-event-sender.ts | 26 +-- .../src/metrics/record-delivery-failure.ts | 6 - .../product-analytics/src/mocks/server.ts | 4 - libs/service/product-analytics/src/types.ts | 12 -- .../src/build-service-audience.ts | 3 - .../service-auth/src/create-service-token.ts | 8 - .../service-auth/src/is-token-issuer.ts | 3 - .../service-auth/src/parse-service-jwks.ts | 6 - .../src/parse-service-private-key.ts | 3 - .../src/parse-service-token.test.ts | 4 - .../service-auth/src/parse-service-token.ts | 10 -- libs/service/service-auth/src/token-claims.ts | 8 - .../service-runtime/src/base-env-schema.ts | 3 - .../service-runtime/src/build-env-contract.ts | 6 - .../service-runtime/src/create-logger.ts | 5 - .../service-runtime/src/create-service.ts | 51 +----- .../src/flush-error-reports.ts | 11 -- .../src/report-unexpected-error.ts | 5 - .../service-runtime/src/sentry-handle.ts | 6 - .../src/set-sentry-handle-for-testing.ts | 6 - .../src/should-trace-request.ts | 12 +- .../src/start-error-reporting.ts | 22 +-- libs/service/service-runtime/src/types.ts | 14 -- .../src/orpc/build-retry-interceptor.ts | 26 --- .../src/orpc/build-tracing-interceptor.ts | 5 - .../src/orpc/make-is-retryable.ts | 7 - .../src/otel/build-log-record.ts | 5 - .../src/otel/build-telemetry-resource.ts | 6 - .../src/otel/create-otlp-log-stream.ts | 6 - .../src/otel/start-metrics-export.ts | 10 +- .../src/otel/start-trace-export.ts | 13 +- .../src/trace/find-span-trace-context.ts | 7 - .../src/trace/find-trace-context.ts | 4 - .../src/trace/get-trace-storage.ts | 13 +- .../service-utils/src/trace/with-root-span.ts | 7 - .../src/trace/with-trace-context.ts | 4 - .../service-utils/src/utils/create-logger.ts | 6 - .../service-utils/src/utils/expand-env.ts | 3 - .../src/orpc/build-contract-mock.test.ts | 3 - .../src/orpc/build-contract-mock.ts | 60 ------- .../src/orpc/build-mock-service.test.ts | 3 - .../src/orpc/build-mock-service.ts | 17 -- .../src/orpc/mocks/server.ts | 4 - .../client-test-utils/src/orpc/rpc-prefix.ts | 3 - .../src/orpc/to-rpc-http-path.ts | 3 - .../src/register-zustand-reset.ts | 15 +- .../src/activity/advance-activity.ts | 39 ----- .../activity/build-activity-mock-handlers.ts | 4 - .../src/activity/get-activity-rewards.ts | 5 - .../src/activity/get-avatar-progression.ts | 13 -- .../activity/get-latest-activity-progress.ts | 5 - .../src/activity/get-revealed-nodes.ts | 6 - .../src/activity/mock-activity-service.ts | 5 - .../src/activity/resolve-encounter-node.ts | 4 - .../src/activity/resume-activity.ts | 4 - .../src/activity/reveal-nodes.ts | 16 -- .../src/activity/track-activity-progress.ts | 13 -- .../src/avatar/build-avatar-mock-handlers.ts | 3 - .../mock-services/src/avatar/create-avatar.ts | 4 - .../src/avatar/find-live-activity-avatar.ts | 4 - .../src/avatar/upsert-active-avatar.ts | 4 - .../src/bun/register-mock-db-reset.ts | 5 - .../src/create-authed-service-client.ts | 5 - .../mock-services/src/create-demo-seed.ts | 5 - .../src/create-test-access-token.ts | 6 - .../mock-services/src/create-viewer.ts | 7 - .../src/db/active-avatar-collection.ts | 4 - .../src/db/activity-collection.ts | 9 - .../mock-services/src/db/avatar-collection.ts | 6 - .../src/db/avatar-item-collection.ts | 6 - .../src/db/checkpoint-collection.ts | 5 - .../src/db/content-document-collection.ts | 11 -- .../src/db/pending-transaction-collection.ts | 5 - .../src/db/product-event-collection.ts | 4 - .../mock-services/src/db/reset-mock-db.ts | 5 - .../src/db/sent-email-collection.ts | 5 - .../src/db/session-collection.ts | 4 - .../db/used-transaction-token-collection.ts | 4 - .../mock-services/src/db/user-collection.ts | 5 - .../src/db/verification-collection.ts | 5 - .../mock-services/src/demo-accounts.ts | 12 -- .../src/email/build-email-mock-handlers.ts | 3 - .../src/keys/build-keys-mock-handlers.ts | 3 - .../src/keys/build-mock-scope-secret.ts | 6 - .../src/keys/derive-avatar-key.ts | 6 - .../src/keys/derive-scope-secret.ts | 4 - .../src/keys/mock-keys-service.ts | 5 - .../src/replay/build-replay-mock-handlers.ts | 3 - .../src/replay/mock-replay-service.ts | 5 - .../src/replay/replay-segment.ts | 5 - libs/testing/mock-services/src/replay/wake.ts | 3 - .../mock-services/src/resolve-service-url.ts | 5 - .../src/resolve-session-context.ts | 9 - .../session/build-session-mock-handlers.ts | 3 - .../src/session/create-session.ts | 7 - .../src/session/delete-session.ts | 5 - .../src/session/refresh-tokens.ts | 4 - .../step-up/consume-pending-transaction.ts | 5 - .../step-up/consume-transaction-token.ts | 5 - .../step-up/create-pending-transaction.ts | 3 - .../step-up/find-live-pending-transaction.ts | 4 - .../session/step-up/record-failed-attempt.ts | 8 - .../src/session/verify-session.ts | 5 - .../tinybird/build-tinybird-mock-handlers.ts | 6 - .../src/user/build-user-mock-handlers.ts | 3 - .../build-verification-mock-handlers.ts | 3 - .../src/verification/create-verification.ts | 5 - .../src/verification/verify-code.ts | 3 - .../composites/create-active-avatar-row.ts | 3 - .../composites/create-activity-chain-row.ts | 5 - .../src/bun/composites/create-activity-row.ts | 3 - .../bun/composites/create-anonymous-viewer.ts | 3 - .../src/bun/composites/create-avatar-row.ts | 4 - .../src/bun/composites/create-viewer.ts | 5 - .../src/bun/create-database-from-template.ts | 3 - .../src/bun/create-service-key-pair.ts | 4 - .../src/bun/create-service-token.ts | 5 - .../src/bun/create-test-db.ts | 5 - .../src/bun/create-test-user.ts | 11 -- .../factories/create-mock-activity-chain.ts | 6 - .../src/bun/factories/create-mock-activity.ts | 5 - .../src/bun/factories/create-mock-avatar.ts | 4 - .../src/bun/factories/create-mock-user.ts | 3 - .../src/bun/get-test-service-key-pair.ts | 4 - .../src/bun/make-test-db.ts | 5 - .../src/bun/setup-bun-test-db.ts | 7 - .../bun/strategies/create-database-test-db.ts | 5 - .../strategies/create-schema-test-db.test.ts | 4 - .../bun/strategies/create-schema-test-db.ts | 27 +-- .../strategies/create-transaction-test-db.ts | 10 -- .../src/bun/test-db-handle.ts | 5 - .../src/bun/test-preload.ts | 8 +- .../src/create-postgres-container.ts | 8 +- .../src/build-rpc-test-client.test.ts | 3 - .../test-utils/src/build-rpc-test-client.ts | 13 -- .../src/bun/create-in-memory-metrics.ts | 22 --- .../test-utils/src/bun/original-env.ts | 3 - .../src/bun/register-bun-test-cleanup.ts | 4 - .../test-utils/src/bun/register-happy-dom.ts | 11 +- .../src/bun/register-msw-lifecycle.ts | 11 -- .../src/bun/remove-env-overrides.ts | 3 - libs/testing/test-utils/src/bun/update-env.ts | 5 - .../src/collect-conformance-cases.test.ts | 9 - .../src/collect-conformance-cases.ts | 51 ------ .../test-utils/src/get-test-jwt-key-pair.ts | 5 - libs/testing/test-utils/src/wait-for.ts | 11 -- package.json | 2 +- scripts/src/bin/check-env-coverage.ts | 1 + scripts/src/bin/deploy.ts | 80 --------- scripts/src/bin/issue-hygiene.ts | 4 - scripts/src/bin/pg-dev-ensure.ts | 6 - scripts/src/bin/pg-mcp-launch.ts | 6 - scripts/src/bin/retrieval-policy.ts | 5 +- scripts/src/bin/write-env-contracts.ts | 4 - .../content/parse-content-document-source.ts | 5 - scripts/src/content/run-content-publish.ts | 4 - scripts/src/deploy/apply-build.ts | 7 - scripts/src/deploy/apply-deploy.ts | 7 - .../src/deploy/apply-ip-posture-actions.ts | 4 - .../src/deploy/apply-machine-sweep-actions.ts | 4 - scripts/src/deploy/apply-retention-actions.ts | 5 - .../deploy/apply-scheduled-machine-actions.ts | 7 +- .../src/deploy/apply-sim-version-actions.ts | 13 +- scripts/src/deploy/build-image-ref.ts | 6 - scripts/src/deploy/build-provider-app-name.ts | 5 - scripts/src/deploy/check-parked-app.ts | 8 - scripts/src/deploy/check-target.ts | 17 -- scripts/src/deploy/find-stale-reason.ts | 11 -- scripts/src/deploy/format-machine-table.ts | 4 - scripts/src/deploy/is-service-machine.ts | 9 +- scripts/src/deploy/load-deploy-manifest.ts | 5 - scripts/src/deploy/load-engine-hash.test.ts | 13 +- scripts/src/deploy/load-engine-hash.ts | 15 +- scripts/src/deploy/parse-app-state.ts | 17 +- scripts/src/deploy/parse-ip-list.ts | 10 +- scripts/src/deploy/plan-ip-posture.ts | 8 - scripts/src/deploy/plan-machine-sweep.ts | 15 -- scripts/src/deploy/plan-retention-actions.ts | 6 - .../deploy/plan-scheduled-machine-actions.ts | 4 - .../src/deploy/plan-sim-version-actions.ts | 19 +-- scripts/src/deploy/read-changes-since.ts | 6 - scripts/src/deploy/read-fleet-image.ts | 7 - scripts/src/deploy/read-fly-env-keys.ts | 4 - scripts/src/deploy/read-fly-secret-names.ts | 4 - scripts/src/deploy/read-provider-app-state.ts | 7 - scripts/src/deploy/read-sim-version-row.ts | 4 - scripts/src/deploy/run-probes.ts | 5 - scripts/src/deploy/types.ts | 41 ----- .../src/deploy/update-parked-activities.ts | 8 - scripts/src/deploy/wait-for-deployed-sha.ts | 6 - scripts/src/docs/collect-doc-paths.ts | 10 -- scripts/src/docs/types.ts | 3 - scripts/src/env/collect-compose-env-keys.ts | 10 -- scripts/src/env/env-file-manifest.ts | 6 - scripts/src/env/find-env-gaps.ts | 4 - scripts/src/env/load-env-contract.ts | 4 - scripts/src/env/load-env-shape.ts | 6 - scripts/src/env/parse-env-keys.ts | 5 - scripts/src/env/parse-notes-plain.ts | 8 +- scripts/src/env/plan-env-writes.ts | 4 - scripts/src/env/read-op-item.ts | 6 +- scripts/src/env/render-env-contract.ts | 5 - scripts/src/env/write-env-file.ts | 7 +- scripts/src/hooks/collect-loaded-skills.ts | 6 - scripts/src/hooks/pick-retrieval-kind.ts | 4 - scripts/src/hooks/plan-retrieval-nudge.ts | 5 - scripts/src/hooks/plan-skill-gate.ts | 9 - scripts/src/hooks/types.ts | 26 --- .../issue-hygiene/build-heading-pattern.ts | 3 - scripts/src/issue-hygiene/check-issue.ts | 14 -- .../src/issue-hygiene/collect-scope-paths.ts | 12 -- .../src/issue-hygiene/find-section-stub.ts | 5 - .../issue-hygiene/render-hygiene-comment.ts | 14 -- scripts/src/issue-hygiene/types.ts | 16 -- scripts/src/postgres/build-dev-db-name.ts | 6 - scripts/src/postgres/build-dev-db-prefix.ts | 6 - scripts/src/postgres/build-dev-dsn.ts | 4 - scripts/src/postgres/create-dev-db.ts | 18 +- scripts/src/postgres/pick-orphaned-dev-dbs.ts | 5 - .../postgres/pick-orphaned-test-templates.ts | 6 - scripts/src/postgres/read-local-branches.ts | 5 - scripts/src/postgres/read-vault-dsn.ts | 5 - scripts/src/postgres/refresh-dev-base.ts | 5 - scripts/src/postgres/render-dbhub-toml.ts | 7 - scripts/src/postgres/sweep-dev-dbs.ts | 3 - scripts/src/postgres/sweep-test-templates.ts | 6 - scripts/src/upkeep/is-trigger-fired.ts | 5 - .../src/upkeep/parse-ignored-advisories.ts | 4 - scripts/src/upkeep/parse-trigger.ts | 4 - scripts/src/utils/require-env-var.ts | 4 - scripts/src/utils/run-flyctl.ts | 5 - .../activity/src/create-activity-service.ts | 15 -- .../find-checkpoint-batch-invalid-reason.ts | 43 +---- services/activity/src/get-optimistic-build.ts | 7 - .../src/handlers/admit-activity-start.ts | 19 --- .../src/handlers/advance-activity.test.ts | 41 +---- .../activity/src/handlers/advance-activity.ts | 107 +----------- .../src/handlers/get-activity-rewards.test.ts | 7 +- .../src/handlers/get-activity-rewards.ts | 11 -- .../handlers/get-avatar-progression.test.ts | 7 +- .../src/handlers/get-avatar-progression.ts | 14 -- .../src/handlers/get-content-document.ts | 7 - .../src/handlers/get-current-activity.test.ts | 6 +- .../src/handlers/get-current-activity.ts | 7 - .../get-latest-activity-progress.test.ts | 7 +- .../handlers/get-latest-activity-progress.ts | 11 -- .../src/handlers/get-revealed-nodes.test.ts | 6 +- .../src/handlers/get-revealed-nodes.ts | 27 --- .../src/handlers/resume-activity.test.ts | 7 +- .../activity/src/handlers/resume-activity.ts | 10 -- .../src/handlers/reveal-nodes.test.ts | 14 +- .../activity/src/handlers/reveal-nodes.ts | 22 --- .../src/handlers/stop-activity.test.ts | 7 +- .../activity/src/handlers/stop-activity.ts | 21 +-- .../activity/src/handlers/to-activity-data.ts | 5 - .../src/handlers/to-checkpoint-data.ts | 5 - .../handlers/track-activity-progress.test.ts | 7 +- .../src/handlers/track-activity-progress.ts | 39 +---- .../update-appended-anchor-from-tail.ts | 9 - .../src/handlers/update-failure-action.ts | 7 - .../src/is-terminal-checkpoint-type.ts | 5 - services/activity/src/is-unique-violation.ts | 3 - .../src/metrics/record-advance-bailout.ts | 6 - .../metrics/record-advance-continuation.ts | 5 - .../record-avatar-not-active-rejection.ts | 5 - .../record-content-incompatible-rejection.ts | 6 - .../src/metrics/record-replay-poke-failed.ts | 5 - .../src/metrics/record-reveal-mint.ts | 4 - .../src/metrics/record-reveal-query.ts | 5 - .../src/metrics/record-reveal-refusal.ts | 7 - .../src/metrics/record-terminal-transition.ts | 5 - .../src/metrics/record-writer-takeover.ts | 5 - services/activity/src/mocks/server.ts | 6 - .../src/pick-checkpoint-batch-race-outcome.ts | 20 --- .../activity/src/require-active-avatar.ts | 13 -- .../activity/src/resolve-encounter-node.ts | 6 - .../activity/src/resolve-sim-version-stamp.ts | 18 -- .../factories/create-mock-activity.ts | 11 -- .../create-mock-catch-up-continuation.ts | 5 - .../factories/create-mock-checkpoint-batch.ts | 26 --- ...-mock-offline-activity-start-submission.ts | 14 -- services/activity/src/types.ts | 42 ----- .../activity/src/wake/make-replay-waker.ts | 19 --- .../src/wake/make-send-replay-wake.ts | 14 -- services/avatar/src/build-router.ts | 3 - services/avatar/src/create-avatar-service.ts | 6 - services/avatar/src/handlers/create-avatar.ts | 16 -- services/avatar/src/handlers/get-avatar.ts | 6 - services/avatar/src/handlers/get-avatars.ts | 8 - services/avatar/src/handlers/remove-avatar.ts | 6 - services/avatar/src/handlers/select-avatar.ts | 15 -- .../avatar/src/handlers/to-avatar-data.ts | 3 - services/avatar/src/handlers/update-avatar.ts | 6 - services/avatar/src/types.ts | 6 - services/email/src/build-router.ts | 10 -- services/email/src/create-email-job-queue.ts | 22 --- services/email/src/create-email-service.ts | 11 -- .../src/metrics/record-delivery-failure.ts | 3 - services/email/src/sweep.ts | 5 +- services/keys/src/build-router.ts | 3 - services/keys/src/create-keys-service.ts | 3 - services/keys/src/env-shape.ts | 4 - .../keys/src/handlers/derive-avatar-key.ts | 7 - .../keys/src/handlers/derive-scope-secret.ts | 7 - .../src/metrics/record-derive-rejection.ts | 4 - services/keys/src/parse-roll-key-roots.ts | 8 - services/keys/src/parse-scope-secret-roots.ts | 8 - services/keys/src/types.ts | 6 - .../src/apply/apply-verified-segment.test.ts | 7 +- .../src/apply/apply-verified-segment.ts | 30 ---- .../src/apply/update-verified-chain-anchor.ts | 5 - services/replay/src/build-provider-router.ts | 5 - services/replay/src/build-router.ts | 5 - services/replay/src/create-replay-provider.ts | 5 - services/replay/src/create-replay-service.ts | 23 --- services/replay/src/dispatch/park-activity.ts | 7 - .../replay/src/dispatch/run-replay-segment.ts | 32 +--- services/replay/src/env-shape.ts | 5 - services/replay/src/get-baked-engine-hash.ts | 9 +- .../replay/src/handlers/replay-segment.ts | 8 - .../src/handlers/run-replay-simulation.ts | 9 - services/replay/src/handlers/wake.ts | 3 - .../src/metrics/record-backlog-claimed.ts | 3 - .../src/metrics/record-clamped-settlement.ts | 7 - .../src/metrics/record-drain-duration.ts | 4 - .../src/metrics/record-iteration-failure.ts | 5 - .../replay/src/metrics/record-rejection.ts | 11 -- .../replay/src/metrics/record-settled-xp.ts | 13 +- .../src/metrics/record-verification-lag.ts | 5 - services/replay/src/metrics/record-wake.ts | 4 - .../replay/src/mint/read-avatar-roll-key.ts | 8 - .../replay/src/mint/roll-reward-items.test.ts | 5 - services/replay/src/mint/roll-reward-items.ts | 7 - services/replay/src/mocks/server.ts | 5 - services/replay/src/provider-env-shape.ts | 6 - .../src/queue/claim-next-seed-chain.test.ts | 7 +- .../replay/src/queue/claim-next-seed-chain.ts | 11 -- .../replay/src/queue/find-replay-target.ts | 6 - .../queue/find-verified-anchor-predecessor.ts | 9 - .../src/queue/update-replay-attempts.ts | 16 -- .../src/replay/build-segment-duration.ts | 11 -- .../src/replay/compare-replay-segment.ts | 48 ------ .../replay/src/replay/create-replay-cache.ts | 25 --- .../src/replay/find-descriptor-divergence.ts | 7 - .../replay/src/replay/find-seed-divergence.ts | 13 -- .../replay/src/replay/is-forward-exited.ts | 6 - .../replay/src/replay/load-replay-segment.ts | 9 - .../replay/to-wire-replay-segment-input.ts | 5 - services/replay/src/replay/types.ts | 51 ------ services/replay/src/serve-provider.ts | 4 - services/replay/src/serve.ts | 10 -- .../src/test-utils/create-activity-row.ts | 4 - .../src/test-utils/create-avatar-row.ts | 5 - .../replay/src/test-utils/create-chain-row.ts | 4 - .../create-honest-activity-fixture.ts | 60 ------- .../src/test-utils/create-provider-process.ts | 10 +- .../create-remote-replay-provider.ts | 5 - .../factories/create-mock-activity-row.ts | 5 - .../factories/create-mock-chain-row.ts | 5 - .../factories/create-mock-encounter-node.ts | 4 - .../factories/create-mock-replay-segment.ts | 7 - .../src/test-utils/find-listening-port.ts | 4 - services/replay/src/types.ts | 24 --- .../replay/src/worker/drain-replay-queue.ts | 11 +- services/replay/src/worker/reject-activity.ts | 12 -- .../src/worker/run-replay-iteration.test.ts | 7 +- .../replay/src/worker/run-replay-iteration.ts | 15 -- .../replay/src/worker/run-replay-target.ts | 60 +------ services/replay/src/worker/types.ts | 26 --- ...update-verified-anchor-from-predecessor.ts | 8 - services/session/src/build-router.ts | 3 - services/session/src/consts.ts | 16 -- services/session/src/create-jwt.ts | 3 - .../session/src/create-session-service.ts | 6 - .../handlers/consume-pending-transaction.ts | 13 -- .../src/handlers/consume-transaction-token.ts | 10 -- .../handlers/create-pending-transaction.ts | 11 -- .../session/src/handlers/create-session.ts | 6 - .../src/handlers/get-pending-transaction.ts | 7 - services/session/src/handlers/get-session.ts | 6 - services/session/src/handlers/get-sessions.ts | 6 - .../src/handlers/record-failed-attempt.ts | 10 -- .../session/src/handlers/refresh-tokens.ts | 12 -- .../session/src/handlers/remove-session.ts | 8 - .../handlers/to-pending-transaction-data.ts | 5 - .../session/src/handlers/to-session-data.ts | 3 - .../session/src/handlers/verify-session.ts | 22 +-- services/session/src/is-deadlock-error.ts | 3 - .../src/metrics/record-failed-attempt.ts | 3 - .../create-pending-transaction-row.ts | 4 - .../src/test-utils/create-session-row.ts | 5 - .../create-mock-pending-transaction.ts | 5 - .../factories/create-mock-session.ts | 4 - services/session/src/types.ts | 9 - services/user/src/build-router.ts | 3 - services/user/src/create-user-service.ts | 6 - services/user/src/handlers/change-password.ts | 6 - .../handlers/create-password-reset-token.ts | 7 - services/user/src/handlers/create-user.ts | 9 - .../user/src/handlers/get-current-user.ts | 6 - services/user/src/handlers/get-user.ts | 6 - services/user/src/handlers/reset-password.ts | 7 - services/user/src/handlers/to-user-data.ts | 3 - services/user/src/handlers/update-email.ts | 19 --- services/user/src/handlers/update-user.ts | 10 -- services/user/src/handlers/verify-password.ts | 13 +- .../user/src/test-utils/create-session-row.ts | 4 - .../src/test-utils/create-verification-row.ts | 5 - .../factories/create-mock-session.ts | 4 - .../factories/create-mock-verification.ts | 3 - services/user/src/types.ts | 9 - services/verification/src/build-router.ts | 3 - .../src/create-verification-service.ts | 6 - .../src/handlers/create-verification.ts | 20 +-- .../src/handlers/get-2fa-verification-uri.ts | 6 - .../src/handlers/get-verification.ts | 6 - .../src/handlers/remove-verification.ts | 6 - .../src/handlers/to-verification-data.ts | 3 - .../src/handlers/update-verification.ts | 6 - .../verification/src/handlers/verify-code.ts | 14 -- .../src/test-utils/create-verification-row.ts | 4 - .../factories/create-mock-verification.ts | 3 - services/verification/src/types.ts | 3 - 1120 files changed, 485 insertions(+), 10393 deletions(-) diff --git a/.claude/skills/code-style/SKILL.md b/.claude/skills/code-style/SKILL.md index 2afb3eafb..a1b8c7176 100644 --- a/.claude/skills/code-style/SKILL.md +++ b/.claude/skills/code-style/SKILL.md @@ -156,34 +156,25 @@ implementing that algorithm — forcing list verbs onto textbook terms hides the ## Comments -Two comment jobs, two locations. A JSDoc block on a declaration carries the caller-facing contract: -what a reader needs to use the thing without opening its body — the guarantee, the invariants a -caller must uphold, the failure modes. A `//` at a statement carries the implementation note: why -that line does the non-obvious thing. A body's mechanism — how the algorithm walks, which step does -what — is never narrated from the top; it lives at the lines, or nowhere when the code already shows -it. - -- Prefer the enforceable form. Before writing a comment, put the fact where a machine holds it: - encode an outcome set as a discriminated union, a bound as a named constant, a caller rule as a - type; protect a frozen wire or draw layout with a golden test. Comment only the residue neither a - type nor a test can hold, and where a test enforces an invariant, point at it rather than - restating the consequence. -- Comment the decision, not the code. A comment states an invariant, cross-file or runtime behavior, - or why a non-obvious choice was made. One that restates the name, the signature, or the next - line's mechanics is a defect — delete it. -- A long JSDoc block is a placement smell, not a prose exercise. When a declaration's comment runs - long because it narrates the body, relocate: the mechanism to `//` at the lines, the enforceable - parts into types or tests, leaving the block at the contract. A genuinely irreducible multi-point - contract stays — render it as structured prose (one point per paragraph, led by its topic - sentence; one fact per sentence; an outcome map or state-to-action table as a bullet list) and - load the `docs-writing` skill for its wording. -- JSDoc blocks are always multi-line (`/**` alone, one `*`-prefixed line per point, `*/` alone — - never single-line `/** … */`), attached directly to the declaration they describe. +Two lint rules own comment shape, and neither has an exception or a baseline marker: +`zgeoff/no-jsdoc` bans every `/** … */` block, and `zgeoff/max-consecutive-line-comments` bans a run +of more than three consecutive `//` lines. A fact a reader needs has a home that stays true: the +code, a type, a named constant, a test whose name states the rule, or the subsystem's doc under +`docs/architecture/`. A comment holds only the residue none of those can hold. + +- Write a `//` comment for one thing: the reason the obvious alternative is wrong, when the cause + lives outside the file. A library quirk, a runtime or platform behavior, a parser or compiler + rule, a production incident. Place it at the line or declaration it explains, three lines at most. +- Never write what the code shows: what a function does, its parameters, its outcomes, an invariant + a test already states, which step does what. An agent derives those from the code, its tests, and + its references; a comment that caches them goes stale. +- A caller-facing contract is a test whose name states it, or a sentence in the subsystem doc. A + design decision is a sentence in the subsystem doc. - Comments describe the code as it is now — no history ("previously", "now uses"), no project state (issue numbers, phase labels, "not wired yet"); those live in the commit message. -- Comments don't name other declarations — renames strand the reference. State the contract instead: - "callers must pass edits sorted last-to-first", not "(buildEditsFromAST's contract)". A - declaration's own parameters and signature types are fine to name. +- Comments don't name other declarations — renames strand the reference. State the fact instead: "an + append from any other session is rejected", not "(see appendCheckpoints)". A declaration's own + parameters and signature types are fine to name. ## Type-only modules diff --git a/.oxlintrc.json b/.oxlintrc.json index b58dd13dd..3a86eb1f4 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -446,10 +446,11 @@ }, { "files": ["**/schema.generated.ts"], - // kysely-codegen column overrides emit inline `import()` type annotations; the file is - // generated, so the style rule has nothing to teach it + // kysely-codegen emits inline `import()` type annotations and a JSDoc header; the file is + // generated, so the style rules have nothing to teach it "rules": { - "typescript/consistent-type-imports": "off" + "typescript/consistent-type-imports": "off", + "zgeoff/no-jsdoc": "off" } }, { diff --git a/AGENTS.md b/AGENTS.md index dd65d6e41..297a62002 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,7 +9,7 @@ read the architecture doc for the subsystem in full before reasoning from its co | ---------------- | ---------------------------------------------------------------------------------------------------------- | | `code-style` | writing, reviewing, or renaming any TypeScript — the function-verb taxonomy lives there | | `testing` | designing, writing, or reviewing tests | -| `docs-writing` | writing or editing any committed prose: `docs/`, READMEs, this file, skills, doc comments | +| `docs-writing` | writing or editing any committed prose: `docs/`, READMEs, this file, skills | | `delivery-lead` | triage, refinement, milestone, board, or "what's next" work — the increment model and the roles live there | | `game-lifecycle` | any work in the activity, replay, or idle packages — the assumptions to drop and the state machines | @@ -341,6 +341,9 @@ the mechanics and provisioning. `// oxlint-disable-next-line -- baseline(#236)`, never turned off in config. The unused-directive check is the ratchet: fixing a baselined site strands its comment, and lint fails until the comment is deleted. +- `zgeoff/no-jsdoc` and `zgeoff/max-consecutive-line-comments` are never baselined and never + disabled inline: a comment the rules reject is deleted or cut, and the fact it held moves to a + test name or the subsystem doc (the `code-style` skill owns the rule for what a comment holds). - `typescript/prefer-readonly-parameter-types` is never baselined: a function's own data/config/props/option types go `readonly` (React props `Readonly`), and framework handles with no readonly form (a `Kysely`/`Elysia`/`RPCHandler`/`Request` handle, a `Date`, …) are diff --git a/apps/web-e2e/benchmarks/drag-pan.spec.ts b/apps/web-e2e/benchmarks/drag-pan.spec.ts index 3eb06a213..4ca137efd 100644 --- a/apps/web-e2e/benchmarks/drag-pan.spec.ts +++ b/apps/web-e2e/benchmarks/drag-pan.spec.ts @@ -2,56 +2,19 @@ import { expect, test } from '../src/test'; import { waitForHoneypotWindow } from '../src/wait-for-honeypot-window'; import { waitForStableFrames } from '../src/wait-for-stable-frames'; -/** - * How many drag legs to walk. Each leg drags 60% of the canvas width in the same direction, so - * travel accumulates leg over leg — enough total ground to cross many chunk boundaries without - * reading the client's internal chunk-size constants, which would couple this black-box benchmark - * to worldmap-client's geometry. Direction never alternates: a there-and-back oscillation would - * revisit the same chunks, and once chunk generation is cached the benchmark would measure cache - * replays instead of the generation cost it exists to track. - */ +// legs never alternate direction: a there-and-back drag revisits chunks whose generation is already +// cached, so the benchmark would measure cache replays instead of the generation cost it tracks const DRAG_LEG_COUNT = 12; - -/** - * Intermediate pointer-move events per leg. Camera-controls reads a drag as a series of pointermove - * deltas, not a single teleport — too few steps understates a real drag's incremental chunk - * crossings. - */ const DRAG_STEPS_PER_LEG = 20; - -/** - * A frame gap past this many milliseconds — more than one missed vsync at 60fps — counts as a - * dropped frame. - */ const DROPPED_FRAME_THRESHOLD_MS = 32; -/** - * The frame-gap sampler's state, parked on the page's own `globalThis` so it survives across the - * two separate `page.evaluate` round trips that start and read it. - */ interface DragPanWindow { __dragPanFrameGaps: Array; __dragPanFrameLoopID: number; } -/** - * Repeatable drag-pan performance probe for the explore map. Reports peak frame gap and - * dropped-frame count for a multi-leg one-way drag across the world map to `console.log` and a - * test annotation; it makes no pass/fail claim about specific numbers, since headless-GPU - * throughput varies by machine. - * - * Excluded from every default run: this config's `testDir` is `./benchmarks`, never scanned by - * `playwright.config.ts`'s `./specs`, so neither `bun run e2e` nor CI ever picks it up. The app - * server serves the prebuilt artifact, so build first, then run on demand: - * - * ```sh - * bun run build --filter=@vers/web - * bun run --cwd apps/web-e2e e2e:bench -- --headed - * ``` - * - * `--headed` is recommended: headless Chromium's software WebGPU path measures compositor - * throughput this benchmark doesn't care about, not the app's own frame cost. - */ +// run with `--headed`: headless Chromium's software WebGPU path measures compositor throughput +// rather than the app's own frame cost test('it drag-pans across the explore map and reports peak frame gap and dropped frames', async ({ page, }) => { @@ -87,10 +50,9 @@ test('it drag-pans across the explore map and reports peak frame gap and dropped const leftX = box.x + box.width * 0.2; const rightX = box.x + box.width * 0.8; - // a throwaway warm-up leg, run before the sampler is installed, so the measured legs below don't - // pay for whatever a drag itself first warms up (pointer-event handler JIT, first-drag camera- - // controls allocations) on top of the scene readiness waitForStableFrames already gated on. Ends - // at rightX, where the first measured leg (below) starts, so no extra jump sits between them. + // a throwaway warm-up leg, run before the sampler is installed, so the measured legs don't pay + // for what a first drag itself warms up (pointer-event handler JIT, first-drag camera-controls + // allocations). Ends at rightX, where the first measured leg starts. await page.mouse.move(leftX, centerY); await page.mouse.down(); await page.mouse.move(rightX, centerY, { steps: DRAG_STEPS_PER_LEG }); diff --git a/apps/web-e2e/playwright.bench.config.ts b/apps/web-e2e/playwright.bench.config.ts index baad56538..6edfb7924 100644 --- a/apps/web-e2e/playwright.bench.config.ts +++ b/apps/web-e2e/playwright.bench.config.ts @@ -6,11 +6,6 @@ import type { E2EOptions } from './src/test'; // measuring the real WebGPU/R3F canvas, not the placeholder const environment = loadE2EEnvironment({}); -/** - * On-demand perf benchmarks: run manually against a real GPU, never picked up by `bun run e2e`'s - * default config. Its own `testDir` keeps every benchmark spec out of `playwright.config.ts`'s - * discovery entirely, so nothing here can ever land on the CI critical path. - */ export default defineConfig({ expect: { timeout: 10 * 1000, diff --git a/apps/web-e2e/playwright.stack.config.ts b/apps/web-e2e/playwright.stack.config.ts index 039df0fd6..6dc1874f9 100644 --- a/apps/web-e2e/playwright.stack.config.ts +++ b/apps/web-e2e/playwright.stack.config.ts @@ -3,12 +3,6 @@ import type { E2EOptions } from './src/test'; const baseURL = process.env['STACK_BASE_URL'] ?? 'http://localhost:3200'; -/** - * The full-stack suite: the whole converged spec set against the real service images the deploy - * pipeline is about to promote, booted by `docker-compose.stack.yml` before playwright runs — no - * webServer entries, the harness owns the stack lifecycle. Specs create their own unique accounts, - * so a retry never replays against state a failed attempt mutated. - */ export default defineConfig({ expect: { timeout: 10 * 1000, diff --git a/apps/web-e2e/specs/avatar-roster.spec.ts b/apps/web-e2e/specs/avatar-roster.spec.ts index eb17c4b9c..fa0ba1f27 100644 --- a/apps/web-e2e/specs/avatar-roster.spec.ts +++ b/apps/web-e2e/specs/avatar-roster.spec.ts @@ -1,11 +1,6 @@ import { expect, test } from '../src/test'; import { waitForHoneypotWindow } from '../src/wait-for-honeypot-window'; -/** - * The multi-avatar journey: create a second avatar from the roster (which auto-selects it), - * switch back to the first, and prove the choice survives a full reload — the selection is - * persisted server-side, not a client artifact. - */ test('it creates a second avatar, switches back, and keeps the choice across a reload', async ({ page, }) => { diff --git a/apps/web-e2e/specs/avatar-satellite.spec.ts b/apps/web-e2e/specs/avatar-satellite.spec.ts index 308a4465f..08c9fee44 100644 --- a/apps/web-e2e/specs/avatar-satellite.spec.ts +++ b/apps/web-e2e/specs/avatar-satellite.spec.ts @@ -1,11 +1,6 @@ import { expect, test } from '../src/test'; import { waitForHoneypotWindow } from '../src/wait-for-honeypot-window'; -/** - * `/avatar` mounts its own satellite canvas alongside the persistent world canvas: two `` - * elements are attached while the panel is up, and navigating away drops back to one as the - * satellite dies with the route (`keepAlive: false`) while the tagged world canvas survives. - */ test('it mounts a second canvas for the avatar satellite and drops it on navigation away', async ({ page, }) => { diff --git a/apps/web-e2e/specs/canvas-persistence.spec.ts b/apps/web-e2e/specs/canvas-persistence.spec.ts index dec621f10..70253b94b 100644 --- a/apps/web-e2e/specs/canvas-persistence.spec.ts +++ b/apps/web-e2e/specs/canvas-persistence.spec.ts @@ -1,11 +1,6 @@ import { expect, test } from '../src/test'; import { waitForHoneypotWindow } from '../src/wait-for-honeypot-window'; -/** - * The `_game` layout mounts its canvas once and never remounts it across child-route navigation: - * a client-side nav to another game route must leave the same `` element in the DOM, - * carrying whatever GPU state it already uploaded. - */ test('it keeps the same canvas element across client-side game navigation', async ({ page }) => { await page.setExtraHTTPHeaders({ 'x-forwarded-for': '127.0.0.1' }); await page.goto('/login'); diff --git a/apps/web-e2e/specs/checkpoint-hash-parity.spec.ts b/apps/web-e2e/specs/checkpoint-hash-parity.spec.ts index 738432586..f1628e20b 100644 --- a/apps/web-e2e/specs/checkpoint-hash-parity.spec.ts +++ b/apps/web-e2e/specs/checkpoint-hash-parity.spec.ts @@ -14,11 +14,6 @@ const CANONICAL_JSON = JSON.stringify([ 'server-key', ]); -/** - * Every party on the checkpoint hash chain — service, verifier, browser client — must derive - * byte-identical digests. This asserts the Node-context contract call and a real browser's - * WebCrypto both derive the frozen digest from the same canonical bytes. - */ test('it derives the same frozen digest from the contract call and from browser WebCrypto', async ({ page, }) => { diff --git a/apps/web-e2e/specs/home-smoke.spec.ts b/apps/web-e2e/specs/home-smoke.spec.ts index 0b757604c..c9d458215 100644 --- a/apps/web-e2e/specs/home-smoke.spec.ts +++ b/apps/web-e2e/specs/home-smoke.spec.ts @@ -1,13 +1,6 @@ import { expect, test } from '../src/test'; import { waitForHoneypotWindow } from '../src/wait-for-honeypot-window'; -/** - * Exercises the home route against a live server, past what `bun test` can drive (it resolves - * package exports without the `react-server` condition, and there's no live request's - * `AsyncLocalStorage` context). The hero's calls to action come from route loader data, so this - * checks both the raw served HTML (200, `text/html`, hero copy and links already present) and the - * hydrated page. - */ test('it serves the home page and renders the signed-out actions', async ({ page, request }) => { const rawResponse = await request.get('/'); diff --git a/apps/web-e2e/specs/production-boot-smoke.spec.ts b/apps/web-e2e/specs/production-boot-smoke.spec.ts index 59671e5e3..084d23470 100644 --- a/apps/web-e2e/specs/production-boot-smoke.spec.ts +++ b/apps/web-e2e/specs/production-boot-smoke.spec.ts @@ -1,9 +1,5 @@ import { expect, test } from '../src/test'; -/** - * Serving proof for the deployable artifact needing no signed-in state and no secrets: the health - * check answers and the anonymous home page renders. - */ test('it serves the production build health check and anonymous home page', async ({ request }) => { const health = await request.get('/health'); diff --git a/apps/web-e2e/specs/signup-journey.spec.ts b/apps/web-e2e/specs/signup-journey.spec.ts index 46f568d14..ac7322f22 100644 --- a/apps/web-e2e/specs/signup-journey.spec.ts +++ b/apps/web-e2e/specs/signup-journey.spec.ts @@ -88,11 +88,6 @@ interface SignUpJourney extends E2EOptions { readonly username: string; } -/** - * Drives the whole account-creation journey — signup, emailed-code verification, onboarding, and - * avatar creation — and lands signed in at `/explore`. Every form submit paces past the artifact's - * real honeypot window first. - */ async function runSignUpIntoGame(page: Page, journey: Readonly): Promise { await page.setExtraHTTPHeaders({ 'x-forwarded-for': '127.0.0.1' }); await page.goto('/signup'); @@ -133,11 +128,8 @@ async function runSignUpIntoGame(page: Page, journey: Readonly): const nameField = page.getByLabel('Name', { exact: true }); // the create-avatar form's client mount replaces the server-rendered markup, so a name typed - // before the swap passes a value assertion yet submits as an empty form — and gating on the - // root hydration marker instead would serialize on the whole game shell, which can take far - // longer than the form needs. So the whole fill-and-submit cycle retries on the navigation - // outcome: an empty submit is rejected server-side without creating anything, which makes the - // retry safe, and the URL guard keeps a slow success from being submitted twice. + // before the swap passes a value assertion yet submits as an empty form. An empty submit is + // rejected server-side without creating anything, so the whole fill-and-submit cycle retries. await expect(async () => { if (new URL(page.url()).pathname !== '/explore') { await nameField.fill(journey.avatarName); @@ -151,11 +143,6 @@ async function runSignUpIntoGame(page: Page, journey: Readonly): }).toPass({ timeout: 20_000 }); } -/** - * Reads the onboarding code from whichever backend the journey signed up against: the mock - * verification service's e2e lookup, or the resend stub that captured the real service-email's - * welcome message. - */ function waitForVerificationCode( options: Readonly, ): Promise { @@ -166,11 +153,6 @@ function waitForVerificationCode( const MockVerificationCodeSchema = z.object({ code: z.string() }); -/** - * Polls the mock backend's test-only verification-code endpoint, which answers 404 until - * `createVerification` has stored a row for the email — the welcome-email send that carries the - * same code is a fire-and-forget queue drain behind the signup response. - */ async function waitForMockVerificationCode( email: string, mockVerificationURL: string | undefined, @@ -203,10 +185,6 @@ async function waitForMockVerificationCode( const CapturedEmailSchema = z.object({ text: z.string() }); const CapturedEmailsSchema = z.object({ emails: z.array(CapturedEmailSchema) }); -/** - * Polls the resend stub's capture endpoint for the welcome email the real service-email handed it - * and pulls the onboarding code out of the verification URL its `code` query param carries. - */ async function waitForStackVerificationCode( email: string, resendStubURL: string | undefined, @@ -237,11 +215,6 @@ async function waitForStackVerificationCode( return code; } -/** - * A globally-unique letters-only avatar name: `AvatarNameSchema` accepts letters only, and the - * real stack's database persists across runs and enforces the same uniqueness the mock backend - * does. - */ function buildAvatarName(): string { const alphabet = 'abcdefghijklmnopqrstuvwxyz'; diff --git a/apps/web-e2e/specs/web-locks-fallback.spec.ts b/apps/web-e2e/specs/web-locks-fallback.spec.ts index 423d1cab5..db3dcd177 100644 --- a/apps/web-e2e/specs/web-locks-fallback.spec.ts +++ b/apps/web-e2e/specs/web-locks-fallback.spec.ts @@ -9,11 +9,7 @@ interface LockProbe { readonly pendingCount: number; } -/** - * Reads the origin's writer-lock state from a page. `navigator.locks.query()` sees locks held by - * the page's dedicated workers, so this is the observable proof of which tab's worker won the - * election. - */ +// `navigator.locks.query()` from the page also reports locks held by the page's dedicated workers function readWriterLock(page: Page, lockName: string): Promise { return page.evaluate(async (name) => { const state = await navigator.locks.query(); @@ -27,12 +23,6 @@ function readWriterLock(page: Page, lockName: string): Promise { }, lockName); } -/** - * The fallback transport for browsers without SharedWorker: every tab spawns a dedicated worker, - * the workers race the writer lock, and closing the writer's tab promotes the next waiter. Real - * tab-death lock release is the one behaviour no in-process test can exercise — this spec is its - * only coverage. - */ test('it elects one writer without SharedWorker and promotes a survivor when the writer tab closes', async ({ context, page, diff --git a/apps/web-e2e/src/create-stack-seed.ts b/apps/web-e2e/src/create-stack-seed.ts index 512026779..0094a6629 100644 --- a/apps/web-e2e/src/create-stack-seed.ts +++ b/apps/web-e2e/src/create-stack-seed.ts @@ -3,12 +3,6 @@ import { createDB } from '@vers/db'; import { DEMO_ACCOUNTS } from '@vers/mock-services'; import invariant from 'tiny-invariant'; -/** - * Seeds the full-stack postgres with the shared demo accounts so a spec's seeded login lands the - * same as it does against the mock backend. Passwords are argon2id-hashed to match the user - * service's own hasher; each account's avatar is a direct row insert, enough for the shell's - * active-avatar gate. Run once against the migrated stack database before playwright. - */ async function createStackSeed(): Promise { const databaseURL = process.env['DATABASE_URL']; diff --git a/apps/web-e2e/src/load-e2e-environment.ts b/apps/web-e2e/src/load-e2e-environment.ts index 1daa3c591..c72ba6e01 100644 --- a/apps/web-e2e/src/load-e2e-environment.ts +++ b/apps/web-e2e/src/load-e2e-environment.ts @@ -18,20 +18,9 @@ interface E2EEnvironment { } interface LoadE2EEnvironmentOptions { - /** - * Extra env keys for the app-web server beyond the shared set — the default config forces the - * placeholder canvas with `FEATURE_GAME_RENDERER: 'false'`; benchmark runs omit it to measure - * the real WebGPU/R3F canvas. - */ readonly appWebEnv?: Readonly>; } -/** - * The environment pieces every playwright config in this package shares: the resolved roots, the - * `.env` load, and the two web servers. Config-specific knobs (testDir, outputDir, timeouts, - * projects) stay in each config file; the server topology lives here once so the configs cannot - * drift apart. - */ export function loadE2EEnvironment(options: Readonly): E2EEnvironment { // resolve the project root without relying on `__dirname`, which is unreliable when a config is // parsed for the task graph rather than run from its own directory @@ -60,10 +49,9 @@ export function loadE2EEnvironment(options: Readonly) projectRoot, webServer: [ { - // the stateful mock backends as real HTTP listeners on the service dev ports the - // artifact's SERVICE_URLS defaults resolve. Never reuse an already-listening server: a - // service answering on these ports could be the real dev stack, and specs must never - // mutate it. + // the stateful mock backends as real HTTP listeners on the service dev ports the artifact's + // SERVICE_URLS defaults resolve. Never reuse an already-listening server: it could be the + // real dev stack, which specs must never mutate. command: 'bun src/serve-mock-services.ts', cwd: projectRoot, reuseExistingServer: false, @@ -75,13 +63,9 @@ export function loadE2EEnvironment(options: Readonly) url: `${process.env['USER_SERVICE_URL'] ?? 'http://localhost:3003'}/health`, }, { - // every spec runs against the deployable artifact, exactly as built — no mock backend - // in-process, no build-time env overrides. Serving it here must not rebuild it: the e2e - // turbo task depends on the app's build task, and any other entrypoint builds first. - // Downstream service calls leave the process over HTTP and land on the mock listeners - // above. Never reuse an already-listening server: whatever answers on this port (a - // leftover vite dev, another app) is not the artifact, and reusing it silently voids the - // production-build guarantee. + // the deployable artifact exactly as built, never rebuilt here: the e2e turbo task depends + // on the app's build task. Never reuse an already-listening server: whatever answers on + // this port is not the artifact, and reusing it voids the production-build guarantee. command: 'node ./server.mjs', cwd: appWebRoot, env: { diff --git a/apps/web-e2e/src/serve-mock-services.ts b/apps/web-e2e/src/serve-mock-services.ts index 2ed7f6d98..520545d42 100644 --- a/apps/web-e2e/src/serve-mock-services.ts +++ b/apps/web-e2e/src/serve-mock-services.ts @@ -13,13 +13,6 @@ import { userRouter } from '@vers/mock-services/user'; import { verificationRouter } from '@vers/mock-services/verification'; import type { ServiceName } from '@vers/service-auth'; -/** - * Serves the stateful mock backends over real HTTP, one listener per service on the same origins - * the production server's `SERVICE_URLS` defaults resolve, so `server.mjs` needs no env - * repointing. The vite-dev mock plugin hosts these same routers in-process; this entrypoint - * exists for runs against the built artifact, which can host no mock backend. Requests - * round-trip oRPC's real wire protocol; a procedure a router doesn't implement 404s. - */ const RPC_HANDLERS: Readonly>> = { activity: new RPCHandler(activityRouter), avatar: new RPCHandler(avatarRouter), @@ -78,11 +71,6 @@ for (const service of SERVICES) { console.log(`mock ${service} listening on ${url.origin}`); } -/** - * Answers the e2e-only lookup a spec polls for the code the mock verification service generated, - * since nothing else observes a mock code once `createVerification` stores it. Responds `{ code }` - * for a stored `(target, type)` row, 404 otherwise — a spec still waiting on delivery. - */ function serveVerificationCode(request: Request): Response { const searchParams = new URL(request.url).searchParams; diff --git a/apps/web-e2e/src/serve-resend-stub.ts b/apps/web-e2e/src/serve-resend-stub.ts index ef81a5618..735fcf053 100644 --- a/apps/web-e2e/src/serve-resend-stub.ts +++ b/apps/web-e2e/src/serve-resend-stub.ts @@ -24,11 +24,9 @@ const emails: Array = []; let nextID = 1; const port = Number(process.env['RESEND_STUB_PORT'] ?? 3020); -// A capture-only stand-in for the Resend HTTP API, for suites running the real service-email -// against a stack that must send no real mail. `POST /emails` accepts a send exactly like the -// Resend endpoint resend-node targets via `RESEND_BASE_URL` and records it in memory; specs pull -// captured sends back with `GET /emails?to=
` to read verification codes out of the -// bodies. State lives for the process lifetime — one stack boot, one mailbox. +// A capture-only stand-in for the Resend HTTP API: `POST /emails` accepts a send exactly like the +// endpoint resend-node targets via `RESEND_BASE_URL` and records it in memory; `GET /emails?to=` +// reads the captured sends back. State lives for the process lifetime. Bun.serve({ fetch: async (request) => { const url = new URL(request.url); diff --git a/apps/web-e2e/src/test.ts b/apps/web-e2e/src/test.ts index f39557482..73feb6e13 100644 --- a/apps/web-e2e/src/test.ts +++ b/apps/web-e2e/src/test.ts @@ -1,20 +1,11 @@ import { test as base } from '@playwright/test'; -/** - * The converged spec set runs against both backends off one directory; each config sets these in - * its `use` block. Only the signup journey reads them — to poll the backend it signed up against - * for the emailed code — so the setup specs' seeded logins ignore them. - */ export interface E2EOptions { readonly codeSource: 'mock' | 'stack'; readonly mockVerificationURL: string | undefined; readonly resendStubURL: string | undefined; } -/** - * The shared `test` with the backend options registered, so every spec imports one configured - * `test`/`expect` pair rather than reaching for the framework's directly. - */ export const test = base.extend({ codeSource: ['mock', { option: true }], mockVerificationURL: [undefined, { option: true }], diff --git a/apps/web-e2e/src/wait-for-honeypot-window.ts b/apps/web-e2e/src/wait-for-honeypot-window.ts index 96b8ca2eb..65ecfd8d7 100644 --- a/apps/web-e2e/src/wait-for-honeypot-window.ts +++ b/apps/web-e2e/src/wait-for-honeypot-window.ts @@ -1,11 +1,5 @@ import type { Page } from '@playwright/test'; -/** - * Waits until the page's honeypot valid-from timestamp has passed, so a form submit isn't flagged - * as bot-speed. The suite runs the production artifact with its real human-speed floor — no - * build-time override — so every spec that submits an auth form must pace itself past the window - * the freshly rendered form declares. - */ export async function waitForHoneypotWindow(page: Page): Promise { const validFrom = await page.locator('input[name="from__confirm"]').inputValue(); diff --git a/apps/web-e2e/src/wait-for-stable-frames.ts b/apps/web-e2e/src/wait-for-stable-frames.ts index 2f5c09999..9c4fa6e8c 100644 --- a/apps/web-e2e/src/wait-for-stable-frames.ts +++ b/apps/web-e2e/src/wait-for-stable-frames.ts @@ -1,34 +1,12 @@ import type { Page } from '@playwright/test'; -/** - * A frame gap under this many milliseconds counts as settled — loose enough that a single fast - * frame during mount doesn't pass it, tight enough that a still-loading scene's own long frames - * keep failing it. - */ const STABLE_FRAME_GAP_THRESHOLD_MS = 20; - -/** - * Consecutive settled frames required before the scene counts as ready. One fast frame can land by - * chance while world data is still loading, a field is still building, or first-frame WebGPU - * pipelines are still compiling; a run of them can't. - */ const STABLE_FRAME_COUNT = 5; - -/** - * How long the gate keeps trying before it fails with an explicit message. A machine whose scene - * never settles (software WebGPU, heavy contention) would otherwise hang the gate silently until - * the whole test times out, hiding which step hung. - */ const STABLE_GATE_BUDGET_MS = 60 * 1000; -/** - * Waits for a live rendering scene to settle into steady frames, rather than proceeding the instant - * its canvas mounts. A persistent canvas is often already visible from the previous route, so a - * `toBeVisible()` check returns before the scene has loaded its data, built its fields, or compiled - * its first-frame WebGPU pipelines — mount-cost frame gaps would otherwise dominate anything the - * caller measures next. Throws with an explicit message if the scene never settles within the gate - * budget, so a stuck scene names itself rather than failing later as an opaque test timeout. - */ +// a persistent canvas is often already visible from the previous route, so a visibility check +// passes before the scene has loaded its data, built its fields, or compiled its first-frame WebGPU +// pipelines export async function waitForStableFrames(page: Page): Promise { const settled = await page.evaluate( ({ budgetMs, stableFrameCount, thresholdMs }) => diff --git a/apps/web/augment-bun-test.ts b/apps/web/augment-bun-test.ts index 4d5e83651..08a0d0b98 100644 --- a/apps/web/augment-bun-test.ts +++ b/apps/web/augment-bun-test.ts @@ -1,10 +1,5 @@ import type { TestingLibraryMatchers } from '@testing-library/jest-dom/matchers'; -/** - * Brings `@testing-library/jest-dom`'s matcher types into `bun:test`'s own `expect`; only the - * types — the runtime matchers are registered separately via `expect.extend` in the preload. - * The jest-extended matcher types come from `@zgeoff/bun-test-extended` via tsconfig `types`. - */ declare module 'bun:test' { // oxlint-disable-next-line typescript/no-empty-interface -- module augmentation, emptiness is the point interface Matchers extends TestingLibraryMatchers {} diff --git a/apps/web/reset-zustand-stores.ts b/apps/web/reset-zustand-stores.ts index 3e2fd2485..b511a2ce8 100644 --- a/apps/web/reset-zustand-stores.ts +++ b/apps/web/reset-zustand-stores.ts @@ -1,11 +1,6 @@ import { registerZustandReset } from '@vers/client-test-utils'; -// its own preload entry, ahead of the main test setup: that file's local `register-*-mock` imports -// (`registerWorldmapSceneMock` among them) transitively import zustand-backed stores, and -// `registerZustandReset` must wrap zustand's `create` before any of those imports run or the -// stores they create are never tracked for reset — a same-file call after those imports is too -// late, since ES module imports are hoisted and evaluate before the importing module's own body. -// Only the wrapper installs this early: the reset itself runs from the teardown hook that also -// unmounts rendered trees, after the unmount, so no still-mounted tree writes the outgoing test's -// state back into the freshly reset stores. +// its own preload entry, ahead of the main test setup: the wrapper must replace zustand's `create` +// before any import that creates a store runs, and ES module imports are hoisted ahead of the +// importing module's own body, so a same-file call after those imports is too late. export const resetZustandStores = registerZustandReset(); diff --git a/apps/web/src/components/auth-layout.tsx b/apps/web/src/components/auth-layout.tsx index 04f1cfbf5..5a8c44c55 100644 --- a/apps/web/src/components/auth-layout.tsx +++ b/apps/web/src/components/auth-layout.tsx @@ -13,9 +13,6 @@ const layout = css({ width: 'full', }); -/** - * The shared frame for pre-auth and account pages: a horizontally centred, width-bounded column. - */ export function AuthLayout(props: Readonly<{ children: ReactNode }>) { return
{props.children}
; } diff --git a/apps/web/src/components/avatar-switched-notice.tsx b/apps/web/src/components/avatar-switched-notice.tsx index 8b01d1536..de6cc87a7 100644 --- a/apps/web/src/components/avatar-switched-notice.tsx +++ b/apps/web/src/components/avatar-switched-notice.tsx @@ -7,12 +7,6 @@ interface AvatarSwitchedNoticeProps { readonly testID?: string; } -/** - * Explains a start or catch-up rejected because the account's active avatar changed, naming the - * new one and offering the one remedy that re-runs every gate against it — a reload. Carries - * `attempts`/`levelUps` tallies when a fallback catch-up already ran for the new avatar before - * this notice rendered, rendering nothing further while they read zero. - */ export function AvatarSwitchedNotice(props: Readonly) { return ( <> diff --git a/apps/web/src/components/game-updated-notice.tsx b/apps/web/src/components/game-updated-notice.tsx index 595f57ff9..cbe00432e 100644 --- a/apps/web/src/components/game-updated-notice.tsx +++ b/apps/web/src/components/game-updated-notice.tsx @@ -4,12 +4,8 @@ interface GameUpdatedNoticeProps { readonly testID?: string; } -/** - * Explains a start rejected because the running build's engine no longer supports the current - * content, offering the one remedy that fetches a build that does — a reload. Deliberately a - * button rather than an automatic reload: a stale service worker or CDN cache can still serve the - * very bundle that failed, and an unconditional reload would loop. - */ +// a button, never an automatic reload: a stale service worker or CDN cache can serve the very +// bundle that failed again, and an unconditional reload would loop export function GameUpdatedNotice(props: Readonly) { return ( <> diff --git a/apps/web/src/components/hydration-marker.tsx b/apps/web/src/components/hydration-marker.tsx index 3b0afbefe..2a7aecf3a 100644 --- a/apps/web/src/components/hydration-marker.tsx +++ b/apps/web/src/components/hydration-marker.tsx @@ -1,10 +1,5 @@ import { useEffect } from 'react'; -/** - * Stamps `data-hydrated` on the root element once React has committed the hydrated tree, i.e. once - * event handlers are live. E2E specs wait for the attribute before driving forms — interacting - * earlier hits server-rendered markup whose submit falls back to a native GET. - */ export function HydrationMarker(): null { useEffect(() => { document.documentElement.dataset['hydrated'] = 'true'; diff --git a/apps/web/src/components/placeholder-grid.tsx b/apps/web/src/components/placeholder-grid.tsx index 7cdae9b22..d1d1681f4 100644 --- a/apps/web/src/components/placeholder-grid.tsx +++ b/apps/web/src/components/placeholder-grid.tsx @@ -14,10 +14,6 @@ const cell = css({ borderWidth: '[1px]', }); -/** - * A grid of empty cells standing in for an item or slot layout. Cells hold a fixed size; the column - * count follows the available width. - */ export function PlaceholderGrid(props: Readonly<{ count: number }>) { return (
diff --git a/apps/web/src/components/root-error-screen.tsx b/apps/web/src/components/root-error-screen.tsx index a95e96c50..b4a696383 100644 --- a/apps/web/src/components/root-error-screen.tsx +++ b/apps/web/src/components/root-error-screen.tsx @@ -4,11 +4,6 @@ import { Button, Heading, Text } from '@vers/design-system'; import { css } from '@vers/styled-system/css'; import { useEffect } from 'react'; -/** - * Root route error boundary: the last-resort screen for a render or loader error nothing below - * caught. Reports the error once on mount — render errors never pass through the query caches, so - * this is their only reporting point. - */ export function RootErrorScreen(props: ErrorComponentProps) { useEffect(() => { Sentry.captureException(props.error); diff --git a/apps/web/src/components/screen-layout.tsx b/apps/web/src/components/screen-layout.tsx index a74cf55e3..b433e9498 100644 --- a/apps/web/src/components/screen-layout.tsx +++ b/apps/web/src/components/screen-layout.tsx @@ -13,10 +13,6 @@ const layout = css({ width: 'full', }); -/** - * The shared frame for a game screen: a titled, padded column that fills its host — the ambient - * sheet for meta screens, the viewport for focus scenes. - */ export function ScreenLayout(props: Readonly<{ children: ReactNode; title: string }>) { return (
diff --git a/apps/web/src/components/screen-panel.tsx b/apps/web/src/components/screen-panel.tsx index 5f3a6c49b..17daf3a67 100644 --- a/apps/web/src/components/screen-panel.tsx +++ b/apps/web/src/components/screen-panel.tsx @@ -19,9 +19,6 @@ const panelLabel = css({ textTransform: 'uppercase', }); -/** - * A labelled section within a screen: the label names the area and children carry its content. - */ export function ScreenPanel(props: Readonly<{ children?: ReactNode; label: string }>) { return (
diff --git a/apps/web/src/components/step-up-challenge-form.tsx b/apps/web/src/components/step-up-challenge-form.tsx index 0d400928a..a4854019a 100644 --- a/apps/web/src/components/step-up-challenge-form.tsx +++ b/apps/web/src/components/step-up-challenge-form.tsx @@ -14,11 +14,6 @@ interface StepUpChallengeFormProps { const formStyles = css({ display: 'flex', flexDirection: 'column', gap: '4' }); -/** - * The step-up gate's inline client island: every 2FA-gated mutation (change email, change - * password, disable 2FA) renders this in place of its own form once its handler reports - * `step-up-required`, and hands the resulting token back to resubmit the original mutation with. - */ export function StepUpChallengeForm(props: StepUpChallengeFormProps) { const verifyStepUpFn = useServerFn(verifyStepUp); const [formError, setFormError] = useState(null); diff --git a/apps/web/src/lib/account/get-account-content.tsx b/apps/web/src/lib/account/get-account-content.tsx index fc68a1244..e92fd8011 100644 --- a/apps/web/src/lib/account/get-account-content.tsx +++ b/apps/web/src/lib/account/get-account-content.tsx @@ -4,10 +4,6 @@ import { AccountContent } from '../../routes/-account/account-content'; import { userClient } from '../rpc/clients/user-client'; import { verificationClient } from '../rpc/clients/verification-client'; -/** - * Runs fresh on every loader pass (no client-side cache layer of its own), so a mutation that - * redirects back to `/account` always lands on current data. - */ export const getAccountContent = createServerFn({ method: 'GET' }).handler(async () => { const user = await userClient.getCurrentUser({}); diff --git a/apps/web/src/lib/activity/build-activity-rewards-query-options.ts b/apps/web/src/lib/activity/build-activity-rewards-query-options.ts index 487410bdf..09ba3c449 100644 --- a/apps/web/src/lib/activity/build-activity-rewards-query-options.ts +++ b/apps/web/src/lib/activity/build-activity-rewards-query-options.ts @@ -1,9 +1,5 @@ import type { OrpcQueryUtils } from '../rpc/orpc'; -/** - * Query options for an activity's revealed reward-slot contents: refetched on a modest interval - * while the panel keeps it mounted, so newly verified rewards surface without a manual refresh. - */ export function buildActivityRewardsQueryOptions(orpc: OrpcQueryUtils, activityID: string) { return orpc.activity.getActivityRewards.queryOptions({ input: { activityID }, diff --git a/apps/web/src/lib/activity/build-avatar-progression-query-options.ts b/apps/web/src/lib/activity/build-avatar-progression-query-options.ts index e1c0923fd..4baff1360 100644 --- a/apps/web/src/lib/activity/build-avatar-progression-query-options.ts +++ b/apps/web/src/lib/activity/build-avatar-progression-query-options.ts @@ -1,30 +1,14 @@ import { orpc } from '../rpc/orpc'; const IDLE_REFETCH_INTERVAL_MS = 10_000; - -/** - * The cadence while an entry is still waiting on the verifier — short enough that a settled total - * lands close behind the run that earned it. - */ const SETTLING_REFETCH_INTERVAL_MS = 2000; -/** - * The one field the refetch cadence reads off a progression response. - */ interface ProgressionRefetchQuery { readonly state: { readonly data?: { readonly pending: ReadonlyArray } | null | undefined; }; } -/** - * Query options for an avatar's settled xp/level plus its pending terminal-but-unsettled xp - * deltas, or `null` when the avatar doesn't exist or isn't owned by the caller. Settlement lands - * server-side with no client signal, so polling is what firms a pending delta up into the settled - * row: the interval tightens while any entry is outstanding and relaxes once none is. A run in - * flight needs no tightening of its own — its live overlay and the settled total that overlay nets - * against advance together, so the figure on screen holds steady however far behind the read lags. - */ export function buildAvatarProgressionQueryOptions(avatarID: string) { return { ...orpc.activity.getAvatarProgression.queryOptions({ input: { avatarID } }), diff --git a/apps/web/src/lib/activity/build-current-activity-query-options.ts b/apps/web/src/lib/activity/build-current-activity-query-options.ts index 14de4f035..3f1fb2fea 100644 --- a/apps/web/src/lib/activity/build-current-activity-query-options.ts +++ b/apps/web/src/lib/activity/build-current-activity-query-options.ts @@ -1,8 +1,5 @@ import { orpc } from '../rpc/orpc'; -/** - * An avatar's current activity row, or `null` when none is active. - */ export function buildCurrentActivityQueryOptions(avatarID: string) { return orpc.activity.getCurrentActivity.queryOptions({ input: { avatarID } }); } diff --git a/apps/web/src/lib/activity/build-optimistic-progression.ts b/apps/web/src/lib/activity/build-optimistic-progression.ts index e9d6238c1..adcbf5e28 100644 --- a/apps/web/src/lib/activity/build-optimistic-progression.ts +++ b/apps/web/src/lib/activity/build-optimistic-progression.ts @@ -28,20 +28,11 @@ interface BuildOptimisticProgressionInput { } interface OptimisticProgression { - /** - * Whether the displayed total carries anything not yet on the settled row: a pending entry, a - * live sim overlay, or both. A screen renders its settling marker exactly when this is true. - */ readonly isSettling: boolean; readonly level: number; readonly xp: number; } -/** - * Derives the level/xp a screen renders from the settled progression read: the settled total plus - * every pending entry's delta, plus a live-sim overlay, net of whatever the settled total already - * carries for that run. - */ export function buildOptimisticProgression( input: Readonly, ): OptimisticProgression { @@ -56,10 +47,9 @@ export function buildOptimisticProgression( const liveActivityID = input.progression.active?.activityID; const simIsLive = liveActivityID === input.simActivity?.id; - // A run other than the sim's is live, so the sim is a stale worker snapshot of a run that has - // already been displaced — its total belongs to nothing the settled row is still tracking. No - // live run at all leaves the overlay standing, covering the window between a terminal append - // and the pending entry that replaces it. + // a live run other than the sim's means the sim is a stale snapshot of a displaced run; no live + // run at all keeps the overlay, covering the window between a terminal append and its pending + // entry. const simIsStale = liveActivityID !== undefined && !simIsLive; const overlayApplies = input.simActivity !== undefined && !simIsPending && !simIsStale; const settledForSim = simIsLive ? (input.progression.active?.settledXP ?? 0) : 0; diff --git a/apps/web/src/lib/activity/build-revealed-nodes-query-options.ts b/apps/web/src/lib/activity/build-revealed-nodes-query-options.ts index b065b235d..b7c701ab6 100644 --- a/apps/web/src/lib/activity/build-revealed-nodes-query-options.ts +++ b/apps/web/src/lib/activity/build-revealed-nodes-query-options.ts @@ -1,20 +1,8 @@ import type { Viewport } from '@vers/worldmap-core'; import { orpc } from '../rpc/orpc'; -/** - * Reveal state changes only when the avatar earns a new first-clear grant, far less often than the - * player pans — long enough that a re-mount or window refocus doesn't re-fetch a viewport nothing - * has changed for. - */ const REVEALED_NODES_STALE_TIME_MS = 30_000; -/** - * Query options for an avatar's revealed world-map cells inside a viewport. The query key carries - * both inputs: the avatar id, so no avatar ever reads another's cached reveal data, and the - * viewport. Callers pass an already chunk-aligned viewport, so for a given avatar the key changes - * only when the player pans across a chunk boundary rather than on every frame's cell-granular - * move. - */ export function buildRevealedNodesQueryOptions(avatarID: string, viewport: Viewport) { return orpc.activity.getRevealedNodes.queryOptions({ input: { avatarID, viewport }, diff --git a/apps/web/src/lib/activity/merge-revealed-rewards.ts b/apps/web/src/lib/activity/merge-revealed-rewards.ts index dba5d7d3d..62a66b4b8 100644 --- a/apps/web/src/lib/activity/merge-revealed-rewards.ts +++ b/apps/web/src/lib/activity/merge-revealed-rewards.ts @@ -1,11 +1,5 @@ import type { RevealedReward, RevealedRewardsPage } from './types'; -/** - * Accumulates a fresh keyset page of revealed rewards onto whatever the cache already holds, - * deduping on `(chainIndex, ordinal)` — the coordinate a reward slot is identified by — so a - * re-fetched overlap never double-counts. `verifiedHead` carries the higher of the two pages': the - * fresher fetch's view of the settled boundary never regresses the cache's own. - */ export function mergeRevealedRewards( previous: Readonly | undefined, page: Readonly, diff --git a/apps/web/src/lib/activity/require-active-activity.ts b/apps/web/src/lib/activity/require-active-activity.ts index 0a67bfbd5..3b1bb99b8 100644 --- a/apps/web/src/lib/activity/require-active-activity.ts +++ b/apps/web/src/lib/activity/require-active-activity.ts @@ -4,11 +4,6 @@ import { findActiveAvatar } from '../avatar/find-active-avatar'; import { activityClient } from '../rpc/clients/activity-client'; import { avatarClient } from '../rpc/clients/avatar-client'; -/** - * The per-screen gate for the engagement view: redirects a caller with no active avatar to the - * create sheet or roster, and a caller with no running activity back to explore, so the screen - * can assume a live activity to render. - */ export const requireActiveActivity = createServerFn({ method: 'GET' }).handler(async () => { const roster = await avatarClient.getAvatars({}); diff --git a/apps/web/src/lib/activity/types.ts b/apps/web/src/lib/activity/types.ts index ef41bdb50..00841d532 100644 --- a/apps/web/src/lib/activity/types.ts +++ b/apps/web/src/lib/activity/types.ts @@ -2,22 +2,12 @@ import type { ContractRouterClient } from '@orpc/contract'; import type { activityContract } from '@vers/contract-activity'; import type { DeepReadonly } from '../rpc/types'; -/** - * One revealed reward slot's wire shape, as `getActivityRewards` returns it — mutable, the form - * mock handlers and payload builders produce. - */ export type RevealedRewardData = Awaited< ReturnType['getActivityRewards']> >['items'][number]; -/** - * One revealed reward slot as consumers read it: the wire shape, deep-readonly. - */ export type RevealedReward = DeepReadonly; -/** - * A page of revealed rewards, keyed by the verified head it was read against. - */ export interface RevealedRewardsPage { readonly items: ReadonlyArray; readonly verifiedHead: number; diff --git a/apps/web/src/lib/activity/use-activity-rewards.ts b/apps/web/src/lib/activity/use-activity-rewards.ts index 36cab4892..749450be7 100644 --- a/apps/web/src/lib/activity/use-activity-rewards.ts +++ b/apps/web/src/lib/activity/use-activity-rewards.ts @@ -7,16 +7,6 @@ import { useIsActivityIngested } from './use-is-activity-ingested'; const REFETCH_INTERVAL_MS = 15_000; -/** - * Polls an activity's revealed rewards, merging each fresh keyset page onto whatever the cache - * already holds — no push channel names when a reward's verifying stream advances, so a short - * poll is the honest minimal trigger. Disabled with no `activityID`, and until the worker has landed - * the activity's start on the server — a run that exists only as a local mint has no rewards to - * read there. Every returned item is - * already settled; each item's `chainIndex` is chain-absolute while the page's `verifiedHead` - * counts from the activity's own start, so comparing the two needs the activity row's - * `startChainIndex` offset. - */ export function useActivityRewards(activityID: string | undefined) { const queryClient = useQueryClient(); const isActivityIngested = useIsActivityIngested(activityID); diff --git a/apps/web/src/lib/activity/use-is-activity-ingested.ts b/apps/web/src/lib/activity/use-is-activity-ingested.ts index 47302c5dd..7ed4cdd0b 100644 --- a/apps/web/src/lib/activity/use-is-activity-ingested.ts +++ b/apps/web/src/lib/activity/use-is-activity-ingested.ts @@ -1,25 +1,11 @@ import { readActivityStart, useLastIngestedActivityID } from '@vers/idle-client'; import { useEffect, useState } from 'react'; -/** - * The last derived answer paired with the activity it was derived for, so the held answer is never - * read against a different activity before that activity's own read lands. - */ interface IngestedActivity { readonly activityID: string | undefined; readonly isIngested: boolean; } -/** - * Whether the server holds the named activity, so a read keyed on it answers rather than reporting - * the activity missing. An activity starts as a local mint carried by a durable pending-start row, - * and the row is dropped once the worker lands the start on the server — so the absence of that - * row is what the answer reads, which survives a reload the way a broadcast alone would not. The - * ingest report is the trigger to read again, not the answer itself. - * - * `undefined` reads false, matching an avatar with no activity in flight. A local store that - * cannot be read reads true, since it says nothing about what the server holds. - */ export function useIsActivityIngested(activityID: string | undefined): boolean { const [ingested, setIngested] = useState({ activityID: undefined, diff --git a/apps/web/src/lib/auth/build-auth-session-config.ts b/apps/web/src/lib/auth/build-auth-session-config.ts index c613f1efd..e2648f766 100644 --- a/apps/web/src/lib/auth/build-auth-session-config.ts +++ b/apps/web/src/lib/auth/build-auth-session-config.ts @@ -1,19 +1,10 @@ import type { getSession } from '@tanstack/react-start/server'; import { readSessionSecret } from './read-session-secret'; -/** - * `getSession`'s config parameter type, without a direct dependency on its owning package. - */ export type SessionConfig = Parameters[0]; -/** - * A generous ceiling for reads: real expiry is enforced by comparing `data.expires` to now. - */ export const AUTH_SESSION_READ_MAX_AGE_SECONDS = 60 * 60 * 24 * 30; -/** - * Builds the `en_session` cookie's session config; `maxAge` governs the emitted `Max-Age`. - */ export function buildAuthSessionConfig(maxAge: number): SessionConfig { const domain = process.env['COOKIE_DOMAIN']; diff --git a/apps/web/src/lib/auth/build-honeypot-valid-from.ts b/apps/web/src/lib/auth/build-honeypot-valid-from.ts index dda0d10d0..9752188b3 100644 --- a/apps/web/src/lib/auth/build-honeypot-valid-from.ts +++ b/apps/web/src/lib/auth/build-honeypot-valid-from.ts @@ -1,13 +1,5 @@ -/** - * A human takes at least this long to fill in a form; a faster submission is treated as a bot. - */ const HONEYPOT_MIN_FILL_TIME_MS = 1500; -/** - * Computes the valid-from timestamp for a freshly rendered form. The floor has no env override: - * e2e specs pace their submits past the window instead, so the artifact under test enforces the - * same timing it ships with. - */ export function buildHoneypotValidFrom(): string { return String(Date.now() + HONEYPOT_MIN_FILL_TIME_MS); } diff --git a/apps/web/src/lib/auth/build-verify-session-config.ts b/apps/web/src/lib/auth/build-verify-session-config.ts index e5bd1ea38..f62f2f6a9 100644 --- a/apps/web/src/lib/auth/build-verify-session-config.ts +++ b/apps/web/src/lib/auth/build-verify-session-config.ts @@ -1,14 +1,8 @@ import type { SessionConfig } from './build-auth-session-config'; import { readSessionSecret } from './read-session-secret'; -/** - * Every in-flight verification flow abandons its state after this long. - */ const VERIFY_SESSION_MAX_AGE_SECONDS = 60 * 10; -/** - * Builds the `en_verification` cookie's session config: a fixed 10-minute lifetime. - */ export function buildVerifySessionConfig(): SessionConfig { const domain = process.env['COOKIE_DOMAIN']; diff --git a/apps/web/src/lib/auth/check-honeypot.ts b/apps/web/src/lib/auth/check-honeypot.ts index 63c4ebeb1..3bc6590e0 100644 --- a/apps/web/src/lib/auth/check-honeypot.ts +++ b/apps/web/src/lib/auth/check-honeypot.ts @@ -2,12 +2,6 @@ import { logger } from '../../server/logger'; import { HONEYPOT_FIELD_NAME, HONEYPOT_VALID_FROM_FIELD_NAME } from './honeypot-field-names'; import { SpamError } from './spam-error'; -/** - * Throws {@link SpamError} for a filled-in honeypot field or a submission that arrived before its - * form's `valid-from` timestamp, logging the flag so spam pressure is visible. Skips the timing - * check under `NODE_ENV=test`: tests submit forms instantly, well inside the window a bot would - * be flagged for. - */ export function checkHoneypot(formData: FormData): void { const honeypotValue = formData.get(HONEYPOT_FIELD_NAME); diff --git a/apps/web/src/lib/auth/check-step-up.ts b/apps/web/src/lib/auth/check-step-up.ts index 2edfd5b70..a2359b835 100644 --- a/apps/web/src/lib/auth/check-step-up.ts +++ b/apps/web/src/lib/auth/check-step-up.ts @@ -18,13 +18,6 @@ interface CheckStepUpOptions { readonly token: string | undefined; } -/** - * Gates a mutation behind step-up: callers with no live 2FA never gate at all. A 2FA-enabled - * caller needs a transaction token minted from a completed step-up code check — an absent, forged, - * expired, mismatched-claim, or session-mismatched token starts a fresh pending transaction instead - * of trusting it. The session check stops a token minted under one auth session from redeeming - * under another, mirroring the pending-transaction consume path's own `sessionID` match. - */ export async function checkStepUp(opts: Readonly): Promise { const twoFactorVerification = await verificationClient.getVerification({ target: opts.target, @@ -53,9 +46,6 @@ export async function checkStepUp(opts: Readonly): Promise>, ): Promise { @@ -57,9 +45,6 @@ export async function createStepUpTransactionToken( return { expiresAt, jti, token }; } -/** - * Verifies a step-up transaction token's signature and expiry, returning its claims. - */ export async function verifyStepUpTransactionToken( token: string, ): Promise { @@ -113,11 +98,6 @@ function getSessionIDClaim(payload: jose.JWTPayload): string | null { let keyPairPromise: Promise<{ privateKey: jose.CryptoKey; publicKey: jose.CryptoKey }> | null = null; -/** - * Lazily generates this process's step-up signing keypair. Minting and verifying always happen in - * the same edge process a token was issued from, so a fresh in-memory keypair per process is - * enough. - */ function getStepUpTransactionKeyPair(): Promise<{ privateKey: jose.CryptoKey; publicKey: jose.CryptoKey; diff --git a/apps/web/src/lib/auth/find-step-up-token.ts b/apps/web/src/lib/auth/find-step-up-token.ts index e7d66281a..4e2837db1 100644 --- a/apps/web/src/lib/auth/find-step-up-token.ts +++ b/apps/web/src/lib/auth/find-step-up-token.ts @@ -1,6 +1,3 @@ -/** - * Reads the step-up transaction token a gated mutation's resubmission carries, if any. - */ export function findStepUpToken(formData: FormData): string | undefined { const raw = formData.get('stepUpToken'); diff --git a/apps/web/src/lib/auth/get-auth-session.ts b/apps/web/src/lib/auth/get-auth-session.ts index d7cc5d71d..9f93dceab 100644 --- a/apps/web/src/lib/auth/get-auth-session.ts +++ b/apps/web/src/lib/auth/get-auth-session.ts @@ -5,11 +5,6 @@ import { } from './build-auth-session-config'; import type { AuthSessionData } from './types'; -/** - * Reads the caller's auth session. Never throws for a missing or expired cookie — an absent - * `accessToken`/`sessionID` is how callers (`requireAuth`, `requireAnonymous`) observe "signed - * out". - */ export async function getAuthSession(): Promise { const session = await getSession( buildAuthSessionConfig(AUTH_SESSION_READ_MAX_AGE_SECONDS), diff --git a/apps/web/src/lib/auth/get-honeypot-valid-from.ts b/apps/web/src/lib/auth/get-honeypot-valid-from.ts index 52f5c7d08..a5eb10363 100644 --- a/apps/web/src/lib/auth/get-honeypot-valid-from.ts +++ b/apps/web/src/lib/auth/get-honeypot-valid-from.ts @@ -1,13 +1,9 @@ import { createServerFn } from '@tanstack/react-start'; import { buildHoneypotValidFrom } from './build-honeypot-valid-from'; -/** - * Issues a form's `valid-from` timestamp from the server, so the value a route ships and the value - * the submission check compares it against are read from the same clock. Routes call this in their - * loader and pass the result down as loader data: computing it while rendering would let hydration - * recompute it against the browser's clock, and a caller whose device clock runs ahead of the - * server would then be rejected as a bot on every auth form. - */ +// issued from a loader, never computed during render: hydration would recompute a render-time value +// against the browser's clock, and a device clock ahead of the server's would then fail every auth +// form as a bot export const getHoneypotValidFrom = createServerFn({ method: 'GET' }).handler(() => buildHoneypotValidFrom(), ); diff --git a/apps/web/src/lib/auth/get-login-path-with-redirect.ts b/apps/web/src/lib/auth/get-login-path-with-redirect.ts index 880b4e8d5..f77666052 100644 --- a/apps/web/src/lib/auth/get-login-path-with-redirect.ts +++ b/apps/web/src/lib/auth/get-login-path-with-redirect.ts @@ -1,14 +1,8 @@ -/** - * The part of a URL {@link getLoginPathWithRedirect} needs to rebuild the page a guard bounced. - */ interface RedirectSource { readonly pathname: string; readonly search: string; } -/** - * Builds `/login?redirect=`, so a completed login returns the caller to where it left off. - */ export function getLoginPathWithRedirect(source: RedirectSource): string { const redirectTo = `${source.pathname}${source.search}`; diff --git a/apps/web/src/lib/auth/get-verify-session.ts b/apps/web/src/lib/auth/get-verify-session.ts index ef8425ca5..92cad157f 100644 --- a/apps/web/src/lib/auth/get-verify-session.ts +++ b/apps/web/src/lib/auth/get-verify-session.ts @@ -2,9 +2,6 @@ import { getSession } from '@tanstack/react-start/server'; import { buildVerifySessionConfig } from './build-verify-session-config'; import type { VerifySessionData } from './types'; -/** - * Reads the caller's in-flight verification state; empty once the 10-minute window lapses. - */ export async function getVerifySession(): Promise { const session = await getSession(buildVerifySessionConfig()); diff --git a/apps/web/src/lib/auth/honeypot-field-names.ts b/apps/web/src/lib/auth/honeypot-field-names.ts index 140e3365a..97235105e 100644 --- a/apps/web/src/lib/auth/honeypot-field-names.ts +++ b/apps/web/src/lib/auth/honeypot-field-names.ts @@ -1,9 +1,2 @@ -/** - * The hidden field a real caller never fills in; any value here marks the submission as spam. - */ export const HONEYPOT_FIELD_NAME = 'name__confirm'; - -/** - * Encodes the earliest timestamp (ms epoch) a submission of this render counts as human-paced. - */ export const HONEYPOT_VALID_FROM_FIELD_NAME = 'from__confirm'; diff --git a/apps/web/src/lib/auth/honeypot-inputs.tsx b/apps/web/src/lib/auth/honeypot-inputs.tsx index 9112ffeb9..95b485212 100644 --- a/apps/web/src/lib/auth/honeypot-inputs.tsx +++ b/apps/web/src/lib/auth/honeypot-inputs.tsx @@ -1,19 +1,9 @@ import { HONEYPOT_FIELD_NAME, HONEYPOT_VALID_FROM_FIELD_NAME } from './honeypot-field-names'; interface HoneypotInputsProps { - /** - * Epoch-ms timestamp the submission must arrive after. Callers pass a server-issued value from - * loader data rather than computing one here: a value built while rendering is rebuilt again - * during hydration, against the browser's clock instead of the server's. - */ readonly validFrom: string; } -/** - * Renders a form-bearing route's hidden anti-spam fields. A submission arriving before `validFrom`, - * or carrying a non-empty honeypot field, is treated as spam by the server-side check these fields - * feed. - */ export function HoneypotInputs(props: Readonly) { return (