Files
triggerdotdev--trigger.dev/apps
Daniel Sutton f2d9670d0e feat(webapp): resolve which shard an environment mints run roots into
Adds the third stage of the run-id mint gate chain. `resolveMintShard(env)`
returns the shard key an environment mints new roots into: the active shard
list, then a per-env or per-org pin, then a rendezvous hash of the environment
id. With `RUN_OPS_MINT_SHARDS` unset or empty it returns "new", which is
today's behaviour, so this merges inert.

`computeRunIdMintKind` and `mintFlipGrace.ts` are untouched. The grace pattern
is cloned into `mintShardGrace.ts` rather than widened, so the existing
cuid/runOpsId flip grace keeps its behaviour.

Design notes:

- Pure core plus env-bound wrapper, mirroring `runOpsMintKind.server.ts`.
  Determinism is a property of `computeMintShard` for fixed deps; the wrapper
  supplies the clock, exactly as `effectiveMintKind` takes `nowMs`.
- Zero new queries on the trigger hot path. Both pins live in the org override
  blob that `mintRunFriendlyId` already holds.
- HRW scores `sha256(envId \0 key)` at 64 bits, over a sorted key list, with a
  lexicographic tie-break. A 32-bit score collides at our environment count,
  and without the sort two deployments listing the same keys in a different CSV
  order would place environments differently.
- `parseShardCsv` rejects anything outside [a-z0-9] and rejects the reserved
  keys at boot. `generateRunOpsIdV2` throws on an out-of-alphabet char, so an
  unvalidated key would become a throw on the mint path.
- A pin outside the active set falls through to the hash and reports once per
  environment per process. Honouring it would leak the drain the active list
  performs; throwing would fail customer triggers whenever a pinned shard
  drains. The loud-on-unknown-key rule governs reading an id, not writing one.
- "new" is a legal pin value, holding one org or environment on gen-1 while the
  rest of the fleet mints gen-2. Without it, a non-empty active set moves every
  environment at once.
- The active-set grace is stamped by `RUN_OPS_MINT_SHARDS_PREV` and
  `RUN_OPS_MINT_SHARDS_FLIPPED_AT`. A prev list with no timestamp is dropped; a
  timestamp with an empty prev list graces a first activation.

No changeset and no `.server-changes` note: nothing user-visible, and no caller
carries the returned key into an id yet.
2026-08-21 18:01:23 +01:00
..