| description | Sync `zbeyens/convex-better-auth` with upstream, then sync kitcn against upstream `convex-better-auth` changes. Use when asked to run `sync-convex-auth`, compare the fork with upstream, fast-forward or PR the fork update when safe, audit commits the fork was behind on, classify relevance to kitcn auth integration, and delegate one implementation PR through `task`. |
| name | sync-convex-auth |
| metadata | {"skiller":{"source":".agents/rules/sync-convex-auth.mdc"}} |
Sync Convex Auth
Handle $ARGUMENTS.
Goal: compare https://github.com/zbeyens/convex-better-auth with its
upstream fork, sync that fork to upstream when it can be done without losing
fork-only work, extract every upstream change that matters to kitcn, then
delegate one coherent implementation slice to
$task so it
opens the PR.
Goal Template
When this sync needs durable goal state, use the project-owned sync template
instead of the generic task template:
node .agents/skills/autogoal/scripts/create-goal-scratchpad.mjs \
--template sync-convex-auth \
--title "sync convex auth"
This plan owns the upstream audit, classification ledger, ambiguity decisions,
fork-sync result, and delegated task prompt. The delegated implementation still
uses task; do not duplicate implementation PR machinery inside the sync plan.
Rules
- Use evidence, not vibes. Read commits, changed files, and patches.
- Treat the fork being behind upstream as signal, not proof. Pull only relevant
work into kitcn.
- Syncing the fork is required. Snapshot the pre-sync range first, then update
zbeyens/convex-better-auth by fast-forward push or fork PR. Never force
push the fork.
- Ignore genuinely irrelevant upstream changes when deciding KitCN work. Do not
mirror upstream into KitCN just to feel caught up.
- Pull all clearly relevant, non-conflicting fixes in the same slice when they
share the same kitcn auth surface.
- Stop and ask the user before importing optional additions where the tradeoff is
unclear, especially slow e2e suites, broad fixture rewrites, examples,
release plumbing, or dev-only test infrastructure.
- Prefer deleting kitcn glue over adding more glue when upstream fixed the real
problem.
- If no actionable opportunity exists, stop with the evidence. Do not open a
vanity PR.
1. Establish Fork, Upstream, And Refs
Use GitHub metadata to discover the upstream parent instead of guessing:
gh repo view zbeyens/convex-better-auth \
--json nameWithOwner,parent,defaultBranchRef \
--jq '{fork: .nameWithOwner, parent: .parent.nameWithOwner, branch: .defaultBranchRef.name}'
If parent is missing or ambiguous, stop and ask for the upstream repo.
Before asking, try these fallbacks in order:
npm view @convex-dev/better-auth repository homepage --json
test -d ../convex-better-auth/.git && git -C ../convex-better-auth remote -v
gh repo view get-convex/better-auth --json nameWithOwner,defaultBranchRef,url
If npm metadata or the local clone clearly point to one upstream repo, use that
repo and continue instead of stopping.
Use a local clone for navigation, creating it only if missing. Identify the
remote that points at the fork and the remote that points at upstream by URL;
do not assume origin is the fork:
test -d ../convex-better-auth/.git || \
gh repo clone zbeyens/convex-better-auth ../convex-better-auth
git -C ../convex-better-auth remote -v
git -C ../convex-better-auth remote get-url <upstream-remote> >/dev/null 2>&1 || \
git -C ../convex-better-auth remote add <upstream-remote> https://github.com/<upstream-owner>/<repo-name>.git
git -C ../convex-better-auth fetch <fork-remote> --tags
git -C ../convex-better-auth fetch <upstream-remote> --tags
Record:
- fork owner/name and default branch
- upstream owner/name and default branch
- fork remote name and upstream remote name
- fork ref and upstream ref being compared
- behind count
- ahead count, if any
- exact commit range
Commands:
git -C ../convex-better-auth rev-list --count <fork-remote>/<fork-branch>..<upstream-remote>/<upstream-branch>
git -C ../convex-better-auth rev-list --count <upstream-remote>/<upstream-branch>..<fork-remote>/<fork-branch>
git -C ../convex-better-auth log --oneline --decorate <fork-remote>/<fork-branch>..<upstream-remote>/<upstream-branch>
If $ARGUMENTS names a base or target ref, use it as the bound after proving it
exists.
2. Sync The Fork
The sync audit must update zbeyens/convex-better-auth itself, not only KitCN.
Do this after recording the pre-sync range above, so the KitCN audit still knows
which upstream commits were imported.
If the fork is already at the upstream ref, record fork sync: already synced.
If the fork is behind and not ahead, fast-forward the fork default branch to the
upstream ref and push:
git -C ../convex-better-auth merge-base --is-ancestor \
<fork-remote>/<fork-branch> <upstream-remote>/<upstream-branch>
git -C ../convex-better-auth push <fork-remote> \
refs/remotes/<upstream-remote>/<upstream-branch>:refs/heads/<fork-branch>
git -C ../convex-better-auth fetch <fork-remote> --tags
git -C ../convex-better-auth rev-parse <fork-remote>/<fork-branch>
If the fast-forward push is rejected because the fork default branch is
protected or direct push is not allowed, open a PR in the fork instead:
git -C ../convex-better-auth switch -C sync-upstream-<date> \
<upstream-remote>/<upstream-branch>
git -C ../convex-better-auth push <fork-remote> \
HEAD:refs/heads/sync-upstream-<date>
gh pr create \
--repo zbeyens/convex-better-auth \
--base <fork-branch> \
--head zbeyens:sync-upstream-<date> \
--title "Sync upstream convex-better-auth" \
--body "Fast-forward fork to <upstream-owner>/<repo-name>@<upstream-ref>."
If the fork is ahead of upstream or has diverged, stop and ask before merging,
rebasing, or overwriting anything. Do not force push. Record:
- fork sync status:
already synced, fast-forward pushed,
fork PR opened, blocked: diverged, or blocked: push rejected
- post-sync fork ref or PR URL
- whether KitCN audit continues from the pre-sync range
3. Read The Upstream Diff
Start with a file summary:
git -C ../convex-better-auth diff --name-status \
<pre-sync-fork-ref>..<pre-sync-upstream-ref>
Then read patches for relevant-looking files:
git -C ../convex-better-auth diff \
<pre-sync-fork-ref>..<pre-sync-upstream-ref> -- \
src package.json bun.lock tsconfig.json '*.md' \
':!**/dist/**' ':!**/build/**' ':!**/node_modules/**'
Use gh compare when it gives cleaner commit/file metadata:
gh api \
repos/<upstream-owner>/<repo-name>/compare/<fork-owner>:<fork-branch>...<upstream-branch> \
--jq '.commits[] | {sha: .sha, message: .commit.message}'
gh api \
repos/<upstream-owner>/<repo-name>/compare/<fork-owner>:<fork-branch>...<upstream-branch> \
--jq '.files[] | {filename,status,patch}'
If the compare is too large, group by subsystem first, then inspect the patches
for likely auth-runtime impact.
4. Search Kitcn For Affected Auth Surfaces
Search local kitcn integration points:
rg -n "@convex-dev/better-auth|convexBetterAuth|getToken|convexClient|convex\\(|BetterAuth|better-auth|auth" \
packages www .agents docs tooling fixtures example
Search institutional notes before proposing work:
rg -i --files-with-matches \
"convex-better-auth|@convex-dev/better-auth|better-auth|auth|react-start|nextjs|jwt|jwks|session|cookie|schema|plugin|getToken" \
docs/solutions docs/plans
Read relevant hits, especially notes about:
@convex-dev/better-auth reexports and wrappers
kitcn/auth, kitcn/auth-client, kitcn/auth-nextjs, and
kitcn/auth-start
- Better Auth and Convex version compatibility
- token, JWT, JWKS, cookie, and session handling
- schema generation, plugin reconciliation, and generated auth contracts
- React, Solid, Next.js, and TanStack Start provider behavior
- scaffold templates, docs, and
packages/kitcn/skills/kitcn/**
- local hacks that might be obsolete after upstream changes
5. Classify Every Upstream Change
Classify each commit or file group:
compatibility: required work to keep kitcn working with upstream auth,
Better Auth, Convex, framework, or package changes.
security: auth correctness or security hardening kitcn should not miss.
bugfix: upstream fix that maps to a kitcn runtime, provider, token, schema,
routing, or scaffold issue.
feature: new upstream API, helper, framework support, or auth capability
kitcn can expose cleanly.
cleanup: upstream change that lets kitcn delete a workaround, wrapper,
fallback, doc warning, copied logic, or special-case patch.
docs: upstream change that only affects user-facing docs, setup guidance, or
skills.
tests: upstream test coverage or harness changes.
no-op: interesting upstream change with no kitcn action.
For every non-no-op, include:
- commit evidence
- diff evidence
- local kitcn files affected
- expected implementation surface
- verification command(s)
- confidence
Use this relevance filter:
- Relevant: runtime auth behavior, package exports kitcn imports or reexports,
helpers kitcn wraps, version compatibility, security, framework integration,
schema/plugin behavior, generated code contracts, docs/skills users rely on,
and cleanup of known kitcn workarounds.
- Usually irrelevant: upstream release config, repository-only CI, maintainer
docs, benchmark harnesses, examples that do not map to kitcn scaffolds, and
tests for behavior kitcn neither exposes nor depends on.
- Ambiguous optional: added test suites, e2e harnesses, examples, fixtures,
benchmark tooling, and dev-only utilities. Stop and ask before pulling these
in unless they are the direct verification path for a selected required fix.
6. Choose One Implementation Slice
Pick the highest-leverage slice using this order:
- security fix
- compatibility breakage
- bugfix that affects kitcn users
- delete dirty hack made obsolete upstream
- agentic or DX improvement for deterministic setup, CLI, or generated output
- feature kitcn can expose cleanly
- docs or skill-only update
- optional tests or examples only after user approval
If several relevant upstream fixes touch the same auth surface and do not
conflict, delegate them together. If they touch separate surfaces, pick the
highest-risk slice first.
If the winning slice touches published package code, the delegated task must
update the active changeset and run bun --cwd packages/kitcn build.
If it touches scaffold templates, the delegated task must run
bun run fixtures:sync and bun run fixtures:check.
If it touches auth runtime, client, provider, or query invalidation surfaces,
the delegated task must follow the repo's auth verification lane. Do not import
a slow upstream e2e suite unless the user explicitly approves it.
7. Delegate Through task
Load
$task with a
prompt in this exact shape:
Implement this convex-better-auth sync opportunity.
Fork: zbeyens/convex-better-auth
Upstream: <upstream-owner>/<repo-name>
Range: <fork-ref>..<upstream-ref>
Behind: <count> commits
Fork sync: <already synced | fast-forward pushed | fork PR URL | blocked reason>
Opportunity: <one-sentence selected slice>
Class: <security | compatibility | bugfix | cleanup | agentic | feature | docs | tests>
Evidence:
- Upstream commits: <short commit list or summary>
- Upstream diff: <refs and files>
- Kitcn evidence: <local files and docs/solutions notes>
Implementation:
- <specific files or surfaces to inspect first>
- <expected code/doc/test shape>
- <anything explicitly ignored as irrelevant>
Acceptance:
- <focused tests/checks>
- <package build if packages/kitcn changes>
- <fixtures commands if scaffold output changes>
- open the PR after verification
Do not preserve obsolete auth workarounds if the upstream change removes the
need for them. Hard cut the hack.
Do not add optional slow e2e suites, broad examples, or dev-only upstream test
infrastructure unless the user approved that scope.
Then follow task until the PR exists or a real blocker is proven.
Output
Before delegation, keep the audit terse:
Fork: zbeyens/convex-better-auth
Upstream: <upstream-owner>/<repo-name>
Range: <fork-ref>..<upstream-ref>
Behind: <count>
Fork sync: <status and post-sync ref or PR URL>
| Class | Opportunity | Evidence | Decision |
| ------ | ----------- | -------- | -------- |
| bugfix | ... | ... | selected |
Delegating to task: <selected slice>
If the right choice is ambiguous, stop and ask one pointed question. Example:
Upstream added a Playwright e2e suite that does not fix a current kitcn bug.
Do you want that pulled in, or should I ignore it and keep this sync to runtime
fixes only?
After task finishes, use its final handoff format.