@pyric/cli 0.1.0-alpha.13 → 0.1.0-alpha.15

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 (614) 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/cli/serve.d.ts +1 -1
  6. package/dist/cli/serve.d.ts.map +1 -1
  7. package/dist/cli/serve.js +208 -285
  8. package/dist/cli/serve.js.map +1 -1
  9. package/dist/cli/service-command-records/database-rules-generate.d.ts +4 -0
  10. package/dist/cli/service-command-records/database-rules-generate.d.ts.map +1 -0
  11. package/dist/cli/service-command-records/database-rules-generate.js +3 -0
  12. package/dist/cli/service-command-records/database-rules-generate.js.map +1 -0
  13. package/dist/cli/service-command-records/database-rules-lint.d.ts +4 -0
  14. package/dist/cli/service-command-records/database-rules-lint.d.ts.map +1 -0
  15. package/dist/cli/service-command-records/database-rules-lint.js +3 -0
  16. package/dist/cli/service-command-records/database-rules-lint.js.map +1 -0
  17. package/dist/cli/service-command-records/database-rules-simulate.d.ts +4 -0
  18. package/dist/cli/service-command-records/database-rules-simulate.d.ts.map +1 -0
  19. package/dist/cli/service-command-records/database-rules-simulate.js +3 -0
  20. package/dist/cli/service-command-records/database-rules-simulate.js.map +1 -0
  21. package/dist/cli/service-command-records/database-rules-validate.d.ts +4 -0
  22. package/dist/cli/service-command-records/database-rules-validate.d.ts.map +1 -0
  23. package/dist/cli/service-command-records/database-rules-validate.js +3 -0
  24. package/dist/cli/service-command-records/database-rules-validate.js.map +1 -0
  25. package/dist/cli/service-command-records/firestore-indexes-generate.d.ts +4 -0
  26. package/dist/cli/service-command-records/firestore-indexes-generate.d.ts.map +1 -0
  27. package/dist/cli/service-command-records/firestore-indexes-generate.js +3 -0
  28. package/dist/cli/service-command-records/firestore-indexes-generate.js.map +1 -0
  29. package/dist/cli/service-command-records/firestore-rules-lint.d.ts +4 -0
  30. package/dist/cli/service-command-records/firestore-rules-lint.d.ts.map +1 -0
  31. package/dist/cli/service-command-records/firestore-rules-lint.js +3 -0
  32. package/dist/cli/service-command-records/firestore-rules-lint.js.map +1 -0
  33. package/dist/cli/service-command-records/firestore-rules-resolve.d.ts +4 -0
  34. package/dist/cli/service-command-records/firestore-rules-resolve.d.ts.map +1 -0
  35. package/dist/cli/service-command-records/firestore-rules-resolve.js +3 -0
  36. package/dist/cli/service-command-records/firestore-rules-resolve.js.map +1 -0
  37. package/dist/cli/service-command-records/firestore-rules-simulate.d.ts +4 -0
  38. package/dist/cli/service-command-records/firestore-rules-simulate.d.ts.map +1 -0
  39. package/dist/cli/service-command-records/firestore-rules-simulate.js +3 -0
  40. package/dist/cli/service-command-records/firestore-rules-simulate.js.map +1 -0
  41. package/dist/cli/service-command-records/firestore-rules-validate.d.ts +4 -0
  42. package/dist/cli/service-command-records/firestore-rules-validate.d.ts.map +1 -0
  43. package/dist/cli/service-command-records/firestore-rules-validate.js +3 -0
  44. package/dist/cli/service-command-records/firestore-rules-validate.js.map +1 -0
  45. package/dist/cli/service-command-records/storage-rules-lint.d.ts +4 -0
  46. package/dist/cli/service-command-records/storage-rules-lint.d.ts.map +1 -0
  47. package/dist/cli/service-command-records/storage-rules-lint.js +3 -0
  48. package/dist/cli/service-command-records/storage-rules-lint.js.map +1 -0
  49. package/dist/cli/service-command-records/storage-rules-simulate.d.ts +4 -0
  50. package/dist/cli/service-command-records/storage-rules-simulate.d.ts.map +1 -0
  51. package/dist/cli/service-command-records/storage-rules-simulate.js +3 -0
  52. package/dist/cli/service-command-records/storage-rules-simulate.js.map +1 -0
  53. package/dist/cli/service-commands.d.ts +7 -0
  54. package/dist/cli/service-commands.d.ts.map +1 -1
  55. package/dist/cli/service-commands.generated.d.ts +35 -0
  56. package/dist/cli/service-commands.generated.d.ts.map +1 -0
  57. package/dist/cli/service-commands.generated.js +25 -0
  58. package/dist/cli/service-commands.generated.js.map +1 -0
  59. package/dist/cli/service-commands.js +23 -40
  60. package/dist/cli/service-commands.js.map +1 -1
  61. package/dist/conformance/.generated/can-i-use-browser.d.ts.map +1 -1
  62. package/dist/conformance/.generated/can-i-use-browser.js +1 -1
  63. package/dist/conformance/.generated/can-i-use-browser.js.map +1 -1
  64. package/dist/conformance/.generated/can-i-use.d.ts.map +1 -1
  65. package/dist/conformance/.generated/can-i-use.js +1 -1
  66. package/dist/conformance/.generated/can-i-use.js.map +1 -1
  67. package/dist/conformance/.generated/conformance-docs.d.ts.map +1 -1
  68. package/dist/conformance/.generated/conformance-docs.js +1 -1
  69. package/dist/conformance/.generated/conformance-docs.js.map +1 -1
  70. package/dist/functions-rtdb/development-runtime.d.ts +63 -0
  71. package/dist/functions-rtdb/development-runtime.d.ts.map +1 -0
  72. package/dist/functions-rtdb/development-runtime.js +244 -0
  73. package/dist/functions-rtdb/development-runtime.js.map +1 -0
  74. package/dist/serve/bridge-mount.d.ts +32 -2
  75. package/dist/serve/bridge-mount.d.ts.map +1 -1
  76. package/dist/serve/bridge-mount.js +232 -18
  77. package/dist/serve/bridge-mount.js.map +1 -1
  78. package/dist/serve/bundler.d.ts +4 -18
  79. package/dist/serve/bundler.d.ts.map +1 -1
  80. package/dist/serve/bundler.js +15 -37
  81. package/dist/serve/bundler.js.map +1 -1
  82. package/dist/serve/entries/app-client.d.ts.map +1 -1
  83. package/dist/serve/entries/app-client.js +5 -5
  84. package/dist/serve/entries/app-client.js.map +1 -1
  85. package/dist/serve/entries/auth-helper-core.d.ts +23 -6
  86. package/dist/serve/entries/auth-helper-core.d.ts.map +1 -1
  87. package/dist/serve/entries/auth-helper-core.js +55 -24
  88. package/dist/serve/entries/auth-helper-core.js.map +1 -1
  89. package/dist/serve/entries/database.d.ts +28 -0
  90. package/dist/serve/entries/database.d.ts.map +1 -1
  91. package/dist/serve/entries/database.js +95 -26
  92. package/dist/serve/entries/database.js.map +1 -1
  93. package/dist/serve/entries/init.d.ts.map +1 -1
  94. package/dist/serve/entries/init.js +21 -12
  95. package/dist/serve/entries/init.js.map +1 -1
  96. package/dist/serve/html-injection.d.ts +5 -0
  97. package/dist/serve/html-injection.d.ts.map +1 -0
  98. package/dist/serve/html-injection.js +59 -0
  99. package/dist/serve/html-injection.js.map +1 -0
  100. package/dist/serve/namespace.d.ts +6 -22
  101. package/dist/serve/namespace.d.ts.map +1 -1
  102. package/dist/serve/namespace.js +23 -145
  103. package/dist/serve/namespace.js.map +1 -1
  104. package/dist/serve/runtime/worker-generation.d.ts +10 -2
  105. package/dist/serve/runtime/worker-generation.d.ts.map +1 -1
  106. package/dist/serve/runtime/worker-generation.js +29 -8
  107. package/dist/serve/runtime/worker-generation.js.map +1 -1
  108. package/dist/serve/runtime/worker-replacement.d.ts +1 -2
  109. package/dist/serve/runtime/worker-replacement.d.ts.map +1 -1
  110. package/dist/serve/sandbox-session.d.ts +78 -0
  111. package/dist/serve/sandbox-session.d.ts.map +1 -0
  112. package/dist/serve/sandbox-session.js +171 -0
  113. package/dist/serve/sandbox-session.js.map +1 -0
  114. package/dist/serve/server.d.ts +5 -2
  115. package/dist/serve/server.d.ts.map +1 -1
  116. package/dist/serve/server.js +21 -5
  117. package/dist/serve/server.js.map +1 -1
  118. package/dist/serve/site-tree.d.ts +8 -0
  119. package/dist/serve/site-tree.d.ts.map +1 -0
  120. package/dist/serve/site-tree.js +113 -0
  121. package/dist/serve/site-tree.js.map +1 -0
  122. package/dist/serve/site-ui/_astro/RulesCodeEditor.CzwHdCi9.js +23 -0
  123. package/dist/serve/site-ui/_astro/_example_.jevZ7OdV.css +1 -0
  124. package/dist/serve/site-ui/_astro/_slug_.BoKXYrnu.css +1 -0
  125. package/dist/serve/site-ui/_astro/_studio_.BtYpqe1A.css +1 -0
  126. package/dist/serve/site-ui/_astro/app.BnMC0ywl.js +109 -0
  127. package/dist/serve/site-ui/_astro/app.BsFsMjn0.css +1 -0
  128. package/dist/serve/site-ui/_astro/app.DVXXR-WI.js +1 -0
  129. package/dist/serve/site-ui/_astro/chess-showcase.DzPO6kz0.js +1 -0
  130. package/dist/serve/site-ui/_astro/chess-source-explorer.C5k9c5yK.js +1 -0
  131. package/dist/serve/site-ui/_astro/chess-v2.CFHmd3UL.js +354 -0
  132. package/dist/serve/site-ui/_astro/client.D2ORs4B-.js +25 -0
  133. package/dist/serve/site-ui/_astro/example-runtime.CM0H02rx.js +291 -0
  134. package/dist/serve/site-ui/_astro/index.B4Kh80he.js +1 -0
  135. package/dist/serve/site-ui/_astro/index.DBy5LfQW.js +9 -0
  136. package/dist/serve/site-ui/_astro/index.DNyk7q8W.js +9 -0
  137. package/dist/serve/site-ui/_astro/jsx-runtime.D_zvdyIk.js +9 -0
  138. package/dist/serve/site-ui/_astro/reads.D1exkX1-.js +1 -0
  139. package/dist/serve/site-ui/_astro/sandbox-controls.BqMePr5V.js +1153 -0
  140. package/dist/serve/site-ui/_astro/seed.BCn5DhHS.js +20 -0
  141. package/dist/serve/site-ui/auth/index.html +11 -0
  142. package/dist/serve/site-ui/docs/_rhythm/index.html +100 -0
  143. package/dist/serve/site-ui/docs/agent/set-up-your-agent/index.html +43 -0
  144. package/dist/serve/site-ui/docs/agent/watch-and-review/index.html +26 -0
  145. package/dist/serve/site-ui/docs/agent/work-with-an-agent/index.html +70 -0
  146. package/dist/serve/{docs-ui → site-ui}/docs/ai-compat/index.html +3 -3
  147. package/dist/serve/site-ui/docs/api-reference/index.html +68 -0
  148. package/dist/serve/{docs-ui → site-ui}/docs/app-compat/index.html +3 -3
  149. package/dist/serve/{docs-ui → site-ui}/docs/auth-compat/index.html +3 -3
  150. package/dist/serve/site-ui/docs/build/ai-logic/index.html +64 -0
  151. package/dist/serve/site-ui/docs/build/authentication/index.html +66 -0
  152. package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +84 -0
  153. package/dist/serve/site-ui/docs/build/cloud-messaging/index.html +71 -0
  154. package/dist/serve/site-ui/docs/build/cloud-storage/index.html +66 -0
  155. package/dist/serve/{docs-ui → site-ui}/docs/build/cloud-storage.md +2 -2
  156. package/dist/serve/site-ui/docs/build/realtime-database/index.html +67 -0
  157. package/dist/serve/site-ui/docs/conformance-scores/index.html +50 -0
  158. package/dist/serve/{docs-ui → site-ui}/docs/conformance-scores.md +3 -3
  159. package/dist/serve/site-ui/docs/create-pyric-reference-api/index.html +531 -0
  160. package/dist/serve/{docs-ui → site-ui}/docs/database-compat/index.html +211 -168
  161. package/dist/serve/{docs-ui → site-ui}/docs/database-compat.md +208 -170
  162. package/dist/serve/site-ui/docs/examples/chess/index.html +384 -0
  163. package/dist/serve/site-ui/docs/examples/chess.md +57 -0
  164. package/dist/serve/site-ui/docs/examples/index.html +3 -0
  165. package/dist/serve/site-ui/docs/examples.md +4 -0
  166. package/dist/serve/{docs-ui → site-ui}/docs/firestore-compat/index.html +55 -91
  167. package/dist/serve/{docs-ui → site-ui}/docs/firestore-compat.md +52 -88
  168. package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +73 -0
  169. package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +29 -0
  170. package/dist/serve/site-ui/docs/get-started/start-building/index.html +33 -0
  171. package/dist/serve/{docs-ui → site-ui}/docs/index.json +595 -26
  172. package/dist/serve/site-ui/docs/messaging-compat/index.html +324 -0
  173. package/dist/serve/{docs-ui → site-ui}/docs/messaging-compat.md +71 -1
  174. package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +28 -0
  175. package/dist/serve/site-ui/docs/observe/see-whats-happening/index.html +74 -0
  176. package/dist/serve/site-ui/docs/observe/shape-your-data/index.html +45 -0
  177. package/dist/serve/site-ui/docs/overview/index.html +17 -0
  178. package/dist/serve/site-ui/docs/pyric-admin-app-reference-api/index.html +186 -0
  179. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-auth-reference-api/index.html +4 -4
  180. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-database-reference-api/index.html +4 -4
  181. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-firestore-reference-api/index.html +318 -202
  182. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-firestore-reference-api.md +154 -27
  183. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-messaging-reference-api/index.html +5 -5
  184. package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api/index.html +318 -0
  185. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ai-reference-api/index.html +5 -5
  186. package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +160 -0
  187. package/dist/serve/site-ui/docs/pyric-app-reference-api/index.html +425 -0
  188. package/dist/serve/{docs-ui → site-ui}/docs/pyric-auth-reference-api/index.html +5 -5
  189. package/dist/serve/site-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +60 -0
  190. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-assurance-reference-api/index.html +4 -4
  191. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-bridge-client-reference-api/index.html +4 -4
  192. package/dist/serve/site-ui/docs/pyric-cli-bridge-reference-api/index.html +507 -0
  193. package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +258 -0
  194. package/dist/serve/site-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +51 -0
  195. package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api/index.html +308 -0
  196. package/dist/serve/site-ui/docs/pyric-cli-credentials-node-reference-api/index.html +68 -0
  197. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-discover-reference-api/index.html +4 -4
  198. package/dist/serve/site-ui/docs/pyric-cli-register-reference-api/index.html +11 -0
  199. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-remote-reference-api/index.html +4 -4
  200. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-serve-worker-reference-api/index.html +1186 -1384
  201. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-serve-worker-reference-api.md +817 -1291
  202. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-verify-reference-api/index.html +4 -4
  203. package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api/index.html +126 -0
  204. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-vite-reference-api.md +1 -1
  205. package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +2641 -0
  206. package/dist/serve/{docs-ui → site-ui}/docs/pyric-database-reference-api.md +1055 -158
  207. package/dist/serve/{docs-ui → site-ui}/docs/pyric-firestore-reference-api/index.html +311 -249
  208. package/dist/serve/{docs-ui → site-ui}/docs/pyric-firestore-reference-api.md +72 -54
  209. package/dist/serve/site-ui/docs/pyric-messaging-reference-api/index.html +509 -0
  210. package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api/index.html +182 -0
  211. package/dist/serve/{docs-ui → site-ui}/docs/pyric-rules-reference-api/index.html +7 -26
  212. package/dist/serve/{docs-ui → site-ui}/docs/pyric-rules-reference-api.md +13 -23
  213. package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api/index.html +121 -0
  214. package/dist/serve/site-ui/docs/pyric-sandbox-firestore-reference-api/index.html +203 -0
  215. package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-reference-api/index.html +26 -5
  216. package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-reference-api.md +22 -22
  217. package/dist/serve/{docs-ui → site-ui}/docs/pyric-storage-reference-api/index.html +5 -15
  218. package/dist/serve/{docs-ui → site-ui}/docs/pyric-storage-reference-api.md +0 -13
  219. package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api/index.html +639 -0
  220. package/dist/serve/site-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +100 -0
  221. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-auth-reference-api/index.html +4 -4
  222. package/dist/serve/site-ui/docs/pyric-ui-events-hooks-reference-api/index.html +24 -0
  223. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-events-reference-api/index.html +4 -4
  224. package/dist/serve/site-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +136 -0
  225. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-firestore-reference-api/index.html +7 -7
  226. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-firestore-reference-api.md +4 -4
  227. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-primitives-reference-api/index.html +4 -4
  228. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rtdb-reference-api/index.html +4 -4
  229. package/dist/serve/site-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +16 -0
  230. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rules-reference-api/index.html +4 -4
  231. package/dist/serve/site-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +176 -0
  232. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-storage-reference-api/index.html +10 -11
  233. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-storage-reference-api.md +7 -8
  234. package/dist/serve/site-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +188 -0
  235. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-traffic-reference-api/index.html +4 -4
  236. package/dist/serve/{docs-ui → site-ui}/docs/rules-compat/index.html +87 -57
  237. package/dist/serve/{docs-ui → site-ui}/docs/rules-compat.md +84 -54
  238. package/dist/serve/site-ui/docs/secure/audit-your-rules/index.html +51 -0
  239. package/dist/serve/site-ui/docs/secure/firestore-rules-limits/index.html +106 -0
  240. package/dist/serve/site-ui/docs/secure/read-a-denial/index.html +41 -0
  241. package/dist/serve/site-ui/docs/secure/rtdb-rules-in-typescript/index.html +67 -0
  242. package/dist/serve/site-ui/docs/secure/rules-standard-library/index.html +159 -0
  243. package/dist/serve/{docs-ui → site-ui}/docs/secure/rules-standard-library.md +2 -2
  244. package/dist/serve/site-ui/docs/secure/secure-it-with-rules/index.html +47 -0
  245. package/dist/serve/site-ui/docs/secure/simulate-and-lint/index.html +95 -0
  246. package/dist/serve/site-ui/docs/secure/write-a-rules-test-suite/index.html +82 -0
  247. package/dist/serve/site-ui/docs/ship/ship-to-production/index.html +37 -0
  248. package/dist/serve/site-ui/docs/ship/test-in-node/index.html +75 -0
  249. package/dist/serve/{docs-ui → site-ui}/docs/storage-compat/index.html +8 -8
  250. package/dist/serve/{docs-ui → site-ui}/docs/storage-compat.md +5 -5
  251. package/dist/serve/site-ui/docs/trust/how-we-know-it-matches-firebase/index.html +132 -0
  252. package/dist/serve/site-ui/docs/trust/rules-standard-library/index.html +861 -0
  253. package/dist/serve/site-ui/docs/trust/rules-standard-library.md +344 -0
  254. package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research/index.html +582 -0
  255. package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research.md +448 -0
  256. package/dist/serve/site-ui/docs/trust/versioning-and-compatibility/index.html +14 -0
  257. package/dist/serve/{docs-ui → site-ui}/docs/tutorial/index.html +4 -4
  258. package/dist/serve/{docs-ui → site-ui}/docs/tutorial.md +1 -1
  259. package/dist/serve/site-ui/examples/chess/index.html +2 -0
  260. package/dist/serve/site-ui/examples/firestore-first-write/index.html +2 -0
  261. package/dist/serve/site-ui/firestore/index.html +11 -0
  262. package/dist/serve/site-ui/index.html +11 -0
  263. package/dist/serve/{docs-ui → site-ui}/llms.txt +6 -2
  264. package/dist/serve/site-ui/rtdb/index.html +11 -0
  265. package/dist/serve/site-ui/settings/index.html +11 -0
  266. package/dist/serve/site-ui/storage/index.html +11 -0
  267. package/dist/serve/site-ui/studio-routes.json +1 -0
  268. package/dist/serve/site-ui/traffic/index.html +11 -0
  269. package/dist/serve/standalone-assets.d.ts +4 -10
  270. package/dist/serve/standalone-assets.d.ts.map +1 -1
  271. package/dist/serve/standalone-assets.js +8 -21
  272. package/dist/serve/standalone-assets.js.map +1 -1
  273. package/dist/serve/vite-ai-config.d.ts +2 -0
  274. package/dist/serve/vite-ai-config.d.ts.map +1 -1
  275. package/dist/serve/vite-ai-config.js +4 -0
  276. package/dist/serve/vite-ai-config.js.map +1 -1
  277. package/dist/serve/vite-functions-development.d.ts +29 -0
  278. package/dist/serve/vite-functions-development.d.ts.map +1 -0
  279. package/dist/serve/vite-functions-development.js +150 -0
  280. package/dist/serve/vite-functions-development.js.map +1 -0
  281. package/dist/serve/vite-generation-bridge.d.ts +17 -0
  282. package/dist/serve/vite-generation-bridge.d.ts.map +1 -0
  283. package/dist/serve/vite-generation-bridge.js +47 -0
  284. package/dist/serve/vite-generation-bridge.js.map +1 -0
  285. package/dist/serve/vite-generation-functions.d.ts +35 -0
  286. package/dist/serve/vite-generation-functions.d.ts.map +1 -0
  287. package/dist/serve/vite-generation-functions.js +46 -0
  288. package/dist/serve/vite-generation-functions.js.map +1 -0
  289. package/dist/serve/vite-generation-middleware.d.ts +10 -0
  290. package/dist/serve/vite-generation-middleware.d.ts.map +1 -0
  291. package/dist/serve/vite-generation-middleware.js +40 -0
  292. package/dist/serve/vite-generation-middleware.js.map +1 -0
  293. package/dist/serve/vite-generation-rules-watch.d.ts +8 -0
  294. package/dist/serve/vite-generation-rules-watch.d.ts.map +1 -0
  295. package/dist/serve/vite-generation-rules-watch.js +33 -0
  296. package/dist/serve/vite-generation-rules-watch.js.map +1 -0
  297. package/dist/serve/vite-module-swap.d.ts +16 -0
  298. package/dist/serve/vite-module-swap.d.ts.map +1 -0
  299. package/dist/serve/vite-module-swap.js +96 -0
  300. package/dist/serve/vite-module-swap.js.map +1 -0
  301. package/dist/serve/vite-page-runtime.d.ts +29 -0
  302. package/dist/serve/vite-page-runtime.d.ts.map +1 -0
  303. package/dist/serve/vite-page-runtime.js +71 -0
  304. package/dist/serve/vite-page-runtime.js.map +1 -0
  305. package/dist/serve/vite-plugin.d.ts +44 -4
  306. package/dist/serve/vite-plugin.d.ts.map +1 -1
  307. package/dist/serve/vite-plugin.js +62 -864
  308. package/dist/serve/vite-plugin.js.map +1 -1
  309. package/dist/serve/vite-sandbox-generation.d.ts +57 -0
  310. package/dist/serve/vite-sandbox-generation.d.ts.map +1 -0
  311. package/dist/serve/vite-sandbox-generation.js +178 -0
  312. package/dist/serve/vite-sandbox-generation.js.map +1 -0
  313. package/dist/serve/vite-worker-runtime.d.ts +1 -1
  314. package/dist/serve/vite-worker-runtime.d.ts.map +1 -1
  315. package/dist/serve/vite-worker-runtime.js +8 -4
  316. package/dist/serve/vite-worker-runtime.js.map +1 -1
  317. package/dist/serve/worker/client/disconnect.d.ts.map +1 -1
  318. package/dist/serve/worker/client/disconnect.js +2 -0
  319. package/dist/serve/worker/client/disconnect.js.map +1 -1
  320. package/dist/serve/worker/client/handles.d.ts +5 -0
  321. package/dist/serve/worker/client/handles.d.ts.map +1 -1
  322. package/dist/serve/worker/client/handles.js.map +1 -1
  323. package/dist/serve/worker/client/pagehide.d.ts +13 -0
  324. package/dist/serve/worker/client/pagehide.d.ts.map +1 -0
  325. package/dist/serve/worker/client/pagehide.js +19 -0
  326. package/dist/serve/worker/client/pagehide.js.map +1 -0
  327. package/dist/serve/worker/client/rtdb-admin.d.ts +8 -0
  328. package/dist/serve/worker/client/rtdb-admin.d.ts.map +1 -0
  329. package/dist/serve/worker/client/rtdb-admin.js +39 -0
  330. package/dist/serve/worker/client/rtdb-admin.js.map +1 -0
  331. package/dist/serve/worker/client/rtdb-connection-lifecycle.d.ts +15 -0
  332. package/dist/serve/worker/client/rtdb-connection-lifecycle.d.ts.map +1 -0
  333. package/dist/serve/worker/client/rtdb-connection-lifecycle.js +45 -0
  334. package/dist/serve/worker/client/rtdb-connection-lifecycle.js.map +1 -0
  335. package/dist/serve/worker/client/rtdb-controls.d.ts +6 -0
  336. package/dist/serve/worker/client/rtdb-controls.d.ts.map +1 -0
  337. package/dist/serve/worker/client/rtdb-controls.js +8 -0
  338. package/dist/serve/worker/client/rtdb-controls.js.map +1 -0
  339. package/dist/serve/worker/client/rtdb-listeners.d.ts +24 -0
  340. package/dist/serve/worker/client/rtdb-listeners.d.ts.map +1 -0
  341. package/dist/serve/worker/client/rtdb-listeners.js +262 -0
  342. package/dist/serve/worker/client/rtdb-listeners.js.map +1 -0
  343. package/dist/serve/worker/client/rtdb-reads.d.ts +4 -0
  344. package/dist/serve/worker/client/rtdb-reads.d.ts.map +1 -0
  345. package/dist/serve/worker/client/rtdb-reads.js +11 -0
  346. package/dist/serve/worker/client/rtdb-reads.js.map +1 -0
  347. package/dist/serve/worker/client/rtdb-references.d.ts +19 -0
  348. package/dist/serve/worker/client/rtdb-references.d.ts.map +1 -0
  349. package/dist/serve/worker/client/rtdb-references.js +63 -0
  350. package/dist/serve/worker/client/rtdb-references.js.map +1 -0
  351. package/dist/serve/worker/client/rtdb-snapshots.d.ts +20 -0
  352. package/dist/serve/worker/client/rtdb-snapshots.d.ts.map +1 -0
  353. package/dist/serve/worker/client/rtdb-snapshots.js +64 -0
  354. package/dist/serve/worker/client/rtdb-snapshots.js.map +1 -0
  355. package/dist/serve/worker/client/rtdb-transactions.d.ts +14 -0
  356. package/dist/serve/worker/client/rtdb-transactions.d.ts.map +1 -0
  357. package/dist/serve/worker/client/rtdb-transactions.js +34 -0
  358. package/dist/serve/worker/client/rtdb-transactions.js.map +1 -0
  359. package/dist/serve/worker/client/rtdb-writes.d.ts +8 -0
  360. package/dist/serve/worker/client/rtdb-writes.d.ts.map +1 -0
  361. package/dist/serve/worker/client/rtdb-writes.js +65 -0
  362. package/dist/serve/worker/client/rtdb-writes.js.map +1 -0
  363. package/dist/serve/worker/client.d.ts +0 -2
  364. package/dist/serve/worker/client.d.ts.map +1 -1
  365. package/dist/serve/worker/client.js +0 -2
  366. package/dist/serve/worker/client.js.map +1 -1
  367. package/dist/serve/worker/entry.js +2 -2
  368. package/dist/serve/worker/entry.js.map +1 -1
  369. package/dist/serve/worker/host/dispatch.d.ts +2 -0
  370. package/dist/serve/worker/host/dispatch.d.ts.map +1 -1
  371. package/dist/serve/worker/host/dispatch.js +24 -2
  372. package/dist/serve/worker/host/dispatch.js.map +1 -1
  373. package/dist/serve/worker/host/rtdb.d.ts +6 -2
  374. package/dist/serve/worker/host/rtdb.d.ts.map +1 -1
  375. package/dist/serve/worker/host/rtdb.js +224 -2
  376. package/dist/serve/worker/host/rtdb.js.map +1 -1
  377. package/dist/serve/worker/host/studio.d.ts.map +1 -1
  378. package/dist/serve/worker/host/studio.js +2 -0
  379. package/dist/serve/worker/host/studio.js.map +1 -1
  380. package/dist/serve/worker/host/subscriptions.d.ts.map +1 -1
  381. package/dist/serve/worker/host/subscriptions.js +3 -3
  382. package/dist/serve/worker/host/subscriptions.js.map +1 -1
  383. package/dist/serve/worker/host.d.ts +1 -1
  384. package/dist/serve/worker/host.d.ts.map +1 -1
  385. package/dist/serve/worker/host.js +1 -1
  386. package/dist/serve/worker/host.js.map +1 -1
  387. package/dist/serve/worker/index.d.ts +16 -1
  388. package/dist/serve/worker/index.d.ts.map +1 -1
  389. package/dist/serve/worker/index.js +17 -4
  390. package/dist/serve/worker/index.js.map +1 -1
  391. package/dist/serve/worker/protocol.d.ts +57 -0
  392. package/dist/serve/worker/protocol.d.ts.map +1 -1
  393. package/dist/serve/worker/protocol.js.map +1 -1
  394. package/dist/serve/worker/rtdb-value-equality.d.ts +3 -0
  395. package/dist/serve/worker/rtdb-value-equality.d.ts.map +1 -0
  396. package/dist/serve/worker/rtdb-value-equality.js +18 -0
  397. package/dist/serve/worker/rtdb-value-equality.js.map +1 -0
  398. package/dist/serve/worker/serve-init.js +2 -2
  399. package/dist/serve/worker/serve-init.js.map +1 -1
  400. package/dist/serve/worker/service-worker-relay.js +2 -2
  401. package/dist/serve/worker/service-worker-relay.js.map +1 -1
  402. package/package.json +7 -5
  403. package/src/assurance/.generated/conformance-verdicts.ts +120 -75
  404. package/src/cli/serve.ts +216 -308
  405. package/src/cli/service-command-records/database-rules-generate.ts +3 -0
  406. package/src/cli/service-command-records/database-rules-lint.ts +3 -0
  407. package/src/cli/service-command-records/database-rules-simulate.ts +3 -0
  408. package/src/cli/service-command-records/database-rules-validate.ts +3 -0
  409. package/src/cli/service-command-records/firestore-indexes-generate.ts +3 -0
  410. package/src/cli/service-command-records/firestore-rules-lint.ts +3 -0
  411. package/src/cli/service-command-records/firestore-rules-resolve.ts +3 -0
  412. package/src/cli/service-command-records/firestore-rules-simulate.ts +3 -0
  413. package/src/cli/service-command-records/firestore-rules-validate.ts +3 -0
  414. package/src/cli/service-command-records/storage-rules-lint.ts +3 -0
  415. package/src/cli/service-command-records/storage-rules-simulate.ts +3 -0
  416. package/src/cli/service-commands.generated.ts +27 -0
  417. package/src/cli/service-commands.test.ts +43 -0
  418. package/src/cli/service-commands.ts +36 -51
  419. package/src/conformance/.generated/can-i-use-browser.ts +1 -1
  420. package/src/conformance/.generated/can-i-use.ts +1 -1
  421. package/src/conformance/.generated/conformance-docs.ts +1 -1
  422. package/src/functions-rtdb/development-runtime.ts +299 -0
  423. package/src/serve/bridge-mount.ts +253 -19
  424. package/src/serve/bundler.ts +17 -36
  425. package/src/serve/entries/app-client.ts +5 -4
  426. package/src/serve/entries/auth-helper-core.ts +83 -30
  427. package/src/serve/entries/database.ts +180 -57
  428. package/src/serve/entries/init.ts +30 -20
  429. package/src/serve/html-injection.ts +65 -0
  430. package/src/serve/namespace.ts +26 -169
  431. package/src/serve/runtime/worker-generation.ts +29 -7
  432. package/src/serve/runtime/worker-replacement.ts +1 -1
  433. package/src/serve/sandbox-session.ts +233 -0
  434. package/src/serve/server.ts +20 -5
  435. package/src/serve/site-tree.ts +146 -0
  436. package/src/serve/standalone-assets.ts +9 -26
  437. package/src/serve/vite-ai-config.ts +8 -0
  438. package/src/serve/vite-functions-development.ts +201 -0
  439. package/src/serve/vite-generation-bridge.ts +66 -0
  440. package/src/serve/vite-generation-functions.ts +78 -0
  441. package/src/serve/vite-generation-middleware.ts +56 -0
  442. package/src/serve/vite-generation-rules-watch.ts +37 -0
  443. package/src/serve/vite-module-swap.ts +119 -0
  444. package/src/serve/vite-page-runtime.ts +100 -0
  445. package/src/serve/vite-plugin.ts +78 -882
  446. package/src/serve/vite-sandbox-generation.ts +255 -0
  447. package/src/serve/vite-worker-runtime.ts +12 -5
  448. package/src/serve/worker/client/disconnect.ts +3 -1
  449. package/src/serve/worker/client/handles.ts +5 -0
  450. package/src/serve/worker/client/pagehide.ts +31 -0
  451. package/src/serve/worker/client/rtdb-admin.ts +74 -0
  452. package/src/serve/worker/client/rtdb-connection-lifecycle.ts +52 -0
  453. package/src/serve/worker/client/rtdb-controls.ts +8 -0
  454. package/src/serve/worker/client/rtdb-listeners.ts +337 -0
  455. package/src/serve/worker/client/rtdb-reads.ts +12 -0
  456. package/src/serve/worker/client/rtdb-references.ts +85 -0
  457. package/src/serve/worker/client/rtdb-snapshots.ts +118 -0
  458. package/src/serve/worker/client/rtdb-transactions.ts +51 -0
  459. package/src/serve/worker/client/rtdb-writes.ts +74 -0
  460. package/src/serve/worker/client.ts +0 -2
  461. package/src/serve/worker/entry.ts +2 -2
  462. package/src/serve/worker/host/dispatch.ts +22 -2
  463. package/src/serve/worker/host/rtdb.ts +243 -2
  464. package/src/serve/worker/host/studio.ts +2 -0
  465. package/src/serve/worker/host/subscriptions.ts +8 -4
  466. package/src/serve/worker/host.ts +1 -1
  467. package/src/serve/worker/index.ts +58 -10
  468. package/src/serve/worker/protocol.ts +23 -2
  469. package/src/serve/worker/rtdb-value-equality.ts +17 -0
  470. package/src/serve/worker/serve-init.ts +2 -2
  471. package/src/serve/worker/service-worker-relay.ts +2 -2
  472. package/dist/serve/docs-ui/_astro/_slug_.DUci-duz.css +0 -1
  473. package/dist/serve/docs-ui/docs/_rhythm/index.html +0 -100
  474. package/dist/serve/docs-ui/docs/agent/set-up-your-agent/index.html +0 -43
  475. package/dist/serve/docs-ui/docs/agent/watch-and-review/index.html +0 -26
  476. package/dist/serve/docs-ui/docs/agent/work-with-an-agent/index.html +0 -70
  477. package/dist/serve/docs-ui/docs/api-reference/index.html +0 -68
  478. package/dist/serve/docs-ui/docs/build/ai-logic/index.html +0 -64
  479. package/dist/serve/docs-ui/docs/build/authentication/index.html +0 -66
  480. package/dist/serve/docs-ui/docs/build/cloud-firestore/index.html +0 -70
  481. package/dist/serve/docs-ui/docs/build/cloud-messaging/index.html +0 -71
  482. package/dist/serve/docs-ui/docs/build/cloud-storage/index.html +0 -66
  483. package/dist/serve/docs-ui/docs/build/realtime-database/index.html +0 -67
  484. package/dist/serve/docs-ui/docs/conformance-scores/index.html +0 -50
  485. package/dist/serve/docs-ui/docs/create-pyric-reference-api/index.html +0 -531
  486. package/dist/serve/docs-ui/docs/functions-rtdb-compat/index.html +0 -73
  487. package/dist/serve/docs-ui/docs/get-started/how-the-swap-works/index.html +0 -29
  488. package/dist/serve/docs-ui/docs/get-started/start-building/index.html +0 -33
  489. package/dist/serve/docs-ui/docs/messaging-compat/index.html +0 -265
  490. package/dist/serve/docs-ui/docs/observe/resolve-runtime-status/index.html +0 -28
  491. package/dist/serve/docs-ui/docs/observe/see-whats-happening/index.html +0 -74
  492. package/dist/serve/docs-ui/docs/observe/shape-your-data/index.html +0 -45
  493. package/dist/serve/docs-ui/docs/overview/index.html +0 -17
  494. package/dist/serve/docs-ui/docs/pyric-admin-app-reference-api/index.html +0 -186
  495. package/dist/serve/docs-ui/docs/pyric-admin-storage-reference-api/index.html +0 -318
  496. package/dist/serve/docs-ui/docs/pyric-ai-scripting-reference-api/index.html +0 -160
  497. package/dist/serve/docs-ui/docs/pyric-app-reference-api/index.html +0 -425
  498. package/dist/serve/docs-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +0 -60
  499. package/dist/serve/docs-ui/docs/pyric-cli-bridge-reference-api/index.html +0 -507
  500. package/dist/serve/docs-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +0 -258
  501. package/dist/serve/docs-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +0 -51
  502. package/dist/serve/docs-ui/docs/pyric-cli-conformance-reference-api/index.html +0 -308
  503. package/dist/serve/docs-ui/docs/pyric-cli-credentials-node-reference-api/index.html +0 -68
  504. package/dist/serve/docs-ui/docs/pyric-cli-register-reference-api/index.html +0 -11
  505. package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api/index.html +0 -126
  506. package/dist/serve/docs-ui/docs/pyric-database-reference-api/index.html +0 -1852
  507. package/dist/serve/docs-ui/docs/pyric-messaging-reference-api/index.html +0 -509
  508. package/dist/serve/docs-ui/docs/pyric-messaging-sw-reference-api/index.html +0 -182
  509. package/dist/serve/docs-ui/docs/pyric-sandbox-database-reference-api/index.html +0 -121
  510. package/dist/serve/docs-ui/docs/pyric-sandbox-firestore-reference-api/index.html +0 -203
  511. package/dist/serve/docs-ui/docs/pyric-ui-agents-reference-api/index.html +0 -639
  512. package/dist/serve/docs-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +0 -100
  513. package/dist/serve/docs-ui/docs/pyric-ui-events-hooks-reference-api/index.html +0 -24
  514. package/dist/serve/docs-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +0 -136
  515. package/dist/serve/docs-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +0 -16
  516. package/dist/serve/docs-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +0 -176
  517. package/dist/serve/docs-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +0 -188
  518. package/dist/serve/docs-ui/docs/secure/audit-your-rules/index.html +0 -51
  519. package/dist/serve/docs-ui/docs/secure/firestore-rules-limits/index.html +0 -106
  520. package/dist/serve/docs-ui/docs/secure/read-a-denial/index.html +0 -41
  521. package/dist/serve/docs-ui/docs/secure/rtdb-rules-in-typescript/index.html +0 -67
  522. package/dist/serve/docs-ui/docs/secure/rules-standard-library/index.html +0 -159
  523. package/dist/serve/docs-ui/docs/secure/secure-it-with-rules/index.html +0 -47
  524. package/dist/serve/docs-ui/docs/secure/simulate-and-lint/index.html +0 -95
  525. package/dist/serve/docs-ui/docs/secure/write-a-rules-test-suite/index.html +0 -82
  526. package/dist/serve/docs-ui/docs/ship/ship-to-production/index.html +0 -37
  527. package/dist/serve/docs-ui/docs/ship/test-in-node/index.html +0 -75
  528. package/dist/serve/docs-ui/docs/trust/how-we-know-it-matches-firebase/index.html +0 -132
  529. package/dist/serve/docs-ui/docs/trust/versioning-and-compatibility/index.html +0 -14
  530. package/dist/serve/docs-ui/index.html +0 -1
  531. package/dist/serve/studio-ui/assets/RulesCodeEditor-BDlH-5lp.js +0 -23
  532. package/dist/serve/studio-ui/assets/index-Bf9SSE8L.js +0 -1218
  533. package/dist/serve/studio-ui/assets/index-BlSGru_r.css +0 -1
  534. package/dist/serve/studio-ui/assets/seed-D_UjxfOU.js +0 -20
  535. package/dist/serve/studio-ui/index.html +0 -32
  536. package/dist/serve/worker/client/rtdb.d.ts +0 -36
  537. package/dist/serve/worker/client/rtdb.d.ts.map +0 -1
  538. package/dist/serve/worker/client/rtdb.js +0 -241
  539. package/dist/serve/worker/client/rtdb.js.map +0 -1
  540. package/src/serve/worker/client/rtdb.ts +0 -311
  541. /package/dist/serve/{docs-ui → site-ui}/404.html +0 -0
  542. /package/dist/serve/{docs-ui → site-ui}/_astro/_slug_.CXh9yTP1.css +0 -0
  543. /package/dist/serve/{docs-ui → site-ui}/docs/_rhythm.md +0 -0
  544. /package/dist/serve/{docs-ui → site-ui}/docs/agent/set-up-your-agent.md +0 -0
  545. /package/dist/serve/{docs-ui → site-ui}/docs/agent/watch-and-review.md +0 -0
  546. /package/dist/serve/{docs-ui → site-ui}/docs/agent/work-with-an-agent.md +0 -0
  547. /package/dist/serve/{docs-ui → site-ui}/docs/ai-compat.md +0 -0
  548. /package/dist/serve/{docs-ui → site-ui}/docs/api-reference.md +0 -0
  549. /package/dist/serve/{docs-ui → site-ui}/docs/app-compat.md +0 -0
  550. /package/dist/serve/{docs-ui → site-ui}/docs/auth-compat.md +0 -0
  551. /package/dist/serve/{docs-ui → site-ui}/docs/build/ai-logic.md +0 -0
  552. /package/dist/serve/{docs-ui → site-ui}/docs/build/authentication.md +0 -0
  553. /package/dist/serve/{docs-ui → site-ui}/docs/build/cloud-firestore.md +0 -0
  554. /package/dist/serve/{docs-ui → site-ui}/docs/build/cloud-messaging.md +0 -0
  555. /package/dist/serve/{docs-ui → site-ui}/docs/build/realtime-database.md +0 -0
  556. /package/dist/serve/{docs-ui → site-ui}/docs/create-pyric-reference-api.md +0 -0
  557. /package/dist/serve/{docs-ui → site-ui}/docs/functions-rtdb-compat.md +0 -0
  558. /package/dist/serve/{docs-ui → site-ui}/docs/get-started/how-the-swap-works.md +0 -0
  559. /package/dist/serve/{docs-ui → site-ui}/docs/get-started/start-building.md +0 -0
  560. /package/dist/serve/{docs-ui → site-ui}/docs/index.html +0 -0
  561. /package/dist/serve/{docs-ui → site-ui}/docs/observe/resolve-runtime-status.md +0 -0
  562. /package/dist/serve/{docs-ui → site-ui}/docs/observe/see-whats-happening.md +0 -0
  563. /package/dist/serve/{docs-ui → site-ui}/docs/observe/shape-your-data.md +0 -0
  564. /package/dist/serve/{docs-ui → site-ui}/docs/overview.md +0 -0
  565. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-app-reference-api.md +0 -0
  566. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-auth-reference-api.md +0 -0
  567. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-database-reference-api.md +0 -0
  568. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-messaging-reference-api.md +0 -0
  569. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-storage-reference-api.md +0 -0
  570. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ai-reference-api.md +0 -0
  571. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ai-scripting-reference-api.md +0 -0
  572. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-app-reference-api.md +0 -0
  573. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-auth-reference-api.md +0 -0
  574. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-assurance-browser-reference-api.md +0 -0
  575. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-assurance-reference-api.md +0 -0
  576. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-bridge-client-reference-api.md +0 -0
  577. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-bridge-reference-api.md +0 -0
  578. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-conformance-browser-reference-api.md +0 -0
  579. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-conformance-docs-reference-api.md +0 -0
  580. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-conformance-reference-api.md +0 -0
  581. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-credentials-node-reference-api.md +0 -0
  582. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-discover-reference-api.md +0 -0
  583. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-register-reference-api.md +0 -0
  584. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-remote-reference-api.md +0 -0
  585. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-verify-reference-api.md +0 -0
  586. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-messaging-reference-api.md +0 -0
  587. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-messaging-sw-reference-api.md +0 -0
  588. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-database-reference-api.md +0 -0
  589. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-firestore-reference-api.md +0 -0
  590. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-agents-reference-api.md +0 -0
  591. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-auth-hooks-reference-api.md +0 -0
  592. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-auth-reference-api.md +0 -0
  593. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-events-hooks-reference-api.md +0 -0
  594. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-events-reference-api.md +0 -0
  595. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-firestore-hooks-reference-api.md +0 -0
  596. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-primitives-reference-api.md +0 -0
  597. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rtdb-reference-api.md +0 -0
  598. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rules-hooks-reference-api.md +0 -0
  599. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rules-reference-api.md +0 -0
  600. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-storage-hooks-reference-api.md +0 -0
  601. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-traffic-hooks-reference-api.md +0 -0
  602. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-traffic-reference-api.md +0 -0
  603. /package/dist/serve/{docs-ui → site-ui}/docs/secure/audit-your-rules.md +0 -0
  604. /package/dist/serve/{docs-ui → site-ui}/docs/secure/firestore-rules-limits.md +0 -0
  605. /package/dist/serve/{docs-ui → site-ui}/docs/secure/read-a-denial.md +0 -0
  606. /package/dist/serve/{docs-ui → site-ui}/docs/secure/rtdb-rules-in-typescript.md +0 -0
  607. /package/dist/serve/{docs-ui → site-ui}/docs/secure/secure-it-with-rules.md +0 -0
  608. /package/dist/serve/{docs-ui → site-ui}/docs/secure/simulate-and-lint.md +0 -0
  609. /package/dist/serve/{docs-ui → site-ui}/docs/secure/write-a-rules-test-suite.md +0 -0
  610. /package/dist/serve/{docs-ui → site-ui}/docs/ship/ship-to-production.md +0 -0
  611. /package/dist/serve/{docs-ui → site-ui}/docs/ship/test-in-node.md +0 -0
  612. /package/dist/serve/{docs-ui → site-ui}/docs/trust/how-we-know-it-matches-firebase.md +0 -0
  613. /package/dist/serve/{docs-ui → site-ui}/docs/trust/versioning-and-compatibility.md +0 -0
  614. /package/dist/serve/{studio-ui → site-ui}/pyric-logo.svg +0 -0
@@ -4,13 +4,13 @@
4
4
 
5
5
  <div class="compat-stat">
6
6
  <p class="compat-stat-figure">
7
- <span class="compat-stat-pct">72.9%</span>
7
+ <span class="compat-stat-pct">100%</span>
8
8
  <span class="compat-stat-label">of the public API supported</span>
9
9
  </p>
10
10
  <div class="compat-meters">
11
- <span class="compat-meter-track"><span class="compat-meter-fill" style="width: 72.9%"></span></span>
11
+ <span class="compat-meter-track"><span class="compat-meter-fill" style="width: 100%"></span></span>
12
12
  </div>
13
- <p class="compat-stat-denom">43 of 59 public API</p>
13
+ <p class="compat-stat-denom">59 of 59 public API</p>
14
14
  </div>
15
15
 
16
16
 
@@ -20,7 +20,6 @@
20
20
  <span class="compat-key-item"><span class="compat-dot" data-status="ok"></span><strong>Conforming</strong> — observable behavior matches Firebase, locked by a passing probe</span>
21
21
  <span class="compat-key-item"><span class="compat-dot" data-status="diverged"></span><strong>Diverged (documented)</strong> — intentional difference with a written reason</span>
22
22
  <span class="compat-key-item"><span class="compat-dot" data-status="unsupported"></span><strong>Not implemented yet</strong> — pending, or intentionally outside the mirror</span>
23
- <span class="compat-key-item"><span class="compat-dot" data-status="unverified"></span><strong>Unverified</strong> — not yet backed by sufficient evidence</span>
24
23
  </div>
25
24
 
26
25
  ## Archived production-toolkit observations
@@ -218,7 +217,7 @@ Two sandbox identity modes are selected by the value passed to
218
217
  - **Sandbox-live** — `getDatabase(sandbox: Sandbox)`. Identity read per
219
218
  operation from `sandbox.currentUser`.
220
219
 
221
- The implementation lives in `packages/pyric/src/database/modular.ts`; the
220
+ The public implementation is split by API family under `packages/pyric/src/database/`; the
222
221
  in-process backend lives in `packages/pyric/src/database/sandbox/`. Rows below
223
222
  are scoped to the modular mirror. The pure rules-engine rows above are internal
224
223
  tooling coverage and are not exports of `pyric/database`.
@@ -253,7 +252,7 @@ tooling coverage and are not exports of `pyric/database`.
253
252
  <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/sandbox-target.test.ts</code> ("ref.root returns the root ref")</div></div>
254
253
  </details>
255
254
  <details class="compat-row" data-status="ok">
256
- <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"><code>get(ref)</code> returns a <code>DataSnapshot</code>-shaped object with <code>val()</code>, <code>exists()</code>, <code>key</code>, <code>child()</code>, <code>hasChildren()</code>, <code>numChildren()</code>, <code>toJSON()</code></span></span></summary>
255
+ <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"><code>get(ref)</code> returns a <code>DataSnapshot</code>-shaped object with <code>val()</code>, <code>exists()</code>, <code>key</code>, <code>child()</code>, <code>hasChildren()</code>, <code>size</code>, and <code>toJSON()</code>; the modular Web surface does not expose <code>numChildren()</code>.</span></span></summary>
257
256
  <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/sandbox-target.test.ts</code> (snapshot shape tests)</div></div>
258
257
  </details>
259
258
  <details class="compat-row" data-status="ok">
@@ -346,7 +345,7 @@ tooling coverage and are not exports of `pyric/database`.
346
345
  </details>
347
346
  <details class="compat-row" data-status="ok">
348
347
  <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"><code>onChildAdded</code> / <code>onChildChanged</code> / <code>onChildRemoved</code> / <code>onChildMoved</code> — plain-ref subscription surface</span></span></summary>
349
- <div class="compat-evidence"><div class="compat-probe">Tier 2: sandbox aligned with oracle observations under <code>packages/conformance/observations/rtdb-modular/rtdb-modular-onchild*.json</code>. See M41–M48 for the per-event behavioral claims.</div></div>
348
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/sandbox-child-events.test.ts</code> exercises all four plain-reference child listener registrars; M41–M48 own their per-event oracle claims.</div></div>
350
349
  </details>
351
350
  <details class="compat-row" data-status="ok">
352
351
  <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"><code>onChildAdded</code> replays each existing direct child of the parent ref on subscribe (one fire per existing key)</span></span></summary>
@@ -369,8 +368,8 @@ tooling coverage and are not exports of `pyric/database`.
369
368
  <div class="compat-evidence"><div class="compat-probe"><code>unit:upstream-rtdb-probes.test.ts</code> (parent wipe fan-out via remove(parent) / set(parent, scalar)) + <code>unit:modular/sandbox-child-events.test.ts</code> (single-child delete carries PRIOR val); matches oracle <code>rtdb-modular-onchildremoved-fires-on-delete.json</code></div></div>
370
369
  </details>
371
370
  <details class="compat-row" data-status="ok">
372
- <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"><code>onChildMoved</code> on a plain ref (no <code>query(_, orderBy*)</code>) NEVER fires per RTDB docs, child_moved emits only under ordered queries</span></span></summary>
373
- <div class="compat-evidence"><div class="compat-probe">Sandbox aligned: <code>unit:modular/sandbox-child-events.test.ts</code> ("does NOT fire on a plain ref (no ordering)"); matches the upstream contract observed under ordered-query in <code>packages/conformance/observations/rtdb-modular/rtdb-modular-onchildmoved-with-orderby.json</code> (where ordered-query did fire Tier 3 will wire that path; Tier 2 locks the plain-ref no-fire case).</div></div>
371
+ <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><span class="compat-behavior">A plain-reference <code>onChildMoved</code> uses Firebase's default priority index: ordinary value changes that preserve priority do not move, while each changed child's priority emits one event even if its predecessor stays the same</span></span></summary>
372
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-priority-contract</code> captures the same one-event-per-priority-operation sequence on a plain ref and an explicit <code>orderByPriority()</code> query, including a priority change that retains the same predecessor; <code>unit:modular/sandbox-child-events.test.ts</code> separately pins no movement for an ordinary value-only change.</div></div>
374
373
  </details>
375
374
  <details class="compat-row" data-status="ok">
376
375
  <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"><code>off(ref)</code> (no event type) removes ALL listeners at that ref — value + every child event variety</span></span></summary>
@@ -408,9 +407,9 @@ tooling coverage and are not exports of `pyric/database`.
408
407
  <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">Returning <code>undefined</code> from the update fn ABORTS the transaction — resolves <code>{ committed: false, snapshot }</code>; no write performed, no listener fan-out</span></span></summary>
409
408
  <div class="compat-evidence"><div class="compat-probe">Sandbox aligned: <code>unit:modular/transaction.test.ts</code> ("returning undefined aborts — committed: false, no write" + "aborted transaction does NOT fan out to listeners"); matches oracle observation <code>packages/conformance/observations/rtdb-modular/rtdb-modular-runtransaction-abort-undefined.json</code> — known divergence: prod's <code>result.snapshot.val()</code> reflects the CLIENT's pre-fetch (often <code>null</code> even when the server has a value because the speculative invocation runs before the server snap arrives); the sandbox returns the actual pre-transaction value at the path (more useful in single-client harness). The agreed-upon contract callers should rely on is <code>committed === false</code> and unchanged server-side data, NOT the snapshot's <code>.val()</code> on the abort path.</div></div>
410
409
  </details>
411
- <details class="compat-row" data-status="ok">
412
- <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">The update fn receives the CURRENT value at the ref's path; for an absent path the argument is <code>null</code> (NOT <code>undefined</code>)</span></span></summary>
413
- <div class="compat-evidence"><div class="compat-probe">Sandbox aligned: <code>unit:modular/transaction.test.ts</code> ("update fn receives null for an absent path" + "update fn receives the existing value for a seeded path"); matches oracle observation <code>packages/conformance/observations/rtdb-modular/rtdb-modular-runtransaction-current-value-arg.json</code> (prod observation showed <code>missingArgs[0].isNull === true</code>) note divergence: prod ALSO speculatively calls the fn with <code>null</code> for a seeded path before the server-snap arrives, the sandbox skips that speculative call (single invocation with the real current value)</div></div>
410
+ <details class="compat-row" data-status="diverged">
411
+ <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">Cold production clients may invoke the update fn first with speculative <code>null</code> and then with the current seeded value; the always-warm in-process sandbox invokes it once with the current value</span></span></summary>
412
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-runtransaction-current-value-arg</code> captures two seeded-path production invocations (<code>null</code>, then current); <code>unit:modular/oracle-conformance-transactions.test.ts</code> pins the sandbox's single current-value invocation. The separate warm-client observation matches the sandbox but does not erase the cold-client contract.</div></div>
414
413
  </details>
415
414
  <details class="compat-row" data-status="ok">
416
415
  <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">The update fn arg is a defensive deep clone — mutating it does NOT corrupt the stored tree (matters for code that does <code>current.count++; return undefined</code> and expects abort to preserve state)</span></span></summary>
@@ -432,9 +431,9 @@ tooling coverage and are not exports of `pyric/database`.
432
431
  <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">Committed transaction fans out to <code>onValue</code> listeners on the watched path with the new value (default applyLocally behavior)</span></span></summary>
433
432
  <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/transaction.test.ts</code> ("committed write fans out to onValue listeners")</div></div>
434
433
  </details>
435
- <details class="compat-row" data-status="unsupported">
436
- <summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><span class="compat-behavior">Concurrent contention / retry-on-conflict single-client sandbox doesn't model real concurrency; the documented "up to 25 retries" contract is degenerate (the fn is invoked once)</span></span></summary>
437
- <div class="compat-evidence"><div class="compat-probe">matrix #161 documents the same gap on the spec side; oracle observation hard to obtain from a single client (oracle row stays <code>?</code>)</div></div>
434
+ <details class="compat-row" data-status="diverged">
435
+ <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"><strong>Divergence:</strong> two ordinary concurrent <code>runTransaction</code> calls are serialized by the in-process backend, so their update functions are not retried with Firebase's captured contention counts. A synchronous re-entrant conflicting write does trigger a deterministic retry.</span></span></summary>
436
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-concurrent-transforms</code> captures invocation counts [2, 3]; <code>unit:modular/transaction-contention-cdd.test.ts</code> pins the sandbox's [1, 1] ordinary-concurrency boundary and separately covers its deterministic re-entrant retry seam.</div></div>
438
437
  </details>
439
438
  <details class="compat-row" data-status="ok">
440
439
  <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">Identity-aware sandbox-live op routing — sign-in/sign-out via <code>pyric/auth</code> is observed by the next RTDB op without re-binding</span></span></summary>
@@ -442,11 +441,11 @@ tooling coverage and are not exports of `pyric/database`.
442
441
  </details>
443
442
  <details class="compat-row" data-status="ok">
444
443
  <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">Backend identity is per-<code>Sandbox</code> — two <code>getDatabase(sandbox)</code> calls on the same sandbox share data, two on different sandboxes don't</span></span></summary>
445
- <div class="compat-evidence"><div class="compat-probe">implicit via the WeakMap binding; tested transitively by <code>sandbox.setData</code> + <code>get</code> round-trips in the same test suite</div></div>
444
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/database-instances-cdd.test.ts</code> proves same-sandbox sharing and independent-sandbox isolation.</div></div>
446
445
  </details>
447
446
  <details class="compat-row" data-status="ok">
448
447
  <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">Sandbox refs carry a stable <code>key</code> (last path segment) and <code>toString()</code> returning <code>sandbox://rtdb/&lt;path&gt;</code></span></span></summary>
449
- <div class="compat-evidence"><div class="compat-probe">covered by the <code>ref</code> / <code>child</code> / <code>parent</code> tests</div></div>
448
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/oracle-conformance-reference-writes.test.ts</code> pins the stable key and local <code>sandbox://rtdb/&lt;path&gt;</code> string boundary alongside the production URL observation.</div></div>
450
449
  </details>
451
450
  <details class="compat-row" data-status="ok">
452
451
  <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"><code>query(ref, orderByChild(p), startAt(v), endAt(w))</code> window is BOTH-INCLUSIVE — children whose ordered field === <code>v</code> or === <code>w</code> are included</span></span></summary>
@@ -456,16 +455,16 @@ tooling coverage and are not exports of `pyric/database`.
456
455
  <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"><code>orderByKey()</code> orders children by RTDB <code>nameCompare</code> — integer-looking keys sort numerically FIRST (so <code>['1','2','10']</code>, not the lexicographic <code>['1','10','2']</code>), then non-integer keys lexicographically; <code>startAt</code>/<code>endAt</code> cursors + the optional <code>key</code> tie-breaker use the same order (DB-B4)</span></span></summary>
457
456
  <div class="compat-evidence"><div class="compat-probe"><code>unit:upstream-rtdb-probes.test.ts</code> (INT32 overflow/underflow cursors) + <code>unit:modular/queries.test.ts</code> + <code>unit:modular/name-compare.test.ts</code>; matches oracle <code>rtdb-modular-orderbykey-window.json</code> and upstream <code>core/util/util.ts:253-276</code></div></div>
458
457
  </details>
459
- <details class="compat-row" data-status="ok">
460
- <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"><code>orderByValue()</code> orders primitive children by their value; <code>limitToFirst(N)</code> returns the N smallest, ascending</span></span></summary>
461
- <div class="compat-evidence"><div class="compat-probe">Sandbox aligned: <code>unit:modular/queries.test.ts</code> ("returns the limitToFirst(N) smallest values, ascending"). Oracle observation <code>packages/conformance/observations/rtdb-modular/rtdb-modular-orderbyvalue-numeric.json</code> shows prod threw <code>Index not defined</code> against blockingfun — the sandbox does NOT enforce <code>.indexOn</code> (rules-engine integration for query indexes is deferred); the semantic claim (ordering by value) is locked here.</div></div>
458
+ <details class="compat-row" data-status="diverged">
459
+ <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">Production rejects an unindexed <code>orderByValue() + limitToFirst(N)</code> query; the sandbox does not enforce <code>.indexOn</code> and returns the N smallest primitive values</span></span></summary>
460
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-orderbyvalue-numeric</code> captures production's <code>Index not defined</code> rejection; <code>unit:modular/oracle-conformance-queries.test.ts</code> pins that rejection beside the sandbox's successful <code>[10,20,30]</code> window.</div></div>
462
461
  </details>
463
462
  <details class="compat-row" data-status="ok">
464
463
  <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"><code>orderByChild(p) + equalTo(v)</code> returns ALL children whose field at <code>p</code> === <code>v</code> — no uniqueness enforced</span></span></summary>
465
464
  <div class="compat-evidence"><div class="compat-probe">Sandbox aligned: <code>unit:modular/queries.test.ts</code> ("returns ALL children whose ordered field === the supplied value"); matches oracle observation <code>packages/conformance/observations/rtdb-modular/rtdb-modular-equalTo-filter.json</code> (both 'b'-grouped children returned).</div></div>
466
465
  </details>
467
466
  <details class="compat-row" data-status="ok">
468
- <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"><code>equalTo</code> with no matches returns an empty snapshot (<code>exists() === false</code>, <code>numChildren() === 0</code>)</span></span></summary>
467
+ <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"><code>equalTo</code> with no matches returns an empty snapshot (<code>exists() === false</code>, <code>size === 0</code>)</span></span></summary>
469
468
  <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/queries.test.ts</code> ("returns an empty snapshot when nothing matches")</div></div>
470
469
  </details>
471
470
  <details class="compat-row" data-status="ok">
@@ -489,7 +488,7 @@ tooling coverage and are not exports of `pyric/database`.
489
488
  <div class="compat-evidence"><div class="compat-probe"><code>unit:upstream-rtdb-probes.test.ts</code> ("one update nulls, mutates, and displaces within a limitToFirst window") + <code>unit:modular/queries.test.ts</code> ("fires only when the windowed result changes"); matches oracle <code>rtdb-modular-onvalue-with-query.json</code></div></div>
490
489
  </details>
491
490
  <details class="compat-row" data-status="ok">
492
- <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"><code>onValue(query)</code> initial fire delivers an empty window (<code>numChildren() === 0</code>) when the path is absent</span></span></summary>
491
+ <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"><code>onValue(query)</code> initial fire delivers an empty window (<code>size === 0</code>) when the path is absent</span></span></summary>
493
492
  <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/queries.test.ts</code> ("initial fire on an empty path delivers an empty window")</div></div>
494
493
  </details>
495
494
  <details class="compat-row" data-status="ok">
@@ -537,7 +536,7 @@ tooling coverage and are not exports of `pyric/database`.
537
536
  <div class="compat-evidence"><div class="compat-probe">Sandbox aligned: <code>unit:modular/push-thenable.test.ts</code> (4 cases); matches oracle <code>packages/conformance/observations/rtdb/rtdb-push-autoid-format.json</code> ("available immediately even when the subsequent server write is denied by rules") + upstream <code>api/Reference_impl.ts:599-630</code></div></div>
538
537
  </details>
539
538
  <details class="compat-row" data-status="ok">
540
- <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"><code>DataSnapshot</code> shape: <code>size</code> (getter), <code>priority</code> (currently always <code>null</code>), <code>exportVal()</code>, <code>key</code>, <code>ref</code>, <code>val()</code>, <code>exists()</code>, <code>child()</code>, <code>hasChild()</code>, <code>hasChildren()</code>, <code>forEach()</code>, <code>toJSON()</code>. It does NOT ship the legacy namespaced <code>numChildren()</code> method (DB-B10)</span></span></summary>
539
+ <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"><code>DataSnapshot</code> shape: <code>size</code> (getter), <code>priority</code> (<code>null</code> when absent), <code>exportVal()</code>, <code>key</code>, <code>ref</code>, <code>val()</code>, <code>exists()</code>, <code>child()</code>, <code>hasChild()</code>, <code>hasChildren()</code>, <code>forEach()</code>, <code>toJSON()</code>. It does NOT ship the legacy namespaced <code>numChildren()</code> method (DB-B10)</span></span></summary>
541
540
  <div class="compat-evidence"><div class="compat-probe">Sandbox aligned: <code>unit:modular/snapshot-shape.test.ts</code> ("exposes size/priority/exportVal; NOT numChildren()"); matches oracle <code>packages/conformance/observations/rtdb-modular/rtdb-modular-get-snapshot-shape.json</code> (<code>hasSize: true, hasNumChildren: false</code>) + upstream <code>api/Reference_impl.ts:288-447</code>. <strong>Flipped masking tests</strong>: <code>modular/queries.test.ts</code> + <code>modular/sandbox-target.test.ts</code> asserted <code>snap.numChildren()</code> — updated to <code>snap.size</code>.</div></div>
542
541
  </details>
543
542
  <details class="compat-row" data-status="ok">
@@ -552,72 +551,160 @@ tooling coverage and are not exports of `pyric/database`.
552
551
  <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"><code>onValue(ref, cb, { onlyOnce: true })</code> fires once then auto-unsubscribes (DB-B12)</span></span></summary>
553
552
  <div class="compat-evidence"><div class="compat-probe">Sandbox aligned: <code>unit:modular/onvalue-onlyonce.test.ts</code>; upstream <code>api/Reference_impl.ts:975-980</code></div></div>
554
553
  </details>
555
- <details class="compat-row" data-status="diverged">
556
- <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"><strong>Divergence (DB-B12, honest doc):</strong> the onChild<em> callbacks do NOT receive the <code>previousChildName</code> second argument; <code>onValue</code>/<code>onChild</em></code> do NOT accept a <code>cancelCallback</code>; <code>onChildAdded</code>/<code>Changed</code>/<code>Removed</code>/<code>Moved</code> accept only plain refs (not <code>Query</code>); <code>child_moved</code> never fires (ordered-query move detection unmodeled). These listener-surface holes are out of scope for the current phase — consumers needing them use <code>firebase/database</code> directly.</span></span></summary>
557
- <div class="compat-evidence"><div class="compat-probe">divergence documented; partial coverage: <code>{ onlyOnce }</code> IS implemented (M74).</div></div>
554
+ <details class="compat-row" data-status="ok">
555
+ <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">Child-listener callbacks receive Firebase's <code>previousChildName</code> second argument, including initial replay and ordered-query movement.</span></span></summary>
556
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-child-previous-name</code> captures initial replay plus add/change/remove/move predecessor values; replayed by <code>unit:modular/listener-lifecycle-cdd.test.ts</code>.</div></div>
557
+ </details>
558
+ <details class="compat-row" data-status="ok">
559
+ <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">Value and child listener overloads accept a cancellation callback and deliver Firebase-shaped permission errors when a listen is denied or revoked; a callbackless listener that loses auth access is terminal and does not resurrect after sign-in.</span></span></summary>
560
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-listener-cancellation</code> captures all five registrars returning normally, asynchronous initial-denial cancellation, one revocation callback each, and the Error/PERMISSION_DENIED/message shape; replayed in <code>unit:modular/listener-lifecycle-cdd.test.ts</code>.</div></div>
561
+ </details>
562
+ <details class="compat-row" data-status="ok">
563
+ <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">All child-listener functions accept <code>Query</code> inputs; add/change/remove events respect the active query window.</span></span></summary>
564
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/listener-lifecycle-cdd.test.ts</code> and <code>unit:modular/sandbox-child-events.test.ts</code> cover initial windows plus entering, leaving, and changing members.</div></div>
565
+ </details>
566
+ <details class="compat-row" data-status="ok">
567
+ <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"><code>onChildMoved</code> fires when an ordered child changes position and co-fires with <code>child_changed</code> when Firebase does, preserving the captured <code>previousChildName</code> sequence.</span></span></summary>
568
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-child-previous-name</code> and the modular oracle suite replay ordered movement, co-fire behavior, and predecessor sequencing.</div></div>
569
+ </details>
570
+ <details class="compat-row" data-status="ok">
571
+ <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">Child listener overloads accept <code>ListenOptions</code> directly or after a cancellation callback; <code>onlyOnce</code> stops delivery after Firebase's captured initial/event batch.</span></span></summary>
572
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-child-listener-only-once</code> captures all four listener families, both overload shapes, the existing-child replay batch, and one-shot post-registration delivery; replayed by <code>unit:modular/listener-lifecycle-cdd.test.ts</code>.</div></div>
558
573
  </details>
559
574
  <details class="compat-row" data-status="ok">
560
575
  <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"><code>.validate</code> rules are enforced on modular sandbox writes through <code>set</code>, atomic <code>update</code>, and <code>runTransaction</code>; a descendant validation failure rejects the operation without changing state.</span></span></summary>
561
576
  <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/sandbox-target.test.ts</code> executes all three write paths against a required-child <code>.validate</code> rule and proves each rejects without committing state. The shared <code>SimulateHandler</code> behavior is production-locked by RTDB rules corpus rows #4 and #15.</div></div>
562
577
  </details>
578
+ <details class="compat-row" data-status="ok">
579
+ <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"><code>onDisconnect(ref)</code> returns the Firebase-shaped five-method handle; registration methods and <code>cancel()</code> return acknowledged Promises</span></span></summary>
580
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-ondisconnect-registration</code>; sandbox <code>unit:database/on-disconnect.test.ts</code>.</div></div>
581
+ </details>
582
+ <details class="compat-row" data-status="ok">
583
+ <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">An acknowledged <code>onDisconnect(ref).set(value)</code> registration does not mutate server data before the client disconnects</span></span></summary>
584
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-ondisconnect-registration</code>; sandbox registration/no-mutation test.</div></div>
585
+ </details>
586
+ <details class="compat-row" data-status="ok">
587
+ <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"><code>goOffline(db)</code> drains that client's queue once, listeners observe the disconnect write in server order, and <code>goOnline(db)</code> does not resurrect executed operations</span></span></summary>
588
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-ondisconnect-clean-set</code>; sandbox clean lifecycle test.</div></div>
589
+ </details>
590
+ <details class="compat-row" data-status="ok">
591
+ <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">Disconnect queues support <code>set</code>, <code>update</code>, <code>remove</code>, exact cancellation, parent cancellation of queued descendants, and captured parent-set/child-set/child-cancel coalescing that preserves the existing canceled child</span></span></summary>
592
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-ondisconnect-operations-cancel</code>; sandbox operation/cancellation test, including the captured parent-set + child-cancel merge result.</div></div>
593
+ </details>
594
+ <details class="compat-row" data-status="ok">
595
+ <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">Rules are evaluated when a disconnect operation is registered and re-evaluated when it executes; an execution-time denial leaves server state unchanged</span></span></summary>
596
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-ondisconnect-rules</code> with successful normal-write controls in both rule phases; sandbox rules-timing test.</div></div>
597
+ </details>
598
+ <details class="compat-row" data-status="ok">
599
+ <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"><strong>Local lifecycle contract:</strong> disconnect queues are owned per Database client, drain on app deletion, clear without executing on sandbox reset, and are excluded from persisted RTDB snapshots</span></span></summary>
600
+ <div class="compat-evidence"><div class="compat-probe">The explicit <code>rtdb-modular#M82</code> assertion set in <code>unit:database/on-disconnect.test.ts</code> covers independent clients, app deletion, reset clearing, and snapshot exclusion; these sandbox-owned boundaries have no production oracle equivalent.</div></div>
601
+ </details>
602
+ <details class="compat-row" data-status="ok">
603
+ <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"><code>OnDisconnect.setWithPriority(value, priority)</code> writes both the value and RTDB priority metadata when the disconnect queue drains.</span></span></summary>
604
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-ondisconnect-operations-cancel</code> captures export-format priority 7; sandbox <code>unit:database/on-disconnect.test.ts</code> replays the value and priority.</div></div>
605
+ </details>
606
+ <details class="compat-row" data-status="diverged">
607
+ <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"><strong>Divergence (pending fix):</strong> clean <code>goOffline</code>, app deletion, playground <code>pagehide</code>, and best-effort MessagePort close drain queued operations, but unannounced total renderer/process loss is not guaranteed by the in-memory sandbox</span></span></summary>
608
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-ondisconnect-abrupt-exit</code> proves Firebase executes an acknowledged registration after forced writer termination. The two-port worker integration exercises <code>goOffline</code>, served-app deletion, and non-persisted <code>pagehide</code>; browser MessagePort close delivery cannot prove total-process loss without durable host-owned leases.</div></div>
609
+ </details>
610
+ <details class="compat-row" data-status="ok">
611
+ <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"><code>Database</code> is exported as a runtime constructor value and handles returned by <code>getDatabase()</code> satisfy Firebase's observable prototype and <code>instanceof</code> contract.</span></span></summary>
612
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-runtime-class-identity</code>; sandbox row assertion <code>rtdb-modular#M85</code> replays runtime identity.</div></div>
613
+ </details>
614
+ <details class="compat-row" data-status="ok">
615
+ <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"><code>DataSnapshot</code> is exported as a runtime constructor value and snapshots returned by reads/listeners satisfy Firebase's observable prototype and <code>instanceof</code> contract.</span></span></summary>
616
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-runtime-class-identity</code>; sandbox row assertion <code>rtdb-modular#M86</code> replays runtime identity.</div></div>
617
+ </details>
618
+ <details class="compat-row" data-status="ok">
619
+ <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"><code>QueryConstraint</code> is exported as a runtime constructor value and constraints returned by <code>orderBy*</code>, bound, and limit factories satisfy Firebase's observable prototype and <code>instanceof</code> contract.</span></span></summary>
620
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-runtime-class-identity</code>; concrete constraint subclasses satisfy <code>instanceof QueryConstraint</code> without using the base prototype directly, replayed by row assertion <code>rtdb-modular#M87</code>.</div></div>
621
+ </details>
622
+ <details class="compat-row" data-status="ok">
623
+ <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"><code>TransactionResult</code> is exported as a runtime constructor value and transaction results satisfy Firebase's observable prototype, <code>instanceof</code>, and <code>toJSON()</code> contract.</span></span></summary>
624
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-runtime-class-identity</code>; sandbox row assertion <code>rtdb-modular#M88</code> replays runtime identity and <code>toJSON()</code>.</div></div>
625
+ </details>
626
+ <details class="compat-row" data-status="ok">
627
+ <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"><code>setPriority</code> and <code>setWithPriority</code> store, replace, preserve, and clear valid RTDB priority metadata; parent <code>exportVal()</code> and <code>toJSON()</code> recursively include descendant priority metadata.</span></span></summary>
628
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-priority-contract</code> captures round-trip/export shape, update/transaction preservation, plain-set clearing, and explicit clearing; replayed by <code>unit:modular/priority-metadata-cdd.test.ts</code>.</div></div>
629
+ </details>
630
+ <details class="compat-row" data-status="ok">
631
+ <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"><code>orderByPriority</code> orders by Firebase priority with key tie-breaking and composes with bounds, equality, and limits; plain snapshots and unconstrained queries use the same default priority index, and invalid priority bounds throw synchronously.</span></span></summary>
632
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-priority-contract</code> captures priority order, key tie-breaking, bounds, and limits; replayed by <code>unit:modular/priority-metadata-cdd.test.ts</code>.</div></div>
633
+ </details>
634
+ <details class="compat-row" data-status="ok">
635
+ <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">Priority changes participate in plain and explicitly ordered child movement/listener sequencing, transactions, and updates without losing metadata.</span></span></summary>
636
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-priority-contract</code> captures priority movement, update/transaction preservation, and descendant delivery when ancestor replacement clears metadata; replayed by <code>unit:modular/priority-metadata-cdd.test.ts</code> and <code>unit:modular/priority-listeners.test.ts</code>. Disconnect priority execution is owned separately by M83.</div></div>
637
+ </details>
638
+ <details class="compat-row" data-status="ok">
639
+ <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"><code>off(query)</code> removes listeners only from the equivalent constrained query view, while <code>off(ref)</code> removes listeners from every query view at that path.</span></span></summary>
640
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-off-duplicate-registration</code> captures exact constrained-query removal and all-view reference removal with independent live-listener controls; replayed by <code>unit:modular/sandbox-child-events.test.ts</code>.</div></div>
641
+ </details>
642
+ <details class="compat-row" data-status="diverged">
643
+ <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"><strong>Divergence:</strong> <code>DatabaseReference</code> and <code>Query</code> equality includes database target, path, and canonical query parameters like Firebase, but <code>toJSON()</code> serializes the local <code>sandbox://rtdb/...</code> identity instead of Firebase's HTTPS database URL.</span></span></summary>
644
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-reference-shape-url</code> captures conforming equality plus HTTPS JSON serialization; <code>unit:modular/oracle-conformance-reference-writes.test.ts</code> pins both the production HTTPS shape and the sandbox's <code>sandbox://</code> boundary.</div></div>
645
+ </details>
646
+ <details class="compat-row" data-status="ok">
647
+ <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 constraint construction preserves Firebase's synchronous validation for limits, child paths, cursor keys, undefined/non-finite/object endpoint values, and index-specific endpoint compatibility, including the captured +Infinity and server-value priority acceptances</span></span></summary>
648
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-query-construction-validation</code> repeats the complete validation matrix twice per run and matched across two clean production runs; <code>unit:modular/query-validation.test.ts</code> replays every captured field exactly.</div></div>
649
+ </details>
563
650
  </div>
564
651
 
565
652
  ### `getDatabase(target)` — initializer
566
653
 
567
654
  <div class="compat-list">
568
- <details class="compat-row" data-status="unsupported">
569
- <summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><span class="compat-behavior"><code>getDatabase(ctx)</code> returns a tagged sandbox-target handle (frozen identity)</span></span></summary>
570
- <div class="compat-evidence"><div class="compat-probe">Phase 3</div></div>
655
+ <details class="compat-row" data-status="ok">
656
+ <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"><code>getDatabase(ctx)</code> returns a tagged sandbox-target handle (frozen identity)</span></span></summary>
657
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/database-instances-cdd.test.ts</code> asserts the returned Database carries a sandbox target.</div></div>
571
658
  </details>
572
- <details class="compat-row" data-status="unsupported">
573
- <summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><span class="compat-behavior"><code>getDatabase(sandbox)</code> returns a tagged sandbox-live handle (per-op identity)</span></span></summary>
574
- <div class="compat-evidence"><div class="compat-probe">Phase 3</div></div>
659
+ <details class="compat-row" data-status="ok">
660
+ <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"><code>getDatabase(sandbox)</code> returns a tagged sandbox-live handle (per-op identity)</span></span></summary>
661
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/database-instances-cdd.test.ts</code> asserts the returned Database carries a sandbox-live target.</div></div>
575
662
  </details>
576
- <details class="compat-row" data-status="unverified">
577
- <summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-behavior">Inactive canonical <code>firebase/database</code> imports remain the upstream package; the mirror does not create tagged production targets</span></span></summary>
578
- <div class="compat-evidence"><div class="compat-probe">package-resolution boundary; inactive RTDB canonical-import isolation is not yet claimed by this row</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"><span class="compat-behavior">Inactive canonical <code>firebase/database</code> imports remain the upstream package; the mirror does not create tagged production targets</span></span></summary>
665
+ <div class="compat-evidence"><div class="compat-probe">Package-resolution boundary assertion in <code>unit:modular/database-instances-cdd.test.ts</code> proves a real Firebase Database remains untagged and is rejected by the mirror.</div></div>
579
666
  </details>
580
667
  <details class="compat-row" data-status="ok">
581
668
  <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"><code>getDatabase()</code> (no argument) — wrapped in the playground preview to supply the sandbox; a raw mirror call rejects with package-resolution guidance</span></span></summary>
582
669
  <div class="compat-evidence"><div class="compat-probe">Phase 3 Tier 5: virtualized in the playground preview scope. Wired at <code>packages/playground/src/components/AppPreview.tsx</code> (slot install with bare-call wrap), <code>packages/playground/src/lib/preview/virtual-imports-plugin.ts</code> (alias map), and <code>packages/playground/src/lib/preview/preview-scope.ts</code> (type-level slot). Mirrors the <code>getAuth</code> / <code>getFirestore</code> wrap pattern. Demo fixture: <code>packages/playground/scripts/fixtures/rtdb-set-get-roundtrip.tsx</code> (bare <code>getDatabase()</code> + <code>set</code>/<code>get</code>/<code>remove</code> round-trip with anonymous sign-in) passes end-to-end through the <code>bun run debug:fixtures</code> Playwright suite.</div>
583
670
  <div class="compat-note">(wrap, fixture passing)</div></div>
584
671
  </details>
585
- <details class="compat-row" data-status="unsupported">
586
- <summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><span class="compat-behavior">Two <code>getDatabase(sandbox)</code> calls share state (same underlying <code>LocalEnvironment</code>)</span></span></summary>
587
- <div class="compat-evidence"><div class="compat-probe">Phase 3</div></div>
672
+ <details class="compat-row" data-status="ok">
673
+ <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">Two <code>getDatabase(sandbox)</code> calls share state (same underlying <code>LocalEnvironment</code>)</span></span></summary>
674
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/database-instances-cdd.test.ts</code> writes through one handle and reads through another handle owned by the same sandbox.</div></div>
588
675
  </details>
589
- <details class="compat-row" data-status="unsupported">
590
- <summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><span class="compat-behavior">Handle dispatch by <code>TARGET_SYMBOL</code> brand — refs route to their owning target via a <code>refToTarget</code> WeakMap (mirror of firestore's pattern)</span></span></summary>
591
- <div class="compat-evidence"><div class="compat-probe">Phase 3</div></div>
676
+ <details class="compat-row" data-status="ok">
677
+ <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">Handle dispatch by <code>TARGET_SYMBOL</code> brand — refs route to their owning target via a <code>refToTarget</code> WeakMap (mirror of firestore's pattern)</span></span></summary>
678
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/database-instances-cdd.test.ts</code> proves references from independent sandbox targets route to independent backends.</div></div>
592
679
  </details>
593
680
  </div>
594
681
 
595
682
  ### `ref(db, path)` / `child` / `parent` / `root`
596
683
 
597
684
  <div class="compat-list">
598
- <details class="compat-row" data-status="unverified">
599
- <summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-behavior"><code>ref(db, path)</code> returns a tagged <code>DatabaseReference</code> carrying <code>key</code>, <code>parent</code>, <code>root</code>, <code>toString()</code></span></span></summary>
600
- <div class="compat-evidence"><div class="compat-probe">upstream <code>firebase/database</code> contract</div></div>
685
+ <details class="compat-row" data-status="ok">
686
+ <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"><code>ref(db, path)</code> returns a tagged <code>DatabaseReference</code> carrying <code>key</code>, <code>parent</code>, <code>root</code>, and <code>toString()</code>, and synchronously rejects paths containing <code>.</code>, <code>#</code>, <code>$</code>, <code>[</code>, or <code>]</code> with Firebase's captured error shape</span></span></summary>
687
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-reference-shape-url</code>; sandbox row assertion <code>rtdb-modular#100</code> replays navigation and every forbidden path character.</div></div>
601
688
  </details>
602
- <details class="compat-row" data-status="unverified">
603
- <summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-behavior"><code>ref(db)</code> with no path returns the root ref (<code>key === null</code>, <code>parent === null</code>)</span></span></summary>
604
- <div class="compat-evidence"><div class="compat-probe">upstream contract</div></div>
689
+ <details class="compat-row" data-status="ok">
690
+ <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"><code>ref(db)</code> with no path returns the root ref (<code>key === null</code>, <code>parent === null</code>)</span></span></summary>
691
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-reference-shape-url</code>; sandbox row assertion <code>rtdb-modular#101</code>.</div></div>
605
692
  </details>
606
- <details class="compat-row" data-status="unverified">
607
- <summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-behavior"><code>child(ref, 'a/b')</code> joins a relative path, including embedded slashes</span></span></summary>
608
- <div class="compat-evidence"><div class="compat-probe">upstream contract</div></div>
693
+ <details class="compat-row" data-status="ok">
694
+ <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><span class="compat-behavior"><code>child(ref, 'a/b')</code> joins a non-empty relative path, including embedded slashes, and synchronously rejects empty or forbidden-character paths with Firebase's captured error shape</span></span></summary>
695
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-reference-shape-url</code>; sandbox row assertion <code>rtdb-modular#102</code> replays embedded-path joining plus empty/invalid validation.</div></div>
609
696
  </details>
610
- <details class="compat-row" data-status="unverified">
611
- <summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-behavior"><code>ref.parent</code> is <code>null</code> at root, otherwise the parent ref</span></span></summary>
612
- <div class="compat-evidence"><div class="compat-probe">upstream contract</div></div>
697
+ <details class="compat-row" data-status="ok">
698
+ <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"><code>ref.parent</code> is <code>null</code> at root, otherwise the parent ref</span></span></summary>
699
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-reference-shape-url</code>; sandbox row assertion <code>rtdb-modular#103</code>.</div></div>
613
700
  </details>
614
- <details class="compat-row" data-status="unverified">
615
- <summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-behavior"><code>ref.key</code> is the final path segment, <code>null</code> for root</span></span></summary>
616
- <div class="compat-evidence"><div class="compat-probe">upstream contract</div></div>
701
+ <details class="compat-row" data-status="ok">
702
+ <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"><code>ref.key</code> is the final path segment, <code>null</code> for root</span></span></summary>
703
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-reference-shape-url</code>; sandbox row assertion <code>rtdb-modular#104</code>.</div></div>
617
704
  </details>
618
- <details class="compat-row" data-status="unsupported">
619
- <summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><span class="compat-behavior">Unknown ref (not produced by this package) → <code>TypeError</code> in shim ops</span></span></summary>
620
- <div class="compat-evidence"><div class="compat-probe">Phase 3</div></div>
705
+ <details class="compat-row" data-status="ok">
706
+ <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">Unknown ref (not produced by this package) → <code>TypeError</code> in shim ops</span></span></summary>
707
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-reference-shape-url</code> captures a synchronous <code>TypeError</code>; sandbox row assertion <code>rtdb-modular#105</code> matches its timing and constructor.</div></div>
621
708
  </details>
622
709
  </div>
623
710
 
@@ -649,9 +736,9 @@ tooling coverage and are not exports of `pyric/database`.
649
736
  ### `set(ref, value)` — full write
650
737
 
651
738
  <div class="compat-list">
652
- <details class="compat-row" data-status="unverified">
653
- <summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-behavior">Replaces the value at the path entirely; resolves to <code>undefined</code> (unlike <code>setDoc</code> which resolves to <code>void</code>, RTDB's <code>set</code> is documented as <code>Promise&lt;void&gt;</code>)</span></span></summary>
654
- <div class="compat-evidence"><div class="compat-probe">upstream contract</div></div>
739
+ <details class="compat-row" data-status="ok">
740
+ <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">Replaces the value at the path entirely; resolves to <code>undefined</code> (unlike <code>setDoc</code> which resolves to <code>void</code>, RTDB's <code>set</code> is documented as <code>Promise&lt;void&gt;</code>)</span></span></summary>
741
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-write-return-validation</code> captures <code>null</code> in JSON for the resolved <code>undefined</code> value; sandbox row assertion <code>rtdb-modular#111</code> matches it.</div></div>
655
742
  </details>
656
743
  <details class="compat-row" data-status="ok">
657
744
  <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"><code>set(ref, null)</code> removes the path entirely — equivalent to <code>remove(ref)</code>, subsequent <code>get</code> returns <code>null</code>-val snapshot</span></span></summary>
@@ -690,9 +777,9 @@ tooling coverage and are not exports of `pyric/database`.
690
777
  <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">Setting a key to <code>null</code> inside <code>update</code> removes that key — same equivalence as <code>set(ref, null)</code></span></span></summary>
691
778
  <div class="compat-evidence"><div class="compat-probe">oracle: <code>packages/conformance/observations/rtdb-modular/rtdb-modular-update-null-removes-key.json</code> — after <code>set({a:1,b:2})</code> then <code>update({a:null})</code>, observed <code>final: {b:2}</code> with <code>a</code> absent.</div></div>
692
779
  </details>
693
- <details class="compat-row" data-status="unverified">
694
- <summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-behavior">Update path validation — overlapping paths (e.g. <code>'/a'</code> and <code>'/a/x'</code> in the same call) throws synchronously before any write</span></span></summary>
695
- <div class="compat-evidence"><div class="compat-probe">upstream contract needs targeted probe</div></div>
780
+ <details class="compat-row" data-status="ok">
781
+ <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">Update path validation — overlapping paths (e.g. <code>'/a'</code> and <code>'/a/x'</code> in the same call) throws synchronously before any write</span></span></summary>
782
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-write-return-validation</code> captures a synchronous ancestor-path error and unchanged terminal state; sandbox row assertion <code>rtdb-modular#120</code> matches both.</div></div>
696
783
  </details>
697
784
  </div>
698
785
 
@@ -753,9 +840,9 @@ tooling coverage and are not exports of `pyric/database`.
753
840
  <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">Unsubscribe — the returned unsubscribe function stops further fires; subsequent writes produce 0 additional fires after <code>unsub()</code></span></span></summary>
754
841
  <div class="compat-evidence"><div class="compat-probe">oracle: <code>packages/conformance/observations/rtdb-modular/rtdb-modular-onvalue-unsubscribe.json</code> — observed <code>preUnsubFires: 2, postUnsubFires: 2</code> (a write performed after <code>unsub()</code> produced 0 additional fires within a 500ms settle window).</div></div>
755
842
  </details>
756
- <details class="compat-row" data-status="unverified">
757
- <summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-behavior">The returned value from <code>onValue(ref, cb)</code> is the unsubscribe function (NOT an object); calling it removes the listener</span></span></summary>
758
- <div class="compat-evidence"><div class="compat-probe">upstream contract locked indirectly by #131</div></div>
843
+ <details class="compat-row" data-status="ok">
844
+ <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">The returned value from <code>onValue(ref, cb)</code> is the unsubscribe function (NOT an object); calling it removes the listener</span></span></summary>
845
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/listener-lifecycle-cdd.test.ts</code> asserts the return is a function and that invoking it stops subsequent delivery; production behavior is adjacent to oracle-backed row #131.</div></div>
759
846
  </details>
760
847
  </div>
761
848
 
@@ -763,8 +850,8 @@ tooling coverage and are not exports of `pyric/database`.
763
850
 
764
851
  <div class="compat-list">
765
852
  <details class="compat-row" data-status="ok">
766
- <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"><code>onChildAdded</code> replays the existing children on subscribe — one fire per existing child key, in <code>orderByKey</code> order by default (unlike <code>onValue</code> which fires once with the parent snapshot)</span></span></summary>
767
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>packages/conformance/observations/rtdb-modular/rtdb-modular-onchildadded-initial-replay.json</code> — seeded <code>{k1, k2, k3}</code>, observed 3 initial fires with <code>firedKeys: ['k1', 'k2', 'k3']</code> in insertion order against blockingfun.</div></div>
853
+ <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"><code>onChildAdded</code> replays the existing children on subscribe — one fire per existing child key, in the default priority index with key tie-breaking (unlike <code>onValue</code> which fires once with the parent snapshot)</span></span></summary>
854
+ <div class="compat-evidence"><div class="compat-probe">oracle: <code>packages/conformance/observations/rtdb-modular/rtdb-modular-onchildadded-initial-replay.json</code> — seeded <code>{k1, k2, k3}</code>, observed 3 initial fires with <code>firedKeys: ['k1', 'k2', 'k3']</code>; the default priority/key order is separately pinned by <code>rtdb-modular-priority-contract</code>.</div></div>
768
855
  </details>
769
856
  <details class="compat-row" data-status="ok">
770
857
  <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">After subscribe, adding a child via <code>push</code> or <code>set(child, …)</code> fires <code>onChildAdded</code> exactly once for that key</span></span></summary>
@@ -778,9 +865,9 @@ tooling coverage and are not exports of `pyric/database`.
778
865
  <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"><code>onChildRemoved</code> fires when a child is deleted (via <code>remove(child)</code> or <code>set(child, null)</code>); snapshot carries the PRIOR value</span></span></summary>
779
866
  <div class="compat-evidence"><div class="compat-probe">oracle: <code>packages/conformance/observations/rtdb-modular/rtdb-modular-onchildremoved-fires-on-delete.json</code> — observed <code>firedOnDelete: 1, removedSnapCarriesPriorValue: true</code> (snapshot.val() was the pre-delete value).</div></div>
780
867
  </details>
781
- <details class="compat-row" data-status="diverged">
782
- <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"><code>onChildMoved</code> under an ordered query. Prod: fires when a child's <code>orderByChild</code>/<code>orderByValue</code> priority changes — emitted only on ordered queries. Sandbox: <strong>never fires on reorder</strong> — <code>onChildMoved</code> supports the plain-ref (no-fire) case only; the ordered-query overload is unimplemented</span></span></summary>
783
- <div class="compat-evidence"><div class="compat-probe">divergence, oracle-locked by <code>packages/conformance/observations/rtdb-modular/rtdb-modular-onchildmoved-with-orderby.json</code>: prod observed <code>firedOnMove: 1</code> under <code>query(ref, orderByChild('priority'))</code> after bumping a child's priority to a new sort position; the sandbox fires 0 on reorder. Partial alignment landed: all <code>onChild*</code> now ACCEPT a <code>Query</code> (previously threw a misleading <code>unrecognized reference</code> TypeError) with window-aware <code>child_added</code>/<code>child_changed</code>/<code>child_removed</code> diffs (<code>src/database/sandbox/backend.ts</code>); the two hold-lifting captures now exist: <code>rtdb-modular-onchildmoved-previouschildname-sequencing</code> pins prev-name sequencing (end/middle/front reorders yield prev k3/k2/null, no initial replay) and <code>rtdb-modular-childchanged-cofire-with-childmoved</code> pins co-fire semantics (a reorder fires BOTH <code>child_changed</code> and <code>child_moved</code>; a non-ordered-field change fires neither moved; prod fires <code>child_moved</code> on an ordered-field value change EVEN WHEN RANK IS UNCHANGED). Implementation of ordered <code>child_moved</code> is unblocked. Both sides pinned in <code>modular/oracle-conformance.test.ts</code> and <code>modular/sandbox-child-events.test.ts</code>. Sandbox Tier 2 locks the plain-ref no-fire case (M46).</div></div>
868
+ <details class="compat-row" data-status="ok">
869
+ <summary class="compat-line"><span class="compat-dot" data-status="ok" role="img" aria-label="Conforming" title="Conforming"></span><span class="compat-main"><span class="compat-behavior"><code>onChildMoved</code> under an explicit ordered query fires when the ordered field changes, co-fires with <code>child_changed</code>, and supplies the captured <code>previousChildName</code>.</span></span></summary>
870
+ <div class="compat-evidence"><div class="compat-probe">Oracle observations <code>rtdb-modular-onchildmoved-with-orderby</code>, <code>rtdb-modular-onchildmoved-previouschildname-sequencing</code>, and <code>rtdb-modular-childchanged-cofire-with-childmoved</code> are replayed by the modular oracle suite.</div></div>
784
871
  </details>
785
872
  </div>
786
873
 
@@ -803,9 +890,9 @@ tooling coverage and are not exports of `pyric/database`.
803
890
  <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">The returned unsubscribe function from <code>onValue(ref, cb)</code> is equivalent to <code>off(ref, 'value', cb)</code></span></span></summary>
804
891
  <div class="compat-evidence"><div class="compat-probe">Sandbox aligned (M48); oracle: <code>packages/conformance/observations/rtdb/rtdb-onvalue-unsub-equivalence.json</code> — <code>unsubReturnType: 'function'</code>, <code>unsubReturnedFnStopsListener: true</code> (the captured return value halted fires on write), <code>offRefValueCbStopsListener: true</code> (the same effect via <code>off(ref, 'value', cb)</code>), <code>bothFormsEquivalent: true</code>.</div></div>
805
892
  </details>
806
- <details class="compat-row" data-status="unverified">
807
- <summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><code class="compat-api">off(ref, eventType, callback)</code><span class="compat-sub"><span class="compat-behavior">When the same callback is registered more than once, each <code>off(ref, eventType, callback)</code> removes one registration without orphaning the others</span></span></span></summary>
808
- <div class="compat-evidence"><div class="compat-probe">Pyric behavior is locked by <code>packages/pyric/test/app/multi-app-listener-auth.test.ts</code>; a production duplicate-registration oracle capture is still needed</div></div>
893
+ <details class="compat-row" data-status="ok">
894
+ <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">off(ref, eventType, callback)</code><span class="compat-sub"><span class="compat-behavior">When the same callback is registered more than once, each <code>off(ref, eventType, callback)</code> removes one registration without orphaning the others</span></span></span></summary>
895
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-off-duplicate-registration</code> proves each matching <code>off</code> removes one registration; sandbox row assertion <code>rtdb-modular#183</code> replays the full sequence.</div></div>
809
896
  </details>
810
897
  </div>
811
898
 
@@ -820,9 +907,9 @@ tooling coverage and are not exports of `pyric/database`.
820
907
  <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"><code>orderByKey()</code> orders by the auto-id / numeric key</span></span></summary>
821
908
  <div class="compat-evidence"><div class="compat-probe">oracle: <code>packages/conformance/observations/rtdb-modular/rtdb-modular-orderbykey-window.json</code> — seeded <code>{a,b,c,d,e}</code> in shuffled insertion order, observed <code>matchedKeys: ['b','c','d']</code> for <code>orderByKey() + startAt('b') + endAt('d')</code> (in key order).</div></div>
822
909
  </details>
823
- <details class="compat-row" data-status="ok">
824
- <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"><code>orderByValue()</code> orders by the primitive value of each child (for collections of primitives)</span></span></summary>
825
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>packages/conformance/observations/rtdb-modular/rtdb-modular-orderbyvalue-numeric.json</code> seeded <code>{alice:30, bob:10, carol:50, dave:20, eve:40}</code>, the prod call threw <code>Index not defined, add ".indexOn": ".value"</code> (so prod enforces an index requirement on <code>orderByValue()</code>); semantic ordering claim still holds, sandbox does not enforce indexes.</div></div>
910
+ <details class="compat-row" data-status="diverged">
911
+ <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">Production enforces <code>.indexOn: '.value'</code> for <code>orderByValue()</code> while the sandbox executes the value ordering without index enforcement</span></span></summary>
912
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-orderbyvalue-numeric</code> rejects the unindexed production query; <code>unit:modular/oracle-conformance-queries.test.ts</code> pins the sandbox's successful ordered result instead of treating that contradiction as conformance.</div></div>
826
913
  </details>
827
914
  <details class="compat-row" data-status="ok">
828
915
  <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"><code>equalTo(v)</code> filters children whose ordered field === v (returns 0, 1, or multiple matches — RTDB does NOT enforce uniqueness)</span></span></summary>
@@ -877,9 +964,9 @@ tooling coverage and are not exports of `pyric/database`.
877
964
  <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"><code>increment(n)</code> against an existing numeric field adds atomically; negative deltas subtract</span></span></summary>
878
965
  <div class="compat-evidence"><div class="compat-probe">Sandbox aligned: <code>unit:modular/increment.test.ts</code> ("subsequent increments accumulate (positive then negative)" + "nested inside an update patch resolves per-field"); matches oracle <code>packages/conformance/observations/rtdb-modular/rtdb-modular-increment-from-missing.json</code> — observed <code>afterSecond: 8</code> (5+3) then <code>afterNegative: 6</code> (8-2).</div></div>
879
966
  </details>
880
- <details class="compat-row" data-status="unverified">
881
- <summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-behavior">Two concurrent <code>increment</code> calls interleave correctly (last-write-wins is NOT the contract both deltas accumulate)</span></span></summary>
882
- <div class="compat-evidence"><div class="compat-probe">hard to observe deterministically from a single client; documented contract</div></div>
967
+ <details class="compat-row" data-status="diverged">
968
+ <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"><strong>Divergence:</strong> production interleaves concurrent <code>increment</code> writes from independent clients and preserves both deltas; the synchronous in-process backend applies each call before returning its promise, so a <code>Promise.all</code> call site is observably serialized even though its terminal value also reaches 5</span></span></summary>
969
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-concurrent-transforms</code> uses two independent clients and captures terminal 5 after concurrent +2/+3 increments; <code>unit:modular/transaction-contention-cdd.test.ts</code> pins the sandbox's synchronous first-write visibility and matching terminal value without claiming that terminal equality proves contention semantics.</div></div>
883
970
  </details>
884
971
  </div>
885
972
 
@@ -894,13 +981,13 @@ tooling coverage and are not exports of `pyric/database`.
894
981
  <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">Returning <code>undefined</code> from the update fn <strong>aborts</strong> the transaction — resolves <code>{ committed: false }</code>, no write performed (RTDB-specific; distinct from Firestore where the only abort path is throwing)</span></span></summary>
895
982
  <div class="compat-evidence"><div class="compat-probe">oracle: <code>packages/conformance/observations/rtdb-modular/rtdb-modular-runtransaction-abort-undefined.json</code> — seeded <code>100</code> then transaction returned <code>undefined</code>; observed <code>committed: false, snapVal: null, afterValOnServer: 100</code> (existing value preserved).</div></div>
896
983
  </details>
897
- <details class="compat-row" data-status="ok">
898
- <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">The update fn is called with the CURRENT server value (may be <code>null</code> if the ref is empty); the fn's return value is the proposed new value</span></span></summary>
899
- <div class="compat-evidence"><div class="compat-probe">oracle: <code>packages/conformance/observations/rtdb-modular/rtdb-modular-runtransaction-success.json</code> — observed <code>seenCurrentValues: [null]</code> on first invocation against an empty ref (a single call, no speculative re-runs against <code>undefined</code>). NOTE — adjacent divergence pinned in <code>modular/oracle-conformance.test.ts</code>: for a SEEDED path, prod speculatively invokes the update fn twice (first with <code>null</code>, then the real value; <code>rtdb-modular-runtransaction-current-value-arg.json</code> <code>seededArgs.length: 2</code>) while the sandbox invokes once with the actual value. The argument-semantics claim of this row holds for the effective invocation on both sides. WARNING for update-fn authors: prod may invoke your fn first with <code>null</code> even when data exists — the pattern <code>if (current === null) return;</code> (abort-on-empty) silently loses writes on prod while working on the sandbox, and side effects inside the fn can run twice on prod. RESOLVED by the warm-client capture <code>rtdb-modular-runtransaction-warm-client-speculation</code>: a warm prod client (active listener + prior get) receives a SINGLE invocation with the cached value, exactly matching the sandbox. The cold-cache speculative double-call is an artifact of an empty client cache, which the always-warm in-process sandbox structurally never has; the sandbox behavior IS the warm-client contract.</div></div>
984
+ <details class="compat-row" data-status="diverged">
985
+ <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">A cold production client can call the update fn with speculative <code>null</code> before the current seeded value; the always-warm sandbox calls it once with the current value</span></span></summary>
986
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-runtransaction-current-value-arg</code> captures the cold two-call sequence and <code>rtdb-modular-runtransaction-warm-client-speculation</code> captures the matching warm one-call case; <code>unit:modular/oracle-conformance-transactions.test.ts</code> pins both sides.</div></div>
900
987
  </details>
901
- <details class="compat-row" data-status="unverified">
902
- <summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-behavior">Concurrent contention — if another client writes between the read and write, the update fn is retried with the new current value (typically up to 25 retries by default)</span></span></summary>
903
- <div class="compat-evidence"><div class="compat-probe">hard to observe deterministically from a single client</div></div>
988
+ <details class="compat-row" data-status="diverged">
989
+ <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">Concurrent contention — if another client writes between the read and write, the update fn is retried with the new current value (typically up to 25 retries by default)</span></span></summary>
990
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-concurrent-transforms</code> captures callback counts [2, 3] across two clients; the synchronous in-process backend serializes the same ordinary calls with [1, 1], pinned by <code>unit:modular/transaction-contention-cdd.test.ts</code>.</div></div>
904
991
  </details>
905
992
  <details class="compat-row" data-status="ok">
906
993
  <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">Result snapshot's <code>.val()</code> reflects the committed value (or the existing value if aborted)</span></span></summary>
@@ -912,14 +999,14 @@ tooling coverage and are not exports of `pyric/database`.
912
999
 
913
1000
  <div class="compat-list">
914
1001
  <details class="compat-row" data-status="diverged">
915
- <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"><code>goOffline(db)</code> accepted no-op: there is no network connection in the local sandbox to toggle, so nothing is disconnected (we deliberately do NOT simulate a disconnect — pending writes, listeners, and <code>get()</code> keep working)</span></span></summary>
916
- <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/fruit-aliases.test.ts</code></div>
917
- <div class="compat-note">no network connection in the local sandbox to toggle</div></div>
1002
+ <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"><code>goOffline(db)</code> drains that client's onDisconnect queue once, but does not make the in-memory data plane unreachable; ordinary writes, listeners, and <code>get()</code> remain available</span></span></summary>
1003
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:database/on-disconnect.test.ts</code> + <code>unit:modular/fruit-aliases.test.ts</code></div>
1004
+ <div class="compat-note">logical disconnect lifecycle is modeled, but the in-memory data plane itself remains available</div></div>
918
1005
  </details>
919
1006
  <details class="compat-row" data-status="diverged">
920
- <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"><code>goOnline(db)</code> accepted no-op: there is no connection to reopen (see <code>goOffline</code>)</span></span></summary>
921
- <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/fruit-aliases.test.ts</code></div>
922
- <div class="compat-note">no network connection in the local sandbox to toggle</div></div>
1007
+ <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"><code>goOnline(db)</code> reconnects the logical lifecycle without resurrecting drained operations; it is otherwise a no-op because the in-memory data plane never became unreachable</span></span></summary>
1008
+ <div class="compat-evidence"><div class="compat-probe"><code>unit:database/on-disconnect.test.ts</code> + <code>unit:modular/fruit-aliases.test.ts</code></div>
1009
+ <div class="compat-note">logical disconnect lifecycle is modeled, but the in-memory data plane itself remains available</div></div>
923
1010
  </details>
924
1011
  </div>
925
1012
 
@@ -955,9 +1042,9 @@ tooling coverage and are not exports of `pyric/database`.
955
1042
  <div class="compat-note">accepted no-op; no sandbox logger to wire into</div></div>
956
1043
  </details>
957
1044
  <details class="compat-row" data-status="diverged">
958
- <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"><code>refFromURL(db, url)</code> real alias: parses the path out of the absolute database URL and delegates to <code>ref(db, path)</code>, so the returned ref resolves + reads exactly like <code>ref(db, path)</code>. Divergence: the sandbox is single-database with no host/namespace, so the URL's HOST is NOT validated against the handle (the real SDK throws if the host doesn't match the db's namespace); only the path is honored</span></span></summary>
959
- <div class="compat-evidence"><div class="compat-probe"><code>unit:modular/fruit-aliases.test.ts</code></div>
960
- <div class="compat-note">path resolves like <code>ref</code>; URL host/namespace not validated (single-database sandbox)</div></div>
1045
+ <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"><strong>Divergence:</strong> <code>refFromURL(db, url)</code> matches Firebase's path parsing, query ignoring, FTP-to-database normalization, and fragment rejection, but the single-database sandbox does not validate the URL host/namespace against the handle; Firebase rejects a mismatched host while the sandbox uses its path.</span></span></summary>
1046
+ <div class="compat-evidence"><div class="compat-probe">Oracle <code>rtdb-modular-reference-shape-url</code> captures accepted FTP/query URLs and rejected fragments, malformed URLs, and host mismatches; <code>unit:modular/oracle-conformance-reference-writes.test.ts</code> pins the conforming validations plus both sides of the host divergence.</div>
1047
+ <div class="compat-note">path and validation behavior conform except URL host/namespace matching (single-database sandbox)</div></div>
961
1048
  </details>
962
1049
  </div>
963
1050
 
@@ -970,22 +1057,36 @@ Known differences between Pyric and production Firebase. Each remains tracked as
970
1057
  <div class="compat-list">
971
1058
  <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">simulateRtdbRules(compiled, input)</code><span class="compat-sub"><span class="compat-behavior">Cross-path <code>root.child(…).val()</code> reads return <code>null</code> for paths NOT present in <code>mockData</code> — divergence from real prod rules where the engine reads the live database</span></span></span></summary>
972
1059
  <div class="compat-evidence"><div class="compat-note">divergence: the simulator uses ONLY what's in <code>mockData</code>. Real rules engine reads from the live RTDB. Documented in <code>validated.ts</code> ("simulation uses empty mockData, so cross-path rule lookups … will evaluate as false")</div></div></details>
973
- <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">**Divergence (DB-B12, honest doc):** the onChild* callbacks do NOT receive the <code>previousChildName</code> second argument; <code>onValue</code>/<code>onChild*</code> do NOT accept a <code>cancelCallback</code>; <code>onChildAdded</code>/<code>Changed</code>/<code>Removed</code>/<code>Moved</code> accept only plain refs (not <code>Query</code>); <code>child_moved</code> never fires (ordered-query move detection unmodeled). These listener-surface holes are out of scope for the current phase — consumers needing them use <code>firebase/database</code> directly.</span></span></span></summary>
974
- <div class="compat-evidence"><div class="compat-note">divergence documented; partial coverage: <code>{ onlyOnce }</code> IS implemented (M74).</div></div></details>
975
- <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"><code>onChildMoved</code> under an ordered query. Prod: fires when a child's <code>orderByChild</code>/<code>orderByValue</code> priority changes emitted only on ordered queries. Sandbox: **never fires on reorder** <code>onChildMoved</code> supports the plain-ref (no-fire) case only; the ordered-query overload is unimplemented</span></span></span></summary>
976
- <div class="compat-evidence"><div class="compat-note">divergence, oracle-locked by <code>packages/conformance/observations/rtdb-modular/rtdb-modular-onchildmoved-with-orderby.json</code>: prod observed <code>firedOnMove: 1</code> under <code>query(ref, orderByChild('priority'))</code> after bumping a child's priority to a new sort position; the sandbox fires 0 on reorder. Partial alignment landed: all <code>onChild*</code> now ACCEPT a <code>Query</code> (previously threw a misleading <code>unrecognized reference</code> TypeError) with window-aware <code>child_added</code>/<code>child_changed</code>/<code>child_removed</code> diffs (<code>src/database/sandbox/backend.ts</code>); the two hold-lifting captures now exist: <code>rtdb-modular-onchildmoved-previouschildname-sequencing</code> pins prev-name sequencing (end/middle/front reorders yield prev k3/k2/null, no initial replay) and <code>rtdb-modular-childchanged-cofire-with-childmoved</code> pins co-fire semantics (a reorder fires BOTH <code>child_changed</code> and <code>child_moved</code>; a non-ordered-field change fires neither moved; prod fires <code>child_moved</code> on an ordered-field value change EVEN WHEN RANK IS UNCHANGED). Implementation of ordered <code>child_moved</code> is unblocked. Both sides pinned in <code>modular/oracle-conformance.test.ts</code> and <code>modular/sandbox-child-events.test.ts</code>. Sandbox Tier 2 locks the plain-ref no-fire case (M46).</div></div></details>
977
- <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"><code>goOffline(db)</code> accepted no-op: there is no network connection in the local sandbox to toggle, so nothing is disconnected (we deliberately do NOT simulate a disconnect — pending writes, listeners, and <code>get()</code> keep working)</span></span></span></summary>
978
- <div class="compat-evidence"><div class="compat-note"><code>unit:modular/fruit-aliases.test.ts</code></div></div></details>
979
- <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"><code>goOnline(db)</code> accepted no-op: there is no connection to reopen (see <code>goOffline</code>)</span></span></span></summary>
980
- <div class="compat-evidence"><div class="compat-note"><code>unit:modular/fruit-aliases.test.ts</code></div></div></details>
1060
+ <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">Cold production clients may invoke the update fn first with speculative <code>null</code> and then with the current seeded value; the always-warm in-process sandbox invokes it once with the current value</span></span></span></summary>
1061
+ <div class="compat-evidence"><div class="compat-note">Oracle <code>rtdb-modular-runtransaction-current-value-arg</code> captures two seeded-path production invocations (<code>null</code>, then current); <code>unit:modular/oracle-conformance-transactions.test.ts</code> pins the sandbox's single current-value invocation. The separate warm-client observation matches the sandbox but does not erase the cold-client contract.</div></div></details>
1062
+ <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">**Divergence:** two ordinary concurrent <code>runTransaction</code> calls are serialized by the in-process backend, so their update functions are not retried with Firebase's captured contention counts. A synchronous re-entrant conflicting write does trigger a deterministic retry.</span></span></span></summary>
1063
+ <div class="compat-evidence"><div class="compat-note">Oracle <code>rtdb-modular-concurrent-transforms</code> captures invocation counts [2, 3]; <code>unit:modular/transaction-contention-cdd.test.ts</code> pins the sandbox's [1, 1] ordinary-concurrency boundary and separately covers its deterministic re-entrant retry seam.</div></div></details>
1064
+ <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">Production rejects an unindexed <code>orderByValue() + limitToFirst(N)</code> query; the sandbox does not enforce <code>.indexOn</code> and returns the N smallest primitive values</span></span></span></summary>
1065
+ <div class="compat-evidence"><div class="compat-note">Oracle <code>rtdb-modular-orderbyvalue-numeric</code> captures production's <code>Index not defined</code> rejection; <code>unit:modular/oracle-conformance-queries.test.ts</code> pins that rejection beside the sandbox's successful <code>[10,20,30]</code> window.</div></div></details>
1066
+ <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">**Divergence (pending fix):** clean <code>goOffline</code>, app deletion, playground <code>pagehide</code>, and best-effort MessagePort close drain queued operations, but unannounced total renderer/process loss is not guaranteed by the in-memory sandbox</span></span></span></summary>
1067
+ <div class="compat-evidence"><div class="compat-note">Oracle <code>rtdb-modular-ondisconnect-abrupt-exit</code> proves Firebase executes an acknowledged registration after forced writer termination. The two-port worker integration exercises <code>goOffline</code>, served-app deletion, and non-persisted <code>pagehide</code>; browser MessagePort close delivery cannot prove total-process loss without durable host-owned leases.</div></div></details>
1068
+ <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">**Divergence:** <code>DatabaseReference</code> and <code>Query</code> equality includes database target, path, and canonical query parameters like Firebase, but <code>toJSON()</code> serializes the local <code>sandbox://rtdb/...</code> identity instead of Firebase's HTTPS database URL.</span></span></span></summary>
1069
+ <div class="compat-evidence"><div class="compat-note">Oracle <code>rtdb-modular-reference-shape-url</code> captures conforming equality plus HTTPS JSON serialization; <code>unit:modular/oracle-conformance-reference-writes.test.ts</code> pins both the production HTTPS shape and the sandbox's <code>sandbox://</code> boundary.</div></div></details>
1070
+ <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">Production enforces <code>.indexOn: '.value'</code> for <code>orderByValue()</code> while the sandbox executes the value ordering without index enforcement</span></span></span></summary>
1071
+ <div class="compat-evidence"><div class="compat-note">Oracle <code>rtdb-modular-orderbyvalue-numeric</code> rejects the unindexed production query; <code>unit:modular/oracle-conformance-queries.test.ts</code> pins the sandbox's successful ordered result instead of treating that contradiction as conformance.</div></div></details>
1072
+ <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">**Divergence:** production interleaves concurrent <code>increment</code> writes from independent clients and preserves both deltas; the synchronous in-process backend applies each call before returning its promise, so a <code>Promise.all</code> call site is observably serialized even though its terminal value also reaches 5</span></span></span></summary>
1073
+ <div class="compat-evidence"><div class="compat-note">Oracle <code>rtdb-modular-concurrent-transforms</code> uses two independent clients and captures terminal 5 after concurrent +2/+3 increments; <code>unit:modular/transaction-contention-cdd.test.ts</code> pins the sandbox's synchronous first-write visibility and matching terminal value without claiming that terminal equality proves contention semantics.</div></div></details>
1074
+ <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">A cold production client can call the update fn with speculative <code>null</code> before the current seeded value; the always-warm sandbox calls it once with the current value</span></span></span></summary>
1075
+ <div class="compat-evidence"><div class="compat-note">Oracle <code>rtdb-modular-runtransaction-current-value-arg</code> captures the cold two-call sequence and <code>rtdb-modular-runtransaction-warm-client-speculation</code> captures the matching warm one-call case; <code>unit:modular/oracle-conformance-transactions.test.ts</code> pins both sides.</div></div></details>
1076
+ <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">Concurrent contention — if another client writes between the read and write, the update fn is retried with the new current value (typically up to 25 retries by default)</span></span></span></summary>
1077
+ <div class="compat-evidence"><div class="compat-note">Oracle <code>rtdb-modular-concurrent-transforms</code> captures callback counts [2, 3] across two clients; the synchronous in-process backend serializes the same ordinary calls with [1, 1], pinned by <code>unit:modular/transaction-contention-cdd.test.ts</code>.</div></div></details>
1078
+ <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"><code>goOffline(db)</code> drains that client's onDisconnect queue once, but does not make the in-memory data plane unreachable; ordinary writes, listeners, and <code>get()</code> remain available</span></span></span></summary>
1079
+ <div class="compat-evidence"><div class="compat-note"><code>unit:database/on-disconnect.test.ts</code> + <code>unit:modular/fruit-aliases.test.ts</code></div></div></details>
1080
+ <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"><code>goOnline(db)</code> reconnects the logical lifecycle without resurrecting drained operations; it is otherwise a no-op because the in-memory data plane never became unreachable</span></span></span></summary>
1081
+ <div class="compat-evidence"><div class="compat-note"><code>unit:database/on-disconnect.test.ts</code> + <code>unit:modular/fruit-aliases.test.ts</code></div></div></details>
981
1082
  <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"><code>forceLongPolling()</code> — accepted no-op: transport selection is not applicable to the in-process/worker sandbox (it never opens a real socket). Accepted so init code that calls it compiles + runs</span></span></span></summary>
982
1083
  <div class="compat-evidence"><div class="compat-note"><code>unit:modular/fruit-aliases.test.ts</code></div></div></details>
983
1084
  <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"><code>forceWebSockets()</code> — accepted no-op: transport selection is not applicable to the in-process/worker sandbox (see <code>forceLongPolling</code>)</span></span></span></summary>
984
1085
  <div class="compat-evidence"><div class="compat-note"><code>unit:modular/fruit-aliases.test.ts</code></div></div></details>
985
1086
  <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"><code>enableLogging(logger?, persistent?)</code> — accepted no-op: the sandbox has no modular-SDK-style logger to wire a level/sink into (it uses host-level <code>console</code> logging directly, matching <code>pyric/firestore</code>'s <code>setLogLevel</code>). Accepted so init code that calls it compiles + runs</span></span></span></summary>
986
1087
  <div class="compat-evidence"><div class="compat-note"><code>unit:modular/fruit-aliases.test.ts</code></div></div></details>
987
- <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"><code>refFromURL(db, url)</code> real alias: parses the path out of the absolute database URL and delegates to <code>ref(db, path)</code>, so the returned ref resolves + reads exactly like <code>ref(db, path)</code>. Divergence: the sandbox is single-database with no host/namespace, so the URL's HOST is NOT validated against the handle (the real SDK throws if the host doesn't match the db's namespace); only the path is honored</span></span></span></summary>
988
- <div class="compat-evidence"><div class="compat-note"><code>unit:modular/fruit-aliases.test.ts</code></div></div></details>
1088
+ <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">**Divergence:** <code>refFromURL(db, url)</code> matches Firebase's path parsing, query ignoring, FTP-to-database normalization, and fragment rejection, but the single-database sandbox does not validate the URL host/namespace against the handle; Firebase rejects a mismatched host while the sandbox uses its path.</span></span></span></summary>
1089
+ <div class="compat-evidence"><div class="compat-note">Oracle <code>rtdb-modular-reference-shape-url</code> captures accepted FTP/query URLs and rejected fragments, malformed URLs, and host mismatches; <code>unit:modular/oracle-conformance-reference-writes.test.ts</code> pins the conforming validations plus both sides of the host divergence.</div></div></details>
989
1090
  </div>
990
1091
 
991
1092
  ### Not implemented yet
@@ -1029,71 +1130,8 @@ Tracked behavior that is not implemented in the current contract.
1029
1130
  <div class="compat-evidence"><div class="compat-note">The stateless <code>simulateRtdbRules(compiled, input)</code> API requires a compiled rules tree and has no generate-before-simulate lifecycle.</div></div></details>
1030
1131
  <details class="compat-row" data-status="unsupported"><summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior">An in-module production target is intentionally absent; direct calls with a real <code>FirebaseApp</code> reject with package-resolution guidance</span></span></span></summary>
1031
1132
  <div class="compat-evidence"><div class="compat-note"><code>unit:modular.test.ts</code>; production remains the responsibility of the unchanged <code>firebase/database</code> package</div></div></details>
1032
- <details class="compat-row" data-status="unsupported"><summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior">Concurrent contention / retry-on-conflict — single-client sandbox doesn't model real concurrency; the documented "up to 25 retries" contract is degenerate (the fn is invoked once)</span></span></span></summary>
1033
- <div class="compat-evidence"><div class="compat-note">matrix #161 documents the same gap on the spec side; oracle observation hard to obtain from a single client (oracle row stays <code>?</code>)</div></div></details>
1034
- <details class="compat-row" data-status="unsupported"><summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior"><code>getDatabase(ctx)</code> returns a tagged sandbox-target handle (frozen identity)</span></span></span></summary>
1035
- <div class="compat-evidence"><div class="compat-note">Phase 3</div></div></details>
1036
- <details class="compat-row" data-status="unsupported"><summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior"><code>getDatabase(sandbox)</code> returns a tagged sandbox-live handle (per-op identity)</span></span></span></summary>
1037
- <div class="compat-evidence"><div class="compat-note">Phase 3</div></div></details>
1038
- <details class="compat-row" data-status="unsupported"><summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior">Two <code>getDatabase(sandbox)</code> calls share state (same underlying <code>LocalEnvironment</code>)</span></span></span></summary>
1039
- <div class="compat-evidence"><div class="compat-note">Phase 3</div></div></details>
1040
- <details class="compat-row" data-status="unsupported"><summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior">Handle dispatch by <code>TARGET_SYMBOL</code> brand — refs route to their owning target via a <code>refToTarget</code> WeakMap (mirror of firestore's pattern)</span></span></span></summary>
1041
- <div class="compat-evidence"><div class="compat-note">Phase 3</div></div></details>
1042
- <details class="compat-row" data-status="unsupported"><summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior">Unknown ref (not produced by this package) → <code>TypeError</code> in shim ops</span></span></span></summary>
1043
- <div class="compat-evidence"><div class="compat-note">Phase 3</div></div></details>
1044
1133
  <details class="compat-row" data-status="unsupported"><summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior">No-op on sandbox-target handles (the sandbox IS the local emulator)</span></span></span></summary>
1045
1134
  <div class="compat-evidence"><div class="compat-note">Phase 3</div></div></details>
1046
1135
  <details class="compat-row" data-status="unsupported"><summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior">A production target is intentionally absent; production code continues to use <code>connectDatabaseEmulator</code> from the unchanged <code>firebase/database</code> package</span></span></span></summary>
1047
1136
  <div class="compat-evidence"><div class="compat-note">Phase 3</div></div></details>
1048
1137
  </div>
1049
-
1050
- ### Unverified
1051
-
1052
- Tracked behavior whose available evidence does not yet establish the production result.
1053
-
1054
- <div class="compat-list">
1055
- <details class="compat-row" data-status="unverified"><summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior">Inactive canonical <code>firebase/database</code> imports remain the upstream package; the mirror does not create tagged production targets</span></span></span></summary>
1056
- <div class="compat-evidence"><div class="compat-note">package-resolution boundary; inactive RTDB canonical-import isolation is not yet claimed by this row</div></div></details>
1057
- <details class="compat-row" data-status="unverified"><summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior"><code>ref(db, path)</code> returns a tagged <code>DatabaseReference</code> carrying <code>key</code>, <code>parent</code>, <code>root</code>, <code>toString()</code></span></span></span></summary>
1058
- <div class="compat-evidence"><div class="compat-note">upstream <code>firebase/database</code> contract</div></div></details>
1059
- <details class="compat-row" data-status="unverified"><summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior"><code>ref(db)</code> with no path returns the root ref (<code>key === null</code>, <code>parent === null</code>)</span></span></span></summary>
1060
- <div class="compat-evidence"><div class="compat-note">upstream contract</div></div></details>
1061
- <details class="compat-row" data-status="unverified"><summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior"><code>child(ref, 'a/b')</code> joins a relative path, including embedded slashes</span></span></span></summary>
1062
- <div class="compat-evidence"><div class="compat-note">upstream contract</div></div></details>
1063
- <details class="compat-row" data-status="unverified"><summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior"><code>ref.parent</code> is <code>null</code> at root, otherwise the parent ref</span></span></span></summary>
1064
- <div class="compat-evidence"><div class="compat-note">upstream contract</div></div></details>
1065
- <details class="compat-row" data-status="unverified"><summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior"><code>ref.key</code> is the final path segment, <code>null</code> for root</span></span></span></summary>
1066
- <div class="compat-evidence"><div class="compat-note">upstream contract</div></div></details>
1067
- <details class="compat-row" data-status="unverified"><summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior">Replaces the value at the path entirely; resolves to <code>undefined</code> (unlike <code>setDoc</code> which resolves to <code>void</code>, RTDB's <code>set</code> is documented as <code>Promise&lt;void&gt;</code>)</span></span></span></summary>
1068
- <div class="compat-evidence"><div class="compat-note">upstream contract</div></div></details>
1069
- <details class="compat-row" data-status="unverified"><summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior">Update path validation — overlapping paths (e.g. <code>'/a'</code> and <code>'/a/x'</code> in the same call) throws synchronously before any write</span></span></span></summary>
1070
- <div class="compat-evidence"><div class="compat-note">upstream contract — needs targeted probe</div></div></details>
1071
- <details class="compat-row" data-status="unverified"><summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior">The returned value from <code>onValue(ref, cb)</code> is the unsubscribe function (NOT an object); calling it removes the listener</span></span></span></summary>
1072
- <div class="compat-evidence"><div class="compat-note">upstream contract — locked indirectly by #131</div></div></details>
1073
- <details class="compat-row" data-status="unverified"><summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><code class="compat-api">off(ref, eventType, callback)</code><span class="compat-sub"><span class="compat-behavior">When the same callback is registered more than once, each <code>off(ref, eventType, callback)</code> removes one registration without orphaning the others</span></span></span></summary>
1074
- <div class="compat-evidence"><div class="compat-note">Pyric behavior is locked by <code>packages/pyric/test/app/multi-app-listener-auth.test.ts</code>; a production duplicate-registration oracle capture is still needed</div></div></details>
1075
- <details class="compat-row" data-status="unverified"><summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior">Two concurrent <code>increment</code> calls interleave correctly (last-write-wins is NOT the contract — both deltas accumulate)</span></span></span></summary>
1076
- <div class="compat-evidence"><div class="compat-note">hard to observe deterministically from a single client; documented contract</div></div></details>
1077
- <details class="compat-row" data-status="unverified"><summary class="compat-line"><span class="compat-dot" data-status="unverified" role="img" aria-label="Unverified" title="Unverified"></span><span class="compat-main"><span class="compat-sub"><span class="compat-behavior">Concurrent contention — if another client writes between the read and write, the update fn is retried with the new current value (typically up to 25 retries by default)</span></span></span></summary>
1078
- <div class="compat-evidence"><div class="compat-note">hard to observe deterministically from a single client</div></div></details>
1079
- </div>
1080
-
1081
- ## Reviewed public-runtime gaps
1082
-
1083
- <div class="compat-list">
1084
- <details class="compat-row" data-status="unsupported">
1085
- <summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><code class="compat-api">database.runtime-class-values</code><span class="compat-sub"><span class="compat-behavior">These Firebase classes are mirrored structurally in Pyric's type surface but are not exported as runtime constructor values; runtime identity remains unbuilt.</span></span></span></summary>
1086
- <div class="compat-evidence"><div class="compat-note"><code>DataSnapshot</code> <code>Database</code> <code>QueryConstraint</code> <code>TransactionResult</code></div>
1087
- <div class="compat-note">upstream:firebase/database</div></div>
1088
- </details>
1089
- <details class="compat-row" data-status="unsupported">
1090
- <summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><code class="compat-api">database.connection-lifecycle</code><span class="compat-sub"><span class="compat-behavior">onDisconnect requires a live connection lifecycle the in-memory sandbox has no equivalent for today — buildable as an honest no-op or inert token like the connection-management APIs, not genuinely un-modelable.</span></span></span></summary>
1091
- <div class="compat-evidence"><div class="compat-note"><code>OnDisconnect</code> <code>onDisconnect</code></div>
1092
- <div class="compat-note">registry:rtdb-modular#163</div></div>
1093
- </details>
1094
- <details class="compat-row" data-status="unsupported">
1095
- <summary class="compat-line"><span class="compat-dot" data-status="unsupported" role="img" aria-label="Not implemented yet" title="Not implemented yet"></span><span class="compat-main"><code class="compat-api">database.priority-ordering</code><span class="compat-sub"><span class="compat-behavior">Firebase's legacy priority ordering system is absent; the sandbox exposes orderByChild/Key/Value only today. Priority ordering is data-modelable as a sort key, so this is revisitable scope rather than a hard sandbox limitation.</span></span></span></summary>
1096
- <div class="compat-evidence"><div class="compat-note"><code>orderByPriority</code> <code>setPriority</code> <code>setWithPriority</code></div>
1097
- <div class="compat-note">upstream:firebase/database</div></div>
1098
- </details>
1099
- </div>