From 4119279df517dff15f9deea8bd7d76b5c75df3b8 Mon Sep 17 00:00:00 2001 From: Patrick Erichsen Date: Wed, 8 Jul 2026 19:43:42 -0700 Subject: [PATCH] docs: streamline repository agent guidance (#3021) --- .agents/skills/clawhub-convex/SKILL.md | 126 ++++++++++++++++++ .../skills/clawhub-convex/agents/openai.yaml | 4 + .../clawhub-production-release/SKILL.md | 97 ++++++++++++++ .../agents/openai.yaml | 4 + .agents/skills/convex-retention/SKILL.md | 2 +- .../create-and-cleanup-migration/SKILL.md | 2 + AGENTS.md | 84 +----------- CLAUDE.md | 64 +-------- 8 files changed, 246 insertions(+), 137 deletions(-) create mode 100644 .agents/skills/clawhub-convex/SKILL.md create mode 100644 .agents/skills/clawhub-convex/agents/openai.yaml create mode 100644 .agents/skills/clawhub-production-release/SKILL.md create mode 100644 .agents/skills/clawhub-production-release/agents/openai.yaml diff --git a/.agents/skills/clawhub-convex/SKILL.md b/.agents/skills/clawhub-convex/SKILL.md new file mode 100644 index 00000000..8f4a94dd --- /dev/null +++ b/.agents/skills/clawhub-convex/SKILL.md @@ -0,0 +1,126 @@ +--- +name: clawhub-convex +description: Apply ClawHub-specific Convex conventions and route to the right managed Convex skill. Use for any change under convex/, Convex commands or deployment targeting, query performance, migrations, retention, runtime validation, or skill stat reads and writes in the ClawHub repository. +--- + +# ClawHub Convex + +Use the managed Convex guidance for general framework behavior and this skill +for ClawHub's repository-specific boundaries. + +## Start Here + +1. Read `convex/_generated/ai/guidelines.md` before editing Convex code. +2. Name the target runtime before running a Convex command: `local`, `dev`, or + `prod`. Include the exact deployment when known and whether the current + function/schema code has already been pushed there. +3. Route to the most specific companion skill: + - Query cost, indexes, read amplification, subscriptions, or OCC: + `convex-performance-audit` + - Production migration, backfill, schema narrowing, or table reshaping: + `convex-migration-helper` and `create-and-cleanup-migration` + - Tables, TTL fields, cleanup crons, retention, auth/session cleanup, metric + dedupe cleanup, or deprecated table removal: `convex-retention` + - Auth, reusable components, or setup: use the matching managed Convex skill. + +Do not edit upstream-managed Convex skills to store ClawHub policy. + +## Commands And Runtime Validation + +- Push new or changed functions before `convex run`: + - dev: `bunx convex dev --once` + - prod: deploy through the workflow described by + `clawhub-production-release` +- For a non-interactive direct production deploy when explicitly required, use + `bunx convex deploy -y`. +- If `bunx convex run --env-file .env.local ...` returns + `401 MissingAccessToken` after login, omit `--env-file` and target the + deployment with `--deployment ` or `--prod`. +- Regenerate committed API/types with `bunx convex codegen` after Convex + API/schema changes. +- Import mutations from `convex/functions.ts`, not + `convex/_generated/server`, so ClawHub's trigger wrapper runs. Type imports + can still come from `convex/_generated/server`. +- Do not disable typechecking for an ordinary direct deploy. The production + workflow owns its explicit deploy behavior and exceptions. + +Mocked `ctx` tests cover pure business logic only. When behavior depends on +pagination, indexes, validators, auth identity, internal/public boundaries, +schedulers, actions calling functions, HTTP actions, storage, or OCC, also run +a real Convex path such as: + +- `bunx convex dev --once` +- `bunx convex run ...` +- an HTTP action smoke +- `bun run test:pw:local-auth` + +Tests that invoke a mutation through `._handler` need a mock database with +`normalizeId: vi.fn()` for trigger-wrapper compatibility. + +## ClawHub Migration Boundaries + +- Default production data changes to `@convex-dev/migrations`; the companion + skills own batching, dry runs, resume/progress, confirmation, validation, and + cleanup. +- Put component-backed table-wide backfills in `convex/migrations.ts`. +- Put custom repairs, admin-gated operations, and incident-specific workflows + in `convex/maintenance.ts`. +- Keep one-off operator migration runs out of `.github/workflows/deploy.yml`. +- Remove temporary migration functions in a follow-up PR after production + apply and verification unless they are intentionally retained as maintenance + tooling. + +## Query And Bandwidth Work + +Use `convex-performance-audit` for the detailed rules on indexes, bounded reads, +denormalization, digest tables, subscriptions, and function limits. Before +writing or reviewing a performance-sensitive query, check deployment health +when available: + +```bash +bunx convex insights --details +bunx convex logs --failure +``` + +Prefer measured runtime signals over speculative restructuring. + +## ClawHub Hot-Path Conventions + +Use `convex-performance-audit` for the complete workflow. Preserve these +ClawHub-specific implementations when touching their paths: + +- Public listing and browse pages use one-shot `ConvexHttpClient.query()` reads + unless the user needs live updates. +- When a `skillSearchDigest` row exists, resolve owner data with + `digestToOwnerInfo(digest)`. Do not re-read the owner document when the + digest already contains the required owner fields. +- Keep denormalized tables synchronized through the existing + `convex-helpers` triggers and skip writes when derived fields did not change. +- Paginate computed search results client-side after running the scoring + pipeline once; do not rerun the full vector, lexical, and popularity pipeline + for each page. +- Add `delayMs` between backfill batches that update reactively subscribed + tables. +- Split mutations that would read more than the transaction budget through the + existing action-query-mutation pattern. + +## Skill Stat Contract + +The `skills` table still has a compatibility shape for four migrated stats: + +| Legacy nested field | Top-level source of truth | +| ----------------------- | ------------------------- | +| `stats.downloads` | `statsDownloads` | +| `stats.stars` | `statsStars` | +| `stats.installsCurrent` | `statsInstallsCurrent` | +| `stats.installsAllTime` | `statsInstallsAllTime` | + +- Read these fields with `readCanonicalStat()` from + `convex/lib/skillStats.ts`. It prefers the top-level field and falls back for + pre-migration documents. +- Write deltas with `applySkillStatDeltas()`. It updates both shapes in one + patch. +- Any direct patch touching these values must update both shapes. +- Nested-only reads remain valid for `stats.comments` and `stats.versions`. +- When adding a migrated stat field, use the same dual-write shape and add a + cursor-based backfill. diff --git a/.agents/skills/clawhub-convex/agents/openai.yaml b/.agents/skills/clawhub-convex/agents/openai.yaml new file mode 100644 index 00000000..cfb720f3 --- /dev/null +++ b/.agents/skills/clawhub-convex/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "ClawHub Convex" + short_description: "Apply ClawHub-specific Convex conventions" + default_prompt: "Use $clawhub-convex to make this Convex change with ClawHub-specific safeguards." diff --git a/.agents/skills/clawhub-production-release/SKILL.md b/.agents/skills/clawhub-production-release/SKILL.md new file mode 100644 index 00000000..a343f730 --- /dev/null +++ b/.agents/skills/clawhub-production-release/SKILL.md @@ -0,0 +1,97 @@ +--- +name: clawhub-production-release +description: Run and verify ClawHub production deploys and stable ClawHub CLI npm releases. Use when deploying backend or frontend changes to clawhub.ai, dispatching the Deploy workflow, publishing a stable CLI tag, checking release prerequisites, or proving the exact production SHA and workflow outcome. +--- + +# ClawHub Production Release + +ClawHub production changes are manual-only. Merging to `main` does not deploy +the app or publish the CLI. + +## Safety Rules + +- Run production workflows from `main`. +- Re-read the workflow and exact `main` SHA immediately before dispatch. +- Do not treat a green workflow alone as proof. Record the workflow URL, exact + deployed SHA, and live-surface verification. +- Do not add one-off migrations or repairs to the deploy workflow. Run + operator-controlled data changes separately with `clawhub-convex` and + `create-and-cleanup-migration`. +- Never start a production deploy or npm publish unless the user explicitly + asked for that release action. + +## App Production Deploy + +The workflow is `.github/workflows/deploy.yml`. + +1. Confirm the selected commit is on `origin/main` and record its SHA. +2. Run the required pre-merge or release validation for the changed surface. +3. Dispatch one target: + +```bash +gh workflow run deploy.yml \ + --repo openclaw/clawhub \ + --ref main \ + -f target=full \ + -f allow_deleting_large_indexes=false +``` + +Choose `full`, `backend`, or `frontend`: + +- `full`: deploy Convex, wait for the matching Vercel production deployment, + and run production smoke checks. +- `backend`: deploy Convex and run production HTTP smoke checks. +- `frontend`: wait for Vercel's production deployment for the selected `main` + SHA, then run HTTP and UI smoke checks. The workflow does not call + `vercel deploy`. + +Set `allow_deleting_large_indexes=true` only after reviewing the Convex index +deletion and explicitly accepting it. + +4. Capture the workflow run URL and wait for completion. +5. Verify the run used the expected SHA. +6. Verify the affected live route, API, or backend contract on + `https://clawhub.ai`. +7. Report the workflow URL, deployed SHA, target, and live proof. + +The workflow uses the GitHub `Production` environment. Backend deploys require +the environment secret `CONVEX_DEPLOY_KEY`. The optional +`PLAYWRIGHT_AUTH_STORAGE_STATE_JSON` enables authenticated UI smoke coverage. + +## Stable CLI npm Release + +The workflow is `.github/workflows/clawhub-cli-npm-release.yml`. Stable tags +must use `vX.Y.Z`. + +1. Confirm the tag points to the intended commit on `main`. +2. Dispatch validation-only preflight: + +```bash +gh workflow run clawhub-cli-npm-release.yml \ + --repo openclaw/clawhub \ + --ref main \ + -f tag=vX.Y.Z \ + -f preflight_only=true +``` + +3. Wait for success and record the preflight run ID and URL. +4. Promote that exact artifact in the real publish: + +```bash +gh workflow run clawhub-cli-npm-release.yml \ + --repo openclaw/clawhub \ + --ref main \ + -f tag=vX.Y.Z \ + -f preflight_only=false \ + -f preflight_run_id= +``` + +5. Wait for the `npm-release` environment job and verify the published version + from npm. +6. Report the preflight URL, publish URL, tag, release SHA, and published + version. + +Real publishes use npm trusted publishing through the `npm-release` GitHub +environment. The trusted publisher must match repository +`openclaw/clawhub`, workflow `clawhub-cli-npm-release.yml`, and environment +`npm-release`. diff --git a/.agents/skills/clawhub-production-release/agents/openai.yaml b/.agents/skills/clawhub-production-release/agents/openai.yaml new file mode 100644 index 00000000..01fc280d --- /dev/null +++ b/.agents/skills/clawhub-production-release/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "ClawHub Production Release" + short_description: "Run ClawHub production and CLI releases" + default_prompt: "Use $clawhub-production-release to prepare and run this ClawHub release." diff --git a/.agents/skills/convex-retention/SKILL.md b/.agents/skills/convex-retention/SKILL.md index a3ebd261..9379fc0a 100644 --- a/.agents/skills/convex-retention/SKILL.md +++ b/.agents/skills/convex-retention/SKILL.md @@ -13,7 +13,7 @@ their lifecycle is handled by usage-time validation or a documented component. ## Checklist -- Read `convex/_generated/ai/guidelines.md` and the Convex ops rules in `AGENTS.md` first. +- Use `clawhub-convex` and read `convex/_generated/ai/guidelines.md` first. - Add every new schema table to `RETENTION_POLICIES`; the `Record` type is the enforcement gate. - For ephemeral tables, prefer an explicit expiration field plus index, then prune with `.withIndex()` diff --git a/.agents/skills/create-and-cleanup-migration/SKILL.md b/.agents/skills/create-and-cleanup-migration/SKILL.md index 3eb163d7..f7d0e4d6 100644 --- a/.agents/skills/create-and-cleanup-migration/SKILL.md +++ b/.agents/skills/create-and-cleanup-migration/SKILL.md @@ -30,6 +30,8 @@ temporary migration code. - resumable/progress behavior - destructive confirmation token - real Convex runtime validation +5. Use `clawhub-convex` for repository-specific file placement and runtime + targeting. Use `clawhub-production-release` for production deploy phases. ## Safety Rules diff --git a/AGENTS.md b/AGENTS.md index 6e8ec72d..afec2208 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -52,7 +52,6 @@ Specialized corpus, scanner, security-worker, UI proof, proof publishing, Crabbo - Tests live in `src/**` and `convex/lib/**`. - Coverage threshold: 80% global (lines/functions/branches/statements). - Example: `convex/lib/skills.test.ts`. -- When adding or changing Convex functions, do not rely only on mocked `ctx` tests for behavior that depends on Convex runtime semantics such as pagination, indexes, validators, auth identity, internal/public function boundaries, scheduler/cron behavior, actions calling queries/mutations, HTTP actions, storage, or OCC/transaction behavior. Add or run a real Convex validation path, such as `convex dev --once`, `convex run`, an HTTP action smoke, or a local-auth Playwright flow, covering the changed behavior. Mocked `ctx.db` / `ctx.runQuery` tests are still fine for pure business logic, but they do not count as Convex runtime validation. - For local UI state testing, prefer creating realistic backend state through seed logic plus a DevPersonaFab entry for the associated test user. Avoid one-off manual DB edits when the state is likely to be reused, such as org membership, official publisher access, moderation holds, or publishing permissions. ## Commit & Pull Request Guidelines @@ -66,64 +65,15 @@ Specialized corpus, scanner, security-worker, UI proof, proof publishing, Crabbo - Screenshot proof MUST come from a real running ClawHub instance in a real browser. Do not use generated HTML mockups, synthetic terminal cards, or manually composed images as proof. For route/status/backend visibility bugs, run ClawHub locally with the relevant Convex code and fixture state, capture the actual browser page, and state the local URL and fixture used. - Before merging any PR, verify TypeScript cleanly with `bunx tsc -p packages/schema/tsconfig.json --noEmit` and `bunx tsc -p packages/clawhub/tsconfig.json --noEmit`; if Convex code changed, also run the repo typecheck path used by deploy so `bunx convex deploy` will not fail on `tsc`. - GitHub comments: for multiline `gh` comments/close messages, use `--body-file`, `--input`, or stdin/heredoc with real newlines; never pass literal `\\n` in shell strings. -- Repo-local developer skills under `.agents/skills/` should normally be ClawHub-specific, such as Convex, moderation, PR maintainer, or UI proof workflows. Keep generic shared skills in the global `agent-skills` install unless the repository explicitly vendors them for a shared operational workflow. Keep top-level `skills/` reserved for installed/published skill content and ignored by git. -- Treat the skill trees installed from `get-convex/agent-skills` by `npx convex ai-files install` as upstream-managed content. The formatter excludes those generated directories so updates do not rewrite vendor files; custom ClawHub skills remain under normal formatting checks. -- The skills from `axiomhq/skills` are explicit vendored exceptions. Install or update them with `npx skills add axiomhq/skills --agent codex --skill axiom-alerting building-dashboards controlling-costs query-metrics spl-to-apl axiom-sre writing-evals --yes --copy` so `skills-lock.json` stays in sync. The v1 lock records the official source, skill paths, and content hashes; `.agents/skills/axiomhq-skills.provenance.json` records the exact reviewed upstream revision represented by the committed files. Update and verify both together, and do not modify the managed files locally. Store all Axiom credentials in user-level configuration such as `~/.config/axiom-sre/config.toml` or `~/.axiom.toml`, never in git. -- The `sentry-fix-issues` skill from `getsentry/sentry-for-ai` is an explicit vendored exception for the shared production-error workflow. Install or update it with `npx skills add getsentry/sentry-for-ai --agent codex --skill sentry-fix-issues --yes --copy`, then update `.agents/skills/getsentry-sentry-for-ai.provenance.json` to the reviewed upstream revision. Keep the managed skill file byte-for-byte upstream and store Sentry authentication only in user-level MCP or CLI configuration, never in git. -## Production Release +## Specialized Workflows -- Production deploys are manual-only. Merging to `main` does **not** deploy. -- To release production, start the GitHub Actions `Deploy` workflow from `main`: - `gh workflow run deploy.yml --repo openclaw/clawhub --ref main` -- The workflow supports `full`, `backend`, and `frontend` targets. -- `frontend` currently means: wait for the Vercel production deploy for the selected `main` SHA, then run production smoke checks. It does not call `vercel deploy` directly yet. -- The workflow uses the GitHub `Production` environment for deploy secrets, but it does not require a separate approval step. -- Prod deploy secrets live on the `Production` environment, not as ordinary repo secrets. Required: `CONVEX_DEPLOY_KEY`. Optional: `PLAYWRIGHT_AUTH_STORAGE_STATE_JSON`. -- CLI npm releases are also manual-only and tag-based. Stable tags only: `vX.Y.Z`. Start `ClawHub CLI NPM Release` from `main`, first with `preflight_only=true`, then rerun it with the same tag and the successful `preflight_run_id`. -- Real CLI publishes wait at the GitHub `npm-release` environment and use npm trusted publishing. Required npm trusted publisher settings: repository `openclaw/clawhub`, workflow `clawhub-cli-npm-release.yml`, environment `npm-release`. - -## Git Notes - -- If `git branch -d/-D ` is policy-blocked, delete the local ref directly: `git update-ref -d refs/heads/`. - -## URL Quick Reference - -- Canonical site: `https://clawhub.ai` (prefer this over legacy domains). -- Skill page URL format: `https://clawhub.ai//` (owner handle preferred; falls back to owner id). -- Skill API detail URL: `https://clawhub.ai/api/v1/skills/`. -- Skill file URL: `https://clawhub.ai/api/v1/skills//file?path=SKILL.md`. -- For “full URL?” requests, return the canonical page URL first, then API URL if useful. - -## Configuration & Security - -- Local env: `.env.local` (never commit secrets). -- Convex env holds JWT keys; Vercel only needs `VITE_CONVEX_URL` + `VITE_CONVEX_SITE_URL`. -- OAuth: GitHub OAuth App credentials required for login. - -## Convex Ops (Gotchas) - -- Before any `bunx convex ...` command, name the target runtime (`local`, `dev`, or `prod`), the exact deployment when known, and whether the current function/schema code has already been pushed or deployed. -- New Convex functions must be pushed before `convex run`: use `bunx convex dev --once` (dev) or `bunx convex deploy` (prod). -- For non-interactive prod deploys, use `bunx convex deploy -y` to skip confirmation. -- If `bunx convex run --env-file .env.local ...` returns `401 MissingAccessToken` despite `bunx convex login`, workaround: omit `--env-file` and use `--deployment ` / `--prod`. - -## Convex Migrations & Backfills - -- Any Convex production data migration, backfill, destructive cleanup, schema narrowing, or table reshaping must start with the `convex-migration-helper` skill. Default to `@convex-dev/migrations` for production data changes because it provides batching, dry runs, resume/progress tracking, and safer operator UX. Exceptions require an explicit note explaining why the component is unnecessary, plus equivalent dry-run support, cursor batching, resume/progress behavior, confirmation for destructive writes, and real Convex runtime validation. -- When adding or changing Convex tables, TTL fields, cleanup crons, retention policy, auth/session cleanup, metric dedupe cleanup, or deprecated table removal, use the repo-local `convex-retention` skill and update `convex/lib/retentionPolicy.ts`. -- Use `convex/migrations.ts` for component-backed table-wide backfills; keep custom repairs, admin-gated operations, and incident-specific workflows in `convex/maintenance.ts`. -- After a migration or cleanup is verified complete, remove temporary migration functions/code in a follow-up PR unless they are intentionally retained as ongoing maintenance tooling. - -## Convex Query & Bandwidth Rules - -- **Always use `.withIndex()` instead of `.filter()` for fields that can be indexed.** `.filter()` causes full table scans — every doc is read and billed. Even a single `.filter()` on a 16K-row table reads ~16 MB per call. -- **Convex reads entire documents** — no field projections. If you only need a few fields from large docs (~6 KB+), denormalize a lightweight summary onto the parent doc or use a lookup table (see `embeddingSkillMap`, `skill.latestVersionSummary`, `skill.badges` for examples). -- **Denormalization pattern**: persist computed fields so they can be indexed. Every mutation that updates source fields must also update the denormalized field. Always write a cursor-based backfill for new fields (see `backfillIsSuspiciousInternal`, `backfillLatestVersionSummaryInternal`, `backfillDenormalizedBadgesInternal` for examples). -- **Cron jobs must never scan entire tables.** Use indexed queries with equality filters. Use cursor-based pagination for large datasets. Prefer incremental/delta tracking over full recounts. -- **32K document limit per query.** Split `.collect()` calls by a partition field (e.g., one day at a time instead of a 7-day range). See `rebuildTrendingLeaderboardAction` in `convex/leaderboards.ts` for an example. -- **Common mistakes**: `.filter().collect()` without an index; `ctx.db.get()` on large docs in a loop for list views; while loops that paginate the whole table to find filtered results. -- **Before writing or reviewing Convex queries, check deployment health.** Run `bunx convex insights` to check for OCC conflicts, `bytesReadLimit`, and `documentsReadLimit` errors. Run `bunx convex logs --failure` to see individual error messages and stack traces. This helps identify which functions are causing bandwidth issues so you can prioritize fixes. +- For any Convex work, use + `.agents/skills/clawhub-convex/SKILL.md`. It routes to the managed Convex + skills and owns ClawHub-specific runtime, migration, retention, validation, + performance, and skill-stat conventions. +- For app production deploys or stable CLI npm releases, use + `.agents/skills/clawhub-production-release/SKILL.md`. @@ -138,23 +88,3 @@ Convex agent skills for common tasks can be installed by running `npx convex ai-files install`. - -## Stat Field Migration Rules - -The `skills` table maintains two parallel sets of stat fields as part of an in-progress field migration: - -| Legacy (nested, `@deprecated`) | Top-level (source of truth, indexable) | -| ------------------------------ | -------------------------------------- | -| `stats.downloads` | `statsDownloads` | -| `stats.stars` | `statsStars` | -| `stats.installsCurrent` | `statsInstallsCurrent` | -| `stats.installsAllTime` | `statsInstallsAllTime` | - -**Rules:** - -- **Always use `readCanonicalStat(skill, field)` (`convex/lib/skillStats.ts`) to read** any of the four migrated fields. It prefers the top-level field and falls back to the nested field for pre-migration documents. Never access `skill.stats.downloads` / `.stars` / `.installsCurrent` / `.installsAllTime` directly. -- **Always use `applySkillStatDeltas()` to write** stat deltas. It writes both the top-level and nested fields in the same patch to keep them in sync. -- **Both sets of fields must be written together** in any patch that touches stat values (see the return shape of `applySkillStatDeltas`). -- **Nested-only reads are acceptable only for** `stats.comments` and `stats.versions` — no top-level field exists for these yet. -- The four legacy nested fields are marked `@deprecated` in `statsValidator` (schema.ts). Any IDE access to `skill.stats.downloads` etc. will show a strikethrough warning — treat this as a signal to use `readCanonicalStat()` instead. -- When adding new stat fields, follow the same dual-write pattern and add a cursor-based backfill mutation (see `backfillSkillStatFieldsInternal` for an example). diff --git a/CLAUDE.md b/CLAUDE.md index 5e1c82de..8232c57b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,61 +1,7 @@ -# ClawHub — Project Rules +# ClawHub Project Rules -## Convex Performance Rules +Follow `AGENTS.md` as the canonical repository instructions. -- For public listing/browse pages, use `ConvexHttpClient.query()` (one-shot fetch), - not `useQuery`/`usePaginatedQuery` (reactive subscription). Reserve reactive - queries for data the user needs to see update in real time. -- Denormalize hot read paths into a single lightweight "digest" table. Every - `ctx.db.get()` join adds a table to the reactive invalidation scope. -- When a `skillSearchDigest` row is available, use `digestToOwnerInfo(digest)` - to resolve owner data. NEVER call `ctx.db.get(ownerUserId)` when digest - owner fields (`ownerHandle`, `ownerName`, `ownerDisplayName`, `ownerImage`) - are already present. Reading from `users` adds the entire table to the - reactive read set and wastes bandwidth. -- Use `convex-helpers` Triggers to sync denormalized tables automatically. - Always add change detection — skip the write if no fields actually changed. -- Use compound indexes instead of JS filtering. If you're filtering docs after - the query, you're scanning documents you'll throw away. -- For search results scored by computed values (vector + lexical + popularity), - fetch all results once and paginate client-side. Don't re-run the full search - pipeline on "load more." -- Backfills on reactively-subscribed tables need `delayMs` between batches. -- Mutations that read >8 MB should use the Action → Query → Mutation pattern - to split reads across transactions. - -## Convex Conventions - -- All mutations import from `convex/functions.ts` (not `convex/_generated/server`) - to get trigger wrapping. Type imports still come from `convex/_generated/server`. -- NEVER use `--typecheck=disable` on `npx convex deploy`. -- Use `npx convex dev --once` to push functions once (not long-running watcher). - -## Production Release - -- Production deploys are manual-only. Merging to `main` does **not** deploy. -- Start the GitHub Actions `Deploy` workflow from `main` with `gh workflow run deploy.yml --repo openclaw/clawhub --ref main`. -- The workflow supports `full`, `backend`, and `frontend` targets. -- `frontend` currently waits for the Vercel production deploy on the selected `main` SHA and then runs smoke checks. It does not trigger Vercel directly yet. -- The workflow uses the `Production` environment for deploy secrets, but it does not wait for a separate approval. -- Required prod secret: `CONVEX_DEPLOY_KEY` on the `Production` environment. Optional smoke secret: `PLAYWRIGHT_AUTH_STORAGE_STATE_JSON`. -- CLI npm releases are manual-only and tag-based through `ClawHub CLI NPM Release`. Stable tags only: `vX.Y.Z`. Run a `preflight_only=true` pass first, then rerun with the same tag plus `preflight_run_id` for the real publish. -- Real CLI publishes wait at `npm-release` and rely on npm trusted publishing for `openclaw/clawhub` + `clawhub-cli-npm-release.yml` + `npm-release`. - -## Testing - -- Tests use `._handler` to call mutation handlers directly with mock `db` objects. -- Mock `db` objects MUST include `normalizeId: vi.fn()` for trigger wrapper compatibility. - - - -This project uses [Convex](https://convex.dev) as its backend. - -When working on Convex code, **always read -`convex/_generated/ai/guidelines.md` first** for important guidelines on -how to correctly use Convex APIs and patterns. The file contains rules that -override what you may have learned about Convex from training data. - -Convex agent skills for common tasks can be installed by running -`npx convex ai-files install`. - - +- For Convex work, also read `.agents/skills/clawhub-convex/SKILL.md`. +- For production app deploys or stable CLI npm releases, also read + `.agents/skills/clawhub-production-release/SKILL.md`.