docs: streamline repository agent guidance (#3021)

This commit is contained in:
Patrick Erichsen
2026-07-08 19:43:42 -07:00
committed by GitHub
parent 05e7aeaf49
commit 4119279df5
8 changed files with 246 additions and 137 deletions
+126
View File
@@ -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 <name>` 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.
@@ -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."
@@ -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=<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`.
@@ -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."
+1 -1
View File
@@ -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<TableNames, RetentionPolicy>` type
is the enforcement gate.
- For ephemeral tables, prefer an explicit expiration field plus index, then prune with `.withIndex()`
@@ -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
+7 -77
View File
@@ -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 <branch>` is policy-blocked, delete the local ref directly: `git update-ref -d refs/heads/<branch>`.
## URL Quick Reference
- Canonical site: `https://clawhub.ai` (prefer this over legacy domains).
- Skill page URL format: `https://clawhub.ai/<owner>/<slug>` (owner handle preferred; falls back to owner id).
- Skill API detail URL: `https://clawhub.ai/api/v1/skills/<slug>`.
- Skill file URL: `https://clawhub.ai/api/v1/skills/<slug>/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 <name>` / `--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`.
<!-- convex-ai-start -->
@@ -138,23 +88,3 @@ Convex agent skills for common tasks can be installed by running
`npx convex ai-files install`.
<!-- convex-ai-end -->
## 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).
+5 -59
View File
@@ -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.
<!-- convex-ai-start -->
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`.
<!-- convex-ai-end -->
- 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`.