Concave Parity

SkillDev tools

Skill: concave-parity

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Concave Parity skill

What this skill tells your AI

The instructions your AI receives, as published by udecode/kitcn in .agents/skills/concave-parity/SKILL.md and read by ahel’s review.

Contract

When the user asks for Concave parity, treat Convex behavior as the source of truth for kitcn runtime contracts.

Do not hand-wave with "compatible enough."

Do not normalize a parity shift into "just how Concave works" if kitcn already has a shim for it. Name the shift, point at the shim, and state the delete condition.

If upstream Concave reaches parity, delete the bandaid. Do not keep fallback sludge around for nostalgia.

Hard Rules

  • Every Concave-specific workaround must be listed here with file locations.
  • Every new Concave workaround needs a removal trigger.
  • If you touch a listed bandaid, re-check whether upstream parity makes it deletable right now.
  • If the shift only affects repo tooling or scenarios, say that explicitly.
  • If the shift is only observed and not patched, keep it in the watchlist, not the bandaid section.

Active Bandaids

1. Local dev site-side 3211 proxy

Convex local dev shape in this repo:

  • backend on 127.0.0.1:3210
  • site URL on 127.0.0.1:3211
  • frontend app on localhost:3005 in prepared scenarios

Concave alpha.14 fixed the backend default to 3210, but it still does not expose the site side on 3211.

kitcn workaround:

  • start a local site proxy on 3211
  • inject CONVEX_SITE_URL=http://127.0.0.1:3211
  • inject SITE_URL from .env.local

Code locations:

  • packages/kitcn/src/cli/commands/dev.ts
    • resolveConcaveLocalDevContract(...)
    • resolveConcaveLocalSiteUrl(...)
    • startLocalSiteProxy(...)
  • packages/kitcn/src/cli/commands/dev.test.ts
  • tooling/scenarios.ts
    • DEFAULT_SCENARIO_READY_URL
    • readScenarioSiteUrl(...)
  • tooling/scaffold-utils.ts
    • local env patching for 3005

Why it exists:

  • prepared apps and auth wiring already assume the Convex-style split
  • upstream still only exposes the backend side

Delete when:

  • Concave local dev natively supports the same backend/site split contract, or
  • kitcn no longer needs to emulate Convex local URLs for prepared apps

2. Startup retry loop for dev migration/backfill hooks

Convex dev startup usually accepts kitcn migration/backfill hooks cleanly on first call.

Concave alpha.14 fixed concave run for internal runtime functions, but startup can still race readiness.

kitcn workaround:

  • Concave-only retry loop
  • backoff: 1s, 2s, 4s
  • show retry count only while retrying

Code locations:

  • packages/kitcn/src/cli/commands/dev.ts
    • runDevStartupRetryLoop(...)
    • startup migration up and aggregateBackfill kickoff callers
  • packages/kitcn/src/cli/commands/dev.test.ts
  • related notes:
    • docs/solutions/integration-issues/concave-internal-runtime-calls-20260322.md
    • docs/solutions/integration-issues/concave-local-dev-auth-cycle-20260319.md

Why it exists:

  • immediate concave run calls can still hit ECONNREFUSED before local dev is ready

Delete when:

  • Concave local dev exposes a reliable readiness signal integrated into the CLI, or
  • startup hooks become reliably callable with no transient failures

3. Vite scenario backend/frontend split

Prepared Vite scenarios in this repo are supposed to prove:

  • frontend on 3005
  • backend on the kitcn local contract

Concave alpha.14 still auto-detects and starts Vite itself, which steals frontend ownership and lands on 5173.

kitcn workaround:

  • run backend dev with --frontend no
  • run the prepared Vite frontend separately

Code locations:

  • tooling/scenarios.ts
    • buildBackendOnlyDevCommand(...)
    • resolveScenarioDevCommands(...)
  • tooling/scenarios.test.ts
  • related note:
    • docs/solutions/integration-issues/scenario-vite-dev-split-and-react18-runtime-20260322.md

Why it exists:

  • scenario proof should validate the prepared app contract, not Concave's auto-detected default frontend behavior

Delete when:

  • Concave backend-only dev becomes unnecessary for prepared Vite scenarios, or
  • Concave frontend auto-detection respects the prepared dev command/port with no special handling

4. Generated auth runtime fallback for empty Concave internals

Convex-generated _generated/api.js exposes internal refs for generated auth runtime calls.

Concave alpha.14 still leaves prepared auth apps with:

export const internal = {};

That breaks generated auth runtime access like authFunctions.findOne even though the actual function paths are known.

kitcn workaround:

  • synthesize generated auth internal refs from their function path names
  • use createGeneratedFunctionReference(...) instead of trusting Concave's empty internal object

Code locations:

  • packages/kitcn/src/auth/generated-contract.ts
  • packages/kitcn/src/auth/generated-contract.test.ts
  • related note:
    • docs/solutions/integration-issues/concave-alpha14-generated-auth-and-run-output-20260323.md

Why it exists:

  • Concave local codegen/runtime shape is still missing generated auth internal refs that Convex-generated output exposes

Delete when:

  • Concave-generated _generated/api.js includes generated auth internal refs, and
  • prepared auth scenarios no longer need synthesized fallback references

5. Concave run output JSON fallback parsing

Convex-style machine output is clean JSON when kitcn shells out to a backend run command and expects structured results.

Concave alpha.14 now prints a human preamble before the JSON body, for example:

  • Running ...
  • Args: ...
  • URL: ...
  • Success
  • pretty JSON

kitcn workaround:

  • parse a trailing JSON block after the preamble
  • keep the existing one-line JSON path for Convex and any future clean output

Code locations:

  • packages/kitcn/src/cli/backend-core.ts
    • parseBackendRunJson(...)
  • packages/kitcn/src/cli/commands/migrate.test.ts
  • related note:
    • docs/solutions/integration-issues/concave-alpha14-generated-auth-and-run-output-20260323.md

Why it exists:

  • alpha.14 made concave run human-friendlier but less machine-clean for the startup migration and aggregate flows kitcn shells out to

Delete when:

  • concave run exposes clean JSON output by default or under a stable flag we can rely on, and
  • parseBackendRunJson(...) no longer needs the trailing-block fallback

6. Manual static JWKS export command

Convex has an env CLI seam, so kitcn env push can fetch and sync static JWKS.

Concave still has no equivalent upstream env command surface. That means auth runtime parity exists, but env-management parity does not.

kitcn workaround:

  • expose kitcn auth jwks
  • expose kitcn auth jwks --rotate
  • print a manual JWKS=... payload instead of inventing fake env passthrough

Code locations:

  • packages/kitcn/src/cli/commands/auth.ts
  • packages/kitcn/src/cli/commands/auth.test.ts
  • packages/kitcn/src/cli/cli.ts
  • packages/kitcn/src/cli/cli.commands.ts

Why it exists:

  • users still need a manual static JWKS path on backend concave
  • kitcn env is correctly Convex-only today

Delete when:

  • Concave exposes a stable env management seam kitcn can wrap directly, or
  • kitcn ships a real cross-backend env abstraction and no longer needs a JWKS-specific manual helper

Removed Bandaids

Internal runtime execution via /api/execute

Removed in alpha.14 verification.

Old workaround:

  • bypass concave run for generated/server:*
  • POST /api/execute
  • call _system:systemExecuteFunction

Why it died:

  • raw concave run now succeeds for generated/server:migrationRun and generated/aggregate:aggregateBackfill

Forced 3210 dev port on Concave

Removed in alpha.14 verification.

Old workaround:

  • always append --port 3210 to concave dev when kitcn owned local dev boot

Why it died:

  • raw concave dev now defaults to 3210

Source-backed Concave API type override

Removed in alpha.14 verification.

Old workaround:

  • wait briefly after Concave codegen
  • overwrite _generated/api.d.ts with a source-backed version

Why it died:

  • raw concave codegen --static now emits the same api.d.ts shape our override used to force

Watchlist: Known Gaps Without a kitcn Bandaid

staticDataModel mismatch

Current repo truth:

  • fixtures/next/convex.json sets codegen.staticDataModel: true
  • Concave-generated _generated/dataModel.d.ts is still dynamic

Current location:

  • .claude/skills/concave/concave.mdc

Meaning:

  • treat this as an upstream parity gap
  • do not silently document it as if Concave already matches Convex here

Read First

Start with the active bandaid seams:

  • packages/kitcn/src/cli/commands/dev.ts
  • tooling/scenarios.ts

Then read the solution notes:

  • docs/solutions/integration-issues/concave-local-dev-auth-cycle-20260319.md
  • docs/solutions/integration-issues/concave-internal-runtime-calls-20260322.md
  • docs/solutions/integration-issues/concave-alpha14-generated-auth-and-run-output-20260323.md
  • docs/solutions/integration-issues/scenario-vite-dev-split-and-react18-runtime-20260322.md

Verification

When touching any active Concave parity bandaid, run the smallest real gate that proves the seam:

bun test packages/kitcn/src/cli/commands/dev.test.ts \
  packages/kitcn/src/cli/commands/migrate.test.ts \
  packages/kitcn/src/auth/generated-contract.test.ts \
  tooling/scenarios.test.ts

bun run test:concave
bun run scenario:test -- next-auth
bun run scenario:test -- vite

Signals

GitHub stars
447
Forks
34
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
concave-parity
Source
github.com/udecode/kitcn