Commit 7fb70a6
committed
fix(core): narrow the binding rules to what each one protects
Three rules introduced with the bindings reached past the thing they exist
to stop.
`_app.appId` was unique as well as immutable, which made an app's second
card unwritable. `appId` is required, so a replacement card for the same
software necessarily repeats it — and uniqueness then refused exactly the
card key rotation calls for, and the same app registered from a second
device, with no way out but hard-deleting the first card and orphaning the
`principalId` on everything it wrote. Uniqueness bought nothing there:
nothing resolves a card *by* `appId`, the cross-check reaching it by `did`
and only comparing, so `_app.did` alone already gives that lookup its single
answer. Immutability is what stops a card being moved onto a name it did not
have, and immutability stays. Uniqueness now covers the two `did` fields —
the ones something resolves by — and `UNIQUE_BINDING_FIELDS` names that
subset rather than leaving it implied by the immutability list.
The `_app` and owner-DID fences keyed on a field being *present* in the
patch, not on its value changing. Read-modify-write is the ordinary client
shape, so a write-holder sending a card back with `name` edited was refused
for round-tripping bindings it never touched — which made "`name` and
`version` stay writable" false for any client that patches with a whole
content object, and disagreed with `checkBindingImmutable()` and
`restoreVersion()`, both of which already compare values. Both fences now
ask whether the write would introduce or alter the field.
The uniqueness scan materialised the whole family through `queryAllPages()`
before testing it, so a family past that helper's cap turned every create
and update into a `StackQueryError` rather than a conflict. It now uses
`findFirstMatch()`, the same bounded walk the `appId` cross-check added
beside it, and stops at the first clash.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017JmFgdZKqgqPFGoxMBgjwn1 parent 7555861 commit 7fb70a6
4 files changed
Lines changed: 165 additions & 37 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
94 | | - | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
95 | 97 | | |
96 | 98 | | |
97 | 99 | | |
98 | 100 | | |
99 | 101 | | |
100 | | - | |
101 | | - | |
102 | | - | |
103 | | - | |
104 | | - | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
105 | 112 | | |
106 | | - | |
| 113 | + | |
107 | 114 | | |
108 | | - | |
109 | | - | |
| 115 | + | |
110 | 116 | | |
111 | 117 | | |
112 | 118 | | |
| |||
175 | 181 | | |
176 | 182 | | |
177 | 183 | | |
178 | | - | |
| 184 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
84 | 84 | | |
85 | 85 | | |
86 | 86 | | |
87 | | - | |
88 | | - | |
| 87 | + | |
| 88 | + | |
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
94 | 94 | | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
95 | 115 | | |
96 | 116 | | |
97 | 117 | | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
98 | 121 | | |
99 | 122 | | |
100 | 123 | | |
| |||
1297 | 1320 | | |
1298 | 1321 | | |
1299 | 1322 | | |
1300 | | - | |
| 1323 | + | |
1301 | 1324 | | |
1302 | 1325 | | |
1303 | 1326 | | |
1304 | 1327 | | |
1305 | 1328 | | |
1306 | | - | |
| 1329 | + | |
1307 | 1330 | | |
1308 | 1331 | | |
1309 | 1332 | | |
1310 | 1333 | | |
1311 | 1334 | | |
1312 | | - | |
1313 | | - | |
1314 | | - | |
| 1335 | + | |
| 1336 | + | |
| 1337 | + | |
| 1338 | + | |
1315 | 1339 | | |
1316 | 1340 | | |
1317 | 1341 | | |
| |||
1321 | 1345 | | |
1322 | 1346 | | |
1323 | 1347 | | |
| 1348 | + | |
1324 | 1349 | | |
1325 | 1350 | | |
1326 | 1351 | | |
1327 | | - | |
| 1352 | + | |
| 1353 | + | |
| 1354 | + | |
1328 | 1355 | | |
1329 | 1356 | | |
1330 | 1357 | | |
1331 | 1358 | | |
1332 | | - | |
1333 | | - | |
1334 | | - | |
1335 | | - | |
1336 | | - | |
1337 | | - | |
1338 | | - | |
| 1359 | + | |
| 1360 | + | |
| 1361 | + | |
| 1362 | + | |
| 1363 | + | |
| 1364 | + | |
| 1365 | + | |
| 1366 | + | |
| 1367 | + | |
| 1368 | + | |
1339 | 1369 | | |
1340 | 1370 | | |
1341 | 1371 | | |
| |||
1351 | 1381 | | |
1352 | 1382 | | |
1353 | 1383 | | |
1354 | | - | |
1355 | | - | |
1356 | | - | |
1357 | | - | |
1358 | | - | |
| 1384 | + | |
| 1385 | + | |
| 1386 | + | |
| 1387 | + | |
| 1388 | + | |
| 1389 | + | |
| 1390 | + | |
| 1391 | + | |
1359 | 1392 | | |
1360 | | - | |
1361 | | - | |
1362 | 1393 | | |
1363 | 1394 | | |
1364 | 1395 | | |
| |||
2483 | 2514 | | |
2484 | 2515 | | |
2485 | 2516 | | |
2486 | | - | |
2487 | | - | |
| 2517 | + | |
| 2518 | + | |
| 2519 | + | |
| 2520 | + | |
| 2521 | + | |
| 2522 | + | |
| 2523 | + | |
| 2524 | + | |
| 2525 | + | |
| 2526 | + | |
| 2527 | + | |
| 2528 | + | |
| 2529 | + | |
| 2530 | + | |
2488 | 2531 | | |
2489 | 2532 | | |
2490 | 2533 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2344 | 2344 | | |
2345 | 2345 | | |
2346 | 2346 | | |
| 2347 | + | |
| 2348 | + | |
| 2349 | + | |
| 2350 | + | |
| 2351 | + | |
| 2352 | + | |
| 2353 | + | |
| 2354 | + | |
| 2355 | + | |
| 2356 | + | |
| 2357 | + | |
| 2358 | + | |
| 2359 | + | |
| 2360 | + | |
| 2361 | + | |
| 2362 | + | |
| 2363 | + | |
| 2364 | + | |
| 2365 | + | |
| 2366 | + | |
| 2367 | + | |
| 2368 | + | |
| 2369 | + | |
| 2370 | + | |
| 2371 | + | |
| 2372 | + | |
2347 | 2373 | | |
2348 | 2374 | | |
2349 | 2375 | | |
| |||
2443 | 2469 | | |
2444 | 2470 | | |
2445 | 2471 | | |
| 2472 | + | |
| 2473 | + | |
| 2474 | + | |
| 2475 | + | |
| 2476 | + | |
| 2477 | + | |
| 2478 | + | |
| 2479 | + | |
| 2480 | + | |
| 2481 | + | |
| 2482 | + | |
| 2483 | + | |
| 2484 | + | |
| 2485 | + | |
| 2486 | + | |
2446 | 2487 | | |
2447 | 2488 | | |
2448 | 2489 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2994 | 2994 | | |
2995 | 2995 | | |
2996 | 2996 | | |
2997 | | - | |
2998 | | - | |
| 2997 | + | |
| 2998 | + | |
| 2999 | + | |
| 3000 | + | |
| 3001 | + | |
| 3002 | + | |
| 3003 | + | |
| 3004 | + | |
| 3005 | + | |
| 3006 | + | |
| 3007 | + | |
| 3008 | + | |
| 3009 | + | |
| 3010 | + | |
| 3011 | + | |
| 3012 | + | |
| 3013 | + | |
| 3014 | + | |
| 3015 | + | |
| 3016 | + | |
| 3017 | + | |
| 3018 | + | |
| 3019 | + | |
2999 | 3020 | | |
3000 | | - | |
| 3021 | + | |
3001 | 3022 | | |
3002 | 3023 | | |
3003 | 3024 | | |
| |||
3068 | 3089 | | |
3069 | 3090 | | |
3070 | 3091 | | |
| 3092 | + | |
| 3093 | + | |
| 3094 | + | |
| 3095 | + | |
| 3096 | + | |
| 3097 | + | |
| 3098 | + | |
| 3099 | + | |
| 3100 | + | |
| 3101 | + | |
| 3102 | + | |
| 3103 | + | |
| 3104 | + | |
| 3105 | + | |
| 3106 | + | |
| 3107 | + | |
| 3108 | + | |
3071 | 3109 | | |
3072 | 3110 | | |
3073 | 3111 | | |
| |||
0 commit comments