pyric/app compatibility matrix
81.3% of the public API supported
13 of 16 public API
Status legend
Conforming — the mirror matches prod, locked by a passing replay
Diverged (documented) — intentional difference with a written reason
Not implemented yet — deliberately or deferred
Unverified — claim from docs not yet observed prod-side
initializeApp(config, name?) — the app registry
initializeApp(config)Registers the default app under the name '[DEFAULT]'; getApps() has length 1 and getApp() (no arg) resolves the same instance
oracle:
app-registry-initializeapp-default (firebase 12.13.0) + replay: oracle-conformance.test.tsinitializeApp(config, 'secondary')Registers a named app alongside the default; getApp('secondary') resolves it and getApps() has length 2 (default + named)
oracle:
app-registry-initializeapp-named (firebase 12.13.0) + replay: oracle-conformance.test.tsinitializeApp(config)A same-name re-initialization with a DIFFERENT config throws FirebaseError code app/duplicate-app, with the app name embedded in the message
oracle:
app-registry-initializeapp-duplicate-name (firebase 12.13.0) + replay: oracle-conformance.test.tsinitializeApp(config)A same-name re-initialization with EQUAL config is idempotent — no throw, returns the existing instance, and getApps() stays length 1
oracle:
app-registry-initializeapp-duplicate-config (firebase 12.13.0) + replay: oracle-conformance.test.tsgetApp()getApp() with no name resolves the default app instance; its name is '[DEFAULT]'
oracle:
app-registry-getapp-default (firebase 12.13.0) + replay: oracle-conformance.test.tsgetApp('secondary')getApp('secondary') resolves the named app instance; its name is 'secondary'
oracle:
app-registry-getapp-named (firebase 12.13.0) + replay: oracle-conformance.test.tsgetApp(name)getApp(name) for a name that was never initialized throws FirebaseError code app/no-app, directing the caller to initializeApp()
oracle:
app-registry-getapp-unknown-name (firebase 12.13.0) + replay: oracle-conformance.test.tsgetApps()getApps() returns an array containing every registered app by identity (the exact instances, not copies)
oracle:
app-registry-getapps-contents (firebase 12.13.0) + replay: oracle-conformance.test.tsdeleteApp(app)deleteApp(app) returns a Promise, deregisters the app (so getApps() shrinks), a later getApp(name) throws app/no-app, and the name can be re-initialized afterwards
oracle:
app-registry-deleteapp (firebase 12.13.0) + replay: oracle-conformance.test.tsdeleteApp(app)deleteApp on an already-deleted app throws FirebaseError code app/app-deleted
oracle:
app-registry-deleteapp-double (firebase 12.13.0) + replay: oracle-conformance.test.tsSDK_VERSIONSDK_VERSION is the Firebase client SDK semver string whose behavior pyric currently mirrors, pinned to the oracle version (12.13.0)
oracle:
app-registry-sdk-version (firebase 12.13.0) + replay: oracle-conformance.test.tsFirebaseErrorFirebaseError is an app-owned Error subclass: instanceof Error, constructor.name is 'FirebaseError', and it preserves .code and .message without loading firebase/app
oracle:
app-registry-firebaseerror-shape (firebase 12.13.0) + replay: oracle-conformance.test.tsonLog / setLogLevelonLog(cb) / setLogLevel(level) are a functioning app-owned diagnostic-logger seam: registering a handler returns undefined, raising the threshold takes effect, and a malformed registerVersion emits a warn entry (type @firebase/app) to the handler
oracle:
app-registry-onlog-setloglevel (firebase 12.13.0) + replay: oracle-conformance.test.tsregisterVersionregisterVersion(library, version) accepts a well-formed registration and returns undefined without throwing; malformed values emit the observed warning through the app-owned logger
oracle:
app-registry-registerversion (firebase 12.13.0) + replay: oracle-conformance.test.tsinitializeServerAppNot implemented; disposition app.server-app owns the reviewed availability and rationale
disposition:app.server-app
initializeApp(options, settings)initializeApp snapshots options, accepts a settings object, initializes automaticDataCollectionEnabled, and leaves that app property mutable
oracle:
app-registry-initializeapp-settings-options (firebase 12.13.0) + replay: oracle-conformance.test.tsinitializeApp(equalOptions, 'secondary')Equal-config named apps are distinct app containers with equal option values and independent name-keyed registry identity
oracle:
app-registry-initializeapp-named-equal-config (firebase 12.13.0) + replay: oracle-conformance.test.tsgetAuth/getFirestore/getDatabase/getStorage(app)Equal-config named apps own distinct app-associated service handles while resolving the same configured RTDB and Storage backend locators
oracle:
app-registry-multi-app-service-containers (firebase 12.13.0) + replay: oracle-conformance.test.tsinitializeApp(differentOptions, 'secondary')Production permits a differently configured named app; Pyric rejects it because one runtime currently owns exactly one sandbox backend
oracle:
app-registry-initializeapp-named-different-config (firebase 12.13.0) + replay pins app/multiple-configs-not-supported; packages/cli/test/e2e/app-multi-app.pw.ts proves the same lock is enforced by the authoritative SharedWorker across same-origin tabs, not only by one page registry (Structured evidence: oracle-conformance.test.ts)deleteApp(app); initializeApp(differentOptions)Production permits a different configuration after deletion; Pyric retains the runtime backend lock and rejects the reinitialization
oracle:
app-registry-delete-reinitialize-different-config (firebase 12.13.0) + replay pins app/multiple-configs-not-supported (Structured evidence: oracle-conformance.test.ts)initializeApp()Without Hosting-provided defaults, omitting options throws FirebaseError code app/no-options with the production message
oracle:
app-registry-initializeapp-no-options (firebase 12.13.0) + replay: oracle-conformance.test.tsgetAuth/getFirestore/getDatabase/getStorage()With a registered default app, each no-argument service factory resolves a service associated with that exact default app
oracle:
app-registry-default-service-factories (firebase 12.13.0) + replay: oracle-conformance.test.tsinitializeApp(equalOptions, name)Equal-config app instances connect to one logical backend: data written through one app is readable through another, while their active Auth sessions remain independent
oracle:
app-production-multi-app-topology (firebase 12.13.0, real Chromium against production) + twin replay: production-multi-app-oracle.test.ts; served SharedWorker replay: app-multi-app.pw.tsdeleteApp(app); app.name / app.options / app.automaticDataCollectionEnabledAfter deletion resolves, every public FirebaseApp property accessor throws FirebaseError code app/app-deleted
oracle:
app-registry-deleted-property-access (firebase 12.13.0) + replay: oracle-conformance.test.tsdeleteApp(app); getAuth/getFirestore/getDatabase/getStorage/getAI(app)After deletion, fresh Auth/Firestore/RTDB/Storage factories reject; cached factories return retained handles; retained Auth sign-out resolves but a new anonymous sign-in rejects app/app-deleted; Firestore reads report termination, RTDB refuses new refs, Storage refs remain constructible, and getAI(deletedApp) returns an app-associated handle
oracles:
app-registry-deleted-service-factories and real-Chromium app-production-multi-app-topology (firebase 12.13.0) + replays: oracle-conformance.test.ts, deleted-service-lifecycle.test.ts, and production-multi-app-oracle.test.tsdeleteApp(app)Deleting one app terminates its Firestore listener through the error callback with code aborted, silently stops its RTDB listener, and leaves equal-config sibling listeners and the shared backend usable
oracle:
app-production-multi-app-topology (firebase 12.13.0, real Chromium against production) + twin replay: production-multi-app-oracle.test.ts; focused family tests: multi-app-listener-auth.test.ts and served app-multi-app.pw.tsgetAI(app, customEngine); deleteApp(app); retainedModel operationServed worker mode rejects page-local custom AnswerEngine objects; a model retained from a deleted app rejects, while an equal-config sibling model remains usable through its own app-scoped worker port
packages/cli/test/e2e/app-deletion.pw.ts observes AI code unsupported for a custom engine, then exercises retained and sibling models through canonical served imports after deleting one app; packages/pyric/src/ai/sandbox-plane.ts guards every model operation. A credentialed production AI lifecycle capture is still neededCurrent gaps
Documented divergences
Known differences between Pyric and production Firebase. Each remains tracked as a non-conforming row.
initializeApp(differentOptions, 'secondary')Production permits a differently configured named app; Pyric rejects it because one runtime currently owns exactly one sandbox backend
oracle:
app-registry-initializeapp-named-different-config (firebase 12.13.0) + replay pins app/multiple-configs-not-supported; packages/cli/test/e2e/app-multi-app.pw.ts proves the same lock is enforced by the authoritative SharedWorker across same-origin tabs, not only by one page registry (Structured evidence: oracle-conformance.test.ts)deleteApp(app); initializeApp(differentOptions)Production permits a different configuration after deletion; Pyric retains the runtime backend lock and rejects the reinitialization
oracle:
app-registry-delete-reinitialize-different-config (firebase 12.13.0) + replay pins app/multiple-configs-not-supported (Structured evidence: oracle-conformance.test.ts)Not implemented yet
Tracked behavior that is not implemented in the current contract.
initializeServerAppNot implemented; disposition app.server-app owns the reviewed availability and rationale
disposition:app.server-app
Unverified
Tracked behavior whose available evidence does not yet establish the production result.
getAI(app, customEngine); deleteApp(app); retainedModel operationServed worker mode rejects page-local custom AnswerEngine objects; a model retained from a deleted app rejects, while an equal-config sibling model remains usable through its own app-scoped worker port
packages/cli/test/e2e/app-deletion.pw.ts observes AI code unsupported for a custom engine, then exercises retained and sibling models through canonical served imports after deleting one app; packages/pyric/src/ai/sandbox-plane.ts guards every model operation. A credentialed production AI lifecycle capture is still neededReviewed public-runtime gaps
app.server-appServer-app (SSR) initialization: a FirebaseServerApp carries per-request auth/heartbeat state with no decided sandbox mirror pattern yet. Deferred, not out of scope — tracked as an unsupported registry row (registry/app.ts app#15).
initializeServerAppregistry:app#15