Estimate: 16m · Depends on: 2.1.2, 1.3.1
Wire issue creation in issuesService.createIssue(...) to assign a human-readable key ({PROJECT_KEY}-{n}, e.g. PROD-123) using Story 1.3's per-project key counter, atomically with the issue insert. The counter increment + issue insert happen in one $transaction so two concurrent creates can't collide on the same number.
Why atomic: the key counter is contended — every create in a project reads-then-increments it. Without a transaction + row lock (SELECT … FOR UPDATE on the project counter row, per CLAUDE.md's transaction rules), two simultaneous creates could both read n and both mint PROD-n. Lock the counter row, increment, insert, commit.
createIssue assigns {projectKey}-{n} using 1.3's counter, atomic with the insert, inside one transaction with a FOR UPDATE lock on the counter row.workspacesService.createWorkspace — the existing atomic-multi-write + collision pattern to mirrormotir-core/CLAUDE.md — transaction + FOR UPDATE rules