Context

On 2026-09-05 two branches were cut from the same commit within two hours of each other. One filed seven notes for the schedule and parameterization papers and took LIT-144 through LIT-150. The other filed two notes for oHC and the Qwen3.8-Next design report and took LIT-144 and LIT-145.

Both were correct at the moment of filing: luria new lit takes the next free number, and on each branch 144 was free. The codes only disagree once the branches meet, and by then each has been written into cross-references, a changelog fragment, a curation entry and a commit message.

It was caught because one session happened to read the other’s pull request. Nothing else would have caught it. luria lint has no reason to look — each branch is internally consistent — and git merges the two files without conflict, because they have different names and different content. The result would have been two documents claiming LIT-144, discovered whenever someone next followed a link.

Luria has the mechanism already. A scheme with allocate = "merge" mints a temporary code from luria new; the work merges under it; and luria concretize, run where merges serialize, assigns the real number and rewrites every reference in the repository. The old spelling goes into the document’s formerly: list, so a temporary code in an unmerged branch, an old commit message or someone’s notes still resolves. This record has been using allocate = "filing", the default, since adoption.

Decision

LIT, SOTA, ADR and DP allocate at merge.

[luria.schemes.LIT]
allocate = "merge"

luria new lit now prints a temporary code. Contributors write it exactly as they wrote a number before — luria link --fix resolves it, the lint accepts it — and it becomes a real code when the work lands. The trunk guard, luria concretize --check, fails if a temporary code reaches main, so the concretize step cannot be silently skipped.

Alternatives considered

Reserve a range per contributor or per session. Avoids collisions and destroys the property that makes sequential numbering worth having: that the number carries the order things entered the record. Ranges make LIT-144 mean “filed by whoever holds the 140s”, which is information nobody wants.

Merge more often. The advice implicit in the status quo, and it does not survive contact: the two branches here overlapped by ninety minutes. Any workflow with more than one contributor, or one contributor and one agent, produces this. Making the window smaller makes the failure rarer and more surprising, which is worse than making it impossible.

Detect the collision in CI instead. A check that two branches allocated the same code can only run where they meet, which is where concretize already runs — and at that point renumbering is the fix, so the check would be a worse version of the mechanism that already exists.

Keep filing-time allocation and renumber by hand when it happens. What was done this time: the later branch moved to LIT-151/LIT-152, which touched ten files. It is a fine one-off and a bad standing policy, because it depends on someone noticing, and the cost of not noticing is a broken reference that survives indefinitely.

Consequences

Existing codes do not change. Temporary codes appear only on documents filed after this, and only until they merge.

The cost is one command in the workflow — luria concretize where merges serialize — and one moment of unfamiliarity when luria new lit prints LIT-tmp3kf9x instead of a number. That is the trade luria’s own record already made, for the same reason.