docs(specs): S32's resolution reads bound themselves
What
S32 said two things that the resolution reads do not do.
- "S32 does not re-enforce it at read time", of ADR-004's 20-upstream cap.
- "ADR-004 sets no cap on rules per association, and neither does this spec."
Both reads carry a bound today. Each reads one row past it and returns a data error when that row arrives. This amendment records the bounds and why they fail closed instead of truncating.
Why fail closed
A clipped upstream list drops a position. A position resolution never
consults is one whose content never contradicts a sibling's established
absence, so the read answers 404 for an image that exists at the
dropped position. A Docker client caches that 404 as permanent. A
500 is recoverable.
A clipped rule set drops deny rules. A deny that stops denying is
the failure the fail-closed rule path exists to prevent.
At ADR-004's 20 upstreams neither bound fires.
What does not move
The write-side enforcement points stay where the spec already put them.
The 422 on the upstream cap stays with S17's upstream-management
surface. Any cap on rules per association stays with S17's rule-CRUD
surface. The read-side bounds guard the window before those ship, while
direct SQL writes every row in these tables.
Error Cases
Adds one row. A read that exceeds its own bound answers 500 INTERNAL
and never 404. The two failures had no row of their own, and the
infrastructure row they were nearest describes a failed cache or health
read, which they are not.
Merge order
Merge order stays !2741 (merged), then !2743 (merged), then !2756 (merged).
Merge this before the S32 plan's Step 4 MR, which implements the two bounded reads. Until this lands, that MR's code and this spec disagree about whether a read-side bound may exist. Step 4's own description names this MR and the same order.
Related to #291 (closed)