Skip to content

ci: run full Detox by risk, and enforce the native gates on every PR - #21

Open
Aalv3 wants to merge 1 commit into
fix/auth-failure-classification-20260830from
ci/risk-based-detox-20260909
Open

Aalv3 wants to merge 1 commit into
fix/auth-failure-classification-20260830from
ci/risk-based-detox-20260909

Conversation

@Aalv3

@Aalv3 Aalv3 commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Founder-approved CI policy change. Implemented as a separate PR, with the surface classifier validated against representative historical diffs before merge.

What the Detox suite actually covers

Three specs, all logged out. Every assertion maps to two files:

Assertion Owning file
logged-out-welcome-scroll js/product/ProductScreens.js
"Members only", "Member sign in", "Signing in…", "Invitation-only membership" js/product/ProductScreens.js
nav-plus-icon js/screens/HomeScreenComponents/NavigationBar.js

It signs in to nothing, so it provides no coverage of notifications, notification routing, the OTP bootstrap, the authenticated WebView, member profiles, avatars, private member photos, rate limiting, or chat. This is stated plainly in docs/NATIVE-CI-POLICY.md so a green Detox run is never mistaken for authenticated-surface evidence.

Reduction

Full iPhone + iPad Detox (~100 min of macOS runner time) now runs only on: ios/, android/, e2e/, .detoxrc*, .github/workflows/, package.json, yarn.lock, app.json, eas.json, Gemfile*, *.config.*, and js/{Discourse,iosAuthSession,site_manager}.js, js/product/ProductScreens.js, js/screens/HomeScreen* — plus the full-detox label, workflow_dispatch, the nightly schedule, and fail-closed when the changed-file list can't be computed.

Increase

verify:ota, verify:ios-auth, verify:release-readiness, verify:backend, validate:ota ran nowhere in CI before this PR — only on a developer's machine. They now run on every PR in a new native-gates workflow. All five confirmed passing on the trunk locally.

ios-tests also gains concurrency cancellation; superseded runs were burning full macOS runners on already-replaced commits.

Classifier validation (13 historical diffs, all correct)

--- expected TRUE ---
PR#2  pin runtime dependencies       true   package.json,yarn.lock
close dependency findings            true   workflows,js/site_manager.js,package.json
remove Ionicons native decl          true   ios/Discourse/Info.plist
iOS share extension host             true   ios/ShareExtension/ShareViewController.swift
forward custom URLs to RN            true   ios/Discourse/AppDelegate.swift
PR#17 CI detox hygiene               true   workflows,e2e/jest.config.js,e2e/loggedOutLaunch.js
PR#16 notification routing           true   js/Discourse.js
PR#19 authenticated WebView          true   js/Discourse.js
--- expected FALSE ---
PR#14 docs certification record      false
ratelimit cooldown split             false
PR#11 private member-photo           false
onboarding policy + launch gates     false
PR#7  native search queries          false

Plus: schedule/workflow_dispatch/full-detox → true, skip-full-detox → false, missing base/head → true (fail closed). Evidence in testing/native-ci-policy/CLASSIFIER-VALIDATION.md.

onboarding policy + launch gates classifying false is correct — AdjusterCardOnboardingScreen.js is post-authentication and unreachable from a logged-out suite.

Preserved

No Detox assertion, matcher, 180s hook budget, --retries 2, or failure-artifact upload is touched. The job steps are byte-identical when they run; only needs: and if: were added. A failing test still fails the job, with full visibility.

Known behavior

A PR stacked on an unmerged branch inherits its parent's files and will usually run the full suite. That is the conservative outcome; skip-full-detox is the documented owner override, not a routine bypass. The durable fix is landing the lineage.

Implementation note

The classifier is plain git + bash — no third-party action, so this adds zero supply-chain surface.

The Detox suite is three logged-out specs. Every assertion in it resolves to
js/product/ProductScreens.js or
js/screens/HomeScreenComponents/NavigationBar.js. It signs in to nothing, so
it cannot observe notifications, the OTP bootstrap, the authenticated WebView,
avatars or rate limiting - yet it charged roughly 100 minutes of macOS runner
time to every JS-only iteration that touched those surfaces.

Full iPhone + iPad Detox now runs when the change can actually affect what the
suite asserts: native ios/ and android/, the e2e harness and Detox config,
workflows, runtime and dependency manifests, and the specific JS files the
specs reach. It also runs nightly, on workflow_dispatch, on the full-detox
label, and whenever the changed-file list cannot be computed - the classifier
fails closed. scripts/ci-detox-surface.sh writes its reasoning to the job
summary, so every run states why Detox ran or was skipped.

The reduction is paired with an increase. verify:ota, verify:ios-auth,
verify:release-readiness, verify:backend and validate:ota guard the OTA channel
wiring, the runtime version and the iOS auth presentation contract, and until
now ran only on a developer's machine. They now run on every pull request. The
cheapest and most safety-relevant checks were the ones CI did not enforce.

ios-tests also gains concurrency cancellation; superseded runs were burning
full macOS runners to test commits that had already been replaced.

No Detox assertion, matcher, hook budget, retry count or failure artifact is
changed. A failing test still fails the job.

Validated against 13 representative historical diffs before merge; evidence in
testing/native-ci-policy/CLASSIFIER-VALIDATION.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fk48MTrNBBSZeLvcJmc8SR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant