diff --git a/okf-bundle/ci-workflows/android.md b/okf-bundle/ci-workflows/android.md new file mode 100644 index 000000000..f834b75d5 --- /dev/null +++ b/okf-bundle/ci-workflows/android.md @@ -0,0 +1,46 @@ +--- +type: Reference +title: Android CI workflow +description: Shape and triage notes for .github/workflows/android.yml. +tags: [ci, gradle, android] +timestamp: 2026-07-31T00:00:00Z +--- + +# Android CI + +Workflow: [.github/workflows/android.yml](../../.github/workflows/android.yml) + +## Triggers + +- `pull_request` +- `push` + +## Job shape + +| Step | Detail | +|------|--------| +| Runner | `ubuntu-latest`, 30m timeout | +| Checkout | `actions/checkout` (pinned) | +| Cache | `~/.gradle/caches`, `~/.gradle/wrapper` keyed on Gradle files | +| JDK | Temurin **21** | +| Build | `./scripts/build.sh` | +| On failure | `./scripts/print_build_logs.sh` | + + + +## What `build.sh` runs + +Canonical owner for the CI unit-path step list. Script: [scripts/build.sh](../../scripts/build.sh). + +1. Copy `library/google-services.json` → `app/` and `proguard-tests/` +2. `./gradlew --max-workers=2 clean` +3. `./gradlew --max-workers=2 assembleDebug` +4. `./gradlew --max-workers=2 checkstyle` +5. `./gradlew --max-workers=2 testDebugUnitTest -x :e2eTest:testDebugUnitTest` + +`proguard-tests:build` is currently commented out (re-enable before release). Green Android CI does **not** prove ProGuard/R8 packaging. + +## Agent notes + +- Match this path locally with `./scripts/build.sh` — [agent command policy](../testing/agent-command-policy.md). +- Do not treat this job as e2e coverage; that is [e2e.md](e2e.md). diff --git a/okf-bundle/ci-workflows/e2e.md b/okf-bundle/ci-workflows/e2e.md new file mode 100644 index 000000000..74a812078 --- /dev/null +++ b/okf-bundle/ci-workflows/e2e.md @@ -0,0 +1,35 @@ +--- +type: Reference +title: E2E CI workflow +description: Shape and triage notes for .github/workflows/e2e_test.yml. +tags: [ci, e2e, emulator, auth] +timestamp: 2026-07-31T00:00:00Z +--- + +# E2E CI + +Workflow: [.github/workflows/e2e_test.yml](../../.github/workflows/e2e_test.yml) + +## Triggers + +- `pull_request` only (not `push`) + +## Job shape + +| Step | Detail | +|------|--------| +| Runner | `ubuntu-latest`, 30m timeout | +| Checkout | `actions/checkout` (pinned) | +| Caches | Gradle caches/wrapper; `~/.cache/firebase/emulators` | +| Node | **20** | +| JDK | Temurin **21** | +| Tools | `npm i -g firebase-tools` | +| Emulator | `./scripts/start-firebase-emulator.sh` (`CI` set → background + readiness poll) | +| Tests | `./gradlew e2eTest` | +| On failure | `./scripts/print_build_logs.sh` | + +## Agent notes + +- Local procedure and suite semantics: [running e2e](../testing/running-e2e.md). +- Auth emulator only — do not invent multi-emulator CI. +- Unit CI excludes `:e2eTest`; this job is the canonical e2e gate for Auth UI changes. diff --git a/okf-bundle/ci-workflows/index.md b/okf-bundle/ci-workflows/index.md new file mode 100644 index 000000000..10d0cafb9 --- /dev/null +++ b/okf-bundle/ci-workflows/index.md @@ -0,0 +1,19 @@ +# CI workflows + +GitHub Actions job shape and failure triage for FirebaseUI-Android. + +## Jobs + +* [Android CI](android.md) — `android.yml`: JDK 21, Gradle cache, `./scripts/build.sh` +* [E2E Tests](e2e.md) — `e2e_test.yml`: firebase-tools, Auth emulator, `./gradlew e2eTest` + +## Shared dependencies + +* [Agent command policy](../testing/agent-command-policy.md) — allowlisted commands for agents +* [Running e2e — e2e agent rule](../testing/running-e2e.md#e2e-agent-rule) — emulator + `e2eTest` only +* [Validation checklist](../testing/validation-checklist.md) — local handoff sequence matching CI + +## Related + +* [Running e2e tests](../testing/running-e2e.md) — local runbook +* [Repo tooling](../repo-tooling/index.md) — Gradle modules, versioning diff --git a/okf-bundle/documentation-policy.md b/okf-bundle/documentation-policy.md new file mode 100644 index 000000000..54739080f --- /dev/null +++ b/okf-bundle/documentation-policy.md @@ -0,0 +1,74 @@ +--- +type: Reference +title: OKF documentation and commit policy +description: Canonical rules for durable vs ephemeral knowledge, commit messages, and post-update bundle consistency. +tags: [okf, documentation, policy, commits, work-queue] +timestamp: 2026-07-31T00:00:00Z +--- + +# OKF documentation and commit policy + +Single source of truth for OKF knowledge and commit wording. Other OKF docs/work queues link here; do not restate. + +## Durable vs ephemeral + +| Kind | Where it lives | What it contains | +|------|----------------|------------------| +| **Durable** | OKF reference docs (design, runbooks, registries, workflows) | Stable API names, module layout, SDK/tooling versions, verification **methods**, architecture, canonical commands | +| **Ephemeral** | Explicit **work-queue** docs only | Session phase/probe IDs, **planned commit subjects** (`commit_subject`), gate state, `next_work_type`, snapshot labels, dated banners, run counts | + +**Rules** + +1. General OKF docs get **durable only** updates: no phase IDs, **commit subjects**, session e2e counts, or gate snapshots. +2. Ephemeral state lives **only** in work queues. When an item closes, durable outcomes move to reference docs; queue rows may archive/delete. +3. Durable docs may link to a work queue for current status; do not duplicate ephemeral fields. +4. Create a work-queue doc only when active cross-cutting work needs gate tracking. Do not invent empty queues for completed migrations. + +## Commits as documentation + +We treat **git commits** as durable documentation: they are the canonical record of what changed, when, and why — for humans and agents reviewing history later, not only for the current PR thread. + +Commit messages use [Conventional Commits](https://www.conventionalcommits.org/) and describe durable product/process deliverables: what changed and why, not probe IDs, gates, e2e counts, or “phase X complete”. + +Scopes commonly used in this repo: `auth`, `firestore`, `database`, `storage`, `common`, `ci`, `deps`, `docs`. Prefer the Gradle module name when the change is module-scoped. + +Examples from [CONTRIBUTING.md](../CONTRIBUTING.md): + +```text +fix(auth): fixed a bug with email sign-in! +feat(auth): add support for passkey authentication +``` + +## Pull requests + +When a PR contains **exactly one commit**, the **PR title must match that commit's subject line exactly** (character-for-character). Multi-commit PRs use a summary title that describes the overall change set. + +PR process expectations live in [.github/PULL_REQUEST_TEMPLATE.md](../.github/PULL_REQUEST_TEMPLATE.md) and [CONTRIBUTING.md](../CONTRIBUTING.md). New features that affect Auth UX should consider [FirebaseUI-iOS](https://github.com/firebase/FirebaseUI-iOS) parity. + +## OKF update contract + +OKF markdown edits require an **independent bundle consistency pass**. Use a fresh context with: + +1. A short summary of what changed and which files were touched. +2. Instruction to scan the **entire** `okf-bundle/` tree. + +Confirm: + +| Check | Requirement | +|-------|-------------| +| **Canonical location** | Each topic has one owning doc; others link to it ([agent command policy](testing/agent-command-policy.md) for **all** agent shell commands; [change authoring](testing/change-authoring-workflow.md) for workflow/gates/frozen tree; [change authoring § validation evidence (blocking)](testing/change-authoring-workflow.md#validation-evidence-blocking); [running e2e](testing/running-e2e.md) for emulator + `e2eTest` detail; [iteration vocabulary](testing/iteration-vocabulary.md) for term ids only; [validation checklist](testing/validation-checklist.md) for command sequence; this file for doc/commit policy) | +| **DRY** | No duplicated procedures, policy paragraphs, or ephemeral snapshots outside work queues | +| **Link hygiene** | Cross-links resolve; indexes list canonical entry points | +| **Durability** | No ephemeral fields leaked into general reference docs | + +Fix violations before handoff/merge. Work-queue edits still follow this split. + +## Work-queue documents + +Work queues are **intentionally ephemeral**: phases, **commit subjects**, gates, active coordination. They are not policy or finalized registry/design homes. + +Work queues record **gates**, **`next_work_type`**, **`validation_tier`**, and **`commit_subject`** using field names and allowed values from [iteration vocabulary](testing/iteration-vocabulary.md). Gate semantics and workflow rules: [change authoring workflow](testing/change-authoring-workflow.md). They do **not** name agent roles, dispatch instructions, or session choreography — those are out of scope for the public repo. + +Record **`commit_subject`** (the planned Conventional Commit subject line) **before** `git commit`, in the same staged changeset as the item being memorialized. Do not record SHAs — they are unstable under history rewrite. After commit, the subject in git and in the queue must match character-for-character ([PR title rule](#pull-requests) for single-commit PRs). + +New work queues link here in frontmatter/opening section; do not copy policy inline. diff --git a/okf-bundle/index.md b/okf-bundle/index.md new file mode 100644 index 000000000..cf5a5a894 --- /dev/null +++ b/okf-bundle/index.md @@ -0,0 +1,29 @@ +--- +okf_version: '0.1' +--- + +# FirebaseUI-Android knowledge bundle + +Agent-oriented knowledge for [firebase/FirebaseUI-Android](https://github.com/firebase/FirebaseUI-Android). Human-facing docs stay in `README.md`, `CONTRIBUTING.md`, module READMEs, and `docs/`. + +- [Documentation/commit policy](/documentation-policy.md) — durable vs ephemeral, commits as documentation, PR titles, OKF consistency + +# CI workflows + +- [CI workflows](/ci-workflows/index.md) — GitHub Actions job shape (`android.yml`, `e2e_test.yml`), failure log triage + +# Testing + +- [Agent command policy](/testing/agent-command-policy.md) — allowlisted shell commands for agents (Gradle, scripts, emulator, validation) +- [Change authoring workflow](/testing/change-authoring-workflow.md) — verified product change loop (unit-focused → area-focused review → commit); [§ validation evidence (blocking)](/testing/change-authoring-workflow.md#validation-evidence-blocking) +- [Iteration vocabulary](/testing/iteration-vocabulary.md) — work type, tier, and queue field identifiers +- [Running e2e tests](/testing/running-e2e.md) — Auth emulator + `./gradlew e2eTest` +- [Validation checklist](/testing/validation-checklist.md) — assemble, checkstyle, unit tests, e2e + +# Modules + +- [Modules](/modules/index.md) — auth, firestore, database, storage, common, and supporting Gradle modules + +# Repo tooling + +- [Repo tooling](/repo-tooling/index.md) — Gradle layout, versioning (`Config.kt`), release/branch pointers diff --git a/okf-bundle/modules/auth.md b/okf-bundle/modules/auth.md new file mode 100644 index 000000000..e96b686da --- /dev/null +++ b/okf-bundle/modules/auth.md @@ -0,0 +1,55 @@ +--- +type: Reference +title: Auth module notes +description: Durable agent notes for firebase-ui-auth (Compose, configuration DSL, MFA, Credential Manager, tests). +tags: [auth, compose, modules] +timestamp: 2026-07-31T00:00:00Z +--- + +# `:auth` — firebase-ui-auth + +Primary Auth UI library. **v10+** is Kotlin + Jetpack Compose + Material 3 (breaking vs 9.x Views). + +## Layout + +| Path | Role | +|------|------| +| `com.firebase.ui.auth` | Core entrypoints (`FirebaseAuthUI`, flow/state types) | +| `…/configuration` | `authUIConfiguration {}` DSL, `AuthProvider.*`, theme, validators, string provider | +| `…/ui/screens` | Compose screens (`FirebaseAuthScreen`, email/phone/MFA, etc.) | +| `…/ui/components` | Shared Compose widgets | +| `…/ui/method_picker` | Provider picker | +| `…/credentialmanager` | Android Credential Manager / password credentials | +| `…/mfa` | MFA enrollment/challenge support | +| `…/data`, `…/util` | Supporting types/helpers | + +Unit tests: `auth/src/test/…`. E2e: `e2eTest/src/test/…` — [running e2e](../testing/running-e2e.md). + +## Public integration surfaces + +Agents changing Auth should know both consumer APIs (do not break without migration notes): + +1. **High-level** — `FirebaseAuthScreen` + `authUIConfiguration { }` (Compose-first). +2. **Low-level** — `AuthFlowController` for Activity-hosted flows. + +Consumer setup skill (outside this repo’s product code): `.agents/skills/firebaseui-android-getting-started/SKILL.md`. + +Human docs: [auth/README.md](../../auth/README.md), [docs/upgrade-to-10.0.md](../../docs/upgrade-to-10.0.md). + +## Validation + +Tier commands and handoff sequence: [validation checklist](../testing/validation-checklist.md). Auth UI / emulator path requires e2e — [running e2e § when required](../testing/running-e2e.md#when-e2e-is-required). Allowlist: [agent command policy](../testing/agent-command-policy.md). + +## Architectural facts (durable) + +- Configuration is Kotlin DSL (`AuthProvider.Email()`, etc.), not 9.x `IdpConfig` builders. +- Theming uses `AuthUITheme` / Material 3, not XML Auth themes as the primary path. +- State is reactive (`Flow`-oriented Auth state), not only `AuthStateListener` callbacks. +- Credential Manager integration lives under `credentialmanager/` — treat password-save/retrieve as Auth-critical surface. +- MFA (SMS/TOTP) has dedicated screens and e2e coverage (`MfaEnrollmentScreenTest`, `MfaChallengeScreenTest`, …). + +## Related + +* [Modules index](index.md) +* [E2e CI](../ci-workflows/e2e.md) +* [Change authoring](../testing/change-authoring-workflow.md) diff --git a/okf-bundle/modules/common.md b/okf-bundle/modules/common.md new file mode 100644 index 000000000..e63013833 --- /dev/null +++ b/okf-bundle/modules/common.md @@ -0,0 +1,26 @@ +--- +type: Reference +title: Common module notes +description: Durable agent notes for shared firebase-ui-common adapter primitives. +tags: [common, modules] +timestamp: 2026-07-31T00:00:00Z +--- + +# `:common` — firebase-ui-common + +Published shared Java primitives used by Firestore and Realtime Database UI adapters (`POM_ARTIFACT_ID=firebase-ui-common`). Not a primary consumer README surface like auth/firestore/database/storage — treat it as a shared library dependency those modules consume. + +## Key types + +| Type | Role | +|------|------| +| `BaseObservableSnapshotArray` | Base observable snapshot list | +| `BaseCachingSnapshotParser` / `BaseSnapshotParser` | Parser bases | +| `BaseChangeEventListener` / `ChangeEventType` | Change-event plumbing | +| `Preconditions` | Shared precondition helpers | + +## Validation + +No `src/test` / `androidTest` today — empty-suite trap: [agent command policy](../testing/agent-command-policy.md#empty-unit-suite-trap). Commands and tiers: [validation checklist](../testing/validation-checklist.md) (module matrix). + +**Module-specific:** changes here can break `:firestore` and `:database`. Prefer also running `./gradlew :firestore:testDebugUnitTest` (real JVM suite) when the shared API is consumed there. Database has no JVM unit suite — [database.md](database.md). diff --git a/okf-bundle/modules/database.md b/okf-bundle/modules/database.md new file mode 100644 index 000000000..a3243f848 --- /dev/null +++ b/okf-bundle/modules/database.md @@ -0,0 +1,35 @@ +--- +type: Reference +title: Database module notes +description: Durable agent notes for firebase-ui-database adapters and paging. +tags: [database, modules] +timestamp: 2026-07-31T00:00:00Z +--- + +# `:database` — firebase-ui-database + +Java library binding Realtime Database references to RecyclerView / ListView (and AndroidX Paging). + +## Key types + +| Type | Role | +|------|------| +| `FirebaseRecyclerAdapter` | RecyclerView adapter | +| `FirebaseListAdapter` | ListView adapter | +| `FirebaseRecyclerOptions` / `FirebaseListOptions` | Options builders | +| `FirebaseArray` / `FirebaseIndexArray` | Observable arrays (including indexed keys/values) | +| `SnapshotParser` family | Snapshot → model mapping | +| `paging/*` | Paging adapters/sources | + +Human docs: [database/README.md](../../database/README.md). + +## Tests / validation + +- No JVM `src/test`. Instrumented tests live under `database/src/androidTest` (human/device only — not CI / not allowlisted). +- Empty-suite trap: [agent command policy](../testing/agent-command-policy.md#empty-unit-suite-trap). +- Commands and tiers: [validation checklist](../testing/validation-checklist.md) (module matrix). + +## Related + +* Shared primitives: [common.md](common.md) +* Firestore counterpart: [firestore.md](firestore.md) diff --git a/okf-bundle/modules/firestore.md b/okf-bundle/modules/firestore.md new file mode 100644 index 000000000..17e600e4d --- /dev/null +++ b/okf-bundle/modules/firestore.md @@ -0,0 +1,35 @@ +--- +type: Reference +title: Firestore module notes +description: Durable agent notes for firebase-ui-firestore adapters and paging. +tags: [firestore, modules] +timestamp: 2026-07-31T00:00:00Z +--- + +# `:firestore` — firebase-ui-firestore + +Java library binding Cloud Firestore queries to RecyclerView (and AndroidX Paging). + +## Key types + +| Type | Role | +|------|------| +| `FirestoreRecyclerAdapter` | Lifecycle-aware RecyclerView adapter | +| `FirestoreRecyclerOptions` | Query/options builder for the adapter | +| `FirestoreArray` / `ObservableSnapshotArray` | Observable snapshot list | +| `SnapshotParser` / `ClassSnapshotParser` / `CachingSnapshotParser` | Document → model mapping | +| `paging/*` (`FirestorePagingAdapter`, `FirestorePagingSource`, …) | AndroidX Paging integration | + +Human docs: [firestore/README.md](../../firestore/README.md). + +## Tests / validation + +- JVM unit suite: `firestore/src/test` +- Instrumented: `firestore/src/androidTest` — human/device only (not CI / not allowlisted) +- Tier commands and evidence: [validation checklist](../testing/validation-checklist.md) +- Auth emulator e2e is **not** required for Firestore-only changes — [running e2e § when required](../testing/running-e2e.md#when-e2e-is-required) + +## Related + +* Shared adapter primitives: [common.md](common.md) +* Parallel Realtime Database adapters: [database.md](database.md) diff --git a/okf-bundle/modules/index.md b/okf-bundle/modules/index.md new file mode 100644 index 000000000..ee3af3980 --- /dev/null +++ b/okf-bundle/modules/index.md @@ -0,0 +1,30 @@ +# Modules + +Published library modules and supporting Gradle projects. Human-facing usage docs: module `README.md` files and [docs/](../../docs/). + +## Published libraries + +| Module | Artifact | Language / UI | OKF notes | +|--------|----------|---------------|-----------| +| `:auth` | `firebase-ui-auth` | Kotlin, Jetpack Compose (v10+) | [auth.md](auth.md) | +| `:firestore` | `firebase-ui-firestore` | Java, RecyclerView / Paging | [firestore.md](firestore.md) | +| `:database` | `firebase-ui-database` | Java, RecyclerView / ListView / Paging | [database.md](database.md) | +| `:storage` | `firebase-ui-storage` | Java, Glide | [storage.md](storage.md) | +| `:common` | `firebase-ui-common` | Java (shared adapter primitives) | [common.md](common.md) | + +Version and SDK floors: `buildSrc/.../Config.kt` — [repo tooling](../repo-tooling/index.md). + +## Supporting modules + +| Module | Role | +|--------|------| +| `:library` | Umbrella / publish aggregation (`prepareArtifacts`) | +| `:app` | Demo app (Auth Compose sample) | +| `:e2eTest` | Auth emulator e2e (Robolectric + Compose UI test) | +| `:proguard-tests` | R8/ProGuard packaging checks (disabled in CI unit path — [Android CI](../ci-workflows/android.md)) | +| `:lint`, `:internal:lint`, `:internal:lintchecks` | Custom lint plumbing | +| `buildSrc` | Shared `Config` (version, SDK levels, submodule list) | + +## Cross-cutting note (v10 Auth) + +FirebaseUI Auth **10.x** is a Compose rewrite (breaking vs 9.x Views). User migration: [docs/upgrade-to-10.0.md](../../docs/upgrade-to-10.0.md). Firestore/database/storage remain View-based; there is no active Compose migration work-queue for those modules unless one is opened later ([documentation policy § work queues](../documentation-policy.md#work-queue-documents)). diff --git a/okf-bundle/modules/storage.md b/okf-bundle/modules/storage.md new file mode 100644 index 000000000..f82e56320 --- /dev/null +++ b/okf-bundle/modules/storage.md @@ -0,0 +1,20 @@ +--- +type: Reference +title: Storage module notes +description: Durable agent notes for firebase-ui-storage Glide integration. +tags: [storage, modules] +timestamp: 2026-07-31T00:00:00Z +--- + +# `:storage` — firebase-ui-storage + +Small Java library integrating Firebase Storage with Glide (`FirebaseImageLoader` and related image loading types under `…/storage/images`). + +## Agent notes + +- Consumers must register an `AppGlideModule` — see [storage/README.md](../../storage/README.md). +- Keep the surface minimal; prefer fixing loader/Glide contract bugs with unit tests under `storage/src/test`. + +## Validation + +JVM unit suite under `storage/src/test`. Tier commands and evidence: [validation checklist](../testing/validation-checklist.md). Auth emulator e2e is not in scope for Storage-only changes — [running e2e § when required](../testing/running-e2e.md#when-e2e-is-required). diff --git a/okf-bundle/repo-tooling/index.md b/okf-bundle/repo-tooling/index.md new file mode 100644 index 000000000..1a6c2c7e0 --- /dev/null +++ b/okf-bundle/repo-tooling/index.md @@ -0,0 +1,44 @@ +--- +type: Reference +title: Repo tooling +description: Gradle multi-module layout, versioning, and release/branch pointers for FirebaseUI-Android. +tags: [gradle, tooling, release] +timestamp: 2026-07-31T00:00:00Z +--- + +# Repo tooling + +## Gradle layout + +- Root build: `build.gradle.kts`, `settings.gradle`, `gradle.properties`, Wrapper via `./gradlew` +- Version catalog: `gradle/libs.versions.toml` +- Shared constants: `buildSrc/src/main/kotlin/Config.kt` + - `Config.version` (e.g. `10.0.0-beta03`) + - `Config.submodules` = `auth`, `common`, `firestore`, `database`, `storage` + - `Config.SdkVersions` — compile / target / min +- Checkstyle: `library/quality/checkstyle.xml` +- Included modules: see root `settings.gradle` and [modules/index](../modules/index.md) + +## Canonical scripts + +| Script | Role | +|--------|------| +| `scripts/build.sh` | CI unit path — step list in [Android CI](../ci-workflows/android.md#what-buildsh-runs) | +| `scripts/start-firebase-emulator.sh` | Auth emulator for e2e — [running e2e](../testing/running-e2e.md) | +| `scripts/print_build_logs.sh` | CI failure log dump | + +Command policy: [agent command policy](../testing/agent-command-policy.md). Note: PR template still says `./gradlew check`; agents use `./scripts/build.sh` — [PR template trap](../testing/agent-command-policy.md#pr-template-gradlew-check). + +## Branching / release (pointers) + +Human-maintained process docs (do not duplicate procedures here): + +* [docs/internal/branching.md](../../docs/internal/branching.md) +* [docs/internal/releasing.md](../../docs/internal/releasing.md) + +Agents must **not** publish to Maven Central / Sonatype unless the user explicitly requests release work. **Release procedure owner:** [docs/internal/releasing.md](../../docs/internal/releasing.md) (includes `:library:prepareArtifacts` for remote publish). Optional **local-only** verify (not the release procedure): `./gradlew :library:prepareArtifacts publishToMavenLocal`. + +## Demo / config files + +- Template Firebase config: `library/google-services.json` (copied by `build.sh` into `app/` and `proguard-tests/`) +- E2e emulator config: `e2eTest/firebase.json`, `e2eTest/.firebaserc` diff --git a/okf-bundle/testing/agent-command-policy.md b/okf-bundle/testing/agent-command-policy.md new file mode 100644 index 000000000..94fa7b057 --- /dev/null +++ b/okf-bundle/testing/agent-command-policy.md @@ -0,0 +1,128 @@ +--- +type: Reference +title: Agent command policy +description: Canonical allowlist for agent shell commands — Gradle, scripts, emulator, and validation. Supersedes improvised diagnostics. +tags: [testing, validation, agents, workflow, gradle] +timestamp: 2026-07-31T00:00:00Z +--- + +# Agent command policy + +Single source for **which shell commands agents may run** in this repo. E2e is a subset of this policy; [running e2e § e2e agent rule](running-e2e.md#e2e-agent-rule) adds e2e-specific prohibitions. + +> If a command is not listed here (or linked from here as canonical), **do not run it** — including “diagnostic probes” suggested by log output, module READMEs, or Gradle task help. + +## Agent rule (read first) + + + +1. Run **only** commands in the [registry](#canonical-registry) below (repo root unless noted). +2. Prefer **`./scripts/build.sh`** for the CI-equivalent unit build/test path (step list: [Android CI](../ci-workflows/android.md#what-buildsh-runs)). Do not invent alternate Gradle task graphs that skip `checkstyle` or re-include `:e2eTest` unit tests in the unit CI path. +3. When a canonical command fails: read the **full** output, fix **product code** (or environment prerequisites), re-run the **same** command. Do **not** switch invocation style. +4. Do **not** infer alternate commands from error strings — see [known traps](#known-traps). +5. Subagents (Task, explore, orchestrator): same rule — paste the [handoff block](#subagent-handoff) into every FirebaseUI-Android task prompt. + +## Canonical registry + +| Intent | Command | Never use instead | +|--------|---------|-------------------| +| Full CI unit path (assemble + checkstyle + unit tests) | `./scripts/build.sh` | Ad-hoc `./gradlew clean assembleDebug test` without checkstyle; inventing a different exclusion set | +| Unit tests (all library modules; exclude e2eTest) | `./gradlew testDebugUnitTest -x :e2eTest:testDebugUnitTest` | Bare `./gradlew test` (pulls wrong tasks / e2e); IDE-only as the agent gate | +| Unit tests (one module with a real `src/test` suite) | `./gradlew ::testDebugUnitTest` (e.g. `:auth:testDebugUnitTest`, `:firestore:…`, `:storage:…`) | `:common:testDebugUnitTest` / `:database:testDebugUnitTest` as “green” evidence (empty suites — [empty unit-suite trap](#empty-unit-suite-trap)); full suite when only one module changed *as a substitute for* the CI path at handoff | +| Assemble one module (when no JVM unit suite) | `./gradlew ::assembleDebug` (e.g. `:database`, `:common`) | Treating empty `testDebugUnitTest` as validation | +| Checkstyle | `./gradlew checkstyle` | Invented ktlint/detekt entrypoints; editing files without re-running checkstyle when Java/Kotlin style is in scope | +| Assemble debug | `./gradlew assembleDebug` | Module-scoped assemble as the only CI substitute at handoff | +| Install demo app | `./gradlew :app:installDebug` | Manual APK sideload scripts | +| Start Auth emulator (e2e prerequisite) | `./scripts/start-firebase-emulator.sh` | Bare `firebase emulators:start` with invented flags/ports; starting Firestore/Database emulators “just in case” | +| E2e suite | `./gradlew e2eTest` (emulator already up) | `./gradlew :e2eTest:testDebugUnitTest` as a silent substitute without understanding the custom task; inventing Espresso/`connectedCheck` for this suite | +| CI failure logs | `./scripts/print_build_logs.sh` | Truncating Gradle logs / guessing from partial output | +| Local Maven publish (optional local verify only) | `./gradlew :library:prepareArtifacts publishToMavenLocal` | Treating this as the Maven Central release procedure ([releasing.md](../../docs/internal/releasing.md) owns release); remote publish unless the user explicitly requested a release | +| Validation sequence | [validation checklist](validation-checklist.md) | Partial one-off task lists that omit checkstyle or the e2e exclusion | + +### JDK / tooling floor + +- **JDK 21+** (CI uses Temurin 21) — [CONTRIBUTING.md](../../CONTRIBUTING.md). +- **Android SDK** with min API aligned to `Config.SdkVersions.min` in `buildSrc`. +- E2e also needs **Node.js**, **npm**, **firebase-tools**, and **jq** (script preflights firebase/node/npm; `jq` is required to parse `e2eTest/.firebaserc` / `firebase.json` but is not preflight-checked — [running e2e](running-e2e.md)). + +### `google-services.json` copy + +`./scripts/build.sh` copies `library/google-services.json` → `app/` and `proguard-tests/`. Prefer the script over hand-copying. Replace `library/google-services.json` only when intentionally pointing the demo/proguard modules at a different Firebase project. + +## When a Gradle command fails + +1. Re-run from repo root with the **same** canonical command (full log — do not truncate). On CI-shaped failures, also run `./scripts/print_build_logs.sh`. +2. Fix **product code** or missing prerequisites (JDK, SDK, emulator online). +3. Re-run the **same** command. +4. Do **not** “verify tooling” with invented Gradle flags, alternate tasks, or skipping checkstyle. + +## Forbidden (always) + +| Command / pattern | Why | +|-------------------|-----| +| Improvised `./gradlew …` graphs not in the registry or validation checklist | Wrong task / cwd / exclusions; invents CI that does not match `.github/workflows` | +| Including `:e2eTest:testDebugUnitTest` in the unit CI path without an emulator | E2e suite expects Auth emulator; unit CI explicitly excludes it (`scripts/build.sh`) | +| Bare `firebase emulators:start` with custom ports | Ports and project ID come from `e2eTest/firebase.json` / `.firebaserc` via the start script | +| `connectedAndroidTest` / device Espresso as a substitute for `e2eTest` | Canonical e2e is Robolectric + emulator via `./gradlew e2eTest` | +| Invented formatters (`ktlintFormat`, random `spotlessApply`) as the style gate | Canonical style gate is `./gradlew checkstyle` | +| Publishing to Maven Central / Sonatype unless the user explicitly requested a release | Release process is human-gated — [repo tooling](../repo-tooling/index.md) | + +## Known traps + + + +### e2eTest vs unit exclusion + +- **Unit CI** runs `testDebugUnitTest -x :e2eTest:testDebugUnitTest`. +- **E2e CI** starts the Auth emulator, then runs the custom Gradle task **`e2eTest`** (registered in `e2eTest/build.gradle.kts`), not a connected device suite. +- Running `:e2eTest:testDebugUnitTest` without the emulator is not the CI e2e path. + + + +### Empty unit-suite trap (`:common`, `:database`) + +- `:common` has **no** test source set. `:database` has **only** `androidTest` (no `src/test`). +- `./gradlew :common:testDebugUnitTest` / `:database:testDebugUnitTest` can exit **0 with zero tests** — that is **not** validation evidence. +- Modules with real JVM unit suites today: `:auth`, `:firestore`, `:storage` (and `:e2eTest` via the custom `e2eTest` task, not the unit CI path). +- Instrumented `connectedAndroidTest` is forbidden as an Auth e2e substitute and is **not** an allowlisted database/firestore gate (not run in `android.yml`). Module matrix: [validation checklist](validation-checklist.md#module-validation-matrix). + + + +### PR template `./gradlew check` + +- [.github/PULL_REQUEST_TEMPLATE.md](../../.github/PULL_REQUEST_TEMPLATE.md) mentions `./gradlew check` (stale vs current CI). +- **Agents:** treat **`./scripts/build.sh`** as the CI-matching unit path — [Android CI](../ci-workflows/android.md). Full handoff (including e2e when Auth UI touched): [validation checklist](validation-checklist.md). + +### ProGuard tests disabled in build.sh + +- See [Android CI § `build.sh`](../ci-workflows/android.md#what-buildsh-runs) — `proguard-tests:build` is commented out; green unit CI does not prove ProGuard/R8. + +### Emulator foreground vs CI + +- Locally, `./scripts/start-firebase-emulator.sh` runs the emulator in the **foreground** (blocking). Start it in a separate terminal (or backgrounded shell the agent can leave running), then run `./gradlew e2eTest` in another. +- In CI (`CI` set), the script backgrounds the emulator and waits until `FIREBASE_AUTH_EMULATOR_URL` responds. + +## Subagent handoff + +Paste into Task / explore / work-queue prompts: + +```text +FirebaseUI-Android agent command policy: okf-bundle/testing/agent-command-policy.md ONLY. +Unit CI path: ./scripts/build.sh (or the exact gradle tasks it runs) — never invent alternate graphs. +Unit tests: ./gradlew testDebugUnitTest -x :e2eTest:testDebugUnitTest OR ./gradlew ::testDebugUnitTest only for modules with src/test (auth/firestore/storage). Never treat :common/:database testDebugUnitTest as evidence (empty suites). +Style: ./gradlew checkstyle ONLY — do not invent ktlint/detekt entrypoints. +E2e: ./scripts/start-firebase-emulator.sh then ./gradlew e2eTest — okf-bundle/testing/running-e2e.md. +Never: bare firebase emulators:start with invented ports; connectedCheck as e2e substitute; Maven Central publish unless user asked. +On failure: fix product code / prerequisites, re-run the same canonical command; use ./scripts/print_build_logs.sh for CI-shaped failures. +Gate close / push: return validation evidence package from okf-bundle/testing/validation-checklist.md — required before commit or publication (okf-bundle/testing/change-authoring-workflow.md#validation-evidence-blocking). +``` + +## Related docs + +| Topic | Owner | +|-------|--------| +| E2e commands, emulator, narrowing | [running-e2e.md](running-e2e.md) | +| Handoff validation sequence | [validation-checklist.md](validation-checklist.md) | +| Work types and gates | [change-authoring-workflow.md](change-authoring-workflow.md) | +| Doc / commit policy | [documentation-policy.md](../documentation-policy.md) | +| CI job shape | [ci-workflows/index.md](../ci-workflows/index.md) | diff --git a/okf-bundle/testing/change-authoring-workflow.md b/okf-bundle/testing/change-authoring-workflow.md new file mode 100644 index 000000000..34cb30879 --- /dev/null +++ b/okf-bundle/testing/change-authoring-workflow.md @@ -0,0 +1,223 @@ +--- +type: Reference +title: Change authoring workflow +description: Canonical cross-module loop for verified product changes — baseline, unit-focused implementation, area-focused review, documentation, commit, and pre-merge validation. +tags: [testing, validation, workflow, implementation, review] +timestamp: 2026-07-31T00:00:00Z +--- + +# Change authoring workflow + +Single source for **how to author and verify a product change** in FirebaseUI-Android (bug fix, feature, migration follow-up). Module docs add artifacts; work queues add ephemeral gate state — neither restates this loop. + +**Policy:** [OKF documentation and commit policy](../documentation-policy.md). **Terms:** [iteration vocabulary](iteration-vocabulary.md). + +## Primary loop + +```mermaid +flowchart TD + START([Pick change scope]) --> GA{Need feasibility /
semantics check?} + GA -->|yes| GAP["gap-analysis
tier: none"] + GA -->|no| BC{Need before snapshot
or area baseline?} + GAP --> BC + + BC -->|yes| BASE["baseline-capture
tier: area-focused"] + BC -->|no| IMPL + BASE --> IMPL + + IMPL["implementation
tier: unit-focused
module tests + narrow e2e"] + IMPL --> IG{implementation gate
green?} + IG -->|no| IMPL + IG -->|yes| REV + + REV["independent-review
tier: area-focused
frozen tree"] + REV --> RG{all findings
resolved?} + RG -->|any unresolved| IMPL + RG -->|yes| DOC + + DOC{User-facing or
OKF durable updates?} + DOC -->|yes| DOCS["documentation
tier: none"] + DOC -->|no| COMMIT + DOCS --> COMMIT + + COMMIT["commit
tier: none"] + COMMIT --> PM{Branch ready
to merge?} + PM -->|yes| FULL["pre-merge-validation
tier: full"] + PM -->|no| END([Hand off / next item]) + FULL --> END +``` + +## Work types + +| Work type | When | Validation tier | Product edits | Commit | +|-----------|------|-----------------|---------------|--------| +| `gap-analysis` | Unclear feasibility, API shape, provider support | none | read-only | no | +| `baseline-capture` | Need before metrics or area-focused suite on the item | `area-focused` | local narrowing OK | no | +| `implementation` | Author fix/feature + tests | `unit-focused` | yes | no | +| `independent-review` | Verify frozen diff | `area-focused` | no — [frozen tree](#frozen-tree) | no | +| `documentation` | User docs + durable OKF updates | none | docs only | no | +| `commit` | Gates closed for the item | none | staging only | yes | +| `pre-merge-validation` | Branch merge gate | `full` | revert temporary narrowing first | no | + +**Commands per work type:** [validation checklist](validation-checklist.md) — link only; do not duplicate here. + +## Validation tiers + +Tier id strings: [iteration vocabulary § validation tier identifiers](iteration-vocabulary.md#validation-tier-identifiers). + +```mermaid +flowchart LR + subgraph unitFocused ["unit-focused — implementation"] + F1[Module-scoped unit tests] + F2[Optional focused e2e class] + F3[Fast feedback] + F4[Never commit temporary narrowing] + end + + subgraph areaFocused ["area-focused — baseline / independent-review"] + A1[Touched module full unit suite] + A2[E2e when Auth UI / emulator path touched] + A3[Frozen tree for review] + end + + subgraph full ["full — pre-merge-validation"] + P1[./scripts/build.sh] + P2[E2e when Auth in PR scope] + P3[Once per branch before merge] + end +``` + +E2e scope and emulator rules: [running e2e § e2e agent rule](running-e2e.md#e2e-agent-rule). + +**Command rule:** Agents run **only** [agent command policy](agent-command-policy.md) allowlisted commands — no improvised Gradle graphs or bare `firebase emulators:start`. + +## Gates + +| Gate | Closes when | +|------|-------------| +| `implementation` | `implementation` work type complete — code plus **unit-focused**-tier checks green; [static analysis](validation-checklist.md#lint-and-formatting) green on the diff; e2e green when Auth UI/emulator path changed | +| `review` | `independent-review` complete — **area-focused**-tier checks green on frozen tree; applicable [validation checklist](validation-checklist.md) rows green; **every review finding resolved** ([§ quality standards](#quality-standards)) | +| `commit` | Durable commit exists for the item **after** prior gates closed with [recorded evidence](#validation-evidence-blocking) | + +**Trust rule:** Code on disk or in git with `review` still **open** is unverified until `independent-review` closes the gate. + +Any unresolved review finding returns the item to **`implementation`** (`unit-focused`), then repeats **`independent-review`** (`area-focused`) — see [§ quality standards](#quality-standards). + + + +### Validation evidence (blocking) + +Gates close **only** when **recorded evidence** shows the required validation tier ran and passed. Assumed green, implementer summaries without exit codes, or "tests passed earlier" without a log path **do not** close a gate. + +| Gate | Minimum evidence (record in work-queue notes or review handoff) | +|------|------------------------------------------------------------------| +| **`implementation`** | Gradle/script **exit codes**; module unit test pass summary; when Auth UI/emulator path touched: **e2e pass** + log path; **`./gradlew checkstyle` exit code 0** when style-relevant sources changed | +| **`review`** | Frozen-tree re-run of area-focused checklist; checkstyle exit 0 when applicable; unit (+ e2e if Auth) evidence on the frozen tree | +| **`commit`** | Prior gates closed **with evidence**; no temporary test narrowing staged | +| **Publication** (`git push`, force-push, PR refresh) | **`review` gate closed on the exact commits being published**; evidence still valid (no product edits since last area-focused run) | + +**Investigate before close:** Any review finding gets **root-cause analysis** — add tests, delete dead code, or record an [acceptable exception](#acceptable-exceptions) with evidence. Do not label gaps "informational" without proof. + + + +### Forbidden shortcuts + +- **`git commit`** while the current work type's validation tier is incomplete or evidence is missing. +- **`git push` / force-push / PR update** claiming remediation or review-green **without** fresh area-focused evidence after the last product edit on the published commits. +- **History rewrite** (rebase, amend stack) **without** re-running validation for the rewritten scope — prior green results are **invalid**. +- **Self-accepted** gaps — only [acceptable exceptions](#acceptable-exceptions) with user confirmation or intractability evidence in durable OKF. + +Publication is not a separate work type; it follows the same evidence bar as `review` + `commit`. + +## Quality standards + +Two authoring standards gate every item, and both admit the same narrow set of [acceptable exceptions](#acceptable-exceptions) — the only things that may be documented and tracked instead of fixed. + + + +### Acceptable exceptions + +Only two things may be documented and tracked instead of fixed. **Both require the user's explicit acceptance and confirmation plus a recorded rationale** — an agent or reviewer may not grant either on its own, and the item stays tracked until resolved. + +1. **Intractable-limitation bar.** The gap is caused by an intractable technical limitation of the language, platform SDK, compiler, or toolchain, shown with evidence — e.g. a Firebase Auth API that does not expose the capability, cited by version. +2. **User-accepted deferral.** The gap is addressable, but the user explicitly defers it with a documented rationale. + +Anything else is drift or a defect, never a self-justifying exception: + +- **If code can be authored, a test that exercises it can be authored** — otherwise it is dead code; delete it, do not document it. +- Convenience, time pressure, "harmless", or "low-risk" carry weight **only** through an explicit user-accepted deferral (2), never on an agent's own authority. + + + +### Review findings — resolve, do not defer + +`independent-review` classifies findings **critical / serious / minor / nit**. The **`review` gate closes only when every finding — including minor and nit — is resolved by a fix**, unless the finding is covered by one of the two [acceptable exceptions](#acceptable-exceptions). An agent or reviewer may **not** defer a finding on its own authority: "green with minors" is not green. + +A finding covered by an accepted exception is recorded — with evidence or the user's rationale — and tracked, not silently dropped. A finding that is neither fixed nor covered by an accepted exception returns the item to **`implementation`**. + +## Frozen tree + +Required for **`independent-review`** and for any e2e run that closes the **`review`** gate: + +- No edits to library modules (`auth/`, `firestore/`, `database/`, `storage/`, `common/`), `e2eTest/`, `app/` product code, or bundle-affecting OKF docs during the run. +- Wait for or cancel in-flight runs before editing again. + +Keep **`implementation`** and **`independent-review`** in separate passes. + +## `implementation` inner loop + +```mermaid +flowchart TD + P0[Pre-flight: JDK, SDK; emulator if e2e] + P1[Edit product code + tests] + P2["Module unit tests — :module:testDebugUnitTest"] + P3{Auth UI / emulator path?} + P3 -->|no| P4[checkstyle if style-relevant] + P3 -->|yes| P5["emulator + ./gradlew e2eTest (or focused class)"] + P4 --> P6{Green?} + P5 --> P6 + P6 -->|no| P1 + P6 -->|yes| DONE([Close implementation gate]) + P0 --> P1 +``` + +**Static analysis before handoff:** Before closing the **`implementation`** gate, run [validation checklist § lint and formatting](validation-checklist.md#lint-and-formatting) when style-relevant sources changed. Fix violations in product code — do not hand off with checkstyle failures. + +## `independent-review` + +On a **frozen tree**: + +1. Revert temporary test narrowing (focused class filters used only for diagnosis). +2. Run **area-focused**-tier checks for the touched module(s). +3. Run applicable [validation checklist](validation-checklist.md) rows — **blocking:** checkstyle when style-relevant; unit tests; e2e when Auth UI/emulator path is in the frozen diff. +4. Outcome closes **review gate** or returns to **`implementation`**. + +## `commit` + +- One focused commit per item when gates close. +- **Evidence required:** [§ validation evidence](#validation-evidence-blocking) must be recorded before `commit_gate` closes. +- **Work queue:** before `git commit`, set the row's `commit_subject` to the commit's subject line, close `commit_gate`, and stage the queue doc **in the same commit** as the product change ([documentation policy § work queues](../documentation-policy.md#work-queue-documents)). Do not record SHAs in queue docs. + +```bash +git status +git diff --stat +``` + +## Module extensions + +| Module / area | Adds to this loop | +|---------------|-------------------| +| Auth (Compose) | Credential Manager / MFA surfaces — [modules/auth](../modules/auth.md); e2e required — [running e2e](running-e2e.md#when-e2e-is-required) | +| Per-module evidence | [validation checklist § module matrix](validation-checklist.md#module-validation-matrix); empty-suite trap — [agent command policy](agent-command-policy.md#empty-unit-suite-trap) | +| Module durable notes | [modules/index](../modules/index.md) | + +Ephemeral coordination (gate rows, `next_work_type`, `commit_subject`): **work queues only** — not part of this workflow. + +## Related docs + +| Topic | Document | +|-------|----------| +| Term ids and queue field schema | [iteration-vocabulary.md](iteration-vocabulary.md) | +| E2e commands | [running-e2e.md](running-e2e.md) | +| Validation commands | [validation-checklist.md](validation-checklist.md) | +| Agent shell allowlist | [agent-command-policy.md](agent-command-policy.md) | diff --git a/okf-bundle/testing/index.md b/okf-bundle/testing/index.md new file mode 100644 index 000000000..a120c118c --- /dev/null +++ b/okf-bundle/testing/index.md @@ -0,0 +1,8 @@ +# Testing + +* [Agent command policy](agent-command-policy.md) — **read before any shell command** (Gradle, scripts, emulator, validation) +* [Documentation/commit policy](../documentation-policy.md) — durable vs ephemeral, OKF scan +* [Change authoring workflow](change-authoring-workflow.md) — verified product change loop (unit-focused → area-focused review → commit); [§ quality standards](change-authoring-workflow.md#quality-standards); [§ validation evidence (blocking)](change-authoring-workflow.md#validation-evidence-blocking) +* [Iteration vocabulary](iteration-vocabulary.md) — work type, tier, and queue field identifiers +* [Running e2e tests](running-e2e.md) — Auth emulator + `./gradlew e2eTest`; start here for e2e +* [Validation checklist](validation-checklist.md) — handoff command sequence diff --git a/okf-bundle/testing/iteration-vocabulary.md b/okf-bundle/testing/iteration-vocabulary.md new file mode 100644 index 000000000..57075d4ae --- /dev/null +++ b/okf-bundle/testing/iteration-vocabulary.md @@ -0,0 +1,87 @@ +--- +type: Reference +title: Iteration vocabulary +description: Identifier glossary and work-queue field schema for OKF — not workflow rules or commands. +tags: [testing, validation, workflow, work-queue] +timestamp: 2026-07-31T00:00:00Z +--- + +# Iteration vocabulary + +Glossary of **string identifiers** and **work-queue field names** used across OKF. This doc does not define procedures, gate rules, or Gradle commands — each topic has one owning doc; others link. + +**Policy:** [OKF documentation and commit policy](../documentation-policy.md). + +| Topic | Owner | +|-------|--------| +| Change loop, gates, frozen tree | [change authoring workflow](change-authoring-workflow.md) | +| **All agent shell commands** | [agent command policy](agent-command-policy.md) | +| E2e-only detail, emulator, suite scope | [running e2e](running-e2e.md) | +| Validation command sequence | [validation checklist](validation-checklist.md) | +| Work-queue gate snapshots | Module/area work queues (ephemeral) | + +## Work type identifiers + +| Work type | Brief meaning | +|-----------|---------------| +| `gap-analysis` | Read-only feasibility / semantics check | +| `baseline-capture` | Record before snapshots or baselines | +| `implementation` | Author product code and tests | +| `independent-review` | Verify a frozen diff | +| `documentation` | User docs and durable OKF updates | +| `commit` | Stage and create one commit | +| `pre-merge-validation` | Branch-wide merge gate | + +When to use each work type, validation tier, edit policy, and commit rules: [change authoring § work types](change-authoring-workflow.md#work-types). + +## Validation tier identifiers + +| Tier id | Brief meaning | +|---------|---------------| +| `unit-focused` | Fast validation while product code is changing (module-scoped unit tests; optional focused e2e) | +| `area-focused` | Full loaded module/area suite for the change (module unit tests + e2e when Auth UI/emulator path touched) | +| `full` | Unfocused — CI unit path + e2e when Auth is in scope | + +E2e scope and rules: [change authoring § validation tiers](change-authoring-workflow.md#validation-tiers), [running e2e](running-e2e.md). + +## Gate identifiers + +Work queues use these **field names** (values: `open` | `closed`): + +| Field | Tracks | +|-------|--------| +| `implementation_gate` | `implementation` work type complete | +| `review_gate` | `independent-review` work type complete | +| `commit_gate` | Durable commit exists for the item **after** prior gates closed with [validation evidence](change-authoring-workflow.md#validation-evidence-blocking) | + +What closes each gate, trust rules, and loop transitions: [change authoring § gates](change-authoring-workflow.md#gates). + +`commit_gate` closes when a durable commit exists whose subject matches the row's `commit_subject`, **after** `implementation_gate` and `review_gate` closed with [validation evidence](change-authoring-workflow.md#validation-evidence-blocking). + +Items may also be marked **`blocked`** when a dependency gate is open elsewhere. + +## Work-queue fields + +Ephemeral work queues may record: + +| Field | Allowed values / meaning | +|-------|--------------------------| +| `next_work_type` | A [work type identifier](#work-type-identifiers) | +| `validation_tier` | `unit-focused` \| `area-focused` \| `full` | +| `module` | Optional Gradle module scope (e.g. `auth`, `firestore`) | +| `implementation_gate` | `open` \| `closed` | +| `review_gate` | `open` \| `closed` | +| `commit_gate` | `open` \| `closed` | +| `commit_subject` | Planned or landed **first line** of the item's focused commit (Conventional Commits subject). Set **before** `git commit`; must match the commit that closes `commit_gate`. Do not record SHAs. | +| `blocked` | Item or dependency blocked until named gate closes | + +Queues record **state**, not who executes the work. + +## Related docs + +| Topic | Document | +|-------|----------| +| **Change authoring loop** | [change-authoring-workflow.md](change-authoring-workflow.md) | +| E2e commands | [running-e2e.md](running-e2e.md) | +| Validation commands | [validation-checklist.md](validation-checklist.md) | +| Doc/commit policy | [documentation-policy.md](../documentation-policy.md) | diff --git a/okf-bundle/testing/running-e2e.md b/okf-bundle/testing/running-e2e.md new file mode 100644 index 000000000..5e5239ff8 --- /dev/null +++ b/okf-bundle/testing/running-e2e.md @@ -0,0 +1,99 @@ +--- +type: Reference +title: Running e2e tests +description: Canonical Auth emulator + Gradle e2eTest commands, environment, and diagnosis for FirebaseUI-Android. +tags: [testing, e2e, emulator, auth, gradle] +timestamp: 2026-07-31T00:00:00Z +--- + +# Running e2e tests + +Canonical e2e runbook for this repo. **Shell allowlist:** [agent command policy](agent-command-policy.md). Do not restate the full allowlist here. + + + +## E2e agent rule (read first) + +1. Start the Auth emulator with **`./scripts/start-firebase-emulator.sh`** only. +2. Run the suite with **`./gradlew e2eTest`** only (custom task in `e2eTest/build.gradle.kts`). +3. Do **not** use `connectedAndroidTest`, Espresso device runs, or bare `firebase emulators:start` with invented ports as substitutes. +4. On failure: read the full Gradle output (and `./scripts/print_build_logs.sh` when useful), fix product/test code or prerequisites, re-run the **same** commands. + +## What this suite is + +| Property | Value | +|----------|--------| +| Module | `:e2eTest` | +| Runner | Robolectric + Compose UI testing (`test` source set) | +| Backend | Firebase **Auth** Emulator only | +| Project ID | From `e2eTest/.firebaserc` (`fake-project-id`) | +| Auth port | From `e2eTest/firebase.json` emulators.auth.port (`9099`) | +| Custom task | `e2eTest` — mirrors the debug unit-test classpath; `doNotTrackState` so it always runs | + +Tests live under `e2eTest/src/test/java/com/firebase/ui/auth/ui/` — mostly `screens/` (email, phone, Google, MFA, reauth, credential linking, anonymous) plus `AccessibilityTest.kt` beside that package. + +This suite does **not** require a real Firebase project. Demo app / Play Services provider setup for the sample app is separate ([modules/auth](../modules/auth.md), [CONTRIBUTING.md](../../CONTRIBUTING.md)). + +## Prerequisites + +```bash +# Once per machine (CI installs firebase-tools each job) +npm install -g firebase-tools +``` + +Also needed: `node`, `npm`, `jq` (used to read `e2eTest/.firebaserc` / `firebase.json`; the script preflights only `firebase` / `node` / `npm`), and a free Auth emulator port. + +## Canonical local run + +**Terminal A** (foreground emulator locally): + +```bash +./scripts/start-firebase-emulator.sh +``` + +**Terminal B**: + +```bash +./gradlew e2eTest +``` + +CI order matches [.github/workflows/e2e_test.yml](../../.github/workflows/e2e_test.yml): install firebase-tools → start script (background when `CI` is set) → `./gradlew e2eTest`. + +## Focused runs (diagnosis only) + +Gradle supports narrowing to a test class while iterating. Prefer this during **`unit-focused`** diagnosis; revert to the full `e2eTest` task before **`area-focused`** / **`review`** gate closure. + +```bash +./gradlew e2eTest --tests 'com.firebase.ui.auth.ui.screens.EmailAuthScreenTest' +``` + +Never commit temporary `.only`-style filters or leave the suite narrowed for review evidence. + + + +## When e2e is required + +| Change surface | E2e required? | +|----------------|---------------| +| `auth/` Compose screens, flow controller, credential manager, MFA | **Yes** — area-focused and full tiers | +| `e2eTest/` itself | **Yes** | +| `firestore/` / `database/` / `storage/` / `common/` only | **No** — unit/androidTest for that module | +| Docs / OKF only | **No** | + +## Diagnosis + +1. Confirm emulator is up: start script succeeded; Auth URL responds (`FIREBASE_AUTH_EMULATOR_URL`, default `http://127.0.0.1:9099`). +2. Confirm prerequisites: script exits non-zero if `firebase` / `node` / `npm` are missing; ensure `jq` is installed too (used without a dedicated preflight check). +3. Re-run **`./gradlew e2eTest`** after product/test fixes — same command. +4. On CI-shaped failures: `./scripts/print_build_logs.sh`. + +Do not “fix” emulator connectivity by inventing alternate ports or starting Firestore/Database emulators unless a future suite documents them as required. + +## Related docs + +| Topic | Document | +|-------|----------| +| Allowlisted commands | [agent-command-policy.md](agent-command-policy.md) | +| Handoff checklist | [validation-checklist.md](validation-checklist.md) | +| E2e CI job | [ci-workflows/e2e.md](../ci-workflows/e2e.md) | +| Auth module notes | [modules/auth.md](../modules/auth.md) | diff --git a/okf-bundle/testing/validation-checklist.md b/okf-bundle/testing/validation-checklist.md new file mode 100644 index 000000000..71b59eb6c --- /dev/null +++ b/okf-bundle/testing/validation-checklist.md @@ -0,0 +1,124 @@ +--- +type: Reference +title: Validation checklist +description: Canonical command sequence for validating FirebaseUI-Android changes and handoff. +tags: [testing, validation, gradle, checkstyle, e2e] +timestamp: 2026-07-31T00:00:00Z +--- + +# Validation checklist + +Validation commands for development/handoff. Other docs/skills link here; do not restate. + +**Agents:** [agent command policy](agent-command-policy.md) — only allowlisted invocations. + +## When to run what + +Work types and tiers: [change authoring workflow](change-authoring-workflow.md). Term ids: [iteration vocabulary](iteration-vocabulary.md). + +| Work type | Scope | Shortcuts | +|-----------|-------|-----------| +| `gap-analysis` | Read APIs, module READMEs, upgrade guides | n/a | +| `baseline-capture` | Touched module unit suite (+ e2e if Auth) | **area-focused** tier | +| `implementation` | Module unit tests; e2e when Auth UI/emulator path changed | **unit-focused** tier; optional `--tests` narrowing for diagnosis | +| `independent-review` | Area checklist on [frozen tree](change-authoring-workflow.md#frozen-tree) | **area-focused**; no temporary narrowing left in place | +| `pre-merge-validation` | CI unit path + e2e when Auth in PR | **full** tier — once per branch | + +## Build and unit tests + +Repo root. Full CI unit path (what `build.sh` runs): [Android CI](../ci-workflows/android.md). + +```bash +./scripts/build.sh +``` + +Module-scoped while iterating — **only modules with a real `src/test` suite** count as unit evidence: + +```bash +./gradlew :auth:testDebugUnitTest +./gradlew :firestore:testDebugUnitTest +./gradlew :storage:testDebugUnitTest +``` + + + +| Module | JVM `src/test`? | Unit-focused evidence | Area-focused / full | +|--------|-----------------|----------------------|---------------------| +| `:auth` | Yes | `:auth:testDebugUnitTest`; optional focused e2e — [running e2e](running-e2e.md) | Full auth unit + e2e; `./scripts/build.sh` at full | +| `:firestore`, `:storage` | Yes | `::testDebugUnitTest` | Same + `./scripts/build.sh` at full | +| `:database` | **No** (only `androidTest`) | `:database:assembleDebug` + checkstyle — **not** `:database:testDebugUnitTest` ([empty-suite trap](agent-command-policy.md#empty-unit-suite-trap)) | `./scripts/build.sh` | +| `:common` | **No** | `:common:assembleDebug` + checkstyle + `:firestore:testDebugUnitTest` when shared API consumed — **not** `:common:testDebugUnitTest` ([trap](agent-command-policy.md#empty-unit-suite-trap)) | `./scripts/build.sh` | + +Instrumented `androidTest` (database/firestore) is **not** in CI or the agent allowlist — human/device only. + + + +## Lint and formatting + +**Blocking before `implementation` handoff and on the frozen tree for `independent-review`** when Java/Kotlin style-relevant sources changed. + +```bash +./gradlew checkstyle +``` + +Config: `library/quality/checkstyle.xml` (wired from root `build.gradle.kts`). There is **no** separate agent entrypoint for ktlint/detekt — do not invent one. + +Follow [Kotlin coding conventions](https://kotlinlang.org/docs/coding-conventions.html), [Android Kotlin style](https://developer.android.com/kotlin/style-guide), and [Compose API guidelines](https://github.com/androidx/androidx/blob/androidx-main/compose/docs/compose-api-guidelines.md) as described in [CONTRIBUTING.md](../../CONTRIBUTING.md). + +## E2e + +When Auth UI / `e2eTest` is in scope — [running e2e](running-e2e.md): + +```bash +./scripts/start-firebase-emulator.sh # separate terminal locally +./gradlew e2eTest +``` + +## Coverage + +This repo does **not** currently configure Jacoco/Codecov (or equivalent) in CI. Do not invent coverage tasks. Prefer meaningful unit + e2e assertions over synthetic coverage gates until tooling is added and documented here. + +## OKF bundle review + +Before handoff, follow [OKF policy](../documentation-policy.md#okf-update-contract): + +1. Update relevant `okf-bundle/modules/` docs with durable learnings. +2. Check `okf-bundle/testing/` for conflicts with verified behavior; fix drift. +3. Run independent scan for canonical ownership, DRY refs, link hygiene, durability. + + + +## Validation evidence package (blocking) + +Before closing **`implementation_gate`**, **`review_gate`**, **`commit_gate`**, or publishing (`git push` / PR update), record evidence per [change authoring § validation evidence](change-authoring-workflow.md#validation-evidence-blocking). Minimum template: + +```markdown +| Step | Command | Exit | Evidence | +|-------------|-------------------------------------------------------------------------|------|-----------------------------------------------| +| unit CI | ./scripts/build.sh | 0 | — | +| module unit | ./gradlew ::testDebugUnitTest | 0 | N/N tests — only if module has `src/test` | +| assemble | ./gradlew ::assembleDebug | 0 | when module has no JVM unit suite | +| checkstyle | ./gradlew checkstyle | 0 | when style-relevant sources | +| e2e | ./gradlew e2eTest | 0 | when Auth UI — /tmp/...log | +``` + +**History rewrite invalidates** prior rows — re-run and replace the table after amend/rebase. + +## Handoff checklist + +- [ ] `./scripts/build.sh` (or equivalent assemble + checkstyle + unit exclusion path) exit 0 +- [ ] Module evidence per [module validation matrix](#module-validation-matrix) +- [ ] `./gradlew checkstyle` when style-relevant sources changed +- [ ] E2e green when Auth UI / `e2eTest` changed ([running e2e](running-e2e.md)) +- [ ] [Validation evidence package](#validation-evidence-package) recorded +- [ ] OKF bundle reviewed/updated per § above +- [ ] Conventional Commit subject prepared ([documentation policy](../documentation-policy.md)); single-commit PR title will match + +## Related docs + +| Topic | Document | +|-------|----------| +| Allowlist | [agent-command-policy.md](agent-command-policy.md) | +| Change loop | [change-authoring-workflow.md](change-authoring-workflow.md) | +| E2e | [running-e2e.md](running-e2e.md) | +| CI | [ci-workflows/index.md](../ci-workflows/index.md) |