Repository navigation
Conversation
|
@AndrewGable I know the tests look... verbose... but it basically just amounts to merging this PR, testing it in dry run mode on a couple of dozen PRs, and verifying the results. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d3ced15e71
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| input, | ||
| instructions: PRODUCT_CHANGE_INSTRUCTIONS, | ||
| model: PRODUCT_CHANGE_MODEL, | ||
| textFormat: PRODUCT_CHANGE_RESPONSE_FORMAT, | ||
| promptCacheKey: 'includes-product-change-v1', | ||
| }); | ||
| const result = openAI.parseJSONResponse(response.text, isProductChangeClassification); |
There was a problem hiding this comment.
Bound the model request below the job timeout
When the Responses API stalls, this request can consume the entire workflow budget: the bundled OpenAI client defaults to a 600,000 ms request timeout, exactly matching labelProductChanges.yml's timeout-minutes: 10. GitHub then terminates the job before classify() can catch the failure and return unsure, so the promised conservative fallback never adds IncludesProductChange for that PR. Pass a shorter abort signal/timeout to the model call so the fallback can complete before the job deadline.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
I don't really think this is necessary as that is a pretty long edge case.
|
After talking with Andrew, we might go a different direction with this, so I'm going to close this for now. |
Explanation of Change
Automatically adds
IncludesProductChangeto non-draft App PRs when an AI classifier finds product/UI changes or cannot confidently rule them out. Includes add-only behavior, dry-run/backfill support, and classification summaries for the trial.Fixed Issues
For https://github.com/Expensify/Expensify/issues/686684
PROPOSAL: N/A — internal implementation.
Tests
Reviewer checks — no local setup or API key required
verifyjob passes. This checks that the committed action bundles match their source.Optional local automated tests — no API key required
ci/includes-product-changewith the repository's Node, npm, Bun, and dependencies installed.npm run test:bunand press Return. Confirm all tests pass.npm run lint-changed,npm run typecheck, andnpm run spell-changed, one command at a time..github/scripts/verifyActions.shand confirm the generated actions match their sources.Real AI accuracy evaluation — after merge
The automated tests above use mocked model responses. They do not establish how accurately the real model classifies PRs.
After merge, run the existing workflow from GitHub's Actions tab using the steps below. GitHub supplies
OPENAI_APP_REVIEWER_API_KEYautomatically; no local API key setup is needed.Automatic add-only labeling starts when this workflow is merged. Evaluate the prompt with historical PRs in dry-run mode after merge, and complete that evaluation before backfilling existing open PRs. Real-model testing is not a pre-merge requirement.
AI Tests
Offline tests
npm run test:bun -- -t 'product-change|OpenAIUtils'.Application offline behavior: N/A.
The action uses the existing OpenAI helper's request/retry behavior and a 10-minute workflow limit. A job stopped by that limit cannot apply the fallback and must be retried.
QA Steps
[No QA] — tooling-only change. Engineer rollout verification:
Expensify/App.main, enter102450as the PR number, and keepdry_runenabled.would_add_labelorwould_skip_label, with nofallbackfield. GitHub supplies the model key automatically; dry runs do not change labels.dry_run=true. Compare the summary's head/base SHA prefixes with the recorded revision, then fill in the actual verdict/action, workflow-run link, and notes. Investigate missed product changes and record fallbacks separately. Closed and already-labeled PRs can be evaluated; drafts are skipped.dry_run=falseto backfill:Treat current reviewer assignments as a comparison point, not ground truth. The later reviewer-assignment change must distinguish pending classification from confirmed non-product results.
QA step 6 evaluation table
Expected results were prepared from diff review on 2026-09-29, before running the classifier. All 24 samples are merged PRs. These are review expectations, not observed model results; the final three columns are intentionally blank.
The sample contains 13 product changes, 9 clearly non-product changes, 1 uncertain dependency change, and 1 expected binary-file fallback. The classifier's input checks accepted the 23 text-based samples. The binary sample failed the readable-patch check as expected. No OpenAI calls were made for this preparation.
How to fill this in: copy
verdictandactionfrom the workflow summary, link the run, and record its explanation orfallbackin Notes. The revision column lists 12-character head / base SHA prefixes; if either differs from the run summary, re-review that sample before scoring it. Record the workflow revision/model when comparing repeated evaluation rounds.How to judge results:
product_changeandunsureboth mean add (would_add_label);clearly_non_productmeans skip (would_skip_label). Anunsureresult on a product-change row still catches the change, but record the uncertainty. Adding the label to a clearly non-product row is a conservative false positive. Treat model/API failures as operational fallbacks, not accurate classifications. The final binary row tests fallback behavior and should be excluded from model-accuracy counts.0b0ac65b09a3/53e6747c08beclearly_non_product/ skipcontributingGuides/PERFORMANCE.mdonly.a454b38fb03f/a9709e2c8906clearly_non_product/ skip3c82e5cd3c2e/ea01dd159fdfclearly_non_product/ skipe1ec2cfc647d/9c680bceb940clearly_non_product/ skip04da0cf741dd/e72bd3189130clearly_non_product/ skip65f22b9a5344/d2911302606dclearly_non_product/ skipc777990b8bd1/87618c248648clearly_non_product/ skipReportTest.ts; no runtime behavior change.243a6609df47/af4ed367c1bbclearly_non_product/ skiptranslateLocalcalls with supplied translation functions, preserving translation keys and naming logic.ff3bbaf3526f/e72bd3189130clearly_non_product/ skipf84dd6b71532/af4ed367c1bbproduct_change/ addMISSING TRANSLATIONoutput, returning the key string instead. The refactor title and NoQA marker must not hide this behavior change.74ddd09efb75/68ad1ed0e2bfproduct_change/ add47f83ef02111/1ec666a7cb7aproduct_change/ addf32dc5ba2d67/5badaa68111dproduct_change/ addf8da012d973b/c6f374078238product_change/ add93856becd417/c6f374078238product_change/ add1754bf462c0a/a9709e2c8906product_change/ add64f1d2008ac8/7041ea0f69f5product_change/ addca06bd260544/bd73f8fbb300product_change/ adddb5d38a0d90c/bd73f8fbb300product_change/ add97ef95d49b86/1bb7b7e7d337product_change/ add78ac577362dd/bfa20a3e0d31product_change/ addshouldSaveRecentSearch=falseso background searches do not overwrite user history.82bd30717c69/d23683be1245product_change/ add1a323e8d3b1b/5badaa68111dunsure/ add516ae6a8ccd3/68ad1ed0e2bfunsure/ add via fallbackdocs/assets/images/wallet-test-transactions.pngwithout a readable patch. Expectfallback: A changed file has no readable patch.before model inference; this is not a product-change accuracy claim.PR Author Checklist
Application/platform-specific items below are N/A for this tooling-only change. Live model and event verification are planned after merge.
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionScreenshots/Videos
Android: Native
N/A — GitHub automation only.
Android: mWeb Chrome
N/A — GitHub automation only.
iOS: Native
N/A — GitHub automation only.
iOS: mWeb Safari
N/A — GitHub automation only.
MacOS: Chrome / Safari
N/A — GitHub automation only.
- Tim's A.I. Agent 🤖