principle-separate-before-serializing-shared-state: Claude Code skill
Architectural guideline for concurrent actors: eliminate shared mutable state across files or keys first, resorting to locks only when a single writer is strictly required.
npx skills add backnotprop/pstack --skill principle-separate-before-serializing-shared-state -a claude-codeWhat principle-separate-before-serializing-shared-state does
Concurrent writes to shared state cause race conditions that are hard to reproduce. This skill enforces a clear rule: before adding locks or relying on conventions, eliminate the shared target altogether. Each actor gets its own isolated file, branch, or key, and data merges only at the read boundary. For instance, two workers write to indexer-state.json and metrics-state.json rather than modifying one shared state.json.
When a single shared write target is an unavoidable invariant, the principle mandates structural serialization: lockfiles, sequential execution phases, a dedicated single-writer actor, or atomic operations. The guide explicitly treats the reflex of needing a lock as a design smell to investigate.
Because the frontmatter sets disable-model-invocation: true, the assistant treats this skill as an internal architectural constraint rather than an invokable runtime tool.
What it helps with
- eliminate race conditions in concurrent agent workflows
- split shared mutable state into isolated actor-specific files
- structure access via lockfiles or sequential phases when sharing is mandatory
- shift data merging to the read boundary
Example prompts for the agent
- Refactor our background workers using principle-separate-before-serializing-shared-state to avoid race conditions
- Review the shared state files against principle-separate-before-serializing-shared-state guidelines
How to install principle-separate-before-serializing-shared-state
1Skills CLI (Vercel)
npx skills add backnotprop/pstack --skill principle-separate-before-serializing-shared-state -a claude-code2Manually: put the files in place
~/.claude/skills/principle-separate-before-serializing-shared-state/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/principle-separate-before-serializing-shared-state/
1Skills CLI (Vercel)
npx skills add backnotprop/pstack --skill principle-separate-before-serializing-shared-state -a codex2Manually: put the files in place
.agents/skills/principle-separate-before-serializing-shared-state/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add backnotprop/pstack --skill principle-separate-before-serializing-shared-state -a cursor2Manually: put the files in place
.cursor/skills/principle-separate-before-serializing-shared-state/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install backnotprop/pstack principle-separate-before-serializing-shared-state2Manually: put the files in place
.github/skills/principle-separate-before-serializing-shared-state/SKILL.md1Skills CLI (Vercel)
npx skills add backnotprop/pstack --skill principle-separate-before-serializing-shared-state -a gemini-cli2Platform CLI
gemini skills install https://github.com/backnotprop/pstack --path skills/principle-separate-before-serializing-shared-stateManually: put the files in place
.devin/skills/principle-separate-before-serializing-shared-state/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add backnotprop/pstack --skill principle-separate-before-serializing-shared-state -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about principle-separate-before-serializing-shared-state
How do I install principle-separate-before-serializing-shared-state in Claude Code?
Run npx skills add backnotprop/pstack --skill principle-separate-before-serializing-shared-state -a claude-code in your terminal.
What is the main goal of this skill?
It provides an architectural rule that prevents race conditions by isolating write targets per actor instead of immediately adding lock mechanisms.
Why is disable-model-invocation set to true?
This flag keeps the skill as a design guideline in context without exposing it as a callable execution tool.
Source text
SKILL.md · MIT
--- name: principle-separate-before-serializing-shared-state description: "Apply when concurrent actors might write to the same file, branch, key, or state object. Eliminate the sharing first; serialize structurally only when one shared writer is a real invariant." disable-model-invocation: true --- # Separate Before Serializing Shared State When concurrent actors might share mutable state, first ask whether they need the same mutable object. If not, eliminate the sharing. When sharing is real, enforce serialization structurally: lockfiles, sequential phases, exclusive ownership. Instructions and conventions are not concurrency control. **Why:** Concurrent writes to shared state create race conditions that are intermittent, hard to reproduce, and expensive to debug. **Pattern:** 1. **Identify shared mutable state** (files both read and write, branches both push to, APIs both define and consume). 2. **Default: eliminate the shared write target.** Ask: do these actors need one canonical object, or are they publishing independent facts? Give each actor its own owned file, key, branch, or state directory, and merge only at the read/reporting boundary. Two workers writing their own `lastX` field into one `state.json` is still shared mutation. `indexer-state.json` + `metrics-state.json` is not. 3. **Only when one shared write target is a real invariant, serialize access structurally** (lockfiles, sequential phases, single-writer actor, or atomic compare-and-swap). Treat "we need a lock" as a design smell to check, not as the default answer.
© backnotprop · MIT · backnotprop/pstack