@pyric/cli 0.1.0-alpha.30.2 → 0.1.0-alpha.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1327) hide show
  1. package/dist/assurance/.generated/conformance-verdicts.d.ts +107 -40
  2. package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
  3. package/dist/assurance/.generated/conformance-verdicts.js +107 -40
  4. package/dist/assurance/.generated/conformance-verdicts.js.map +1 -1
  5. package/dist/assurance/capabilities.d.ts.map +1 -1
  6. package/dist/assurance/capabilities.js +12 -14
  7. package/dist/assurance/capabilities.js.map +1 -1
  8. package/dist/bounded-request.d.ts +27 -5
  9. package/dist/bounded-request.d.ts.map +1 -1
  10. package/dist/bounded-request.js +48 -4
  11. package/dist/bounded-request.js.map +1 -1
  12. package/dist/bridge/client/bridge-url.d.ts +5 -1
  13. package/dist/bridge/client/bridge-url.d.ts.map +1 -1
  14. package/dist/bridge/client/bridge-url.js +5 -1
  15. package/dist/bridge/client/bridge-url.js.map +1 -1
  16. package/dist/bridge/client/bridge.d.ts +9 -3
  17. package/dist/bridge/client/bridge.d.ts.map +1 -1
  18. package/dist/bridge/client/bridge.js +17 -3
  19. package/dist/bridge/client/bridge.js.map +1 -1
  20. package/dist/bridge/frame-output.d.ts.map +1 -1
  21. package/dist/bridge/frame-output.js +46 -0
  22. package/dist/bridge/frame-output.js.map +1 -1
  23. package/dist/bridge/protocol.d.ts +10 -0
  24. package/dist/bridge/protocol.d.ts.map +1 -1
  25. package/dist/bridge/protocol.js +10 -0
  26. package/dist/bridge/protocol.js.map +1 -1
  27. package/dist/bridge/server/in-process.d.ts +16 -7
  28. package/dist/bridge/server/in-process.d.ts.map +1 -1
  29. package/dist/bridge/server/in-process.js +51 -17
  30. package/dist/bridge/server/in-process.js.map +1 -1
  31. package/dist/bridge/server/peer.d.ts +8 -0
  32. package/dist/bridge/server/peer.d.ts.map +1 -1
  33. package/dist/bridge/server/peer.js +10 -0
  34. package/dist/bridge/server/peer.js.map +1 -1
  35. package/dist/bridge/server/standalone.d.ts +7 -2
  36. package/dist/bridge/server/standalone.d.ts.map +1 -1
  37. package/dist/bridge/server/standalone.js +27 -99
  38. package/dist/bridge/server/standalone.js.map +1 -1
  39. package/dist/bridge/surface/arguments/firestore.d.ts +6 -6
  40. package/dist/bridge/surface/arguments/sandbox.d.ts +0 -47
  41. package/dist/bridge/surface/arguments/sandbox.d.ts.map +1 -1
  42. package/dist/bridge/surface/arguments/sandbox.js +2 -59
  43. package/dist/bridge/surface/arguments/sandbox.js.map +1 -1
  44. package/dist/bridge/surface/arguments/seed.d.ts +61 -0
  45. package/dist/bridge/surface/arguments/seed.d.ts.map +1 -0
  46. package/dist/bridge/surface/arguments/seed.js +67 -0
  47. package/dist/bridge/surface/arguments/seed.js.map +1 -0
  48. package/dist/bridge/surface/arguments/storage.d.ts +2 -2
  49. package/dist/bridge/surface/context.d.ts +5 -10
  50. package/dist/bridge/surface/context.d.ts.map +1 -1
  51. package/dist/bridge/surface/context.js +11 -23
  52. package/dist/bridge/surface/context.js.map +1 -1
  53. package/dist/bridge/surface/database-instance-catalog.d.ts +0 -3
  54. package/dist/bridge/surface/database-instance-catalog.d.ts.map +1 -1
  55. package/dist/bridge/surface/database-instance-catalog.js +4 -27
  56. package/dist/bridge/surface/database-instance-catalog.js.map +1 -1
  57. package/dist/bridge/surface/database-instance-project.d.ts +5 -0
  58. package/dist/bridge/surface/database-instance-project.d.ts.map +1 -0
  59. package/dist/bridge/surface/database-instance-project.js +32 -0
  60. package/dist/bridge/surface/database-instance-project.js.map +1 -0
  61. package/dist/bridge/surface/database-instance.d.ts +3 -3
  62. package/dist/bridge/surface/database-instance.d.ts.map +1 -1
  63. package/dist/bridge/surface/database-instance.js +1 -2
  64. package/dist/bridge/surface/database-instance.js.map +1 -1
  65. package/dist/bridge/surface/functions-runtime.d.ts +2 -2
  66. package/dist/bridge/surface/functions-runtime.js +5 -5
  67. package/dist/bridge/surface/functions-runtime.js.map +1 -1
  68. package/dist/bridge/surface/held-identity.d.ts +4 -4
  69. package/dist/bridge/surface/held-identity.d.ts.map +1 -1
  70. package/dist/bridge/surface/held-identity.js.map +1 -1
  71. package/dist/bridge/surface/manifest.sandbox.generated.d.ts +3 -0
  72. package/dist/bridge/surface/manifest.sandbox.generated.d.ts.map +1 -0
  73. package/dist/bridge/surface/manifest.sandbox.generated.js +135 -0
  74. package/dist/bridge/surface/manifest.sandbox.generated.js.map +1 -0
  75. package/dist/bridge/surface/method-types.d.ts +48 -7
  76. package/dist/bridge/surface/method-types.d.ts.map +1 -1
  77. package/dist/bridge/surface/method-types.js +15 -0
  78. package/dist/bridge/surface/method-types.js.map +1 -1
  79. package/dist/bridge/surface/methods/ai_logic/clearScripts.d.ts +2 -1
  80. package/dist/bridge/surface/methods/ai_logic/clearScripts.d.ts.map +1 -1
  81. package/dist/bridge/surface/methods/ai_logic/clearScripts.js +2 -1
  82. package/dist/bridge/surface/methods/ai_logic/clearScripts.js.map +1 -1
  83. package/dist/bridge/surface/methods/ai_logic/script.d.ts +2 -1
  84. package/dist/bridge/surface/methods/ai_logic/script.d.ts.map +1 -1
  85. package/dist/bridge/surface/methods/ai_logic/script.js +2 -1
  86. package/dist/bridge/surface/methods/ai_logic/script.js.map +1 -1
  87. package/dist/bridge/surface/methods/ai_logic/scripts.d.ts +2 -1
  88. package/dist/bridge/surface/methods/ai_logic/scripts.d.ts.map +1 -1
  89. package/dist/bridge/surface/methods/ai_logic/scripts.js +2 -1
  90. package/dist/bridge/surface/methods/ai_logic/scripts.js.map +1 -1
  91. package/dist/bridge/surface/methods/ai_logic/status.d.ts +2 -1
  92. package/dist/bridge/surface/methods/ai_logic/status.d.ts.map +1 -1
  93. package/dist/bridge/surface/methods/ai_logic/status.js +1 -0
  94. package/dist/bridge/surface/methods/ai_logic/status.js.map +1 -1
  95. package/dist/bridge/surface/methods/assurance/attach.d.ts +1 -0
  96. package/dist/bridge/surface/methods/assurance/attach.d.ts.map +1 -1
  97. package/dist/bridge/surface/methods/assurance/attach.js +1 -0
  98. package/dist/bridge/surface/methods/assurance/attach.js.map +1 -1
  99. package/dist/bridge/surface/methods/assurance/canIUse.d.ts +1 -0
  100. package/dist/bridge/surface/methods/assurance/canIUse.d.ts.map +1 -1
  101. package/dist/bridge/surface/methods/assurance/canIUse.js +1 -0
  102. package/dist/bridge/surface/methods/assurance/canIUse.js.map +1 -1
  103. package/dist/bridge/surface/methods/assurance/define.d.ts +1 -0
  104. package/dist/bridge/surface/methods/assurance/define.d.ts.map +1 -1
  105. package/dist/bridge/surface/methods/assurance/define.js +1 -0
  106. package/dist/bridge/surface/methods/assurance/define.js.map +1 -1
  107. package/dist/bridge/surface/methods/assurance/export.d.ts +1 -0
  108. package/dist/bridge/surface/methods/assurance/export.d.ts.map +1 -1
  109. package/dist/bridge/surface/methods/assurance/export.js +1 -0
  110. package/dist/bridge/surface/methods/assurance/export.js.map +1 -1
  111. package/dist/bridge/surface/methods/assurance/inspect.d.ts +1 -0
  112. package/dist/bridge/surface/methods/assurance/inspect.d.ts.map +1 -1
  113. package/dist/bridge/surface/methods/assurance/inspect.js +1 -0
  114. package/dist/bridge/surface/methods/assurance/inspect.js.map +1 -1
  115. package/dist/bridge/surface/methods/assurance/map.d.ts +1 -0
  116. package/dist/bridge/surface/methods/assurance/map.d.ts.map +1 -1
  117. package/dist/bridge/surface/methods/assurance/map.js +1 -0
  118. package/dist/bridge/surface/methods/assurance/map.js.map +1 -1
  119. package/dist/bridge/surface/methods/assurance/minimize.d.ts +1 -0
  120. package/dist/bridge/surface/methods/assurance/minimize.d.ts.map +1 -1
  121. package/dist/bridge/surface/methods/assurance/minimize.js +1 -0
  122. package/dist/bridge/surface/methods/assurance/minimize.js.map +1 -1
  123. package/dist/bridge/surface/methods/assurance/propose.d.ts +1 -0
  124. package/dist/bridge/surface/methods/assurance/propose.d.ts.map +1 -1
  125. package/dist/bridge/surface/methods/assurance/propose.js +1 -0
  126. package/dist/bridge/surface/methods/assurance/propose.js.map +1 -1
  127. package/dist/bridge/surface/methods/assurance/replaySession.d.ts +1 -0
  128. package/dist/bridge/surface/methods/assurance/replaySession.d.ts.map +1 -1
  129. package/dist/bridge/surface/methods/assurance/replaySession.js +1 -0
  130. package/dist/bridge/surface/methods/assurance/replaySession.js.map +1 -1
  131. package/dist/bridge/surface/methods/assurance/run.d.ts +1 -0
  132. package/dist/bridge/surface/methods/assurance/run.d.ts.map +1 -1
  133. package/dist/bridge/surface/methods/assurance/run.js +1 -0
  134. package/dist/bridge/surface/methods/assurance/run.js.map +1 -1
  135. package/dist/bridge/surface/methods/assurance/start.d.ts +1 -0
  136. package/dist/bridge/surface/methods/assurance/start.d.ts.map +1 -1
  137. package/dist/bridge/surface/methods/assurance/start.js +1 -0
  138. package/dist/bridge/surface/methods/assurance/start.js.map +1 -1
  139. package/dist/bridge/surface/methods/assurance/testRulesHosted.d.ts +1 -0
  140. package/dist/bridge/surface/methods/assurance/testRulesHosted.d.ts.map +1 -1
  141. package/dist/bridge/surface/methods/assurance/testRulesHosted.js +1 -0
  142. package/dist/bridge/surface/methods/assurance/testRulesHosted.js.map +1 -1
  143. package/dist/bridge/surface/methods/assurance/verify.d.ts +1 -0
  144. package/dist/bridge/surface/methods/assurance/verify.d.ts.map +1 -1
  145. package/dist/bridge/surface/methods/assurance/verify.js +1 -0
  146. package/dist/bridge/surface/methods/assurance/verify.js.map +1 -1
  147. package/dist/bridge/surface/methods/assurance/verifyCases.d.ts +1 -0
  148. package/dist/bridge/surface/methods/assurance/verifyCases.d.ts.map +1 -1
  149. package/dist/bridge/surface/methods/assurance/verifyCases.js +1 -0
  150. package/dist/bridge/surface/methods/assurance/verifyCases.js.map +1 -1
  151. package/dist/bridge/surface/methods/auth/actAsAdmin.d.ts +2 -1
  152. package/dist/bridge/surface/methods/auth/actAsAdmin.d.ts.map +1 -1
  153. package/dist/bridge/surface/methods/auth/actAsAdmin.js +1 -0
  154. package/dist/bridge/surface/methods/auth/actAsAdmin.js.map +1 -1
  155. package/dist/bridge/surface/methods/auth/actAsAnonymous.d.ts +2 -1
  156. package/dist/bridge/surface/methods/auth/actAsAnonymous.d.ts.map +1 -1
  157. package/dist/bridge/surface/methods/auth/actAsAnonymous.js +1 -0
  158. package/dist/bridge/surface/methods/auth/actAsAnonymous.js.map +1 -1
  159. package/dist/bridge/surface/methods/auth/createCustomToken.d.ts +1 -0
  160. package/dist/bridge/surface/methods/auth/createCustomToken.d.ts.map +1 -1
  161. package/dist/bridge/surface/methods/auth/createCustomToken.js +1 -0
  162. package/dist/bridge/surface/methods/auth/createCustomToken.js.map +1 -1
  163. package/dist/bridge/surface/methods/auth/createUser.d.ts +2 -1
  164. package/dist/bridge/surface/methods/auth/createUser.d.ts.map +1 -1
  165. package/dist/bridge/surface/methods/auth/createUser.js +2 -1
  166. package/dist/bridge/surface/methods/auth/createUser.js.map +1 -1
  167. package/dist/bridge/surface/methods/auth/deleteUser.d.ts +2 -1
  168. package/dist/bridge/surface/methods/auth/deleteUser.d.ts.map +1 -1
  169. package/dist/bridge/surface/methods/auth/deleteUser.js +2 -1
  170. package/dist/bridge/surface/methods/auth/deleteUser.js.map +1 -1
  171. package/dist/bridge/surface/methods/auth/getUser.d.ts +2 -1
  172. package/dist/bridge/surface/methods/auth/getUser.d.ts.map +1 -1
  173. package/dist/bridge/surface/methods/auth/getUser.js +2 -1
  174. package/dist/bridge/surface/methods/auth/getUser.js.map +1 -1
  175. package/dist/bridge/surface/methods/auth/getUserByEmail.d.ts +2 -1
  176. package/dist/bridge/surface/methods/auth/getUserByEmail.d.ts.map +1 -1
  177. package/dist/bridge/surface/methods/auth/getUserByEmail.js +2 -1
  178. package/dist/bridge/surface/methods/auth/getUserByEmail.js.map +1 -1
  179. package/dist/bridge/surface/methods/auth/impersonate.d.ts +2 -1
  180. package/dist/bridge/surface/methods/auth/impersonate.d.ts.map +1 -1
  181. package/dist/bridge/surface/methods/auth/impersonate.js +1 -0
  182. package/dist/bridge/surface/methods/auth/impersonate.js.map +1 -1
  183. package/dist/bridge/surface/methods/auth/importUsers.d.ts +2 -1
  184. package/dist/bridge/surface/methods/auth/importUsers.d.ts.map +1 -1
  185. package/dist/bridge/surface/methods/auth/importUsers.js +3 -2
  186. package/dist/bridge/surface/methods/auth/importUsers.js.map +1 -1
  187. package/dist/bridge/surface/methods/auth/listUsers.d.ts +2 -1
  188. package/dist/bridge/surface/methods/auth/listUsers.d.ts.map +1 -1
  189. package/dist/bridge/surface/methods/auth/listUsers.js +2 -1
  190. package/dist/bridge/surface/methods/auth/listUsers.js.map +1 -1
  191. package/dist/bridge/surface/methods/auth/sessions.d.ts +2 -1
  192. package/dist/bridge/surface/methods/auth/sessions.d.ts.map +1 -1
  193. package/dist/bridge/surface/methods/auth/sessions.js +1 -0
  194. package/dist/bridge/surface/methods/auth/sessions.js.map +1 -1
  195. package/dist/bridge/surface/methods/auth/setCustomUserClaims.d.ts +2 -1
  196. package/dist/bridge/surface/methods/auth/setCustomUserClaims.d.ts.map +1 -1
  197. package/dist/bridge/surface/methods/auth/setCustomUserClaims.js +2 -1
  198. package/dist/bridge/surface/methods/auth/setCustomUserClaims.js.map +1 -1
  199. package/dist/bridge/surface/methods/auth/signInAnonymously.d.ts +2 -1
  200. package/dist/bridge/surface/methods/auth/signInAnonymously.d.ts.map +1 -1
  201. package/dist/bridge/surface/methods/auth/signInAnonymously.js +1 -0
  202. package/dist/bridge/surface/methods/auth/signInAnonymously.js.map +1 -1
  203. package/dist/bridge/surface/methods/auth/signInWithCredential.d.ts +2 -1
  204. package/dist/bridge/surface/methods/auth/signInWithCredential.d.ts.map +1 -1
  205. package/dist/bridge/surface/methods/auth/signInWithCredential.js +1 -0
  206. package/dist/bridge/surface/methods/auth/signInWithCredential.js.map +1 -1
  207. package/dist/bridge/surface/methods/auth/signInWithCustomToken.d.ts +2 -1
  208. package/dist/bridge/surface/methods/auth/signInWithCustomToken.d.ts.map +1 -1
  209. package/dist/bridge/surface/methods/auth/signInWithCustomToken.js +1 -0
  210. package/dist/bridge/surface/methods/auth/signInWithCustomToken.js.map +1 -1
  211. package/dist/bridge/surface/methods/auth/signInWithEmailAndPassword.d.ts +2 -1
  212. package/dist/bridge/surface/methods/auth/signInWithEmailAndPassword.d.ts.map +1 -1
  213. package/dist/bridge/surface/methods/auth/signInWithEmailAndPassword.js +1 -0
  214. package/dist/bridge/surface/methods/auth/signInWithEmailAndPassword.js.map +1 -1
  215. package/dist/bridge/surface/methods/auth/signOut.d.ts +2 -1
  216. package/dist/bridge/surface/methods/auth/signOut.d.ts.map +1 -1
  217. package/dist/bridge/surface/methods/auth/signOut.js +1 -0
  218. package/dist/bridge/surface/methods/auth/signOut.js.map +1 -1
  219. package/dist/bridge/surface/methods/auth/takeAuthMail.d.ts +2 -1
  220. package/dist/bridge/surface/methods/auth/takeAuthMail.d.ts.map +1 -1
  221. package/dist/bridge/surface/methods/auth/takeAuthMail.js +1 -0
  222. package/dist/bridge/surface/methods/auth/takeAuthMail.js.map +1 -1
  223. package/dist/bridge/surface/methods/auth/updateUser.d.ts +2 -1
  224. package/dist/bridge/surface/methods/auth/updateUser.d.ts.map +1 -1
  225. package/dist/bridge/surface/methods/auth/updateUser.js +2 -1
  226. package/dist/bridge/surface/methods/auth/updateUser.js.map +1 -1
  227. package/dist/bridge/surface/methods/auth/useAppSession.d.ts +2 -1
  228. package/dist/bridge/surface/methods/auth/useAppSession.d.ts.map +1 -1
  229. package/dist/bridge/surface/methods/auth/useAppSession.js +1 -0
  230. package/dist/bridge/surface/methods/auth/useAppSession.js.map +1 -1
  231. package/dist/bridge/surface/methods/auth/whoami.d.ts +2 -1
  232. package/dist/bridge/surface/methods/auth/whoami.d.ts.map +1 -1
  233. package/dist/bridge/surface/methods/auth/whoami.js +1 -0
  234. package/dist/bridge/surface/methods/auth/whoami.js.map +1 -1
  235. package/dist/bridge/surface/methods/database/crawl.d.ts +2 -1
  236. package/dist/bridge/surface/methods/database/crawl.d.ts.map +1 -1
  237. package/dist/bridge/surface/methods/database/crawl.js +1 -0
  238. package/dist/bridge/surface/methods/database/crawl.js.map +1 -1
  239. package/dist/bridge/surface/methods/database/get.d.ts +2 -1
  240. package/dist/bridge/surface/methods/database/get.d.ts.map +1 -1
  241. package/dist/bridge/surface/methods/database/get.js +1 -0
  242. package/dist/bridge/surface/methods/database/get.js.map +1 -1
  243. package/dist/bridge/surface/methods/database/push.d.ts +2 -1
  244. package/dist/bridge/surface/methods/database/push.d.ts.map +1 -1
  245. package/dist/bridge/surface/methods/database/push.js +1 -0
  246. package/dist/bridge/surface/methods/database/push.js.map +1 -1
  247. package/dist/bridge/surface/methods/database/query.d.ts +2 -1
  248. package/dist/bridge/surface/methods/database/query.d.ts.map +1 -1
  249. package/dist/bridge/surface/methods/database/query.js +1 -0
  250. package/dist/bridge/surface/methods/database/query.js.map +1 -1
  251. package/dist/bridge/surface/methods/database/remove.d.ts +2 -1
  252. package/dist/bridge/surface/methods/database/remove.d.ts.map +1 -1
  253. package/dist/bridge/surface/methods/database/remove.js +1 -0
  254. package/dist/bridge/surface/methods/database/remove.js.map +1 -1
  255. package/dist/bridge/surface/methods/database/set.d.ts +2 -1
  256. package/dist/bridge/surface/methods/database/set.d.ts.map +1 -1
  257. package/dist/bridge/surface/methods/database/set.js +1 -0
  258. package/dist/bridge/surface/methods/database/set.js.map +1 -1
  259. package/dist/bridge/surface/methods/database/update.d.ts +2 -1
  260. package/dist/bridge/surface/methods/database/update.d.ts.map +1 -1
  261. package/dist/bridge/surface/methods/database/update.js +1 -0
  262. package/dist/bridge/surface/methods/database/update.js.map +1 -1
  263. package/dist/bridge/surface/methods/firestore/addDoc.d.ts +2 -1
  264. package/dist/bridge/surface/methods/firestore/addDoc.d.ts.map +1 -1
  265. package/dist/bridge/surface/methods/firestore/addDoc.js +2 -1
  266. package/dist/bridge/surface/methods/firestore/addDoc.js.map +1 -1
  267. package/dist/bridge/surface/methods/firestore/deleteDoc.d.ts +2 -1
  268. package/dist/bridge/surface/methods/firestore/deleteDoc.d.ts.map +1 -1
  269. package/dist/bridge/surface/methods/firestore/deleteDoc.js +2 -1
  270. package/dist/bridge/surface/methods/firestore/deleteDoc.js.map +1 -1
  271. package/dist/bridge/surface/methods/firestore/discoverPaths.d.ts +2 -1
  272. package/dist/bridge/surface/methods/firestore/discoverPaths.d.ts.map +1 -1
  273. package/dist/bridge/surface/methods/firestore/discoverPaths.js +1 -0
  274. package/dist/bridge/surface/methods/firestore/discoverPaths.js.map +1 -1
  275. package/dist/bridge/surface/methods/firestore/extractIndexes.d.ts +7 -6
  276. package/dist/bridge/surface/methods/firestore/extractIndexes.d.ts.map +1 -1
  277. package/dist/bridge/surface/methods/firestore/extractIndexes.js +1 -0
  278. package/dist/bridge/surface/methods/firestore/extractIndexes.js.map +1 -1
  279. package/dist/bridge/surface/methods/firestore/findCollectionGroup.d.ts +2 -1
  280. package/dist/bridge/surface/methods/firestore/findCollectionGroup.d.ts.map +1 -1
  281. package/dist/bridge/surface/methods/firestore/findCollectionGroup.js +1 -0
  282. package/dist/bridge/surface/methods/firestore/findCollectionGroup.js.map +1 -1
  283. package/dist/bridge/surface/methods/firestore/getAggregateFromServer.d.ts +6 -5
  284. package/dist/bridge/surface/methods/firestore/getAggregateFromServer.d.ts.map +1 -1
  285. package/dist/bridge/surface/methods/firestore/getAggregateFromServer.js +1 -0
  286. package/dist/bridge/surface/methods/firestore/getAggregateFromServer.js.map +1 -1
  287. package/dist/bridge/surface/methods/firestore/getCountFromServer.d.ts +6 -5
  288. package/dist/bridge/surface/methods/firestore/getCountFromServer.d.ts.map +1 -1
  289. package/dist/bridge/surface/methods/firestore/getCountFromServer.js +1 -0
  290. package/dist/bridge/surface/methods/firestore/getCountFromServer.js.map +1 -1
  291. package/dist/bridge/surface/methods/firestore/getDoc.d.ts +2 -1
  292. package/dist/bridge/surface/methods/firestore/getDoc.d.ts.map +1 -1
  293. package/dist/bridge/surface/methods/firestore/getDoc.js +2 -1
  294. package/dist/bridge/surface/methods/firestore/getDoc.js.map +1 -1
  295. package/dist/bridge/surface/methods/firestore/getDocs.d.ts +6 -5
  296. package/dist/bridge/surface/methods/firestore/getDocs.d.ts.map +1 -1
  297. package/dist/bridge/surface/methods/firestore/getDocs.js +2 -1
  298. package/dist/bridge/surface/methods/firestore/getDocs.js.map +1 -1
  299. package/dist/bridge/surface/methods/firestore/setDoc.d.ts +2 -1
  300. package/dist/bridge/surface/methods/firestore/setDoc.d.ts.map +1 -1
  301. package/dist/bridge/surface/methods/firestore/setDoc.js +2 -1
  302. package/dist/bridge/surface/methods/firestore/setDoc.js.map +1 -1
  303. package/dist/bridge/surface/methods/firestore/updateDoc.d.ts +2 -1
  304. package/dist/bridge/surface/methods/firestore/updateDoc.d.ts.map +1 -1
  305. package/dist/bridge/surface/methods/firestore/updateDoc.js +2 -1
  306. package/dist/bridge/surface/methods/firestore/updateDoc.js.map +1 -1
  307. package/dist/bridge/surface/methods/firestore/writeBatch.d.ts +2 -1
  308. package/dist/bridge/surface/methods/firestore/writeBatch.d.ts.map +1 -1
  309. package/dist/bridge/surface/methods/firestore/writeBatch.js +2 -1
  310. package/dist/bridge/surface/methods/firestore/writeBatch.js.map +1 -1
  311. package/dist/bridge/surface/methods/firestore/writeIndexes.d.ts +1 -0
  312. package/dist/bridge/surface/methods/firestore/writeIndexes.d.ts.map +1 -1
  313. package/dist/bridge/surface/methods/firestore/writeIndexes.js +1 -0
  314. package/dist/bridge/surface/methods/firestore/writeIndexes.js.map +1 -1
  315. package/dist/bridge/surface/methods/functions/executions.d.ts +3 -2
  316. package/dist/bridge/surface/methods/functions/executions.d.ts.map +1 -1
  317. package/dist/bridge/surface/methods/functions/executions.js +2 -1
  318. package/dist/bridge/surface/methods/functions/executions.js.map +1 -1
  319. package/dist/bridge/surface/methods/functions/fire.d.ts +1 -0
  320. package/dist/bridge/surface/methods/functions/fire.d.ts.map +1 -1
  321. package/dist/bridge/surface/methods/functions/fire.js +6 -5
  322. package/dist/bridge/surface/methods/functions/fire.js.map +1 -1
  323. package/dist/bridge/surface/methods/functions/listTriggers.d.ts +2 -1
  324. package/dist/bridge/surface/methods/functions/listTriggers.d.ts.map +1 -1
  325. package/dist/bridge/surface/methods/functions/listTriggers.js +1 -0
  326. package/dist/bridge/surface/methods/functions/listTriggers.js.map +1 -1
  327. package/dist/bridge/surface/methods/messaging/deliveries.d.ts +2 -1
  328. package/dist/bridge/surface/methods/messaging/deliveries.d.ts.map +1 -1
  329. package/dist/bridge/surface/methods/messaging/deliveries.js +1 -0
  330. package/dist/bridge/surface/methods/messaging/deliveries.js.map +1 -1
  331. package/dist/bridge/surface/methods/messaging/send.d.ts +2 -1
  332. package/dist/bridge/surface/methods/messaging/send.d.ts.map +1 -1
  333. package/dist/bridge/surface/methods/messaging/send.js +2 -1
  334. package/dist/bridge/surface/methods/messaging/send.js.map +1 -1
  335. package/dist/bridge/surface/methods/messaging/subscribeToTopic.d.ts +2 -1
  336. package/dist/bridge/surface/methods/messaging/subscribeToTopic.d.ts.map +1 -1
  337. package/dist/bridge/surface/methods/messaging/subscribeToTopic.js +1 -0
  338. package/dist/bridge/surface/methods/messaging/subscribeToTopic.js.map +1 -1
  339. package/dist/bridge/surface/methods/messaging/tokens.d.ts +2 -1
  340. package/dist/bridge/surface/methods/messaging/tokens.d.ts.map +1 -1
  341. package/dist/bridge/surface/methods/messaging/tokens.js +1 -0
  342. package/dist/bridge/surface/methods/messaging/tokens.js.map +1 -1
  343. package/dist/bridge/surface/methods/messaging/unsubscribeFromTopic.d.ts +2 -1
  344. package/dist/bridge/surface/methods/messaging/unsubscribeFromTopic.d.ts.map +1 -1
  345. package/dist/bridge/surface/methods/messaging/unsubscribeFromTopic.js +1 -0
  346. package/dist/bridge/surface/methods/messaging/unsubscribeFromTopic.js.map +1 -1
  347. package/dist/bridge/surface/methods/registry.d.ts.map +1 -1
  348. package/dist/bridge/surface/methods/registry.js +2 -8
  349. package/dist/bridge/surface/methods/registry.js.map +1 -1
  350. package/dist/bridge/surface/methods/rules/explainDenial.d.ts +1 -0
  351. package/dist/bridge/surface/methods/rules/explainDenial.d.ts.map +1 -1
  352. package/dist/bridge/surface/methods/rules/explainDenial.js +1 -0
  353. package/dist/bridge/surface/methods/rules/explainDenial.js.map +1 -1
  354. package/dist/bridge/surface/methods/rules/getStdlib.d.ts +1 -0
  355. package/dist/bridge/surface/methods/rules/getStdlib.d.ts.map +1 -1
  356. package/dist/bridge/surface/methods/rules/getStdlib.js +1 -0
  357. package/dist/bridge/surface/methods/rules/getStdlib.js.map +1 -1
  358. package/dist/bridge/surface/methods/rules/lint.d.ts +1 -0
  359. package/dist/bridge/surface/methods/rules/lint.d.ts.map +1 -1
  360. package/dist/bridge/surface/methods/rules/lint.js +1 -0
  361. package/dist/bridge/surface/methods/rules/lint.js.map +1 -1
  362. package/dist/bridge/surface/methods/rules/listStdlib.d.ts +1 -0
  363. package/dist/bridge/surface/methods/rules/listStdlib.d.ts.map +1 -1
  364. package/dist/bridge/surface/methods/rules/listStdlib.js +1 -0
  365. package/dist/bridge/surface/methods/rules/listStdlib.js.map +1 -1
  366. package/dist/bridge/surface/methods/rules/set.d.ts +1 -0
  367. package/dist/bridge/surface/methods/rules/set.d.ts.map +1 -1
  368. package/dist/bridge/surface/methods/rules/set.js +1 -0
  369. package/dist/bridge/surface/methods/rules/set.js.map +1 -1
  370. package/dist/bridge/surface/methods/rules/simulate.d.ts +1 -0
  371. package/dist/bridge/surface/methods/rules/simulate.d.ts.map +1 -1
  372. package/dist/bridge/surface/methods/rules/simulate.js +1 -0
  373. package/dist/bridge/surface/methods/rules/simulate.js.map +1 -1
  374. package/dist/bridge/surface/methods/sandbox/activity.d.ts +2 -1
  375. package/dist/bridge/surface/methods/sandbox/activity.d.ts.map +1 -1
  376. package/dist/bridge/surface/methods/sandbox/activity.js +2 -1
  377. package/dist/bridge/surface/methods/sandbox/activity.js.map +1 -1
  378. package/dist/bridge/surface/methods/sandbox/advanceClock.d.ts +2 -1
  379. package/dist/bridge/surface/methods/sandbox/advanceClock.d.ts.map +1 -1
  380. package/dist/bridge/surface/methods/sandbox/advanceClock.js +1 -0
  381. package/dist/bridge/surface/methods/sandbox/advanceClock.js.map +1 -1
  382. package/dist/bridge/surface/methods/sandbox/apply.d.ts +1 -0
  383. package/dist/bridge/surface/methods/sandbox/apply.d.ts.map +1 -1
  384. package/dist/bridge/surface/methods/sandbox/apply.js +1 -0
  385. package/dist/bridge/surface/methods/sandbox/apply.js.map +1 -1
  386. package/dist/bridge/surface/methods/sandbox/checkpoint.d.ts +1 -0
  387. package/dist/bridge/surface/methods/sandbox/checkpoint.d.ts.map +1 -1
  388. package/dist/bridge/surface/methods/sandbox/checkpoint.js +1 -0
  389. package/dist/bridge/surface/methods/sandbox/checkpoint.js.map +1 -1
  390. package/dist/bridge/surface/methods/sandbox/deleteCapture.d.ts +1 -0
  391. package/dist/bridge/surface/methods/sandbox/deleteCapture.d.ts.map +1 -1
  392. package/dist/bridge/surface/methods/sandbox/deleteCapture.js +1 -1
  393. package/dist/bridge/surface/methods/sandbox/deleteCapture.js.map +1 -1
  394. package/dist/bridge/surface/methods/sandbox/deleteCheckpoint.d.ts +1 -0
  395. package/dist/bridge/surface/methods/sandbox/deleteCheckpoint.d.ts.map +1 -1
  396. package/dist/bridge/surface/methods/sandbox/deleteCheckpoint.js +1 -0
  397. package/dist/bridge/surface/methods/sandbox/deleteCheckpoint.js.map +1 -1
  398. package/dist/bridge/surface/methods/sandbox/diff.d.ts +1 -0
  399. package/dist/bridge/surface/methods/sandbox/diff.d.ts.map +1 -1
  400. package/dist/bridge/surface/methods/sandbox/diff.js +1 -0
  401. package/dist/bridge/surface/methods/sandbox/diff.js.map +1 -1
  402. package/dist/bridge/surface/methods/sandbox/discard.d.ts +1 -0
  403. package/dist/bridge/surface/methods/sandbox/discard.d.ts.map +1 -1
  404. package/dist/bridge/surface/methods/sandbox/discard.js +1 -0
  405. package/dist/bridge/surface/methods/sandbox/discard.js.map +1 -1
  406. package/dist/bridge/surface/methods/sandbox/events.d.ts +2 -1
  407. package/dist/bridge/surface/methods/sandbox/events.d.ts.map +1 -1
  408. package/dist/bridge/surface/methods/sandbox/events.js +2 -1
  409. package/dist/bridge/surface/methods/sandbox/events.js.map +1 -1
  410. package/dist/bridge/surface/methods/sandbox/exportFixture.d.ts +1 -0
  411. package/dist/bridge/surface/methods/sandbox/exportFixture.d.ts.map +1 -1
  412. package/dist/bridge/surface/methods/sandbox/exportFixture.js +1 -0
  413. package/dist/bridge/surface/methods/sandbox/exportFixture.js.map +1 -1
  414. package/dist/bridge/surface/methods/sandbox/fork.d.ts +1 -0
  415. package/dist/bridge/surface/methods/sandbox/fork.d.ts.map +1 -1
  416. package/dist/bridge/surface/methods/sandbox/fork.js +1 -0
  417. package/dist/bridge/surface/methods/sandbox/fork.js.map +1 -1
  418. package/dist/bridge/surface/methods/sandbox/inspect.d.ts +2 -1
  419. package/dist/bridge/surface/methods/sandbox/inspect.d.ts.map +1 -1
  420. package/dist/bridge/surface/methods/sandbox/inspect.js +2 -1
  421. package/dist/bridge/surface/methods/sandbox/inspect.js.map +1 -1
  422. package/dist/bridge/surface/methods/sandbox/listBranches.d.ts +1 -0
  423. package/dist/bridge/surface/methods/sandbox/listBranches.d.ts.map +1 -1
  424. package/dist/bridge/surface/methods/sandbox/listBranches.js +1 -0
  425. package/dist/bridge/surface/methods/sandbox/listBranches.js.map +1 -1
  426. package/dist/bridge/surface/methods/sandbox/listCaptures.d.ts +1 -0
  427. package/dist/bridge/surface/methods/sandbox/listCaptures.d.ts.map +1 -1
  428. package/dist/bridge/surface/methods/sandbox/listCaptures.js +1 -1
  429. package/dist/bridge/surface/methods/sandbox/listCaptures.js.map +1 -1
  430. package/dist/bridge/surface/methods/sandbox/listCheckpoints.d.ts +1 -0
  431. package/dist/bridge/surface/methods/sandbox/listCheckpoints.d.ts.map +1 -1
  432. package/dist/bridge/surface/methods/sandbox/listCheckpoints.js +1 -0
  433. package/dist/bridge/surface/methods/sandbox/listCheckpoints.js.map +1 -1
  434. package/dist/bridge/surface/methods/sandbox/listeners.d.ts +2 -1
  435. package/dist/bridge/surface/methods/sandbox/listeners.d.ts.map +1 -1
  436. package/dist/bridge/surface/methods/sandbox/listeners.js +1 -0
  437. package/dist/bridge/surface/methods/sandbox/listeners.js.map +1 -1
  438. package/dist/bridge/surface/methods/sandbox/openCapture.d.ts +1 -0
  439. package/dist/bridge/surface/methods/sandbox/openCapture.d.ts.map +1 -1
  440. package/dist/bridge/surface/methods/sandbox/openCapture.js +1 -1
  441. package/dist/bridge/surface/methods/sandbox/openCapture.js.map +1 -1
  442. package/dist/bridge/surface/methods/sandbox/promote.d.ts +1 -0
  443. package/dist/bridge/surface/methods/sandbox/promote.d.ts.map +1 -1
  444. package/dist/bridge/surface/methods/sandbox/promote.js +1 -0
  445. package/dist/bridge/surface/methods/sandbox/promote.js.map +1 -1
  446. package/dist/bridge/surface/methods/sandbox/renameCapture.d.ts +3 -2
  447. package/dist/bridge/surface/methods/sandbox/renameCapture.d.ts.map +1 -1
  448. package/dist/bridge/surface/methods/sandbox/renameCapture.js +1 -1
  449. package/dist/bridge/surface/methods/sandbox/renameCapture.js.map +1 -1
  450. package/dist/bridge/surface/methods/sandbox/reset.d.ts +3 -2
  451. package/dist/bridge/surface/methods/sandbox/reset.d.ts.map +1 -1
  452. package/dist/bridge/surface/methods/sandbox/reset.js +1 -0
  453. package/dist/bridge/surface/methods/sandbox/reset.js.map +1 -1
  454. package/dist/bridge/surface/methods/sandbox/resetClock.d.ts +2 -1
  455. package/dist/bridge/surface/methods/sandbox/resetClock.d.ts.map +1 -1
  456. package/dist/bridge/surface/methods/sandbox/resetClock.js +1 -0
  457. package/dist/bridge/surface/methods/sandbox/resetClock.js.map +1 -1
  458. package/dist/bridge/surface/methods/sandbox/restore.d.ts +1 -0
  459. package/dist/bridge/surface/methods/sandbox/restore.d.ts.map +1 -1
  460. package/dist/bridge/surface/methods/sandbox/restore.js +1 -0
  461. package/dist/bridge/surface/methods/sandbox/restore.js.map +1 -1
  462. package/dist/bridge/surface/methods/sandbox/saveCapture.d.ts +1 -0
  463. package/dist/bridge/surface/methods/sandbox/saveCapture.d.ts.map +1 -1
  464. package/dist/bridge/surface/methods/sandbox/saveCapture.js +1 -1
  465. package/dist/bridge/surface/methods/sandbox/saveCapture.js.map +1 -1
  466. package/dist/bridge/surface/methods/sandbox/seed.d.ts +2 -1
  467. package/dist/bridge/surface/methods/sandbox/seed.d.ts.map +1 -1
  468. package/dist/bridge/surface/methods/sandbox/seed.js +3 -2
  469. package/dist/bridge/surface/methods/sandbox/seed.js.map +1 -1
  470. package/dist/bridge/surface/methods/sandbox/seedFromFixture.d.ts +1 -0
  471. package/dist/bridge/surface/methods/sandbox/seedFromFixture.d.ts.map +1 -1
  472. package/dist/bridge/surface/methods/sandbox/seedFromFixture.js +1 -0
  473. package/dist/bridge/surface/methods/sandbox/seedFromFixture.js.map +1 -1
  474. package/dist/bridge/surface/methods/sandbox/setClock.d.ts +2 -1
  475. package/dist/bridge/surface/methods/sandbox/setClock.d.ts.map +1 -1
  476. package/dist/bridge/surface/methods/sandbox/setClock.js +1 -0
  477. package/dist/bridge/surface/methods/sandbox/setClock.js.map +1 -1
  478. package/dist/bridge/surface/methods/sandbox-registry.d.ts +6 -0
  479. package/dist/bridge/surface/methods/sandbox-registry.d.ts.map +1 -0
  480. package/dist/bridge/surface/methods/sandbox-registry.js +21 -0
  481. package/dist/bridge/surface/methods/sandbox-registry.js.map +1 -0
  482. package/dist/bridge/surface/methods/storage/deleteObject.d.ts +2 -1
  483. package/dist/bridge/surface/methods/storage/deleteObject.d.ts.map +1 -1
  484. package/dist/bridge/surface/methods/storage/deleteObject.js +1 -0
  485. package/dist/bridge/surface/methods/storage/deleteObject.js.map +1 -1
  486. package/dist/bridge/surface/methods/storage/getBytes.d.ts +2 -1
  487. package/dist/bridge/surface/methods/storage/getBytes.d.ts.map +1 -1
  488. package/dist/bridge/surface/methods/storage/getBytes.js +1 -0
  489. package/dist/bridge/surface/methods/storage/getBytes.js.map +1 -1
  490. package/dist/bridge/surface/methods/storage/getDownloadURL.d.ts +2 -1
  491. package/dist/bridge/surface/methods/storage/getDownloadURL.d.ts.map +1 -1
  492. package/dist/bridge/surface/methods/storage/getDownloadURL.js +1 -0
  493. package/dist/bridge/surface/methods/storage/getDownloadURL.js.map +1 -1
  494. package/dist/bridge/surface/methods/storage/getMetadata.d.ts +2 -1
  495. package/dist/bridge/surface/methods/storage/getMetadata.d.ts.map +1 -1
  496. package/dist/bridge/surface/methods/storage/getMetadata.js +1 -0
  497. package/dist/bridge/surface/methods/storage/getMetadata.js.map +1 -1
  498. package/dist/bridge/surface/methods/storage/listAll.d.ts +2 -1
  499. package/dist/bridge/surface/methods/storage/listAll.d.ts.map +1 -1
  500. package/dist/bridge/surface/methods/storage/listAll.js +1 -0
  501. package/dist/bridge/surface/methods/storage/listAll.js.map +1 -1
  502. package/dist/bridge/surface/methods/storage/provision.d.ts +1 -0
  503. package/dist/bridge/surface/methods/storage/provision.d.ts.map +1 -1
  504. package/dist/bridge/surface/methods/storage/provision.js +1 -0
  505. package/dist/bridge/surface/methods/storage/provision.js.map +1 -1
  506. package/dist/bridge/surface/methods/storage/setCrossServiceIam.d.ts +2 -1
  507. package/dist/bridge/surface/methods/storage/setCrossServiceIam.d.ts.map +1 -1
  508. package/dist/bridge/surface/methods/storage/setCrossServiceIam.js +1 -0
  509. package/dist/bridge/surface/methods/storage/setCrossServiceIam.js.map +1 -1
  510. package/dist/bridge/surface/methods/storage/status.d.ts +1 -0
  511. package/dist/bridge/surface/methods/storage/status.d.ts.map +1 -1
  512. package/dist/bridge/surface/methods/storage/status.js +1 -0
  513. package/dist/bridge/surface/methods/storage/status.js.map +1 -1
  514. package/dist/bridge/surface/methods/storage/updateMetadata.d.ts +6 -5
  515. package/dist/bridge/surface/methods/storage/updateMetadata.d.ts.map +1 -1
  516. package/dist/bridge/surface/methods/storage/updateMetadata.js +1 -0
  517. package/dist/bridge/surface/methods/storage/updateMetadata.js.map +1 -1
  518. package/dist/bridge/surface/methods/storage/uploadBytes.d.ts +1 -0
  519. package/dist/bridge/surface/methods/storage/uploadBytes.d.ts.map +1 -1
  520. package/dist/bridge/surface/methods/storage/uploadBytes.js +1 -0
  521. package/dist/bridge/surface/methods/storage/uploadBytes.js.map +1 -1
  522. package/dist/bridge/surface/render/discriminator-schemas.d.ts +2 -2
  523. package/dist/bridge/surface/request-instant.d.ts +2 -2
  524. package/dist/bridge/surface/request-instant.d.ts.map +1 -1
  525. package/dist/bridge/surface/request-instant.js.map +1 -1
  526. package/dist/bridge/surface/rules-engines/database.d.ts.map +1 -1
  527. package/dist/bridge/surface/rules-engines/database.js +1 -2
  528. package/dist/bridge/surface/rules-engines/database.js.map +1 -1
  529. package/dist/bridge/surface/rules-engines/storage-request-resource.d.ts +38 -0
  530. package/dist/bridge/surface/rules-engines/storage-request-resource.d.ts.map +1 -0
  531. package/dist/bridge/surface/rules-engines/storage-request-resource.js +246 -0
  532. package/dist/bridge/surface/rules-engines/storage-request-resource.js.map +1 -0
  533. package/dist/bridge/surface/rules-engines/storage.d.ts.map +1 -1
  534. package/dist/bridge/surface/rules-engines/storage.js +44 -65
  535. package/dist/bridge/surface/rules-engines/storage.js.map +1 -1
  536. package/dist/bridge/surface/sandbox-context.d.ts +25 -0
  537. package/dist/bridge/surface/sandbox-context.d.ts.map +1 -0
  538. package/dist/bridge/surface/sandbox-context.js +29 -0
  539. package/dist/bridge/surface/sandbox-context.js.map +1 -0
  540. package/dist/bridge/surface/service-handles.d.ts +6 -6
  541. package/dist/bridge/surface/service-handles.d.ts.map +1 -1
  542. package/dist/bridge/surface/service-handles.js +7 -4
  543. package/dist/bridge/surface/service-handles.js.map +1 -1
  544. package/dist/bridge/surface/sign-in.d.ts +2 -2
  545. package/dist/bridge/surface/sign-in.d.ts.map +1 -1
  546. package/dist/bridge/surface/sign-in.js +1 -1
  547. package/dist/bridge/surface/sign-in.js.map +1 -1
  548. package/dist/bridge/surface/storage-rules.d.ts +2 -9
  549. package/dist/bridge/surface/storage-rules.d.ts.map +1 -1
  550. package/dist/bridge/surface/storage-rules.js +0 -10
  551. package/dist/bridge/surface/storage-rules.js.map +1 -1
  552. package/dist/bridge/surface/stored-identity.d.ts +3 -3
  553. package/dist/bridge/surface/stored-identity.d.ts.map +1 -1
  554. package/dist/bridge/surface/stored-identity.js.map +1 -1
  555. package/dist/bridge/surface/types.d.ts +29 -8
  556. package/dist/bridge/surface/types.d.ts.map +1 -1
  557. package/dist/cli/firebase-json.d.ts +35 -7
  558. package/dist/cli/firebase-json.d.ts.map +1 -1
  559. package/dist/cli/firebase-json.js +13 -0
  560. package/dist/cli/firebase-json.js.map +1 -1
  561. package/dist/cli/firestore-indexes.d.ts.map +1 -1
  562. package/dist/cli/firestore-indexes.js +2 -1
  563. package/dist/cli/firestore-indexes.js.map +1 -1
  564. package/dist/cli/index.d.ts +6 -0
  565. package/dist/cli/index.d.ts.map +1 -1
  566. package/dist/cli/index.js +44 -11
  567. package/dist/cli/index.js.map +1 -1
  568. package/dist/cli/public-dir-hint.d.ts +8 -0
  569. package/dist/cli/public-dir-hint.d.ts.map +1 -0
  570. package/dist/cli/public-dir-hint.js +30 -0
  571. package/dist/cli/public-dir-hint.js.map +1 -0
  572. package/dist/cli/run.d.ts +8 -2
  573. package/dist/cli/run.d.ts.map +1 -1
  574. package/dist/cli/run.js +28 -5
  575. package/dist/cli/run.js.map +1 -1
  576. package/dist/cli/sandbox-runner.d.ts.map +1 -1
  577. package/dist/cli/sandbox-runner.js +11 -2
  578. package/dist/cli/sandbox-runner.js.map +1 -1
  579. package/dist/cli/serve-diagnostics.d.ts.map +1 -1
  580. package/dist/cli/serve-diagnostics.js +11 -1
  581. package/dist/cli/serve-diagnostics.js.map +1 -1
  582. package/dist/cli/serve.d.ts.map +1 -1
  583. package/dist/cli/serve.js +25 -24
  584. package/dist/cli/serve.js.map +1 -1
  585. package/dist/cli/snapshot.d.ts.map +1 -1
  586. package/dist/cli/snapshot.js +13 -5
  587. package/dist/cli/snapshot.js.map +1 -1
  588. package/dist/cli/surface-method-runner.js +1 -1
  589. package/dist/cli/surface-method-runner.js.map +1 -1
  590. package/dist/cli/verify.d.ts.map +1 -1
  591. package/dist/cli/verify.js +10 -1
  592. package/dist/cli/verify.js.map +1 -1
  593. package/dist/conformance/.generated/can-i-use-browser.d.ts.map +1 -1
  594. package/dist/conformance/.generated/can-i-use-browser.js +19 -3
  595. package/dist/conformance/.generated/can-i-use-browser.js.map +1 -1
  596. package/dist/conformance/.generated/can-i-use.d.ts.map +1 -1
  597. package/dist/conformance/.generated/can-i-use.js +1 -1
  598. package/dist/conformance/.generated/can-i-use.js.map +1 -1
  599. package/dist/conformance/.generated/conformance-docs.d.ts.map +1 -1
  600. package/dist/conformance/.generated/conformance-docs.js +1 -1
  601. package/dist/conformance/.generated/conformance-docs.js.map +1 -1
  602. package/dist/conformance/.generated/served-availability.d.ts.map +1 -1
  603. package/dist/conformance/.generated/served-availability.js +1 -1
  604. package/dist/conformance/.generated/served-availability.js.map +1 -1
  605. package/dist/discover/merge.d.ts.map +1 -1
  606. package/dist/discover/merge.js +11 -3
  607. package/dist/discover/merge.js.map +1 -1
  608. package/dist/functions/child-protocol.d.ts +43 -0
  609. package/dist/functions/child-protocol.d.ts.map +1 -0
  610. package/dist/functions/child-protocol.js +14 -0
  611. package/dist/functions/child-protocol.js.map +1 -0
  612. package/dist/functions/child.d.ts +2 -0
  613. package/dist/functions/child.d.ts.map +1 -0
  614. package/dist/functions/child.js +92 -0
  615. package/dist/functions/child.js.map +1 -0
  616. package/dist/{functions-rtdb → functions}/development-runtime.d.ts +5 -4
  617. package/dist/functions/development-runtime.d.ts.map +1 -0
  618. package/dist/{functions-rtdb → functions}/development-runtime.js +2 -2
  619. package/dist/functions/development-runtime.js.map +1 -0
  620. package/dist/functions/endpoints.d.ts +39 -0
  621. package/dist/functions/endpoints.d.ts.map +1 -0
  622. package/dist/functions/endpoints.js +48 -0
  623. package/dist/functions/endpoints.js.map +1 -0
  624. package/dist/functions/events.d.ts.map +1 -0
  625. package/dist/functions/events.js.map +1 -0
  626. package/dist/functions/execution-log.d.ts.map +1 -0
  627. package/dist/functions/execution-log.js.map +1 -0
  628. package/dist/functions/module-loader.d.ts.map +1 -0
  629. package/dist/functions/module-loader.js.map +1 -0
  630. package/dist/functions/project.d.ts +7 -0
  631. package/dist/functions/project.d.ts.map +1 -0
  632. package/dist/{functions-rtdb → functions}/project.js +1 -1
  633. package/dist/functions/project.js.map +1 -0
  634. package/dist/functions/rtdb/child-runtime.d.ts +23 -0
  635. package/dist/functions/rtdb/child-runtime.d.ts.map +1 -0
  636. package/dist/functions/rtdb/child-runtime.js +102 -0
  637. package/dist/functions/rtdb/child-runtime.js.map +1 -0
  638. package/dist/functions/rtdb/delivery.d.ts.map +1 -0
  639. package/dist/functions/rtdb/delivery.js.map +1 -0
  640. package/dist/{functions-rtdb → functions/rtdb}/discovery.d.ts +3 -20
  641. package/dist/functions/rtdb/discovery.d.ts.map +1 -0
  642. package/dist/{functions-rtdb → functions/rtdb}/discovery.js +6 -21
  643. package/dist/functions/rtdb/discovery.js.map +1 -0
  644. package/dist/functions/rtdb/event.d.ts.map +1 -0
  645. package/dist/functions/rtdb/event.js.map +1 -0
  646. package/dist/functions/rtdb/execution.d.ts.map +1 -0
  647. package/dist/functions/rtdb/execution.js.map +1 -0
  648. package/dist/functions/rtdb/in-memory-delivery.d.ts.map +1 -0
  649. package/dist/functions/rtdb/in-memory-delivery.js.map +1 -0
  650. package/dist/functions/rtdb/projection.d.ts.map +1 -0
  651. package/dist/functions/rtdb/projection.js.map +1 -0
  652. package/dist/functions/rtdb/reference-pattern.d.ts.map +1 -0
  653. package/dist/functions/rtdb/reference-pattern.js.map +1 -0
  654. package/dist/{functions-rtdb → functions/rtdb}/remote-delivery.d.ts +1 -1
  655. package/dist/functions/rtdb/remote-delivery.d.ts.map +1 -0
  656. package/dist/functions/rtdb/remote-delivery.js.map +1 -0
  657. package/dist/{functions-rtdb/child.d.ts → functions/spawn.d.ts} +16 -38
  658. package/dist/functions/spawn.d.ts.map +1 -0
  659. package/dist/functions/spawn.js +166 -0
  660. package/dist/functions/spawn.js.map +1 -0
  661. package/dist/functions/unsupported.d.ts +23 -0
  662. package/dist/functions/unsupported.d.ts.map +1 -0
  663. package/dist/functions/unsupported.js +25 -0
  664. package/dist/functions/unsupported.js.map +1 -0
  665. package/dist/google-endpoints.d.ts +9 -2
  666. package/dist/google-endpoints.d.ts.map +1 -1
  667. package/dist/google-endpoints.js +72 -3
  668. package/dist/google-endpoints.js.map +1 -1
  669. package/dist/next/bridge-import-loader.d.ts +9 -0
  670. package/dist/next/bridge-import-loader.d.ts.map +1 -0
  671. package/dist/next/bridge-import-loader.js +45 -0
  672. package/dist/next/bridge-import-loader.js.map +1 -0
  673. package/dist/next/bridge-imports.d.ts +26 -0
  674. package/dist/next/bridge-imports.d.ts.map +1 -0
  675. package/dist/next/bridge-imports.js +90 -0
  676. package/dist/next/bridge-imports.js.map +1 -0
  677. package/dist/next/client-aliases.d.ts +13 -5
  678. package/dist/next/client-aliases.d.ts.map +1 -1
  679. package/dist/next/client-aliases.js +14 -27
  680. package/dist/next/client-aliases.js.map +1 -1
  681. package/dist/next/guard.d.ts +3 -2
  682. package/dist/next/guard.d.ts.map +1 -1
  683. package/dist/next/guard.js +28 -10
  684. package/dist/next/guard.js.map +1 -1
  685. package/dist/next/turbopack-config.d.ts +9 -0
  686. package/dist/next/turbopack-config.d.ts.map +1 -1
  687. package/dist/next/turbopack-config.js +21 -0
  688. package/dist/next/turbopack-config.js.map +1 -1
  689. package/dist/next/webpack-config.d.ts +9 -0
  690. package/dist/next/webpack-config.d.ts.map +1 -1
  691. package/dist/next/webpack-config.js +18 -0
  692. package/dist/next/webpack-config.js.map +1 -1
  693. package/dist/next/with-pyric.d.ts +1 -0
  694. package/dist/next/with-pyric.d.ts.map +1 -1
  695. package/dist/next/with-pyric.js +25 -0
  696. package/dist/next/with-pyric.js.map +1 -1
  697. package/dist/register/activation.d.ts +16 -0
  698. package/dist/register/activation.d.ts.map +1 -0
  699. package/dist/register/activation.js +22 -0
  700. package/dist/register/activation.js.map +1 -0
  701. package/dist/register/app-bridge-admin-app-check.d.ts.map +1 -1
  702. package/dist/register/app-bridge-admin-app-check.js +3 -1
  703. package/dist/register/app-bridge-admin-app-check.js.map +1 -1
  704. package/dist/register/child-process-guard.d.ts +43 -0
  705. package/dist/register/child-process-guard.d.ts.map +1 -0
  706. package/dist/register/child-process-guard.js +165 -0
  707. package/dist/register/child-process-guard.js.map +1 -0
  708. package/dist/register/client/bootstrap.js +6 -1
  709. package/dist/register/client/bootstrap.js.map +1 -1
  710. package/dist/register/connect-prototypes.d.ts +9 -0
  711. package/dist/register/connect-prototypes.d.ts.map +1 -1
  712. package/dist/register/connect-prototypes.js +11 -0
  713. package/dist/register/connect-prototypes.js.map +1 -1
  714. package/dist/register/hooks.d.ts +7 -1
  715. package/dist/register/hooks.d.ts.map +1 -1
  716. package/dist/register/hooks.js +44 -2
  717. package/dist/register/hooks.js.map +1 -1
  718. package/dist/register/index.d.ts.map +1 -1
  719. package/dist/register/index.js +93 -23
  720. package/dist/register/index.js.map +1 -1
  721. package/dist/register/mapping.d.ts +33 -0
  722. package/dist/register/mapping.d.ts.map +1 -1
  723. package/dist/register/mapping.js +45 -3
  724. package/dist/register/mapping.js.map +1 -1
  725. package/dist/register/net-guard.d.ts +17 -0
  726. package/dist/register/net-guard.d.ts.map +1 -1
  727. package/dist/register/net-guard.js +118 -41
  728. package/dist/register/net-guard.js.map +1 -1
  729. package/dist/register/package-identity.d.ts +16 -0
  730. package/dist/register/package-identity.d.ts.map +1 -0
  731. package/dist/register/package-identity.js +97 -0
  732. package/dist/register/package-identity.js.map +1 -0
  733. package/dist/register/swap-or-stop.d.ts +27 -0
  734. package/dist/register/swap-or-stop.d.ts.map +1 -0
  735. package/dist/register/swap-or-stop.js +170 -0
  736. package/dist/register/swap-or-stop.js.map +1 -0
  737. package/dist/register/worker-guard.d.ts +20 -0
  738. package/dist/register/worker-guard.d.ts.map +1 -0
  739. package/dist/register/worker-guard.js +77 -0
  740. package/dist/register/worker-guard.js.map +1 -0
  741. package/dist/remote/resolve-host.d.ts +9 -0
  742. package/dist/remote/resolve-host.d.ts.map +1 -1
  743. package/dist/remote/resolve-host.js +13 -2
  744. package/dist/remote/resolve-host.js.map +1 -1
  745. package/dist/serve/ai-proxy.d.ts +2 -0
  746. package/dist/serve/ai-proxy.d.ts.map +1 -1
  747. package/dist/serve/ai-proxy.js +33 -8
  748. package/dist/serve/ai-proxy.js.map +1 -1
  749. package/dist/serve/app-ports.d.ts +48 -0
  750. package/dist/serve/app-ports.d.ts.map +1 -0
  751. package/dist/serve/app-ports.js +82 -0
  752. package/dist/serve/app-ports.js.map +1 -0
  753. package/dist/serve/bridge-mount.d.ts +13 -0
  754. package/dist/serve/bridge-mount.d.ts.map +1 -1
  755. package/dist/serve/bridge-mount.js +28 -8
  756. package/dist/serve/bridge-mount.js.map +1 -1
  757. package/dist/serve/bundler.d.ts +6 -0
  758. package/dist/serve/bundler.d.ts.map +1 -1
  759. package/dist/serve/bundler.js +78 -26
  760. package/dist/serve/bundler.js.map +1 -1
  761. package/dist/serve/discovery.d.ts +17 -3
  762. package/dist/serve/discovery.d.ts.map +1 -1
  763. package/dist/serve/discovery.js +199 -63
  764. package/dist/serve/discovery.js.map +1 -1
  765. package/dist/serve/entries/auth.d.ts.map +1 -1
  766. package/dist/serve/entries/auth.js +19 -1
  767. package/dist/serve/entries/auth.js.map +1 -1
  768. package/dist/serve/entries/firestore-surface.d.ts +1 -0
  769. package/dist/serve/entries/firestore-surface.d.ts.map +1 -1
  770. package/dist/serve/entries/firestore-surface.js +1 -0
  771. package/dist/serve/entries/firestore-surface.js.map +1 -1
  772. package/dist/serve/entries/init-payload.d.ts +9 -2
  773. package/dist/serve/entries/init-payload.d.ts.map +1 -1
  774. package/dist/serve/entries/init-payload.js +25 -5
  775. package/dist/serve/entries/init-payload.js.map +1 -1
  776. package/dist/serve/entries/moved-host.d.ts +18 -0
  777. package/dist/serve/entries/moved-host.d.ts.map +1 -0
  778. package/dist/serve/entries/moved-host.js +14 -0
  779. package/dist/serve/entries/moved-host.js.map +1 -0
  780. package/dist/serve/entries/runtime-origin.d.ts +6 -0
  781. package/dist/serve/entries/runtime-origin.d.ts.map +1 -1
  782. package/dist/serve/entries/runtime-origin.js.map +1 -1
  783. package/dist/serve/entries/unsupported/firestore.d.ts +0 -1
  784. package/dist/serve/entries/unsupported/firestore.d.ts.map +1 -1
  785. package/dist/serve/entries/unsupported/firestore.js +0 -1
  786. package/dist/serve/entries/unsupported/firestore.js.map +1 -1
  787. package/dist/serve/entries/worker-runtime.d.ts.map +1 -1
  788. package/dist/serve/entries/worker-runtime.js +19 -7
  789. package/dist/serve/entries/worker-runtime.js.map +1 -1
  790. package/dist/serve/firebase-module-swap.d.ts +19 -2
  791. package/dist/serve/firebase-module-swap.d.ts.map +1 -1
  792. package/dist/serve/firebase-module-swap.js +92 -16
  793. package/dist/serve/firebase-module-swap.js.map +1 -1
  794. package/dist/serve/gemini-proxy.js +2 -2
  795. package/dist/serve/gemini-proxy.js.map +1 -1
  796. package/dist/serve/hosted/runtime.d.ts.map +1 -1
  797. package/dist/serve/hosted/runtime.js +10 -3
  798. package/dist/serve/hosted/runtime.js.map +1 -1
  799. package/dist/serve/namespace.d.ts +7 -0
  800. package/dist/serve/namespace.d.ts.map +1 -1
  801. package/dist/serve/namespace.js +32 -24
  802. package/dist/serve/namespace.js.map +1 -1
  803. package/dist/serve/repro/compare.d.ts +2 -1
  804. package/dist/serve/repro/compare.d.ts.map +1 -1
  805. package/dist/serve/repro/compare.js +9 -1
  806. package/dist/serve/repro/compare.js.map +1 -1
  807. package/dist/serve/rules-fixture-check.d.ts.map +1 -1
  808. package/dist/serve/rules-fixture-check.js +22 -10
  809. package/dist/serve/rules-fixture-check.js.map +1 -1
  810. package/dist/serve/rules.d.ts +35 -9
  811. package/dist/serve/rules.d.ts.map +1 -1
  812. package/dist/serve/rules.js +72 -21
  813. package/dist/serve/rules.js.map +1 -1
  814. package/dist/serve/sandbox-session.d.ts +3 -0
  815. package/dist/serve/sandbox-session.d.ts.map +1 -1
  816. package/dist/serve/sandbox-session.js +10 -3
  817. package/dist/serve/sandbox-session.js.map +1 -1
  818. package/dist/serve/server.d.ts +10 -2
  819. package/dist/serve/server.d.ts.map +1 -1
  820. package/dist/serve/server.js +24 -4
  821. package/dist/serve/server.js.map +1 -1
  822. package/dist/serve/site-ui/_astro/{RulesCodeEditor.Cp_-FK3b.js → RulesCodeEditor.D-eQLCvu.js} +1 -1
  823. package/dist/serve/site-ui/_astro/app.BjQiEBOY.js +1 -0
  824. package/dist/serve/site-ui/_astro/app.C84Qr10v.js +151 -0
  825. package/dist/serve/site-ui/_astro/{chess-showcase.CVhCNUi_.js → chess-showcase.CsH1s4g7.js} +1 -1
  826. package/dist/serve/site-ui/_astro/{example-runtime.zC1l-Yka.js → example-runtime.CTp8mh7I.js} +1 -1
  827. package/dist/serve/site-ui/_astro/sandbox-controls.DI8MTU3L.js +1725 -0
  828. package/dist/serve/site-ui/_astro/{seed.B4vza_Bv.js → seed.BvtbLu-q.js} +1 -1
  829. package/dist/serve/site-ui/_astro/writes.D8gcuovU.js +1 -0
  830. package/dist/serve/site-ui/auth/index.html +1 -1
  831. package/dist/serve/site-ui/docs/ai-compat/index.html +48 -9
  832. package/dist/serve/site-ui/docs/ai-compat.md +53 -8
  833. package/dist/serve/site-ui/docs/app-check-compat/index.html +102 -26
  834. package/dist/serve/site-ui/docs/app-check-compat.md +107 -25
  835. package/dist/serve/site-ui/docs/auth-compat/index.html +33 -21
  836. package/dist/serve/site-ui/docs/auth-compat.md +35 -20
  837. package/dist/serve/site-ui/docs/build/ai-logic/index.html +13 -4
  838. package/dist/serve/site-ui/docs/build/ai-logic.md +14 -4
  839. package/dist/serve/site-ui/docs/conformance-scores/index.html +2 -2
  840. package/dist/serve/site-ui/docs/conformance-scores.md +2 -2
  841. package/dist/serve/site-ui/docs/database-compat/index.html +113 -49
  842. package/dist/serve/site-ui/docs/database-compat.md +118 -48
  843. package/dist/serve/site-ui/docs/firestore-compat/index.html +144 -37
  844. package/dist/serve/site-ui/docs/firestore-compat.md +149 -36
  845. package/dist/serve/site-ui/docs/firestore-swift-compat/index.html +1 -1
  846. package/dist/serve/site-ui/docs/firestore-swift-compat.md +1 -1
  847. package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +12 -12
  848. package/dist/serve/site-ui/docs/functions-rtdb-compat.md +12 -12
  849. package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +1 -1
  850. package/dist/serve/site-ui/docs/get-started/how-the-swap-works.md +1 -1
  851. package/dist/serve/site-ui/docs/get-started/node-host/index.html +1 -0
  852. package/dist/serve/site-ui/docs/get-started/node-host.md +2 -0
  853. package/dist/serve/site-ui/docs/index.json +45 -5
  854. package/dist/serve/site-ui/docs/messaging-compat/index.html +2 -2
  855. package/dist/serve/site-ui/docs/messaging-compat.md +2 -2
  856. package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +3 -1
  857. package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api.md +2 -0
  858. package/dist/serve/site-ui/docs/pyric-app-check-reference-api/index.html +11 -3
  859. package/dist/serve/site-ui/docs/pyric-app-check-reference-api.md +13 -3
  860. package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api/index.html +1 -1
  861. package/dist/serve/site-ui/docs/pyric-cli-bridge-client-reference-api.md +1 -1
  862. package/dist/serve/site-ui/docs/pyric-cli-next-reference-api/index.html +1 -0
  863. package/dist/serve/site-ui/docs/pyric-cli-next-reference-api.md +1 -0
  864. package/dist/serve/site-ui/docs/pyric-cli-register-client-firestore-reference-api/index.html +1 -1
  865. package/dist/serve/site-ui/docs/pyric-cli-register-client-firestore-reference-api.md +1 -1
  866. package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api/index.html +17 -9
  867. package/dist/serve/site-ui/docs/pyric-cli-serve-worker-reference-api.md +13 -11
  868. package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +8 -4
  869. package/dist/serve/site-ui/docs/pyric-database-reference-api.md +9 -4
  870. package/dist/serve/site-ui/docs/pyric-rules-reference-api/index.html +15 -4
  871. package/dist/serve/site-ui/docs/pyric-rules-reference-api.md +21 -4
  872. package/dist/serve/site-ui/docs/pyric-storage-reference-api/index.html +7 -1
  873. package/dist/serve/site-ui/docs/pyric-storage-reference-api.md +1 -0
  874. package/dist/serve/site-ui/docs/reference/cli/index.html +4 -3
  875. package/dist/serve/site-ui/docs/reference/cli.md +5 -3
  876. package/dist/serve/site-ui/docs/rules-compat/index.html +150 -49
  877. package/dist/serve/site-ui/docs/rules-compat.md +149 -51
  878. package/dist/serve/site-ui/docs/storage-compat/index.html +20 -20
  879. package/dist/serve/site-ui/docs/storage-compat.md +20 -20
  880. package/dist/serve/site-ui/docs/tutorial/index.html +2 -1
  881. package/dist/serve/site-ui/docs/tutorial.md +2 -1
  882. package/dist/serve/site-ui/examples/chess/index.html +1 -1
  883. package/dist/serve/site-ui/firestore/index.html +1 -1
  884. package/dist/serve/site-ui/rtdb/index.html +1 -1
  885. package/dist/serve/site-ui/settings/index.html +1 -1
  886. package/dist/serve/site-ui/storage/index.html +1 -1
  887. package/dist/serve/site-ui/studio/index.html +1 -1
  888. package/dist/serve/site-ui/traffic/index.html +1 -1
  889. package/dist/serve/vite-ai-config.d.ts +8 -0
  890. package/dist/serve/vite-ai-config.d.ts.map +1 -1
  891. package/dist/serve/vite-ai-config.js +16 -1
  892. package/dist/serve/vite-ai-config.js.map +1 -1
  893. package/dist/serve/vite-functions-development.d.ts +3 -3
  894. package/dist/serve/vite-functions-development.d.ts.map +1 -1
  895. package/dist/serve/vite-functions-development.js +1 -1
  896. package/dist/serve/vite-functions-development.js.map +1 -1
  897. package/dist/serve/vite-generation-bridge.d.ts +2 -2
  898. package/dist/serve/vite-generation-bridge.d.ts.map +1 -1
  899. package/dist/serve/vite-generation-functions.d.ts +3 -3
  900. package/dist/serve/vite-generation-functions.d.ts.map +1 -1
  901. package/dist/serve/vite-generation-functions.js +1 -1
  902. package/dist/serve/vite-generation-functions.js.map +1 -1
  903. package/dist/serve/vite-generation-middleware.d.ts +1 -1
  904. package/dist/serve/vite-generation-middleware.d.ts.map +1 -1
  905. package/dist/serve/vite-generation-middleware.js +36 -1
  906. package/dist/serve/vite-generation-middleware.js.map +1 -1
  907. package/dist/serve/vite-module-swap.d.ts.map +1 -1
  908. package/dist/serve/vite-module-swap.js +8 -0
  909. package/dist/serve/vite-module-swap.js.map +1 -1
  910. package/dist/serve/vite-page-runtime.d.ts.map +1 -1
  911. package/dist/serve/vite-page-runtime.js +7 -1
  912. package/dist/serve/vite-page-runtime.js.map +1 -1
  913. package/dist/serve/vite-rules-source.d.ts +1 -1
  914. package/dist/serve/vite-rules-source.d.ts.map +1 -1
  915. package/dist/serve/vite-rules-source.js +2 -4
  916. package/dist/serve/vite-rules-source.js.map +1 -1
  917. package/dist/serve/vite-sandbox-generation.d.ts +2 -2
  918. package/dist/serve/vite-sandbox-generation.d.ts.map +1 -1
  919. package/dist/serve/vite-sandbox-generation.js +2 -2
  920. package/dist/serve/vite-sandbox-generation.js.map +1 -1
  921. package/dist/serve/worker/client/auth.d.ts +29 -5
  922. package/dist/serve/worker/client/auth.d.ts.map +1 -1
  923. package/dist/serve/worker/client/auth.js +61 -11
  924. package/dist/serve/worker/client/auth.js.map +1 -1
  925. package/dist/serve/worker/client/clock.d.ts +0 -16
  926. package/dist/serve/worker/client/clock.d.ts.map +1 -1
  927. package/dist/serve/worker/client/clock.js +23 -10
  928. package/dist/serve/worker/client/clock.js.map +1 -1
  929. package/dist/serve/worker/client/firestore-reads.d.ts +12 -5
  930. package/dist/serve/worker/client/firestore-reads.d.ts.map +1 -1
  931. package/dist/serve/worker/client/firestore-reads.js +47 -16
  932. package/dist/serve/worker/client/firestore-reads.js.map +1 -1
  933. package/dist/serve/worker/client/firestore-refs.d.ts.map +1 -1
  934. package/dist/serve/worker/client/firestore-refs.js +4 -14
  935. package/dist/serve/worker/client/firestore-refs.js.map +1 -1
  936. package/dist/serve/worker/client/rtdb-connection-lifecycle.d.ts.map +1 -1
  937. package/dist/serve/worker/client/rtdb-connection-lifecycle.js +5 -0
  938. package/dist/serve/worker/client/rtdb-connection-lifecycle.js.map +1 -1
  939. package/dist/serve/worker/client/rtdb-snapshots.d.ts +7 -0
  940. package/dist/serve/worker/client/rtdb-snapshots.d.ts.map +1 -1
  941. package/dist/serve/worker/client/rtdb-snapshots.js +25 -1
  942. package/dist/serve/worker/client/rtdb-snapshots.js.map +1 -1
  943. package/dist/serve/worker/client/rtdb-value-validation.d.ts +21 -0
  944. package/dist/serve/worker/client/rtdb-value-validation.d.ts.map +1 -0
  945. package/dist/serve/worker/client/rtdb-value-validation.js +183 -0
  946. package/dist/serve/worker/client/rtdb-value-validation.js.map +1 -0
  947. package/dist/serve/worker/client/rtdb-writes.d.ts.map +1 -1
  948. package/dist/serve/worker/client/rtdb-writes.js +7 -0
  949. package/dist/serve/worker/client/rtdb-writes.js.map +1 -1
  950. package/dist/serve/worker/client/snapshots.d.ts +2 -0
  951. package/dist/serve/worker/client/snapshots.d.ts.map +1 -1
  952. package/dist/serve/worker/client/snapshots.js +13 -7
  953. package/dist/serve/worker/client/snapshots.js.map +1 -1
  954. package/dist/serve/worker/client/websocket-connection.d.ts +6 -0
  955. package/dist/serve/worker/client/websocket-connection.d.ts.map +1 -1
  956. package/dist/serve/worker/client/websocket-connection.js +32 -3
  957. package/dist/serve/worker/client/websocket-connection.js.map +1 -1
  958. package/dist/serve/worker/host/auth-credential-sign-in.d.ts +33 -0
  959. package/dist/serve/worker/host/auth-credential-sign-in.d.ts.map +1 -0
  960. package/dist/serve/worker/host/auth-credential-sign-in.js +70 -0
  961. package/dist/serve/worker/host/auth-credential-sign-in.js.map +1 -0
  962. package/dist/serve/worker/host/auth-reauthentication.js +3 -3
  963. package/dist/serve/worker/host/auth-reauthentication.js.map +1 -1
  964. package/dist/serve/worker/host/rules.d.ts +15 -1
  965. package/dist/serve/worker/host/rules.d.ts.map +1 -1
  966. package/dist/serve/worker/host/rules.js +43 -34
  967. package/dist/serve/worker/host/rules.js.map +1 -1
  968. package/dist/serve/worker/host/staged-sign-in-results.d.ts +24 -0
  969. package/dist/serve/worker/host/staged-sign-in-results.d.ts.map +1 -0
  970. package/dist/serve/worker/host/staged-sign-in-results.js +40 -0
  971. package/dist/serve/worker/host/staged-sign-in-results.js.map +1 -0
  972. package/dist/serve/worker/host/storage.d.ts.map +1 -1
  973. package/dist/serve/worker/host/storage.js +20 -12
  974. package/dist/serve/worker/host/storage.js.map +1 -1
  975. package/dist/serve/worker/host/subscriptions.d.ts.map +1 -1
  976. package/dist/serve/worker/host/subscriptions.js +6 -2
  977. package/dist/serve/worker/host/subscriptions.js.map +1 -1
  978. package/dist/serve/worker/host-auth.d.ts +3 -0
  979. package/dist/serve/worker/host-auth.d.ts.map +1 -1
  980. package/dist/serve/worker/host-auth.js +32 -13
  981. package/dist/serve/worker/host-auth.js.map +1 -1
  982. package/dist/serve/worker/inbound-validation/operation-arguments.d.ts.map +1 -1
  983. package/dist/serve/worker/inbound-validation/operation-arguments.js +27 -14
  984. package/dist/serve/worker/inbound-validation/operation-arguments.js.map +1 -1
  985. package/dist/serve/worker/operation-persistence.d.ts +1 -0
  986. package/dist/serve/worker/operation-persistence.d.ts.map +1 -1
  987. package/dist/serve/worker/operation-persistence.js +1 -0
  988. package/dist/serve/worker/operation-persistence.js.map +1 -1
  989. package/dist/serve/worker/protocol.d.ts +9 -1
  990. package/dist/serve/worker/protocol.d.ts.map +1 -1
  991. package/dist/serve/worker/protocol.js.map +1 -1
  992. package/dist/serve/worker/rtdb-value-equality.d.ts.map +1 -1
  993. package/dist/serve/worker/rtdb-value-equality.js +3 -1
  994. package/dist/serve/worker/rtdb-value-equality.js.map +1 -1
  995. package/dist/serve/worker/serve-init.d.ts.map +1 -1
  996. package/dist/serve/worker/serve-init.js +3 -9
  997. package/dist/serve/worker/serve-init.js.map +1 -1
  998. package/dist/serve/worker-build-lock.d.ts +23 -0
  999. package/dist/serve/worker-build-lock.d.ts.map +1 -0
  1000. package/dist/serve/worker-build-lock.js +179 -0
  1001. package/dist/serve/worker-build-lock.js.map +1 -0
  1002. package/dist/serve/worker-bundle-cache.d.ts +17 -0
  1003. package/dist/serve/worker-bundle-cache.d.ts.map +1 -0
  1004. package/dist/serve/worker-bundle-cache.js +89 -0
  1005. package/dist/serve/worker-bundle-cache.js.map +1 -0
  1006. package/dist/verify/cases.js +7 -3
  1007. package/dist/verify/cases.js.map +1 -1
  1008. package/dist/verify/index.d.ts.map +1 -1
  1009. package/dist/verify/index.js +11 -5
  1010. package/dist/verify/index.js.map +1 -1
  1011. package/package.json +10 -4
  1012. package/src/assurance/.generated/conformance-verdicts.ts +107 -40
  1013. package/src/assurance/capabilities.ts +11 -15
  1014. package/src/bounded-request.ts +66 -7
  1015. package/src/bridge/client/bridge-url.ts +5 -1
  1016. package/src/bridge/client/bridge.ts +19 -3
  1017. package/src/bridge/frame-output.ts +45 -0
  1018. package/src/bridge/protocol.ts +13 -0
  1019. package/src/bridge/server/in-process.ts +57 -17
  1020. package/src/bridge/server/peer.ts +11 -0
  1021. package/src/bridge/server/standalone.ts +29 -107
  1022. package/src/bridge/surface/arguments/sandbox.ts +2 -69
  1023. package/src/bridge/surface/arguments/seed.ts +78 -0
  1024. package/src/bridge/surface/context.ts +26 -37
  1025. package/src/bridge/surface/database-instance-catalog.ts +4 -32
  1026. package/src/bridge/surface/database-instance-project.ts +40 -0
  1027. package/src/bridge/surface/database-instance.ts +4 -4
  1028. package/src/bridge/surface/functions-runtime.ts +5 -5
  1029. package/src/bridge/surface/held-identity.ts +4 -4
  1030. package/src/bridge/surface/manifest.sandbox.generated.ts +137 -0
  1031. package/src/bridge/surface/method-types.ts +61 -7
  1032. package/src/bridge/surface/methods/ai_logic/clearScripts.ts +2 -1
  1033. package/src/bridge/surface/methods/ai_logic/script.ts +2 -1
  1034. package/src/bridge/surface/methods/ai_logic/scripts.ts +2 -1
  1035. package/src/bridge/surface/methods/ai_logic/status.ts +1 -0
  1036. package/src/bridge/surface/methods/assurance/attach.ts +1 -0
  1037. package/src/bridge/surface/methods/assurance/canIUse.ts +1 -0
  1038. package/src/bridge/surface/methods/assurance/define.ts +1 -0
  1039. package/src/bridge/surface/methods/assurance/export.ts +1 -0
  1040. package/src/bridge/surface/methods/assurance/inspect.ts +1 -0
  1041. package/src/bridge/surface/methods/assurance/map.ts +1 -0
  1042. package/src/bridge/surface/methods/assurance/minimize.ts +1 -0
  1043. package/src/bridge/surface/methods/assurance/propose.ts +1 -0
  1044. package/src/bridge/surface/methods/assurance/replaySession.ts +1 -0
  1045. package/src/bridge/surface/methods/assurance/run.ts +1 -0
  1046. package/src/bridge/surface/methods/assurance/start.ts +1 -0
  1047. package/src/bridge/surface/methods/assurance/testRulesHosted.ts +1 -0
  1048. package/src/bridge/surface/methods/assurance/verify.ts +1 -0
  1049. package/src/bridge/surface/methods/assurance/verifyCases.ts +1 -0
  1050. package/src/bridge/surface/methods/auth/actAsAdmin.ts +1 -0
  1051. package/src/bridge/surface/methods/auth/actAsAnonymous.ts +1 -0
  1052. package/src/bridge/surface/methods/auth/createCustomToken.ts +1 -0
  1053. package/src/bridge/surface/methods/auth/createUser.ts +2 -1
  1054. package/src/bridge/surface/methods/auth/deleteUser.ts +2 -1
  1055. package/src/bridge/surface/methods/auth/getUser.ts +2 -1
  1056. package/src/bridge/surface/methods/auth/getUserByEmail.ts +2 -1
  1057. package/src/bridge/surface/methods/auth/impersonate.ts +1 -0
  1058. package/src/bridge/surface/methods/auth/importUsers.ts +3 -2
  1059. package/src/bridge/surface/methods/auth/listUsers.ts +2 -1
  1060. package/src/bridge/surface/methods/auth/sessions.ts +1 -0
  1061. package/src/bridge/surface/methods/auth/setCustomUserClaims.ts +2 -1
  1062. package/src/bridge/surface/methods/auth/signInAnonymously.ts +1 -0
  1063. package/src/bridge/surface/methods/auth/signInWithCredential.ts +1 -0
  1064. package/src/bridge/surface/methods/auth/signInWithCustomToken.ts +1 -0
  1065. package/src/bridge/surface/methods/auth/signInWithEmailAndPassword.ts +1 -0
  1066. package/src/bridge/surface/methods/auth/signOut.ts +1 -0
  1067. package/src/bridge/surface/methods/auth/takeAuthMail.ts +1 -0
  1068. package/src/bridge/surface/methods/auth/updateUser.ts +2 -1
  1069. package/src/bridge/surface/methods/auth/useAppSession.ts +1 -0
  1070. package/src/bridge/surface/methods/auth/whoami.ts +1 -0
  1071. package/src/bridge/surface/methods/database/crawl.ts +1 -0
  1072. package/src/bridge/surface/methods/database/get.ts +1 -0
  1073. package/src/bridge/surface/methods/database/push.ts +1 -0
  1074. package/src/bridge/surface/methods/database/query.ts +1 -0
  1075. package/src/bridge/surface/methods/database/remove.ts +1 -0
  1076. package/src/bridge/surface/methods/database/set.ts +1 -0
  1077. package/src/bridge/surface/methods/database/update.ts +1 -0
  1078. package/src/bridge/surface/methods/firestore/addDoc.ts +2 -1
  1079. package/src/bridge/surface/methods/firestore/deleteDoc.ts +2 -1
  1080. package/src/bridge/surface/methods/firestore/discoverPaths.ts +1 -0
  1081. package/src/bridge/surface/methods/firestore/extractIndexes.ts +1 -0
  1082. package/src/bridge/surface/methods/firestore/findCollectionGroup.ts +1 -0
  1083. package/src/bridge/surface/methods/firestore/getAggregateFromServer.ts +1 -0
  1084. package/src/bridge/surface/methods/firestore/getCountFromServer.ts +1 -0
  1085. package/src/bridge/surface/methods/firestore/getDoc.ts +2 -1
  1086. package/src/bridge/surface/methods/firestore/getDocs.ts +2 -1
  1087. package/src/bridge/surface/methods/firestore/setDoc.ts +2 -1
  1088. package/src/bridge/surface/methods/firestore/updateDoc.ts +2 -1
  1089. package/src/bridge/surface/methods/firestore/writeBatch.ts +2 -1
  1090. package/src/bridge/surface/methods/firestore/writeIndexes.ts +1 -0
  1091. package/src/bridge/surface/methods/functions/executions.ts +2 -1
  1092. package/src/bridge/surface/methods/functions/fire.ts +7 -6
  1093. package/src/bridge/surface/methods/functions/listTriggers.ts +1 -0
  1094. package/src/bridge/surface/methods/messaging/deliveries.ts +1 -0
  1095. package/src/bridge/surface/methods/messaging/send.ts +2 -1
  1096. package/src/bridge/surface/methods/messaging/subscribeToTopic.ts +1 -0
  1097. package/src/bridge/surface/methods/messaging/tokens.ts +1 -0
  1098. package/src/bridge/surface/methods/messaging/unsubscribeFromTopic.ts +1 -0
  1099. package/src/bridge/surface/methods/registry.ts +2 -12
  1100. package/src/bridge/surface/methods/rules/explainDenial.ts +1 -0
  1101. package/src/bridge/surface/methods/rules/getStdlib.ts +1 -0
  1102. package/src/bridge/surface/methods/rules/lint.ts +1 -0
  1103. package/src/bridge/surface/methods/rules/listStdlib.ts +1 -0
  1104. package/src/bridge/surface/methods/rules/set.ts +1 -0
  1105. package/src/bridge/surface/methods/rules/simulate.ts +1 -0
  1106. package/src/bridge/surface/methods/sandbox/activity.ts +2 -1
  1107. package/src/bridge/surface/methods/sandbox/advanceClock.ts +1 -0
  1108. package/src/bridge/surface/methods/sandbox/apply.ts +1 -0
  1109. package/src/bridge/surface/methods/sandbox/checkpoint.ts +1 -0
  1110. package/src/bridge/surface/methods/sandbox/deleteCapture.ts +1 -1
  1111. package/src/bridge/surface/methods/sandbox/deleteCheckpoint.ts +1 -0
  1112. package/src/bridge/surface/methods/sandbox/diff.ts +1 -0
  1113. package/src/bridge/surface/methods/sandbox/discard.ts +1 -0
  1114. package/src/bridge/surface/methods/sandbox/events.ts +2 -1
  1115. package/src/bridge/surface/methods/sandbox/exportFixture.ts +1 -0
  1116. package/src/bridge/surface/methods/sandbox/fork.ts +1 -0
  1117. package/src/bridge/surface/methods/sandbox/inspect.ts +2 -1
  1118. package/src/bridge/surface/methods/sandbox/listBranches.ts +1 -0
  1119. package/src/bridge/surface/methods/sandbox/listCaptures.ts +1 -1
  1120. package/src/bridge/surface/methods/sandbox/listCheckpoints.ts +1 -0
  1121. package/src/bridge/surface/methods/sandbox/listeners.ts +1 -0
  1122. package/src/bridge/surface/methods/sandbox/openCapture.ts +1 -1
  1123. package/src/bridge/surface/methods/sandbox/promote.ts +1 -0
  1124. package/src/bridge/surface/methods/sandbox/renameCapture.ts +1 -1
  1125. package/src/bridge/surface/methods/sandbox/reset.ts +3 -2
  1126. package/src/bridge/surface/methods/sandbox/resetClock.ts +1 -0
  1127. package/src/bridge/surface/methods/sandbox/restore.ts +1 -0
  1128. package/src/bridge/surface/methods/sandbox/saveCapture.ts +1 -1
  1129. package/src/bridge/surface/methods/sandbox/seed.ts +3 -2
  1130. package/src/bridge/surface/methods/sandbox/seedFromFixture.ts +1 -0
  1131. package/src/bridge/surface/methods/sandbox/setClock.ts +1 -0
  1132. package/src/bridge/surface/methods/sandbox-registry.ts +24 -0
  1133. package/src/bridge/surface/methods/storage/deleteObject.ts +1 -0
  1134. package/src/bridge/surface/methods/storage/getBytes.ts +1 -0
  1135. package/src/bridge/surface/methods/storage/getDownloadURL.ts +1 -0
  1136. package/src/bridge/surface/methods/storage/getMetadata.ts +1 -0
  1137. package/src/bridge/surface/methods/storage/listAll.ts +1 -0
  1138. package/src/bridge/surface/methods/storage/provision.ts +1 -0
  1139. package/src/bridge/surface/methods/storage/setCrossServiceIam.ts +1 -0
  1140. package/src/bridge/surface/methods/storage/status.ts +1 -0
  1141. package/src/bridge/surface/methods/storage/updateMetadata.ts +1 -0
  1142. package/src/bridge/surface/methods/storage/uploadBytes.ts +1 -0
  1143. package/src/bridge/surface/request-instant.ts +2 -2
  1144. package/src/bridge/surface/rules-engines/database.ts +1 -2
  1145. package/src/bridge/surface/rules-engines/storage-request-resource.ts +275 -0
  1146. package/src/bridge/surface/rules-engines/storage.ts +54 -81
  1147. package/src/bridge/surface/sandbox-context.ts +49 -0
  1148. package/src/bridge/surface/service-handles.ts +13 -9
  1149. package/src/bridge/surface/sign-in.ts +3 -3
  1150. package/src/bridge/surface/storage-rules.ts +2 -14
  1151. package/src/bridge/surface/stored-identity.ts +3 -3
  1152. package/src/bridge/surface/types.ts +30 -8
  1153. package/src/cli/firebase-json.ts +45 -7
  1154. package/src/cli/firestore-indexes.ts +2 -1
  1155. package/src/cli/index.ts +46 -11
  1156. package/src/cli/public-dir-hint.ts +35 -0
  1157. package/src/cli/run.ts +35 -7
  1158. package/src/cli/sandbox-runner.ts +10 -2
  1159. package/src/cli/serve-diagnostics.ts +12 -1
  1160. package/src/cli/serve.ts +27 -26
  1161. package/src/cli/service-commands.test.ts +7 -0
  1162. package/src/cli/snapshot.ts +15 -6
  1163. package/src/cli/surface-method-runner.ts +1 -1
  1164. package/src/cli/verify.ts +11 -1
  1165. package/src/conformance/.generated/can-i-use-browser.ts +22 -3
  1166. package/src/conformance/.generated/can-i-use.ts +1 -1
  1167. package/src/conformance/.generated/conformance-docs.ts +1 -1
  1168. package/src/conformance/.generated/served-availability.ts +1 -1
  1169. package/src/discover/merge.ts +12 -3
  1170. package/src/functions/child-protocol.ts +59 -0
  1171. package/src/functions/child.ts +107 -0
  1172. package/src/{functions-rtdb → functions}/development-runtime.ts +13 -14
  1173. package/src/functions/endpoints.ts +80 -0
  1174. package/src/{functions-rtdb → functions}/project.ts +2 -2
  1175. package/src/functions/rtdb/child-runtime.ts +139 -0
  1176. package/src/{functions-rtdb → functions/rtdb}/discovery.ts +9 -43
  1177. package/src/{functions-rtdb → functions/rtdb}/remote-delivery.ts +1 -1
  1178. package/src/functions/spawn.ts +212 -0
  1179. package/src/functions/unsupported.ts +42 -0
  1180. package/src/google-endpoints.ts +74 -3
  1181. package/src/next/bridge-import-loader.ts +56 -0
  1182. package/src/next/bridge-imports.ts +108 -0
  1183. package/src/next/client-aliases.ts +14 -27
  1184. package/src/next/guard.ts +33 -11
  1185. package/src/next/turbopack-config.ts +26 -0
  1186. package/src/next/webpack-config.ts +26 -0
  1187. package/src/next/with-pyric.ts +26 -0
  1188. package/src/register/activation.ts +26 -0
  1189. package/src/register/app-bridge-admin-app-check.ts +3 -1
  1190. package/src/register/child-process-guard.ts +189 -0
  1191. package/src/register/client/bootstrap.ts +7 -1
  1192. package/src/register/connect-prototypes.ts +12 -0
  1193. package/src/register/hooks.ts +56 -3
  1194. package/src/register/index.ts +92 -20
  1195. package/src/register/mapping.ts +57 -3
  1196. package/src/register/net-guard.ts +149 -39
  1197. package/src/register/package-identity.ts +98 -0
  1198. package/src/register/swap-or-stop.ts +194 -0
  1199. package/src/register/worker-guard.ts +90 -0
  1200. package/src/remote/resolve-host.ts +14 -2
  1201. package/src/serve/ai-proxy.ts +36 -8
  1202. package/src/serve/app-ports.ts +119 -0
  1203. package/src/serve/bridge-mount.ts +36 -8
  1204. package/src/serve/bundler.ts +87 -29
  1205. package/src/serve/discovery.ts +244 -67
  1206. package/src/serve/entries/auth.ts +22 -1
  1207. package/src/serve/entries/firestore-surface.ts +1 -0
  1208. package/src/serve/entries/init-payload.ts +28 -5
  1209. package/src/serve/entries/moved-host.ts +28 -0
  1210. package/src/serve/entries/runtime-origin.ts +6 -0
  1211. package/src/serve/entries/unsupported/firestore.ts +0 -1
  1212. package/src/serve/entries/worker-runtime.ts +19 -6
  1213. package/src/serve/firebase-module-swap.ts +98 -15
  1214. package/src/serve/gemini-proxy.ts +2 -2
  1215. package/src/serve/hosted/runtime.ts +10 -2
  1216. package/src/serve/namespace.ts +41 -29
  1217. package/src/serve/repro/compare.ts +9 -1
  1218. package/src/serve/rules-fixture-check.ts +34 -9
  1219. package/src/serve/rules.ts +104 -20
  1220. package/src/serve/sandbox-session.ts +11 -3
  1221. package/src/serve/server.ts +29 -2
  1222. package/src/serve/vite-ai-config.ts +19 -1
  1223. package/src/serve/vite-functions-development.ts +3 -3
  1224. package/src/serve/vite-generation-bridge.ts +2 -2
  1225. package/src/serve/vite-generation-functions.ts +5 -5
  1226. package/src/serve/vite-generation-middleware.ts +38 -2
  1227. package/src/serve/vite-module-swap.ts +8 -0
  1228. package/src/serve/vite-page-runtime.ts +6 -0
  1229. package/src/serve/vite-rules-source.ts +2 -5
  1230. package/src/serve/vite-sandbox-generation.ts +5 -5
  1231. package/src/serve/worker/__tests__/auth-credential-sign-in.test.ts +343 -0
  1232. package/src/serve/worker/__tests__/auth-m2-parity.test.ts +45 -1
  1233. package/src/serve/worker/__tests__/staged-sign-in-results.test.ts +139 -0
  1234. package/src/serve/worker/client/auth.ts +97 -21
  1235. package/src/serve/worker/client/clock.ts +10 -12
  1236. package/src/serve/worker/client/firestore-reads.ts +70 -21
  1237. package/src/serve/worker/client/firestore-refs.ts +4 -14
  1238. package/src/serve/worker/client/rtdb-connection-lifecycle.ts +5 -0
  1239. package/src/serve/worker/client/rtdb-snapshots.ts +24 -2
  1240. package/src/serve/worker/client/rtdb-value-validation.ts +198 -0
  1241. package/src/serve/worker/client/rtdb-writes.ts +7 -0
  1242. package/src/serve/worker/client/snapshots.ts +15 -6
  1243. package/src/serve/worker/client/websocket-connection.ts +39 -3
  1244. package/src/serve/worker/host/auth-credential-sign-in.ts +97 -0
  1245. package/src/serve/worker/host/auth-reauthentication.ts +3 -3
  1246. package/src/serve/worker/host/rules.ts +53 -34
  1247. package/src/serve/worker/host/staged-sign-in-results.ts +53 -0
  1248. package/src/serve/worker/host/storage.ts +26 -11
  1249. package/src/serve/worker/host/subscriptions.ts +7 -4
  1250. package/src/serve/worker/host-auth.ts +33 -15
  1251. package/src/serve/worker/inbound-validation/operation-arguments.ts +27 -14
  1252. package/src/serve/worker/operation-persistence.ts +1 -0
  1253. package/src/serve/worker/protocol.ts +7 -1
  1254. package/src/serve/worker/rtdb-value-equality.ts +3 -1
  1255. package/src/serve/worker/serve-init.ts +3 -9
  1256. package/src/serve/worker-build-lock.ts +207 -0
  1257. package/src/serve/worker-bundle-cache.ts +90 -0
  1258. package/src/verify/cases.ts +6 -3
  1259. package/src/verify/index.ts +16 -4
  1260. package/dist/functions-rtdb/child.d.ts.map +0 -1
  1261. package/dist/functions-rtdb/child.js +0 -386
  1262. package/dist/functions-rtdb/child.js.map +0 -1
  1263. package/dist/functions-rtdb/delivery.d.ts.map +0 -1
  1264. package/dist/functions-rtdb/delivery.js.map +0 -1
  1265. package/dist/functions-rtdb/development-runtime.d.ts.map +0 -1
  1266. package/dist/functions-rtdb/development-runtime.js.map +0 -1
  1267. package/dist/functions-rtdb/discovery.d.ts.map +0 -1
  1268. package/dist/functions-rtdb/discovery.js.map +0 -1
  1269. package/dist/functions-rtdb/event.d.ts.map +0 -1
  1270. package/dist/functions-rtdb/event.js.map +0 -1
  1271. package/dist/functions-rtdb/events.d.ts.map +0 -1
  1272. package/dist/functions-rtdb/events.js.map +0 -1
  1273. package/dist/functions-rtdb/execution-log.d.ts.map +0 -1
  1274. package/dist/functions-rtdb/execution-log.js.map +0 -1
  1275. package/dist/functions-rtdb/execution.d.ts.map +0 -1
  1276. package/dist/functions-rtdb/execution.js.map +0 -1
  1277. package/dist/functions-rtdb/in-memory-delivery.d.ts.map +0 -1
  1278. package/dist/functions-rtdb/in-memory-delivery.js.map +0 -1
  1279. package/dist/functions-rtdb/module-loader.d.ts.map +0 -1
  1280. package/dist/functions-rtdb/module-loader.js.map +0 -1
  1281. package/dist/functions-rtdb/project.d.ts +0 -7
  1282. package/dist/functions-rtdb/project.d.ts.map +0 -1
  1283. package/dist/functions-rtdb/project.js.map +0 -1
  1284. package/dist/functions-rtdb/projection.d.ts.map +0 -1
  1285. package/dist/functions-rtdb/projection.js.map +0 -1
  1286. package/dist/functions-rtdb/reference-pattern.d.ts.map +0 -1
  1287. package/dist/functions-rtdb/reference-pattern.js.map +0 -1
  1288. package/dist/functions-rtdb/remote-delivery.d.ts.map +0 -1
  1289. package/dist/functions-rtdb/remote-delivery.js.map +0 -1
  1290. package/dist/serve/gemini-error-redaction.d.ts +0 -6
  1291. package/dist/serve/gemini-error-redaction.d.ts.map +0 -1
  1292. package/dist/serve/gemini-error-redaction.js +0 -61
  1293. package/dist/serve/gemini-error-redaction.js.map +0 -1
  1294. package/dist/serve/site-ui/_astro/app.C--T2qDK.js +0 -151
  1295. package/dist/serve/site-ui/_astro/app.DqyhRyrU.js +0 -1
  1296. package/dist/serve/site-ui/_astro/sandbox-controls.Bv6lfpIe.js +0 -1725
  1297. package/dist/serve/site-ui/_astro/writes.Bg0YEEA7.js +0 -1
  1298. package/src/functions-rtdb/child.ts +0 -512
  1299. package/src/serve/gemini-error-redaction.ts +0 -60
  1300. /package/dist/{functions-rtdb → functions}/events.d.ts +0 -0
  1301. /package/dist/{functions-rtdb → functions}/events.js +0 -0
  1302. /package/dist/{functions-rtdb → functions}/execution-log.d.ts +0 -0
  1303. /package/dist/{functions-rtdb → functions}/execution-log.js +0 -0
  1304. /package/dist/{functions-rtdb → functions}/module-loader.d.ts +0 -0
  1305. /package/dist/{functions-rtdb → functions}/module-loader.js +0 -0
  1306. /package/dist/{functions-rtdb → functions/rtdb}/delivery.d.ts +0 -0
  1307. /package/dist/{functions-rtdb → functions/rtdb}/delivery.js +0 -0
  1308. /package/dist/{functions-rtdb → functions/rtdb}/event.d.ts +0 -0
  1309. /package/dist/{functions-rtdb → functions/rtdb}/event.js +0 -0
  1310. /package/dist/{functions-rtdb → functions/rtdb}/execution.d.ts +0 -0
  1311. /package/dist/{functions-rtdb → functions/rtdb}/execution.js +0 -0
  1312. /package/dist/{functions-rtdb → functions/rtdb}/in-memory-delivery.d.ts +0 -0
  1313. /package/dist/{functions-rtdb → functions/rtdb}/in-memory-delivery.js +0 -0
  1314. /package/dist/{functions-rtdb → functions/rtdb}/projection.d.ts +0 -0
  1315. /package/dist/{functions-rtdb → functions/rtdb}/projection.js +0 -0
  1316. /package/dist/{functions-rtdb → functions/rtdb}/reference-pattern.d.ts +0 -0
  1317. /package/dist/{functions-rtdb → functions/rtdb}/reference-pattern.js +0 -0
  1318. /package/dist/{functions-rtdb → functions/rtdb}/remote-delivery.js +0 -0
  1319. /package/src/{functions-rtdb → functions}/events.ts +0 -0
  1320. /package/src/{functions-rtdb → functions}/execution-log.ts +0 -0
  1321. /package/src/{functions-rtdb → functions}/module-loader.ts +0 -0
  1322. /package/src/{functions-rtdb → functions/rtdb}/delivery.ts +0 -0
  1323. /package/src/{functions-rtdb → functions/rtdb}/event.ts +0 -0
  1324. /package/src/{functions-rtdb → functions/rtdb}/execution.ts +0 -0
  1325. /package/src/{functions-rtdb → functions/rtdb}/in-memory-delivery.ts +0 -0
  1326. /package/src/{functions-rtdb → functions/rtdb}/projection.ts +0 -0
  1327. /package/src/{functions-rtdb → functions/rtdb}/reference-pattern.ts +0 -0
@@ -18,6 +18,7 @@ html{scrollbar-gutter:stable}
18
18
  <div class="compat-key">
19
19
  <span class="compat-key-item"><span class="compat-dot" data-status="ok"></span><strong>Conforming</strong> — sandbox matches prod, locked by a passing probe</span>
20
20
  <span class="compat-key-item"><span class="compat-dot" data-status="diverged"></span><strong>Diverged (documented)</strong> — intentional difference with a written reason</span>
21
+ <span class="compat-key-item"><span class="compat-dot" data-status="bug"></span><strong>Bug</strong> — should match prod but doesn't; failing probe pins it</span>
21
22
  </div>
22
23
  <h2 id="getfirestoretarget--initializer"><code>getFirestore(target)</code> — initializer</h2>
23
24
  <div class="compat-list">
@@ -48,11 +49,11 @@ html{scrollbar-gutter:stable}
48
49
  </details>
49
50
  </div>
50
51
  <h2 id="named-databases">Named databases</h2>
51
- <p>In production <code>getFirestore(app, databaseId)</code> selects a named database with its own documents, and rules see that id in the <code>database</code> path variable. Pyric models one database per app, <code>(default)</code>.</p>
52
+ <p>In production <code>getFirestore(app, databaseId)</code> selects a named database with its own documents, and rules see that id in the <code>database</code> path variable. Pyric models one database per app, <code>(default)</code>. When <code>firebase.json</code> declares <code>firestore</code> as an array, pyric serves the <code>(default)</code> entry’s rules and prints a startup warning for each named entry.</p>
52
53
  <div class="compat-list">
53
54
  <details class="compat-row" data-status="diverged">
54
55
  <summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getFirestore(app, databaseId)</code><span class="compat-sub"><span class="compat-behavior">In the sandbox, <code>getFirestore(app, databaseId)</code> ignores the database id and returns the app's <code>(default)</code> handle, so documents written under one id are read under every other id.</span></span></span></summary>
55
- <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/named-database.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>packages/pyric/test/firestore/named-database.test.ts</code></a> asserts two database ids return the <code>(default)</code> handle and that a document written under one id reads back under another.</div>
56
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/named-database.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>packages/pyric/test/firestore/named-database.test.ts</code></a> asserts two database ids return the <code>(default)</code> handle and that a document written under one id reads back under another. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-named-database-absent.json" target="_blank" rel="noopener noreferrer"><code>firestore-named-database-absent</code></a>)</div>
56
57
  <div class="compat-note">every database id resolves to (default)</div></div>
57
58
  </details>
58
59
  <details class="compat-row" data-status="diverged">
@@ -62,12 +63,12 @@ html{scrollbar-gutter:stable}
62
63
  </details>
63
64
  <details class="compat-row" data-status="diverged">
64
65
  <summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">pyric-admin getFirestore(app, databaseId)</code><span class="compat-sub"><span class="compat-behavior"><code>pyric-admin</code> <code>getFirestore</code> takes no database id; a second argument is ignored and the handle reads and writes <code>(default)</code>. The Admin SDK's <code>getFirestore(app, databaseId)</code> selects the named database.</span></span></span></summary>
65
- <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/firestore/named-database.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>packages/pyric-admin/test/firestore/named-database.test.ts</code></a> writes through <code>getFirestore(app, 'reports')</code> and reads the document through <code>getFirestore(app)</code> and <code>getFirestore(app, 'archive')</code>.</div>
66
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/firestore/named-database.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>packages/pyric-admin/test/firestore/named-database.test.ts</code></a> writes through <code>getFirestore(app, 'reports')</code> and reads the document through <code>getFirestore(app)</code> and <code>getFirestore(app, 'archive')</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-named-database-admin-mixing.json" target="_blank" rel="noopener noreferrer"><code>firestore-named-database-admin-mixing</code></a>)</div>
66
67
  <div class="compat-note">no database id parameter; every call resolves to (default)</div></div>
67
68
  </details>
68
69
  <details class="compat-row" data-status="diverged">
69
70
  <summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">Rules <code>match /databases/{database}/documents</code></code><span class="compat-sub"><span class="compat-behavior">Rules evaluate the <code>database</code> path variable as <code>(default)</code> for every request, whatever database id the handle was created with. Production binds the named database's id.</span></span></span></summary>
70
- <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/named-database.test.ts#L11" target="_blank" rel="noopener noreferrer"><code>packages/pyric/test/firestore/named-database.test.ts</code></a> writes through a handle created for <code>reports</code>: a rule requiring <code>database == '(default)'</code> allows the write and a rule requiring <code>database == 'reports'</code> denies it.</div>
71
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/named-database.test.ts#L11" target="_blank" rel="noopener noreferrer"><code>packages/pyric/test/firestore/named-database.test.ts</code></a> writes through a handle created for <code>reports</code>: a rule requiring <code>database == '(default)'</code> allows the write and a rule requiring <code>database == 'reports'</code> denies it. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-named-database-rules-api.json" target="_blank" rel="noopener noreferrer"><code>firestore-named-database-rules-api</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-named-database-cross-database.json" target="_blank" rel="noopener noreferrer"><code>firestore-named-database-cross-database</code></a>)</div>
71
72
  <div class="compat-note"><code>database</code> is always (default)</div></div>
72
73
  </details>
73
74
  </div>
@@ -99,7 +100,7 @@ html{scrollbar-gutter:stable}
99
100
  </details>
100
101
  <details class="compat-row" data-status="ok">
101
102
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Path constructors</code><span class="compat-sub"><span class="compat-behavior"><code>collectionGroup(db, id)</code> returns a query spanning every collection with that id; <code>onSnapshot</code> on it delivers the initial snapshot and every later write to a collection with that id at any depth</span></span></span></summary>
102
- <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox-target.test.ts#L20" target="_blank" rel="noopener noreferrer"><code>unit:sandbox-target.test.ts</code></a> ("gathers documents across every parent collection"). UPDATED, 2026-10-07: oracle <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-collection-group-listener.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-collection-group-listener.json</code></a>, captured with the Web SDK against temporarily deployed production rules that were restored afterwards. Under <code>match /{path=**}/&#x3C;id>/{id}</code>, a listener on <code>collectionGroup(db, id)</code> fired once with the existing document, once with <code>added</code> for a write in a subcollection with that id, once with <code>added</code> for a write in the root collection with that id, and not at all for a write in a sibling collection; a listener on a collection id that only a concrete match governs received <code>permission-denied</code>. <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L986" target="_blank" rel="noopener noreferrer"><code>unit:firestore/oracle-conformance.test.ts</code></a> replays the capture in the sandbox; <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/collection-group-rules.test.ts#L3" target="_blank" rel="noopener noreferrer"><code>unit:firestore/collection-group-rules.test.ts</code></a> pins the same sequence, the denial routed to the error callback, and query constraints on the listener; <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/collection-group-listener.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>cli:serve/worker/collection-group-listener.test.ts</code></a> pins the same delivery and denial through the worker bridge.</div></div>
103
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox-target.test.ts#L20" target="_blank" rel="noopener noreferrer"><code>unit:sandbox-target.test.ts</code></a> ("gathers documents across every parent collection"). UPDATED, 2026-10-07: oracle <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-collection-group-listener.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-collection-group-listener.json</code></a>, captured with the Web SDK against temporarily deployed production rules that were restored afterwards. Under <code>match /{path=**}/&#x3C;id>/{id}</code>, a listener on <code>collectionGroup(db, id)</code> fired once with the existing document, once with <code>added</code> for a write in a subcollection with that id, once with <code>added</code> for a write in the root collection with that id, and not at all for a write in a sibling collection; a listener on a collection id that only a concrete match governs received <code>permission-denied</code>. <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L1002" target="_blank" rel="noopener noreferrer"><code>unit:firestore/oracle-conformance.test.ts</code></a> replays the capture in the sandbox; <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/collection-group-rules.test.ts#L3" target="_blank" rel="noopener noreferrer"><code>unit:firestore/collection-group-rules.test.ts</code></a> pins the same sequence, the denial routed to the error callback, and query constraints on the listener; <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/collection-group-listener.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>cli:serve/worker/collection-group-listener.test.ts</code></a> pins the same delivery and denial through the worker bridge.</div></div>
103
104
  </details>
104
105
  <details class="compat-row" data-status="ok">
105
106
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Path constructors</code><span class="compat-sub"><span class="compat-behavior">Unknown ref (not produced by this package) → <code>TypeError</code> with "unrecognized reference"</span></span></span></summary>
@@ -134,14 +135,14 @@ html{scrollbar-gutter:stable}
134
135
  </details>
135
136
  <details class="compat-row" data-status="ok">
136
137
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">getDoc(ref)</code><span class="compat-sub"><span class="compat-behavior">Rules-denied modular writes throw a <code>FirebaseError('permission-denied')</code>, matching the production error class and code</span></span></span></summary>
137
- <div class="compat-evidence"><div class="compat-probe">Oracle-locked by <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-rules-denied-error.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-rules-denied-error.json</code></a>: prod throws a <code>FirebaseError</code> (name + constructor name both <code>FirebaseError</code>), <code>.code === 'permission-denied'</code>, and the value is an <code>instanceof FirebaseError</code> and <code>Error</code>. <code>oracle:firestore#21</code> replays the same denied modular write against the sandbox and asserts that complete class shape. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L637" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
138
+ <div class="compat-evidence"><div class="compat-probe">Oracle-locked by <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-rules-denied-error.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-rules-denied-error.json</code></a>: prod throws a <code>FirebaseError</code> (name + constructor name both <code>FirebaseError</code>), <code>.code === 'permission-denied'</code>, and the value is an <code>instanceof FirebaseError</code> and <code>Error</code>. <code>oracle:firestore#21</code> replays the same denied modular write against the sandbox and asserts that complete class shape. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L653" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
138
139
  </details>
139
140
  </div>
140
141
  <h2 id="getdocsquery--bulk-read"><code>getDocs(query)</code> — bulk read</h2>
141
142
  <div class="compat-list">
142
143
  <details class="compat-row" data-status="ok">
143
144
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">getDocs(query)</code><span class="compat-sub"><span class="compat-behavior">Returns <code>QuerySnapshot</code> with <code>size</code>, <code>empty</code>, <code>docs</code> (<code>QueryDocumentSnapshot[]</code>)</span></span></span></summary>
144
- <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox-target.test.ts#L23" target="_blank" rel="noopener noreferrer"><code>unit:sandbox-target.test.ts</code></a>, <code>playground:firestore-query</code> (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L49" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
145
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox-target.test.ts#L23" target="_blank" rel="noopener noreferrer"><code>unit:sandbox-target.test.ts</code></a>, <code>playground:firestore-query</code> (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L50" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
145
146
  </details>
146
147
  <details class="compat-row" data-status="ok">
147
148
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">getDocs(query)</code><span class="compat-sub"><span class="compat-behavior"><code>QuerySnapshot.forEach(callback, thisArg)</code> calls <code>callback.call(thisArg, doc)</code> once per document, in query order, with the document alone, and <code>DocumentSnapshot.get(fieldPath)</code> returns the stored field at a dotted string or <code>FieldPath</code> (<code>undefined</code> when absent), for <code>getDocs</code> (with or without a converter, and the empty <code>getDocsFromCache</code> miss), <code>getDoc</code> and listener snapshots, in the in-page sandbox and through the served worker client, which the client SDKs in a Node host server process use.</span></span></span></summary>
@@ -200,7 +201,7 @@ html{scrollbar-gutter:stable}
200
201
  </details>
201
202
  <details class="compat-row" data-status="ok">
202
203
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">setDoc(ref, data[, options])</code><span class="compat-sub"><span class="compat-behavior">Rules-denied <code>setDoc</code> throws a <code>FirebaseError</code> with code <code>permission-denied</code>, matching production</span></span></span></summary>
203
- <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox-target.test.ts#L25" target="_blank" rel="noopener noreferrer"><code>unit:sandbox-target.test.ts</code></a> ("getDoc denies when rules reject"), <code>playground:rules-data-validation</code>, oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-write-denied-error-code.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-write-denied-error-code.json</code></a> (prod <code>setDoc</code> on a denied path throws a <code>FirebaseError</code> with <code>.code === 'permission-denied'</code>, <code>.message === '7 PERMISSION_DENIED: Missing or insufficient permissions.'</code>, <code>instanceof Error</code>); <code>oracle:firestore#32</code> pins the sandbox error shape (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L625" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
204
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox-target.test.ts#L25" target="_blank" rel="noopener noreferrer"><code>unit:sandbox-target.test.ts</code></a> ("getDoc denies when rules reject"), <code>playground:rules-data-validation</code>, oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-write-denied-error-code.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-write-denied-error-code.json</code></a> (prod <code>setDoc</code> on a denied path throws a <code>FirebaseError</code> with <code>.code === 'permission-denied'</code>, <code>.message === '7 PERMISSION_DENIED: Missing or insufficient permissions.'</code>, <code>instanceof Error</code>); <code>oracle:firestore#32</code> pins the sandbox error shape (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L641" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
204
205
  </details>
205
206
  </div>
206
207
  <h2 id="updatedocref-data--partial-write"><code>updateDoc(ref, data)</code> — partial write</h2>
@@ -261,7 +262,7 @@ html{scrollbar-gutter:stable}
261
262
  </details>
262
263
  <details class="compat-row" data-status="ok">
263
264
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">addDoc(coll, data)</code><span class="compat-sub"><span class="compat-behavior">Auto-id format — production and sandbox mint 20-character IDs from <code>[A-Za-z0-9]</code></span></span></span></summary>
264
- <div class="compat-evidence"><div class="compat-probe">Oracle-locked: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-adddoc-autoid-format.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-adddoc-autoid-format.json</code></a> records production's 20-character alphanumeric shape; <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L194" target="_blank" rel="noopener noreferrer"><code>packages/pyric/test/firestore/oracle-conformance.test.ts</code></a> generates 25 sandbox IDs and checks both invariants against that observation.</div></div>
265
+ <div class="compat-evidence"><div class="compat-probe">Oracle-locked: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-adddoc-autoid-format.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-adddoc-autoid-format.json</code></a> records production's 20-character alphanumeric shape; <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L210" target="_blank" rel="noopener noreferrer"><code>packages/pyric/test/firestore/oracle-conformance.test.ts</code></a> generates 25 sandbox IDs and checks both invariants against that observation.</div></div>
265
266
  </details>
266
267
  </div>
267
268
  <h2 id="withconverter--typed-refs"><code>withConverter</code> — typed refs</h2>
@@ -355,7 +356,7 @@ html{scrollbar-gutter:stable}
355
356
  </details>
356
357
  <details class="compat-row" data-status="ok">
357
358
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Query construction</code><span class="compat-sub"><span class="compat-behavior"><code>limitToLast(n)</code> returns the trailing n documents in an ordered result; without <code>orderBy</code>, it throws a <code>FirestoreError</code> with production's <code>unimplemented</code> code</span></span></span></summary>
358
- <div class="compat-evidence"><div class="compat-probe">Oracle-locked by <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-limittolast-preconditions.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-limittolast-preconditions.json</code></a>: production's no-orderBy precondition throws code <code>unimplemented</code>, while ordered trailing-window semantics return <code>["b"]</code>. <code>oracle:firestore#61</code> replays both claims. Cursor composition + descending: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/upstream-query-probes.test.ts#L10" target="_blank" rel="noopener noreferrer"><code>unit:upstream-query-probes.test.ts</code></a>; cursor/empty-snapshot preconditions: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox-target.test.ts#L562" target="_blank" rel="noopener noreferrer"><code>unit:sandbox-target.test.ts</code></a> + <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/sandbox/firestore/admin-compat/cursors.test.ts#L198" target="_blank" rel="noopener noreferrer"><code>unit:admin-compat/cursors.test.ts</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L340" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
359
+ <div class="compat-evidence"><div class="compat-probe">Oracle-locked by <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-limittolast-preconditions.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-limittolast-preconditions.json</code></a>: production's no-orderBy precondition throws code <code>unimplemented</code>, while ordered trailing-window semantics return <code>["b"]</code>. <code>oracle:firestore#61</code> replays both claims. Cursor composition + descending: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/upstream-query-probes.test.ts#L10" target="_blank" rel="noopener noreferrer"><code>unit:upstream-query-probes.test.ts</code></a>; cursor/empty-snapshot preconditions: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox-target.test.ts#L562" target="_blank" rel="noopener noreferrer"><code>unit:sandbox-target.test.ts</code></a> + <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/sandbox/firestore/admin-compat/cursors.test.ts#L198" target="_blank" rel="noopener noreferrer"><code>unit:admin-compat/cursors.test.ts</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L356" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>)</div></div>
359
360
  </details>
360
361
  <details class="compat-row" data-status="ok">
361
362
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Query construction</code><span class="compat-sub"><span class="compat-behavior">Composite filters AND with other constraints — <code>query(coll, or(...), orderBy(...), limit(...))</code></span></span></span></summary>
@@ -420,8 +421,8 @@ html{scrollbar-gutter:stable}
420
421
  <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox-target.test.ts#L793" target="_blank" rel="noopener noreferrer"><code>unit:sandbox-target.test.ts</code></a></div></div>
421
422
  </details>
422
423
  <details class="compat-row" data-status="ok">
423
- <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Aggregates</code><span class="compat-sub"><span class="compat-behavior"><code>getAggregateFromServer(query, spec)</code> returns <code>{ data: () => Record&#x3C;alias, number|null> }</code></span></span></span></summary>
424
- <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox-target.test.ts#L809" target="_blank" rel="noopener noreferrer"><code>unit:sandbox-target.test.ts</code></a>; collectionGroup + nested paths: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/upstream-write-aggregate-probes.test.ts#L22" target="_blank" rel="noopener noreferrer"><code>unit:upstream-write-aggregate-probes.test.ts</code></a></div></div>
424
+ <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Aggregates</code><span class="compat-sub"><span class="compat-behavior"><code>getAggregateFromServer(query, spec)</code> returns <code>{ data: () => Record&#x3C;alias, number|null> }</code> in the in-page sandbox, on a served page and in a registered Node process</span></span></span></summary>
425
+ <div class="compat-evidence"><div class="compat-probe">In-page: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox-target.test.ts#L809" target="_blank" rel="noopener noreferrer"><code>unit:sandbox-target.test.ts</code></a>; collectionGroup + nested paths: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/upstream-write-aggregate-probes.test.ts#L22" target="_blank" rel="noopener noreferrer"><code>unit:upstream-write-aggregate-probes.test.ts</code></a>. Production: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-aggregate-field-semantics.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-aggregate-field-semantics</code></a> key <code>countOnly</code> (<code>{ n: 4 }</code>), replayed through the served surface export and through the worker client and host in <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/oracle-captures/firestore-served-surface.test.ts#L17" target="_blank" rel="noopener noreferrer"><code>unit:cli/serve/worker/oracle-captures/firestore-served-surface.test.ts</code></a>; that scenario's other keys are pinned under FL-27, FL-28 and FL-30. A served page and a registered Node process aggregate over the host in <code>test/apps/client-sdk-under-register</code>.</div></div>
425
426
  </details>
426
427
  <details class="compat-row" data-status="ok">
427
428
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Aggregates</code><span class="compat-sub"><span class="compat-behavior"><code>count()</code> / <code>sum(field)</code> / <code>average(field)</code> compose under one spec — <code>field</code> may be a dotted nested path</span></span></span></summary>
@@ -503,7 +504,7 @@ html{scrollbar-gutter:stable}
503
504
  </details>
504
505
  <details class="compat-row" data-status="ok">
505
506
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">runTransaction(db, fn)</code><span class="compat-sub"><span class="compat-behavior">Retry behavior — a read-document conflict reruns the callback against fresh data; <code>maxAttempts</code> bounds persistent contention</span></span></span></summary>
506
- <div class="compat-evidence"><div class="compat-probe">Oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-transaction-contention-retries.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-transaction-contention-retries.json</code></a> — two production Web SDK clients force one retry (<code>[0, 40]</code>, final <code>42</code>) and persistent contention with <code>maxAttempts: 2</code> runs exactly twice then throws <code>failed-precondition</code>. <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L671" target="_blank" rel="noopener noreferrer"><code>packages/pyric/test/firestore/oracle-conformance.test.ts</code></a> replays both cases through the sandbox. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox-target.test.ts#L37" target="_blank" rel="noopener noreferrer"><code>sandbox-target.test.ts</code></a>)</div></div>
507
+ <div class="compat-evidence"><div class="compat-probe">Oracle: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-transaction-contention-retries.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-transaction-contention-retries.json</code></a> — two production Web SDK clients force one retry (<code>[0, 40]</code>, final <code>42</code>) and persistent contention with <code>maxAttempts: 2</code> runs exactly twice then throws <code>failed-precondition</code>. <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L687" target="_blank" rel="noopener noreferrer"><code>packages/pyric/test/firestore/oracle-conformance.test.ts</code></a> replays both cases through the sandbox. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox-target.test.ts#L37" target="_blank" rel="noopener noreferrer"><code>sandbox-target.test.ts</code></a>)</div></div>
507
508
  </details>
508
509
  <details class="compat-row" data-status="ok">
509
510
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">runTransaction(db, fn)</code><span class="compat-sub"><span class="compat-behavior">Throws <code>FirebaseError('permission-denied')</code> on rule denial inside the transaction (the inner write's denial — not a generic <code>aborted</code>). Sandbox throws <code>FirestoreCompatError</code> with the same <code>code: 'permission-denied'</code></span></span></span></summary>
@@ -619,11 +620,11 @@ html{scrollbar-gutter:stable}
619
620
  </details>
620
621
  <details class="compat-row" data-status="ok">
621
622
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Equality helpers</code><span class="compat-sub"><span class="compat-behavior"><code>queryEqual(a, b)</code> structurally compares collection and collection-group scope, filter/order/limit/cursor constraint structure, converter identity, and construction-time Firestore value snapshots for both equality and execution without re-observing caller objects. Snapshots cover maps/arrays, scalar objects, references (including raw and converted <code>addDoc()</code> results), and vectors; normalize Date to Timestamp; preserve the distinction between -0 and 0; compare snapshot and explicit bounds for all four cursor overloads by value without invoking snapshot converters, including across live-target rebuilds; reject undefined, bigint, nested arrays for ordinary and array-membership operands, and recursively nested cross-database references during query construction; and preserve Firebase's nested-array allowance for <code>in</code>/<code>not-in</code> candidate lists.</span></span></span></summary>
622
- <div class="compat-evidence"><div class="compat-probe">Oracle-locked by <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-queryequal-structural.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-queryequal-structural.json</code></a>: collection and collection-group scope, order sequence/direction, limits, composite filters, cursor values/inclusivity, converters, and Firestore operands all distinguish equal from changed queries as production does. The capture executes mutable maps, Timestamp, Bytes, GeoPoint, DocumentReference (including raw and converted <code>addDoc()</code> results), and Vector queries; proves Bytes/Vector source-array mutation cannot change existing or new queries; proves all four snapshot cursor overloads compare with explicit bounds and execute twice without invoking a consumer converter; and locks recursive foreign-reference rejection, Date/Timestamp normalization, and -0 handling. <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-query-nested-array-validation.json" target="_blank" rel="noopener noreferrer"><code>firestore-query-nested-array-validation.json</code></a> separately pins the production SDK's client-side rejection of nested arrays without implying a cloud round trip. The replay forces live-target identity rebuilds for every snapshot cursor overload. <code>oracle:firestore#116</code> replays every claimed fact. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L1167" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/equality.test.ts#L14" target="_blank" rel="noopener noreferrer"><code>equality.test.ts</code></a>)</div></div>
623
+ <div class="compat-evidence"><div class="compat-probe">Oracle-locked by <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-queryequal-structural.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-queryequal-structural.json</code></a>: collection and collection-group scope, order sequence/direction, limits, composite filters, cursor values/inclusivity, converters, and Firestore operands all distinguish equal from changed queries as production does. The capture executes mutable maps, Timestamp, Bytes, GeoPoint, DocumentReference (including raw and converted <code>addDoc()</code> results), and Vector queries; proves Bytes/Vector source-array mutation cannot change existing or new queries; proves all four snapshot cursor overloads compare with explicit bounds and execute twice without invoking a consumer converter; and locks recursive foreign-reference rejection, Date/Timestamp normalization, and -0 handling. <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-query-nested-array-validation.json" target="_blank" rel="noopener noreferrer"><code>firestore-query-nested-array-validation.json</code></a> separately pins the production SDK's client-side rejection of nested arrays without implying a cloud round trip. The replay forces live-target identity rebuilds for every snapshot cursor overload. <code>oracle:firestore#116</code> replays every claimed fact. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L1183" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/equality.test.ts#L14" target="_blank" rel="noopener noreferrer"><code>equality.test.ts</code></a>)</div></div>
623
624
  </details>
624
625
  <details class="compat-row" data-status="ok">
625
626
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Equality helpers</code><span class="compat-sub"><span class="compat-behavior"><code>snapshotEqual(a, b)</code> follows production snapshot state. A query's first one-shot read differs from the next identical read, then repeated settled reads (including an independently built equivalent query) compare structurally until query state changes and settles again. Listener snapshots compare query, documents, changes, and metadata. Document snapshots compare path, existence, Firestore-typed data, converter identity, and snapshot kind, so two gets of the same document are equal while a query-child snapshot and a direct get are distinct; scalar-shaped plain maps remain distinct from Timestamp, reference, GeoPoint, and Vector values.</span></span></span></summary>
626
- <div class="compat-evidence"><div class="compat-probe">Oracle-locked by <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-snapshotequal-structural.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-snapshotequal-structural.json</code></a>: sequential and equivalent-query reads prove the initial-to-settled transition; a changed result restarts that transition; listener sensitivity cases vary query, documents/change history, and metadata-only state; direct document cases vary path, existence, data, converter, and snapshot kind; and four collision probes distinguish scalar-shaped maps from their Timestamp, reference, GeoPoint, and Vector counterparts. <code>oracle:firestore#117</code> replays every reachable fact. JSON reconstruction remains raw characterization only because Pyric does not expose that separate API. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L1574" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/equality.test.ts#L16" target="_blank" rel="noopener noreferrer"><code>equality.test.ts</code></a>)</div></div>
627
+ <div class="compat-evidence"><div class="compat-probe">Oracle-locked by <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-snapshotequal-structural.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-snapshotequal-structural.json</code></a>: sequential and equivalent-query reads prove the initial-to-settled transition; a changed result restarts that transition; listener sensitivity cases vary query, documents/change history, and metadata-only state; direct document cases vary path, existence, data, converter, and snapshot kind; and four collision probes distinguish scalar-shaped maps from their Timestamp, reference, GeoPoint, and Vector counterparts. <code>oracle:firestore#117</code> replays every reachable fact. JSON reconstruction remains raw characterization only because Pyric does not expose that separate API. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L1590" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/equality.test.ts#L16" target="_blank" rel="noopener noreferrer"><code>equality.test.ts</code></a>)</div></div>
627
628
  </details>
628
629
  <details class="compat-row" data-status="ok">
629
630
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Equality helpers</code><span class="compat-sub"><span class="compat-behavior">Cross-flavor <code>refEqual</code> via <code>QuerySnapshot.docs[i].ref</code> works</span></span></span></summary>
@@ -648,29 +649,32 @@ html{scrollbar-gutter:stable}
648
649
  <h2 id="offline--persistence--network-family">Offline / persistence / network family</h2>
649
650
  <h2 id="offline--persistence--network-family-continued">Offline / persistence / network family (continued)</h2>
650
651
  <div class="compat-list">
651
- <details class="compat-row" data-status="ok">
652
- <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">enableIndexedDbPersistence</code><span class="compat-sub"><span class="compat-behavior">Resolves before Firestore starts and rejects with <code>failed-precondition</code> after any operation has started the service</span></span></span></summary>
653
- <div class="compat-evidence"><div class="compat-probe">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>firestore-browser-lifecycle.json</code></a>; replayed through the public modular API by <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L721" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a> and focused lifecycle coverage. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/persistence-network.test.ts#L7" target="_blank" rel="noopener noreferrer"><code>persistence-network.test.ts</code></a>)</div></div>
652
+ <details class="compat-row" data-status="diverged">
653
+ <summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">enableIndexedDbPersistence</code><span class="compat-sub"><span class="compat-behavior">Resolves before Firestore starts and rejects with <code>failed-precondition</code> after any operation has started the service</span></span></span></summary>
654
+ <div class="compat-evidence"><div class="compat-probe">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>firestore-browser-lifecycle.json</code></a>; replayed through the public modular API by <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L737" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a> and focused lifecycle coverage. Served planes: an accepted no-op that resolves after first use (FP-9). (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/persistence-network.test.ts#L7" target="_blank" rel="noopener noreferrer"><code>persistence-network.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/oracle-captures/firestore-served-surface.test.ts#L89" target="_blank" rel="noopener noreferrer"><code>firestore-served-surface.test.ts</code></a>)</div>
655
+ <div class="compat-note">an accepted no-op on the served planes (FP-9)</div></div>
654
656
  </details>
655
657
  <details class="compat-row" data-status="ok">
656
658
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">enableMultiTabIndexedDbPersistence</code><span class="compat-sub"><span class="compat-behavior">Enables multi-client shared persistence before first use, permits two clients to opt in, and rejects initialization after a client has started with <code>failed-precondition</code></span></span></span></summary>
657
- <div class="compat-evidence"><div class="compat-probe">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>firestore-browser-lifecycle.json</code></a> exercises fresh, after-use, and two-client initialization; replayed through public APIs by <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L721" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a> and focused persistence tests. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/persistence-network.test.ts#L14" target="_blank" rel="noopener noreferrer"><code>persistence-network.test.ts</code></a>)</div></div>
659
+ <div class="compat-evidence"><div class="compat-probe">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>firestore-browser-lifecycle.json</code></a> exercises fresh, after-use, and two-client initialization; replayed through public APIs by <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L737" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a> and focused persistence tests. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/persistence-network.test.ts#L14" target="_blank" rel="noopener noreferrer"><code>persistence-network.test.ts</code></a>)</div></div>
658
660
  </details>
659
661
  <details class="compat-row" data-status="ok">
660
662
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">clearIndexedDbPersistence</code><span class="compat-sub"><span class="compat-behavior">Maps to <code>Sandbox.clearPersistence()</code> — actually wipes the persisted blob (honest, not a no-op); already a no-op when persistence was never enabled</span></span></span></summary>
661
663
  <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/persistence-network.test.ts#L14" target="_blank" rel="noopener noreferrer"><code>unit:firestore/persistence-network.test.ts</code></a></div></div>
662
664
  </details>
663
- <details class="compat-row" data-status="ok">
664
- <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">enableNetwork / disableNetwork</code><span class="compat-sub"><span class="compat-behavior">Disabling network exposes local mutations with cache/pending-write metadata while holding write acknowledgement until network is re-enabled</span></span></span></summary>
665
- <div class="compat-evidence"><div class="compat-probe">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>firestore-browser-lifecycle.json</code></a>; replayed through the public modular API by <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L721" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a> and focused network coverage. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/persistence-network.test.ts#L9" target="_blank" rel="noopener noreferrer"><code>persistence-network.test.ts</code></a>)</div></div>
665
+ <details class="compat-row" data-status="diverged">
666
+ <summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">enableNetwork / disableNetwork</code><span class="compat-sub"><span class="compat-behavior">Disabling network exposes local mutations with cache/pending-write metadata while holding write acknowledgement until network is re-enabled</span></span></span></summary>
667
+ <div class="compat-evidence"><div class="compat-probe">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>firestore-browser-lifecycle.json</code></a>; replayed through the public modular API by <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L737" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a> and focused network coverage. Served planes: accepted no-ops, so an offline write commits at once (FP-9). (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/persistence-network.test.ts#L9" target="_blank" rel="noopener noreferrer"><code>persistence-network.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/oracle-captures/firestore-served-surface.test.ts#L89" target="_blank" rel="noopener noreferrer"><code>firestore-served-surface.test.ts</code></a>)</div>
668
+ <div class="compat-note">an accepted no-op on the served planes (FP-9)</div></div>
666
669
  </details>
667
670
  <details class="compat-row" data-status="ok">
668
671
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">waitForPendingWrites</code><span class="compat-sub"><span class="compat-behavior">Waits for outstanding offline write acknowledgements and resolves when network re-enable drains them</span></span></span></summary>
669
- <div class="compat-evidence"><div class="compat-probe">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>firestore-browser-lifecycle.json</code></a>; replayed through the public modular API by <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L721" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a> and focused pending-write coverage. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/persistence-network.test.ts#L11" target="_blank" rel="noopener noreferrer"><code>persistence-network.test.ts</code></a>)</div></div>
672
+ <div class="compat-evidence"><div class="compat-probe">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>firestore-browser-lifecycle.json</code></a>; replayed through the public modular API by <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L737" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a> and focused pending-write coverage. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/persistence-network.test.ts#L11" target="_blank" rel="noopener noreferrer"><code>persistence-network.test.ts</code></a>)</div></div>
670
673
  </details>
671
- <details class="compat-row" data-status="ok">
672
- <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">terminate</code><span class="compat-sub"><span class="compat-behavior">Terminates only the selected Firestore service instance: held refs reject with <code>failed-precondition</code>, owned listeners stop, and sibling Firestore or Auth services remain usable</span></span></span></summary>
673
- <div class="compat-evidence"><div class="compat-probe">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-browser-lifecycle.json</code></a> records <code>failed-precondition</code> on the terminated instance while Auth and a sibling Firestore instance continue. Replayed by <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L721" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>; focused ownership coverage in <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/terminate.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>terminate.test.ts</code></a>.</div></div>
674
+ <details class="compat-row" data-status="diverged">
675
+ <summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">terminate</code><span class="compat-sub"><span class="compat-behavior">Terminates only the selected Firestore service instance: held refs reject with <code>failed-precondition</code>, owned listeners stop, and sibling Firestore or Auth services remain usable</span></span></span></summary>
676
+ <div class="compat-evidence"><div class="compat-probe">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-browser-lifecycle.json</code></a> records <code>failed-precondition</code> on the terminated instance while Auth and a sibling Firestore instance continue. Replayed by <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L737" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>; focused ownership coverage in <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/terminate.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>terminate.test.ts</code></a>. SharedWorker: a no-op, so held refs keep working (FP-9).</div>
677
+ <div class="compat-note">a no-op over the SharedWorker (FP-9)</div></div>
674
678
  </details>
675
679
  </div>
676
680
  <h2 id="tier-1-cache-init--get-from--family">Tier-1 cache-init + get-from-* family</h2>
@@ -690,9 +694,10 @@ html{scrollbar-gutter:stable}
690
694
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">getDocFromServer / getDocsFromServer</code><span class="compat-sub"><span class="compat-behavior">Delegates to <code>getDoc</code> / <code>getDocs</code> in the sandbox mirror — the sandbox store IS the authoritative source, so there is no separate server round-trip to force and no observable divergence from the default read</span></span></span></summary>
691
695
  <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/tier1-cache-init-align.test.ts#L12" target="_blank" rel="noopener noreferrer"><code>unit:firestore/tier1-cache-init-align.test.ts</code></a></div></div>
692
696
  </details>
693
- <details class="compat-row" data-status="ok">
694
- <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">getDocFromCache / getDocsFromCache</code><span class="compat-sub"><span class="compat-behavior">Explicit cache reads distinguish cold and warm state: cold document reads reject with <code>unavailable</code>, cold queries return empty, and server/default reads populate subsequent cache reads</span></span></span></summary>
695
- <div class="compat-evidence"><div class="compat-probe">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>firestore-browser-lifecycle.json</code></a> captures cold and warm document and query cache behavior; <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L721" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a> replays it through public APIs. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/tier1-cache-init-align.test.ts#L13" target="_blank" rel="noopener noreferrer"><code>tier1-cache-init-align.test.ts</code></a>)</div></div>
697
+ <details class="compat-row" data-status="diverged">
698
+ <summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getDocFromCache / getDocsFromCache</code><span class="compat-sub"><span class="compat-behavior">Explicit cache reads distinguish cold and warm state: cold document reads reject with <code>unavailable</code>, cold queries return empty, and server/default reads populate subsequent cache reads</span></span></span></summary>
699
+ <div class="compat-evidence"><div class="compat-probe">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>firestore-browser-lifecycle.json</code></a> captures cold and warm document and query cache behavior; <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L737" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a> replays it through public APIs. Served planes: reads the store, so a cold read resolves (FP-9). (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/tier1-cache-init-align.test.ts#L13" target="_blank" rel="noopener noreferrer"><code>tier1-cache-init-align.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/oracle-captures/firestore-served-surface.test.ts#L89" target="_blank" rel="noopener noreferrer"><code>firestore-served-surface.test.ts</code></a>)</div>
700
+ <div class="compat-note">reads the store on the served planes (FP-9)</div></div>
696
701
  </details>
697
702
  <details class="compat-row" data-status="diverged">
698
703
  <summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">setLogLevel</code><span class="compat-sub"><span class="compat-behavior">Accepted no-op. The sandbox has no modular-SDK-style logger to wire a level into. It uses host-level <code>console</code> logging directly, gated by <code>pyric sandbox</code>'s own flags, not this call</span></span></span></summary>
@@ -701,7 +706,7 @@ html{scrollbar-gutter:stable}
701
706
  </details>
702
707
  <details class="compat-row" data-status="ok">
703
708
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">onSnapshotsInSync</code><span class="compat-sub"><span class="compat-behavior">Emits an initial in-sync signal, batches another signal after snapshot listener delivery, and stops after unsubscribe</span></span></span></summary>
704
- <div class="compat-evidence"><div class="compat-probe">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>firestore-browser-lifecycle.json</code></a> records initial sync, write snapshot, then sync; replayed by <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L721" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a> and focused listener tests. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/tier1-cache-init-align.test.ts#L14" target="_blank" rel="noopener noreferrer"><code>tier1-cache-init-align.test.ts</code></a>)</div></div>
709
+ <div class="compat-evidence"><div class="compat-probe">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>firestore-browser-lifecycle.json</code></a> records initial sync, write snapshot, then sync; replayed by <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L737" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a> and focused listener tests. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/tier1-cache-init-align.test.ts#L14" target="_blank" rel="noopener noreferrer"><code>tier1-cache-init-align.test.ts</code></a>)</div></div>
705
710
  </details>
706
711
  <details class="compat-row" data-status="ok">
707
712
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">Runtime ES Classes / Constructor Tokens</code><span class="compat-sub"><span class="compat-behavior">Exports ES classes and constructor tokens matching structural type handles for instanceof checks and prototype inheritance</span></span></span></summary>
@@ -790,7 +795,7 @@ on a compiled ruleset share one parse per ruleset source, and the next
790
795
  </details>
791
796
  <details class="compat-row" data-status="ok">
792
797
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><span class="compat-behavior">A single-document write exposes <code>request.resource.data</code> as the document the write stores. <code>updateDoc(ref, {'board.c1r1': 'x'})</code> shows rules a nested <code>board.c1r1</code> beside the existing <code>board</code> keys, not a top-level field named <code>"board.c1r1"</code>; a dotted <code>deleteField()</code> removes the nested leaf; <code>setDoc(ref, data, {merge: true})</code> deep-merges a nested map and keeps its sibling keys, and <code>{mergeFields}</code> writes only the listed paths. The field-and-value form carries each field path as literal segments: <code>updateDoc(ref, new FieldPath('a.b'), 'x')</code> writes a top-level field <code>'a.b'</code>, <code>new FieldPath('board', 'c1.r1')</code> writes a dotted key inside <code>board</code>, and a dotted string field is a nested path, through <code>updateDoc</code>, <code>WriteBatch.update</code>, <code>Transaction.update</code>, the Admin-shaped <code>update</code>, and the served worker. <code>resource.data</code> is unchanged by the projection.</span></span></summary>
793
- <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-write-request-resource.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-write-request-resource</code></a> (captured 2026-10-07 against deployed production rules with the Web SDK, stable across two runs). Each case is one client write to a seeded document, and each predicate over <code>request.resource.data</code> or <code>request.resource.data.diff(resource.data)</code> is a separate guarded rule, so the allow or deny of the write reads out what production built. Production exposes the stored document: <code>updateDoc(ref, {'board.c1r1': 'x'})</code> gives <code>request.resource.data.board.c1r1 == 'x'</code> with <code>board.c2r2</code> and the top-level fields kept, no <code>'board.c1r1'</code> key, and <code>affectedKeys()</code> and <code>changedKeys()</code> equal to <code>['board']</code>; a dotted <code>deleteField()</code> removes only the nested leaf; <code>setDoc</code> with <code>merge</code> deep-merges (<code>affectedKeys()</code> is <code>['board', 'extra']</code>); <code>mergeFields</code> writes only the listed path; <code>updateDoc(ref, {board: {c1r1: 'x'}})</code> replaces the whole <code>board</code> map; non-merge <code>setDoc</code> drops the unlisted top-level field (<code>removedKeys()</code> is <code>['keep']</code>); <code>resource.data</code> is unchanged by the write; the field-and-value form <code>updateDoc(ref, new FieldPath('a.b'), 'x')</code> writes a literal top-level key <code>'a.b'</code> (<code>'a.b' in request.resource.data</code>, <code>!('a' in request.resource.data)</code>, <code>affectedKeys() == ['a.b']</code>) and <code>new FieldPath('board', 'c1.r1')</code> writes a literal dotted key inside <code>board</code> (<code>affectedKeys() == ['board']</code>). The sandbox replays every verdict, the literal-dot field-path cases included (<a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L41" target="_blank" rel="noopener noreferrer"><code>unit:firestore/oracle-conformance.test.ts</code></a>, 58 predicates over 10 writes). Update field paths travel as segment vectors: the served worker protocol and the remote Admin arm carry <code>fields: [{ path: string[], value }]</code>, and inside the engine an update payload is keyed by a Pyric-internal encoding that backtick-quotes a segment containing <code>.</code>. That encoding stays in the engine: request events, write events, errors and denial context carry the update's fields as nested maps plus <code>updateMask</code> (its field paths as segment vectors), and replay rebuilds the update from the two. <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/remote/remote-firestore.test.ts#L37" target="_blank" rel="noopener noreferrer"><code>packages/pyric-admin/test/remote/remote-firestore.test.ts</code></a> covers the remote Admin arm. <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/update-field-paths.test.ts#L4" target="_blank" rel="noopener noreferrer"><code>unit:firestore/update-field-paths.test.ts</code></a> covers <code>updateDoc</code>, <code>WriteBatch.update</code>, <code>Transaction.update</code>, a transform and <code>deleteField()</code> at a literal-dot path, and the Admin-shaped <code>DocumentReference.update</code>, <code>WriteBatch.update</code> and <code>Transaction.update</code>; <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/update-field-paths.test.ts#L5" target="_blank" rel="noopener noreferrer"><code>packages/cli/test/serve/worker/update-field-paths.test.ts</code></a> covers the served worker, including rules that read the literal key. Argument validation is client-side SDK code with no server round trip, so its messages follow the Web SDK <code>parseUpdateVarargs</code> / <code>fieldPathFromArgument</code> and the Admin SDK <code>WriteBatch.update</code> sources: an odd field-and-value count, an empty segment, a reserved character, a non-string field, and an <code>undefined</code> value each throw the SDK's message. The Rules Test API takes <code>request.resource</code> as input and cannot show any of this, so the capture uses a client write. <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox/rules-test-case.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>unit:firestore/sandbox/rules-test-case.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/sandbox/firestore/simulator/local-environment.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>unit:sandbox/firestore/simulator/local-environment.test.ts</code></a>, and <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/sandbox/firestore/simulator/project-after-state.test.ts#L12" target="_blank" rel="noopener noreferrer"><code>unit:sandbox/firestore/simulator/project-after-state.test.ts</code></a> pin the local projection.</div></div>
798
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-write-request-resource.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-write-request-resource</code></a> (captured 2026-10-07 against deployed production rules with the Web SDK, stable across two runs). Each case is one client write to a seeded document, and each predicate over <code>request.resource.data</code> or <code>request.resource.data.diff(resource.data)</code> is a separate guarded rule, so the allow or deny of the write reads out what production built. Production exposes the stored document: <code>updateDoc(ref, {'board.c1r1': 'x'})</code> gives <code>request.resource.data.board.c1r1 == 'x'</code> with <code>board.c2r2</code> and the top-level fields kept, no <code>'board.c1r1'</code> key, and <code>affectedKeys()</code> and <code>changedKeys()</code> equal to <code>['board']</code>; a dotted <code>deleteField()</code> removes only the nested leaf; <code>setDoc</code> with <code>merge</code> deep-merges (<code>affectedKeys()</code> is <code>['board', 'extra']</code>); <code>mergeFields</code> writes only the listed path; <code>updateDoc(ref, {board: {c1r1: 'x'}})</code> replaces the whole <code>board</code> map; non-merge <code>setDoc</code> drops the unlisted top-level field (<code>removedKeys()</code> is <code>['keep']</code>); <code>resource.data</code> is unchanged by the write; the field-and-value form <code>updateDoc(ref, new FieldPath('a.b'), 'x')</code> writes a literal top-level key <code>'a.b'</code> (<code>'a.b' in request.resource.data</code>, <code>!('a' in request.resource.data)</code>, <code>affectedKeys() == ['a.b']</code>) and <code>new FieldPath('board', 'c1.r1')</code> writes a literal dotted key inside <code>board</code> (<code>affectedKeys() == ['board']</code>). The sandbox replays every verdict, the literal-dot field-path cases included (<a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L42" target="_blank" rel="noopener noreferrer"><code>unit:firestore/oracle-conformance.test.ts</code></a>, 58 predicates over 10 writes). Update field paths travel as segment vectors: the served worker protocol and the remote Admin arm carry <code>fields: [{ path: string[], value }]</code>, and inside the engine an update payload is keyed by a Pyric-internal encoding that backtick-quotes a segment containing <code>.</code>. That encoding stays in the engine: request events, write events, errors and denial context carry the update's fields as nested maps plus <code>updateMask</code> (its field paths as segment vectors), and replay rebuilds the update from the two. <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/remote/remote-firestore.test.ts#L37" target="_blank" rel="noopener noreferrer"><code>packages/pyric-admin/test/remote/remote-firestore.test.ts</code></a> covers the remote Admin arm. <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/update-field-paths.test.ts#L4" target="_blank" rel="noopener noreferrer"><code>unit:firestore/update-field-paths.test.ts</code></a> covers <code>updateDoc</code>, <code>WriteBatch.update</code>, <code>Transaction.update</code>, a transform and <code>deleteField()</code> at a literal-dot path, and the Admin-shaped <code>DocumentReference.update</code>, <code>WriteBatch.update</code> and <code>Transaction.update</code>; <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/update-field-paths.test.ts#L5" target="_blank" rel="noopener noreferrer"><code>packages/cli/test/serve/worker/update-field-paths.test.ts</code></a> covers the served worker, including rules that read the literal key. Argument validation is client-side SDK code with no server round trip, so its messages follow the Web SDK <code>parseUpdateVarargs</code> / <code>fieldPathFromArgument</code> and the Admin SDK <code>WriteBatch.update</code> sources: an odd field-and-value count, an empty segment, a reserved character, a non-string field, and an <code>undefined</code> value each throw the SDK's message. The Rules Test API takes <code>request.resource</code> as input and cannot show any of this, so the capture uses a client write. <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox/rules-test-case.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>unit:firestore/sandbox/rules-test-case.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/sandbox/firestore/simulator/local-environment.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>unit:sandbox/firestore/simulator/local-environment.test.ts</code></a>, and <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/sandbox/firestore/simulator/project-after-state.test.ts#L12" target="_blank" rel="noopener noreferrer"><code>unit:sandbox/firestore/simulator/project-after-state.test.ts</code></a> pin the local projection.</div></div>
794
799
  </details>
795
800
  <details class="compat-row" data-status="ok">
796
801
  <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><span class="compat-behavior">Int/float distinction (<code>1.5 is int</code>→false, <code>1 is float</code>→false, <code>1.0 is float</code>→true) + integer division (<code>10 / 4 == 2</code>) + int div/mod-by-zero ERRORS (RULES-B5); strict <code>int('12abc')</code>/<code>float('abc')</code> parsing (RULES-B6 rest); <code>bool()</code> is not a Firestore rules function, so <code>bool('true')</code> is "Function not found error: Name: [bool]" and denies; <code>string(1.0)</code>→"1.0" (RULES-B12 rest)</span></span></summary>
@@ -823,7 +828,7 @@ on a compiled ruleset share one parse per ruleset source, and the next
823
828
  <div class="compat-list">
824
829
  <details class="compat-row" data-status="diverged">
825
830
  <summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getFirestore(app) in a registered server process</code><span class="compat-sub"><span class="compat-behavior">Under a remote register activation on the Node host, <code>firebase/firestore</code> in a server process reads and writes the host's documents under its rules as the process's signed-in user. An open listener keeps the process up; a finished write releases it at once. A CommonJS <code>require('firebase/firestore')</code> resolves the same client. An app whose options differ from the host's gets each call rejected with <code>app/multiple-configs-not-supported</code>, and nothing throws past the call. When the host is not the Node host, every call fails with <code>failed-precondition</code> and a message naming the Node host (<code>pyric sandbox --hosted</code> or <code>pyric({ hosted: true })</code>); when no host is found, with the discovery error <code>pyric-admin</code> gets. No call falls back to an in-process sandbox.</span></span></span></summary>
826
- <div class="compat-evidence"><div class="compat-probe">App scenario <code>test/apps/client-sdk-under-register</code> runs the client SDKs under <code>node --import @pyric/cli/register</code> against a hosted Vite dev server, reads back with <code>firebase-admin</code> and a page, and asserts a write the page and firebase-admin read, a CommonJS require, an app with other options rejected per call, and that a listener holds the process while a finished write does not. On main (942cb175) it failed: the calls ran against a private in-process sandbox, so an upload returned a <a href="https://github.com/davideast/pyric/blob/main/test/apps/client-sdk-under-register/scenario.ts#L1" target="_blank" rel="noopener noreferrer"><code>data:</code></a> URL and firebase-admin read nothing they wrote. <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/register/node-origin.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>packages/cli/test/register/node-origin.test.ts</code></a> runs the served surfaces under a Node origin whose host is not the Node host, or cannot be found, and asserts every call fails, <code>useWorker</code> stays true, the served app entry's placeholder sandbox stays empty, and a <code>pyric/*</code> mirror resolved from the app refuses. <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/register/mapping.test.ts#L80" target="_blank" rel="noopener noreferrer"><code>mapping.test.ts</code></a> pins the mapping per activation value.. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/register/register-child.test.ts#L201" target="_blank" rel="noopener noreferrer"><code>register-child.test.ts</code></a>)</div>
831
+ <div class="compat-evidence"><div class="compat-probe">App scenario <code>test/apps/client-sdk-under-register</code> runs the client SDKs under <code>node --import @pyric/cli/register</code> against a hosted Vite dev server, reads back with <code>firebase-admin</code> and a page, and asserts a write the page and firebase-admin read, a CommonJS require, an app with other options rejected per call, and that a listener holds the process while a finished write does not. On main (942cb175) it failed: the calls ran against a private in-process sandbox, so an upload returned a <a href="https://github.com/davideast/pyric/blob/main/test/apps/client-sdk-under-register/scenario.ts#L1" target="_blank" rel="noopener noreferrer"><code>data:</code></a> URL and firebase-admin read nothing they wrote. <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/register/node-origin.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>packages/cli/test/register/node-origin.test.ts</code></a> runs the served surfaces under a Node origin whose host is not the Node host, or cannot be found, and asserts every call fails, <code>useWorker</code> stays true, the served app entry's placeholder sandbox stays empty, and a <code>pyric/*</code> mirror resolved from the app refuses. <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/register/mapping.test.ts#L78" target="_blank" rel="noopener noreferrer"><code>mapping.test.ts</code></a> pins the mapping per activation value.. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/register/register-child.test.ts#L201" target="_blank" rel="noopener noreferrer"><code>register-child.test.ts</code></a>)</div>
827
832
  <div class="compat-note">a finished write releases the process at once, where production holds it until the write stream's 60 s idle timeout; one configuration per runtime</div></div>
828
833
  </details>
829
834
  </div>
@@ -841,36 +846,138 @@ on a compiled ruleset share one parse per ruleset source, and the next
841
846
  <div class="compat-note">admin reads and writes bypass the rules, as firebase-admin's do</div></div>
842
847
  </details>
843
848
  </div>
849
+ <h2 id="behavior-checked-against-production-captures">Behavior checked against production captures</h2>
850
+ <p>Each row cites a production capture from the SDK behavior hunt. A <code>bug</code> row states production’s behavior and pyric’s; its test holds both answers until the fix lands.</p>
851
+ <div class="compat-list">
852
+ <details class="compat-row" data-status="bug">
853
+ <summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">getAggregateFromServer(query, { n: count(), s: sum(field) })</code><span class="compat-sub"><span class="compat-behavior">Production: when count() is paired with sum(y), count includes only the docs that have y (3 of 4). Pyric counts every doc in the query (4). FL-27.</span></span></span></summary>
854
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-aggregate-field-semantics.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-aggregate-field-semantics</code></a> key <code>countAndSumY</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-aggregate-field-semantics.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-aggregate-field-semantics.test.ts</code></a>)</div></div>
855
+ </details>
856
+ <details class="compat-row" data-status="bug">
857
+ <summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">sum(field) / average(field) over NaN or Infinity</code><span class="compat-sub"><span class="compat-behavior">Production: sum and average over a field holding NaN return NaN, and over Infinity return Infinity. Pyric skips the non-finite values (sum 3 and average 1.5; sum 1 and average 1). FL-28.</span></span></span></summary>
858
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-aggregate-field-semantics.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-aggregate-field-semantics</code></a> keys <code>nan</code> and <code>inf</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-aggregate-field-semantics.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-aggregate-field-semantics.test.ts</code></a>)</div></div>
859
+ </details>
860
+ <details class="compat-row" data-status="diverged">
861
+ <summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getDocs / getAggregateFromServer on a shape that needs a composite index</code><span class="compat-sub"><span class="compat-behavior">Production fails a query or multi-field aggregation that needs a missing composite index with <code>failed-precondition</code>. Pyric runs it by design; only the served dev chip signals it, and two-range, OR and aggregate shapes get no signal. FL-30.</span></span></span></summary>
862
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-query-composite-index-required.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-query-composite-index-required</code></a> (four shapes and two controls) and <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-aggregate-field-semantics.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-aggregate-field-semantics</code></a> keys <code>multi</code> and <code>nullField</code>. Decided 2026-10-27: fix where production is clear; until then this row says they differ. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-query-composite-index-required.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-query-composite-index-required.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-aggregate-field-semantics.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-aggregate-field-semantics.test.ts</code></a>)</div></div>
863
+ </details>
864
+ <details class="compat-row" data-status="bug">
865
+ <summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">where(field, 'in' | 'not-in' | 'array-contains-any', values) / or(...)</code><span class="compat-sub"><span class="compat-behavior">Production: getDocs fails with <code>invalid-argument</code> for <code>in</code> with 31 values, <code>not-in</code> with 11, <code>array-contains-any</code> with 31, or() with 31 branches, and 36 terms after normalization; 30 and 10 values succeed. Pyric runs every one. FL-29.</span></span></span></summary>
866
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-query-disjunction-limits.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-query-disjunction-limits</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-query-disjunction-limits.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-query-disjunction-limits.test.ts</code></a>)</div></div>
867
+ </details>
868
+ <details class="compat-row" data-status="ok">
869
+ <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">where(field, '==' | '!=', 0) with a -0 value stored</code><span class="compat-sub"><span class="compat-behavior">-0 equals 0 in <code>==</code> and <code>!=</code> but not in <code>in</code>, as in production. FL-31.</span></span></span></summary>
870
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-query-negative-zero.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-query-negative-zero</code></a> and <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-non-finite-number-roundtrip.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-non-finite-number-roundtrip</code></a> key <code>eq0</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-query-negative-zero.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-query-negative-zero.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-non-finite-number-roundtrip.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-non-finite-number-roundtrip.test.ts</code></a>)</div></div>
871
+ </details>
872
+ <details class="compat-row" data-status="bug">
873
+ <summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">onSnapshot: per-doc metadata.hasPendingWrites on the local-write echo</code><span class="compat-sub"><span class="compat-behavior">Production: the echo of a local write reports <code>hasPendingWrites</code> true on the doc, for a doc listener and for the doc inside a query snapshot, and only on the written doc. Pyric reports false on the doc. FL-20.</span></span></span></summary>
874
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-listener-local-write-metadata.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-listener-local-write-metadata</code></a> and <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-query-doc-pending-writes.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-query-doc-pending-writes</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-listener-local-write-metadata.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-listener-local-write-metadata.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-query-doc-pending-writes.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-query-doc-pending-writes.test.ts</code></a>)</div></div>
875
+ </details>
876
+ <details class="compat-row" data-status="bug">
877
+ <summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">QuerySnapshot.docChanges({ includeMetadataChanges: true }) on the ack snapshot</code><span class="compat-sub"><span class="compat-behavior">Production: the snapshot that acknowledges a local write lists the doc as <code>modified</code> with <code>hasPendingWrites</code> false. Pyric's list is empty. FL-21.</span></span></span></summary>
878
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-listener-local-write-metadata.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-listener-local-write-metadata</code></a> key <code>qMeta</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-listener-local-write-metadata.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-listener-local-write-metadata.test.ts</code></a>)</div></div>
879
+ </details>
880
+ <details class="compat-row" data-status="bug">
881
+ <summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">setDoc past the documented write limits</code><span class="compat-sub"><span class="compat-behavior">Production fails with <code>invalid-argument</code> past its write limits (1 MiB docs, reserved or 1,501-byte ids and field names, 501 transforms, 26 nested maps); pyric stores them. FW-14.</span></span></span></summary>
882
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-write-server-limits.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-write-server-limits</code></a> and <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-write-map-depth-limit.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-write-map-depth-limit</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-write-server-limits.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-write-server-limits.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-write-map-depth-limit.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-write-map-depth-limit.test.ts</code></a>)</div></div>
883
+ </details>
884
+ <details class="compat-row" data-status="ok">
885
+ <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><code class="compat-api">writeBatch / runTransaction: delete then update of one doc</code><span class="compat-sub"><span class="compat-behavior">A batch or transaction that deletes and then updates one doc fails with <code>invalid-argument</code> and leaves the doc unchanged, as production does. Set then update and update then delete commit. Only the error text differs. The capture refuted hunt finding FW-19.</span></span></span></summary>
886
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-delete-then-update-same-commit.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-delete-then-update-same-commit</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-delete-then-update-same-commit.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-delete-then-update-same-commit.test.ts</code></a>)</div></div>
887
+ </details>
888
+ <details class="compat-row" data-status="bug">
889
+ <summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">runTransaction when the update function swallows a read-after-write error</code><span class="compat-sub"><span class="compat-behavior">Production: runTransaction rejects <code>invalid-argument</code> and writes nothing, even when the update function catches the read-after-write error and returns. Pyric resolves with the returned value and commits the write. FW-6.</span></span></span></summary>
890
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-transaction-client-checks.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-transaction-client-checks</code></a> key <code>swallowedReadAfterWrite</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-transaction-client-checks.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-transaction-client-checks.test.ts</code></a>)</div></div>
891
+ </details>
892
+ <details class="compat-row" data-status="bug">
893
+ <summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">runTransaction error codes</code><span class="compat-sub"><span class="compat-behavior">Production fails read-after-write and update-after-missing-read with <code>invalid-argument</code>; pyric gives <code>failed-precondition</code> and <code>not-found</code>. FW-7.</span></span></span></summary>
894
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-transaction-client-checks.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-transaction-client-checks</code></a> keys <code>readAfterWrite</code> and <code>updateAfterReadMissing</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-transaction-client-checks.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-transaction-client-checks.test.ts</code></a>)</div></div>
895
+ </details>
896
+ <details class="compat-row" data-status="bug">
897
+ <summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">serverTimestamp() read from the pending local echo</code><span class="compat-sub"><span class="compat-behavior">Production's pending serverTimestamp echo is pending and reads null, or the estimate or prior value by option; pyric reads a resolved Timestamp. FW-10; also #1355.</span></span></span></summary>
898
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-servertimestamp-pending-echo.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-servertimestamp-pending-echo</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-servertimestamp-pending-echo.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-servertimestamp-pending-echo.test.ts</code></a>)</div></div>
899
+ </details>
900
+ <details class="compat-row" data-status="bug">
901
+ <summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">setDoc that the rules deny, made while the network is disabled</code><span class="compat-sub"><span class="compat-behavior">Production keeps a denied offline write pending with a local event, then rejects after reconnect; pyric rejects at once. FW-17.</span></span></span></summary>
902
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-offline-denied-write.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-offline-denied-write</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-offline-denied-write.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-offline-denied-write.test.ts</code></a>)</div></div>
903
+ </details>
904
+ <details class="compat-row" data-status="bug">
905
+ <summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">NaN, Infinity, -Infinity and -0 on the served planes</code><span class="compat-sub"><span class="compat-behavior">Production keeps NaN, Infinity, -Infinity and -0 on a server read, and <code>== NaN</code> matches only the NaN doc. The in-page sandbox agrees. On the SharedWorker and Node host planes they read back as null and 0. FP-1.</span></span></span></summary>
906
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-non-finite-number-roundtrip.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-non-finite-number-roundtrip</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/oracle-captures/firestore-non-finite-number-roundtrip.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-non-finite-number-roundtrip.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-non-finite-number-roundtrip.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-non-finite-number-roundtrip.test.ts</code></a>)</div></div>
907
+ </details>
908
+ <details class="compat-row" data-status="bug">
909
+ <summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">QueryDocumentSnapshot.metadata.hasPendingWrites on the served planes</code><span class="compat-sub"><span class="compat-behavior">Production: only the doc with a pending write reports <code>hasPendingWrites</code> true. The served planes report each doc's own value from the in-page engine, which reports false on the written doc (FL-20), and they skip the first snapshot from the cache (#1355). FP-5 is fixed.</span></span></span></summary>
910
+ <div class="compat-evidence"><div class="compat-probe"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-query-doc-pending-writes.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-query-doc-pending-writes</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/oracle-captures/firestore-query-doc-pending-writes.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-query-doc-pending-writes.test.ts</code></a>)</div></div>
911
+ </details>
912
+ </div>
844
913
  <h2 id="current-gaps">Current gaps</h2>
845
914
  <h3 id="documented-divergences">Documented divergences</h3>
846
915
  <p>Known differences between Pyric and production Firebase. Each remains tracked as a non-conforming row.</p>
847
916
  <div class="compat-list">
848
917
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getFirestore(app, databaseId)</code><span class="compat-sub"><span class="compat-behavior">In the sandbox, <code>getFirestore(app, databaseId)</code> ignores the database id and returns the app's <code>(default)</code> handle, so documents written under one id are read under every other id.</span></span></span></summary>
849
- <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/named-database.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>packages/pyric/test/firestore/named-database.test.ts</code></a> asserts two database ids return the <code>(default)</code> handle and that a document written under one id reads back under another.</div></div></details>
918
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/named-database.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>packages/pyric/test/firestore/named-database.test.ts</code></a> asserts two database ids return the <code>(default)</code> handle and that a document written under one id reads back under another. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-named-database-absent.json" target="_blank" rel="noopener noreferrer"><code>firestore-named-database-absent</code></a>)</div></div></details>
850
919
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getFirestore(app, databaseId) (served mode)</code><span class="compat-sub"><span class="compat-behavior">The served <code>firebase/firestore</code> entry ignores the database id: the worker path returns the app's one handle and the in-page fallback delegates to the sandbox <code>getFirestore(app)</code>. The worker protocol carries no database id.</span></span></span></summary>
851
920
  <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/composite-filters-served-entry.test.ts#L26" target="_blank" rel="noopener noreferrer"><code>packages/cli/test/serve/worker/composite-filters-served-entry.test.ts</code></a> imports the served entry over a worker host, asserts <code>getFirestore(app, 'reports')</code> returns the app's handle, and reads the <code>(default)</code> documents through it.</div></div></details>
852
921
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">pyric-admin getFirestore(app, databaseId)</code><span class="compat-sub"><span class="compat-behavior"><code>pyric-admin</code> <code>getFirestore</code> takes no database id; a second argument is ignored and the handle reads and writes <code>(default)</code>. The Admin SDK's <code>getFirestore(app, databaseId)</code> selects the named database.</span></span></span></summary>
853
- <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/firestore/named-database.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>packages/pyric-admin/test/firestore/named-database.test.ts</code></a> writes through <code>getFirestore(app, 'reports')</code> and reads the document through <code>getFirestore(app)</code> and <code>getFirestore(app, 'archive')</code>.</div></div></details>
922
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/firestore/named-database.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>packages/pyric-admin/test/firestore/named-database.test.ts</code></a> writes through <code>getFirestore(app, 'reports')</code> and reads the document through <code>getFirestore(app)</code> and <code>getFirestore(app, 'archive')</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-named-database-admin-mixing.json" target="_blank" rel="noopener noreferrer"><code>firestore-named-database-admin-mixing</code></a>)</div></div></details>
854
923
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">Rules `match /databases/{database}/documents`</code><span class="compat-sub"><span class="compat-behavior">Rules evaluate the <code>database</code> path variable as <code>(default)</code> for every request, whatever database id the handle was created with. Production binds the named database's id.</span></span></span></summary>
855
- <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/named-database.test.ts#L11" target="_blank" rel="noopener noreferrer"><code>packages/pyric/test/firestore/named-database.test.ts</code></a> writes through a handle created for <code>reports</code>: a rule requiring <code>database == '(default)'</code> allows the write and a rule requiring <code>database == 'reports'</code> denies it.</div></div></details>
924
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/named-database.test.ts#L11" target="_blank" rel="noopener noreferrer"><code>packages/pyric/test/firestore/named-database.test.ts</code></a> writes through a handle created for <code>reports</code>: a rule requiring <code>database == '(default)'</code> allows the write and a rule requiring <code>database == 'reports'</code> denies it. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-named-database-rules-api.json" target="_blank" rel="noopener noreferrer"><code>firestore-named-database-rules-api</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-named-database-cross-database.json" target="_blank" rel="noopener noreferrer"><code>firestore-named-database-cross-database</code></a>)</div></div></details>
856
925
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getDocs(query)</code><span class="compat-sub"><span class="compat-behavior">Query-proof scope remains conservative. Equality and finite scalar in filters can pin candidate fields; array-contains proves the corresponding membership fact, not the whole array. Helpers and positive OR branches reduce to sufficient, candidate-independent residuals. Every finite combination (up to 30) must pass auth, query limits, and any lookup whose path is pinned by the query. Unpinned fields, candidate identity, dynamic document-dependent collections, unbounded range guarantees, and unsupported syntax remain deny-only gaps. Queries are never authorized by filtering stored rows. A collection-group query is authorized only by a top-level <code>list</code> or <code>read</code> rule at <code>match /{path=**}/&#x3C;collectionId>/{id}</code> or <code>match /{document=**}</code> whose condition reads no path binding; any other shape, including a match nested in <code>match /{document=**}</code>, denies the query. This expanded local support has unit evidence and upstream documented semantics, but no new hosted observation.</span></span></span></summary>
857
926
  <div class="compat-evidence"><div class="compat-note">Local query support: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/query-proof-application.test.ts#L10" target="_blank" rel="noopener noreferrer"><code>unit:firestore/query-proof-application.test.ts</code></a> covers finite membership, guardian array membership, pinned lookup paths, auth and limit controls, and adversarial array/lookup cases. Upstream semantics: firebase.google.com/docs/firestore/security/rules-query and firebase.google.com/docs/firestore/query-data/queries. Local diagnostic contract (#583): <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/query-proof-diagnostics.test.ts#L7" target="_blank" rel="noopener noreferrer"><code>unit:firestore/query-proof-diagnostics.test.ts</code></a> pins dynamic membership rejection, fallback attribution, constraint/residual distinctions, modular listener context, captured lifecycle errors, and immutable operation-summary proof metadata; this adds no production observation. <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/rules/simulator/query-proof.test.ts#L7" target="_blank" rel="noopener noreferrer"><code>unit:rules/simulator/query-proof.test.ts</code></a> (function-inlining provable cases; full-accounting rejections for mixed equality + <code>in</code>/<code>get</code>/<code>hasOnly</code>/range/<code>is</code> shapes in inline and helper form; fail-closed classifier probes: bracket-access <code>resource['data']</code>, <code>exists()</code> keyed by <code>resource.data</code> through path-literal segments, slice access, <code>resource.id</code>, and an unrecognized node shape), <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/query-proof-enforcement.test.ts#L19" target="_blank" rel="noopener noreferrer"><code>unit:firestore/query-proof-enforcement.test.ts</code></a> (seeded end-to-end denials of the demonstrated attacks: forbidden-field absence check in member and bracket form, banned-owner <code>exists()</code> lookup, slice conjunct, each returning zero documents). Collection-group scope: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/collection-group-rules.test.ts#L18" target="_blank" rel="noopener noreferrer"><code>unit:firestore/collection-group-rules.test.ts</code></a> authorizes <code>getDocs(collectionGroup(db, 'items'))</code> under <code>match /{path=**}/items/{id}</code>, proves a data-gated rule from the query's equality, and denies under a rule for another collection id, a rule that reads the recursive binding, and concrete collection rules; <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/sandbox/collection-group-rule-proof.test.ts#L1" target="_blank" rel="noopener noreferrer"><code>unit:firestore/sandbox/collection-group-rule-proof.test.ts</code></a> pins the projection. Upstream semantics: firebase.google.com/docs/firestore/security/rules-query#secure_and_query_documents_based_on_collection_groups. No hosted collection-group query is captured; the production matcher verdicts for the same rule shape, from the Rules Test API, live in <code>oracle:rules-firestore-hierarchical-match-cascade</code>.</div></div></details>
858
927
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">Query construction</code><span class="compat-sub"><span class="compat-behavior">Index validation against <code>firestore.indexes.json</code> — sandbox uses <code>LocalEnvironment</code>'s lint pass; prod has its own server-side validation</span></span></span></summary>
859
928
  <div class="compat-evidence"><div class="compat-note">divergence: sandbox can mis-pass a query that prod would reject at the server with <code>failed-precondition</code> if no index exists</div></div></details>
860
929
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">Aggregates</code><span class="compat-sub"><span class="compat-behavior">Aggregates count documents server-side without paying read cost per doc in prod; sandbox computes locally (no cost model)</span></span></span></summary>
861
930
  <div class="compat-evidence"><div class="compat-note">divergence: cost behavior differs, observable shape identical. Oracle-locked: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-count-aggregate-shape.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-count-aggregate-shape.json</code></a> — <code>getCountFromServer().data()</code> returns <code>{ count: &#x3C;number> }</code> (single key, no other fields). Empty query returns <code>count: 0</code> (not <code>null</code>/<code>undefined</code>); seeded 3 docs returns <code>count: 3</code>; filtered query honors the <code>where</code> constraint (<code>count: 2</code>).</div></div></details>
931
+ <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">enableIndexedDbPersistence</code><span class="compat-sub"><span class="compat-behavior">Resolves before Firestore starts and rejects with <code>failed-precondition</code> after any operation has started the service</span></span></span></summary>
932
+ <div class="compat-evidence"><div class="compat-note">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>firestore-browser-lifecycle.json</code></a>; replayed through the public modular API by <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L737" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a> and focused lifecycle coverage. Served planes: an accepted no-op that resolves after first use (FP-9). (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/persistence-network.test.ts#L7" target="_blank" rel="noopener noreferrer"><code>persistence-network.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/oracle-captures/firestore-served-surface.test.ts#L89" target="_blank" rel="noopener noreferrer"><code>firestore-served-surface.test.ts</code></a>)</div></div></details>
933
+ <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">enableNetwork / disableNetwork</code><span class="compat-sub"><span class="compat-behavior">Disabling network exposes local mutations with cache/pending-write metadata while holding write acknowledgement until network is re-enabled</span></span></span></summary>
934
+ <div class="compat-evidence"><div class="compat-note">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>firestore-browser-lifecycle.json</code></a>; replayed through the public modular API by <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L737" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a> and focused network coverage. Served planes: accepted no-ops, so an offline write commits at once (FP-9). (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/persistence-network.test.ts#L9" target="_blank" rel="noopener noreferrer"><code>persistence-network.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/oracle-captures/firestore-served-surface.test.ts#L89" target="_blank" rel="noopener noreferrer"><code>firestore-served-surface.test.ts</code></a>)</div></div></details>
935
+ <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">terminate</code><span class="compat-sub"><span class="compat-behavior">Terminates only the selected Firestore service instance: held refs reject with <code>failed-precondition</code>, owned listeners stop, and sibling Firestore or Auth services remain usable</span></span></span></summary>
936
+ <div class="compat-evidence"><div class="compat-note">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>packages/conformance/observations/firestore/firestore-browser-lifecycle.json</code></a> records <code>failed-precondition</code> on the terminated instance while Auth and a sibling Firestore instance continue. Replayed by <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L737" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a>; focused ownership coverage in <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/terminate.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>terminate.test.ts</code></a>. SharedWorker: a no-op, so held refs keep working (FP-9).</div></div></details>
862
937
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">initializeFirestore</code><span class="compat-sub"><span class="compat-behavior">Delegates to sandbox <code>getFirestore(app)</code> and returns the same handle. Accepts the <code>settings</code> argument (so the explicit-init pattern doesn't crash at import) but no-ops the cache/network settings — persistence is always on</span></span></span></summary>
863
938
  <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/tier1-cache-init-align.test.ts#L7" target="_blank" rel="noopener noreferrer"><code>unit:firestore/tier1-cache-init-align.test.ts</code></a></div></div></details>
864
939
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">persistentLocalCache / memoryLocalCache / persistentSingleTabManager / persistentMultipleTabManager / memoryEagerGarbageCollector / memoryLruGarbageCollector</code><span class="compat-sub"><span class="compat-behavior">Config token accepted, inert — each returns a small tagged object so identity/usage doesn't crash. Persistence is the sandbox default; there is no cache tier left to configure</span></span></span></summary>
865
940
  <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/tier1-cache-init-align.test.ts#L8" target="_blank" rel="noopener noreferrer"><code>unit:firestore/tier1-cache-init-align.test.ts</code></a></div></div></details>
941
+ <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getDocFromCache / getDocsFromCache</code><span class="compat-sub"><span class="compat-behavior">Explicit cache reads distinguish cold and warm state: cold document reads reject with <code>unavailable</code>, cold queries return empty, and server/default reads populate subsequent cache reads</span></span></span></summary>
942
+ <div class="compat-evidence"><div class="compat-note">Real Chromium: <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-browser-lifecycle.json" target="_blank" rel="noopener noreferrer"><code>firestore-browser-lifecycle.json</code></a> captures cold and warm document and query cache behavior; <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-conformance.test.ts#L737" target="_blank" rel="noopener noreferrer"><code>oracle-conformance.test.ts</code></a> replays it through public APIs. Served planes: reads the store, so a cold read resolves (FP-9). (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/tier1-cache-init-align.test.ts#L13" target="_blank" rel="noopener noreferrer"><code>tier1-cache-init-align.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/oracle-captures/firestore-served-surface.test.ts#L89" target="_blank" rel="noopener noreferrer"><code>firestore-served-surface.test.ts</code></a>)</div></div></details>
866
943
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">setLogLevel</code><span class="compat-sub"><span class="compat-behavior">Accepted no-op. The sandbox has no modular-SDK-style logger to wire a level into. It uses host-level <code>console</code> logging directly, gated by <code>pyric sandbox</code>'s own flags, not this call</span></span></span></summary>
867
944
  <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/tier1-cache-init-align.test.ts#L13" target="_blank" rel="noopener noreferrer"><code>unit:firestore/tier1-cache-init-align.test.ts</code></a></div></div></details>
868
945
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">Writes and reads in flight at a hosted connection drop (web hosted client)</code><span class="compat-sub"><span class="compat-behavior">A Firestore write (<code>setDoc</code>, <code>updateDoc</code>, <code>deleteDoc</code>, a batch <code>commit</code>) or read (<code>getDoc</code>, <code>getDocs</code>) the web hosted client's socket had taken when it dropped fails once with <code>unavailable</code> and the message "The hosted sandbox connection was lost. Requests already sent may have completed; check state before retrying." It is not sent again. In production the Firestore Web SDK keeps a write in its mutation queue and sends it again on the next write stream until the backend acknowledges it, and answers a <code>getDoc</code> from its local cache, with <code>fromCache</code>, or fails it with <code>unavailable</code> when the document is not cached.</span></span></span></summary>
869
946
  <div class="compat-evidence"><div class="compat-note">Production behavior read from <code>@firebase/firestore</code> 4.14.1, as recorded in ADR-0019 ("Reads and writes are treated alike, unlike production"). <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/hosted-reconnect-hold.test.ts#L412" target="_blank" rel="noopener noreferrer"><code>packages/cli/test/serve/worker/hosted-reconnect-hold.test.ts</code></a> drops a real loopback socket with <code>setDoc</code>, <code>getDoc</code> and <code>batchCommit</code> in flight and asserts each fails once with that message and reaches the host once. The Realtime Database follows its SDK here instead (row <code>rtdb-modular#HD1</code>, #1088).</div></div></details>
870
947
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getFirestore(app) in a registered server process</code><span class="compat-sub"><span class="compat-behavior">Under a remote register activation on the Node host, <code>firebase/firestore</code> in a server process reads and writes the host's documents under its rules as the process's signed-in user. An open listener keeps the process up; a finished write releases it at once. A CommonJS <code>require('firebase/firestore')</code> resolves the same client. An app whose options differ from the host's gets each call rejected with <code>app/multiple-configs-not-supported</code>, and nothing throws past the call. When the host is not the Node host, every call fails with <code>failed-precondition</code> and a message naming the Node host (<code>pyric sandbox --hosted</code> or <code>pyric({ hosted: true })</code>); when no host is found, with the discovery error <code>pyric-admin</code> gets. No call falls back to an in-process sandbox.</span></span></span></summary>
871
- <div class="compat-evidence"><div class="compat-note">App scenario <code>test/apps/client-sdk-under-register</code> runs the client SDKs under <code>node --import @pyric/cli/register</code> against a hosted Vite dev server, reads back with <code>firebase-admin</code> and a page, and asserts a write the page and firebase-admin read, a CommonJS require, an app with other options rejected per call, and that a listener holds the process while a finished write does not. On main (942cb175) it failed: the calls ran against a private in-process sandbox, so an upload returned a <a href="https://github.com/davideast/pyric/blob/main/test/apps/client-sdk-under-register/scenario.ts#L1" target="_blank" rel="noopener noreferrer"><code>data:</code></a> URL and firebase-admin read nothing they wrote. <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/register/node-origin.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>packages/cli/test/register/node-origin.test.ts</code></a> runs the served surfaces under a Node origin whose host is not the Node host, or cannot be found, and asserts every call fails, <code>useWorker</code> stays true, the served app entry's placeholder sandbox stays empty, and a <code>pyric/*</code> mirror resolved from the app refuses. <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/register/mapping.test.ts#L80" target="_blank" rel="noopener noreferrer"><code>mapping.test.ts</code></a> pins the mapping per activation value.. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/register/register-child.test.ts#L201" target="_blank" rel="noopener noreferrer"><code>register-child.test.ts</code></a>)</div></div></details>
948
+ <div class="compat-evidence"><div class="compat-note">App scenario <code>test/apps/client-sdk-under-register</code> runs the client SDKs under <code>node --import @pyric/cli/register</code> against a hosted Vite dev server, reads back with <code>firebase-admin</code> and a page, and asserts a write the page and firebase-admin read, a CommonJS require, an app with other options rejected per call, and that a listener holds the process while a finished write does not. On main (942cb175) it failed: the calls ran against a private in-process sandbox, so an upload returned a <a href="https://github.com/davideast/pyric/blob/main/test/apps/client-sdk-under-register/scenario.ts#L1" target="_blank" rel="noopener noreferrer"><code>data:</code></a> URL and firebase-admin read nothing they wrote. <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/register/node-origin.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>packages/cli/test/register/node-origin.test.ts</code></a> runs the served surfaces under a Node origin whose host is not the Node host, or cannot be found, and asserts every call fails, <code>useWorker</code> stays true, the served app entry's placeholder sandbox stays empty, and a <code>pyric/*</code> mirror resolved from the app refuses. <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/register/mapping.test.ts#L78" target="_blank" rel="noopener noreferrer"><code>mapping.test.ts</code></a> pins the mapping per activation value.. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/register/register-child.test.ts#L201" target="_blank" rel="noopener noreferrer"><code>register-child.test.ts</code></a>)</div></div></details>
872
949
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getFirestore(app) in a server-rendered module under vite dev</code><span class="compat-sub"><span class="compat-behavior">On a hosted dev server, <code>firebase/firestore</code> in a server-rendered module reads and writes the host's documents under its rules as the SSR session's user: a write the rules deny for that user fails with <code>permission-denied</code>. <code>ssrLoadModule</code>, the environment runner and every <code>ssr.noExternal</code> setting share one app and one session. On a SharedWorker dev server every call fails with <code>failed-precondition</code> and a message naming <code>pyric({ hosted: true })</code>. No call reaches production or an in-process sandbox.</span></span></span></summary>
873
950
  <div class="compat-evidence"><div class="compat-note">App scenario <code>test/apps/vite-ssr-client-sdk</code> writes and reads the SSR user's own document, is denied another user's, reads the writes back with <code>firebase-admin</code> in SSR and in a process on the host, with each externalization setting, and refuses on a SharedWorker dev server. On main (ba2c0bf0a) the scenario failed: SSR sign-in rejected with <code>auth/network-request-failed</code> from the network guard, and the RTDB, Firestore and Storage writes did not settle, because the imports loaded the real SDK. <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/vite-module-swap.test.ts#L4" target="_blank" rel="noopener noreferrer"><code>vite-module-swap.test.ts</code></a> pins the routing per specifier, AI mode and environment (Vite 5's <code>ssr</code> option, a runnable environment, a non-runnable one), <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/vite-ssr-activation.test.ts#L1" target="_blank" rel="noopener noreferrer"><code>vite-ssr-activation.test.ts</code></a> the host, the restart hand-over and the SharedWorker refusal, and <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/vite-plugin-firestore.test.ts#L36" target="_blank" rel="noopener noreferrer"><code>vite-plugin-firestore.test.ts</code></a> runs Vite with <code>firebase</code> installed, so it takes the externalized path. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/test/apps/vite-ssr-client-sdk/scenario.ts#L1" target="_blank" rel="noopener noreferrer"><code>scenario.ts</code></a>)</div></div></details>
874
951
  <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">firebase-admin/firestore in a server-rendered module under vite dev</code><span class="compat-sub"><span class="compat-behavior">On a hosted dev server, <code>firebase-admin/firestore</code> in a server-rendered module reads and writes the dev server host's documents as admin, past the rules, as a <code>firebase-admin</code> process on the host does. On a SharedWorker dev server its first call fails with <code>failed-precondition</code> and a message naming <code>pyric({ hosted: true })</code>.</span></span></span></summary>
875
952
  <div class="compat-evidence"><div class="compat-note">App scenario <code>test/apps/vite-ssr-client-sdk</code> reads a document the rules let only the SSR user read with <code>firebase-admin</code> in SSR through both loaders and with each externalization setting. On main (ba2c0bf0a) <code>firebase-admin</code> in SSR was the real SDK. <a href="https://github.com/davideast/pyric/blob/main/packages/pyric-admin/test/app/ambient-init.test.ts#L128" target="_blank" rel="noopener noreferrer"><code>ambient-init.test.ts</code></a> pins the ambient binding. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/test/apps/vite-ssr-client-sdk/scenario.ts#L1" target="_blank" rel="noopener noreferrer"><code>scenario.ts</code></a>)</div></div></details>
876
- </div> </article> </main> <aside class="doc-toc" aria-label="On this page" data-astro-cid-mw7aashj> <h2 class="doc-toc-heading" data-astro-cid-mw7aashj>On this page</h2> <ul data-astro-cid-mw7aashj> <li data-depth="2" data-astro-cid-mw7aashj> <a href="#status-legend" data-astro-cid-mw7aashj>Status legend</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#getfirestoretarget--initializer" data-astro-cid-mw7aashj>getFirestore(target) — initializer</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#named-databases" data-astro-cid-mw7aashj>Named databases</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#path-constructors--doc--collection--collectiongroup" data-astro-cid-mw7aashj>Path constructors — doc / collection / collectionGroup</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#getdocref--single-doc-read" data-astro-cid-mw7aashj>getDoc(ref) — single-doc read</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#getdocsquery--bulk-read" data-astro-cid-mw7aashj>getDocs(query) — bulk read</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#setdocref-data-options--full-write" data-astro-cid-mw7aashj>setDoc(ref, data[, options]) — full write</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#updatedocref-data--partial-write" data-astro-cid-mw7aashj>updateDoc(ref, data) — partial write</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#deletedocref" data-astro-cid-mw7aashj>deleteDoc(ref)</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#adddoccoll-data--auto-id-write" data-astro-cid-mw7aashj>addDoc(coll, data) — auto-id write</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#withconverter--typed-refs" data-astro-cid-mw7aashj>withConverter — typed refs</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#query-construction--query--where--or--and--orderby--limit" data-astro-cid-mw7aashj>Query construction — query / where / or / and / orderBy / limit</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#cursor-pagination--startat--startafter--endat--endbefore" data-astro-cid-mw7aashj>Cursor pagination — startAt / startAfter / endAt / endBefore</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#aggregates--getcountfromserver--getaggregatefromserver--count--sum--average" data-astro-cid-mw7aashj>Aggregates — getCountFromServer / getAggregateFromServer / count / sum / average</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#onsnapshotreforquery---listeners" data-astro-cid-mw7aashj>onSnapshot(refOrQuery, …) — listeners</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#runtransactiondb-fn" data-astro-cid-mw7aashj>runTransaction(db, fn)</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#writebatchdb" data-astro-cid-mw7aashj>writeBatch(db)</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#sentinels--servertimestamp--increment--arrayunion--arrayremove--deletefield--fieldvalue--timestamp" data-astro-cid-mw7aashj>Sentinels — serverTimestamp / increment / arrayUnion / arrayRemove / deleteField / FieldValue / Timestamp</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#scalar-types--bytes--geopoint--fieldpath--documentid" data-astro-cid-mw7aashj>Scalar types — Bytes / GeoPoint / FieldPath / documentId</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#equality-helpers--refequal--queryequal--snapshotequal" data-astro-cid-mw7aashj>Equality helpers — refEqual / queryEqual / snapshotEqual</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#connectfirestoreemulator" data-astro-cid-mw7aashj>connectFirestoreEmulator</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#offline--persistence--network-family" data-astro-cid-mw7aashj>Offline / persistence / network family</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#offline--persistence--network-family-continued" data-astro-cid-mw7aashj>Offline / persistence / network family (continued)</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#tier-1-cache-init--get-from--family" data-astro-cid-mw7aashj>Tier-1 cache-init + get-from-* family</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#tier-1-cache-init--get-from--family-continued" data-astro-cid-mw7aashj>Tier-1 cache-init + get-from-* family (continued)</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#rules-engine-via-setrules-from-pyricsandboxfirestore" data-astro-cid-mw7aashj>Rules engine (via setRules from pyric/sandbox/firestore)</a> </li><li data-depth="3" data-astro-cid-mw7aashj> <a href="#calls-in-flight-when-the-hosted-connection-drops" data-astro-cid-mw7aashj>Calls in flight when the hosted connection drops</a> </li><li data-depth="3" data-astro-cid-mw7aashj> <a href="#client-sdks-in-a-registered-server-process" data-astro-cid-mw7aashj>Client SDKs in a registered server process</a> </li><li data-depth="3" data-astro-cid-mw7aashj> <a href="#server-rendered-modules-under-vite-dev" data-astro-cid-mw7aashj>Server-rendered modules under vite dev</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#current-gaps" data-astro-cid-mw7aashj>Current gaps</a> </li><li data-depth="3" data-astro-cid-mw7aashj> <a href="#documented-divergences" data-astro-cid-mw7aashj>Documented divergences</a> </li> </ul> </aside> </div> <script type="module">const a=document.querySelector("[data-api-symbol-filter]"),d=[...document.querySelectorAll("[data-api-symbol-group]")],n=document.querySelector("[data-api-symbol-empty]");a?.addEventListener("input",()=>{const t=a.value.trim().toLowerCase();let o=0;for(const i of d){let e=0;i.querySelectorAll("[data-api-symbol]").forEach(l=>{const r=!t||(l.dataset.apiSymbol??"").includes(t);l.hidden=!r,r&&e++}),i.hidden=e===0,o+=e}n&&(n.hidden=o>0)});</script> <script type="module">const s=new Map;document.querySelectorAll('.doc-toc a[href^="#"]').forEach(t=>s.set(decodeURIComponent(t.hash.slice(1)),t));if(s.size>0){const t=new Set,n=()=>{let o=null;for(const e of s.keys())if(t.has(e)){o=e;break}s.forEach((e,c)=>e.classList.toggle("active",c===o))},r=new IntersectionObserver(o=>{for(const e of o)e.isIntersecting?t.add(e.target.id):t.delete(e.target.id);n()},{rootMargin:"-72px 0px -60% 0px"});s.forEach((o,e)=>{const c=document.getElementById(e);c&&r.observe(c)})}</script> <script type="module">document.querySelector('.studio__nav [aria-current="page"]')?.scrollIntoView({block:"nearest",inline:"center"});</script> </body></html>
953
+ <details class="compat-row" data-status="diverged"><summary class="compat-line"><span class="compat-dot" data-status="diverged" role="img" aria-label="Diverged (documented)" title="Diverged (documented)"></span><span class="compat-main"><code class="compat-api">getDocs / getAggregateFromServer on a shape that needs a composite index</code><span class="compat-sub"><span class="compat-behavior">Production fails a query or multi-field aggregation that needs a missing composite index with <code>failed-precondition</code>. Pyric runs it by design; only the served dev chip signals it, and two-range, OR and aggregate shapes get no signal. FL-30.</span></span></span></summary>
954
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-query-composite-index-required.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-query-composite-index-required</code></a> (four shapes and two controls) and <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-aggregate-field-semantics.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-aggregate-field-semantics</code></a> keys <code>multi</code> and <code>nullField</code>. Decided 2026-10-27: fix where production is clear; until then this row says they differ. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-query-composite-index-required.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-query-composite-index-required.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-aggregate-field-semantics.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-aggregate-field-semantics.test.ts</code></a>)</div></div></details>
955
+ </div>
956
+ <h3 id="bugs">Bugs</h3>
957
+ <p>Behavior that should match production Firebase but currently does not.</p>
958
+ <div class="compat-list">
959
+ <details class="compat-row" data-status="bug"><summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">getAggregateFromServer(query, { n: count(), s: sum(field) })</code><span class="compat-sub"><span class="compat-behavior">Production: when count() is paired with sum(y), count includes only the docs that have y (3 of 4). Pyric counts every doc in the query (4). FL-27.</span></span></span></summary>
960
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-aggregate-field-semantics.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-aggregate-field-semantics</code></a> key <code>countAndSumY</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-aggregate-field-semantics.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-aggregate-field-semantics.test.ts</code></a>)</div></div></details>
961
+ <details class="compat-row" data-status="bug"><summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">sum(field) / average(field) over NaN or Infinity</code><span class="compat-sub"><span class="compat-behavior">Production: sum and average over a field holding NaN return NaN, and over Infinity return Infinity. Pyric skips the non-finite values (sum 3 and average 1.5; sum 1 and average 1). FL-28.</span></span></span></summary>
962
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-aggregate-field-semantics.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-aggregate-field-semantics</code></a> keys <code>nan</code> and <code>inf</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-aggregate-field-semantics.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-aggregate-field-semantics.test.ts</code></a>)</div></div></details>
963
+ <details class="compat-row" data-status="bug"><summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">where(field, 'in' | 'not-in' | 'array-contains-any', values) / or(...)</code><span class="compat-sub"><span class="compat-behavior">Production: getDocs fails with <code>invalid-argument</code> for <code>in</code> with 31 values, <code>not-in</code> with 11, <code>array-contains-any</code> with 31, or() with 31 branches, and 36 terms after normalization; 30 and 10 values succeed. Pyric runs every one. FL-29.</span></span></span></summary>
964
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-query-disjunction-limits.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-query-disjunction-limits</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-query-disjunction-limits.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-query-disjunction-limits.test.ts</code></a>)</div></div></details>
965
+ <details class="compat-row" data-status="bug"><summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">onSnapshot: per-doc metadata.hasPendingWrites on the local-write echo</code><span class="compat-sub"><span class="compat-behavior">Production: the echo of a local write reports <code>hasPendingWrites</code> true on the doc, for a doc listener and for the doc inside a query snapshot, and only on the written doc. Pyric reports false on the doc. FL-20.</span></span></span></summary>
966
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-listener-local-write-metadata.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-listener-local-write-metadata</code></a> and <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-query-doc-pending-writes.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-query-doc-pending-writes</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-listener-local-write-metadata.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-listener-local-write-metadata.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-query-doc-pending-writes.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-query-doc-pending-writes.test.ts</code></a>)</div></div></details>
967
+ <details class="compat-row" data-status="bug"><summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">QuerySnapshot.docChanges({ includeMetadataChanges: true }) on the ack snapshot</code><span class="compat-sub"><span class="compat-behavior">Production: the snapshot that acknowledges a local write lists the doc as <code>modified</code> with <code>hasPendingWrites</code> false. Pyric's list is empty. FL-21.</span></span></span></summary>
968
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-listener-local-write-metadata.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-listener-local-write-metadata</code></a> key <code>qMeta</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-listener-local-write-metadata.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-listener-local-write-metadata.test.ts</code></a>)</div></div></details>
969
+ <details class="compat-row" data-status="bug"><summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">setDoc past the documented write limits</code><span class="compat-sub"><span class="compat-behavior">Production fails with <code>invalid-argument</code> past its write limits (1 MiB docs, reserved or 1,501-byte ids and field names, 501 transforms, 26 nested maps); pyric stores them. FW-14.</span></span></span></summary>
970
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-write-server-limits.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-write-server-limits</code></a> and <a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-write-map-depth-limit.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-write-map-depth-limit</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-write-server-limits.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-write-server-limits.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-write-map-depth-limit.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-write-map-depth-limit.test.ts</code></a>)</div></div></details>
971
+ <details class="compat-row" data-status="bug"><summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">runTransaction when the update function swallows a read-after-write error</code><span class="compat-sub"><span class="compat-behavior">Production: runTransaction rejects <code>invalid-argument</code> and writes nothing, even when the update function catches the read-after-write error and returns. Pyric resolves with the returned value and commits the write. FW-6.</span></span></span></summary>
972
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-transaction-client-checks.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-transaction-client-checks</code></a> key <code>swallowedReadAfterWrite</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-transaction-client-checks.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-transaction-client-checks.test.ts</code></a>)</div></div></details>
973
+ <details class="compat-row" data-status="bug"><summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">runTransaction error codes</code><span class="compat-sub"><span class="compat-behavior">Production fails read-after-write and update-after-missing-read with <code>invalid-argument</code>; pyric gives <code>failed-precondition</code> and <code>not-found</code>. FW-7.</span></span></span></summary>
974
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-transaction-client-checks.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-transaction-client-checks</code></a> keys <code>readAfterWrite</code> and <code>updateAfterReadMissing</code>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-transaction-client-checks.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-transaction-client-checks.test.ts</code></a>)</div></div></details>
975
+ <details class="compat-row" data-status="bug"><summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">serverTimestamp() read from the pending local echo</code><span class="compat-sub"><span class="compat-behavior">Production's pending serverTimestamp echo is pending and reads null, or the estimate or prior value by option; pyric reads a resolved Timestamp. FW-10; also #1355.</span></span></span></summary>
976
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-servertimestamp-pending-echo.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-servertimestamp-pending-echo</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-servertimestamp-pending-echo.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-servertimestamp-pending-echo.test.ts</code></a>)</div></div></details>
977
+ <details class="compat-row" data-status="bug"><summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">setDoc that the rules deny, made while the network is disabled</code><span class="compat-sub"><span class="compat-behavior">Production keeps a denied offline write pending with a local event, then rejects after reconnect; pyric rejects at once. FW-17.</span></span></span></summary>
978
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-offline-denied-write.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-offline-denied-write</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-offline-denied-write.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-offline-denied-write.test.ts</code></a>)</div></div></details>
979
+ <details class="compat-row" data-status="bug"><summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">NaN, Infinity, -Infinity and -0 on the served planes</code><span class="compat-sub"><span class="compat-behavior">Production keeps NaN, Infinity, -Infinity and -0 on a server read, and <code>== NaN</code> matches only the NaN doc. The in-page sandbox agrees. On the SharedWorker and Node host planes they read back as null and 0. FP-1.</span></span></span></summary>
980
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-non-finite-number-roundtrip.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-non-finite-number-roundtrip</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/oracle-captures/firestore-non-finite-number-roundtrip.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-non-finite-number-roundtrip.test.ts</code></a>, <a href="https://github.com/davideast/pyric/blob/main/packages/pyric/test/firestore/oracle-captures/firestore-non-finite-number-roundtrip.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-non-finite-number-roundtrip.test.ts</code></a>)</div></div></details>
981
+ <details class="compat-row" data-status="bug"><summary class="compat-line"><span class="compat-dot" data-status="bug" role="img" aria-label="Bug" title="Bug"></span><span class="compat-main"><code class="compat-api">QueryDocumentSnapshot.metadata.hasPendingWrites on the served planes</code><span class="compat-sub"><span class="compat-behavior">Production: only the doc with a pending write reports <code>hasPendingWrites</code> true. The served planes report each doc's own value from the in-page engine, which reports false on the written doc (FL-20), and they skip the first snapshot from the cache (#1355). FP-5 is fixed.</span></span></span></summary>
982
+ <div class="compat-evidence"><div class="compat-note"><a href="https://github.com/davideast/pyric/blob/main/packages/conformance/observations/firestore/firestore-query-doc-pending-writes.json" target="_blank" rel="noopener noreferrer"><code>oracle:firestore-query-doc-pending-writes</code></a>. (Structured evidence: <a href="https://github.com/davideast/pyric/blob/main/packages/cli/test/serve/worker/oracle-captures/firestore-query-doc-pending-writes.test.ts#L2" target="_blank" rel="noopener noreferrer"><code>firestore-query-doc-pending-writes.test.ts</code></a>)</div></div></details>
983
+ </div> </article> </main> <aside class="doc-toc" aria-label="On this page" data-astro-cid-mw7aashj> <h2 class="doc-toc-heading" data-astro-cid-mw7aashj>On this page</h2> <ul data-astro-cid-mw7aashj> <li data-depth="2" data-astro-cid-mw7aashj> <a href="#status-legend" data-astro-cid-mw7aashj>Status legend</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#getfirestoretarget--initializer" data-astro-cid-mw7aashj>getFirestore(target) — initializer</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#named-databases" data-astro-cid-mw7aashj>Named databases</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#path-constructors--doc--collection--collectiongroup" data-astro-cid-mw7aashj>Path constructors — doc / collection / collectionGroup</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#getdocref--single-doc-read" data-astro-cid-mw7aashj>getDoc(ref) — single-doc read</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#getdocsquery--bulk-read" data-astro-cid-mw7aashj>getDocs(query) — bulk read</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#setdocref-data-options--full-write" data-astro-cid-mw7aashj>setDoc(ref, data[, options]) — full write</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#updatedocref-data--partial-write" data-astro-cid-mw7aashj>updateDoc(ref, data) — partial write</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#deletedocref" data-astro-cid-mw7aashj>deleteDoc(ref)</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#adddoccoll-data--auto-id-write" data-astro-cid-mw7aashj>addDoc(coll, data) — auto-id write</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#withconverter--typed-refs" data-astro-cid-mw7aashj>withConverter — typed refs</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#query-construction--query--where--or--and--orderby--limit" data-astro-cid-mw7aashj>Query construction — query / where / or / and / orderBy / limit</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#cursor-pagination--startat--startafter--endat--endbefore" data-astro-cid-mw7aashj>Cursor pagination — startAt / startAfter / endAt / endBefore</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#aggregates--getcountfromserver--getaggregatefromserver--count--sum--average" data-astro-cid-mw7aashj>Aggregates — getCountFromServer / getAggregateFromServer / count / sum / average</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#onsnapshotreforquery---listeners" data-astro-cid-mw7aashj>onSnapshot(refOrQuery, …) — listeners</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#runtransactiondb-fn" data-astro-cid-mw7aashj>runTransaction(db, fn)</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#writebatchdb" data-astro-cid-mw7aashj>writeBatch(db)</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#sentinels--servertimestamp--increment--arrayunion--arrayremove--deletefield--fieldvalue--timestamp" data-astro-cid-mw7aashj>Sentinels — serverTimestamp / increment / arrayUnion / arrayRemove / deleteField / FieldValue / Timestamp</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#scalar-types--bytes--geopoint--fieldpath--documentid" data-astro-cid-mw7aashj>Scalar types — Bytes / GeoPoint / FieldPath / documentId</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#equality-helpers--refequal--queryequal--snapshotequal" data-astro-cid-mw7aashj>Equality helpers — refEqual / queryEqual / snapshotEqual</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#connectfirestoreemulator" data-astro-cid-mw7aashj>connectFirestoreEmulator</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#offline--persistence--network-family" data-astro-cid-mw7aashj>Offline / persistence / network family</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#offline--persistence--network-family-continued" data-astro-cid-mw7aashj>Offline / persistence / network family (continued)</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#tier-1-cache-init--get-from--family" data-astro-cid-mw7aashj>Tier-1 cache-init + get-from-* family</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#tier-1-cache-init--get-from--family-continued" data-astro-cid-mw7aashj>Tier-1 cache-init + get-from-* family (continued)</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#rules-engine-via-setrules-from-pyricsandboxfirestore" data-astro-cid-mw7aashj>Rules engine (via setRules from pyric/sandbox/firestore)</a> </li><li data-depth="3" data-astro-cid-mw7aashj> <a href="#calls-in-flight-when-the-hosted-connection-drops" data-astro-cid-mw7aashj>Calls in flight when the hosted connection drops</a> </li><li data-depth="3" data-astro-cid-mw7aashj> <a href="#client-sdks-in-a-registered-server-process" data-astro-cid-mw7aashj>Client SDKs in a registered server process</a> </li><li data-depth="3" data-astro-cid-mw7aashj> <a href="#server-rendered-modules-under-vite-dev" data-astro-cid-mw7aashj>Server-rendered modules under vite dev</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#behavior-checked-against-production-captures" data-astro-cid-mw7aashj>Behavior checked against production captures</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#current-gaps" data-astro-cid-mw7aashj>Current gaps</a> </li><li data-depth="3" data-astro-cid-mw7aashj> <a href="#documented-divergences" data-astro-cid-mw7aashj>Documented divergences</a> </li><li data-depth="3" data-astro-cid-mw7aashj> <a href="#bugs" data-astro-cid-mw7aashj>Bugs</a> </li> </ul> </aside> </div> <script type="module">const a=document.querySelector("[data-api-symbol-filter]"),d=[...document.querySelectorAll("[data-api-symbol-group]")],n=document.querySelector("[data-api-symbol-empty]");a?.addEventListener("input",()=>{const t=a.value.trim().toLowerCase();let o=0;for(const i of d){let e=0;i.querySelectorAll("[data-api-symbol]").forEach(l=>{const r=!t||(l.dataset.apiSymbol??"").includes(t);l.hidden=!r,r&&e++}),i.hidden=e===0,o+=e}n&&(n.hidden=o>0)});</script> <script type="module">const s=new Map;document.querySelectorAll('.doc-toc a[href^="#"]').forEach(t=>s.set(decodeURIComponent(t.hash.slice(1)),t));if(s.size>0){const t=new Set,n=()=>{let o=null;for(const e of s.keys())if(t.has(e)){o=e;break}s.forEach((e,c)=>e.classList.toggle("active",c===o))},r=new IntersectionObserver(o=>{for(const e of o)e.isIntersecting?t.add(e.target.id):t.delete(e.target.id);n()},{rootMargin:"-72px 0px -60% 0px"});s.forEach((o,e)=>{const c=document.getElementById(e);c&&r.observe(c)})}</script> <script type="module">document.querySelector('.studio__nav [aria-current="page"]')?.scrollIntoView({block:"nearest",inline:"center"});</script> </body></html>