feat(datastore): the container upstream write envelope and associate part 4/15 (S17 Phase 6 plan: 42/42)
Why
The first container association write. One READ COMMITTED transaction holds the virtual child row's lock, the candidate's own row is read FOR SHARE against a concurrent tombstone, the list is settled, and the insert lands last.
The repair record rides here because the renumber emits it, and it names the parent repositories.id, which is what that field means everywhere else.
The list-repair WARN names the parent under repository_id, the id an operator can look up. npm and Maven name the child surrogate under their own keys, and Name the parent repository in the npm and Maven... (#1437) • Unassigned adds the parent id to their records.
Associate's argument guards get their tests in the next part, which merges right after this one: feat(datastore): container upstream reposition ... (!2844 - merged) • Hayley Swimelar • 19.5.
Datastore only: no route reaches Associate yet, so no e2e scenario or user doc changes here. The scenario catalogs land with test(managementapi): cover the container upstre... (!2859 - merged) • Hayley Swimelar • 19.5, and the user docs with feat(managementapi): container virtual upstream... (!2856 - merged) • Hayley Swimelar • 19.5.
Size
This part is 642 changed lines against main, past the 500 that docs/dev/development-model.md asks a description to justify.
| Group | Changed lines |
|---|---|
Production Go (container_virtual_upstreams.go 352, query_names.go 9, container_virtual_resolution.go 5) |
366 |
Sidecar (container_virtual_upstreams.md) |
160 |
Tests (container_virtual_upstreams_test.go 114, npm_virtual_upstreams_test.go 2) |
116 |
It stays one part because every function in it is on Associate's call path, so a split would land the transaction envelope and its lock order with no caller to review them against.
The stack
Fifteen parts, each stacked on the last, each green on its own, reviewed in this order. Each part stays under 700 changed lines, counted as insertions plus deletions against the part it targets.
The delete guard in part 9 lands before the routes in part 11, so no window exists where a container association is writable without the refusal that protects it.
Related to #314 (closed)