diff --git a/.agents/.gitignore b/.agents/.gitignore new file mode 100644 index 00000000..e25e21b3 --- /dev/null +++ b/.agents/.gitignore @@ -0,0 +1,2 @@ +reports +work-queues diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..c6dc3727 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,12 @@ +# React Native Google Mobile Ads — agents + +`src/` → `lib/` via `yarn prepare`. Native `android/` `ios/`. Expo `plugin/`. Example `RNGoogleMobileAdsExample/`. E2e `e2e/`. Docs `docs/`. Contributor/review norms: `CONTRIBUTING.md`. + +Root `yarn`. Shell: [agent-command-policy](okf-bundle/testing/agent-command-policy.md) only. E2e: [running-e2e § agent rule](okf-bundle/testing/running-e2e.md#agent-rule-read-first) and [platform coverage](okf-bundle/testing/running-e2e.md#platform-coverage-gate-blocking). A green e2e workflow is **not** a pass ([continue-on-error](okf-bundle/ci-workflows/index.md#e2e-continue-on-error)); use local counts + `/tmp/rngma-e2e-*.log`. Loop: [change-authoring](okf-bundle/testing/change-authoring-workflow.md#loop) (`documentation?` then frozen [OKF scan](okf-bundle/testing/validation-checklist.md#okf-bundle-review) when `okf-bundle/`, `AGENTS.md`, or `CONTRIBUTING.md` changed; freeze: [§ frozen tree](okf-bundle/testing/change-authoring-workflow.md#frozen-tree)). Before commit or push: [validation evidence package](okf-bundle/testing/validation-checklist.md#validation-evidence-package). [Coverage evidence](okf-bundle/testing/coverage-design.md#coverage-evidence-package) only when `src/` **or** `android/` **or** `ios/` **or** `plugin/` TS is in the diff; `app.plugin.js`-only is `n/a` unless `plugin/` TS changed ([§ gates](okf-bundle/testing/change-authoring-workflow.md#gates)). Index: [okf-bundle](okf-bundle/index.md). Testing: [testing/index.md](okf-bundle/testing/index.md). Match work type and validation tier: [iteration vocabulary](okf-bundle/testing/iteration-vocabulary.md). + +Follow [documentation-policy § public vs ephemeral vs private](okf-bundle/documentation-policy.md#durable-vs-ephemeral). Do not stage `.agents/work-queues/` or `.agents/reports/`. Do not add queue files under `okf-bundle/`. + +## PR instructions + +- Scoped PRs. API/behavior change → tests + docs + types in the same PR. +- PR titles: [documentation-policy § pull requests](okf-bundle/documentation-policy.md#pull-requests) (single-commit title equals that commit's subject; multi-commit PRs use a summary title). Examples: `CONTRIBUTING.md`. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 988de8e1..78703497 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,7 @@ We welcome any type of contribution, not just code. You can help with; - **Docs**: improve reference coverage, add more examples, fix typos or anything else you can spot. - At the bottom of every page on our docs site you can click the `Edit this page` button to go to that pages markdown file or view the [documents](https://github.com/invertase/react-native-google-mobile-ads/tree/main/docs) directly - **Community**: presenting the project at meetups, organizing a dedicated meetup for the local community, ... -- **Code**: take a look at the [open issues](issues). Even if you can't write code, commenting on them, showing that you care about a given issue matters. +- **Code**: take a look at the [open issues](https://github.com/invertase/react-native-google-mobile-ads/issues). Even if you can't write code, commenting on them, showing that you care about a given issue matters. ## Project Guidelines @@ -26,9 +26,9 @@ We aim to keep all project discussion inside GitHub issues. This is to make sure This is normal don't worry - not everyone can develop native code for Obj-C and Java, we understand that. -Although we won't merge Pull Requests unless they support all applicable platforms, we do however recommend that you still submit a PR +Although we won't merge product features that ship on both OS unless they support all applicable platforms, we do however recommend that you still submit a PR for the Platform that you do know and then label it as either `Help: iOS` or `Help: Android` (or post a comment requesting it to be labeled). -This will allow other contributors to help add the missing platform support by making changes to your existing PR. +This will allow other contributors to help add the missing platform support by making changes to your existing PR. Test and platform expectations: [platform coverage](okf-bundle/testing/running-e2e.md#platform-coverage-gate-blocking). ### Our expectations on you as a contributor @@ -38,7 +38,7 @@ To quote [@alloy](https://github.com/alloy) from [this issue](https://github.com We want contributors to provide ideas, keep the ship shipping and to take some of the load from others. It is non-obligatory; we’re here to get things done in an enjoyable way. :trophy: -We do ask though that you follow the conduct guidelines set out in our [Code of Conduct](/CODE_OF_CONDUCT.md) throughout your contribution journey. +We do ask though that you follow the conduct guidelines set out in our [Code of Conduct](CODE_OF_CONDUCT.md) throughout your contribution journey. ### What about if you have problems that cannot be discussed in a public issue? @@ -88,14 +88,13 @@ To aid review we also ask that you fill out the PR template as much as possible. ### Your PR title -We use the [Conventional Commits](https://www.conventionalcommits.org/) format throughout the project. Your Pull Request title should be -in this format; however your commits themselves do not need to follow this format as all PRs are eventually squash merged. +Commit subjects and Pull Request titles use [Conventional Commits](https://www.conventionalcommits.org/). Full rules (single-commit title equals that commit's subject; multi-commit PRs use a summary title; squash/amend is a **fix** for a non-conforming subject, not a skip): [OKF documentation policy § pull requests](okf-bundle/documentation-policy.md#pull-requests). #### Examples - `docs(consent, ios): added extra example for GDPR flow on iOS` - `tests(perf): should throw invalid arg error` -- `fix(insterstial, android): fixed NPE crash` +- `fix(interstitial, android): fixed NPE crash` - `feat(video): add support for video load timeouts` See the [Conventional Commits](https://www.conventionalcommits.org/) specification for more information. @@ -107,17 +106,16 @@ Pull Requests to the `main` branch require one or more peer-review approvals and Reviews of Pull Requests are based on the following acceptance criteria: - Does the PR provide cross-platform support? - - i.e. if adding a new feature then does the implementation provide iOS and Android support. - - Pull Requests should not be merged unless both platforms are supported (unless the feature is specific to one platform only) + - Product features that ship on both platforms need both. + - Which platforms and which tests: [platform coverage](okf-bundle/testing/running-e2e.md#platform-coverage-gate-blocking). Lint/evidence: [work types](okf-bundle/testing/validation-checklist.md#work-types) / [gates](okf-bundle/testing/change-authoring-workflow.md#gates). Frozen review: [§ frozen tree](okf-bundle/testing/change-authoring-workflow.md#frozen-tree). - If APIs have changed; - Has the documentation been updated? - Have the TypeScript types been added? - Have the tests been updated or new tests been added to test newly implemented or changed functionality. - - E2E tests. - - Other tests through Jest. -- Do all CI checks pass. + - E2E and Jest when [platform coverage](okf-bundle/testing/running-e2e.md#platform-coverage-gate-blocking) requires them. +- Do all CI checks pass. A green e2e GitHub Actions job is not an e2e pass — [continue-on-error](okf-bundle/ci-workflows/index.md#e2e-continue-on-error). -Once a PR is merged into the `main` branch; new versions of the changed packages are automatically created and published to NPM. +Once a PR is merged into the `main` branch, maintainers publish with `workflow_dispatch` — [CI publish](okf-bundle/ci-workflows/index.md#workflows). Push to `main` does not publish. ## [No Brown M&M's](http://en.wikipedia.org/wiki/Van_Halen#Contract_riders) diff --git a/okf-bundle/architecture-decisions.md b/okf-bundle/architecture-decisions.md new file mode 100644 index 00000000..57573c14 --- /dev/null +++ b/okf-bundle/architecture-decisions.md @@ -0,0 +1,35 @@ +--- +type: Reference +title: Architecture decisions (ADR) +description: Canonical owner of durable GMA product and tooling decisions. +tags: [okf, adr] +timestamp: 2026-08-22T00:00:00Z +--- + +# Architecture decisions (ADR) + +**Canonical owner** of durable “what + why” decisions for this repo. Procedures and commands live in [testing](testing/index.md). Do not duplicate these decisions in work queues. Queues stay under `.agents/work-queues/` (gitignored). + +**Policy:** [OKF documentation policy](documentation-policy.md). + +## Decision ID convention + +Cite decisions as **`GMA-AD-`**. + +## Status legend + +| Status | Meaning | +|--------|---------| +| **Accepted** | Decided; follow this. | +| **Proposed** | Planned; not yet the rule. | +| **Rejected** | Considered and declined; keep so it is not re-litigated. | + +Add rows when a refactor choice lands (module boundaries, codegen, plugin behavior, native backend). Do not paste decisions from other repos. + + + +## GMA-AD-1 — Expo config plugin is a separate validation path — **Accepted** + +The Expo config plugin under `plugin/` is a **separate validation path**: Metro/Expo consume compiled plugin output, not `plugin/src/`. Native e2e does not cover plugin JS/config by itself. + +Commands: [validation checklist § Expo plugin](testing/validation-checklist.md#expo-plugin) (root Jest is the gate). When to run e2e vs plugin Jest: [running e2e § platform coverage](testing/running-e2e.md#platform-coverage-gate-blocking). diff --git a/okf-bundle/ci-workflows/index.md b/okf-bundle/ci-workflows/index.md new file mode 100644 index 00000000..0d33934e --- /dev/null +++ b/okf-bundle/ci-workflows/index.md @@ -0,0 +1,38 @@ +# CI workflows + +GitHub Actions job shape and artifact triage for **this** repo. Commands: [agent command policy](../testing/agent-command-policy.md). E2e names: [local e2e](../testing/running-e2e.md#local-e2e-commands). Which e2e to run: [platform coverage](../testing/running-e2e.md#platform-coverage-gate-blocking). + +Do not copy other repos’ Detox patch inventories, macOS-app e2e suites, Jacoco merge, or emulator-cloud quota notes. + + + +## Workflows + +| Workflow | File | Local equivalent | Artifacts / notes | +|----------|------|------------------|-------------------| +| Jest | [`.github/workflows/tests_jest.yml`](../../.github/workflows/tests_jest.yml) | `yarn tests:jest-coverage` | Codecov upload | +| E2e Android | [`.github/workflows/tests_e2e_android.yml`](../../.github/workflows/tests_e2e_android.yml) | [platform coverage](../testing/running-e2e.md#platform-coverage-gate-blocking) + [named scripts](../testing/running-e2e.md#local-e2e-commands) | `adb_logs`; Codecov; Metro prefetch on `:8081`. **Run Emulator Tests**: [continue-on-error](#e2e-continue-on-error) | +| E2e iOS | [`.github/workflows/tests_e2e_ios.yml`](../../.github/workflows/tests_e2e_ios.yml) | [platform coverage](../testing/running-e2e.md#platform-coverage-gate-blocking) + [named scripts](../testing/running-e2e.md#local-e2e-commands) | `simulator_log`; Codecov; Metro prefetch on `:8081`. **Build and Run e2e app** and **Create Simulator Log**: [continue-on-error](#e2e-continue-on-error) | +| Lint | [`.github/workflows/linting.yml`](../../.github/workflows/linting.yml) | [lint-by-tree](../testing/validation-checklist.md#lint-and-formatting) | CI always runs `yarn lint:code`; local agents do not copy that unless `src/` **and** `android/` **and** `ios/` changed. Also `yarn tsc:compile`. `eslint-report.json` | +| Docs | [`.github/workflows/docs.yml`](../../.github/workflows/docs.yml) | `yarn lint:spellcheck` | Job title mentions Markdown; CI is spellcheck only — [§ lint](../testing/validation-checklist.md#lint-and-formatting) | +| PR title | [`.github/workflows/pr_title.yml`](../../.github/workflows/pr_title.yml) | [documentation-policy § pull requests](../documentation-policy.md#pull-requests) | Conventional Commits; `validateSingleCommit` | +| Test patches | [`.github/workflows/create_test_patches.yml`](../../.github/workflows/create_test_patches.yml) | Do not invent a local substitute | `workflow_dispatch` + push/PR; patch-package artifacts | +| Publish | [`.github/workflows/publish.yml`](../../.github/workflows/publish.yml) | Maintainers only | `on.push` exists; the job `if` runs only on `workflow_dispatch`. Push to `main` does not publish. | +| Stale | [`.github/workflows/stale.yml`](../../.github/workflows/stale.yml) | n/a | Scheduled issue/PR stale bot | + +Jest/e2e/patch workflows `paths-ignore` markdown and `docs/**` (YAML also lists `website/**`; that tree is not in this repo — ignore it). Lint runs on markdown PRs and pushes to `main`. Docs spellcheck is PR-only. + + + +## E2e continue-on-error + +`continue-on-error: true` is on Android **Run Emulator Tests** and iOS **Build and Run e2e app**. iOS **Create Simulator Log** also sets it; that step is log capture, not the e2e pass signal. A green workflow is **not** an e2e pass. Pass signal: local counts + `/tmp/rngma-e2e-*.log`, or triaged `simulator_log` / `adb_logs`. + + + +## Triage + +- iOS e2e failure: download `simulator_log`, then local `/tmp/rngma-e2e-ios.log`. +- Android e2e failure: download `adb_logs`, then local `/tmp/rngma-e2e-android.log`. +- Packager never healthy: Metro must be **this** checkout on `:8081` — [running e2e § pre-flight](../testing/running-e2e.md#pre-flight). +- Grow platform pages here only after a failure mode is verified on **this** repo. diff --git a/okf-bundle/documentation-policy.md b/okf-bundle/documentation-policy.md new file mode 100644 index 00000000..c12faad3 --- /dev/null +++ b/okf-bundle/documentation-policy.md @@ -0,0 +1,103 @@ +--- +type: Reference +title: OKF documentation and commit policy +description: Canonical rules for public vs ephemeral vs private knowledge, commit messages, and post-update bundle consistency. +tags: [okf, documentation, policy, commits, work-queue] +timestamp: 2026-08-22T00: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. + + + +## Public vs ephemeral vs private + +| Kind | Where it lives | What it contains | +|------|----------------|------------------| +| **Public (durable)** | GitHub-**public** reference docs and indexes under `okf-bundle/` (not work-queue files) | Stable API names, registry IDs, SDK versions, classifications, verification **methods**, architecture, canonical commands | +| **Ephemeral** | Work-queue **files** (default `.agents/work-queues/`, gitignored) | Session phase/probe IDs, **planned commit subjects** (`commit_subject`), gate state, `next_work_type`, snapshot labels, dated banners, run counts | +| **Private** | Internal tracker and internal docs (not named here) | Tracker identifiers, discussion, non-public commercial terms. Not GitHub-public; not the same as ephemeral | + +GitHub-public **reference** docs, `AGENTS.md`, commits, and PR titles must **not** contain ephemeral **state/values** (for example probe IDs, dated banners, run counts) or private **items** (for example tracker identifiers, internal docs). Gate **names** and close rules: [change authoring § gates](testing/change-authoring-workflow.md#gates). + +Work-queue **files** may hold ephemeral fields. Default queues are `.agents/work-queues/` (gitignored; do not stage or commit). Coverage evidence lives under `.agents/reports/` (also gitignored; do not stage). This repo does not commit queues under `okf-bundle/`. Do not add them. + +Private items stay off GitHub, including off `AGENTS.md`, commits, PR titles, reference docs, and any queue file. + +**Rules** + +1. General OKF docs get **public/durable only** updates. Ephemeral fields and private items stay out of all GitHub-public **reference** docs (this heading defines the kinds; it is not the only file the restriction covers). +2. Ephemeral state lives **only** in work queues. Private tracker state lives in the internal tracker. When an item closes, **public** outcomes move to reference docs; leave session state in the queue and tracker state in the internal tracker. Queue rows may archive/delete. +3. GitHub-public **reference** docs must not link to gitignored queue files (they are not on GitHub). Do not copy queue rows into reference docs. Local queues stay under `.agents/work-queues/`. + + + +## 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”. + + + +## Pull requests + +Commit subjects and PR titles use [Conventional Commits](https://www.conventionalcommits.org/). 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. + +PRs are squash-merged. Maintainers or agents may amend or squash to **fix** a non-conforming subject so the published commit is Conventional Commits. That is an exception flow to repair a violation, not permission to skip the format on commits. + + + +## OKF update contract + +OKF markdown edits require an **independent bundle consistency pass**: + +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. Bundle owners: [index.md](index.md). Testing owners: [testing/index.md](testing/index.md) (file **and** section links). | +| **DRY** | No duplicated procedures, policy paragraphs, or ephemeral snapshots outside work queues | +| **Efficiency** | Shortest text that stays **complete and true** ([§ Efficiency](#efficiency)). Completeness wins over brevity | +| **Link hygiene** | Cross-links resolve; indexes list canonical entry points | +| **Durability** | No ephemeral **state/values** and no private **items** in GitHub-public **reference** docs, `AGENTS.md`, commits, or PR titles. Work-queue **files** may hold ephemeral fields. Private items stay off GitHub. Default queues and coverage reports are gitignored under `.agents/work-queues/` and `.agents/reports/`. Do not add new queue files under `okf-bundle/` | + +**Blocking on `commit`.** Fix violations before `git commit` ([change authoring § commit](testing/change-authoring-workflow.md#commit)). Gate close is not a later escape hatch. Frozen `independent-review` **reports only**; `okf-bundle/` / `AGENTS.md` / `CONTRIBUTING.md` findings apply in `documentation?` then another frozen scan — product/lint findings are not this dump ([§ frozen tree](testing/change-authoring-workflow.md#frozen-tree)). Commands: [validation-checklist § OKF bundle review](testing/validation-checklist.md#okf-bundle-review). Loop: [change authoring](testing/change-authoring-workflow.md#loop). Work-queue edits still follow this split. + + + +## Efficiency + +Efficiency is **information-preserving brevity**, not a token budget. + +**Pass when:** + +- Non-owning docs **link** to the owner instead of copying procedures, policy paragraphs, or command lists. +- Sentences and tables are as short as they can be **without** dropping a rule, case, exception, location, dual path (for example single- vs multi-commit PR titles), blocking step, or inbound heading id. +- Index and `AGENTS.md` summaries remain **true**: every distinction an agent needs in order to act correctly is either stated or linked with enough qualifier that the wrong place or rule cannot be assumed. + +**Fail when:** + +- A shorter owner doc omits a requirement that existed, or that other docs still depend on. +- A summary collapses two cases into one. +- A heading rename breaks `#fragment` links. +- “Don’t restate” is used to skip updating `AGENTS.md` or indexes after a policy change. + +If shortening would change how an agent acts, keep the longer text. + + + +## Work-queue documents + +Work queues are **intentionally ephemeral**: phases, **commit subjects**, gates. They are not policy or finalized registry/design homes. + +Default location and gitignore: [§ public vs ephemeral vs private](#durable-vs-ephemeral). Field names: [iteration vocabulary](testing/iteration-vocabulary.md). Gate semantics, workflow rules, and `commit_subject` staging: [change authoring workflow](testing/change-authoring-workflow.md) (including [§ commit](testing/change-authoring-workflow.md#commit)). + +Who executes is out of scope. + +New work queues link here in frontmatter/opening section; do not copy policy inline. diff --git a/okf-bundle/documentation-site-maintenance.md b/okf-bundle/documentation-site-maintenance.md new file mode 100644 index 00000000..ba7da654 --- /dev/null +++ b/okf-bundle/documentation-site-maintenance.md @@ -0,0 +1,32 @@ +--- +type: Reference +title: Documentation site maintenance +description: Canonical maintenance for docs.page (docs.json + docs/). +tags: [okf, documentation, docs-page] +timestamp: 2026-08-22T00:00:00Z +--- + +# Documentation site maintenance + +Single source for **user-facing documentation site** maintenance: [docs.page](https://docs.page) content under `docs/` plus root `docs.json`. + +**Policy:** [OKF documentation and commit policy](documentation-policy.md). + +This repo does **not** publish a TypeDoc `/reference/` site. Do not invent `yarn reference:api`, TypeDoc configs, or legacy `/reference/` redirect audits unless those tools exist here. + + + +## docs.json + +When adding or renaming user docs pages: + +- Add or update sidebar entries in `docs.json` in the same change as `docs/**`. +- Paths in the sidebar are docs.page routes (for example `/displaying-ads`), not GitHub file paths. +- Run markdown/spellcheck per [validation checklist § lint](testing/validation-checklist.md#lint-and-formatting). + +Redirect keys in `docs.json` are not in use today. Do not add a redirect-audit procedure until this repo actually has `redirects`. + +## Related + +- User docs live in `docs/`. Agent knowledge lives in `okf-bundle/` — [documentation policy](documentation-policy.md). +- CI docs job: `.github/workflows/docs.yml` — [§ lint](testing/validation-checklist.md#lint-and-formatting) (spellcheck in CI; markdown check is local). diff --git a/okf-bundle/index.md b/okf-bundle/index.md new file mode 100644 index 00000000..30f3ce96 --- /dev/null +++ b/okf-bundle/index.md @@ -0,0 +1,11 @@ +--- +okf_version: '0.1' +--- + +# React Native Google Mobile Ads knowledge bundle + +- [Documentation/commit policy](documentation-policy.md#durable-vs-ephemeral) — three kinds; [work queues](documentation-policy.md#work-queues) (do not add queues here); [commits as documentation](documentation-policy.md#commits-as-documentation); [Efficiency](documentation-policy.md#efficiency); [OKF update contract](documentation-policy.md#okf-update-contract); [pull requests](documentation-policy.md#pull-requests) +- [Documentation site maintenance](documentation-site-maintenance.md) — docs.page [`docs.json`](documentation-site-maintenance.md#docsjson) + `docs/` +- [Architecture decisions](architecture-decisions.md) — `GMA-AD-*` (what + why); [GMA-AD-1](architecture-decisions.md#gma-ad-1) +- [CI workflows](ci-workflows/index.md) — [§ workflows](ci-workflows/index.md#workflows); [e2e continue-on-error](ci-workflows/index.md#e2e-continue-on-error); [§ triage](ci-workflows/index.md#triage) +- [Testing](testing/index.md) — all testing files; [platform coverage](testing/running-e2e.md#platform-coverage-gate-blocking), [Expo plugin](testing/validation-checklist.md#expo-plugin), [coverage evidence](testing/coverage-design.md#coverage-evidence-package) diff --git a/okf-bundle/testing/agent-command-policy.md b/okf-bundle/testing/agent-command-policy.md new file mode 100644 index 00000000..01d51252 --- /dev/null +++ b/okf-bundle/testing/agent-command-policy.md @@ -0,0 +1,65 @@ +--- +type: Reference +title: Agent command policy +description: Allowlisted agent shell commands. +tags: [testing, validation, agents, yarn] +timestamp: 2026-08-22T00:00:00Z +--- + +# Agent command policy + +If a command is not listed (or linked) here, **do not run it**. E2e: [local e2e commands](running-e2e.md#local-e2e-commands). + +1. Registry only, repo root unless noted. +2. When this pass runs tsc/Jest/lint/Metro/native: `yarn` then `yarn prepare` exit 0 first — [§ prepare](#prepare-must-finish-first). +3. On lint check failure: [lint-and-formatting](validation-checklist.md#lint-and-formatting) (check vs `:fix`/`--replace` by work type). For other failures: [§ frozen tree](change-authoring-workflow.md#frozen-tree) — on `independent-review`, record a finding and do not edit (except revert `.only`); apply per that heading (product/lint → `implementation`; `okf-bundle/` / `AGENTS.md` / `CONTRIBUTING.md` → `documentation?`), then re-run the **same** command. +4. [Constraints block](#constraints-block). + + + +## Canonical registry + +| Intent | Command | Never | +|--------|---------|-------| +| Install | `yarn` | `npm install`; example-only install first | +| Example deps | `yarn tests:install` | `npm install` in example | +| `src/` → `lib/` + plugin | `yarn prepare` | ad-hoc bob/babel/tsc | +| TS check | `yarn tsc:compile` | invented `tsc` configs | +| Jest | `yarn tests:jest`, `yarn tests:jest-coverage` | `npx jest` random cwd | +| Lint (local) | [lint-by-tree](validation-checklist.md#lint-and-formatting) (`yarn lint:js` / `yarn lint:android` / `yarn lint:ios:check`; check vs `:fix`/`--replace` by work type) | ad-hoc eslint; `npx google-java-format`; invented `clang-format` / prettier | +| Lint CI combo | `yarn lint:code` locally only if this diff includes `src/` **and** `android/` **and** `ios/` — [lint-and-formatting](validation-checklist.md#lint-and-formatting) | do not use **this** command as the local default; do not use it on a single- or two-tree diff; do not use it on frozen `independent-review` | +| Lint + tsc | `yarn lint` (`lint:code` + `tsc:compile`) locally only if this diff includes `src/` **and** `android/` **and** `ios/` — [lint-and-formatting](validation-checklist.md#lint-and-formatting) | do not treat as the same as `yarn lint:code`; do not use **this** command as the local default on a narrower diff; do not use it on frozen `independent-review` | +| Docs | `yarn lint:markdown:check`, `yarn lint:spellcheck` when `docs/**` — [lint-and-formatting](validation-checklist.md#lint-and-formatting) | ad-hoc prettier as gate; markdown check on an OKF/`AGENTS.md`/`CONTRIBUTING.md`-only diff | +| Packager | `yarn tests:packager`, `yarn tests:packager:reset-cache` | bare Metro | +| E2e | [local e2e names](running-e2e.md#local-e2e-commands); which to run: [platform coverage](running-e2e.md#platform-coverage-gate-blocking) | `jet`, `npx jet`, `detox test`; globs; running every named e2e script unless that table requires it | +| `.only` scan | `rg '\.only\(' src/ e2e/ plugin/ __tests__/` | other grep as the gate | + +Redirect/`tee` of the **same** listed yarn script is allowed. Do not add other wrappers. + + + +## Prepare must finish first + +`yarn` / `yarn prepare` only when this pass will run tsc, Jest, lint, Metro, or native. `yarn lint:markdown:check` and `yarn lint:spellcheck` **are** lint — they require `yarn` then `yarn prepare`. + +- Skip both when this pass will not run tsc/Jest/lint (including markdown/spellcheck)/Metro/native (for example `okf-bundle/` / `AGENTS.md` / `CONTRIBUTING.md` with no `docs/**`). A `documentation` pass on `docs/**` is **not** a skip. +- When this pass will run them, run prepare first even if the [evidence prepare row](validation-checklist.md#validation-evidence-package) is `n/a` (for example android-only lint: run prepare; do not record it in that row). + +`yarn` / `yarn prepare` are blocking (genversion → bob → plugin). Metro reads `lib/`. Do not parallelize with Jest/tsc/Gradle/pods. + +Sandbox with no exit status on e2e/packager/Gradle/pods: retry the **same** command unrestricted. + +Traps: `genversion` via `yarn prepare` only. Example is `portal:../` — prepare before Metro. CI lint = `yarn lint:code`; CI tsc = `yarn tsc:compile`; docs CI = `yarn lint:spellcheck`. + + + +## Constraints block + +```text +RNGMA: okf-bundle/testing/agent-command-policy.md ONLY. +Lint: validation-checklist.md#lint-and-formatting only (lint:js / lint:android / lint:ios:check by tree; check vs :fix/--replace by work type; yarn lint:code only if src AND android AND ios AND not frozen independent-review; yarn lint is lint:code plus tsc). +E2e names: running-e2e.md#local-e2e-commands (tee of those same named scripts OK). Which to run: running-e2e.md#platform-coverage-gate-blocking. Do not glob yarn tests:android:* (Windows/release names) or yarn tests:ios:*. Do not run every named e2e script unless that table requires it. Jest and packager stay Canonical registry names. +Never jet/npx jet/detox/npm install/ad-hoc gradlew/`npx google-java-format` (Java gate is yarn lint:android). +yarn then yarn prepare when this pass runs tsc/Jest/lint (including markdown/spellcheck)/Metro/native (agent-command-policy.md#prepare-must-finish-first). Same command on retry except lint hops #lint-and-formatting; other failures hop #frozen-tree. +Gates: validation-checklist.md#validation-evidence-package (+ coverage-design.md#coverage-evidence-package if src/ or android/ or ios/ or plugin/ TS). +``` diff --git a/okf-bundle/testing/change-authoring-workflow.md b/okf-bundle/testing/change-authoring-workflow.md new file mode 100644 index 00000000..f7a694ab --- /dev/null +++ b/okf-bundle/testing/change-authoring-workflow.md @@ -0,0 +1,103 @@ +--- +type: Reference +title: Change authoring workflow +description: Verified product-change loop, gates, frozen tree, quality bar. +tags: [testing, validation, workflow] +timestamp: 2026-08-22T00:00:00Z +--- + +# Change authoring workflow + +How to author a product change. Queues hold gate state; they do not restate this loop. + +**Policy:** [documentation policy](../documentation-policy.md). **Terms:** [iteration vocabulary](iteration-vocabulary.md). **Commands:** [validation checklist](validation-checklist.md), [agent command policy](agent-command-policy.md). + +**Product trees:** `src/`, `android/`, `ios/`, `plugin/`, `e2e/`, `docs/`, `RNGoogleMobileAdsExample/` (not `node_modules`). `lib/` and `src/version.ts` from `yarn prepare`. + + + +## Loop + +`gap-analysis?` → `baseline-capture?` → `implementation` (`unit-focused`) → `documentation?` → `independent-review` (`area-focused`, frozen) → `commit` → `pre-merge-validation` (`full`) if merging. + +OKF, `AGENTS.md`, and `CONTRIBUTING.md` edits belong in `documentation?` **on the same change set** as the product work they describe. `independent-review` of that frozen tree **is** the [OKF bundle scan](validation-checklist.md#okf-bundle-review) when the frozen tree includes `okf-bundle/`, `AGENTS.md`, or `CONTRIBUTING.md` (including a `CONTRIBUTING.md`-only tree). Do not add OKF after a frozen review without another `independent-review`. Close `commit` only after that scan (when OKF/`AGENTS.md`/`CONTRIBUTING.md` changed). + +| Work type | Tier | Edits | Commit | +|-----------|------|-------|--------| +| `gap-analysis` | none | read-only | no | +| `baseline-capture` | `area-focused` | no `.only` | no | +| `implementation` | `unit-focused` | yes | no | +| `documentation` | none | docs/OKF/`AGENTS.md`/`CONTRIBUTING.md` | no | +| `independent-review` | `area-focused` | frozen — [§ frozen tree](#frozen-tree) | no | +| `commit` | none | stage | yes | +| `pre-merge-validation` | `full` | revert `.only` | no | + +Tiers: `unit-focused` = Jest + optional `.only`/narrow e2e for **diagnosis only**; closing `implementation` still follows [platform coverage](running-e2e.md#platform-coverage-gate-blocking) and [lint-by-tree](validation-checklist.md#lint-and-formatting). `area-focused` = full area, no `.only`, frozen for review. `full` / `pre-merge-validation` = [platform coverage](running-e2e.md#platform-coverage-gate-blocking) **and** the lint-by-tree / evidence rows that already apply for this diff; not automatically both platforms; CI e2e jobs are not the pass signal. + + + +## Gates + +| Gate | Closes when | +|------|-------------| +| `implementation` (`implementation_gate`) | Unit-focused green; [platform coverage](running-e2e.md#platform-coverage-gate-blocking); [lint](validation-checklist.md#lint-and-formatting) | +| `independent-review` (`review_gate`) | `documentation?` already done when OKF/`AGENTS.md`/`CONTRIBUTING.md`/user docs changed; area-focused green on frozen tree; **all** findings fixed ([§ quality](#quality-standards)); apply per [§ frozen tree](#frozen-tree) (not every finding → `documentation?`); OKF scan when `okf-bundle/`, `AGENTS.md`, or `CONTRIBUTING.md` is in the frozen tree | +| `coverage_evidence_gate` | Closes per [coverage evidence](coverage-design.md#coverage-evidence-package) (`n/a` unless the diff includes `src/` **or** `android/` **or** `ios/` **or** `plugin/` TS; `app.plugin.js`-only is `n/a` unless `plugin/` TS changed — plugin Jest still follows [§ Expo plugin](validation-checklist.md#expo-plugin)) | +| `commit` (`commit_gate`) | Prior gates closed with [evidence package](validation-checklist.md#validation-evidence-package) | +| `pre-merge-validation` | [Validation-checklist work types](validation-checklist.md#work-types) pre-merge row recorded (platform coverage + lint/evidence); CI e2e is not the pass | + +Open `review_gate` = unverified. + + + +### Validation evidence + +**Blocking.** Record the [validation evidence package](validation-checklist.md#validation-evidence-package). No exit codes / log paths → gate stays open. + + + +## Quality standards + +Finding severity and close-rule: [§ review findings](#review-findings). Exceptions: [§ acceptable exceptions](#acceptable-exceptions). + + + +### Acceptable exceptions + +Only with **user confirmation**: (1) intractable platform/SDK/toolchain limit + evidence, or (2) user deferral + rationale. Testable code gets a test or is deleted. + + + +### Review findings + +Findings `critical`/`serious`/`minor`/`nit`. `review_gate` closes only when all are fixed or an [exception](#acceptable-exceptions) applies. Where to apply: [§ frozen tree](#frozen-tree) — split by **what failed**, not every frozen finding → `documentation?`. + + + +## Frozen tree + +No edits during `independent-review` except revert `.only`: product trees (above); `okf-bundle/`; `AGENTS.md`; `CONTRIBUTING.md`. This pass is report-only ([lint-and-formatting](validation-checklist.md#lint-and-formatting), [OKF bundle review](validation-checklist.md#okf-bundle-review)). Follow-up owner is **what failed**: findings in `okf-bundle/` / `AGENTS.md` / `CONTRIBUTING.md` → new `documentation?`, then another frozen scan; findings in product / tests / lint (including iOS `:fix` after check failure, and Android format) → `implementation`. Do not send every frozen-review finding to `documentation?`. Separate implementation/`documentation` and review passes. + + + +## Host rule + +[Pre-flight](running-e2e.md#pre-flight) each run (prepare finished, Metro is this checkout). Canonical e2e: [local e2e commands](running-e2e.md#local-e2e-commands) only. + + + +## Implementation + +[Pre-flight](running-e2e.md#pre-flight) → edit → [platform coverage](running-e2e.md#platform-coverage-gate-blocking) and [lint-by-tree](validation-checklist.md#lint-and-formatting) for this diff (Jest only if that table or [evidence](validation-checklist.md#validation-evidence-package) requires it). + +Native GMA/UMP calls: read each platform’s official API; don’t copy Android fixes to iOS without checking; record citations in the queue. + +`.only` or a single e2e file is allowed for `unit-focused` diagnosis only. Revert before `area-focused` / `full`. Never commit `.only`. Diagnosis steps: [running e2e § diagnosis](running-e2e.md#e2e-diagnosis). + + + +## Commit + +One focused commit when `commit_gate` closes. Before `git commit`, scan for `.only` with the [registry](agent-command-policy.md#canonical-registry) `.only` scan command. Never stage `.only`. Do not stage `.agents/work-queues/`, `.agents/reports/`, or new queue files under `okf-bundle/` — [documentation policy](../documentation-policy.md#durable-vs-ephemeral). Before `git commit`, set the queue row's `commit_subject` to the commit's subject line and close `commit_gate`. Do not record SHAs. After commit, the git subject and the queue `commit_subject` must match character-for-character. Single-commit PR titles: [documentation-policy § pull requests](../documentation-policy.md#pull-requests). + +Gate rows, `next_work_type`, and `commit_subject` live in work queues only. Staging, SHA ban, and character-match for `commit_subject` are this section. diff --git a/okf-bundle/testing/coverage-design.md b/okf-bundle/testing/coverage-design.md new file mode 100644 index 00000000..dddb32dc --- /dev/null +++ b/okf-bundle/testing/coverage-design.md @@ -0,0 +1,32 @@ +--- +type: Reference +title: Coverage design +description: Touched-line coverage and evidence package. +tags: [testing, coverage, jest] +timestamp: 2026-08-22T00:00:00Z +--- + +# Coverage design + +| Layer | Command | +|-------|---------| +| Jest (`src/**`) | `yarn tests:jest-coverage` — only if `src/` or `plugin/` TS was touched. `src/version.ts` is generated by `yarn prepare`; it is out of the [touched-line bar](#touched-line-bar), not a Jest config ignore. | +| Plugin TS | root `yarn tests:jest-coverage plugin/__tests__/` (or touched plugin paths). Not `plugin/jest.config.js`. | +| E2e | [local e2e](running-e2e.md#local-e2e-commands) when [platform coverage](running-e2e.md#platform-coverage-gate-blocking) requires it | + +CI Codecov: Jest + e2e jobs. Review signal = **touched files**. Native Jacoco/LCOV yarn targets do not exist yet — do not invent them. + + + +## Touched-line bar + +New code: coverage only rises. + +- Touched TypeScript in `src/` or `plugin/`: **100% reachable touched lines**. `src/version.ts` is generated by `yarn prepare`; leave it out of this bar. Else [acceptable exception](change-authoring-workflow.md#acceptable-exceptions) or delete dead code. +- Native (`android/**`, `ios/**`): e2e counts satisfy coverage until Jacoco/LCOV yarn targets exist. Do not stamp 100% on an empty TS set. Do not run `yarn tests:jest-coverage` for native-only diffs. + + + +## Coverage evidence package + +**Blocking.** Required to close `review_gate` / `coverage_evidence_gate` when the diff includes `src/` **or** `android/` **or** `ios/` **or** `plugin/` TS. `app.plugin.js`-only is `n/a` unless `plugin/` TS changed (plugin Jest still follows [Expo plugin](validation-checklist.md#expo-plugin)). Do not use `plugin/**` as the required-when test. Native-only still records e2e counts. Write `.agents/reports//coverage-evidence.md` (that directory is gitignored; **do not stage** it — same rule as `.agents/work-queues/`). Include artifacts + timestamps; per-file % for touched TS; branch → test; every gap (fix / delete / exception). Verdict: `100% on reachable touched lines` for touched TS, or `NOT 100%` with dispositions. Do not invent native coverage numbers and do not run jest-coverage on native-only diffs. Missing package = blocking finding. diff --git a/okf-bundle/testing/index.md b/okf-bundle/testing/index.md new file mode 100644 index 00000000..4d3baffc --- /dev/null +++ b/okf-bundle/testing/index.md @@ -0,0 +1,12 @@ +# Testing + +* [Agent command policy](agent-command-policy.md) — shell allowlist (read first); [§ canonical registry](agent-command-policy.md#canonical-registry); [§ prepare must finish first](agent-command-policy.md#prepare-must-finish-first); [§ constraints block](agent-command-policy.md#constraints-block) +* [Documentation/commit policy](../documentation-policy.md) — [public vs ephemeral vs private](../documentation-policy.md#durable-vs-ephemeral), [work queues](../documentation-policy.md#work-queues), [commits as documentation](../documentation-policy.md#commits-as-documentation), [pull requests](../documentation-policy.md#pull-requests), [OKF update contract](../documentation-policy.md#okf-update-contract), [Efficiency](../documentation-policy.md#efficiency) +* [Change authoring](change-authoring-workflow.md) — [§ loop](change-authoring-workflow.md#loop), [§ gates](change-authoring-workflow.md#gates), [§ frozen tree](change-authoring-workflow.md#frozen-tree), [§ quality standards](change-authoring-workflow.md#quality-standards), [§ acceptable exceptions](change-authoring-workflow.md#acceptable-exceptions), [§ review findings](change-authoring-workflow.md#review-findings), [§ host rule](change-authoring-workflow.md#host-rule), [§ implementation](change-authoring-workflow.md#implementation), [§ commit](change-authoring-workflow.md#commit); evidence owner: [validation evidence package](validation-checklist.md#validation-evidence-package) ([§ validation evidence](change-authoring-workflow.md#validation-evidence-blocking)) +* [Iteration vocabulary](iteration-vocabulary.md) — work types, tiers, queue fields +* [Running e2e](running-e2e.md) — [§ agent rule](running-e2e.md#agent-rule-read-first); [§ local e2e commands](running-e2e.md#local-e2e-commands); [§ platform coverage gate](running-e2e.md#platform-coverage-gate-blocking); [§ pre-flight](running-e2e.md#pre-flight); [§ diagnosis](running-e2e.md#e2e-diagnosis) +* [Validation checklist](validation-checklist.md) — [§ work types](validation-checklist.md#work-types); [§ lint](validation-checklist.md#lint-and-formatting); [§ Expo plugin](validation-checklist.md#expo-plugin); [§ OKF bundle review](validation-checklist.md#okf-bundle-review); [§ validation evidence package](validation-checklist.md#validation-evidence-package) +* [Coverage design](coverage-design.md) — [touched-line bar](coverage-design.md#touched-line-bar); [§ evidence package](coverage-design.md#coverage-evidence-package) (`n/a` for `app.plugin.js`-only unless `plugin/` TS changed) +* [Architecture decisions](../architecture-decisions.md) — `GMA-AD-*`; [GMA-AD-1 plugin path](../architecture-decisions.md#gma-ad-1) +* [Documentation site maintenance](../documentation-site-maintenance.md) — user docs.page [`docs.json`](../documentation-site-maintenance.md#docsjson) +* [CI workflows](../ci-workflows/index.md) — [§ workflows](../ci-workflows/index.md#workflows); [e2e continue-on-error](../ci-workflows/index.md#e2e-continue-on-error); [§ triage](../ci-workflows/index.md#triage) diff --git a/okf-bundle/testing/iteration-vocabulary.md b/okf-bundle/testing/iteration-vocabulary.md new file mode 100644 index 00000000..1d2f979b --- /dev/null +++ b/okf-bundle/testing/iteration-vocabulary.md @@ -0,0 +1,33 @@ +--- +type: Reference +title: Iteration vocabulary +description: Work-type, tier, and work-queue field identifiers — not procedures. +tags: [testing, validation, workflow, work-queue] +timestamp: 2026-08-22T00:00:00Z +--- + +# Iteration vocabulary + +Identifiers only. Procedures: [change authoring](change-authoring-workflow.md). Commands: [agent command policy](agent-command-policy.md). Policy: [documentation policy](../documentation-policy.md). + +Order is **not** implied by this table; sequence: [change authoring § loop](change-authoring-workflow.md#loop). + +| Work type | Meaning | +|-----------|---------| +| `gap-analysis` | Read-only feasibility / semantics | +| `baseline-capture` | Before snapshots | +| `implementation` | Product code + tests | +| `documentation` | User docs + durable OKF + `AGENTS.md` + `CONTRIBUTING.md` | +| `independent-review` | Frozen-diff verify | +| `commit` | One focused commit | +| `pre-merge-validation` | Branch merge gate | + +| Tier | Meaning | +|------|---------| +| `unit-focused` | Fast, while code is changing | +| `area-focused` | Full area spec | +| `full` | [Platform coverage](running-e2e.md#platform-coverage-gate-blocking) **and** lint-by-tree / evidence for this diff; not automatically both platforms; CI e2e jobs are not the pass signal | + +Queue fields (`open`\|`closed` unless noted): `next_work_type`, `validation_tier`, `platform`, `implementation_gate`, `review_gate`, `commit_gate`, `coverage_evidence_gate` (`open`\|`closed`\|`n/a`), `commit_subject` (planned or landed Conventional Commits first line), `blocked`. + +State only — not who executes. Gate close rules: [change authoring § gates](change-authoring-workflow.md#gates). `commit_subject` match and staging: [change authoring § commit](change-authoring-workflow.md#commit). diff --git a/okf-bundle/testing/running-e2e.md b/okf-bundle/testing/running-e2e.md new file mode 100644 index 00000000..16d7c93f --- /dev/null +++ b/okf-bundle/testing/running-e2e.md @@ -0,0 +1,76 @@ +--- +type: Reference +title: Running e2e tests +description: Canonical local e2e yarn scripts (exact names). +tags: [testing, e2e, ios, android] +timestamp: 2026-08-22T00:00:00Z +--- + +# Running e2e tests + + + +## Agent rule + +Use **only** [local e2e commands](#local-e2e-commands). No direct Jet/Metro/Gradle/`pod`. Install: [agent command policy](agent-command-policy.md). When to run e2e vs Jest: [§ platform coverage](#platform-coverage-gate-blocking). + +Once: `yarn && yarn prepare && yarn tests:install` (+ `yarn tests:ios:pod:install` on iOS). + + + +## Local e2e commands + +**Names only.** Which of these to run is [platform coverage](#platform-coverage-gate-blocking). When running e2e, use only these named scripts (no `yarn tests:android:*` / `yarn tests:ios:*` globs). Do **not** run every named script unless that table requires it. + +Named scripts: `yarn tests:packager`, `yarn tests:packager:reset-cache`, `yarn tests:android:build`, `yarn tests:android:run`, `yarn tests:ios:pod:install`, `yarn tests:ios:run`. + +When those named scripts are the e2e gate, `tee` `yarn tests:android:run` to `/tmp/rngma-e2e-android.log` and `yarn tests:ios:run` to `/tmp/rngma-e2e-ios.log`. Redirect/`tee` of the **same** named yarn script is allowed; do not add other wrappers. + +Specs: `e2e/*.e2e.js`. App: `RNGoogleMobileAdsExample/`. One e2e at a time (`:8081`). No source edits during a run. + +There is no separate macOS-app e2e target. iOS e2e is `yarn tests:ios:pod:install` / `yarn tests:ios:run` (local Mac or CI `macos-15`). + +A green GitHub Actions e2e workflow is **not** a pass ([continue-on-error](../ci-workflows/index.md#e2e-continue-on-error)). Use local counts + `/tmp/rngma-e2e-*.log`, or triaged `simulator_log` / `adb_logs`. + + + +## Platform coverage gate + +**Owner for which e2e/Jest this diff needs.** Lint/tsc: [lint-by-tree](validation-checklist.md#lint-and-formatting) and [evidence](validation-checklist.md#validation-evidence-package). Other docs hop here. Apply **every matching row**. JS-only `src/` does not apply if `src/specs/**`, `android/**`, or `ios/**` also changed. + +| Diff | Required before impl/review gates | +|------|-----------------------------------| +| Docs/md/OKF only (`docs/**`, `**/*.md`, `okf-bundle/**`, `AGENTS.md`, `CONTRIBUTING.md`; no product trees) | No e2e. | +| Root `__tests__/` only | Root `yarn tests:jest` (paths as needed). **Not** native e2e. | +| JS-only `src/` excluding `src/specs/**` | `yarn prepare` + root Jest. Packager only if you will actually start Metro; JS-only does not require it. **Not** native e2e. | +| JS/config plugin only (`plugin/**`, `app.plugin.js`; no native-manifest/plist output) | [GMA-AD-1](../architecture-decisions.md#gma-ad-1) + [Expo plugin](validation-checklist.md#expo-plugin). Not native e2e. | +| Touched `e2e/**` | Android: `yarn tests:packager` (or `:reset-cache` when [pre-flight](#pre-flight) says free `:8081`) + `yarn tests:android:build` + `yarn tests:android:run`. iOS: `yarn tests:packager` (same reset) + `yarn tests:ios:pod:install` + `yarn tests:ios:run`. Specs that changed, on the platform(s) those specs exercise. [Tee](#local-e2e-commands). | +| `RNGoogleMobileAdsExample/**` (example app/config, not `node_modules`) | Android: `yarn tests:packager` (or `:reset-cache` when [pre-flight](#pre-flight) says free `:8081`) + `yarn tests:android:build` + `yarn tests:android:run`. iOS: `yarn tests:packager` (same reset) + `yarn tests:ios:pod:install` + `yarn tests:ios:run`. Each platform the example change can affect. [Tee](#local-e2e-commands). | +| Plugin output that changes native manifests/plists, or touched `android/**`, `ios/**`, podspec, or `src/specs/**` | Android: `yarn tests:packager` (or `:reset-cache` when [pre-flight](#pre-flight) says free `:8081`) + `yarn tests:android:build` + `yarn tests:android:run`. iOS: `yarn tests:packager` (same reset) + `yarn tests:ios:pod:install` + `yarn tests:ios:run`. **Each affected platform.** [Tee](#local-e2e-commands). | + +A green run of **unrelated** e2e files does not close review for the touched area. + +`full` / `pre-merge-validation`: [validation-checklist work types](validation-checklist.md#work-types) (this table **and** lint-by-tree / evidence for this diff). CI e2e jobs are not the pass signal ([continue-on-error](../ci-workflows/index.md#e2e-continue-on-error)). + + + +## Pre-flight + +**Blocking.** [Prepare must finish first](agent-command-policy.md#prepare-must-finish-first): `yarn` then `yarn prepare` before Metro/e2e (this pass runs Metro/native). Do not parallelize prepare with packager, Jest, Gradle, or pods. What to record stays on the [evidence prepare row](validation-checklist.md#validation-evidence-package). + +Metro on `:8081` must be **this** checkout (`RNGoogleMobileAdsExample/`), not another worktree. One e2e at a time. Free `:8081` before `yarn tests:packager:reset-cache`. Revert `.only` before area-focused/full. + +Interrupted Shell: log footer `N passing`/`N failing` = complete. An open tee or missing footer is **not** success — recover Metro `:8081` and re-run the **same** command. + + + +## Diagnosis + +1. Confirm [pre-flight](#pre-flight). +2. Same failure twice on the canonical command → narrow to one file or `.only` (`unit-focused` only). +3. Read `/tmp/rngma-e2e-ios.log` / `/tmp/rngma-e2e-android.log` (CI: `simulator_log` / `adb_logs` — [CI workflows](../ci-workflows/index.md)). +4. Revert `.only` and extra native logging before area-focused review or commit. + +Do not invent harness override files or debug flags from other repos. + +Merge: no `.only`. Pre-merge validation: [platform coverage](#platform-coverage-gate-blocking) for this diff (CI e2e not the pass) **and** the lint/tsc/coverage rows that [validation evidence](validation-checklist.md#validation-evidence-package) / [lint-by-tree](validation-checklist.md#lint-and-formatting) already require for this diff. diff --git a/okf-bundle/testing/validation-checklist.md b/okf-bundle/testing/validation-checklist.md new file mode 100644 index 00000000..3c9c057f --- /dev/null +++ b/okf-bundle/testing/validation-checklist.md @@ -0,0 +1,72 @@ +--- +type: Reference +title: Validation checklist +description: Validation command sequence. +tags: [testing, validation, jest, lint] +timestamp: 2026-08-22T00:00:00Z +--- + +# Validation checklist + +Coverage: [coverage design](coverage-design.md). Tiers: [change authoring](change-authoring-workflow.md). Sequence uses [canonical registry](agent-command-policy.md#canonical-registry) names. E2e: [local e2e commands](running-e2e.md#local-e2e-commands). + + + +| Work type | Run | +|-----------|-----| +| `gap-analysis` | Read APIs/docs | +| `baseline-capture` | Only the [platform coverage](running-e2e.md#platform-coverage-gate-blocking) rows for this diff; no `.only` | +| `implementation` | [Platform coverage](running-e2e.md#platform-coverage-gate-blocking) and [lint-by-tree](#lint-and-formatting) for this diff; `.only` local OK | +| `documentation` | Promote durable OKF / user docs / `AGENTS.md` / `CONTRIBUTING.md`. [Lint](#lint-and-formatting) if `docs/**`. **Do not** run the independent OKF scan here. | +| `independent-review` | Rows that apply to **this** diff ([platform coverage](running-e2e.md#platform-coverage-gate-blocking), check-only [lint-by-tree](#lint-and-formatting)), frozen, no `.only`. [OKF scan](#okf-bundle-review) when the frozen tree includes `okf-bundle/`, `AGENTS.md`, or `CONTRIBUTING.md`. | +| `pre-merge-validation` | [Platform coverage](running-e2e.md#platform-coverage-gate-blocking) for this diff; [lint-by-tree](#lint-and-formatting) / evidence rows that already apply; CI e2e jobs are not the pass signal | + + + +## Lint and formatting + +This heading owns lint-by-tree, check vs `:fix`/`--replace` by work type, and when markdown check applies. Registry hops here: [canonical registry](agent-command-policy.md#canonical-registry), [constraints block](agent-command-policy.md#constraints-block). + +**Check vs format.** `implementation` and `documentation`: after a check failure, run the allowlisted `:fix` then re-check. `yarn lint:android` already `--replace` (and `--set-exit-if-changed`). `independent-review` is **check-only** on the frozen tree ([§ frozen tree](change-authoring-workflow.md#frozen-tree)): run matching **check** commands; do not run `lint:ios:fix` or `lint:markdown:fix`. Frozen `independent-review` does **not** run `yarn lint:android` because that script is `--replace` only; Android format is not a frozen-pass check — apply it in `implementation`. Do not invent `npx google-java-format` or a check-only yarn name. A check failure is a finding; apply per [§ frozen tree](change-authoring-workflow.md#frozen-tree) (product/lint including iOS `:fix` and Android format → `implementation`; markdown format when `docs/**` → `documentation`). + +**Which trees.** `yarn lint:js` only if `src/` (script scope is `src/`). Plugin JS: [Expo plugin](#expo-plugin) Jest, not `lint:js`. Root `__tests__/` is not in `lint:js`. `yarn lint:android` if `android/` **and** the work type may `--replace` (`implementation` / `documentation`). `yarn lint:ios:check` if `ios/`. `yarn lint:code` only when this diff includes `src/` **and** `android/` **and** `ios/` **and** the work type may `--replace`; never as a stand-in for a single-tree lint; never on frozen `independent-review` (it runs `lint:android`). `yarn lint` is `lint:code` plus `tsc:compile` (same three-tree rule). Frozen three-tree: `lint:js` and `lint:ios:check` only. + +**Docs.** `yarn lint:markdown:check` and `yarn lint:spellcheck` **only** when the diff includes `docs/**`. Independent-review of `okf-bundle/` / `AGENTS.md` / `CONTRIBUTING.md` with **no** `docs/**` does **not** run markdown check or `lint:markdown:fix`. CI docs job is spellcheck only; markdown check is local. Allowlist: [agent command policy](agent-command-policy.md). User-docs sidebar: [documentation site maintenance](../documentation-site-maintenance.md). + + + +## Expo plugin + +**Blocking when the diff touches `plugin/` or `app.plugin.js`.** [GMA-AD-1](../architecture-decisions.md#gma-ad-1): `yarn prepare` (includes `build:plugin`) then **root** `yarn tests:jest plugin/__tests__/`. Root Jest is the gate. `plugin/jest.config.js` exists for expo-module-scripts; do not invoke it instead of root Jest, and do not delete it as “invented.” + +E2e vs plugin Jest: [platform coverage](running-e2e.md#platform-coverage-gate-blocking). + + + +## OKF bundle review + +This scan **is** `independent-review` of the frozen tree when `okf-bundle/`, `AGENTS.md`, or `CONTRIBUTING.md` is in that tree ([change authoring § loop](change-authoring-workflow.md#loop)). Do not run it during `documentation` (that work type only promotes durable text). This scan does **not** run `yarn lint:markdown:check` / `lint:markdown:fix` unless `docs/**` is also in the frozen tree ([§ lint](#lint-and-formatting)). Run the [OKF update contract](../documentation-policy.md#okf-update-contract): + +1. Confirm durable learnings landed in the owning `okf-bundle/` doc. If the frozen tree is `AGENTS.md`-only or `CONTRIBUTING.md`-only, still confirm those files against the [OKF update contract](../documentation-policy.md#okf-update-contract) rows that apply to them, and still complete step 3. +2. Check `okf-bundle/testing/` for conflicts with verified behavior; report drift (do not edit on this frozen pass). +3. Independent scan of the **entire** `okf-bundle/` tree **and** `AGENTS.md` / `CONTRIBUTING.md` (an `AGENTS.md`-only or `CONTRIBUTING.md`-only frozen tree still scans all three). Include a short summary of what changed and which files were touched. Confirm every contract row: Canonical location, DRY, [Efficiency](../documentation-policy.md#efficiency), link hygiene, Durability. This frozen scan **reports only** ([§ frozen tree](change-authoring-workflow.md#frozen-tree)). Apply `okf-bundle/` / `AGENTS.md` / `CONTRIBUTING.md` findings in a new `documentation?` pass, then another frozen scan — product/lint findings are [§ frozen tree](change-authoring-workflow.md#frozen-tree) (`implementation`), not this dump. Close `commit` only with a clean scan: [OKF update contract](../documentation-policy.md#okf-update-contract) and [§ commit](change-authoring-workflow.md#commit). Gate close is not a later escape hatch. + +Goal: each iteration improves OKF and removes conflicting guidance. The contract owns check meanings; this scan hops there — do not skip the hop by treating this list as a thinner substitute. + + + +## Validation evidence package + +**Blocking.** Record this table before closing gates or pushing. History rewrite invalidates it. E2e: Android/iOS named-script trios on [platform coverage](running-e2e.md#platform-coverage-gate-blocking); [local e2e](running-e2e.md#local-e2e-commands) is the name list and tee only. Apply only the rows this diff requires. + +| Step | Command | Exit | Evidence | +|------|---------|------|----------| +| prepare | `yarn prepare` | 0 | if `src/` or `plugin/` or `app.plugin.js` (or `lib/` is stale) | +| tsc | `yarn tsc:compile` | 0 | if `src/` or `plugin/` or `app.plugin.js` | +| jest | `yarn tests:jest ` | 0 | N/N — if `src/`, `plugin/`, or `__tests__/` | +| e2e iOS / Android | Android/iOS named-script trios on [platform coverage](running-e2e.md#platform-coverage-gate-blocking); [names + tee](running-e2e.md#local-e2e-commands) | 0 | counts + `/tmp/rngma-e2e-*.log` — only if that table requires e2e | +| lint | [§ lint](#lint-and-formatting) for this diff (`lint:js` only if `src/`; not plugin; not root `__tests__/`). `yarn lint:code` / `yarn lint` only when this diff includes `src/` **and** `android/` **and** `ios/` and the work type may `--replace` | 0 | matching linters | +| docs | `yarn lint:markdown:check` and `yarn lint:spellcheck` | 0 | if `docs/**` — [§ lint](#lint-and-formatting) | +| plugin | `yarn tests:jest plugin/__tests__/` | 0 | if `plugin/` or `app.plugin.js` — [§ Expo plugin](#expo-plugin) | +| coverage | [evidence package](coverage-design.md#coverage-evidence-package) | — | required when `src/` **or** `android/` **or** `ios/` **or** `plugin/` TS; `app.plugin.js`-only is `n/a` unless `plugin/` TS changed | +| OKF scan | [§ OKF bundle review](#okf-bundle-review) | pass | if frozen tree includes `okf-bundle/`, `AGENTS.md`, or `CONTRIBUTING.md` — not during `documentation`; gate close is not a skip |