When adding concurrency behavior (locks, in-flight guards, timeouts, retries, sampling), ensure three properties:

1) Atomic “check-and-act” before any await (avoid TOCTOU)

2) Revalidate decisions against a fresh snapshot (avoid stale-snapshot races)

3) Cleanup must drain/await in-flight work even on failure (avoid teardown ordering bugs)

Practical patterns

A) Atomic in-flight reservation

const inFlight = new Set<string>();

async function createSession(id: string) {
  // synchronous check-and-add before any await
  if (inFlight.has(id)) throw new Error('409 conflict');
  inFlight.add(id);
  try {
    // do awaits/spawn here
    await doWork();
  } finally {
    inFlight.delete(id);
  }
}

B) Generation guard for out-of-order async completion

let gen = 0;
const lastApplied = { current: -1 };

async function refresh() {
  const myGen = ++gen;
  const value = await compute();
  if (myGen !== gen) return;         // stale completion
  if (lastApplied.current !== myGen) {
    lastApplied.current = myGen;
    setState(value);
  }
}

C) Double-sample + drift flag

const headBefore = await getPrHead();
const comments = await fetchAllComments();
const headAfter = await getPrHead();
const drift = headBefore !== headAfter;
// If drift, mark threads as staleWorktree or fail-closed.

D) Drain async writes in finally

let outputWrites = Promise.resolve();

try {
  await pumpInputToPty();
  await outputWrites;
  return;
} finally {
  // ensure pending writes finish or are cancelled before teardown
  await outputWrites.catch(() => {});
}

If any change touches session creation, process spawning, locks/reservations, per-attempt retries, terminal/IO pipelines, or sampling across async boundaries, apply this checklist and add regression tests for the “race-changed-decision” branches—not just the happy path.