Replace pnpm-lock.yaml with package-lock.json and drop pnpm-workspace.yaml.
The three security overrides move to package.json#overrides, which npm reads
natively; allowBuilds for esbuild is unnecessary because npm runs dependency
build scripts by default.
android/build:web drove the web build through corepack pnpm, so it would have
broken once web/pnpm-lock.yaml was gone. It now uses npm --prefix.
Fresh resolution picks up patched versions the old lockfile had pinned below,
so npm audit reports no advisories where pnpm audit reported eight.
Both subprojects ship from the same commit, so ordinary CI is now a single
ci.yml; only the tag-driven release stands apart. The web app is built twice
per run — once per base path — and every consumer downloads the artifact
instead of rebuilding, replacing three redundant base-"" builds on main.
Nothing deploys unless the test job is green, and android-release runs the
suite before signing (ci.yml does not fire on tags, so it was the only gap).
Shared toolchain setup moves into composite actions, which puts the web build
and the APK on the same Node version for the first time. The Firebase PR path
was still on npm ci against a stale web/package-lock.json that could resolve a
different tree than pnpm-lock.yaml; drop the lockfile and the npm path with it.
Also: least-privilege permissions widened per job, persist-credentials off on
every checkout, concurrency groups that cancel superseded PRs but never a live
deploy, npm caching for android, and the Firebase action pinned by commit SHA
to match how the release actions were already pinned.
GitHub only runs workflows from .github/workflows at the root, so the six
workflows inherited from the two projects have to live there rather than under
web/ and android/. Each one gets a path filter so web-only changes do not
trigger Android builds, a working directory for its subproject, and a prefixed
filename to keep the two sets apart.
Gradle now sits at android/android, the Firebase action reads its config from
web/ via entryPoint, and the Android checkout no longer needs submodules.