Commit 21d3218
authored
cache: the Store admission/serve sidecar seam (RPZ phase 4 prerequisite) (#601)
* cache: the sidecar seam — policy state beside entries, judged at the byte serve
The admission/serve seam RPZ's response-IP phase builds on, policy-free
by itself (docs/rpz-design.md §5.6 item 6). Three pieces:
- CacheEntry carries an atomic sidecar pointer beside its immutable
payload, the same shape as the prefetch claim: opaque policy state a
wired evaluator computed from the entry's own stored records. nil is
load-bearing — unknown, never clean.
- Admission: a single evaluator wired into the Store stamps every entry
at every door — the SetFromResponse funnel, the prefetch CAS
replacement, and the compatibility Set (the audit found three doors
where the design counted on the writer alone). An entry that predates
the wiring is evaluated and stamped by the first decoded serve.
- Serve: a WireHitGate is consulted before every record-bearing byte
serve — the wire-born exact hit, the Msg-born inline byte path, and
the composed chase, which shows the gate one sidecar per segment in
chain order (a whole-chain verdict on the alias would go stale when
the target refreshed under it). A false verdict declines to the
decoded path; composite denial classes carry no records and are not
gated.
Wired through Setup's marker pattern (SidecarPolicyProvider ->
SidecarPolicySetter), first provider wins. Unwired, the seam is one nil
field check per hit: the existing zero-alloc hit-class pins run
unchanged, and every stamp and gate call is mutation-pinned by the seam
tests.
* review: a three-way verdict — pure judgment, restamp on the decoded serve, counting after the commit
Both findings land on the same joint and one contract change closes them:
the gate's boolean became a verdict, and accounting left it entirely.
- Judge{WireHit,WireChase} return Serve, Decode, or Restamp, and are
pure decisions over the sidecars. Decode means policy wants the full
message and the sidecar itself was fine; Restamp means the sidecar is
unusable — unevaluated, or stamped under a generation the gate no
longer accepts. The decoded serve acts on Restamp by re-evaluating the
entry's records and CASing over the judged pointer, stale and nil
alike, so a policy reload no longer strands live entries on the
decoded path until eviction. The verdict is judged once per hit,
before the byte/decoded split, internal serves included — the
Msg-path chase reaches its segments through internal sub-queries,
which is where a stale segment gets its restamp.
- Count{WireHit,WireChase} fire once per byte-served hit, after the
transport accepted the bytes — past the last point a serve can still
fall back to the decoded path (writer readiness, chain mismatch,
build, the fallback sentinel) and be counted a second time by the
policy writer there. A transport failure after the commit counts,
matching the response-counts-as-written parity the serve paths
already keep.
Every placement is pinned: stale-restamp against a nil-only CAS,
fallback-after-approval counting nothing on both the Msg-born and
wire-born paths, committed serves counting exactly once on both, and
the chase count with its segments.
* cache: build the chase sidecar slice only when a gate is wired
Moving the segment array out of the gate branch for the commit-time
count made it visible to escape analysis through the interface call, so
every ungated chase paid a heap allocation the hit-class pins forbid —
CI caught it. The slice is now made on the gated branch only and stays
in scope for the count; an ungated chase touches nothing.
* cache: the chase sidecars travel by value, and a pin holds the gated path to the ungated cost
The gated chase still allocated: the slice handed to JudgeWireChase
escaped through the interface call, so wiring the gate put a heap
allocation on every cache-contained chase hit — the zero-allocation hit
contract holds with policy live, not only without it. The chain is now a
bounded value type (SidecarChain, capacity asserted against the chase
depth at compile time) passed by value through Judge and Count, which
closes the slice-escape class in the type system rather than in review.
The new pin closes the blind spot the finding named: the allocation CI
never wires a gate, so a baseline-relative AllocsPerRun test serves the
exact and chase hits against two caches — one bare, one behind an
allocation-free Serve gate — and refuses any gated surplus. Verified to
fire: an escaping allocation planted on the gated branch reads 3.0
against a 2.0 baseline.1 parent 5fa514e commit 21d3218
9 files changed
Lines changed: 928 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
193 | 193 | | |
194 | 194 | | |
195 | 195 | | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
121 | 121 | | |
122 | 122 | | |
123 | 123 | | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
124 | 130 | | |
125 | 131 | | |
126 | 132 | | |
| |||
1324 | 1330 | | |
1325 | 1331 | | |
1326 | 1332 | | |
| 1333 | + | |
| 1334 | + | |
| 1335 | + | |
| 1336 | + | |
| 1337 | + | |
| 1338 | + | |
1327 | 1339 | | |
1328 | 1340 | | |
1329 | 1341 | | |
| |||
1349 | 1361 | | |
1350 | 1362 | | |
1351 | 1363 | | |
| 1364 | + | |
| 1365 | + | |
| 1366 | + | |
1352 | 1367 | | |
1353 | 1368 | | |
1354 | 1369 | | |
| |||
1360 | 1375 | | |
1361 | 1376 | | |
1362 | 1377 | | |
| 1378 | + | |
| 1379 | + | |
| 1380 | + | |
1363 | 1381 | | |
1364 | 1382 | | |
1365 | 1383 | | |
| |||
1457 | 1475 | | |
1458 | 1476 | | |
1459 | 1477 | | |
| 1478 | + | |
| 1479 | + | |
| 1480 | + | |
| 1481 | + | |
| 1482 | + | |
| 1483 | + | |
| 1484 | + | |
| 1485 | + | |
| 1486 | + | |
| 1487 | + | |
| 1488 | + | |
| 1489 | + | |
| 1490 | + | |
| 1491 | + | |
| 1492 | + | |
| 1493 | + | |
| 1494 | + | |
| 1495 | + | |
1460 | 1496 | | |
1461 | 1497 | | |
1462 | 1498 | | |
| |||
1470 | 1506 | | |
1471 | 1507 | | |
1472 | 1508 | | |
| 1509 | + | |
| 1510 | + | |
| 1511 | + | |
1473 | 1512 | | |
1474 | 1513 | | |
1475 | 1514 | | |
| |||
1487 | 1526 | | |
1488 | 1527 | | |
1489 | 1528 | | |
| 1529 | + | |
| 1530 | + | |
| 1531 | + | |
1490 | 1532 | | |
1491 | 1533 | | |
1492 | 1534 | | |
| |||
1510 | 1552 | | |
1511 | 1553 | | |
1512 | 1554 | | |
| 1555 | + | |
| 1556 | + | |
| 1557 | + | |
1513 | 1558 | | |
1514 | 1559 | | |
1515 | 1560 | | |
| |||
1529 | 1574 | | |
1530 | 1575 | | |
1531 | 1576 | | |
| 1577 | + | |
| 1578 | + | |
| 1579 | + | |
| 1580 | + | |
| 1581 | + | |
| 1582 | + | |
| 1583 | + | |
| 1584 | + | |
| 1585 | + | |
| 1586 | + | |
| 1587 | + | |
| 1588 | + | |
| 1589 | + | |
| 1590 | + | |
| 1591 | + | |
1532 | 1592 | | |
1533 | 1593 | | |
1534 | 1594 | | |
| |||
1649 | 1709 | | |
1650 | 1710 | | |
1651 | 1711 | | |
| 1712 | + | |
1652 | 1713 | | |
1653 | 1714 | | |
1654 | 1715 | | |
1655 | 1716 | | |
| 1717 | + | |
| 1718 | + | |
| 1719 | + | |
| 1720 | + | |
| 1721 | + | |
| 1722 | + | |
| 1723 | + | |
| 1724 | + | |
| 1725 | + | |
| 1726 | + | |
| 1727 | + | |
| 1728 | + | |
1656 | 1729 | | |
1657 | 1730 | | |
1658 | 1731 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
34 | 38 | | |
35 | 39 | | |
36 | 40 | | |
| |||
73 | 77 | | |
74 | 78 | | |
75 | 79 | | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
76 | 99 | | |
77 | 100 | | |
78 | 101 | | |
| |||
106 | 129 | | |
107 | 130 | | |
108 | 131 | | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
109 | 135 | | |
110 | 136 | | |
111 | 137 | | |
| |||
120 | 146 | | |
121 | 147 | | |
122 | 148 | | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
123 | 152 | | |
124 | 153 | | |
125 | 154 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
| 64 | + | |
64 | 65 | | |
65 | 66 | | |
66 | 67 | | |
| |||
0 commit comments