agentsclimarketplace

Concurrency reasoning

Skill pipipip169/fable5-handoff/sources/adamentwistle-fable-skills/concurrency-reasoning

The retirement handoff of Claude Fable 5 - written by the model itself. Domain-neutral discipline files that transfer flagship working method to any model, any agent framework, any team.

Install
npx -y skills add pipipip169/fable5-handoff --skill concurrency-reasoning

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

3 things to look at

  • 25 days oldThe repository was created 25 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Async/concurrent/streaming discipline — five questions (overlapping runs, check-then-act, mutation across await, response ordering, cancellation), idempotent retries, shared-state audit, race amplification. Use for async fan-out, streams/SSE, jobs, caches, or flaky timing-smell bugs.

SKILL.md

3.4 KB, as published. Nobody here has run it

Concurrency Reasoning

Concurrency bugs don't announce themselves in review — the code reads fine sequentially. The discipline is asking a fixed set of questions about every async surface, because the compiler won't.

The core question set (ask for every async/shared surface)

  1. What happens if this runs twice, overlapping? Two clicks, two requests, a retry racing the original, cron overlapping its previous run. If the answer involves corrupted state or double effects, you need a guard (idempotency key, mutex, request de-dupe, disable-on-click).
  2. What happens between the check and the act? Every if (exists) then update on shared state is a TOCTOU window. Close it with atomic operations (upsert, compare-and-swap, unique constraints, transactions) — not with a smaller window.
  3. Who else mutates this while I await? Every await is a yield point: module-level variables, caches, and objects captured by closures can change under you mid-function. Re-read state after awaits if it matters; don't cache pre-await reads across the gap.
  4. What order do these land in? Two in-flight requests resolve in either order. If responses update the same state (search-as-you-type, autosave), guard with sequence numbers / "latest wins" checks / cancellation of the superseded one.
  5. What happens on cancellation/unmount/disconnect mid-flight? Streaming handlers and UI callbacks firing after teardown → guard with abort signals, mounted flags, or subscription cleanup. Partial effects from an aborted multi-step operation need cleanup or resumability.

Retries and exactly-once

  • Retry only idempotent operations — or make them idempotent first (idempotency keys, natural unique constraints). A retried "create" without one is a duplicate.
  • Retries need backoff + jitter + a cap; retrying immediately in a loop is a DoS on your own dependency.
  • Distinguish "the request failed" from "the request's response failed" — the operation may have succeeded server-side. Design reads-back or upserts accordingly.

Shared-state audit (for the diff you're writing)

Enumerate every piece of state your async code touches that outlives one invocation: module globals, singletons, caches, class fields, DB rows, files. For each: who writes it, from how many concurrent contexts, and what serializes those writes? "Nothing serializes them, but it's probably fine" is a bug report from the future.

Debugging suspected races

  • Flaky test / intermittent failure → don't rerun until green. Amplify instead: run 20–100× in a loop, add load, add artificial delays (sleep at suspected interleaving points) to widen the window and make it deterministic.
  • Bisect by interleaving, not by code: log timestamps + IDs at each async boundary and reconstruct the actual order of the failing run.
  • The fix must name the interleaving it prevents. "Added a lock and it stopped failing" without knowing the race is a hidden deadlock waiting.

Deadlock/starvation reflexes

Consistent lock ordering; never hold a lock across an await/IO; timeouts on anything that waits on another party; bounded queues (an unbounded queue turns backpressure into an OOM).

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.