@pyric/cli 0.1.0-alpha.14 → 0.1.0-alpha.16

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 (606) hide show
  1. package/dist/assurance/.generated/conformance-verdicts.d.ts +120 -75
  2. package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
  3. package/dist/assurance/.generated/conformance-verdicts.js +120 -75
  4. package/dist/assurance/.generated/conformance-verdicts.js.map +1 -1
  5. package/dist/bridge/client/dispatch.js +1 -1
  6. package/dist/bridge/client/dispatch.js.map +1 -1
  7. package/dist/cli/serve.d.ts +1 -1
  8. package/dist/cli/serve.d.ts.map +1 -1
  9. package/dist/cli/serve.js +207 -284
  10. package/dist/cli/serve.js.map +1 -1
  11. package/dist/cli/service-command-records/database-rules-generate.d.ts +4 -0
  12. package/dist/cli/service-command-records/database-rules-generate.d.ts.map +1 -0
  13. package/dist/cli/service-command-records/database-rules-generate.js +3 -0
  14. package/dist/cli/service-command-records/database-rules-generate.js.map +1 -0
  15. package/dist/cli/service-command-records/database-rules-lint.d.ts +4 -0
  16. package/dist/cli/service-command-records/database-rules-lint.d.ts.map +1 -0
  17. package/dist/cli/service-command-records/database-rules-lint.js +3 -0
  18. package/dist/cli/service-command-records/database-rules-lint.js.map +1 -0
  19. package/dist/cli/service-command-records/database-rules-simulate.d.ts +4 -0
  20. package/dist/cli/service-command-records/database-rules-simulate.d.ts.map +1 -0
  21. package/dist/cli/service-command-records/database-rules-simulate.js +3 -0
  22. package/dist/cli/service-command-records/database-rules-simulate.js.map +1 -0
  23. package/dist/cli/service-command-records/database-rules-validate.d.ts +4 -0
  24. package/dist/cli/service-command-records/database-rules-validate.d.ts.map +1 -0
  25. package/dist/cli/service-command-records/database-rules-validate.js +3 -0
  26. package/dist/cli/service-command-records/database-rules-validate.js.map +1 -0
  27. package/dist/cli/service-command-records/firestore-indexes-generate.d.ts +4 -0
  28. package/dist/cli/service-command-records/firestore-indexes-generate.d.ts.map +1 -0
  29. package/dist/cli/service-command-records/firestore-indexes-generate.js +3 -0
  30. package/dist/cli/service-command-records/firestore-indexes-generate.js.map +1 -0
  31. package/dist/cli/service-command-records/firestore-rules-lint.d.ts +4 -0
  32. package/dist/cli/service-command-records/firestore-rules-lint.d.ts.map +1 -0
  33. package/dist/cli/service-command-records/firestore-rules-lint.js +3 -0
  34. package/dist/cli/service-command-records/firestore-rules-lint.js.map +1 -0
  35. package/dist/cli/service-command-records/firestore-rules-resolve.d.ts +4 -0
  36. package/dist/cli/service-command-records/firestore-rules-resolve.d.ts.map +1 -0
  37. package/dist/cli/service-command-records/firestore-rules-resolve.js +3 -0
  38. package/dist/cli/service-command-records/firestore-rules-resolve.js.map +1 -0
  39. package/dist/cli/service-command-records/firestore-rules-simulate.d.ts +4 -0
  40. package/dist/cli/service-command-records/firestore-rules-simulate.d.ts.map +1 -0
  41. package/dist/cli/service-command-records/firestore-rules-simulate.js +3 -0
  42. package/dist/cli/service-command-records/firestore-rules-simulate.js.map +1 -0
  43. package/dist/cli/service-command-records/firestore-rules-validate.d.ts +4 -0
  44. package/dist/cli/service-command-records/firestore-rules-validate.d.ts.map +1 -0
  45. package/dist/cli/service-command-records/firestore-rules-validate.js +3 -0
  46. package/dist/cli/service-command-records/firestore-rules-validate.js.map +1 -0
  47. package/dist/cli/service-command-records/storage-rules-lint.d.ts +4 -0
  48. package/dist/cli/service-command-records/storage-rules-lint.d.ts.map +1 -0
  49. package/dist/cli/service-command-records/storage-rules-lint.js +3 -0
  50. package/dist/cli/service-command-records/storage-rules-lint.js.map +1 -0
  51. package/dist/cli/service-command-records/storage-rules-simulate.d.ts +4 -0
  52. package/dist/cli/service-command-records/storage-rules-simulate.d.ts.map +1 -0
  53. package/dist/cli/service-command-records/storage-rules-simulate.js +3 -0
  54. package/dist/cli/service-command-records/storage-rules-simulate.js.map +1 -0
  55. package/dist/cli/service-commands.d.ts +7 -0
  56. package/dist/cli/service-commands.d.ts.map +1 -1
  57. package/dist/cli/service-commands.generated.d.ts +35 -0
  58. package/dist/cli/service-commands.generated.d.ts.map +1 -0
  59. package/dist/cli/service-commands.generated.js +25 -0
  60. package/dist/cli/service-commands.generated.js.map +1 -0
  61. package/dist/cli/service-commands.js +23 -40
  62. package/dist/cli/service-commands.js.map +1 -1
  63. package/dist/conformance/.generated/can-i-use-browser.d.ts.map +1 -1
  64. package/dist/conformance/.generated/can-i-use-browser.js +1 -1
  65. package/dist/conformance/.generated/can-i-use-browser.js.map +1 -1
  66. package/dist/conformance/.generated/can-i-use.d.ts.map +1 -1
  67. package/dist/conformance/.generated/can-i-use.js +1 -1
  68. package/dist/conformance/.generated/can-i-use.js.map +1 -1
  69. package/dist/conformance/.generated/conformance-docs.d.ts.map +1 -1
  70. package/dist/conformance/.generated/conformance-docs.js +1 -1
  71. package/dist/conformance/.generated/conformance-docs.js.map +1 -1
  72. package/dist/functions-rtdb/development-runtime.d.ts +63 -0
  73. package/dist/functions-rtdb/development-runtime.d.ts.map +1 -0
  74. package/dist/functions-rtdb/development-runtime.js +244 -0
  75. package/dist/functions-rtdb/development-runtime.js.map +1 -0
  76. package/dist/serve/bridge-mount.d.ts +32 -2
  77. package/dist/serve/bridge-mount.d.ts.map +1 -1
  78. package/dist/serve/bridge-mount.js +232 -18
  79. package/dist/serve/bridge-mount.js.map +1 -1
  80. package/dist/serve/bundler.d.ts +2 -18
  81. package/dist/serve/bundler.d.ts.map +1 -1
  82. package/dist/serve/bundler.js +7 -35
  83. package/dist/serve/bundler.js.map +1 -1
  84. package/dist/serve/entries/app-client.d.ts.map +1 -1
  85. package/dist/serve/entries/app-client.js +5 -5
  86. package/dist/serve/entries/app-client.js.map +1 -1
  87. package/dist/serve/entries/auth-helper-core.d.ts +32 -6
  88. package/dist/serve/entries/auth-helper-core.d.ts.map +1 -1
  89. package/dist/serve/entries/auth-helper-core.js +82 -24
  90. package/dist/serve/entries/auth-helper-core.js.map +1 -1
  91. package/dist/serve/entries/auth.d.ts.map +1 -1
  92. package/dist/serve/entries/auth.js +6 -4
  93. package/dist/serve/entries/auth.js.map +1 -1
  94. package/dist/serve/entries/database.d.ts +28 -0
  95. package/dist/serve/entries/database.d.ts.map +1 -1
  96. package/dist/serve/entries/database.js +95 -26
  97. package/dist/serve/entries/database.js.map +1 -1
  98. package/dist/serve/entries/init.d.ts.map +1 -1
  99. package/dist/serve/entries/init.js +21 -12
  100. package/dist/serve/entries/init.js.map +1 -1
  101. package/dist/serve/html-injection.d.ts +5 -0
  102. package/dist/serve/html-injection.d.ts.map +1 -0
  103. package/dist/serve/html-injection.js +59 -0
  104. package/dist/serve/html-injection.js.map +1 -0
  105. package/dist/serve/namespace.d.ts +6 -22
  106. package/dist/serve/namespace.d.ts.map +1 -1
  107. package/dist/serve/namespace.js +23 -145
  108. package/dist/serve/namespace.js.map +1 -1
  109. package/dist/serve/runtime/worker-replacement.d.ts +1 -2
  110. package/dist/serve/runtime/worker-replacement.d.ts.map +1 -1
  111. package/dist/serve/sandbox-session.d.ts +78 -0
  112. package/dist/serve/sandbox-session.d.ts.map +1 -0
  113. package/dist/serve/sandbox-session.js +171 -0
  114. package/dist/serve/sandbox-session.js.map +1 -0
  115. package/dist/serve/server.d.ts +5 -2
  116. package/dist/serve/server.d.ts.map +1 -1
  117. package/dist/serve/server.js +21 -5
  118. package/dist/serve/server.js.map +1 -1
  119. package/dist/serve/site-tree.d.ts +8 -0
  120. package/dist/serve/site-tree.d.ts.map +1 -0
  121. package/dist/serve/site-tree.js +113 -0
  122. package/dist/serve/site-tree.js.map +1 -0
  123. package/dist/serve/site-ui/_astro/RulesCodeEditor.CzwHdCi9.js +23 -0
  124. package/dist/serve/site-ui/_astro/_example_.jevZ7OdV.css +1 -0
  125. package/dist/serve/site-ui/_astro/_slug_.BoKXYrnu.css +1 -0
  126. package/dist/serve/site-ui/_astro/_studio_.BtYpqe1A.css +1 -0
  127. package/dist/serve/site-ui/_astro/app.4HeLP_FA.js +109 -0
  128. package/dist/serve/site-ui/_astro/app.BgSnCR5G.js +1 -0
  129. package/dist/serve/site-ui/_astro/app.BsFsMjn0.css +1 -0
  130. package/dist/serve/site-ui/_astro/chess-showcase.CnoxIle5.js +1 -0
  131. package/dist/serve/site-ui/_astro/chess-source-explorer.C5k9c5yK.js +1 -0
  132. package/dist/serve/site-ui/_astro/chess-v2.CFHmd3UL.js +354 -0
  133. package/dist/serve/site-ui/_astro/client.D2ORs4B-.js +25 -0
  134. package/dist/serve/site-ui/_astro/example-runtime.R1d96L6-.js +291 -0
  135. package/dist/serve/site-ui/_astro/index.BJiOemMX.js +1 -0
  136. package/dist/serve/site-ui/_astro/index.DBy5LfQW.js +9 -0
  137. package/dist/serve/site-ui/_astro/index.DNyk7q8W.js +9 -0
  138. package/dist/serve/site-ui/_astro/jsx-runtime.D_zvdyIk.js +9 -0
  139. package/dist/serve/site-ui/_astro/reads.BrKNdKAa.js +1 -0
  140. package/dist/serve/site-ui/_astro/sandbox-controls.BTb3EbQp.js +1153 -0
  141. package/dist/serve/site-ui/_astro/seed.EyI3VYEu.js +20 -0
  142. package/dist/serve/site-ui/auth/index.html +11 -0
  143. package/dist/serve/site-ui/docs/_rhythm/index.html +100 -0
  144. package/dist/serve/site-ui/docs/agent/set-up-your-agent/index.html +43 -0
  145. package/dist/serve/site-ui/docs/agent/watch-and-review/index.html +26 -0
  146. package/dist/serve/site-ui/docs/agent/work-with-an-agent/index.html +70 -0
  147. package/dist/serve/{docs-ui → site-ui}/docs/ai-compat/index.html +3 -3
  148. package/dist/serve/site-ui/docs/api-reference/index.html +68 -0
  149. package/dist/serve/{docs-ui → site-ui}/docs/app-compat/index.html +3 -3
  150. package/dist/serve/{docs-ui → site-ui}/docs/auth-compat/index.html +3 -3
  151. package/dist/serve/site-ui/docs/build/ai-logic/index.html +64 -0
  152. package/dist/serve/site-ui/docs/build/authentication/index.html +66 -0
  153. package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +84 -0
  154. package/dist/serve/site-ui/docs/build/cloud-messaging/index.html +71 -0
  155. package/dist/serve/site-ui/docs/build/cloud-storage/index.html +66 -0
  156. package/dist/serve/{docs-ui → site-ui}/docs/build/cloud-storage.md +2 -2
  157. package/dist/serve/site-ui/docs/build/realtime-database/index.html +67 -0
  158. package/dist/serve/site-ui/docs/conformance-scores/index.html +50 -0
  159. package/dist/serve/{docs-ui → site-ui}/docs/conformance-scores.md +3 -3
  160. package/dist/serve/site-ui/docs/create-pyric-reference-api/index.html +531 -0
  161. package/dist/serve/{docs-ui → site-ui}/docs/database-compat/index.html +211 -168
  162. package/dist/serve/{docs-ui → site-ui}/docs/database-compat.md +208 -170
  163. package/dist/serve/site-ui/docs/examples/chess/index.html +384 -0
  164. package/dist/serve/site-ui/docs/examples/chess.md +57 -0
  165. package/dist/serve/site-ui/docs/examples/index.html +3 -0
  166. package/dist/serve/site-ui/docs/examples.md +4 -0
  167. package/dist/serve/{docs-ui → site-ui}/docs/firestore-compat/index.html +55 -91
  168. package/dist/serve/{docs-ui → site-ui}/docs/firestore-compat.md +52 -88
  169. package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +73 -0
  170. package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +29 -0
  171. package/dist/serve/site-ui/docs/get-started/start-building/index.html +33 -0
  172. package/dist/serve/{docs-ui → site-ui}/docs/index.json +595 -26
  173. package/dist/serve/site-ui/docs/messaging-compat/index.html +324 -0
  174. package/dist/serve/{docs-ui → site-ui}/docs/messaging-compat.md +71 -1
  175. package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +28 -0
  176. package/dist/serve/site-ui/docs/observe/see-whats-happening/index.html +74 -0
  177. package/dist/serve/site-ui/docs/observe/shape-your-data/index.html +45 -0
  178. package/dist/serve/site-ui/docs/overview/index.html +17 -0
  179. package/dist/serve/site-ui/docs/pyric-admin-app-reference-api/index.html +186 -0
  180. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-auth-reference-api/index.html +4 -4
  181. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-database-reference-api/index.html +4 -4
  182. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-firestore-reference-api/index.html +318 -202
  183. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-firestore-reference-api.md +154 -27
  184. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-messaging-reference-api/index.html +5 -5
  185. package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api/index.html +318 -0
  186. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ai-reference-api/index.html +5 -5
  187. package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +160 -0
  188. package/dist/serve/site-ui/docs/pyric-app-reference-api/index.html +425 -0
  189. package/dist/serve/{docs-ui → site-ui}/docs/pyric-auth-reference-api/index.html +6 -6
  190. package/dist/serve/{docs-ui → site-ui}/docs/pyric-auth-reference-api.md +1 -1
  191. package/dist/serve/site-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +60 -0
  192. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-assurance-reference-api/index.html +4 -4
  193. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-bridge-client-reference-api/index.html +4 -4
  194. package/dist/serve/site-ui/docs/pyric-cli-bridge-reference-api/index.html +507 -0
  195. package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +258 -0
  196. package/dist/serve/site-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +51 -0
  197. package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api/index.html +308 -0
  198. package/dist/serve/site-ui/docs/pyric-cli-credentials-node-reference-api/index.html +68 -0
  199. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-discover-reference-api/index.html +4 -4
  200. package/dist/serve/site-ui/docs/pyric-cli-register-reference-api/index.html +11 -0
  201. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-remote-reference-api/index.html +4 -4
  202. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-serve-worker-reference-api/index.html +1186 -1384
  203. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-serve-worker-reference-api.md +817 -1291
  204. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-verify-reference-api/index.html +4 -4
  205. package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api/index.html +126 -0
  206. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-vite-reference-api.md +1 -1
  207. package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +2641 -0
  208. package/dist/serve/{docs-ui → site-ui}/docs/pyric-database-reference-api.md +1055 -158
  209. package/dist/serve/{docs-ui → site-ui}/docs/pyric-firestore-reference-api/index.html +311 -249
  210. package/dist/serve/{docs-ui → site-ui}/docs/pyric-firestore-reference-api.md +72 -54
  211. package/dist/serve/site-ui/docs/pyric-messaging-reference-api/index.html +509 -0
  212. package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api/index.html +182 -0
  213. package/dist/serve/{docs-ui → site-ui}/docs/pyric-rules-reference-api/index.html +7 -26
  214. package/dist/serve/{docs-ui → site-ui}/docs/pyric-rules-reference-api.md +13 -23
  215. package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api/index.html +121 -0
  216. package/dist/serve/site-ui/docs/pyric-sandbox-firestore-reference-api/index.html +203 -0
  217. package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-reference-api/index.html +26 -5
  218. package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-reference-api.md +22 -22
  219. package/dist/serve/{docs-ui → site-ui}/docs/pyric-storage-reference-api/index.html +5 -15
  220. package/dist/serve/{docs-ui → site-ui}/docs/pyric-storage-reference-api.md +0 -13
  221. package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api/index.html +639 -0
  222. package/dist/serve/site-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +100 -0
  223. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-auth-reference-api/index.html +4 -4
  224. package/dist/serve/site-ui/docs/pyric-ui-events-hooks-reference-api/index.html +24 -0
  225. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-events-reference-api/index.html +4 -4
  226. package/dist/serve/site-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +136 -0
  227. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-firestore-reference-api/index.html +7 -7
  228. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-firestore-reference-api.md +4 -4
  229. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-primitives-reference-api/index.html +4 -4
  230. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rtdb-reference-api/index.html +4 -4
  231. package/dist/serve/site-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +16 -0
  232. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rules-reference-api/index.html +4 -4
  233. package/dist/serve/site-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +176 -0
  234. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-storage-reference-api/index.html +10 -11
  235. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-storage-reference-api.md +7 -8
  236. package/dist/serve/site-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +188 -0
  237. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-traffic-reference-api/index.html +4 -4
  238. package/dist/serve/{docs-ui → site-ui}/docs/rules-compat/index.html +87 -57
  239. package/dist/serve/{docs-ui → site-ui}/docs/rules-compat.md +84 -54
  240. package/dist/serve/site-ui/docs/secure/audit-your-rules/index.html +51 -0
  241. package/dist/serve/site-ui/docs/secure/firestore-rules-limits/index.html +106 -0
  242. package/dist/serve/site-ui/docs/secure/read-a-denial/index.html +41 -0
  243. package/dist/serve/site-ui/docs/secure/rtdb-rules-in-typescript/index.html +67 -0
  244. package/dist/serve/site-ui/docs/secure/rules-standard-library/index.html +159 -0
  245. package/dist/serve/{docs-ui → site-ui}/docs/secure/rules-standard-library.md +2 -2
  246. package/dist/serve/site-ui/docs/secure/secure-it-with-rules/index.html +47 -0
  247. package/dist/serve/site-ui/docs/secure/simulate-and-lint/index.html +95 -0
  248. package/dist/serve/site-ui/docs/secure/write-a-rules-test-suite/index.html +82 -0
  249. package/dist/serve/site-ui/docs/ship/ship-to-production/index.html +37 -0
  250. package/dist/serve/site-ui/docs/ship/test-in-node/index.html +75 -0
  251. package/dist/serve/{docs-ui → site-ui}/docs/storage-compat/index.html +8 -8
  252. package/dist/serve/{docs-ui → site-ui}/docs/storage-compat.md +5 -5
  253. package/dist/serve/site-ui/docs/trust/how-we-know-it-matches-firebase/index.html +132 -0
  254. package/dist/serve/site-ui/docs/trust/rules-standard-library/index.html +861 -0
  255. package/dist/serve/site-ui/docs/trust/rules-standard-library.md +344 -0
  256. package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research/index.html +582 -0
  257. package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research.md +448 -0
  258. package/dist/serve/site-ui/docs/trust/versioning-and-compatibility/index.html +14 -0
  259. package/dist/serve/{docs-ui → site-ui}/docs/tutorial/index.html +4 -4
  260. package/dist/serve/{docs-ui → site-ui}/docs/tutorial.md +1 -1
  261. package/dist/serve/site-ui/examples/chess/index.html +2 -0
  262. package/dist/serve/site-ui/examples/firestore-first-write/index.html +2 -0
  263. package/dist/serve/site-ui/firestore/index.html +11 -0
  264. package/dist/serve/site-ui/index.html +11 -0
  265. package/dist/serve/{docs-ui → site-ui}/llms.txt +6 -2
  266. package/dist/serve/site-ui/rtdb/index.html +11 -0
  267. package/dist/serve/site-ui/settings/index.html +11 -0
  268. package/dist/serve/site-ui/storage/index.html +11 -0
  269. package/dist/serve/site-ui/studio-routes.json +1 -0
  270. package/dist/serve/site-ui/traffic/index.html +11 -0
  271. package/dist/serve/standalone-assets.d.ts +4 -10
  272. package/dist/serve/standalone-assets.d.ts.map +1 -1
  273. package/dist/serve/standalone-assets.js +8 -21
  274. package/dist/serve/standalone-assets.js.map +1 -1
  275. package/dist/serve/vite-functions-development.d.ts +29 -0
  276. package/dist/serve/vite-functions-development.d.ts.map +1 -0
  277. package/dist/serve/vite-functions-development.js +150 -0
  278. package/dist/serve/vite-functions-development.js.map +1 -0
  279. package/dist/serve/vite-generation-bridge.d.ts +17 -0
  280. package/dist/serve/vite-generation-bridge.d.ts.map +1 -0
  281. package/dist/serve/vite-generation-bridge.js +47 -0
  282. package/dist/serve/vite-generation-bridge.js.map +1 -0
  283. package/dist/serve/vite-generation-functions.d.ts +35 -0
  284. package/dist/serve/vite-generation-functions.d.ts.map +1 -0
  285. package/dist/serve/vite-generation-functions.js +46 -0
  286. package/dist/serve/vite-generation-functions.js.map +1 -0
  287. package/dist/serve/vite-generation-middleware.d.ts +10 -0
  288. package/dist/serve/vite-generation-middleware.d.ts.map +1 -0
  289. package/dist/serve/vite-generation-middleware.js +40 -0
  290. package/dist/serve/vite-generation-middleware.js.map +1 -0
  291. package/dist/serve/vite-generation-rules-watch.d.ts +8 -0
  292. package/dist/serve/vite-generation-rules-watch.d.ts.map +1 -0
  293. package/dist/serve/vite-generation-rules-watch.js +33 -0
  294. package/dist/serve/vite-generation-rules-watch.js.map +1 -0
  295. package/dist/serve/vite-module-swap.d.ts +16 -0
  296. package/dist/serve/vite-module-swap.d.ts.map +1 -0
  297. package/dist/serve/vite-module-swap.js +96 -0
  298. package/dist/serve/vite-module-swap.js.map +1 -0
  299. package/dist/serve/vite-page-runtime.d.ts +29 -0
  300. package/dist/serve/vite-page-runtime.d.ts.map +1 -0
  301. package/dist/serve/vite-page-runtime.js +71 -0
  302. package/dist/serve/vite-page-runtime.js.map +1 -0
  303. package/dist/serve/vite-plugin.d.ts +44 -4
  304. package/dist/serve/vite-plugin.d.ts.map +1 -1
  305. package/dist/serve/vite-plugin.js +62 -864
  306. package/dist/serve/vite-plugin.js.map +1 -1
  307. package/dist/serve/vite-sandbox-generation.d.ts +57 -0
  308. package/dist/serve/vite-sandbox-generation.d.ts.map +1 -0
  309. package/dist/serve/vite-sandbox-generation.js +178 -0
  310. package/dist/serve/vite-sandbox-generation.js.map +1 -0
  311. package/dist/serve/worker/client/disconnect.d.ts.map +1 -1
  312. package/dist/serve/worker/client/disconnect.js +2 -0
  313. package/dist/serve/worker/client/disconnect.js.map +1 -1
  314. package/dist/serve/worker/client/handles.d.ts +5 -0
  315. package/dist/serve/worker/client/handles.d.ts.map +1 -1
  316. package/dist/serve/worker/client/handles.js.map +1 -1
  317. package/dist/serve/worker/client/pagehide.d.ts +13 -0
  318. package/dist/serve/worker/client/pagehide.d.ts.map +1 -0
  319. package/dist/serve/worker/client/pagehide.js +19 -0
  320. package/dist/serve/worker/client/pagehide.js.map +1 -0
  321. package/dist/serve/worker/client/rtdb-admin.d.ts +8 -0
  322. package/dist/serve/worker/client/rtdb-admin.d.ts.map +1 -0
  323. package/dist/serve/worker/client/rtdb-admin.js +39 -0
  324. package/dist/serve/worker/client/rtdb-admin.js.map +1 -0
  325. package/dist/serve/worker/client/rtdb-connection-lifecycle.d.ts +15 -0
  326. package/dist/serve/worker/client/rtdb-connection-lifecycle.d.ts.map +1 -0
  327. package/dist/serve/worker/client/rtdb-connection-lifecycle.js +45 -0
  328. package/dist/serve/worker/client/rtdb-connection-lifecycle.js.map +1 -0
  329. package/dist/serve/worker/client/rtdb-controls.d.ts +6 -0
  330. package/dist/serve/worker/client/rtdb-controls.d.ts.map +1 -0
  331. package/dist/serve/worker/client/rtdb-controls.js +8 -0
  332. package/dist/serve/worker/client/rtdb-controls.js.map +1 -0
  333. package/dist/serve/worker/client/rtdb-listeners.d.ts +24 -0
  334. package/dist/serve/worker/client/rtdb-listeners.d.ts.map +1 -0
  335. package/dist/serve/worker/client/rtdb-listeners.js +262 -0
  336. package/dist/serve/worker/client/rtdb-listeners.js.map +1 -0
  337. package/dist/serve/worker/client/rtdb-reads.d.ts +4 -0
  338. package/dist/serve/worker/client/rtdb-reads.d.ts.map +1 -0
  339. package/dist/serve/worker/client/rtdb-reads.js +11 -0
  340. package/dist/serve/worker/client/rtdb-reads.js.map +1 -0
  341. package/dist/serve/worker/client/rtdb-references.d.ts +19 -0
  342. package/dist/serve/worker/client/rtdb-references.d.ts.map +1 -0
  343. package/dist/serve/worker/client/rtdb-references.js +63 -0
  344. package/dist/serve/worker/client/rtdb-references.js.map +1 -0
  345. package/dist/serve/worker/client/rtdb-snapshots.d.ts +20 -0
  346. package/dist/serve/worker/client/rtdb-snapshots.d.ts.map +1 -0
  347. package/dist/serve/worker/client/rtdb-snapshots.js +64 -0
  348. package/dist/serve/worker/client/rtdb-snapshots.js.map +1 -0
  349. package/dist/serve/worker/client/rtdb-transactions.d.ts +14 -0
  350. package/dist/serve/worker/client/rtdb-transactions.d.ts.map +1 -0
  351. package/dist/serve/worker/client/rtdb-transactions.js +34 -0
  352. package/dist/serve/worker/client/rtdb-transactions.js.map +1 -0
  353. package/dist/serve/worker/client/rtdb-writes.d.ts +8 -0
  354. package/dist/serve/worker/client/rtdb-writes.d.ts.map +1 -0
  355. package/dist/serve/worker/client/rtdb-writes.js +65 -0
  356. package/dist/serve/worker/client/rtdb-writes.js.map +1 -0
  357. package/dist/serve/worker/client.d.ts +0 -2
  358. package/dist/serve/worker/client.d.ts.map +1 -1
  359. package/dist/serve/worker/client.js +0 -2
  360. package/dist/serve/worker/client.js.map +1 -1
  361. package/dist/serve/worker/entry.js +2 -2
  362. package/dist/serve/worker/entry.js.map +1 -1
  363. package/dist/serve/worker/host/dispatch.d.ts +2 -0
  364. package/dist/serve/worker/host/dispatch.d.ts.map +1 -1
  365. package/dist/serve/worker/host/dispatch.js +24 -2
  366. package/dist/serve/worker/host/dispatch.js.map +1 -1
  367. package/dist/serve/worker/host/rtdb.d.ts +6 -2
  368. package/dist/serve/worker/host/rtdb.d.ts.map +1 -1
  369. package/dist/serve/worker/host/rtdb.js +224 -2
  370. package/dist/serve/worker/host/rtdb.js.map +1 -1
  371. package/dist/serve/worker/host/studio.d.ts.map +1 -1
  372. package/dist/serve/worker/host/studio.js +2 -0
  373. package/dist/serve/worker/host/studio.js.map +1 -1
  374. package/dist/serve/worker/host/subscriptions.d.ts.map +1 -1
  375. package/dist/serve/worker/host/subscriptions.js +3 -3
  376. package/dist/serve/worker/host/subscriptions.js.map +1 -1
  377. package/dist/serve/worker/host.d.ts +1 -1
  378. package/dist/serve/worker/host.d.ts.map +1 -1
  379. package/dist/serve/worker/host.js +1 -1
  380. package/dist/serve/worker/host.js.map +1 -1
  381. package/dist/serve/worker/index.d.ts +16 -1
  382. package/dist/serve/worker/index.d.ts.map +1 -1
  383. package/dist/serve/worker/index.js +17 -4
  384. package/dist/serve/worker/index.js.map +1 -1
  385. package/dist/serve/worker/protocol.d.ts +57 -0
  386. package/dist/serve/worker/protocol.d.ts.map +1 -1
  387. package/dist/serve/worker/protocol.js.map +1 -1
  388. package/dist/serve/worker/rtdb-value-equality.d.ts +3 -0
  389. package/dist/serve/worker/rtdb-value-equality.d.ts.map +1 -0
  390. package/dist/serve/worker/rtdb-value-equality.js +18 -0
  391. package/dist/serve/worker/rtdb-value-equality.js.map +1 -0
  392. package/dist/serve/worker/serve-init.js +2 -2
  393. package/dist/serve/worker/serve-init.js.map +1 -1
  394. package/dist/serve/worker/service-worker-relay.js +2 -2
  395. package/dist/serve/worker/service-worker-relay.js.map +1 -1
  396. package/package.json +7 -5
  397. package/src/assurance/.generated/conformance-verdicts.ts +120 -75
  398. package/src/bridge/client/dispatch.ts +1 -1
  399. package/src/cli/serve.ts +215 -307
  400. package/src/cli/service-command-records/database-rules-generate.ts +3 -0
  401. package/src/cli/service-command-records/database-rules-lint.ts +3 -0
  402. package/src/cli/service-command-records/database-rules-simulate.ts +3 -0
  403. package/src/cli/service-command-records/database-rules-validate.ts +3 -0
  404. package/src/cli/service-command-records/firestore-indexes-generate.ts +3 -0
  405. package/src/cli/service-command-records/firestore-rules-lint.ts +3 -0
  406. package/src/cli/service-command-records/firestore-rules-resolve.ts +3 -0
  407. package/src/cli/service-command-records/firestore-rules-simulate.ts +3 -0
  408. package/src/cli/service-command-records/firestore-rules-validate.ts +3 -0
  409. package/src/cli/service-command-records/storage-rules-lint.ts +3 -0
  410. package/src/cli/service-command-records/storage-rules-simulate.ts +3 -0
  411. package/src/cli/service-commands.generated.ts +27 -0
  412. package/src/cli/service-commands.test.ts +43 -0
  413. package/src/cli/service-commands.ts +36 -51
  414. package/src/conformance/.generated/can-i-use-browser.ts +1 -1
  415. package/src/conformance/.generated/can-i-use.ts +1 -1
  416. package/src/conformance/.generated/conformance-docs.ts +1 -1
  417. package/src/functions-rtdb/development-runtime.ts +299 -0
  418. package/src/serve/bridge-mount.ts +253 -19
  419. package/src/serve/bundler.ts +8 -34
  420. package/src/serve/entries/app-client.ts +5 -4
  421. package/src/serve/entries/auth-helper-core.ts +117 -30
  422. package/src/serve/entries/auth.ts +8 -4
  423. package/src/serve/entries/database.ts +180 -57
  424. package/src/serve/entries/init.ts +30 -20
  425. package/src/serve/html-injection.ts +65 -0
  426. package/src/serve/namespace.ts +26 -169
  427. package/src/serve/runtime/worker-replacement.ts +1 -1
  428. package/src/serve/sandbox-session.ts +233 -0
  429. package/src/serve/server.ts +20 -5
  430. package/src/serve/site-tree.ts +146 -0
  431. package/src/serve/standalone-assets.ts +9 -26
  432. package/src/serve/vite-functions-development.ts +201 -0
  433. package/src/serve/vite-generation-bridge.ts +66 -0
  434. package/src/serve/vite-generation-functions.ts +78 -0
  435. package/src/serve/vite-generation-middleware.ts +56 -0
  436. package/src/serve/vite-generation-rules-watch.ts +37 -0
  437. package/src/serve/vite-module-swap.ts +119 -0
  438. package/src/serve/vite-page-runtime.ts +100 -0
  439. package/src/serve/vite-plugin.ts +78 -883
  440. package/src/serve/vite-sandbox-generation.ts +255 -0
  441. package/src/serve/worker/client/disconnect.ts +3 -1
  442. package/src/serve/worker/client/handles.ts +5 -0
  443. package/src/serve/worker/client/pagehide.ts +31 -0
  444. package/src/serve/worker/client/rtdb-admin.ts +74 -0
  445. package/src/serve/worker/client/rtdb-connection-lifecycle.ts +52 -0
  446. package/src/serve/worker/client/rtdb-controls.ts +8 -0
  447. package/src/serve/worker/client/rtdb-listeners.ts +337 -0
  448. package/src/serve/worker/client/rtdb-reads.ts +12 -0
  449. package/src/serve/worker/client/rtdb-references.ts +85 -0
  450. package/src/serve/worker/client/rtdb-snapshots.ts +118 -0
  451. package/src/serve/worker/client/rtdb-transactions.ts +51 -0
  452. package/src/serve/worker/client/rtdb-writes.ts +74 -0
  453. package/src/serve/worker/client.ts +0 -2
  454. package/src/serve/worker/entry.ts +2 -2
  455. package/src/serve/worker/host/dispatch.ts +22 -2
  456. package/src/serve/worker/host/rtdb.ts +243 -2
  457. package/src/serve/worker/host/studio.ts +2 -0
  458. package/src/serve/worker/host/subscriptions.ts +8 -4
  459. package/src/serve/worker/host.ts +1 -1
  460. package/src/serve/worker/index.ts +58 -10
  461. package/src/serve/worker/protocol.ts +23 -2
  462. package/src/serve/worker/rtdb-value-equality.ts +17 -0
  463. package/src/serve/worker/serve-init.ts +2 -2
  464. package/src/serve/worker/service-worker-relay.ts +2 -2
  465. package/dist/serve/docs-ui/_astro/_slug_.DUci-duz.css +0 -1
  466. package/dist/serve/docs-ui/docs/_rhythm/index.html +0 -100
  467. package/dist/serve/docs-ui/docs/agent/set-up-your-agent/index.html +0 -43
  468. package/dist/serve/docs-ui/docs/agent/watch-and-review/index.html +0 -26
  469. package/dist/serve/docs-ui/docs/agent/work-with-an-agent/index.html +0 -70
  470. package/dist/serve/docs-ui/docs/api-reference/index.html +0 -68
  471. package/dist/serve/docs-ui/docs/build/ai-logic/index.html +0 -64
  472. package/dist/serve/docs-ui/docs/build/authentication/index.html +0 -66
  473. package/dist/serve/docs-ui/docs/build/cloud-firestore/index.html +0 -70
  474. package/dist/serve/docs-ui/docs/build/cloud-messaging/index.html +0 -71
  475. package/dist/serve/docs-ui/docs/build/cloud-storage/index.html +0 -66
  476. package/dist/serve/docs-ui/docs/build/realtime-database/index.html +0 -67
  477. package/dist/serve/docs-ui/docs/conformance-scores/index.html +0 -50
  478. package/dist/serve/docs-ui/docs/create-pyric-reference-api/index.html +0 -531
  479. package/dist/serve/docs-ui/docs/functions-rtdb-compat/index.html +0 -73
  480. package/dist/serve/docs-ui/docs/get-started/how-the-swap-works/index.html +0 -29
  481. package/dist/serve/docs-ui/docs/get-started/start-building/index.html +0 -33
  482. package/dist/serve/docs-ui/docs/messaging-compat/index.html +0 -265
  483. package/dist/serve/docs-ui/docs/observe/resolve-runtime-status/index.html +0 -28
  484. package/dist/serve/docs-ui/docs/observe/see-whats-happening/index.html +0 -74
  485. package/dist/serve/docs-ui/docs/observe/shape-your-data/index.html +0 -45
  486. package/dist/serve/docs-ui/docs/overview/index.html +0 -17
  487. package/dist/serve/docs-ui/docs/pyric-admin-app-reference-api/index.html +0 -186
  488. package/dist/serve/docs-ui/docs/pyric-admin-storage-reference-api/index.html +0 -318
  489. package/dist/serve/docs-ui/docs/pyric-ai-scripting-reference-api/index.html +0 -160
  490. package/dist/serve/docs-ui/docs/pyric-app-reference-api/index.html +0 -425
  491. package/dist/serve/docs-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +0 -60
  492. package/dist/serve/docs-ui/docs/pyric-cli-bridge-reference-api/index.html +0 -507
  493. package/dist/serve/docs-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +0 -258
  494. package/dist/serve/docs-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +0 -51
  495. package/dist/serve/docs-ui/docs/pyric-cli-conformance-reference-api/index.html +0 -308
  496. package/dist/serve/docs-ui/docs/pyric-cli-credentials-node-reference-api/index.html +0 -68
  497. package/dist/serve/docs-ui/docs/pyric-cli-register-reference-api/index.html +0 -11
  498. package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api/index.html +0 -126
  499. package/dist/serve/docs-ui/docs/pyric-database-reference-api/index.html +0 -1852
  500. package/dist/serve/docs-ui/docs/pyric-messaging-reference-api/index.html +0 -509
  501. package/dist/serve/docs-ui/docs/pyric-messaging-sw-reference-api/index.html +0 -182
  502. package/dist/serve/docs-ui/docs/pyric-sandbox-database-reference-api/index.html +0 -121
  503. package/dist/serve/docs-ui/docs/pyric-sandbox-firestore-reference-api/index.html +0 -203
  504. package/dist/serve/docs-ui/docs/pyric-ui-agents-reference-api/index.html +0 -639
  505. package/dist/serve/docs-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +0 -100
  506. package/dist/serve/docs-ui/docs/pyric-ui-events-hooks-reference-api/index.html +0 -24
  507. package/dist/serve/docs-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +0 -136
  508. package/dist/serve/docs-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +0 -16
  509. package/dist/serve/docs-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +0 -176
  510. package/dist/serve/docs-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +0 -188
  511. package/dist/serve/docs-ui/docs/secure/audit-your-rules/index.html +0 -51
  512. package/dist/serve/docs-ui/docs/secure/firestore-rules-limits/index.html +0 -106
  513. package/dist/serve/docs-ui/docs/secure/read-a-denial/index.html +0 -41
  514. package/dist/serve/docs-ui/docs/secure/rtdb-rules-in-typescript/index.html +0 -67
  515. package/dist/serve/docs-ui/docs/secure/rules-standard-library/index.html +0 -159
  516. package/dist/serve/docs-ui/docs/secure/secure-it-with-rules/index.html +0 -47
  517. package/dist/serve/docs-ui/docs/secure/simulate-and-lint/index.html +0 -95
  518. package/dist/serve/docs-ui/docs/secure/write-a-rules-test-suite/index.html +0 -82
  519. package/dist/serve/docs-ui/docs/ship/ship-to-production/index.html +0 -37
  520. package/dist/serve/docs-ui/docs/ship/test-in-node/index.html +0 -75
  521. package/dist/serve/docs-ui/docs/trust/how-we-know-it-matches-firebase/index.html +0 -132
  522. package/dist/serve/docs-ui/docs/trust/versioning-and-compatibility/index.html +0 -14
  523. package/dist/serve/docs-ui/index.html +0 -1
  524. package/dist/serve/studio-ui/assets/RulesCodeEditor-BDlH-5lp.js +0 -23
  525. package/dist/serve/studio-ui/assets/index-Bf9SSE8L.js +0 -1218
  526. package/dist/serve/studio-ui/assets/index-BlSGru_r.css +0 -1
  527. package/dist/serve/studio-ui/assets/seed-D_UjxfOU.js +0 -20
  528. package/dist/serve/studio-ui/index.html +0 -32
  529. package/dist/serve/worker/client/rtdb.d.ts +0 -36
  530. package/dist/serve/worker/client/rtdb.d.ts.map +0 -1
  531. package/dist/serve/worker/client/rtdb.js +0 -241
  532. package/dist/serve/worker/client/rtdb.js.map +0 -1
  533. package/src/serve/worker/client/rtdb.ts +0 -311
  534. /package/dist/serve/{docs-ui → site-ui}/404.html +0 -0
  535. /package/dist/serve/{docs-ui → site-ui}/_astro/_slug_.CXh9yTP1.css +0 -0
  536. /package/dist/serve/{docs-ui → site-ui}/docs/_rhythm.md +0 -0
  537. /package/dist/serve/{docs-ui → site-ui}/docs/agent/set-up-your-agent.md +0 -0
  538. /package/dist/serve/{docs-ui → site-ui}/docs/agent/watch-and-review.md +0 -0
  539. /package/dist/serve/{docs-ui → site-ui}/docs/agent/work-with-an-agent.md +0 -0
  540. /package/dist/serve/{docs-ui → site-ui}/docs/ai-compat.md +0 -0
  541. /package/dist/serve/{docs-ui → site-ui}/docs/api-reference.md +0 -0
  542. /package/dist/serve/{docs-ui → site-ui}/docs/app-compat.md +0 -0
  543. /package/dist/serve/{docs-ui → site-ui}/docs/auth-compat.md +0 -0
  544. /package/dist/serve/{docs-ui → site-ui}/docs/build/ai-logic.md +0 -0
  545. /package/dist/serve/{docs-ui → site-ui}/docs/build/authentication.md +0 -0
  546. /package/dist/serve/{docs-ui → site-ui}/docs/build/cloud-firestore.md +0 -0
  547. /package/dist/serve/{docs-ui → site-ui}/docs/build/cloud-messaging.md +0 -0
  548. /package/dist/serve/{docs-ui → site-ui}/docs/build/realtime-database.md +0 -0
  549. /package/dist/serve/{docs-ui → site-ui}/docs/create-pyric-reference-api.md +0 -0
  550. /package/dist/serve/{docs-ui → site-ui}/docs/functions-rtdb-compat.md +0 -0
  551. /package/dist/serve/{docs-ui → site-ui}/docs/get-started/how-the-swap-works.md +0 -0
  552. /package/dist/serve/{docs-ui → site-ui}/docs/get-started/start-building.md +0 -0
  553. /package/dist/serve/{docs-ui → site-ui}/docs/index.html +0 -0
  554. /package/dist/serve/{docs-ui → site-ui}/docs/observe/resolve-runtime-status.md +0 -0
  555. /package/dist/serve/{docs-ui → site-ui}/docs/observe/see-whats-happening.md +0 -0
  556. /package/dist/serve/{docs-ui → site-ui}/docs/observe/shape-your-data.md +0 -0
  557. /package/dist/serve/{docs-ui → site-ui}/docs/overview.md +0 -0
  558. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-app-reference-api.md +0 -0
  559. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-auth-reference-api.md +0 -0
  560. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-database-reference-api.md +0 -0
  561. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-messaging-reference-api.md +0 -0
  562. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-storage-reference-api.md +0 -0
  563. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ai-reference-api.md +0 -0
  564. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ai-scripting-reference-api.md +0 -0
  565. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-app-reference-api.md +0 -0
  566. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-assurance-browser-reference-api.md +0 -0
  567. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-assurance-reference-api.md +0 -0
  568. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-bridge-client-reference-api.md +0 -0
  569. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-bridge-reference-api.md +0 -0
  570. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-conformance-browser-reference-api.md +0 -0
  571. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-conformance-docs-reference-api.md +0 -0
  572. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-conformance-reference-api.md +0 -0
  573. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-credentials-node-reference-api.md +0 -0
  574. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-discover-reference-api.md +0 -0
  575. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-register-reference-api.md +0 -0
  576. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-remote-reference-api.md +0 -0
  577. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-verify-reference-api.md +0 -0
  578. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-messaging-reference-api.md +0 -0
  579. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-messaging-sw-reference-api.md +0 -0
  580. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-database-reference-api.md +0 -0
  581. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-firestore-reference-api.md +0 -0
  582. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-agents-reference-api.md +0 -0
  583. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-auth-hooks-reference-api.md +0 -0
  584. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-auth-reference-api.md +0 -0
  585. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-events-hooks-reference-api.md +0 -0
  586. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-events-reference-api.md +0 -0
  587. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-firestore-hooks-reference-api.md +0 -0
  588. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-primitives-reference-api.md +0 -0
  589. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rtdb-reference-api.md +0 -0
  590. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rules-hooks-reference-api.md +0 -0
  591. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rules-reference-api.md +0 -0
  592. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-storage-hooks-reference-api.md +0 -0
  593. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-traffic-hooks-reference-api.md +0 -0
  594. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-traffic-reference-api.md +0 -0
  595. /package/dist/serve/{docs-ui → site-ui}/docs/secure/audit-your-rules.md +0 -0
  596. /package/dist/serve/{docs-ui → site-ui}/docs/secure/firestore-rules-limits.md +0 -0
  597. /package/dist/serve/{docs-ui → site-ui}/docs/secure/read-a-denial.md +0 -0
  598. /package/dist/serve/{docs-ui → site-ui}/docs/secure/rtdb-rules-in-typescript.md +0 -0
  599. /package/dist/serve/{docs-ui → site-ui}/docs/secure/secure-it-with-rules.md +0 -0
  600. /package/dist/serve/{docs-ui → site-ui}/docs/secure/simulate-and-lint.md +0 -0
  601. /package/dist/serve/{docs-ui → site-ui}/docs/secure/write-a-rules-test-suite.md +0 -0
  602. /package/dist/serve/{docs-ui → site-ui}/docs/ship/ship-to-production.md +0 -0
  603. /package/dist/serve/{docs-ui → site-ui}/docs/ship/test-in-node.md +0 -0
  604. /package/dist/serve/{docs-ui → site-ui}/docs/trust/how-we-know-it-matches-firebase.md +0 -0
  605. /package/dist/serve/{docs-ui → site-ui}/docs/trust/versioning-and-compatibility.md +0 -0
  606. /package/dist/serve/{studio-ui → site-ui}/pyric-logo.svg +0 -0
@@ -1,15 +1,15 @@
1
- <!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>pyric/firestore compatibility matrix · Pyric Studio</title><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.CXh9yTP1.css">
2
- <link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.DUci-duz.css"></head> <body> <header class="studio__bar"> <div class="studio__bar-inner"> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric Studio">Pyric</a> <nav class="studio__nav" aria-label="Studio tabs"> <a class="studio__nav-tab" href="/__pyric/ui/"> Home </a><a class="studio__nav-tab" href="/__pyric/ui/firestore"> Firestore </a><a class="studio__nav-tab" href="/__pyric/ui/auth"> Auth </a><a class="studio__nav-tab" href="/__pyric/ui/rtdb"> RTDB </a><a class="studio__nav-tab" href="/__pyric/ui/storage"> Storage </a><a class="studio__nav-tab" href="/__pyric/ui/traffic"> Traffic </a><a class="studio__nav-tab" href="/__pyric/ui/settings"> Settings </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page"> Docs </a> </nav> </div> </header> <div class="docs-shell"> <details class="docs-nav-drawer"> <summary>Navigate</summary> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <script type="module">let i=null;function d(t){return i||(i=fetch(t).then(e=>e.json())),i}function l(t,e){return t.title.toLowerCase().includes(e)||t.excerpt.toLowerCase().includes(e)?!0:t.headings.some(r=>r.text.toLowerCase().includes(e))}function u(t,e,r){if(e.innerHTML="",t.length===0){e.hidden=!1;{const n=document.createElement("li");n.className="docs-search-empty",n.textContent="No matches",e.appendChild(n)}return}e.hidden=!1;for(const n of t.slice(0,8)){const s=document.createElement("li"),c=document.createElement("a");c.href=n.path;const o=document.createElement("span");o.className="docs-search-result-title",o.textContent=n.title;const a=document.createElement("span");a.className="docs-search-result-meta",a.textContent=[n.group,n.section].filter(Boolean).join(" / "),c.append(o,a),s.appendChild(c),e.appendChild(s)}}document.querySelectorAll(".docs-search").forEach(t=>{const e=t.dataset.indexUrl,r=t.querySelector(".docs-search-input"),n=t.querySelector(".docs-search-results");r.addEventListener("input",async()=>{const s=r.value.trim().toLowerCase();if(!s){n.hidden=!0,n.innerHTML="";return}const{pages:c}=await d(e);r.value.trim().toLowerCase()===s&&u(c.filter(o=>l(o,s)),n)}),r.addEventListener("focus",()=>{d(e),n.childElementCount>0&&(n.hidden=!1)}),r.addEventListener("keydown",s=>{s.key==="Escape"&&(r.value="",n.hidden=!0,n.innerHTML="",r.blur())}),r.addEventListener("blur",()=>{window.setTimeout(()=>{n.hidden=!0},150)})});document.addEventListener("keydown",t=>{if(!(t.metaKey||t.ctrlKey)||t.key.toLowerCase()!=="k")return;const e=[...document.querySelectorAll(".docs-search-input")].find(r=>r.offsetParent!==null);e&&(t.preventDefault(),e.focus(),e.select())});</script> <details class="docs-nav-group"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><a class="docs-nav-toplink" href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Trust </a><details class="docs-nav-group" open> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Public API coverage </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/" aria-current="page"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group"> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div> </div> </details> </nav> </details> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <details class="docs-nav-group" id="nav-group-overview"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-get-started"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-build"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-secure-debug"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-observe-shape"> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-ship-test"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-work-with-an-agent"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><a class="docs-nav-toplink" href="/__pyric/ui/docs/trust/versioning-and-compatibility/" id="nav-group-trust"> Trust </a><details class="docs-nav-group" id="nav-group-conformance" open> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Public API coverage </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/" aria-current="page"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group" id="nav-group-reference"> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div> </div> </details> </nav> <main class="doc-main"> <nav class="docs-breadcrumbs" aria-label="Breadcrumb"> <ol> <li> <a href="/__pyric/ui/docs/conformance-scores/">Conformance</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span aria-current="page">Firestore</span> </li> </ol> </nav> <article class="prose"> <!-- Generated from the conformance model (registry rows + surface contracts). Do not edit by hand; run bun run compat:generate. -->
1
+ <!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>pyric/firestore compatibility matrix · Pyric Studio</title><link rel="icon" type="image/svg+xml" href="/__pyric/ui/pyric-logo.svg"><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.CXh9yTP1.css">
2
+ <link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.BoKXYrnu.css"></head> <body> <header class="studio__bar" data-astro-cid-mw7aashj> <div class="studio__bar-inner" data-astro-cid-mw7aashj> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric Studio" data-astro-cid-mw7aashj>Pyric</a> <nav class="studio__nav" aria-label="Studio tabs" data-astro-cid-mw7aashj> <a class="studio__nav-tab" href="/__pyric/ui/" data-astro-cid-mw7aashj> Home </a><a class="studio__nav-tab" href="/__pyric/ui/firestore" data-astro-cid-mw7aashj> Firestore </a><a class="studio__nav-tab" href="/__pyric/ui/auth" data-astro-cid-mw7aashj> Auth </a><a class="studio__nav-tab" href="/__pyric/ui/rtdb" data-astro-cid-mw7aashj> RTDB </a><a class="studio__nav-tab" href="/__pyric/ui/storage" data-astro-cid-mw7aashj> Storage </a><a class="studio__nav-tab" href="/__pyric/ui/traffic" data-astro-cid-mw7aashj> Traffic </a><a class="studio__nav-tab" href="/__pyric/ui/settings" data-astro-cid-mw7aashj> Settings </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page" data-astro-cid-mw7aashj> Docs </a> </nav> </div> </header> <div class="docs-shell" data-astro-cid-mw7aashj> <details class="docs-nav-drawer" data-astro-cid-mw7aashj> <summary data-astro-cid-mw7aashj>Navigate</summary> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <script type="module">let i=null;function d(t){return i||(i=fetch(t).then(e=>e.json())),i}function l(t,e){return t.title.toLowerCase().includes(e)||t.excerpt.toLowerCase().includes(e)?!0:t.headings.some(r=>r.text.toLowerCase().includes(e))}function u(t,e,r){if(e.innerHTML="",t.length===0){e.hidden=!1;{const n=document.createElement("li");n.className="docs-search-empty",n.textContent="No matches",e.appendChild(n)}return}e.hidden=!1;for(const n of t.slice(0,8)){const s=document.createElement("li"),c=document.createElement("a");c.href=n.path;const o=document.createElement("span");o.className="docs-search-result-title",o.textContent=n.title;const a=document.createElement("span");a.className="docs-search-result-meta",a.textContent=[n.group,n.section].filter(Boolean).join(" / "),c.append(o,a),s.appendChild(c),e.appendChild(s)}}document.querySelectorAll(".docs-search").forEach(t=>{const e=t.dataset.indexUrl,r=t.querySelector(".docs-search-input"),n=t.querySelector(".docs-search-results");r.addEventListener("input",async()=>{const s=r.value.trim().toLowerCase();if(!s){n.hidden=!0,n.innerHTML="";return}const{pages:c}=await d(e);r.value.trim().toLowerCase()===s&&u(c.filter(o=>l(o,s)),n)}),r.addEventListener("focus",()=>{d(e),n.childElementCount>0&&(n.hidden=!1)}),r.addEventListener("keydown",s=>{s.key==="Escape"&&(r.value="",n.hidden=!0,n.innerHTML="",r.blur())}),r.addEventListener("blur",()=>{window.setTimeout(()=>{n.hidden=!0},150)})});document.addEventListener("keydown",t=>{if(!(t.metaKey||t.ctrlKey)||t.key.toLowerCase()!=="k")return;const e=[...document.querySelectorAll(".docs-search-input")].find(r=>r.offsetParent!==null);e&&(t.preventDefault(),e.focus(),e.select())});</script> <details class="docs-nav-group"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/storage-rules-stdlib-research/"> Storage Rules modules: evidence and design </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" open> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Public API coverage </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/" aria-current="page"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group"> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div> </div> </details> </nav> </details> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <details class="docs-nav-group" id="nav-group-overview"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-get-started"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-build"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-secure-debug"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-secure-debug-examples"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-observe-shape"> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-ship-test"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-work-with-an-agent"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-trust"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/storage-rules-stdlib-research/"> Storage Rules modules: evidence and design </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-conformance" open> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Public API coverage </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/" aria-current="page"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group" id="nav-group-reference"> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div> </div> </details> </nav> <main class="doc-main" data-astro-cid-mw7aashj> <nav class="docs-breadcrumbs" aria-label="Breadcrumb"> <ol> <li> <a href="/__pyric/ui/docs/conformance-scores/">Conformance</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span aria-current="page">Firestore</span> </li> </ol> </nav> <article class="prose" data-astro-cid-mw7aashj> <!-- Generated from the conformance model (registry rows + surface contracts). Do not edit by hand; run bun run compat:generate. -->
3
3
  <h1 id="pyricfirestore-compatibility-matrix"><code>pyric/firestore</code> compatibility matrix</h1>
4
4
  <div class="compat-stat">
5
5
  <p class="compat-stat-figure">
6
- <span class="compat-stat-pct">52.7%</span>
6
+ <span class="compat-stat-pct">53.8%</span>
7
7
  <span class="compat-stat-label">of the public API supported</span>
8
8
  </p>
9
9
  <div class="compat-meters">
10
- <span class="compat-meter-track"><span class="compat-meter-fill" style="width: 52.7%"></span></span>
10
+ <span class="compat-meter-track"><span class="compat-meter-fill" style="width: 53.8%"></span></span>
11
11
  </div>
12
- <p class="compat-stat-denom">96 of 182 public API</p>
12
+ <p class="compat-stat-denom">98 of 182 public API</p>
13
13
  </div>
14
14
  <h2 id="status-legend">Status legend</h2>
15
15
  <div class="compat-key">
@@ -105,9 +105,9 @@
105
105
  <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">Re-evaluates rules under current user on every call (sandbox-live) — read denied throws <code>permission-denied</code></span></span></span></summary>
106
106
  <div class="compat-evidence"><div class="compat-probe"><code>unit:sandbox-live-identity.test.ts</code> ("doc read denied when current user lacks read access"), oracle: <code>packages/conformance/observations/firestore/firestore-read-denied-error-code.json</code> (prod <code>getDoc</code> on a denied path throws a <code>FirebaseError</code> with <code>.code === 'permission-denied'</code>, <code>.message === 'Missing or insufficient permissions.'</code>, <code>instanceof Error</code>)</div></div>
107
107
  </details>
108
- <details class="compat-row" data-status="diverged">
109
- <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">getDoc(ref)</code><span class="compat-sub"><span class="compat-behavior">Rules denial throws <code>SandboxError('permission-denied', …)</code> on sandbox; <code>FirebaseError('permission-denied')</code> on prod</span></span></span></summary>
110
- <div class="compat-evidence"><div class="compat-probe">divergence: same code, different class — both expose <code>.code === 'permission-denied'</code>. Oracle-locked: <code>packages/conformance/observations/firestore/firestore-rules-denied-error.json</code> prod throws a <code>FirebaseError</code> (name + constructor name both <code>FirebaseError</code>), <code>.code === 'permission-denied'</code>, <code>.message === '7 PERMISSION_DENIED: Missing or insufficient permissions.'</code>, and the value is an <code>instanceof Error</code>.</div></div>
108
+ <details class="compat-row" data-status="ok">
109
+ <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>
110
+ <div class="compat-evidence"><div class="compat-probe">Oracle-locked by <code>packages/conformance/observations/firestore/firestore-rules-denied-error.json</code>: 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.</div></div>
111
111
  </details>
112
112
  </div>
113
113
  <h2 id="getdocsquery--bulk-read"><code>getDocs(query)</code> — bulk read</h2>
@@ -168,8 +168,8 @@
168
168
  <div class="compat-evidence"><div class="compat-probe"><code>unit:sandbox-target.test.ts</code> ("withConverter on a DocumentReference round-trips")</div></div>
169
169
  </details>
170
170
  <details class="compat-row" data-status="ok">
171
- <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 write throws <code>permission-denied</code> (sandbox) / <code>FirebaseError</code> (prod)</span></span></span></summary>
172
- <div class="compat-evidence"><div class="compat-probe"><code>unit:sandbox-target.test.ts</code> ("getDoc denies when rules reject"), <code>playground:rules-data-validation</code>, oracle: <code>packages/conformance/observations/firestore/firestore-write-denied-error-code.json</code> (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>)</div></div>
171
+ <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>
172
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:sandbox-target.test.ts</code> ("getDoc denies when rules reject"), <code>playground:rules-data-validation</code>, oracle: <code>packages/conformance/observations/firestore/firestore-write-denied-error-code.json</code> (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</div></div>
173
173
  </details>
174
174
  </div>
175
175
  <h2 id="updatedocref-data--partial-write"><code>updateDoc(ref, data)</code> — partial write</h2>
@@ -228,10 +228,9 @@
228
228
  <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">Converter on the parent collection propagates onto the returned ref</span></span></span></summary>
229
229
  <div class="compat-evidence"><div class="compat-probe"><code>unit:sandbox-target.test.ts</code> ("addDoc through a converted collection")</div></div>
230
230
  </details>
231
- <details class="compat-row" data-status="diverged">
232
- <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">addDoc(coll, data)</code><span class="compat-sub"><span class="compat-behavior">Auto-id format — prod uses 20-char base64-ish IDs; sandbox uses <code>pyric-admin</code>'s auto-id (also opaque, distinct format)</span></span></span></summary>
233
- <div class="compat-evidence"><div class="compat-probe">divergence: IDs are opaque on both sides; format differs but consumer code never parses them. Oracle-locked: <code>packages/conformance/observations/firestore/firestore-adddoc-autoid-format.json</code> prod auto-ids are 20 characters, all alphanumeric (mixed upper, lower, digits; no other chars). Example: <code>S3PJENMPOk4qcDXol8Ez</code>.</div>
234
- <div class="compat-note">format</div></div>
231
+ <details class="compat-row" data-status="ok">
232
+ <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>
233
+ <div class="compat-evidence"><div class="compat-probe">Oracle-locked: <code>packages/conformance/observations/firestore/firestore-adddoc-autoid-format.json</code> records production's 20-character alphanumeric shape; <code>packages/pyric/test/firestore/oracle-conformance.test.ts</code> generates 25 sandbox IDs and checks both invariants against that observation.</div></div>
235
234
  </details>
236
235
  </div>
237
236
  <h2 id="withconverter--typed-refs"><code>withConverter</code> — typed refs</h2>
@@ -301,11 +300,11 @@
301
300
  </details>
302
301
  <details class="compat-row" data-status="ok">
303
302
  <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"><strong>Canonical type-order comparison (FS-B3)</strong> — orderBy + range filters compare by Firestore's canonical type order (<code>null &#x3C; bool &#x3C; number &#x3C; timestamp &#x3C; string &#x3C; bytes &#x3C; ref &#x3C; geopoint &#x3C; array &#x3C; map</code>), then within-type; numbers sort numerically (not lexicographically), NaN sorts as the smallest number, and range filters (<code>&#x3C;</code>/<code>&#x3C;=</code>/<code>></code>/<code>>=</code>) only match same-type values. Pre-FS-B3 the comparator fell back to <code>String(a).localeCompare(String(b))</code>.</span></span></span></summary>
304
- <div class="compat-evidence"><div class="compat-probe"><code>unit:admin-compat/canonical-type-order.test.ts</code> (cross-type ranking, numeric sort, NaN, timestamps, arrays; verified failing pre-fix)</div></div>
303
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:firestore/sandbox/query-value-order.test.ts</code> (cross-type ranking, numeric sort, NaN, timestamps, arrays; verified failing pre-fix)</div></div>
305
304
  </details>
306
305
  <details class="compat-row" data-status="ok">
307
306
  <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"><strong>orderBy excludes missing-field docs (FS-B3)</strong> — a doc lacking an orderBy field is omitted from the result (matches prod); pre-fix it was sorted in via <code>compareValues(undefined, …)</code>.</span></span></span></summary>
308
- <div class="compat-evidence"><div class="compat-probe"><code>unit:admin-compat/canonical-type-order.test.ts</code> ("excludes the missing-field doc")</div></div>
307
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:firestore/sandbox/query-value-order.test.ts</code> ("excludes the missing-field doc")</div></div>
309
308
  </details>
310
309
  <details class="compat-row" data-status="ok">
311
310
  <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"><strong>Implicit orderBy + <code>__name__</code> tiebreak (FS-B8)</strong> — the query's sort is normalized to: explicit orderBy clauses, then an implicit order on each inequality-filtered field, then a final document-key (<code>__name__</code>) clause. Equal-valued docs sort deterministically by key; a <code>where('x','>',v)</code> with no explicit orderBy returns docs ordered by <code>x</code>. Mirrors <code>clones/.../core/query.ts:queryNormalizedOrderBy</code>. Pre-FS-B8 equal-valued docs were nondeterministic and inequality results came back in insertion order.</span></span></span></summary>
@@ -315,9 +314,9 @@
315
314
  <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>limit(n)</code> — caps result count</span></span></span></summary>
316
315
  <div class="compat-evidence"><div class="compat-probe"><code>unit:sandbox-target.test.ts</code></div></div>
317
316
  </details>
318
- <details class="compat-row" data-status="diverged">
319
- <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"><code>limitToLast(n)</code> trailing n in ordered result (requires <code>orderBy</code>). Sandbox: the no-orderBy precondition throws a <code>FirestoreError</code> with <code>.code === 'invalid-argument'</code> (FS-B16; pre-fix plain <code>Error</code>s). Prod: the same precondition throws <code>.code === 'unimplemented'</code></span></span></span></summary>
320
- <div class="compat-evidence"><div class="compat-probe">divergence, oracle-locked by <code>packages/conformance/observations/firestore/firestore-limittolast-preconditions.json</code>: prod's no-orderBy <code>limitToLast</code> throws code <code>unimplemented</code>, the sandbox throws <code>invalid-argument</code>. Trailing-window semantics with <code>orderBy</code> conform (observed <code>["b"]</code> matches). Both sides pinned in <code>oracle-conformance.test.ts</code>. Cursor composition + descending: <code>unit:upstream-query-probes.test.ts</code>. Cursor/empty-snapshot precondition codes remain per <code>unit:sandbox-target.test.ts</code> + <code>unit:admin-compat/cursors.test.ts</code> (verified failing pre-fix)</div></div>
317
+ <details class="compat-row" data-status="ok">
318
+ <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>
319
+ <div class="compat-evidence"><div class="compat-probe">Oracle-locked by <code>packages/conformance/observations/firestore/firestore-limittolast-preconditions.json</code>: 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: <code>unit:upstream-query-probes.test.ts</code>; cursor/empty-snapshot preconditions: <code>unit:sandbox-target.test.ts</code> + <code>unit:admin-compat/cursors.test.ts</code>.</div></div>
321
320
  </details>
322
321
  <details class="compat-row" data-status="ok">
323
322
  <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>
@@ -461,11 +460,11 @@
461
460
  </details>
462
461
  <details class="compat-row" data-status="ok">
463
462
  <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">Identity is frozen at <code>runTransaction</code> start — mid-transaction <code>setUser</code> does NOT re-auth in-flight reads</span></span></span></summary>
464
- <div class="compat-evidence"><div class="compat-probe">(documented invariant)</div></div>
463
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:firestore/sandbox-live-identity.test.ts</code> changes the live session from alice to bob inside the callback; the transaction still reads and commits under alice's captured identity.</div></div>
465
464
  </details>
466
- <details class="compat-row" data-status="diverged">
467
- <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">runTransaction(db, fn)</code><span class="compat-sub"><span class="compat-behavior">Retry behavior — prod retries on contention up to 5 times; sandbox is single-threaded, no contention possible</span></span></span></summary>
468
- <div class="compat-evidence"><div class="compat-probe">divergence: contention story not modeled; sandbox just runs once</div></div>
465
+ <details class="compat-row" data-status="ok">
466
+ <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>
467
+ <div class="compat-evidence"><div class="compat-probe">Oracle: <code>packages/conformance/observations/firestore/firestore-transaction-contention-retries.json</code> 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>. <code>packages/pyric/test/firestore/oracle-conformance.test.ts</code> replays both cases through the sandbox.</div></div>
469
468
  </details>
470
469
  <details class="compat-row" data-status="ok">
471
470
  <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>
@@ -484,11 +483,11 @@
484
483
  </details>
485
484
  <details class="compat-row" data-status="ok">
486
485
  <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(db)</code><span class="compat-sub"><span class="compat-behavior">Batch is tagged on construction and remains bound to the sandbox owner that created it</span></span></span></summary>
487
- <div class="compat-evidence"><div class="compat-probe">(implementation invariant; cross-sandbox ownership is not directly probed)</div></div>
486
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:firestore/sandbox-live-identity.test.ts</code> constructs a batch from sandbox A with a reference from sandbox B and proves the commit remains isolated to A.</div></div>
488
487
  </details>
489
488
  <details class="compat-row" data-status="ok">
490
489
  <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(db)</code><span class="compat-sub"><span class="compat-behavior">Batch identity is frozen at construction (per current implementation)</span></span></span></summary>
491
- <div class="compat-evidence"><div class="compat-probe">(documented invariant)</div></div>
490
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:firestore/sandbox-live-identity.test.ts</code> constructs under alice, switches the live session to bob, and proves commit still succeeds under alice's captured identity.</div></div>
492
491
  </details>
493
492
  </div>
494
493
  <h2 id="sentinels--servertimestamp--increment--arrayunion--arrayremove--deletefield--fieldvalue--timestamp">Sentinels — <code>serverTimestamp</code> / <code>increment</code> / <code>arrayUnion</code> / <code>arrayRemove</code> / <code>deleteField</code> / <code>FieldValue</code> / <code>Timestamp</code></h2>
@@ -579,13 +578,13 @@
579
578
  <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>refEqual(sandboxRef, foreignRef)</code> throws <code>TypeError</code> — references not created by this sandbox mirror are unrecognized</span></span></span></summary>
580
579
  <div class="compat-evidence"><div class="compat-probe"><code>unit:sandbox-target.test.ts</code> (foreign refs throw unrecognized-reference TypeError)</div></div>
581
580
  </details>
582
- <details class="compat-row" data-status="diverged">
583
- <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">Equality helpers</code><span class="compat-sub"><span class="compat-behavior"><code>queryEqual(a, b)</code> is identity-only in the sandbox mirror; production's untouched Firebase SDK uses structural equality</span></span></span></summary>
584
- <div class="compat-evidence"><div class="compat-probe">divergence: sandbox does identity-only; prod does deep structural. Oracle-locked: <code>packages/conformance/observations/firestore/firestore-queryequal-structural.json</code> two independently-built queries with the same <code>where('x','==',1)</code> constraint compare equal in prod (<code>sameQueryBuiltTwice: true</code>), confirming structural semantics. Common use case (caching the same returned query) works on both.</div></div>
581
+ <details class="compat-row" data-status="ok">
582
+ <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>
583
+ <div class="compat-evidence"><div class="compat-probe">Oracle-locked by <code>packages/conformance/observations/firestore/firestore-queryequal-structural.json</code>: 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. <code>firestore-query-nested-array-validation.json</code> 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.</div></div>
585
584
  </details>
586
- <details class="compat-row" data-status="diverged">
587
- <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">Equality helpers</code><span class="compat-sub"><span class="compat-behavior"><code>snapshotEqual(a, b)</code>. Prod: returns a boolean true on identity, false even for two fetches of the same data. Sandbox: <strong>throws</strong> (<code>unrecognized reference</code>) for sandbox-target snapshots instead of returning a boolean</span></span></span></summary>
588
- <div class="compat-evidence"><div class="compat-probe">divergence, oracle-locked by <code>packages/conformance/observations/firestore/firestore-snapshotequal-structural.json</code> (<code>identity: true</code>, <code>twoFetchesSameData: false</code> prod is identity-only, NOT structural; an earlier structural guess was corrected by the oracle). The sandbox routes both args through the ref-tagging path, which does not recognize sandbox <code>QuerySnapshot</code>s, so <code>snapshotEqual</code> throws rather than comparing. Both sides pinned in <code>oracle-conformance.test.ts</code>. Fix candidate: identity-compare sandbox snapshots before the ref-tagging dispatch.</div></div>
585
+ <details class="compat-row" data-status="ok">
586
+ <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>
587
+ <div class="compat-evidence"><div class="compat-probe">Oracle-locked by <code>packages/conformance/observations/firestore/firestore-snapshotequal-structural.json</code>: 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.</div></div>
589
588
  </details>
590
589
  <details class="compat-row" data-status="ok">
591
590
  <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>
@@ -610,34 +609,29 @@
610
609
  <h2 id="offline--persistence--network-family">Offline / persistence / network family</h2>
611
610
  <h2 id="offline--persistence--network-family-continued">Offline / persistence / network family (continued)</h2>
612
611
  <div class="compat-list">
613
- <details class="compat-row" data-status="diverged">
614
- <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 in the sandbox mirror persistence is already the default; does not reject with <code>'failed-precondition'</code> when called after other ops (deliberately more lenient than the real SDK — no cache-init race to protect)</span></span></span></summary>
615
- <div class="compat-evidence"><div class="compat-probe"><code>unit:firestore/persistence-network.test.ts</code></div>
616
- <div class="compat-note">no failed-precondition</div></div>
612
+ <details class="compat-row" data-status="ok">
613
+ <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>
614
+ <div class="compat-evidence"><div class="compat-probe">Real Chromium: <code>firestore-browser-lifecycle.json</code>; replayed through the public modular API by <code>oracle-conformance.test.ts</code> and focused lifecycle coverage.</div></div>
617
615
  </details>
618
- <details class="compat-row" data-status="diverged">
619
- <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">enableMultiTabIndexedDbPersistence</code><span class="compat-sub"><span class="compat-behavior">Resolves in the sandbox mirror the SharedWorker path already is the one shared store every tab talks to</span></span></span></summary>
620
- <div class="compat-evidence"><div class="compat-probe"><code>unit:firestore/persistence-network.test.ts</code></div>
621
- <div class="compat-note">no failed-precondition</div></div>
616
+ <details class="compat-row" data-status="ok">
617
+ <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>
618
+ <div class="compat-evidence"><div class="compat-probe">Real Chromium: <code>firestore-browser-lifecycle.json</code> exercises fresh, after-use, and two-client initialization; replayed through public APIs by <code>oracle-conformance.test.ts</code> and focused persistence tests.</div></div>
622
619
  </details>
623
620
  <details class="compat-row" data-status="ok">
624
621
  <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>
625
622
  <div class="compat-evidence"><div class="compat-probe"><code>unit:firestore/persistence-network.test.ts</code></div></div>
626
623
  </details>
627
- <details class="compat-row" data-status="diverged">
628
- <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">Resolve in the sandbox mirror no network exists to toggle; writes issued while "disabled" still commit immediately (no offline queue is simulated)</span></span></span></summary>
629
- <div class="compat-evidence"><div class="compat-probe"><code>unit:firestore/persistence-network.test.ts</code></div>
630
- <div class="compat-note">no offline queue</div></div>
624
+ <details class="compat-row" data-status="ok">
625
+ <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>
626
+ <div class="compat-evidence"><div class="compat-probe">Real Chromium: <code>firestore-browser-lifecycle.json</code>; replayed through the public modular API by <code>oracle-conformance.test.ts</code> and focused network coverage.</div></div>
631
627
  </details>
632
- <details class="compat-row" data-status="diverged">
633
- <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">waitForPendingWrites</code><span class="compat-sub"><span class="compat-behavior">Resolves immediately in the sandbox mirror — every accepted write is already committed locally by the time its own promise resolves, so there are never writes still pending a server round-trip</span></span></span></summary>
634
- <div class="compat-evidence"><div class="compat-probe"><code>unit:firestore/persistence-network.test.ts</code></div>
635
- <div class="compat-note">always resolves; prod can hang offline</div></div>
628
+ <details class="compat-row" data-status="ok">
629
+ <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>
630
+ <div class="compat-evidence"><div class="compat-probe">Real Chromium: <code>firestore-browser-lifecycle.json</code>; replayed through the public modular API by <code>oracle-conformance.test.ts</code> and focused pending-write coverage.</div></div>
636
631
  </details>
637
- <details class="compat-row" data-status="diverged">
638
- <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">Genuinely tears the sandbox target down by calling <code>Sandbox.dispose()</code>, which tears down listener registries on the sandbox's environment (idempotent, doesn't touch data). This differs from the real SDK in scope: <code>dispose()</code> operates on the whole <code>Sandbox</code>, not a Firestore-only slice, so if <code>pyric/database</code>/<code>pyric/storage</code> share the same <code>Sandbox</code> their listener registries are torn down too</span></span></span></summary>
639
- <div class="compat-evidence"><div class="compat-probe"><code>unit:firestore/terminate.test.ts</code></div>
640
- <div class="compat-note">tears down the whole Sandbox, not a Firestore-only slice</div></div>
632
+ <details class="compat-row" data-status="ok">
633
+ <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>
634
+ <div class="compat-evidence"><div class="compat-probe">Real Chromium: <code>packages/conformance/observations/firestore/firestore-browser-lifecycle.json</code> records <code>failed-precondition</code> on the terminated instance while Auth and a sibling Firestore instance continue. Replayed by <code>oracle-conformance.test.ts</code>; focused ownership coverage in <code>terminate.test.ts</code>.</div></div>
641
635
  </details>
642
636
  </div>
643
637
  <h2 id="tier-1-cache-init--get-from--family">Tier-1 cache-init + get-from-* family</h2>
@@ -657,20 +651,18 @@
657
651
  <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>
658
652
  <div class="compat-evidence"><div class="compat-probe"><code>unit:firestore/tier1-cache-init-align.test.ts</code></div></div>
659
653
  </details>
660
- <details class="compat-row" data-status="diverged">
661
- <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">Delegates to <code>getDoc</code> / <code>getDocs</code> in the sandbox mirror. Real Firebase THROWS <code>'unavailable'</code> here on a genuine cache miss; pyric never misses the local store always has the answer (or a non-existent snapshot) — so it never throws for that reason</span></span></span></summary>
662
- <div class="compat-evidence"><div class="compat-probe"><code>unit:firestore/tier1-cache-init-align.test.ts</code></div>
663
- <div class="compat-note">never throws unavailable; sandbox has no cache miss</div></div>
654
+ <details class="compat-row" data-status="ok">
655
+ <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>
656
+ <div class="compat-evidence"><div class="compat-probe">Real Chromium: <code>firestore-browser-lifecycle.json</code> captures cold and warm document and query cache behavior; <code>oracle-conformance.test.ts</code> replays it through public APIs.</div></div>
664
657
  </details>
665
658
  <details class="compat-row" data-status="diverged">
666
659
  <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 dev</code>'s own flags, not this call</span></span></span></summary>
667
660
  <div class="compat-evidence"><div class="compat-probe"><code>unit:firestore/tier1-cache-init-align.test.ts</code></div>
668
661
  <div class="compat-note">accepted no-op; no sandbox logger wired</div></div>
669
662
  </details>
670
- <details class="compat-row" data-status="diverged">
671
- <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">onSnapshotsInSync</code><span class="compat-sub"><span class="compat-behavior">Fires the callback once the current snapshot-delivery microtask queue settles — the closest honest approximation of "every active listener has delivered its latest state" available without a true cross-listener sync signal. Not scoped to real server round-trips like the real SDK's guarantee; scoped to local delivery only</span></span></span></summary>
672
- <div class="compat-evidence"><div class="compat-probe"><code>unit:firestore/tier1-cache-init-align.test.ts</code></div>
673
- <div class="compat-note">approximated from local snapshot-delivery settle, not a true global in-sync signal</div></div>
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">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>
665
+ <div class="compat-evidence"><div class="compat-probe">Real Chromium: <code>firestore-browser-lifecycle.json</code> records initial sync, write snapshot, then sync; replayed by <code>oracle-conformance.test.ts</code> and focused listener tests.</div></div>
674
666
  </details>
675
667
  </div>
676
668
  <h2 id="rules-engine-via-setrules-from-pyricsandboxfirestore">Rules engine (via <code>setRules</code> from <code>pyric/sandbox/firestore</code>)</h2>
@@ -731,9 +723,9 @@ shape consumer code depends on.</p>
731
723
  <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>/<code>bool('false')</code>/<code>bool('yes')</code> parsing (RULES-B6 rest); <code>string(1.0)</code>→"1.0" (RULES-B12 rest)</span></span></summary>
732
724
  <div class="compat-evidence"><div class="compat-probe"><code>unit:rules/simulator/evaluator.test.ts</code> (RULES-B5 + "RULES-B6 remainder" blocks); <code>unit:rules/simulator/handler.test.ts</code> ("RULES-B5 end-to-end" block)</div></div>
733
725
  </details>
734
- <details class="compat-row" data-status="diverged">
735
- <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"><span class="compat-behavior">DEFERRED sub-items of row 138: strict bool in <code>&#x26;&#x26;</code>/<code>||</code>/ternary (<code>1 &#x26;&#x26; true</code> should error) corpus-coupled, needs emulator; a FLOAT stored in JSON test-data reads as int (<code>data.x is float</code>→false; prod uses the stored Firestore type tag) needs a <code>__type:'float'</code> test-data revive marker; <code>resource</code>-null-on-create (RULES-B12 rest)</span></span></summary>
736
- <div class="compat-evidence"><div class="compat-probe">DEFERRED see the design rationale (limitation + sub-items); strict-bool also in <code>step-07</code>.</div></div>
726
+ <details class="compat-row" data-status="ok">
727
+ <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">Strict boolean control flow matches production: non-booleans in <code>&#x26;&#x26;</code>, <code>||</code>, or a ternary condition error and deny. Firestore double payloads retain float identity in the simulator (fractional JSON numbers are revived directly; <code>{ __type:'float', value }</code> preserves an explicitly tagged double). On create, <code>resource == null</code> denies while <code>request.resource</code> exposes the incoming document.</span></span></summary>
728
+ <div class="compat-evidence"><div class="compat-probe">Production behavior is recorded by Firestore Rules rows <code>firestore-rules#188</code>, <code>firestore-rules#167</code>, and <code>firestore-rules#166</code>. Direct evaluator/handler tests guard strict operands, fractional-number revival, the explicit float tag, and create-time resource verdicts on the SDK-facing simulator path.</div></div>
737
729
  </details>
738
730
  <details class="compat-row" data-status="ok">
739
731
  <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">Query-proof EVALUATION — the rules-side decision ("rules are not filters"): given a <code>list</code> rule + query constraints, decide provable-or-reject (a doc-dependent rule like <code>resource.data.visibility == 'public'</code> is provable ONLY with a matching <code>where('visibility','==','public')</code>; otherwise the whole query is rejected) (RULES-B11 rules-side)</span></span></summary>
@@ -748,46 +740,18 @@ shape consumer code depends on.</p>
748
740
  <h3 id="documented-divergences">Documented divergences</h3>
749
741
  <p>Known differences between Pyric and production Firebase. Each remains tracked as a non-conforming row.</p>
750
742
  <div class="compat-list">
751
- <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">getDoc(ref)</code><span class="compat-sub"><span class="compat-behavior">Rules denial throws <code>SandboxError('permission-denied', …)</code> on sandbox; <code>FirebaseError('permission-denied')</code> on prod</span></span></span></summary>
752
- <div class="compat-evidence"><div class="compat-note">divergence: same code, different class — both expose <code>.code === 'permission-denied'</code>. Oracle-locked: <code>packages/conformance/observations/firestore/firestore-rules-denied-error.json</code> — prod throws a <code>FirebaseError</code> (name + constructor name both <code>FirebaseError</code>), <code>.code === 'permission-denied'</code>, <code>.message === '7 PERMISSION_DENIED: Missing or insufficient permissions.'</code>, and the value is an <code>instanceof Error</code>.</div></div></details>
753
743
  <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 **prover scope is conservative, with full accounting and a fail-closed classifier** — user functions are inlined (nested helper-calling-helper and multi-parameter helpers included, matching production's rules-function inlining), and a <code>list</code> rule is provable only when its **entire** doc-dependence reduces to top-level AND-conjunct <code>resource.data.&#x3C;field> == &#x3C;literal></code> equalities (with <code>request.auth.uid</code> pinned to the caller) each discharged by a <code>where(field, '==', value)</code> filter. Doc-dependence is decided by a fail-closed classifier: an expression counts as doc-independent only when every node is positively recognized as such — any touch of the <code>resource</code> root in any syntactic form (<code>resource.data</code>, <code>resource['data']</code>, slices, <code>resource.id</code>, path-literal segments feeding <code>exists</code>/<code>get</code> lookups) and any unrecognized node shape classifies doc-dependent. Any doc-dependent conjunct that is not a discharged equality — disjunctions over doc data, inequality/range predicates (<code>resource.data.score > 10</code> + <code>where('score','>',10)</code>), <code>in</code> / negated-<code>in</code> membership checks, <code>get(key, default)</code>, <code>keys().hasOnly(...)</code>, <code>is</code> type checks, nested-path predicates, data-keyed document lookups — makes the whole query conservatively DENY, even when every equality conjunct is discharged; production's prover may allow some of these. Divergence is deny-only: mixed equality + non-equality shapes are rejected up front rather than trusted to a residual evaluation that absent-tolerant predicates could pass vacuously.</span></span></span></summary>
754
744
  <div class="compat-evidence"><div class="compat-note"><code>unit:rules/simulator/query-proof.test.ts</code> (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), <code>unit:firestore/query-proof-enforcement.test.ts</code> (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)</div></div></details>
755
- <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">addDoc(coll, data)</code><span class="compat-sub"><span class="compat-behavior">Auto-id format — prod uses 20-char base64-ish IDs; sandbox uses <code>pyric-admin</code>'s auto-id (also opaque, distinct format)</span></span></span></summary>
756
- <div class="compat-evidence"><div class="compat-note">divergence: IDs are opaque on both sides; format differs but consumer code never parses them. Oracle-locked: <code>packages/conformance/observations/firestore/firestore-adddoc-autoid-format.json</code> — prod auto-ids are 20 characters, all alphanumeric (mixed upper, lower, digits; no other chars). Example: <code>S3PJENMPOk4qcDXol8Ez</code>.</div></div></details>
757
- <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"><code>limitToLast(n)</code> — trailing n in ordered result (requires <code>orderBy</code>). Sandbox: the no-orderBy precondition throws a <code>FirestoreError</code> with <code>.code === 'invalid-argument'</code> (FS-B16; pre-fix plain <code>Error</code>s). Prod: the same precondition throws <code>.code === 'unimplemented'</code></span></span></span></summary>
758
- <div class="compat-evidence"><div class="compat-note">divergence, oracle-locked by <code>packages/conformance/observations/firestore/firestore-limittolast-preconditions.json</code>: prod's no-orderBy <code>limitToLast</code> throws code <code>unimplemented</code>, the sandbox throws <code>invalid-argument</code>. Trailing-window semantics with <code>orderBy</code> conform (observed <code>["b"]</code> matches). Both sides pinned in <code>oracle-conformance.test.ts</code>. Cursor composition + descending: <code>unit:upstream-query-probes.test.ts</code>. Cursor/empty-snapshot precondition codes remain per <code>unit:sandbox-target.test.ts</code> + <code>unit:admin-compat/cursors.test.ts</code> (verified failing pre-fix)</div></div></details>
759
745
  <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>
760
746
  <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>
761
747
  <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>
762
748
  <div class="compat-evidence"><div class="compat-note">divergence: cost behavior differs, observable shape identical. Oracle-locked: <code>packages/conformance/observations/firestore/firestore-count-aggregate-shape.json</code> — <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>
763
- <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">runTransaction(db, fn)</code><span class="compat-sub"><span class="compat-behavior">Retry behavior — prod retries on contention up to 5 times; sandbox is single-threaded, no contention possible</span></span></span></summary>
764
- <div class="compat-evidence"><div class="compat-note">divergence: contention story not modeled; sandbox just runs once</div></div></details>
765
- <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">Equality helpers</code><span class="compat-sub"><span class="compat-behavior"><code>queryEqual(a, b)</code> is identity-only in the sandbox mirror; production's untouched Firebase SDK uses structural equality</span></span></span></summary>
766
- <div class="compat-evidence"><div class="compat-note">divergence: sandbox does identity-only; prod does deep structural. Oracle-locked: <code>packages/conformance/observations/firestore/firestore-queryequal-structural.json</code> — two independently-built queries with the same <code>where('x','==',1)</code> constraint compare equal in prod (<code>sameQueryBuiltTwice: true</code>), confirming structural semantics. Common use case (caching the same returned query) works on both.</div></div></details>
767
- <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">Equality helpers</code><span class="compat-sub"><span class="compat-behavior"><code>snapshotEqual(a, b)</code>. Prod: returns a boolean — true on identity, false even for two fetches of the same data. Sandbox: **throws** (<code>unrecognized reference</code>) for sandbox-target snapshots instead of returning a boolean</span></span></span></summary>
768
- <div class="compat-evidence"><div class="compat-note">divergence, oracle-locked by <code>packages/conformance/observations/firestore/firestore-snapshotequal-structural.json</code> (<code>identity: true</code>, <code>twoFetchesSameData: false</code> — prod is identity-only, NOT structural; an earlier structural guess was corrected by the oracle). The sandbox routes both args through the ref-tagging path, which does not recognize sandbox <code>QuerySnapshot</code>s, so <code>snapshotEqual</code> throws rather than comparing. Both sides pinned in <code>oracle-conformance.test.ts</code>. Fix candidate: identity-compare sandbox snapshots before the ref-tagging dispatch.</div></div></details>
769
- <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 in the sandbox mirror — persistence is already the default; does not reject with <code>'failed-precondition'</code> when called after other ops (deliberately more lenient than the real SDK — no cache-init race to protect)</span></span></span></summary>
770
- <div class="compat-evidence"><div class="compat-note"><code>unit:firestore/persistence-network.test.ts</code></div></div></details>
771
- <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">enableMultiTabIndexedDbPersistence</code><span class="compat-sub"><span class="compat-behavior">Resolves in the sandbox mirror — the SharedWorker path already is the one shared store every tab talks to</span></span></span></summary>
772
- <div class="compat-evidence"><div class="compat-note"><code>unit:firestore/persistence-network.test.ts</code></div></div></details>
773
- <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">Resolve in the sandbox mirror — no network exists to toggle; writes issued while "disabled" still commit immediately (no offline queue is simulated)</span></span></span></summary>
774
- <div class="compat-evidence"><div class="compat-note"><code>unit:firestore/persistence-network.test.ts</code></div></div></details>
775
- <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">waitForPendingWrites</code><span class="compat-sub"><span class="compat-behavior">Resolves immediately in the sandbox mirror — every accepted write is already committed locally by the time its own promise resolves, so there are never writes still pending a server round-trip</span></span></span></summary>
776
- <div class="compat-evidence"><div class="compat-note"><code>unit:firestore/persistence-network.test.ts</code></div></div></details>
777
- <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">Genuinely tears the sandbox target down by calling <code>Sandbox.dispose()</code>, which tears down listener registries on the sandbox's environment (idempotent, doesn't touch data). This differs from the real SDK in scope: <code>dispose()</code> operates on the whole <code>Sandbox</code>, not a Firestore-only slice, so if <code>pyric/database</code>/<code>pyric/storage</code> share the same <code>Sandbox</code> their listener registries are torn down too</span></span></span></summary>
778
- <div class="compat-evidence"><div class="compat-note"><code>unit:firestore/terminate.test.ts</code></div></div></details>
779
749
  <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>
780
750
  <div class="compat-evidence"><div class="compat-note"><code>unit:firestore/tier1-cache-init-align.test.ts</code></div></div></details>
781
751
  <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>
782
752
  <div class="compat-evidence"><div class="compat-note"><code>unit:firestore/tier1-cache-init-align.test.ts</code></div></div></details>
783
- <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">Delegates to <code>getDoc</code> / <code>getDocs</code> in the sandbox mirror. Real Firebase THROWS <code>'unavailable'</code> here on a genuine cache miss; pyric never misses — the local store always has the answer (or a non-existent snapshot) — so it never throws for that reason</span></span></span></summary>
784
- <div class="compat-evidence"><div class="compat-note"><code>unit:firestore/tier1-cache-init-align.test.ts</code></div></div></details>
785
753
  <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 dev</code>'s own flags, not this call</span></span></span></summary>
786
754
  <div class="compat-evidence"><div class="compat-note"><code>unit:firestore/tier1-cache-init-align.test.ts</code></div></div></details>
787
- <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">onSnapshotsInSync</code><span class="compat-sub"><span class="compat-behavior">Fires the callback once the current snapshot-delivery microtask queue settles — the closest honest approximation of "every active listener has delivered its latest state" available without a true cross-listener sync signal. Not scoped to real server round-trips like the real SDK's guarantee; scoped to local delivery only</span></span></span></summary>
788
- <div class="compat-evidence"><div class="compat-note"><code>unit:firestore/tier1-cache-init-align.test.ts</code></div></div></details>
789
- <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"><span class="compat-sub"><span class="compat-behavior">DEFERRED sub-items of row 138: strict bool in <code>&#x26;&#x26;</code>/<code>||</code>/ternary (<code>1 &#x26;&#x26; true</code> should error) — corpus-coupled, needs emulator; a FLOAT stored in JSON test-data reads as int (<code>data.x is float</code>→false; prod uses the stored Firestore type tag) — needs a <code>__type:'float'</code> test-data revive marker; <code>resource</code>-null-on-create (RULES-B12 rest)</span></span></span></summary>
790
- <div class="compat-evidence"><div class="compat-note">DEFERRED — see the design rationale (limitation + sub-items); strict-bool also in <code>step-07</code>.</div></div></details>
791
755
  </div>
792
756
  <h2 id="reviewed-public-runtime-gaps">Reviewed public-runtime gaps</h2>
793
757
  <div class="compat-list">
@@ -821,4 +785,4 @@ shape consumer code depends on.</p>
821
785
  <div class="compat-evidence"><div class="compat-note"><code>ensureFirestoreConfigured</code> <code>executeWrite</code></div>
822
786
  <div class="compat-note">upstream:firebase/firestore</div></div>
823
787
  </details>
824
- </div> </article> </main> <aside class="doc-toc" aria-label="On this page"> <h2 class="doc-toc-heading">On this page</h2> <ul> <li data-depth="2"> <a href="#status-legend">Status legend</a> </li><li data-depth="2"> <a href="#getfirestoretarget--initializer">getFirestore(target) — initializer</a> </li><li data-depth="2"> <a href="#path-constructors--doc--collection--collectiongroup">Path constructors — doc / collection / collectionGroup</a> </li><li data-depth="2"> <a href="#getdocref--single-doc-read">getDoc(ref) — single-doc read</a> </li><li data-depth="2"> <a href="#getdocsquery--bulk-read">getDocs(query) — bulk read</a> </li><li data-depth="2"> <a href="#setdocref-data-options--full-write">setDoc(ref, data[, options]) — full write</a> </li><li data-depth="2"> <a href="#updatedocref-data--partial-write">updateDoc(ref, data) — partial write</a> </li><li data-depth="2"> <a href="#deletedocref">deleteDoc(ref)</a> </li><li data-depth="2"> <a href="#adddoccoll-data--auto-id-write">addDoc(coll, data) — auto-id write</a> </li><li data-depth="2"> <a href="#withconverter--typed-refs">withConverter — typed refs</a> </li><li data-depth="2"> <a href="#query-construction--query--where--or--and--orderby--limit">Query construction — query / where / or / and / orderBy / limit</a> </li><li data-depth="2"> <a href="#cursor-pagination--startat--startafter--endat--endbefore">Cursor pagination — startAt / startAfter / endAt / endBefore</a> </li><li data-depth="2"> <a href="#aggregates--getcountfromserver--getaggregatefromserver--count--sum--average">Aggregates — getCountFromServer / getAggregateFromServer / count / sum / average</a> </li><li data-depth="2"> <a href="#onsnapshotreforquery---listeners">onSnapshot(refOrQuery, …) — listeners</a> </li><li data-depth="2"> <a href="#runtransactiondb-fn">runTransaction(db, fn)</a> </li><li data-depth="2"> <a href="#writebatchdb">writeBatch(db)</a> </li><li data-depth="2"> <a href="#sentinels--servertimestamp--increment--arrayunion--arrayremove--deletefield--fieldvalue--timestamp">Sentinels — serverTimestamp / increment / arrayUnion / arrayRemove / deleteField / FieldValue / Timestamp</a> </li><li data-depth="2"> <a href="#scalar-types--bytes--geopoint--fieldpath--documentid">Scalar types — Bytes / GeoPoint / FieldPath / documentId</a> </li><li data-depth="2"> <a href="#equality-helpers--refequal--queryequal--snapshotequal">Equality helpers — refEqual / queryEqual / snapshotEqual</a> </li><li data-depth="2"> <a href="#connectfirestoreemulator">connectFirestoreEmulator</a> </li><li data-depth="2"> <a href="#offline--persistence--network-family">Offline / persistence / network family</a> </li><li data-depth="2"> <a href="#offline--persistence--network-family-continued">Offline / persistence / network family (continued)</a> </li><li data-depth="2"> <a href="#tier-1-cache-init--get-from--family">Tier-1 cache-init + get-from-* family</a> </li><li data-depth="2"> <a href="#tier-1-cache-init--get-from--family-continued">Tier-1 cache-init + get-from-* family (continued)</a> </li><li data-depth="2"> <a href="#rules-engine-via-setrules-from-pyricsandboxfirestore">Rules engine (via setRules from pyric/sandbox/firestore)</a> </li><li data-depth="2"> <a href="#current-gaps">Current gaps</a> </li><li data-depth="3"> <a href="#documented-divergences">Documented divergences</a> </li><li data-depth="2"> <a href="#reviewed-public-runtime-gaps">Reviewed public-runtime gaps</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>
788
+ </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="#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="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="2" data-astro-cid-mw7aashj> <a href="#reviewed-public-runtime-gaps" data-astro-cid-mw7aashj>Reviewed public-runtime gaps</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>