@pyric/cli 0.1.0-alpha.14 → 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 (599) 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 +207 -284
  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 +2 -18
  79. package/dist/serve/bundler.d.ts.map +1 -1
  80. package/dist/serve/bundler.js +7 -35
  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-replacement.d.ts +1 -2
  105. package/dist/serve/runtime/worker-replacement.d.ts.map +1 -1
  106. package/dist/serve/sandbox-session.d.ts +78 -0
  107. package/dist/serve/sandbox-session.d.ts.map +1 -0
  108. package/dist/serve/sandbox-session.js +171 -0
  109. package/dist/serve/sandbox-session.js.map +1 -0
  110. package/dist/serve/server.d.ts +5 -2
  111. package/dist/serve/server.d.ts.map +1 -1
  112. package/dist/serve/server.js +21 -5
  113. package/dist/serve/server.js.map +1 -1
  114. package/dist/serve/site-tree.d.ts +8 -0
  115. package/dist/serve/site-tree.d.ts.map +1 -0
  116. package/dist/serve/site-tree.js +113 -0
  117. package/dist/serve/site-tree.js.map +1 -0
  118. package/dist/serve/site-ui/_astro/RulesCodeEditor.CzwHdCi9.js +23 -0
  119. package/dist/serve/site-ui/_astro/_example_.jevZ7OdV.css +1 -0
  120. package/dist/serve/site-ui/_astro/_slug_.BoKXYrnu.css +1 -0
  121. package/dist/serve/site-ui/_astro/_studio_.BtYpqe1A.css +1 -0
  122. package/dist/serve/site-ui/_astro/app.BnMC0ywl.js +109 -0
  123. package/dist/serve/site-ui/_astro/app.BsFsMjn0.css +1 -0
  124. package/dist/serve/site-ui/_astro/app.DVXXR-WI.js +1 -0
  125. package/dist/serve/site-ui/_astro/chess-showcase.DzPO6kz0.js +1 -0
  126. package/dist/serve/site-ui/_astro/chess-source-explorer.C5k9c5yK.js +1 -0
  127. package/dist/serve/site-ui/_astro/chess-v2.CFHmd3UL.js +354 -0
  128. package/dist/serve/site-ui/_astro/client.D2ORs4B-.js +25 -0
  129. package/dist/serve/site-ui/_astro/example-runtime.CM0H02rx.js +291 -0
  130. package/dist/serve/site-ui/_astro/index.B4Kh80he.js +1 -0
  131. package/dist/serve/site-ui/_astro/index.DBy5LfQW.js +9 -0
  132. package/dist/serve/site-ui/_astro/index.DNyk7q8W.js +9 -0
  133. package/dist/serve/site-ui/_astro/jsx-runtime.D_zvdyIk.js +9 -0
  134. package/dist/serve/site-ui/_astro/reads.D1exkX1-.js +1 -0
  135. package/dist/serve/site-ui/_astro/sandbox-controls.BqMePr5V.js +1153 -0
  136. package/dist/serve/site-ui/_astro/seed.BCn5DhHS.js +20 -0
  137. package/dist/serve/site-ui/auth/index.html +11 -0
  138. package/dist/serve/site-ui/docs/_rhythm/index.html +100 -0
  139. package/dist/serve/site-ui/docs/agent/set-up-your-agent/index.html +43 -0
  140. package/dist/serve/site-ui/docs/agent/watch-and-review/index.html +26 -0
  141. package/dist/serve/site-ui/docs/agent/work-with-an-agent/index.html +70 -0
  142. package/dist/serve/{docs-ui → site-ui}/docs/ai-compat/index.html +3 -3
  143. package/dist/serve/site-ui/docs/api-reference/index.html +68 -0
  144. package/dist/serve/{docs-ui → site-ui}/docs/app-compat/index.html +3 -3
  145. package/dist/serve/{docs-ui → site-ui}/docs/auth-compat/index.html +3 -3
  146. package/dist/serve/site-ui/docs/build/ai-logic/index.html +64 -0
  147. package/dist/serve/site-ui/docs/build/authentication/index.html +66 -0
  148. package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +84 -0
  149. package/dist/serve/site-ui/docs/build/cloud-messaging/index.html +71 -0
  150. package/dist/serve/site-ui/docs/build/cloud-storage/index.html +66 -0
  151. package/dist/serve/{docs-ui → site-ui}/docs/build/cloud-storage.md +2 -2
  152. package/dist/serve/site-ui/docs/build/realtime-database/index.html +67 -0
  153. package/dist/serve/site-ui/docs/conformance-scores/index.html +50 -0
  154. package/dist/serve/{docs-ui → site-ui}/docs/conformance-scores.md +3 -3
  155. package/dist/serve/site-ui/docs/create-pyric-reference-api/index.html +531 -0
  156. package/dist/serve/{docs-ui → site-ui}/docs/database-compat/index.html +211 -168
  157. package/dist/serve/{docs-ui → site-ui}/docs/database-compat.md +208 -170
  158. package/dist/serve/site-ui/docs/examples/chess/index.html +384 -0
  159. package/dist/serve/site-ui/docs/examples/chess.md +57 -0
  160. package/dist/serve/site-ui/docs/examples/index.html +3 -0
  161. package/dist/serve/site-ui/docs/examples.md +4 -0
  162. package/dist/serve/{docs-ui → site-ui}/docs/firestore-compat/index.html +55 -91
  163. package/dist/serve/{docs-ui → site-ui}/docs/firestore-compat.md +52 -88
  164. package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +73 -0
  165. package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +29 -0
  166. package/dist/serve/site-ui/docs/get-started/start-building/index.html +33 -0
  167. package/dist/serve/{docs-ui → site-ui}/docs/index.json +595 -26
  168. package/dist/serve/site-ui/docs/messaging-compat/index.html +324 -0
  169. package/dist/serve/{docs-ui → site-ui}/docs/messaging-compat.md +71 -1
  170. package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +28 -0
  171. package/dist/serve/site-ui/docs/observe/see-whats-happening/index.html +74 -0
  172. package/dist/serve/site-ui/docs/observe/shape-your-data/index.html +45 -0
  173. package/dist/serve/site-ui/docs/overview/index.html +17 -0
  174. package/dist/serve/site-ui/docs/pyric-admin-app-reference-api/index.html +186 -0
  175. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-auth-reference-api/index.html +4 -4
  176. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-database-reference-api/index.html +4 -4
  177. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-firestore-reference-api/index.html +318 -202
  178. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-firestore-reference-api.md +154 -27
  179. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-messaging-reference-api/index.html +5 -5
  180. package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api/index.html +318 -0
  181. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ai-reference-api/index.html +5 -5
  182. package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +160 -0
  183. package/dist/serve/site-ui/docs/pyric-app-reference-api/index.html +425 -0
  184. package/dist/serve/{docs-ui → site-ui}/docs/pyric-auth-reference-api/index.html +5 -5
  185. package/dist/serve/site-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +60 -0
  186. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-assurance-reference-api/index.html +4 -4
  187. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-bridge-client-reference-api/index.html +4 -4
  188. package/dist/serve/site-ui/docs/pyric-cli-bridge-reference-api/index.html +507 -0
  189. package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +258 -0
  190. package/dist/serve/site-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +51 -0
  191. package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api/index.html +308 -0
  192. package/dist/serve/site-ui/docs/pyric-cli-credentials-node-reference-api/index.html +68 -0
  193. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-discover-reference-api/index.html +4 -4
  194. package/dist/serve/site-ui/docs/pyric-cli-register-reference-api/index.html +11 -0
  195. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-remote-reference-api/index.html +4 -4
  196. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-serve-worker-reference-api/index.html +1186 -1384
  197. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-serve-worker-reference-api.md +817 -1291
  198. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-verify-reference-api/index.html +4 -4
  199. package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api/index.html +126 -0
  200. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-vite-reference-api.md +1 -1
  201. package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +2641 -0
  202. package/dist/serve/{docs-ui → site-ui}/docs/pyric-database-reference-api.md +1055 -158
  203. package/dist/serve/{docs-ui → site-ui}/docs/pyric-firestore-reference-api/index.html +311 -249
  204. package/dist/serve/{docs-ui → site-ui}/docs/pyric-firestore-reference-api.md +72 -54
  205. package/dist/serve/site-ui/docs/pyric-messaging-reference-api/index.html +509 -0
  206. package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api/index.html +182 -0
  207. package/dist/serve/{docs-ui → site-ui}/docs/pyric-rules-reference-api/index.html +7 -26
  208. package/dist/serve/{docs-ui → site-ui}/docs/pyric-rules-reference-api.md +13 -23
  209. package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api/index.html +121 -0
  210. package/dist/serve/site-ui/docs/pyric-sandbox-firestore-reference-api/index.html +203 -0
  211. package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-reference-api/index.html +26 -5
  212. package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-reference-api.md +22 -22
  213. package/dist/serve/{docs-ui → site-ui}/docs/pyric-storage-reference-api/index.html +5 -15
  214. package/dist/serve/{docs-ui → site-ui}/docs/pyric-storage-reference-api.md +0 -13
  215. package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api/index.html +639 -0
  216. package/dist/serve/site-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +100 -0
  217. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-auth-reference-api/index.html +4 -4
  218. package/dist/serve/site-ui/docs/pyric-ui-events-hooks-reference-api/index.html +24 -0
  219. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-events-reference-api/index.html +4 -4
  220. package/dist/serve/site-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +136 -0
  221. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-firestore-reference-api/index.html +7 -7
  222. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-firestore-reference-api.md +4 -4
  223. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-primitives-reference-api/index.html +4 -4
  224. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rtdb-reference-api/index.html +4 -4
  225. package/dist/serve/site-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +16 -0
  226. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rules-reference-api/index.html +4 -4
  227. package/dist/serve/site-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +176 -0
  228. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-storage-reference-api/index.html +10 -11
  229. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-storage-reference-api.md +7 -8
  230. package/dist/serve/site-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +188 -0
  231. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-traffic-reference-api/index.html +4 -4
  232. package/dist/serve/{docs-ui → site-ui}/docs/rules-compat/index.html +87 -57
  233. package/dist/serve/{docs-ui → site-ui}/docs/rules-compat.md +84 -54
  234. package/dist/serve/site-ui/docs/secure/audit-your-rules/index.html +51 -0
  235. package/dist/serve/site-ui/docs/secure/firestore-rules-limits/index.html +106 -0
  236. package/dist/serve/site-ui/docs/secure/read-a-denial/index.html +41 -0
  237. package/dist/serve/site-ui/docs/secure/rtdb-rules-in-typescript/index.html +67 -0
  238. package/dist/serve/site-ui/docs/secure/rules-standard-library/index.html +159 -0
  239. package/dist/serve/{docs-ui → site-ui}/docs/secure/rules-standard-library.md +2 -2
  240. package/dist/serve/site-ui/docs/secure/secure-it-with-rules/index.html +47 -0
  241. package/dist/serve/site-ui/docs/secure/simulate-and-lint/index.html +95 -0
  242. package/dist/serve/site-ui/docs/secure/write-a-rules-test-suite/index.html +82 -0
  243. package/dist/serve/site-ui/docs/ship/ship-to-production/index.html +37 -0
  244. package/dist/serve/site-ui/docs/ship/test-in-node/index.html +75 -0
  245. package/dist/serve/{docs-ui → site-ui}/docs/storage-compat/index.html +8 -8
  246. package/dist/serve/{docs-ui → site-ui}/docs/storage-compat.md +5 -5
  247. package/dist/serve/site-ui/docs/trust/how-we-know-it-matches-firebase/index.html +132 -0
  248. package/dist/serve/site-ui/docs/trust/rules-standard-library/index.html +861 -0
  249. package/dist/serve/site-ui/docs/trust/rules-standard-library.md +344 -0
  250. package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research/index.html +582 -0
  251. package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research.md +448 -0
  252. package/dist/serve/site-ui/docs/trust/versioning-and-compatibility/index.html +14 -0
  253. package/dist/serve/{docs-ui → site-ui}/docs/tutorial/index.html +4 -4
  254. package/dist/serve/{docs-ui → site-ui}/docs/tutorial.md +1 -1
  255. package/dist/serve/site-ui/examples/chess/index.html +2 -0
  256. package/dist/serve/site-ui/examples/firestore-first-write/index.html +2 -0
  257. package/dist/serve/site-ui/firestore/index.html +11 -0
  258. package/dist/serve/site-ui/index.html +11 -0
  259. package/dist/serve/{docs-ui → site-ui}/llms.txt +6 -2
  260. package/dist/serve/site-ui/rtdb/index.html +11 -0
  261. package/dist/serve/site-ui/settings/index.html +11 -0
  262. package/dist/serve/site-ui/storage/index.html +11 -0
  263. package/dist/serve/site-ui/studio-routes.json +1 -0
  264. package/dist/serve/site-ui/traffic/index.html +11 -0
  265. package/dist/serve/standalone-assets.d.ts +4 -10
  266. package/dist/serve/standalone-assets.d.ts.map +1 -1
  267. package/dist/serve/standalone-assets.js +8 -21
  268. package/dist/serve/standalone-assets.js.map +1 -1
  269. package/dist/serve/vite-functions-development.d.ts +29 -0
  270. package/dist/serve/vite-functions-development.d.ts.map +1 -0
  271. package/dist/serve/vite-functions-development.js +150 -0
  272. package/dist/serve/vite-functions-development.js.map +1 -0
  273. package/dist/serve/vite-generation-bridge.d.ts +17 -0
  274. package/dist/serve/vite-generation-bridge.d.ts.map +1 -0
  275. package/dist/serve/vite-generation-bridge.js +47 -0
  276. package/dist/serve/vite-generation-bridge.js.map +1 -0
  277. package/dist/serve/vite-generation-functions.d.ts +35 -0
  278. package/dist/serve/vite-generation-functions.d.ts.map +1 -0
  279. package/dist/serve/vite-generation-functions.js +46 -0
  280. package/dist/serve/vite-generation-functions.js.map +1 -0
  281. package/dist/serve/vite-generation-middleware.d.ts +10 -0
  282. package/dist/serve/vite-generation-middleware.d.ts.map +1 -0
  283. package/dist/serve/vite-generation-middleware.js +40 -0
  284. package/dist/serve/vite-generation-middleware.js.map +1 -0
  285. package/dist/serve/vite-generation-rules-watch.d.ts +8 -0
  286. package/dist/serve/vite-generation-rules-watch.d.ts.map +1 -0
  287. package/dist/serve/vite-generation-rules-watch.js +33 -0
  288. package/dist/serve/vite-generation-rules-watch.js.map +1 -0
  289. package/dist/serve/vite-module-swap.d.ts +16 -0
  290. package/dist/serve/vite-module-swap.d.ts.map +1 -0
  291. package/dist/serve/vite-module-swap.js +96 -0
  292. package/dist/serve/vite-module-swap.js.map +1 -0
  293. package/dist/serve/vite-page-runtime.d.ts +29 -0
  294. package/dist/serve/vite-page-runtime.d.ts.map +1 -0
  295. package/dist/serve/vite-page-runtime.js +71 -0
  296. package/dist/serve/vite-page-runtime.js.map +1 -0
  297. package/dist/serve/vite-plugin.d.ts +44 -4
  298. package/dist/serve/vite-plugin.d.ts.map +1 -1
  299. package/dist/serve/vite-plugin.js +62 -864
  300. package/dist/serve/vite-plugin.js.map +1 -1
  301. package/dist/serve/vite-sandbox-generation.d.ts +57 -0
  302. package/dist/serve/vite-sandbox-generation.d.ts.map +1 -0
  303. package/dist/serve/vite-sandbox-generation.js +178 -0
  304. package/dist/serve/vite-sandbox-generation.js.map +1 -0
  305. package/dist/serve/worker/client/disconnect.d.ts.map +1 -1
  306. package/dist/serve/worker/client/disconnect.js +2 -0
  307. package/dist/serve/worker/client/disconnect.js.map +1 -1
  308. package/dist/serve/worker/client/handles.d.ts +5 -0
  309. package/dist/serve/worker/client/handles.d.ts.map +1 -1
  310. package/dist/serve/worker/client/handles.js.map +1 -1
  311. package/dist/serve/worker/client/pagehide.d.ts +13 -0
  312. package/dist/serve/worker/client/pagehide.d.ts.map +1 -0
  313. package/dist/serve/worker/client/pagehide.js +19 -0
  314. package/dist/serve/worker/client/pagehide.js.map +1 -0
  315. package/dist/serve/worker/client/rtdb-admin.d.ts +8 -0
  316. package/dist/serve/worker/client/rtdb-admin.d.ts.map +1 -0
  317. package/dist/serve/worker/client/rtdb-admin.js +39 -0
  318. package/dist/serve/worker/client/rtdb-admin.js.map +1 -0
  319. package/dist/serve/worker/client/rtdb-connection-lifecycle.d.ts +15 -0
  320. package/dist/serve/worker/client/rtdb-connection-lifecycle.d.ts.map +1 -0
  321. package/dist/serve/worker/client/rtdb-connection-lifecycle.js +45 -0
  322. package/dist/serve/worker/client/rtdb-connection-lifecycle.js.map +1 -0
  323. package/dist/serve/worker/client/rtdb-controls.d.ts +6 -0
  324. package/dist/serve/worker/client/rtdb-controls.d.ts.map +1 -0
  325. package/dist/serve/worker/client/rtdb-controls.js +8 -0
  326. package/dist/serve/worker/client/rtdb-controls.js.map +1 -0
  327. package/dist/serve/worker/client/rtdb-listeners.d.ts +24 -0
  328. package/dist/serve/worker/client/rtdb-listeners.d.ts.map +1 -0
  329. package/dist/serve/worker/client/rtdb-listeners.js +262 -0
  330. package/dist/serve/worker/client/rtdb-listeners.js.map +1 -0
  331. package/dist/serve/worker/client/rtdb-reads.d.ts +4 -0
  332. package/dist/serve/worker/client/rtdb-reads.d.ts.map +1 -0
  333. package/dist/serve/worker/client/rtdb-reads.js +11 -0
  334. package/dist/serve/worker/client/rtdb-reads.js.map +1 -0
  335. package/dist/serve/worker/client/rtdb-references.d.ts +19 -0
  336. package/dist/serve/worker/client/rtdb-references.d.ts.map +1 -0
  337. package/dist/serve/worker/client/rtdb-references.js +63 -0
  338. package/dist/serve/worker/client/rtdb-references.js.map +1 -0
  339. package/dist/serve/worker/client/rtdb-snapshots.d.ts +20 -0
  340. package/dist/serve/worker/client/rtdb-snapshots.d.ts.map +1 -0
  341. package/dist/serve/worker/client/rtdb-snapshots.js +64 -0
  342. package/dist/serve/worker/client/rtdb-snapshots.js.map +1 -0
  343. package/dist/serve/worker/client/rtdb-transactions.d.ts +14 -0
  344. package/dist/serve/worker/client/rtdb-transactions.d.ts.map +1 -0
  345. package/dist/serve/worker/client/rtdb-transactions.js +34 -0
  346. package/dist/serve/worker/client/rtdb-transactions.js.map +1 -0
  347. package/dist/serve/worker/client/rtdb-writes.d.ts +8 -0
  348. package/dist/serve/worker/client/rtdb-writes.d.ts.map +1 -0
  349. package/dist/serve/worker/client/rtdb-writes.js +65 -0
  350. package/dist/serve/worker/client/rtdb-writes.js.map +1 -0
  351. package/dist/serve/worker/client.d.ts +0 -2
  352. package/dist/serve/worker/client.d.ts.map +1 -1
  353. package/dist/serve/worker/client.js +0 -2
  354. package/dist/serve/worker/client.js.map +1 -1
  355. package/dist/serve/worker/entry.js +2 -2
  356. package/dist/serve/worker/entry.js.map +1 -1
  357. package/dist/serve/worker/host/dispatch.d.ts +2 -0
  358. package/dist/serve/worker/host/dispatch.d.ts.map +1 -1
  359. package/dist/serve/worker/host/dispatch.js +24 -2
  360. package/dist/serve/worker/host/dispatch.js.map +1 -1
  361. package/dist/serve/worker/host/rtdb.d.ts +6 -2
  362. package/dist/serve/worker/host/rtdb.d.ts.map +1 -1
  363. package/dist/serve/worker/host/rtdb.js +224 -2
  364. package/dist/serve/worker/host/rtdb.js.map +1 -1
  365. package/dist/serve/worker/host/studio.d.ts.map +1 -1
  366. package/dist/serve/worker/host/studio.js +2 -0
  367. package/dist/serve/worker/host/studio.js.map +1 -1
  368. package/dist/serve/worker/host/subscriptions.d.ts.map +1 -1
  369. package/dist/serve/worker/host/subscriptions.js +3 -3
  370. package/dist/serve/worker/host/subscriptions.js.map +1 -1
  371. package/dist/serve/worker/host.d.ts +1 -1
  372. package/dist/serve/worker/host.d.ts.map +1 -1
  373. package/dist/serve/worker/host.js +1 -1
  374. package/dist/serve/worker/host.js.map +1 -1
  375. package/dist/serve/worker/index.d.ts +16 -1
  376. package/dist/serve/worker/index.d.ts.map +1 -1
  377. package/dist/serve/worker/index.js +17 -4
  378. package/dist/serve/worker/index.js.map +1 -1
  379. package/dist/serve/worker/protocol.d.ts +57 -0
  380. package/dist/serve/worker/protocol.d.ts.map +1 -1
  381. package/dist/serve/worker/protocol.js.map +1 -1
  382. package/dist/serve/worker/rtdb-value-equality.d.ts +3 -0
  383. package/dist/serve/worker/rtdb-value-equality.d.ts.map +1 -0
  384. package/dist/serve/worker/rtdb-value-equality.js +18 -0
  385. package/dist/serve/worker/rtdb-value-equality.js.map +1 -0
  386. package/dist/serve/worker/serve-init.js +2 -2
  387. package/dist/serve/worker/serve-init.js.map +1 -1
  388. package/dist/serve/worker/service-worker-relay.js +2 -2
  389. package/dist/serve/worker/service-worker-relay.js.map +1 -1
  390. package/package.json +7 -5
  391. package/src/assurance/.generated/conformance-verdicts.ts +120 -75
  392. package/src/cli/serve.ts +215 -307
  393. package/src/cli/service-command-records/database-rules-generate.ts +3 -0
  394. package/src/cli/service-command-records/database-rules-lint.ts +3 -0
  395. package/src/cli/service-command-records/database-rules-simulate.ts +3 -0
  396. package/src/cli/service-command-records/database-rules-validate.ts +3 -0
  397. package/src/cli/service-command-records/firestore-indexes-generate.ts +3 -0
  398. package/src/cli/service-command-records/firestore-rules-lint.ts +3 -0
  399. package/src/cli/service-command-records/firestore-rules-resolve.ts +3 -0
  400. package/src/cli/service-command-records/firestore-rules-simulate.ts +3 -0
  401. package/src/cli/service-command-records/firestore-rules-validate.ts +3 -0
  402. package/src/cli/service-command-records/storage-rules-lint.ts +3 -0
  403. package/src/cli/service-command-records/storage-rules-simulate.ts +3 -0
  404. package/src/cli/service-commands.generated.ts +27 -0
  405. package/src/cli/service-commands.test.ts +43 -0
  406. package/src/cli/service-commands.ts +36 -51
  407. package/src/conformance/.generated/can-i-use-browser.ts +1 -1
  408. package/src/conformance/.generated/can-i-use.ts +1 -1
  409. package/src/conformance/.generated/conformance-docs.ts +1 -1
  410. package/src/functions-rtdb/development-runtime.ts +299 -0
  411. package/src/serve/bridge-mount.ts +253 -19
  412. package/src/serve/bundler.ts +8 -34
  413. package/src/serve/entries/app-client.ts +5 -4
  414. package/src/serve/entries/auth-helper-core.ts +83 -30
  415. package/src/serve/entries/database.ts +180 -57
  416. package/src/serve/entries/init.ts +30 -20
  417. package/src/serve/html-injection.ts +65 -0
  418. package/src/serve/namespace.ts +26 -169
  419. package/src/serve/runtime/worker-replacement.ts +1 -1
  420. package/src/serve/sandbox-session.ts +233 -0
  421. package/src/serve/server.ts +20 -5
  422. package/src/serve/site-tree.ts +146 -0
  423. package/src/serve/standalone-assets.ts +9 -26
  424. package/src/serve/vite-functions-development.ts +201 -0
  425. package/src/serve/vite-generation-bridge.ts +66 -0
  426. package/src/serve/vite-generation-functions.ts +78 -0
  427. package/src/serve/vite-generation-middleware.ts +56 -0
  428. package/src/serve/vite-generation-rules-watch.ts +37 -0
  429. package/src/serve/vite-module-swap.ts +119 -0
  430. package/src/serve/vite-page-runtime.ts +100 -0
  431. package/src/serve/vite-plugin.ts +78 -883
  432. package/src/serve/vite-sandbox-generation.ts +255 -0
  433. package/src/serve/worker/client/disconnect.ts +3 -1
  434. package/src/serve/worker/client/handles.ts +5 -0
  435. package/src/serve/worker/client/pagehide.ts +31 -0
  436. package/src/serve/worker/client/rtdb-admin.ts +74 -0
  437. package/src/serve/worker/client/rtdb-connection-lifecycle.ts +52 -0
  438. package/src/serve/worker/client/rtdb-controls.ts +8 -0
  439. package/src/serve/worker/client/rtdb-listeners.ts +337 -0
  440. package/src/serve/worker/client/rtdb-reads.ts +12 -0
  441. package/src/serve/worker/client/rtdb-references.ts +85 -0
  442. package/src/serve/worker/client/rtdb-snapshots.ts +118 -0
  443. package/src/serve/worker/client/rtdb-transactions.ts +51 -0
  444. package/src/serve/worker/client/rtdb-writes.ts +74 -0
  445. package/src/serve/worker/client.ts +0 -2
  446. package/src/serve/worker/entry.ts +2 -2
  447. package/src/serve/worker/host/dispatch.ts +22 -2
  448. package/src/serve/worker/host/rtdb.ts +243 -2
  449. package/src/serve/worker/host/studio.ts +2 -0
  450. package/src/serve/worker/host/subscriptions.ts +8 -4
  451. package/src/serve/worker/host.ts +1 -1
  452. package/src/serve/worker/index.ts +58 -10
  453. package/src/serve/worker/protocol.ts +23 -2
  454. package/src/serve/worker/rtdb-value-equality.ts +17 -0
  455. package/src/serve/worker/serve-init.ts +2 -2
  456. package/src/serve/worker/service-worker-relay.ts +2 -2
  457. package/dist/serve/docs-ui/_astro/_slug_.DUci-duz.css +0 -1
  458. package/dist/serve/docs-ui/docs/_rhythm/index.html +0 -100
  459. package/dist/serve/docs-ui/docs/agent/set-up-your-agent/index.html +0 -43
  460. package/dist/serve/docs-ui/docs/agent/watch-and-review/index.html +0 -26
  461. package/dist/serve/docs-ui/docs/agent/work-with-an-agent/index.html +0 -70
  462. package/dist/serve/docs-ui/docs/api-reference/index.html +0 -68
  463. package/dist/serve/docs-ui/docs/build/ai-logic/index.html +0 -64
  464. package/dist/serve/docs-ui/docs/build/authentication/index.html +0 -66
  465. package/dist/serve/docs-ui/docs/build/cloud-firestore/index.html +0 -70
  466. package/dist/serve/docs-ui/docs/build/cloud-messaging/index.html +0 -71
  467. package/dist/serve/docs-ui/docs/build/cloud-storage/index.html +0 -66
  468. package/dist/serve/docs-ui/docs/build/realtime-database/index.html +0 -67
  469. package/dist/serve/docs-ui/docs/conformance-scores/index.html +0 -50
  470. package/dist/serve/docs-ui/docs/create-pyric-reference-api/index.html +0 -531
  471. package/dist/serve/docs-ui/docs/functions-rtdb-compat/index.html +0 -73
  472. package/dist/serve/docs-ui/docs/get-started/how-the-swap-works/index.html +0 -29
  473. package/dist/serve/docs-ui/docs/get-started/start-building/index.html +0 -33
  474. package/dist/serve/docs-ui/docs/messaging-compat/index.html +0 -265
  475. package/dist/serve/docs-ui/docs/observe/resolve-runtime-status/index.html +0 -28
  476. package/dist/serve/docs-ui/docs/observe/see-whats-happening/index.html +0 -74
  477. package/dist/serve/docs-ui/docs/observe/shape-your-data/index.html +0 -45
  478. package/dist/serve/docs-ui/docs/overview/index.html +0 -17
  479. package/dist/serve/docs-ui/docs/pyric-admin-app-reference-api/index.html +0 -186
  480. package/dist/serve/docs-ui/docs/pyric-admin-storage-reference-api/index.html +0 -318
  481. package/dist/serve/docs-ui/docs/pyric-ai-scripting-reference-api/index.html +0 -160
  482. package/dist/serve/docs-ui/docs/pyric-app-reference-api/index.html +0 -425
  483. package/dist/serve/docs-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +0 -60
  484. package/dist/serve/docs-ui/docs/pyric-cli-bridge-reference-api/index.html +0 -507
  485. package/dist/serve/docs-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +0 -258
  486. package/dist/serve/docs-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +0 -51
  487. package/dist/serve/docs-ui/docs/pyric-cli-conformance-reference-api/index.html +0 -308
  488. package/dist/serve/docs-ui/docs/pyric-cli-credentials-node-reference-api/index.html +0 -68
  489. package/dist/serve/docs-ui/docs/pyric-cli-register-reference-api/index.html +0 -11
  490. package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api/index.html +0 -126
  491. package/dist/serve/docs-ui/docs/pyric-database-reference-api/index.html +0 -1852
  492. package/dist/serve/docs-ui/docs/pyric-messaging-reference-api/index.html +0 -509
  493. package/dist/serve/docs-ui/docs/pyric-messaging-sw-reference-api/index.html +0 -182
  494. package/dist/serve/docs-ui/docs/pyric-sandbox-database-reference-api/index.html +0 -121
  495. package/dist/serve/docs-ui/docs/pyric-sandbox-firestore-reference-api/index.html +0 -203
  496. package/dist/serve/docs-ui/docs/pyric-ui-agents-reference-api/index.html +0 -639
  497. package/dist/serve/docs-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +0 -100
  498. package/dist/serve/docs-ui/docs/pyric-ui-events-hooks-reference-api/index.html +0 -24
  499. package/dist/serve/docs-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +0 -136
  500. package/dist/serve/docs-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +0 -16
  501. package/dist/serve/docs-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +0 -176
  502. package/dist/serve/docs-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +0 -188
  503. package/dist/serve/docs-ui/docs/secure/audit-your-rules/index.html +0 -51
  504. package/dist/serve/docs-ui/docs/secure/firestore-rules-limits/index.html +0 -106
  505. package/dist/serve/docs-ui/docs/secure/read-a-denial/index.html +0 -41
  506. package/dist/serve/docs-ui/docs/secure/rtdb-rules-in-typescript/index.html +0 -67
  507. package/dist/serve/docs-ui/docs/secure/rules-standard-library/index.html +0 -159
  508. package/dist/serve/docs-ui/docs/secure/secure-it-with-rules/index.html +0 -47
  509. package/dist/serve/docs-ui/docs/secure/simulate-and-lint/index.html +0 -95
  510. package/dist/serve/docs-ui/docs/secure/write-a-rules-test-suite/index.html +0 -82
  511. package/dist/serve/docs-ui/docs/ship/ship-to-production/index.html +0 -37
  512. package/dist/serve/docs-ui/docs/ship/test-in-node/index.html +0 -75
  513. package/dist/serve/docs-ui/docs/trust/how-we-know-it-matches-firebase/index.html +0 -132
  514. package/dist/serve/docs-ui/docs/trust/versioning-and-compatibility/index.html +0 -14
  515. package/dist/serve/docs-ui/index.html +0 -1
  516. package/dist/serve/studio-ui/assets/RulesCodeEditor-BDlH-5lp.js +0 -23
  517. package/dist/serve/studio-ui/assets/index-Bf9SSE8L.js +0 -1218
  518. package/dist/serve/studio-ui/assets/index-BlSGru_r.css +0 -1
  519. package/dist/serve/studio-ui/assets/seed-D_UjxfOU.js +0 -20
  520. package/dist/serve/studio-ui/index.html +0 -32
  521. package/dist/serve/worker/client/rtdb.d.ts +0 -36
  522. package/dist/serve/worker/client/rtdb.d.ts.map +0 -1
  523. package/dist/serve/worker/client/rtdb.js +0 -241
  524. package/dist/serve/worker/client/rtdb.js.map +0 -1
  525. package/src/serve/worker/client/rtdb.ts +0 -311
  526. /package/dist/serve/{docs-ui → site-ui}/404.html +0 -0
  527. /package/dist/serve/{docs-ui → site-ui}/_astro/_slug_.CXh9yTP1.css +0 -0
  528. /package/dist/serve/{docs-ui → site-ui}/docs/_rhythm.md +0 -0
  529. /package/dist/serve/{docs-ui → site-ui}/docs/agent/set-up-your-agent.md +0 -0
  530. /package/dist/serve/{docs-ui → site-ui}/docs/agent/watch-and-review.md +0 -0
  531. /package/dist/serve/{docs-ui → site-ui}/docs/agent/work-with-an-agent.md +0 -0
  532. /package/dist/serve/{docs-ui → site-ui}/docs/ai-compat.md +0 -0
  533. /package/dist/serve/{docs-ui → site-ui}/docs/api-reference.md +0 -0
  534. /package/dist/serve/{docs-ui → site-ui}/docs/app-compat.md +0 -0
  535. /package/dist/serve/{docs-ui → site-ui}/docs/auth-compat.md +0 -0
  536. /package/dist/serve/{docs-ui → site-ui}/docs/build/ai-logic.md +0 -0
  537. /package/dist/serve/{docs-ui → site-ui}/docs/build/authentication.md +0 -0
  538. /package/dist/serve/{docs-ui → site-ui}/docs/build/cloud-firestore.md +0 -0
  539. /package/dist/serve/{docs-ui → site-ui}/docs/build/cloud-messaging.md +0 -0
  540. /package/dist/serve/{docs-ui → site-ui}/docs/build/realtime-database.md +0 -0
  541. /package/dist/serve/{docs-ui → site-ui}/docs/create-pyric-reference-api.md +0 -0
  542. /package/dist/serve/{docs-ui → site-ui}/docs/functions-rtdb-compat.md +0 -0
  543. /package/dist/serve/{docs-ui → site-ui}/docs/get-started/how-the-swap-works.md +0 -0
  544. /package/dist/serve/{docs-ui → site-ui}/docs/get-started/start-building.md +0 -0
  545. /package/dist/serve/{docs-ui → site-ui}/docs/index.html +0 -0
  546. /package/dist/serve/{docs-ui → site-ui}/docs/observe/resolve-runtime-status.md +0 -0
  547. /package/dist/serve/{docs-ui → site-ui}/docs/observe/see-whats-happening.md +0 -0
  548. /package/dist/serve/{docs-ui → site-ui}/docs/observe/shape-your-data.md +0 -0
  549. /package/dist/serve/{docs-ui → site-ui}/docs/overview.md +0 -0
  550. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-app-reference-api.md +0 -0
  551. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-auth-reference-api.md +0 -0
  552. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-database-reference-api.md +0 -0
  553. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-messaging-reference-api.md +0 -0
  554. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-storage-reference-api.md +0 -0
  555. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ai-reference-api.md +0 -0
  556. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ai-scripting-reference-api.md +0 -0
  557. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-app-reference-api.md +0 -0
  558. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-auth-reference-api.md +0 -0
  559. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-assurance-browser-reference-api.md +0 -0
  560. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-assurance-reference-api.md +0 -0
  561. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-bridge-client-reference-api.md +0 -0
  562. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-bridge-reference-api.md +0 -0
  563. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-conformance-browser-reference-api.md +0 -0
  564. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-conformance-docs-reference-api.md +0 -0
  565. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-conformance-reference-api.md +0 -0
  566. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-credentials-node-reference-api.md +0 -0
  567. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-discover-reference-api.md +0 -0
  568. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-register-reference-api.md +0 -0
  569. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-remote-reference-api.md +0 -0
  570. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-verify-reference-api.md +0 -0
  571. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-messaging-reference-api.md +0 -0
  572. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-messaging-sw-reference-api.md +0 -0
  573. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-database-reference-api.md +0 -0
  574. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-firestore-reference-api.md +0 -0
  575. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-agents-reference-api.md +0 -0
  576. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-auth-hooks-reference-api.md +0 -0
  577. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-auth-reference-api.md +0 -0
  578. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-events-hooks-reference-api.md +0 -0
  579. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-events-reference-api.md +0 -0
  580. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-firestore-hooks-reference-api.md +0 -0
  581. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-primitives-reference-api.md +0 -0
  582. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rtdb-reference-api.md +0 -0
  583. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rules-hooks-reference-api.md +0 -0
  584. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rules-reference-api.md +0 -0
  585. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-storage-hooks-reference-api.md +0 -0
  586. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-traffic-hooks-reference-api.md +0 -0
  587. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-traffic-reference-api.md +0 -0
  588. /package/dist/serve/{docs-ui → site-ui}/docs/secure/audit-your-rules.md +0 -0
  589. /package/dist/serve/{docs-ui → site-ui}/docs/secure/firestore-rules-limits.md +0 -0
  590. /package/dist/serve/{docs-ui → site-ui}/docs/secure/read-a-denial.md +0 -0
  591. /package/dist/serve/{docs-ui → site-ui}/docs/secure/rtdb-rules-in-typescript.md +0 -0
  592. /package/dist/serve/{docs-ui → site-ui}/docs/secure/secure-it-with-rules.md +0 -0
  593. /package/dist/serve/{docs-ui → site-ui}/docs/secure/simulate-and-lint.md +0 -0
  594. /package/dist/serve/{docs-ui → site-ui}/docs/secure/write-a-rules-test-suite.md +0 -0
  595. /package/dist/serve/{docs-ui → site-ui}/docs/ship/ship-to-production.md +0 -0
  596. /package/dist/serve/{docs-ui → site-ui}/docs/ship/test-in-node.md +0 -0
  597. /package/dist/serve/{docs-ui → site-ui}/docs/trust/how-we-know-it-matches-firebase.md +0 -0
  598. /package/dist/serve/{docs-ui → site-ui}/docs/trust/versioning-and-compatibility.md +0 -0
  599. /package/dist/serve/{studio-ui → site-ui}/pyric-logo.svg +0 -0
@@ -18,6 +18,8 @@
18
18
 
19
19
  <div class="compat-key">
20
20
  <span class="compat-key-item"><span class="compat-dot" data-status="ok"></span><strong>Conforming</strong> — sandbox matches prod, locked by a passing probe</span>
21
+ <span class="compat-key-item"><span class="compat-dot" data-status="unsupported"></span><strong>Not implemented yet</strong> — deliberately or pending</span>
22
+ <span class="compat-key-item"><span class="compat-dot" data-status="unverified"></span><strong>Unverified</strong> — a target with a derived failing test, not a guarantee</span>
21
23
  </div>
22
24
 
23
25
  ## `firebase/messaging` (client)
@@ -61,7 +63,7 @@
61
63
  </details>
62
64
  <details class="compat-row" data-status="ok">
63
65
  <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">interface FcmOptions { link?; analyticsLabel? }</code><span class="compat-sub"><span class="compat-behavior">WebpushFcmOptions-style options carried on a client <code>MessagePayload</code> (<code>link</code>, <code>analyticsLabel</code>).</span></span></span></summary>
64
- <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>public-types</code>); no observation yet.</div></div>
66
+ <div class="compat-evidence"><div class="compat-probe">Upstream typings (<code>@firebase/messaging</code> 0.12.26 <code>public-types</code>); no observation yet — type-only shape closed by the assignability census (resolved decision #5).</div></div>
65
67
  </details>
66
68
  <details class="compat-row" data-status="ok">
67
69
  <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">NextFn, Observer, Unsubscribe (re-exported from @firebase/util)</code><span class="compat-sub"><span class="compat-behavior">The callback, observer, and teardown types consumed by <code>onMessage</code> / <code>onBackgroundMessage</code> are re-exported from <code>@firebase/util</code>.</span></span></span></summary>
@@ -98,6 +100,27 @@
98
100
  </details>
99
101
  </div>
100
102
 
103
+ ## Behavior classes over time & across clients (client receive plane)
104
+
105
+ <div class="compat-list">
106
+ <details class="compat-row" data-status="unverified">
107
+ <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">Multi-tab delivery routing (several window clients, one shared service worker)</code><span class="compat-sub"><span class="compat-behavior">When several window clients (browser tabs) of one origin share a single service-worker registration, a foreground delivery reaches every visible tab through <code>onMessage</code>, and when no tab is visible the one shared service worker receives the message once through <code>onBackgroundMessage</code> (the worker is shared across tabs, not instantiated per tab). A notification click focuses a single existing client rather than opening a duplicate. Stated from the FCM web SDK and the Service Worker client model; no committed observation replays the multi-tab fan-out yet.</span></span></span></summary>
108
+ <div class="compat-evidence"><div class="compat-probe">Upstream documentation (<code>@firebase/messaging</code> 0.12.26 + W3C Service Worker <code>Clients</code> model); no observation yet. Candidate probe: open two tabs on one registration and deliver with one tab visible, then with both hidden — assert <code>onMessage</code> fires once per visible tab and <code>onBackgroundMessage</code> fires exactly once on the shared worker.</div></div>
109
+ </details>
110
+ <details class="compat-row" data-status="unverified">
111
+ <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">Multi-device delivery (one app instance holding several tokens; per-token fan-out)</code><span class="compat-sub"><span class="compat-behavior">A single user or app can hold several registration tokens at once — one per browser, profile, or device. A token-targeted send reaches exactly one token; a topic, condition, or multicast send fans out independently to every subscribed token, with no server-side de-duplication across a user’s devices, so each device receives its own copy. Stated from the FCM targeting model; no committed observation replays cross-device fan-out yet.</span></span></span></summary>
112
+ <div class="compat-evidence"><div class="compat-probe">Upstream documentation (FCM targeting model); no observation yet. Candidate probe: mint two distinct tokens, subscribe both to one topic, send once, and assert each token receives the message independently.</div></div>
113
+ </details>
114
+ <details class="compat-row" data-status="unverified">
115
+ <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">Registration-token rotation and refresh over the app lifecycle</code><span class="compat-sub"><span class="compat-behavior">A registration token is stable within a session (row messaging#2 pins that repeated <code>getToken</code> calls on one service-worker registration return the same token) but is not permanent across the app lifecycle: the SDK rotates it on events such as app reinstall, SDK upgrade, a restored backup, or a notification-permission change, and Google may retire a token server-side. The modular web SDK has no token-refresh callback, so an app observes a new token only by calling <code>getToken</code> again; a rotated-away old token eventually stops delivering and the send plane reports the dead token (the UNREGISTERED path pinned by messaging#3). This lifecycle rotation is deliberately outside the within-session stability observation. Stated from FCM token-management documentation; no committed observation replays rotation across lifecycle events yet.</span></span></span></summary>
116
+ <div class="compat-evidence"><div class="compat-probe">Upstream documentation (FCM token-management guidance); the committed <code>messaging-web-token-stability</code> observation covers only within-session stability, not lifecycle rotation. Candidate probe (long-horizon): force a service-worker unregister/re-register or an app-instance reset, re-mint via <code>getToken</code>, and record whether the token changed and whether the prior token then reports UNREGISTERED on send.</div></div>
117
+ </details>
118
+ <details class="compat-row" data-status="unsupported">
119
+ <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">Registration-token inactivity expiry (server-side staleness window)</code><span class="compat-sub"><span class="compat-behavior">FCM treats a registration token that has gone unused for an extended period (Google documents roughly 270 days of app-instance inactivity) as stale and drops it from delivery targeting, independent of any explicit <code>deleteToken</code>. The expiry clock is Google server-side inactivity accounting, and the recommended mitigation is periodic token refresh. Stated from FCM best-practices documentation; the sandbox has no server-side inactivity clock to model.</span></span></span></summary>
120
+ <div class="compat-evidence"><div class="compat-probe">Upstream documentation (FCM registration-token best practices); no observation. This time-based server-side behavior is out of sandbox scope (see the row disposition); the explicit-deletion path to a dead token is already tracked by messaging#3.</div></div>
121
+ </details>
122
+ </div>
123
+
101
124
  ## `firebase-admin/messaging` — entry + `Messaging` class
102
125
 
103
126
  <div class="compat-list">
@@ -283,3 +306,50 @@
283
306
  <div class="compat-evidence"><div class="compat-probe">oracle: <code>messaging-send-no-target-error-envelope.json</code> + <code>messaging-send-invalid-token-error-envelope.json</code> (both carry the INVALID_ARGUMENT FcmError). Replayed by the conformance suite.</div></div>
284
307
  </details>
285
308
  </div>
309
+
310
+ ## Behavior classes — quota, retry, offline delivery (send plane)
311
+
312
+ <div class="compat-list">
313
+ <details class="compat-row" data-status="unsupported">
314
+ <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">FCM send quota and rate-limit throttling</code><span class="compat-sub"><span class="compat-behavior">FCM enforces project-level send quotas and per-target rate limits (per-device and per-topic message rates) accounted on Google servers over rolling windows; exceeding them yields quota / rate-limit rejections. The admin error taxonomy names these as <code>MessagingClientErrorCode.MESSAGE_RATE_EXCEEDED</code>, <code>DEVICE_MESSAGE_RATE_EXCEEDED</code>, and <code>TOPICS_MESSAGE_RATE_EXCEEDED</code> (wire <code>QUOTA_EXCEEDED</code> / <code>RESOURCE_EXHAUSTED</code>, HTTP 429). Stated from FCM quota documentation; the sandbox has no global quota ledger to model.</span></span></span></summary>
315
+ <div class="compat-evidence"><div class="compat-probe">Upstream documentation (FCM quotas and <code>MessagingClientErrorCode</code> rate-limit members, firebase-admin 13.10.0); no observation. This behavior is out of sandbox scope (see the row disposition).</div></div>
316
+ </details>
317
+ <details class="compat-row" data-status="unverified">
318
+ <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">Send retry and backoff on transient transport failures</code><span class="compat-sub"><span class="compat-behavior">The admin SDK retries transient send-transport failures — connection errors and HTTP 5xx / <code>SERVER_UNAVAILABLE</code> / <code>INTERNAL</code> responses — with backoff before surfacing the error to the caller, so a caller sees a resolved send or a terminal error rather than every intermediate failure. <code>enableLegacyHttpTransport</code> switches <code>sendEach</code> / <code>sendEachForMulticast</code> from HTTP/2 to HTTP/1.1, changing multiplexing and the retry/transport path. Stated from the admin SDK and google-auth transport documentation; no committed observation replays the retry count or backoff schedule yet.</span></span></span></summary>
319
+ <div class="compat-evidence"><div class="compat-probe">Upstream documentation (firebase-admin 13.10.0 send transport + google-auth retry defaults); no observation yet. Candidate probe: point the send transport at a fault-injecting stub that returns 503 then 200 and record the retry count and backoff intervals before the resolved send.</div></div>
320
+ </details>
321
+ <details class="compat-row" data-status="unverified">
322
+ <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">Offline store-and-forward delivery</code><span class="compat-sub"><span class="compat-category">TTL and collapse-key semantics</span> · <span class="compat-behavior">When a target device is offline FCM stores the message and delivers it on reconnect, up to its time-to-live (<code>android.ttl</code>, APNs expiration, webpush <code>headers.TTL</code>; the legacy default is 2419200 seconds / four weeks). A collapse key (<code>android.collapseKey</code>, <code>collapseKey</code>) marks a message as collapsible so a newer collapsible message replaces an older still-undelivered one, and only the last is delivered on reconnect; a message whose TTL elapses before reconnect is dropped rather than delivered. Stated from FCM message-lifecycle documentation; no committed observation replays store-and-forward, collapse, or TTL expiry yet.</span></span></span></summary>
323
+ <div class="compat-evidence"><div class="compat-probe">Upstream documentation (FCM message lifecycle: TTL, collapse keys, store-and-forward); no observation yet. Candidate probe: send several collapsible messages to a token whose web client is offline, bring it online within TTL, and assert only the last collapsible message is delivered; separately, let a short-TTL message expire before reconnect and assert it is dropped.</div></div>
324
+ </details>
325
+ </div>
326
+
327
+ ## Current gaps
328
+
329
+ ### Not implemented yet
330
+
331
+ Tracked behavior that is not implemented in the current contract.
332
+
333
+ <div class="compat-list">
334
+ <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"><code class="compat-api">Registration-token inactivity expiry (server-side staleness window)</code><span class="compat-sub"><span class="compat-behavior">FCM treats a registration token that has gone unused for an extended period (Google documents roughly 270 days of app-instance inactivity) as stale and drops it from delivery targeting, independent of any explicit <code>deleteToken</code>. The expiry clock is Google server-side inactivity accounting, and the recommended mitigation is periodic token refresh. Stated from FCM best-practices documentation; the sandbox has no server-side inactivity clock to model.</span></span></span></summary>
335
+ <div class="compat-evidence"><div class="compat-note">Upstream documentation (FCM registration-token best practices); no observation. This time-based server-side behavior is out of sandbox scope (see the row disposition); the explicit-deletion path to a dead token is already tracked by messaging#3.</div></div></details>
336
+ <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"><code class="compat-api">FCM send quota and rate-limit throttling</code><span class="compat-sub"><span class="compat-behavior">FCM enforces project-level send quotas and per-target rate limits (per-device and per-topic message rates) accounted on Google servers over rolling windows; exceeding them yields quota / rate-limit rejections. The admin error taxonomy names these as <code>MessagingClientErrorCode.MESSAGE_RATE_EXCEEDED</code>, <code>DEVICE_MESSAGE_RATE_EXCEEDED</code>, and <code>TOPICS_MESSAGE_RATE_EXCEEDED</code> (wire <code>QUOTA_EXCEEDED</code> / <code>RESOURCE_EXHAUSTED</code>, HTTP 429). Stated from FCM quota documentation; the sandbox has no global quota ledger to model.</span></span></span></summary>
337
+ <div class="compat-evidence"><div class="compat-note">Upstream documentation (FCM quotas and <code>MessagingClientErrorCode</code> rate-limit members, firebase-admin 13.10.0); no observation. This behavior is out of sandbox scope (see the row disposition).</div></div></details>
338
+ </div>
339
+
340
+ ### Unverified
341
+
342
+ Tracked behavior whose available evidence does not yet establish the production result.
343
+
344
+ <div class="compat-list">
345
+ <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">Multi-tab delivery routing (several window clients, one shared service worker)</code><span class="compat-sub"><span class="compat-behavior">When several window clients (browser tabs) of one origin share a single service-worker registration, a foreground delivery reaches every visible tab through <code>onMessage</code>, and when no tab is visible the one shared service worker receives the message once through <code>onBackgroundMessage</code> (the worker is shared across tabs, not instantiated per tab). A notification click focuses a single existing client rather than opening a duplicate. Stated from the FCM web SDK and the Service Worker client model; no committed observation replays the multi-tab fan-out yet.</span></span></span></summary>
346
+ <div class="compat-evidence"><div class="compat-note">Upstream documentation (<code>@firebase/messaging</code> 0.12.26 + W3C Service Worker <code>Clients</code> model); no observation yet. Candidate probe: open two tabs on one registration and deliver with one tab visible, then with both hidden — assert <code>onMessage</code> fires once per visible tab and <code>onBackgroundMessage</code> fires exactly once on the shared worker.</div></div></details>
347
+ <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">Multi-device delivery (one app instance holding several tokens; per-token fan-out)</code><span class="compat-sub"><span class="compat-behavior">A single user or app can hold several registration tokens at once — one per browser, profile, or device. A token-targeted send reaches exactly one token; a topic, condition, or multicast send fans out independently to every subscribed token, with no server-side de-duplication across a user’s devices, so each device receives its own copy. Stated from the FCM targeting model; no committed observation replays cross-device fan-out yet.</span></span></span></summary>
348
+ <div class="compat-evidence"><div class="compat-note">Upstream documentation (FCM targeting model); no observation yet. Candidate probe: mint two distinct tokens, subscribe both to one topic, send once, and assert each token receives the message independently.</div></div></details>
349
+ <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">Registration-token rotation and refresh over the app lifecycle</code><span class="compat-sub"><span class="compat-behavior">A registration token is stable within a session (row messaging#2 pins that repeated <code>getToken</code> calls on one service-worker registration return the same token) but is not permanent across the app lifecycle: the SDK rotates it on events such as app reinstall, SDK upgrade, a restored backup, or a notification-permission change, and Google may retire a token server-side. The modular web SDK has no token-refresh callback, so an app observes a new token only by calling <code>getToken</code> again; a rotated-away old token eventually stops delivering and the send plane reports the dead token (the UNREGISTERED path pinned by messaging#3). This lifecycle rotation is deliberately outside the within-session stability observation. Stated from FCM token-management documentation; no committed observation replays rotation across lifecycle events yet.</span></span></span></summary>
350
+ <div class="compat-evidence"><div class="compat-note">Upstream documentation (FCM token-management guidance); the committed <code>messaging-web-token-stability</code> observation covers only within-session stability, not lifecycle rotation. Candidate probe (long-horizon): force a service-worker unregister/re-register or an app-instance reset, re-mint via <code>getToken</code>, and record whether the token changed and whether the prior token then reports UNREGISTERED on send.</div></div></details>
351
+ <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">Send retry and backoff on transient transport failures</code><span class="compat-sub"><span class="compat-behavior">The admin SDK retries transient send-transport failures — connection errors and HTTP 5xx / <code>SERVER_UNAVAILABLE</code> / <code>INTERNAL</code> responses — with backoff before surfacing the error to the caller, so a caller sees a resolved send or a terminal error rather than every intermediate failure. <code>enableLegacyHttpTransport</code> switches <code>sendEach</code> / <code>sendEachForMulticast</code> from HTTP/2 to HTTP/1.1, changing multiplexing and the retry/transport path. Stated from the admin SDK and google-auth transport documentation; no committed observation replays the retry count or backoff schedule yet.</span></span></span></summary>
352
+ <div class="compat-evidence"><div class="compat-note">Upstream documentation (firebase-admin 13.10.0 send transport + google-auth retry defaults); no observation yet. Candidate probe: point the send transport at a fault-injecting stub that returns 503 then 200 and record the retry count and backoff intervals before the resolved send.</div></div></details>
353
+ <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">Offline store-and-forward delivery</code><span class="compat-sub"><span class="compat-behavior">When a target device is offline FCM stores the message and delivers it on reconnect, up to its time-to-live (<code>android.ttl</code>, APNs expiration, webpush <code>headers.TTL</code>; the legacy default is 2419200 seconds / four weeks). A collapse key (<code>android.collapseKey</code>, <code>collapseKey</code>) marks a message as collapsible so a newer collapsible message replaces an older still-undelivered one, and only the last is delivered on reconnect; a message whose TTL elapses before reconnect is dropped rather than delivered. Stated from FCM message-lifecycle documentation; no committed observation replays store-and-forward, collapse, or TTL expiry yet.</span></span></span></summary>
354
+ <div class="compat-evidence"><div class="compat-note">Upstream documentation (FCM message lifecycle: TTL, collapse keys, store-and-forward); no observation yet. Candidate probe: send several collapsible messages to a token whose web client is offline, bring it online within TTL, and assert only the last collapsible message is delivered; separately, let a short-TTL message expire before reconnect and assert it is dropped.</div></div></details>
355
+ </div>
@@ -0,0 +1,28 @@
1
+ <!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Resolve runtime errors and stale workers · Pyric Studio</title><meta name="description" content="Use the Pyric runtime chip to inspect sandbox errors, activate a new worker, and open Studio."><link rel="icon" type="image/svg+xml" href="/__pyric/ui/pyric-logo.svg"><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.CXh9yTP1.css">
2
+ <link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.BoKXYrnu.css"></head> <body> <header class="studio__bar" data-astro-cid-mw7aashj> <div class="studio__bar-inner" data-astro-cid-mw7aashj> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric Studio" data-astro-cid-mw7aashj>Pyric</a> <nav class="studio__nav" aria-label="Studio tabs" data-astro-cid-mw7aashj> <a class="studio__nav-tab" href="/__pyric/ui/" data-astro-cid-mw7aashj> Home </a><a class="studio__nav-tab" href="/__pyric/ui/firestore" data-astro-cid-mw7aashj> Firestore </a><a class="studio__nav-tab" href="/__pyric/ui/auth" data-astro-cid-mw7aashj> Auth </a><a class="studio__nav-tab" href="/__pyric/ui/rtdb" data-astro-cid-mw7aashj> RTDB </a><a class="studio__nav-tab" href="/__pyric/ui/storage" data-astro-cid-mw7aashj> Storage </a><a class="studio__nav-tab" href="/__pyric/ui/traffic" data-astro-cid-mw7aashj> Traffic </a><a class="studio__nav-tab" href="/__pyric/ui/settings" data-astro-cid-mw7aashj> Settings </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page" data-astro-cid-mw7aashj> Docs </a> </nav> </div> </header> <div class="docs-shell" data-astro-cid-mw7aashj> <details class="docs-nav-drawer" data-astro-cid-mw7aashj> <summary data-astro-cid-mw7aashj>Navigate</summary> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <script type="module">let i=null;function d(t){return i||(i=fetch(t).then(e=>e.json())),i}function l(t,e){return t.title.toLowerCase().includes(e)||t.excerpt.toLowerCase().includes(e)?!0:t.headings.some(r=>r.text.toLowerCase().includes(e))}function u(t,e,r){if(e.innerHTML="",t.length===0){e.hidden=!1;{const n=document.createElement("li");n.className="docs-search-empty",n.textContent="No matches",e.appendChild(n)}return}e.hidden=!1;for(const n of t.slice(0,8)){const s=document.createElement("li"),c=document.createElement("a");c.href=n.path;const o=document.createElement("span");o.className="docs-search-result-title",o.textContent=n.title;const a=document.createElement("span");a.className="docs-search-result-meta",a.textContent=[n.group,n.section].filter(Boolean).join(" / "),c.append(o,a),s.appendChild(c),e.appendChild(s)}}document.querySelectorAll(".docs-search").forEach(t=>{const e=t.dataset.indexUrl,r=t.querySelector(".docs-search-input"),n=t.querySelector(".docs-search-results");r.addEventListener("input",async()=>{const s=r.value.trim().toLowerCase();if(!s){n.hidden=!0,n.innerHTML="";return}const{pages:c}=await d(e);r.value.trim().toLowerCase()===s&&u(c.filter(o=>l(o,s)),n)}),r.addEventListener("focus",()=>{d(e),n.childElementCount>0&&(n.hidden=!1)}),r.addEventListener("keydown",s=>{s.key==="Escape"&&(r.value="",n.hidden=!0,n.innerHTML="",r.blur())}),r.addEventListener("blur",()=>{window.setTimeout(()=>{n.hidden=!0},150)})});document.addEventListener("keydown",t=>{if(!(t.metaKey||t.ctrlKey)||t.key.toLowerCase()!=="k")return;const e=[...document.querySelectorAll(".docs-search-input")].find(r=>r.offsetParent!==null);e&&(t.preventDefault(),e.focus(),e.select())});</script> <details class="docs-nav-group"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" open> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/" aria-current="page"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/storage-rules-stdlib-research/"> Storage Rules modules: evidence and design </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Public API coverage </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group"> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div> </div> </details> </nav> </details> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <details class="docs-nav-group" id="nav-group-overview"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-get-started"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-build"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-secure-debug"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-secure-debug-examples"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-observe-shape" open> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/" aria-current="page"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-ship-test"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-work-with-an-agent"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-trust"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/storage-rules-stdlib-research/"> Storage Rules modules: evidence and design </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-conformance"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Public API coverage </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group" id="nav-group-reference"> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div> </div> </details> </nav> <main class="doc-main" data-astro-cid-mw7aashj> <nav class="docs-breadcrumbs" aria-label="Breadcrumb"> <ol> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/">Observe &amp; shape</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span aria-current="page">Runtime status</span> </li> </ol> </nav> <article class="prose" data-astro-cid-mw7aashj> <h1 id="resolve-runtime-errors-and-stale-workers">Resolve runtime errors and stale workers</h1>
3
+ <p>During Vite development, Pyric adds a compact runtime chip to the bottom-right corner of the application. It is collapsed by default and reports <code>ready</code> while the sandbox is healthy. Open it when the chip reports errors or an update.</p>
4
+ <h2 id="inspect-a-sandbox-error">Inspect a sandbox error</h2>
5
+ <ol>
6
+ <li>Select the chip to open the runtime panel.</li>
7
+ <li>Read the error in the scrollable error area.</li>
8
+ <li>Use the copy button beside that error to paste the complete message and context into an issue, terminal, or agent conversation.</li>
9
+ <li>Select <strong>Studio</strong> to open Pyric Studio in a new tab when you need to inspect the sandbox’s data, rules, or traffic.</li>
10
+ </ol>
11
+ <p>The chip reports errors from the Pyric sandbox. Errors produced only by application UI code remain in the browser’s normal developer tools.</p>
12
+ <h2 id="activate-a-new-worker">Activate a new worker</h2>
13
+ <p>Vite can serve a newer Pyric worker while an older SharedWorker is still running for the origin. When that happens, the collapsed chip shows <code>update</code> and the panel labels the worker as <strong>New worker available</strong>.</p>
14
+ <ol>
15
+ <li>Save any unsaved, UI-only form input. Updating reloads every connected tab for this origin.</li>
16
+ <li>Open the chip.</li>
17
+ <li>Select <strong>Update worker</strong>.</li>
18
+ </ol>
19
+ <p>The old worker stops taking new work, finishes operations it already accepted, flushes captured state, and then reloads its connected tabs onto the new worker generation. The update control always occupies the same place in the panel, but remains disabled when the running worker is current.</p>
20
+ <p>If replacement fails, the panel records the failure as a copyable error and leaves the update available so you can try again. Resolve the reported cause first. If a stale worker remains after a failed recovery, close every tab for that development origin and reopen the application.</p>
21
+ <h2 id="configure-the-chip">Configure the chip</h2>
22
+ <p>The default configuration is the recommended one:</p>
23
+ <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#61AFEF">pyric</span><span style="color:#ABB2BF">()</span></span></code></pre>
24
+ <p>To keep the panel open from the first load while actively debugging runtime failures:</p>
25
+ <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#61AFEF">pyric</span><span style="color:#ABB2BF">({ </span><span style="color:#E06C75">runtimeChip</span><span style="color:#ABB2BF">: { </span><span style="color:#E06C75">initiallyOpen</span><span style="color:#ABB2BF">: </span><span style="color:#D19A66">true</span><span style="color:#ABB2BF"> } })</span></span></code></pre>
26
+ <p>To hide the runtime surface entirely:</p>
27
+ <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#61AFEF">pyric</span><span style="color:#ABB2BF">({ </span><span style="color:#E06C75">runtimeChip</span><span style="color:#ABB2BF">: </span><span style="color:#D19A66">false</span><span style="color:#ABB2BF"> })</span></span></code></pre>
28
+ <p>The chip is a development surface. A normal production Vite build does not inject it. Disabling Pyric Studio with <code>ui: false</code> keeps the Studio action visible but unavailable, so the panel does not shift as its status changes.</p> </article> </main> <aside class="doc-toc" aria-label="On this page" data-astro-cid-mw7aashj> <h2 class="doc-toc-heading" data-astro-cid-mw7aashj>On this page</h2> <ul data-astro-cid-mw7aashj> <li data-depth="2" data-astro-cid-mw7aashj> <a href="#inspect-a-sandbox-error" data-astro-cid-mw7aashj>Inspect a sandbox error</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#activate-a-new-worker" data-astro-cid-mw7aashj>Activate a new worker</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#configure-the-chip" data-astro-cid-mw7aashj>Configure the chip</a> </li> </ul> </aside> </div> <script type="module">const a=document.querySelector("[data-api-symbol-filter]"),d=[...document.querySelectorAll("[data-api-symbol-group]")],n=document.querySelector("[data-api-symbol-empty]");a?.addEventListener("input",()=>{const t=a.value.trim().toLowerCase();let o=0;for(const i of d){let e=0;i.querySelectorAll("[data-api-symbol]").forEach(l=>{const r=!t||(l.dataset.apiSymbol??"").includes(t);l.hidden=!r,r&&e++}),i.hidden=e===0,o+=e}n&&(n.hidden=o>0)});</script> <script type="module">const s=new Map;document.querySelectorAll('.doc-toc a[href^="#"]').forEach(t=>s.set(decodeURIComponent(t.hash.slice(1)),t));if(s.size>0){const t=new Set,n=()=>{let o=null;for(const e of s.keys())if(t.has(e)){o=e;break}s.forEach((e,c)=>e.classList.toggle("active",c===o))},r=new IntersectionObserver(o=>{for(const e of o)e.isIntersecting?t.add(e.target.id):t.delete(e.target.id);n()},{rootMargin:"-72px 0px -60% 0px"});s.forEach((o,e)=>{const c=document.getElementById(e);c&&r.observe(c)})}</script> <script type="module">document.querySelector('.studio__nav [aria-current="page"]')?.scrollIntoView({block:"nearest",inline:"center"});</script> </body></html>
@@ -0,0 +1,74 @@
1
+ <!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Watch every read, write, and denial live · Pyric Studio</title><meta name="description" content="See every operation your backend performs, with its rules verdict, without writing a log line."><link rel="icon" type="image/svg+xml" href="/__pyric/ui/pyric-logo.svg"><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.CXh9yTP1.css">
2
+ <link rel="stylesheet" href="/__pyric/ui/_astro/_slug_.BoKXYrnu.css"></head> <body> <header class="studio__bar" data-astro-cid-mw7aashj> <div class="studio__bar-inner" data-astro-cid-mw7aashj> <a class="studio__brand" href="/__pyric/ui/" aria-label="Pyric Studio" data-astro-cid-mw7aashj>Pyric</a> <nav class="studio__nav" aria-label="Studio tabs" data-astro-cid-mw7aashj> <a class="studio__nav-tab" href="/__pyric/ui/" data-astro-cid-mw7aashj> Home </a><a class="studio__nav-tab" href="/__pyric/ui/firestore" data-astro-cid-mw7aashj> Firestore </a><a class="studio__nav-tab" href="/__pyric/ui/auth" data-astro-cid-mw7aashj> Auth </a><a class="studio__nav-tab" href="/__pyric/ui/rtdb" data-astro-cid-mw7aashj> RTDB </a><a class="studio__nav-tab" href="/__pyric/ui/storage" data-astro-cid-mw7aashj> Storage </a><a class="studio__nav-tab" href="/__pyric/ui/traffic" data-astro-cid-mw7aashj> Traffic </a><a class="studio__nav-tab" href="/__pyric/ui/settings" data-astro-cid-mw7aashj> Settings </a><a class="studio__nav-tab" href="/__pyric/ui/docs" aria-current="page" data-astro-cid-mw7aashj> Docs </a> </nav> </div> </header> <div class="docs-shell" data-astro-cid-mw7aashj> <details class="docs-nav-drawer" data-astro-cid-mw7aashj> <summary data-astro-cid-mw7aashj>Navigate</summary> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <script type="module">let i=null;function d(t){return i||(i=fetch(t).then(e=>e.json())),i}function l(t,e){return t.title.toLowerCase().includes(e)||t.excerpt.toLowerCase().includes(e)?!0:t.headings.some(r=>r.text.toLowerCase().includes(e))}function u(t,e,r){if(e.innerHTML="",t.length===0){e.hidden=!1;{const n=document.createElement("li");n.className="docs-search-empty",n.textContent="No matches",e.appendChild(n)}return}e.hidden=!1;for(const n of t.slice(0,8)){const s=document.createElement("li"),c=document.createElement("a");c.href=n.path;const o=document.createElement("span");o.className="docs-search-result-title",o.textContent=n.title;const a=document.createElement("span");a.className="docs-search-result-meta",a.textContent=[n.group,n.section].filter(Boolean).join(" / "),c.append(o,a),s.appendChild(c),e.appendChild(s)}}document.querySelectorAll(".docs-search").forEach(t=>{const e=t.dataset.indexUrl,r=t.querySelector(".docs-search-input"),n=t.querySelector(".docs-search-results");r.addEventListener("input",async()=>{const s=r.value.trim().toLowerCase();if(!s){n.hidden=!0,n.innerHTML="";return}const{pages:c}=await d(e);r.value.trim().toLowerCase()===s&&u(c.filter(o=>l(o,s)),n)}),r.addEventListener("focus",()=>{d(e),n.childElementCount>0&&(n.hidden=!1)}),r.addEventListener("keydown",s=>{s.key==="Escape"&&(r.value="",n.hidden=!0,n.innerHTML="",r.blur())}),r.addEventListener("blur",()=>{window.setTimeout(()=>{n.hidden=!0},150)})});document.addEventListener("keydown",t=>{if(!(t.metaKey||t.ctrlKey)||t.key.toLowerCase()!=="k")return;const e=[...document.querySelectorAll(".docs-search-input")].find(r=>r.offsetParent!==null);e&&(t.preventDefault(),e.focus(),e.select())});</script> <details class="docs-nav-group"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" open> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/" aria-current="page"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/storage-rules-stdlib-research/"> Storage Rules modules: evidence and design </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Public API coverage </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group"> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div> </div> </details> </nav> </details> <nav class="docs-nav" aria-label="Documentation"> <div class="docs-search" data-index-url="/__pyric/ui/docs/index.json"> <div class="docs-search-field"> <svg class="docs-search-icon" viewBox="0 0 16 16" width="14" height="14" aria-hidden="true"> <path d="M11.5 11.5 15 15M13 7A6 6 0 1 1 1 7a6 6 0 0 1 12 0Z" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"></path> </svg> <input type="text" class="docs-search-input" placeholder="Search docs" aria-label="Search docs" autocomplete="off" spellcheck="false"> <kbd class="docs-search-kbd">⌘K</kbd> </div> <ul class="docs-search-results" hidden></ul> </div> <details class="docs-nav-group" id="nav-group-overview"> <summary>Overview</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/overview/"> Overview </a> </li><li> <a href="/__pyric/ui/docs/tutorial/"> Tutorial </a> </li><li> <a href="/__pyric/ui/docs/examples/"> Examples </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-get-started"> <summary>Get started</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/get-started/start-building/"> Quickstart </a> </li><li> <a href="/__pyric/ui/docs/get-started/how-the-swap-works/"> How the swap works </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-build"> <summary>Build</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/build/authentication/"> Authentication </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-firestore/"> Cloud Firestore </a> </li><li> <a href="/__pyric/ui/docs/build/realtime-database/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-storage/"> Cloud Storage </a> </li><li> <a href="/__pyric/ui/docs/build/cloud-messaging/"> Cloud Messaging </a> </li><li> <a href="/__pyric/ui/docs/build/ai-logic/"> AI Logic </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-secure-debug"> <summary>Secure &amp; debug</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/secure/secure-it-with-rules/"> Security Rules </a> </li><li> <a href="/__pyric/ui/docs/secure/simulate-and-lint/"> Simulate and lint before you deploy </a> </li><li> <a href="/__pyric/ui/docs/secure/write-a-rules-test-suite/"> Write a rules test suite </a> </li><li> <a href="/__pyric/ui/docs/secure/read-a-denial/"> Read a denial and understand it </a> </li><li> <a href="/__pyric/ui/docs/secure/rules-standard-library/"> The rules standard library </a> </li><li> <a href="/__pyric/ui/docs/secure/rtdb-rules-in-typescript/"> RTDB rules in TypeScript </a> </li><li> <a href="/__pyric/ui/docs/secure/firestore-rules-limits/"> Rules limits </a> </li><li> <a href="/__pyric/ui/docs/secure/audit-your-rules/"> Audit rules and data </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading" id="nav-section-secure-debug-examples"> Examples </h2> <ul> <li> <a href="/__pyric/ui/docs/examples/chess/"> Chess showcase </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-observe-shape" open> <summary>Observe &amp; shape</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/" aria-current="page"> Traffic &amp; rule verdicts </a> </li><li> <a href="/__pyric/ui/docs/observe/resolve-runtime-status/"> Runtime status </a> </li><li> <a href="/__pyric/ui/docs/observe/shape-your-data/"> Seed, snapshot, replay </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-ship-test"> <summary>Ship &amp; test</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/ship/ship-to-production/"> Ship to production </a> </li><li> <a href="/__pyric/ui/docs/ship/test-in-node/"> Test in Node </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-work-with-an-agent"> <summary>Work with an agent</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/agent/set-up-your-agent/"> Connect an agent </a> </li><li> <a href="/__pyric/ui/docs/agent/work-with-an-agent/"> Use the MCP tools </a> </li><li> <a href="/__pyric/ui/docs/agent/watch-and-review/"> Watch in Pyric Studio </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-trust"> <summary>Trust</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/trust/versioning-and-compatibility/"> Versioning and the fb tag </a> </li><li> <a href="/__pyric/ui/docs/trust/storage-rules-stdlib-research/"> Storage Rules modules: evidence and design </a> </li><li> <a href="/__pyric/ui/docs/trust/rules-standard-library/"> Rules standard library reference </a> </li> </ul> </div> </div> </details><details class="docs-nav-group" id="nav-group-conformance"> <summary>Conformance</summary> <div class="docs-nav-group-body"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/conformance-scores/"> Public API coverage </a> </li><li> <a href="/__pyric/ui/docs/trust/how-we-know-it-matches-firebase/"> How we know it matches Firebase </a> </li><li> <a href="/__pyric/ui/docs/app-compat/"> App </a> </li><li> <a href="/__pyric/ui/docs/ai-compat/"> AI Logic </a> </li><li> <a href="/__pyric/ui/docs/auth-compat/"> Auth </a> </li><li> <a href="/__pyric/ui/docs/firestore-compat/"> Firestore </a> </li><li> <a href="/__pyric/ui/docs/database-compat/"> Realtime Database </a> </li><li> <a href="/__pyric/ui/docs/storage-compat/"> Storage </a> </li><li> <a href="/__pyric/ui/docs/messaging-compat/"> Messaging </a> </li><li> <a href="/__pyric/ui/docs/functions-rtdb-compat/"> Functions · RTDB </a> </li><li> <a href="/__pyric/ui/docs/rules-compat/"> Rules </a> </li> </ul> </div> </div> </details> <details class="docs-nav-group" id="nav-group-reference"> <summary>Reference</summary> <div class="docs-nav-group-body docs-nav-group-body--reference"> <div class="docs-nav-section"> <ul> <li> <a href="/__pyric/ui/docs/api-reference/"> API reference </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-app-reference-api/"> pyric/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-firestore-reference-api/"> pyric/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-auth-reference-api/"> pyric/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-reference-api/"> pyric/ai </a> </li><li> <a href="/__pyric/ui/docs/pyric-ai-scripting-reference-api/"> pyric/ai/scripting </a> </li><li> <a href="/__pyric/ui/docs/pyric-database-reference-api/"> pyric/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-storage-reference-api/"> pyric/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-reference-api/"> pyric/messaging </a> </li><li> <a href="/__pyric/ui/docs/pyric-messaging-sw-reference-api/"> pyric/messaging/sw </a> </li><li> <a href="/__pyric/ui/docs/pyric-rules-reference-api/"> pyric/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-reference-api/"> pyric/sandbox </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-firestore-reference-api/"> pyric/sandbox/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-sandbox-database-reference-api/"> pyric/sandbox/database </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">pyric-admin</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-admin-app-reference-api/"> pyric-admin/app </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-firestore-reference-api/"> pyric-admin/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-auth-reference-api/"> pyric-admin/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-database-reference-api/"> pyric-admin/database </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-storage-reference-api/"> pyric-admin/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-admin-messaging-reference-api/"> pyric-admin/messaging </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">create-pyric</h2> <ul> <li> <a href="/__pyric/ui/docs/create-pyric-reference-api/"> create-pyric </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/cli</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-cli-credentials-node-reference-api/"> @pyric/cli/credentials/node </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-verify-reference-api/"> @pyric/cli/verify </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-reference-api/"> @pyric/cli/conformance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-browser-reference-api/"> @pyric/cli/conformance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-conformance-docs-reference-api/"> @pyric/cli/conformance/docs </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-reference-api/"> @pyric/cli/assurance </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-assurance-browser-reference-api/"> @pyric/cli/assurance/browser </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-reference-api/"> @pyric/cli/bridge </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-bridge-client-reference-api/"> @pyric/cli/bridge/client </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-discover-reference-api/"> @pyric/cli/discover </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-vite-reference-api/"> @pyric/cli/vite </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-serve-worker-reference-api/"> @pyric/cli/serve/worker </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-remote-reference-api/"> @pyric/cli/remote </a> </li><li> <a href="/__pyric/ui/docs/pyric-cli-register-reference-api/"> @pyric/cli/register </a> </li> </ul> </div><div class="docs-nav-section"> <h2 class="docs-nav-heading">@pyric/ui</h2> <ul> <li> <a href="/__pyric/ui/docs/pyric-ui-auth-reference-api/"> @pyric/ui/auth </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-auth-hooks-reference-api/"> @pyric/ui/auth/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-primitives-reference-api/"> @pyric/ui/primitives </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-reference-api/"> @pyric/ui/firestore </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-firestore-hooks-reference-api/"> @pyric/ui/firestore/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rtdb-reference-api/"> @pyric/ui/rtdb </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-reference-api/"> @pyric/ui/storage </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-storage-hooks-reference-api/"> @pyric/ui/storage/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-reference-api/"> @pyric/ui/traffic </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-traffic-hooks-reference-api/"> @pyric/ui/traffic/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-reference-api/"> @pyric/ui/events </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-events-hooks-reference-api/"> @pyric/ui/events/hooks </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-agents-reference-api/"> @pyric/ui/agents </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-reference-api/"> @pyric/ui/rules </a> </li><li> <a href="/__pyric/ui/docs/pyric-ui-rules-hooks-reference-api/"> @pyric/ui/rules/hooks </a> </li> </ul> </div> </div> </details> </nav> <main class="doc-main" data-astro-cid-mw7aashj> <nav class="docs-breadcrumbs" aria-label="Breadcrumb"> <ol> <li> <a href="/__pyric/ui/docs/observe/see-whats-happening/">Observe &amp; shape</a> </li><li> <span class="docs-breadcrumbs-sep" aria-hidden="true">/</span> <span aria-current="page">Traffic &amp; rule verdicts</span> </li> </ol> </nav> <article class="prose" data-astro-cid-mw7aashj> <h1 id="watch-every-read-write-and-denial-live">Watch every read, write, and denial live</h1>
3
+ <p>Every operation your app performs produces a typed event: the request with its rules verdict, the committed write, the snapshot a listener delivered. You don’t instrument anything. The stream is already there, and you can watch it two ways: in Studio, or with one subscription in code.</p>
4
+ <h2 id="open-the-traffic-view">Open the Traffic view</h2>
5
+ <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="bash"><code><span class="line"><span style="color:#61AFEF">pyric</span><span style="color:#98C379"> dev</span><span style="color:#D19A66"> --ui</span></span></code></pre>
6
+ <p>Studio mounts at <code>/__pyric/ui/</code> on your dev server. The Traffic tab shows the stream live: each request, who made it, the allow or deny verdict, and how long the rules evaluation took. Sign in, write a document, break a rule on purpose. Each one appears as it happens, in the same backend your open tabs are using.</p>
7
+ <h2 id="subscribe-to-the-event-stream">Subscribe to the event stream</h2>
8
+ <p>One subscription covers everything observable:</p>
9
+ <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#C678DD">import</span><span style="color:#ABB2BF"> { </span><span style="color:#E06C75">initializeSandbox</span><span style="color:#ABB2BF"> } </span><span style="color:#C678DD">from</span><span style="color:#98C379"> 'pyric/sandbox'</span><span style="color:#ABB2BF">;</span></span>
10
+ <span class="line"></span>
11
+ <span class="line"><span style="color:#C678DD">const</span><span style="color:#E5C07B"> sandbox</span><span style="color:#56B6C2"> =</span><span style="color:#61AFEF"> initializeSandbox</span><span style="color:#ABB2BF">();</span></span>
12
+ <span class="line"></span>
13
+ <span class="line"><span style="color:#C678DD">const</span><span style="color:#E5C07B"> unsubscribe</span><span style="color:#56B6C2"> =</span><span style="color:#E5C07B"> sandbox</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">onEvent</span><span style="color:#ABB2BF">((</span><span style="color:#E06C75;font-style:italic">event</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#ABB2BF"> {</span></span>
14
+ <span class="line"><span style="color:#E5C07B"> console</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">log</span><span style="color:#ABB2BF">(</span><span style="color:#E5C07B">event</span><span style="color:#ABB2BF">.</span><span style="color:#E06C75">kind</span><span style="color:#ABB2BF">);</span></span>
15
+ <span class="line"><span style="color:#ABB2BF">});</span></span></code></pre>
16
+ <p>The kinds at a glance:</p>
17
+ <div class="table-scroll">
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+ <table><thead><tr><th><code>event.kind</code></th><th>What it tells you</th></tr></thead><tbody><tr><td><code>request</code></td><td>An operation the rules engine evaluated, with <code>result: 'allow' | 'deny'</code>, the identity, and <code>evalMs</code></td></tr><tr><td><code>write</code></td><td>A committed write, with the document’s prior and next state</td></tr><tr><td><code>snapshot_delivery</code></td><td>A listener delivered results to your callback, with added, modified, and removed counts</td></tr><tr><td><code>snapshot_suppressed</code></td><td>A listener woke up but had nothing new to deliver</td></tr><tr><td><code>listener_attach</code> / <code>listener_detach</code> / <code>listener_errored</code></td><td>Listener lifecycle, including denials that silently terminate a stream</td></tr><tr><td><code>session_boundary</code></td><td>A <code>reset()</code> or <code>dispose()</code> happened, so you can segment a persisted stream</td></tr></tbody></table></div>
51
+ <p>Denials are a one-line filter over the same stream:</p>
52
+ <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="ts"><code><span class="line"><span style="color:#E5C07B">sandbox</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">onEvent</span><span style="color:#ABB2BF">((</span><span style="color:#E06C75;font-style:italic">event</span><span style="color:#ABB2BF">) </span><span style="color:#C678DD">=></span><span style="color:#ABB2BF"> {</span></span>
53
+ <span class="line"><span style="color:#C678DD"> if</span><span style="color:#ABB2BF"> (</span><span style="color:#E5C07B">event</span><span style="color:#ABB2BF">.</span><span style="color:#E06C75">kind</span><span style="color:#56B6C2"> ===</span><span style="color:#98C379"> 'request'</span><span style="color:#56B6C2"> &#x26;&#x26;</span><span style="color:#E5C07B"> event</span><span style="color:#ABB2BF">.</span><span style="color:#E06C75">result</span><span style="color:#56B6C2"> ===</span><span style="color:#98C379"> 'deny'</span><span style="color:#ABB2BF">) {</span></span>
54
+ <span class="line"><span style="color:#E5C07B"> console</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">log</span><span style="color:#ABB2BF">(</span><span style="color:#98C379">`</span><span style="color:#C678DD">${</span><span style="color:#E5C07B">event</span><span style="color:#ABB2BF">.</span><span style="color:#E06C75">method</span><span style="color:#C678DD">}</span><span style="color:#C678DD"> ${</span><span style="color:#E5C07B">event</span><span style="color:#ABB2BF">.</span><span style="color:#E06C75">path</span><span style="color:#C678DD">}</span><span style="color:#98C379"> denied for </span><span style="color:#C678DD">${</span><span style="color:#E5C07B">event</span><span style="color:#ABB2BF">.</span><span style="color:#E5C07B">auth</span><span style="color:#ABB2BF">?.</span><span style="color:#E06C75">uid</span><span style="color:#56B6C2"> ??</span><span style="color:#98C379"> 'anonymous'</span><span style="color:#C678DD">}</span><span style="color:#98C379">`</span><span style="color:#ABB2BF">);</span></span>
55
+ <span class="line"><span style="color:#ABB2BF"> }</span></span>
56
+ <span class="line"><span style="color:#ABB2BF">});</span></span></code></pre>
57
+ <p>The subscription survives <code>sandbox.reset()</code>. A <code>session_boundary</code> event fires before each rollover, so a subscriber attached once keeps working across every test.</p>
58
+ <h2 id="when-a-denial-needs-explaining">When a denial needs explaining</h2>
59
+ <p>A <code>deny</code> event is not a bare <code>permission-denied</code> string. It carries the method and path, the identity the rules saw, the reasons, and the request data that was evaluated. That is enough to answer “which rule said no, and what did it see” without adding a single log line. <a href="../../secure/read-a-denial/">Read a denial and understand it</a> walks through one.</p>
60
+ <h2 id="build-a-traffic-monitor">Build a traffic monitor</h2>
61
+ <p>Studio’s Traffic view is a consumer of <code>onEvent</code>, and you can build your own in about seventy lines. Subscribe, format each kind, and you get a terminal log like this:</p>
62
+ <pre class="astro-code one-dark-pro" style="background-color:#282c34;color:#abb2bf; overflow-x: auto;" tabindex="0" data-language="plaintext"><code><span class="line"><span>[#3] request allow set notes/n1 by alice 1.4ms</span></span>
63
+ <span class="line"><span>[#4] write set notes/n1 by alice (was: null)</span></span>
64
+ <span class="line"><span>[#5] snapshot_delivery query notes (+1 ~0 -0) size=1 by alice triggered by set notes/n1</span></span>
65
+ <span class="line"><span>[#7] request deny get notes/n1 by bob 0.2ms Rule #0 (read,write) deny</span></span></code></pre>
66
+ <p>Two things to know before you ship one:</p>
67
+ <ul>
68
+ <li>Listener re-evaluations dominate the raw stream. Default your view to user-origin requests, deliveries, lifecycle, and denials, and put <code>origin: 'listener'</code> traffic behind a toggle.</li>
69
+ <li>Your callback runs synchronously with the operation that produced it, so push heavy work off the hot path with <code>queueMicrotask</code> or a worker.</li>
70
+ </ul>
71
+ <h2 id="inspect-the-backend-through-an-agent">Inspect the backend through an agent</h2>
72
+ <p>An agent doesn’t scroll a panel. It calls <code>sandbox_inspect</code> and gets the current rules, a lint summary, a document census, and the recent requests and denials in one response. That one call replaced a debugging session that once took fifty-one tool calls. See <a href="../../agent/set-up-your-agent/">Set up your agent</a>.</p>
73
+ <h2 id="where-to-go-next">Where to go next</h2>
74
+ <p>Chase a specific denial in <a href="../../secure/read-a-denial/">Read a denial and understand it</a>, or start treating the state you’re watching as source in <a href="../shape-your-data/">Shape your data</a>.</p> </article> </main> <aside class="doc-toc" aria-label="On this page" data-astro-cid-mw7aashj> <h2 class="doc-toc-heading" data-astro-cid-mw7aashj>On this page</h2> <ul data-astro-cid-mw7aashj> <li data-depth="2" data-astro-cid-mw7aashj> <a href="#open-the-traffic-view" data-astro-cid-mw7aashj>Open the Traffic view</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#subscribe-to-the-event-stream" data-astro-cid-mw7aashj>Subscribe to the event stream</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#when-a-denial-needs-explaining" data-astro-cid-mw7aashj>When a denial needs explaining</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#build-a-traffic-monitor" data-astro-cid-mw7aashj>Build a traffic monitor</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#inspect-the-backend-through-an-agent" data-astro-cid-mw7aashj>Inspect the backend through an agent</a> </li><li data-depth="2" data-astro-cid-mw7aashj> <a href="#where-to-go-next" data-astro-cid-mw7aashj>Where to go next</a> </li> </ul> </aside> </div> <script type="module">const a=document.querySelector("[data-api-symbol-filter]"),d=[...document.querySelectorAll("[data-api-symbol-group]")],n=document.querySelector("[data-api-symbol-empty]");a?.addEventListener("input",()=>{const t=a.value.trim().toLowerCase();let o=0;for(const i of d){let e=0;i.querySelectorAll("[data-api-symbol]").forEach(l=>{const r=!t||(l.dataset.apiSymbol??"").includes(t);l.hidden=!r,r&&e++}),i.hidden=e===0,o+=e}n&&(n.hidden=o>0)});</script> <script type="module">const s=new Map;document.querySelectorAll('.doc-toc a[href^="#"]').forEach(t=>s.set(decodeURIComponent(t.hash.slice(1)),t));if(s.size>0){const t=new Set,n=()=>{let o=null;for(const e of s.keys())if(t.has(e)){o=e;break}s.forEach((e,c)=>e.classList.toggle("active",c===o))},r=new IntersectionObserver(o=>{for(const e of o)e.isIntersecting?t.add(e.target.id):t.delete(e.target.id);n()},{rootMargin:"-72px 0px -60% 0px"});s.forEach((o,e)=>{const c=document.getElementById(e);c&&r.observe(c)})}</script> <script type="module">document.querySelector('.studio__nav [aria-current="page"]')?.scrollIntoView({block:"nearest",inline:"center"});</script> </body></html>